aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.cvsignore2
-rw-r--r--AUTHORS24
-rw-r--r--BUGS146
-rw-r--r--CHANGES230
-rw-r--r--COPYING26
-rw-r--r--ChangeLog2474
-rw-r--r--FAQ80
-rw-r--r--INSTALL168
-rw-r--r--Makefile118
-rw-r--r--Makefile.devel532
-rw-r--r--Makefile.xemacs14
-rw-r--r--README69
-rw-r--r--README.devel96
-rw-r--r--README.windows12
-rw-r--r--REGISTER12
-rw-r--r--TODO52
-rw-r--r--acl2/README22
-rw-r--r--acl2/acl2.el71
-rw-r--r--acl2/example.acl213
-rw-r--r--acl2/x-symbol-acl2.el85
-rw-r--r--bin/proofgeneral22
-rw-r--r--coq/BUGS27
-rw-r--r--coq/README38
-rw-r--r--coq/coq-syntax.el354
-rw-r--r--coq/coq.el720
-rw-r--r--coq/coqtags73
-rw-r--r--coq/example.v14
-rw-r--r--coq/todo78
-rw-r--r--coq/x-symbol-coq.el92
-rw-r--r--demoisa/README55
-rw-r--r--demoisa/demoisa-easy.el62
-rw-r--r--demoisa/demoisa.el157
-rw-r--r--doc/.cvsignore48
-rw-r--r--doc/Makefile24
-rw-r--r--doc/Makefile.doc164
-rw-r--r--doc/PG-adapting.texi3794
-rw-r--r--doc/ProofGeneral.jpgbin0 -> 12002 bytes
-rw-r--r--doc/ProofGeneral.texi4126
-rw-r--r--doc/README.doc38
-rw-r--r--doc/dir19
-rw-r--r--doc/docstring-magic.el67
-rw-r--r--doc/localdir3
-rw-r--r--etc/ProofGeneral.menu7
-rw-r--r--etc/ProofGeneral.spec110
-rw-r--r--etc/README31
-rw-r--r--etc/TESTS95
-rw-r--r--etc/announce78
-rw-r--r--etc/bug-notes.txt48
-rw-r--r--etc/coq/multiple/.cvsignore1
-rw-r--r--etc/coq/multiple/README27
-rw-r--r--etc/coq/multiple/a.v11
-rw-r--r--etc/coq/multiple/b.v11
-rw-r--r--etc/coq/multiple/c.v14
-rw-r--r--etc/coq/unnamed_thm.v30
-rw-r--r--etc/cvs-tips.txt113
-rw-r--r--etc/debugging-tips.txt10
-rw-r--r--etc/demoisa/A.ML1
-rw-r--r--etc/demoisa/B.ML1
-rw-r--r--etc/demoisa/C.ML1
-rw-r--r--etc/demoisa/D.ML1
-rw-r--r--etc/demoisa/README11
-rw-r--r--etc/doc-notes.txt196
-rw-r--r--etc/isa/\backslashname/test.ML11
-rw-r--r--etc/isa/\backslashname/test.thy1
-rw-r--r--etc/isa/depends/Fib.ML106
-rw-r--r--etc/isa/depends/Fib.thy17
-rw-r--r--etc/isa/depends/Primes.ML197
-rw-r--r--etc/isa/depends/Primes.thy33
-rw-r--r--etc/isa/depends/Usedepends.ML3
-rw-r--r--etc/isa/depends/Usedepends.thy5
-rw-r--r--etc/isa/goal-matching.ML10
-rw-r--r--etc/isa/long-line-backslash.ML20
-rw-r--r--etc/isa/message-test.ML16
-rw-r--r--etc/isa/multiple/A.ML11
-rw-r--r--etc/isa/multiple/A.thy7
-rw-r--r--etc/isa/multiple/B.ML4
-rw-r--r--etc/isa/multiple/B.thy7
-rw-r--r--etc/isa/multiple/C.ML4
-rw-r--r--etc/isa/multiple/C.thy10
-rw-r--r--etc/isa/multiple/D.ML3
-rw-r--r--etc/isa/multiple/D.thy7
-rw-r--r--etc/isa/multiple/Err.ML5
-rw-r--r--etc/isa/multiple/Err.thy3
-rw-r--r--etc/isa/multiple/README102
-rw-r--r--etc/isa/multiple/foobar/foo.ML4
-rw-r--r--etc/isa/settings.ML21
-rw-r--r--etc/isa/thy/test.ML5
-rw-r--r--etc/isa/xsym.ML18
-rw-r--r--etc/isar/CommentParsingBug.thy3
-rw-r--r--etc/isar/Parsing.thy37
-rw-r--r--etc/isar/README8
-rw-r--r--etc/isar/XEmacsSyntacticContextProb.thy20
-rw-r--r--etc/isar/bad1.thy3
-rw-r--r--etc/isar/bad2.thy1
-rw-r--r--etc/isar/multiple/A.thy7
-rw-r--r--etc/isar/multiple/B.thy4
-rw-r--r--etc/isar/multiple/C.thy5
-rw-r--r--etc/isar/multiple/D.thy4
-rw-r--r--etc/isar/multiple/README3
-rw-r--r--etc/isar/trace_simp.thy18
-rw-r--r--etc/junk.el157
-rw-r--r--etc/lego/GoalGoal.l13
-rw-r--r--etc/lego/error-eg.l16
-rw-r--r--etc/lego/lego-site.el23
-rw-r--r--etc/lego/long-line-backslash.l22
-rw-r--r--etc/lego/multiple/A.l1
-rw-r--r--etc/lego/multiple/B.l4
-rw-r--r--etc/lego/multiple/C.l1
-rw-r--r--etc/lego/multiple/D.l1
-rw-r--r--etc/lego/multiple/README33
-rw-r--r--etc/lego/unsaved-goals.l54
-rw-r--r--etc/patches/duplicated-short-messages-fix.txt107
-rw-r--r--etc/patches/fix-attempt-for-eager-cleaning.txt66
-rw-r--r--etc/pgkit/xmltest1.xml3
-rw-r--r--etc/pgkit/xmltest2.xml23
-rw-r--r--etc/profiling.txt397
-rw-r--r--etc/proofgeneral-domain.txt29
-rw-r--r--etc/release-log.txt68
-rw-r--r--etc/screenshot-notes.txt36
-rw-r--r--etc/test-schedule.txt19
-rw-r--r--etc/testing-log.txt142
-rw-r--r--generic/README15
-rw-r--r--generic/_pkg.el4
-rw-r--r--generic/pg-metadata.el112
-rw-r--r--generic/pg-pgip.el130
-rw-r--r--generic/pg-user.el918
-rw-r--r--generic/pg-xml.el252
-rw-r--r--generic/proof-autoloads.el191
-rw-r--r--generic/proof-compat.el299
-rw-r--r--generic/proof-config.el2311
-rw-r--r--generic/proof-depends.el207
-rw-r--r--generic/proof-easy-config.el84
-rw-r--r--generic/proof-indent.el98
-rw-r--r--generic/proof-menu.el601
-rw-r--r--generic/proof-script.el2661
-rw-r--r--generic/proof-shell.el2255
-rw-r--r--generic/proof-site.el378
-rw-r--r--generic/proof-splash.el264
-rw-r--r--generic/proof-syntax.el286
-rw-r--r--generic/proof-system.el21
-rw-r--r--generic/proof-toolbar.el587
-rw-r--r--generic/proof-utils.el763
-rw-r--r--generic/proof-x-symbol.el336
-rw-r--r--generic/proof.el120
-rw-r--r--generic/span-extent.el113
-rw-r--r--generic/span-overlay.el313
-rw-r--r--generic/span.el20
-rw-r--r--generic/texi-docstring-magic.el381
-rw-r--r--hol98/README53
-rw-r--r--hol98/example.sml30
-rw-r--r--hol98/hol98.el158
-rw-r--r--hol98/todo25
-rw-r--r--hol98/x-symbol-hol98.el85
-rw-r--r--html/.cvsignore1
-rw-r--r--html/.htaccess2
-rw-r--r--html/Kit/Makefile11
-rw-r--r--html/Kit/dtd/pgip.dtd226
-rw-r--r--html/Kit/dtd/pgml.dtd75
-rw-r--r--html/ProofGeneralPortrait.eps.gzbin0 -> 1646905 bytes
-rw-r--r--html/about5
-rw-r--r--html/about.html56
-rw-r--r--html/counter.php350
-rw-r--r--html/cvsweb.cgi2685
-rw-r--r--html/cvsweb.conf350
-rw-r--r--html/devel5
-rw-r--r--html/devel.html109
-rw-r--r--html/develdownload5
-rw-r--r--html/develdownload.html5
-rw-r--r--html/develdownload.php141
-rw-r--r--html/doc5
-rw-r--r--html/doc.html107
-rw-r--r--html/download5
-rw-r--r--html/download.html224
-rw-r--r--html/elispmarkup.php3135
-rw-r--r--html/features5
-rw-r--r--html/features.html194
-rw-r--r--html/feedback6
-rw-r--r--html/feedback.php87
-rw-r--r--html/fileshow.php24
-rw-r--r--html/footer.html10
-rw-r--r--html/functions.php3294
-rw-r--r--html/gallery6
-rw-r--r--html/gallery.php84
-rw-r--r--html/head.html30
-rw-r--r--html/header.html62
-rw-r--r--html/hits26
-rw-r--r--html/htmlshow.html5
-rw-r--r--html/htmlshow.php11
-rw-r--r--html/images/.cvsignore1
-rw-r--r--html/images/IsaPGscreen.jpgbin0 -> 50670 bytes
-rw-r--r--html/images/PG-small.jpgbin0 -> 1902 bytes
-rw-r--r--html/images/ProofGeneral.jpgbin0 -> 16123 bytes
-rw-r--r--html/images/bullethole.gifbin0 -> 928 bytes
-rw-r--r--html/images/canvaswallpaper.jpgbin0 -> 3546 bytes
-rw-r--r--html/images/coq-badge.gifbin0 -> 3174 bytes
-rw-r--r--html/images/coqlogo4.gifbin0 -> 1621 bytes
-rw-r--r--html/images/coqlogo4.xcfbin0 -> 3840 bytes
-rw-r--r--html/images/isabelle-badge.gifbin0 -> 4674 bytes
-rw-r--r--html/images/isabelle.gifbin0 -> 2477 bytes
-rw-r--r--html/images/lego-badge.gifbin0 -> 3925 bytes
-rw-r--r--html/images/pg-coq-screenshot.pngbin0 -> 138364 bytes
-rw-r--r--html/images/pg-coq-thumb.pngbin0 -> 22324 bytes
-rw-r--r--html/images/pg-isa-screenshot.pngbin0 -> 46767 bytes
-rw-r--r--html/images/pg-isa-thumb.pngbin0 -> 16726 bytes
-rw-r--r--html/images/pg-isar-screenshot.pngbin0 -> 50400 bytes
-rw-r--r--html/images/pg-isar-thumb.pngbin0 -> 20072 bytes
-rw-r--r--html/images/pg-lego-console-thumb.pngbin0 -> 5648 bytes
-rw-r--r--html/images/pg-lego-console.pngbin0 -> 5992 bytes
-rw-r--r--html/images/pg-lego-screenshot.pngbin0 -> 32219 bytes
-rw-r--r--html/images/pg-lego-thumb.pngbin0 -> 10979 bytes
-rw-r--r--html/images/pg-text.gifbin0 -> 7956 bytes
-rw-r--r--html/images/portrait-thumb.jpgbin0 -> 6220 bytes
-rw-r--r--html/images/portrait.jpgbin0 -> 84799 bytes
-rw-r--r--html/images/silverrule.gifbin0 -> 4612 bytes
-rw-r--r--html/images/vh40.gifbin0 -> 906 bytes
-rw-r--r--html/images/whip-thumb.jpgbin0 -> 5270 bytes
-rw-r--r--html/images/whip.jpgbin0 -> 67684 bytes
-rw-r--r--html/images/whole-man-thumb.jpgbin0 -> 5714 bytes
-rw-r--r--html/images/whole-man.jpgbin0 -> 63335 bytes
-rw-r--r--html/index.php9
-rw-r--r--html/index.shtml3
-rw-r--r--html/kit5
-rw-r--r--html/kit.html5
-rw-r--r--html/kit.php49
-rw-r--r--html/links5
-rw-r--r--html/links.html71
-rw-r--r--html/mailinglist99
-rw-r--r--html/mailinglist.html6
-rw-r--r--html/main5
-rw-r--r--html/main.html154
-rw-r--r--html/mission.html136
-rw-r--r--html/news5
-rw-r--r--html/news.html28
-rw-r--r--html/notes.txt56
-rw-r--r--html/oldnews.html383
-rw-r--r--html/oldrel.php141
-rw-r--r--html/papers/pgoutline.pdfbin0 -> 203019 bytes
-rw-r--r--html/papers/pgoutline.ps.gzbin0 -> 200909 bytes
-rw-r--r--html/papers/pgtalk.pdfbin0 -> 1075411 bytes
-rw-r--r--html/projects.html96
-rw-r--r--html/projects/acs.html36
-rw-r--r--html/projects/coqfile.html22
-rw-r--r--html/projects/coqpbp.html17
-rw-r--r--html/projects/corba.html37
-rw-r--r--html/projects/hol.html40
-rw-r--r--html/projects/isapbp.html25
-rw-r--r--html/projects/mm.html23
-rw-r--r--html/projects/outline.html26
-rw-r--r--html/projects/pgip.html22
-rw-r--r--html/projects/pgml.html26
-rw-r--r--html/projects/reelcase.html34
-rw-r--r--html/projects/scrgen.html26
-rw-r--r--html/projects/test.html24
-rw-r--r--html/projects/thybrowse.html34
-rw-r--r--html/projects/webreplay.html24
-rw-r--r--html/projects/xmlpgip.html40
-rw-r--r--html/proofgen.css136
-rw-r--r--html/register110
-rw-r--r--html/register.html110
-rw-r--r--html/screenshot9
-rw-r--r--html/screenshot.html108
-rw-r--r--html/smallheader.html8
-rw-r--r--html/smallpage.html6
-rw-r--r--html/smallpage.php12
-rw-r--r--images/.cvsignore4
-rw-r--r--images/Makefile100
-rw-r--r--images/ProofGeneral.8bit.gifbin0 -> 16547 bytes
-rw-r--r--images/ProofGeneral.gifbin0 -> 18165 bytes
-rw-r--r--images/ProofGeneral.jpgbin0 -> 16123 bytes
-rw-r--r--images/ProofGeneral.xcfbin0 -> 80632 bytes
-rw-r--r--images/README16
-rw-r--r--images/abort.8bit.xpm44
-rw-r--r--images/abort.xcfbin0 -> 1865 bytes
-rw-r--r--images/abort.xpm71
-rw-r--r--images/blank.xcfbin0 -> 266 bytes
-rw-r--r--images/command.8bit.xpm44
-rw-r--r--images/command.xcfbin0 -> 2828 bytes
-rw-r--r--images/command.xpm336
-rw-r--r--images/context.8bit.xpm44
-rw-r--r--images/context.xcfbin0 -> 2816 bytes
-rw-r--r--images/context.xpm180
-rw-r--r--images/coq-badge.xcfbin0 -> 120521 bytes
-rw-r--r--images/find.8bit.xpm44
-rw-r--r--images/find.xcfbin0 -> 3137 bytes
-rw-r--r--images/find.xpm259
-rw-r--r--images/fireworks.xcfbin0 -> 99268 bytes
-rw-r--r--images/gimp/.cvsignore5
-rw-r--r--images/gimp/scripts/proofgeneral.scm98
-rw-r--r--images/goal.8bit.xpm44
-rw-r--r--images/goal.xcfbin0 -> 3573 bytes
-rw-r--r--images/goal.xpm586
-rw-r--r--images/goal_large.xcfbin0 -> 194264 bytes
-rw-r--r--images/goto.8bit.xpm44
-rw-r--r--images/goto.xcfbin0 -> 2230 bytes
-rw-r--r--images/goto.xpm106
-rw-r--r--images/help.8bit.xpm44
-rw-r--r--images/help.xcfbin0 -> 3708 bytes
-rw-r--r--images/help.xpm368
-rw-r--r--images/info.8bit.xpm44
-rw-r--r--images/info.xcfbin0 -> 2656 bytes
-rw-r--r--images/info.xpm113
-rw-r--r--images/interrupt.8bit.xpm44
-rw-r--r--images/interrupt.xcfbin0 -> 2063 bytes
-rw-r--r--images/interrupt.xpm87
-rw-r--r--images/isabelle-badge.xcfbin0 -> 157845 bytes
-rw-r--r--images/isabelle_transparent.8bit.gifbin0 -> 7407 bytes
-rw-r--r--images/isabelle_transparent.gifbin0 -> 9365 bytes
-rw-r--r--images/isabelle_transparent.xcfbin0 -> 37982 bytes
-rw-r--r--images/lego-badge.xcfbin0 -> 135157 bytes
-rw-r--r--images/next.8bit.xpm44
-rw-r--r--images/next.xcfbin0 -> 1118 bytes
-rw-r--r--images/next.xpm59
-rw-r--r--images/notes.txt100
-rw-r--r--images/pg-text.8bit.gifbin0 -> 5859 bytes
-rw-r--r--images/pg-text.gifbin0 -> 7956 bytes
-rw-r--r--images/pg-text.jpgbin0 -> 7784 bytes
-rw-r--r--images/pg-text.xcfbin0 -> 38464 bytes
-rw-r--r--images/pgicon.pngbin0 -> 4213 bytes
-rw-r--r--images/pgmini.xpm241
-rw-r--r--images/qed.8bit.xpm44
-rw-r--r--images/qed.xcfbin0 -> 3613 bytes
-rw-r--r--images/qed.xpm573
-rw-r--r--images/restart.8bit.xpm44
-rw-r--r--images/restart.xcfbin0 -> 1312 bytes
-rw-r--r--images/restart.xpm55
-rw-r--r--images/retract.8bit.xpm44
-rw-r--r--images/retract.xcfbin0 -> 1673 bytes
-rw-r--r--images/retract.xpm62
-rw-r--r--images/state.8bit.xpm44
-rw-r--r--images/state.xcfbin0 -> 2761 bytes
-rw-r--r--images/state.xpm180
-rw-r--r--images/undo.8bit.xpm44
-rw-r--r--images/undo.xcfbin0 -> 1135 bytes
-rw-r--r--images/undo.xpm59
-rw-r--r--images/use.8bit.xpm44
-rw-r--r--images/use.xcfbin0 -> 1575 bytes
-rw-r--r--images/use.xpm62
-rw-r--r--isa/BUGS50
-rw-r--r--isa/Example-Xsym.ML15
-rw-r--r--isa/Example.ML13
-rw-r--r--isa/Example.thy10
-rw-r--r--isa/Example2.ML15
-rw-r--r--isa/README33
-rw-r--r--isa/depends.ML100
-rw-r--r--isa/interface236
-rw-r--r--isa/interface-setup.el48
-rw-r--r--isa/isa-syntax.el304
-rw-r--r--isa/isa.el765
-rw-r--r--isa/isabelle-system.el382
-rw-r--r--isa/thy-mode.el1047
-rw-r--r--isa/todo84
-rw-r--r--isa/x-symbol-isabelle.el410
-rw-r--r--isar/BUGS7
-rw-r--r--isar/Example.thy49
-rw-r--r--isar/README35
-rw-r--r--isar/interface236
-rw-r--r--isar/isar-keywords.el396
-rw-r--r--isar/isar-syntax.el392
-rw-r--r--isar/isar.el564
-rw-r--r--isar/todo20
-rw-r--r--lego/BUGS53
-rw-r--r--lego/README37
-rw-r--r--lego/example.l15
-rw-r--r--lego/example2.l1
-rw-r--r--lego/lego-syntax.el117
-rw-r--r--lego/lego.el445
-rw-r--r--lego/legotags91
-rw-r--r--lego/readonly/readonly.l1
-rw-r--r--lego/todo44
-rw-r--r--lego/x-symbol-lego.el82
-rw-r--r--papers/README4
-rw-r--r--phox/.cvsignore12
-rw-r--r--phox/README17
-rw-r--r--phox/example.phx22
-rw-r--r--phox/phox-extraction.el170
-rw-r--r--phox/phox-font.el87
-rw-r--r--phox/phox-fun.el427
-rw-r--r--phox/phox-outline.el57
-rw-r--r--phox/phox-sym-lock.el363
-rw-r--r--phox/phox-tags.el119
-rw-r--r--phox/phox.el256
-rw-r--r--plastic/README13
-rw-r--r--plastic/plastic-syntax.el118
-rw-r--r--plastic/plastic.el684
-rw-r--r--plastic/test.lf64
-rw-r--r--plastic/todo10
-rw-r--r--todo958
-rw-r--r--twelf/README27
-rw-r--r--twelf/example.elf64
-rw-r--r--twelf/twelf-font.el444
-rw-r--r--twelf/twelf-old.el2661
-rw-r--r--twelf/twelf.el208
-rw-r--r--twelf/x-symbol-twelf.el87
393 files changed, 55698 insertions, 0 deletions
diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 00000000..694eb3fa
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,2 @@
+nohup.out
+TAGS
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 00000000..0dccdeb4
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,24 @@
+Current Authors/Maintainers:
+
+ David Aspinall <da@dcs.ed.ac.uk>
+ doc, etc, generic, html, images, isa, demoisa
+ Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+ isar
+ Paul Callaghan <P.C.Callaghan@durham.ac.uk>
+ plastic, lego
+ Pierre Courtieu <courtieu@lri.fr>
+ coq
+ Christoph Rafalli <Christophe.Raffalli@univ-savoie.fr>
+ phox
+
+Previous Authors:
+
+ Thomas Kleymann (lego, doc, generic)
+ Healfdene Goguen (coq, generic, doc)
+ Dilip Sequeira (lego)
+ Patrick Loiseleur (coq)
+
+Assistance also from:
+
+ David von Oheimb (x-symbol)
+
diff --git a/BUGS b/BUGS
new file mode 100644
index 00000000..f230ab8b
--- /dev/null
+++ b/BUGS
@@ -0,0 +1,146 @@
+-*- outline -*-
+
+* Known Bugs and Workarounds for Proof General.
+
+Contact: mailto:bugs@proofgeneral.org
+See also: http://www.proofgeneral.org/ProofGeneral/BUGS
+
+Generic bugs are listed here, which may affect all of the supported
+provers. See lego/BUGS coq/BUGS, etc, for specific bug lists for each
+of the provers supported.
+
+The bugs here are split into problems which apply for all Emacs
+versions, and those which only apply to particular versions.
+
+
+* Generic problems, for all Emacs versions
+
+** Visibility control doesn't distinguish theorems with same name.
+
+If you have more than one theorem with the same name in a buffer,
+their proof visibilities are controlled together.
+
+** If the proof assistant goes into a loop displaying lots of information
+
+It may be difficult or impossible to interrupt it, because Emacs
+doesn't get a chance to process the C-c C-c keypress or "Stop" button
+push (or anything else). In this situation, you will need to send an
+interrupt to the (e.g.) Isabelle process from another shell. If that
+doesn't stop things, you can try 'kill -FPE <emacs-pid>'.
+This problem can happen with looping rewrite rules in the Isabelle
+simplifier, when tracing rewriting. It seems to be worse on
+certain architectures, and slower machines.
+
+** Toolbar enablers for XEmacs 21, some artefacts.
+
+ There is a timing issue, so that occasionally the buttons are
+ disabled/enabled when they shouldn't be. An extra click on the
+ toolbar solves this.
+
+** Using C-g can leave script management in a mess.
+
+ The code is not fully protected from Emacs interrupts.
+ Workaround: Don't type C-g while script management is processing.
+ If you do, use proof-restart-scripting.
+
+** Outline-mode does not work in processed proof script files
+
+ Because of read-only restrictions of the protected region.
+ This is an inherent problem with outline because it works by
+ modifying the buffer.
+ Workaround: none, nevermind. (If it's hugely needed we could support
+ modified outline commands).
+
+** Multiple file scripting is slightly vulnerable.
+
+ Files are not locked when they are being read by the prover, so a long
+ file could be edited and saved as the prover is processing it,
+ resulting in a loss of synchronization between Emacs and the proof
+ assistant. Files ought to be coloured red while they are being
+ processed, just as single lines are. Workaround: be careful not
+ to edit a file as it is being read by the proof assistant!
+ (Only applies to Lego and Isabelle)
+
+** When proof-rsh-command is set to "ssh host", C-c C-c broken
+
+ The whole process may be killed instead of interrupted. This isn't a
+ bug in Proof General, but the behaviour of ssh. Try using rsh
+ instead, it is said to forward signals to the remote command.
+
+** In tty mode, the binding C-c C-RET has no effect.
+
+ Workaround: manually bind C-c RET to 'proof-goto-point instead.
+
+* Problems with particular Emacs versions
+
+** Emacs menus: options not updated dynamically, positions erratic, etc.
+
+Also, proof assistant specific menus only appear in scripting buffer.
+These are drawbacks with FSF Emacs menu support.
+
+** Emacs faces sometimes faulty, esp in console mode
+
+Emacs support is let down in console mode, because faces are not
+implemented there. (XEmacs can use colours and underline in console
+mode)
+
+** XEmacs 21.1.9 on Win32
+
+Some strange problems reading files with this version of Emacs. Gives
+spurious "end of internal input stream", or silently ignores parts of
+files. Example is coq/coq.el which reads in fine on Linux.
+Solution: use a more recent version of XEmacs.
+
+** If you have problems using Mule versions of FSF Emacs
+
+Beware setting standard-display-european: Pascal Brisset suggests
+adding this line to .emacs should help:
+
+ (setq process-coding-system-alist '(("" . no-conversion)))
+
+** Strict read only disabled by default in FSF Emacs.
+
+ Unfortunately strict read only is incompatible with font lock in
+ FSF Emacs, so it is disabled by default. Instead, you get a warning message
+ if the locked region is edited.
+
+** In FSFmacs, spurious "Region read only" errors
+
+ Same problem as above, different symptom.
+ When proof-strict-read-only is set and font lock is on, these
+ errors are given which break font lock.
+ Workaround: turn off proof-strict-read-only, font-lock, or for
+ the best of all possible worlds, switch to XEmacs.
+
+
+** XEmacs undo in the script buffer can edit the "uneditable region"
+
+ Test case: Insert some nonsense text after the locked region.
+ Kill the line. Process to the next command.
+ Press C-x u, nonsense text appears in locked region.
+ Workaround: take care with undo in XEmacs.
+
+** As of FSFmacs 20.3, multi-byte character codes are used.
+
+ This breaks some of the code in Proof General, which is turned off in
+ case the suspicious looking function
+ toggle-enable-multibyte-characters is present. The code that is
+ turned off deals with term markup for proof by pointing, which only
+ affects LEGO at the moment. This problem could affect forthcoming
+ versions of XEmacs (but hasn't as far as XEmacs 21.1). Can anybody
+ tell me if it affects Mule versions of Emacs? Workaround: for LEGO
+ pbp, use FSFmacs 20.2, or XEmacs 20.4/later.
+
+** XEmacs sometimes has strange start-up delays of several seconds.
+
+ Possibly due to face allocation, when running remotely and
+ displaying on an 8-bit display. One workaround (and in fact the
+ recommended way of working) is to run XEmacs locally and only
+ the proof assistant on your fast compute server, by setting
+ proof-rsh-command.
+
+
+
+
+
+
diff --git a/CHANGES b/CHANGES
new file mode 100644
index 00000000..b0d9490b
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,230 @@
+-*- outline -*-
+
+--- This is a development release of Proof General, ---
+--- some features may be incomplete or buggy. Please ---
+--- report any problems to da@dcs.ed.ac.uk, thanks. ---
+
+* Summary of Changes for Proof General 3.4pre from 3.3
+
+** Generic Changes
+
+*** Support added for GNU Emacs 21.
+
+ Toolbar and splash screen supported.
+
+ X-Symbol support in progress
+
+ Fontification (as ever) is tricky.
+ Current status for X-symbol:
+
+ broken in GNU Emacs 20(?), partly working in 21 (goals broken, script OK)
+ partly broken in XEmacs 21.4 (script buffer faulty, goals OK)
+ fully working in XEmacs 21.1
+
+ Future PG development will no longer support Emacs 20.
+
+
+*** Support for "tracing" buffers improved and enabled by default.
+
+ (Tracing is only deployed in Isabelle so far)
+
+ Compared with experimental tracing in PG 3.3, there is now only one
+ tracing buffer, treated somewhat like a response buffer.
+
+ Issues:
+
+ 1. Large volumes of output can cause Emacs to hog CPU spending
+ all its time processing the output (esp with fontifying and X-symbol
+ decoding). It becomes difficult to use normal editing commands,
+ even C-c C-c to interrupt the prover. Workaround: hitting C-g,
+ the Emacs quit key, will interrupt the prover in this state.
+ See manual for further description of this.
+
+ 2. Interrupt response may be lost in large volumes of output, when
+ using pty communication. Symptom is interrupt on C-g, but PG thinks
+ the prover is still busy. Workaround: hit return in the shell buffer,
+ or set proof-shell-process-connection-type to nil to use piped
+ communication.
+
+
+** Isabelle Changes
+
+ Isabelle/Isar syntax changes, other tweaks.
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------
+
+
+OLDER CHANGES
+=============
+
+
+* Summary of Changes for Proof General 3.3 from 3.2
+
+** Generic Changes
+
+*** Visibility control for completed proofs
+
+ You can make proofs invisible using a context sensitive menu
+ (right button on a completed proof), or as soon as they are
+ completed with the "Options -> Disappearing Proofs" option.
+ Two menu items "Show proofs" and "Hide proofs" apply to
+ all the completed proofs in the buffer.
+
+ NB: proofs of theorems with the same name are not
+ distinguished, their visibility is controlled together.
+
+*** Command to insert last output as comment in proof script.
+
+ Sometimes it is useful to paste some of the output from
+ goals or response buffer into the proof script. A new
+ function `pg-insert-last-output-as-comment' (C-c C-;)
+ inserts the last output and converts it into a comment
+ using `comment-region'.
+
+*** Changes to colours, mouse highlighting, echo help messages
+
+ Now `proof-locked-face' becomes a lighter cyan. This is
+ less obtrusive when editing proofs, but is not so visible
+ for demonstrating PG: if you prefer the old stronger colour,
+ customize the face to "lightsteelblue2" using
+ M-x customize-face RET proof-locked-face.
+
+ New face `proof-mouse-highlight-face' (default: darker blue
+ than locked region) is now used for mouse highlighting regions of
+ script. Less ugly than the previous default (green) highlight face.
+
+ Also, for XEmacs, there are now (trivial) help messages in echo
+ area describing the highlighted region under the mouse.
+
+*** Experimental features and new user option
+
+ There's a new user option `proof-experimental-features' which
+ is nil by default. If you set it to t, you will (maybe after
+ restarting Proof General) enable certain experimental features.
+
+ In this release, the experimental features are:
+
+ Context menu options to move spans up/down
+ Context menu dependency commands (Isabelle only, see below)
+
+ To customize this from the menu:
+
+ Proof General -> Customize -> User Options -> Experimental features
+
+*** Proof General startup script welcomes user
+
+ The "binary" (startup script) bin/proofgeneral now loads
+ PG and invokes a function to display a splash message,
+ which invites the user to load a file. A bit more
+ friendly than simply being confronted by a standard
+ XEmacs screen.
+
+*** Changes to Proof General RPM packaging mechanism
+
+ Can now build RPM packages with "rpm -ta" from tarball source.
+ RPM includes menu file and icons so that Proof General may
+ appear on your window system menus (tested under Linux Mandrake).
+ We no longer distribute an SRPM.
+
+*** Compatibility fixes.
+
+ Fixes for FSF Emacs and XEmacs 21.4
+
+ Better support for win32 versions of XEmacs (see README.windows).
+
+ Fixes for recent version 3.3g of X-Symbol (and note on
+ web page about using ~/.xemacs/xemacs-packages/ for install locn).
+
+*** Bug fixes.
+
+ XEmacs 21.1 has faulty implementation of buffer-syntactic-context,
+ workaround added. (Symptom was parsing breaking, giving unexpected
+ "I can't see any complete commands to process!" error message, esp
+ with strings broken across lines containing parentheses).
+
+ Fixed Emacs-confusion minibuffer contents switching bug. (Bug
+ was triggered by using toolbar while minibuffer active).
+
+** Coq Changes
+
+ Compatibility for V7 added.
+
+ Experimental enhancements to handling of compiled files and
+ file dependency. (Only tested with Coq 6.3.1: we need help
+ from Coq implementors to add primitive support in V7, please
+ appeal to them to help Proof General!).
+
+ 1) At the end of scripting foo.v (i.e. when activing scripting is
+ switched off), "Reset Initial. Compile Module <foo>" is
+ automatically issued. This clears the context and writes a .vo file,
+ to keep your .vo files up to date. It means that when using PG Coq,
+ you should use the correct commands ("Require foo.") to load all
+ the modules you depend on, so that scripting can continue in the
+ next file.
+
+ 2) PG tracks file dependencies by noticing "Reinterning" messages
+ from Coq. When a file "b.v" is processed which has a "Require a",
+ command, PG will try to find "a.v" and will automatically lock
+ it. (This part of the process is fragile, for two reasons: it
+ is hard to find the directory for a.v, since Coq doesn't report
+ it, and the reinterning message is only issued the first time the
+ file is reinterned).
+
+ 3) When a file is retracted, PG attempts to automatically unlock
+ all the dependent files, by issuing a coqdep command to determine
+ the dependencies. (This is a rather nasty hack, it's hoped for
+ the future that Coq will support this functionality directly).
+
+ This functionality is enabled with the Coq settings option
+ "Auto Compile Vos".
+
+ Whole goals output is displayed. (Improvement suggested by
+ Robert Schneck).
+
+** Isabelle Changes
+
+ Support for theorem dependency tracking: context-sensitive menu
+ (right button on a completed proof) provides a facility for browsing
+ the ancestors and child theorems of a theorem, and highlighting them.
+
+ The idea of this feature is that it can help you untangle and
+ rearrange big proof scripts, by seeing which parts are
+ interdependent.
+
+ This facility is not yet closely integrated with Isabelle and
+ relies on an auxiliary ML file which is only compatible with
+ Isabelle99-2. It is only supplied for Isabelle/classic.
+
+ To activate the feature, use the Isabelle setting option "Theorem
+ Dependencies." Notice that you need to switch this on *after*
+ starting an Isabelles session, and must switch on/off on every
+ restart. (This behaviour will improve once better integrated
+ with Isabelle).
+
+ NB this is classed as an experimental feature, so you must set
+ proof-experimental-features to enable it.
+
+ Not yet documented. Comments and suggestions welcome.
+
+
+** Changes for developers to note
+
+*** proof-shell-process-output now sets proof-shell-last-output and
+ proof-shell-last-output-kind which gives clearer interface internally
+ and with rest of code. See docs.
+
+*** Support for "tracing" buffers added.
+ This was added for Isabelle's simplifier tracing, when a large
+ amount of output is produced during a proof for debugging.
+ The user would rather see the output as it arrives than wait
+ for a long time.
+ Experimental stage and not yet enabled for any prover.
+ See proof-shell-spill-output-regexp.
+ \ No newline at end of file
diff --git a/COPYING b/COPYING
new file mode 100644
index 00000000..e5a70db0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,26 @@
+Proof General is Copyright (C) 1998-2002 LFCS, University of Edinburgh.
+
+You are allowed to freely copy and modify this software, providing you
+observe these conditions:
+
+1. Title to and copyright of the Proof General system remains with the
+Laboratory for Foundations of Computer Science at the University of
+Edinburgh.
+
+2. Proof General may be used freely for research and educational
+purposes. For commercial purposes another license must be applied
+for.
+
+3. You accept Proof General "as is". The University of Edinburgh
+provides no warranty of any kind in respect of Proof General.
+Nevertheless you are encouraged to report to LFCS any problems with or
+suggestions for improvement of Proof General.
+
+4. You may freely modify Proof General on condition that any
+significant changes are notified to LFCS and made available to LFCS
+such that they may be incorporated within future releases of
+Proof General under these copying conditions.
+
+5. You will acknowledge LFCS and The University of Edinburgh as the
+designers and implementors of Proof General in any relevant document
+or publication.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 00000000..56defa21
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,2474 @@
+2002-02-14 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+2002-02-12 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/interface, isa/interface:
+ option -g GEOMETRY;
+
+ * isar/isar.el:
+ observe isar-undo-ignore-regexp in isar-count-undos and isar-find-and-forget;
+
+ * isar/isar-syntax.el:
+ added isar-undo-ignore-regexp;
+
+2002-02-08 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar.el:
+ more robust proof-shell-interrupt-regexp and proof-shell-error-regexp;
+
+2002-01-31 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * html/about.html:
+ Fix more broken front page links
+
+ * INSTALL: Update for recent releases.
+
+ * ChangeLog: Updated.
+
+ * generic/proof-script.el:
+ Simplify fix for repeated comments (commentre includes whitespace).
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/proof-syntax.el:
+ Tweak comment
+
+ * generic/proof-script.el:
+ Fix problem noticed with Isar and repeated comments.
+
+ * etc/isar/CommentParsingBug.thy:
+ New files.
+
+2002-01-31 David Aspinall <da@proofgeneral.org>
+
+ * html/about.html:
+ Fix more broken front page links
+
+ * INSTALL: Update for recent releases.
+
+ * ChangeLog: Updated.
+
+ * generic/proof-script.el:
+ Simplify fix for repeated comments (commentre includes whitespace).
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/proof-syntax.el:
+ Tweak comment
+
+ * generic/proof-script.el:
+ Fix problem noticed with Isar and repeated comments.
+
+ * etc/isar/CommentParsingBug.thy:
+ New files.
+
+2002-01-31 David Aspinall <da@proofgeneral.org>
+
+ * generic/proof-script.el:
+ Simplify fix for repeated comments (commentre includes whitespace).
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/proof-syntax.el:
+ Tweak comment
+
+ * generic/proof-script.el:
+ Fix problem noticed with Isar and repeated comments.
+
+ * etc/isar/CommentParsingBug.thy:
+ New files.
+
+2002-01-31 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/proof-syntax.el:
+ Tweak comment
+
+ * generic/proof-script.el:
+ Fix problem noticed with Isar and repeated comments.
+
+ * etc/isar/CommentParsingBug.thy:
+ New files.
+
+2002-01-26 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar-keywords.el: tuned comment;
+
+2002-01-21 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/isabelle-system.el:
+ full-proofs setting;
+
+ * isa/README, isar/README:
+ Isabelle2002 instead of Isabelle2001;
+
+2002-01-17 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * phox/.cvsignore:
+ *** empty log message ***
+
+2002-01-16 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * lego/example.l, isar/Example.thy, coq/example.v:
+ Whitespace
+
+ * generic/proof.el: Comments
+
+ * generic/proof-script.el:
+ Also bury trace buffer
+
+ * generic/proof-config.el: Comments
+
+ * isa/Example.ML: Whitespace
+
+ * generic/proof-shell.el:
+ Only create trace buffer if liable to be used. Remove experimental spill-output style tracing code.
+
+ * generic/proof-config.el, isar/isar.el, isa/isa.el:
+ Set proof-shell-trace-output-regexp in proof-pre-shell-start-hook
+
+ * isa/isa.el, isar/isar.el, generic/proof-config.el:
+ Rename proof-shell-spill-output-regexp -> proof-shell-trace-output-regexp
+
+ * doc/PG-adapting.texi:
+ FSF Emacs -> GNU Emacs
+
+ * doc/ProofGeneral.texi:
+ Document the tracing buffer; FSF Emacs -> GNU Emacs
+
+2002-01-16 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * lego/example.l, isar/Example.thy, coq/example.v:
+ Whitespace
+
+ * generic/proof.el: Comments
+
+ * generic/proof-script.el:
+ Also bury trace buffer
+
+ * generic/proof-config.el: Comments
+
+ * isa/Example.ML: Whitespace
+
+ * generic/proof-shell.el:
+ Only create trace buffer if liable to be used. Remove experimental spill-output style tracing code.
+
+ * generic/proof-config.el, isar/isar.el, isa/isa.el:
+ Set proof-shell-trace-output-regexp in proof-pre-shell-start-hook
+
+ * isa/isa.el, isar/isar.el, generic/proof-config.el:
+ Rename proof-shell-spill-output-regexp -> proof-shell-trace-output-regexp
+
+ * doc/PG-adapting.texi:
+ FSF Emacs -> GNU Emacs
+
+ * doc/ProofGeneral.texi:
+ Document the tracing buffer; FSF Emacs -> GNU Emacs
+
+2002-01-15 David Aspinall <da@proofgeneral.org>
+
+ * generic/proof-x-symbol.el:
+ Also put trace buffer in x sym mode
+
+ * ChangeLog: Updated.
+
+ * generic/proof-shell.el:
+ Remove defunct code
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/feedback.html: Deleted files.
+
+ * CHANGES:
+ Describe tracing improvements.
+
+ * generic/proof-utils.el:
+ windows-of-buffer -> get-buffer-window-list GNU name
+
+ * generic/proof-shell.el:
+ Inspect quit-flag when displaying tracing output; send an interrupt to the prover if set.
+
+ * generic/proof-shell.el:
+ Redisplay during tracing output on XEmacs
+
+ * html/projects.html, html/download.html, html/gallery.php, html/links.html, html/main.html, html/oldnews.html:
+ Fix link to feedback page
+
+2002-01-15 David Aspinall <da@proofgeneral.org>
+
+ * generic/proof-shell.el:
+ Remove defunct code
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/feedback.html: Deleted files.
+
+ * CHANGES:
+ Describe tracing improvements.
+
+ * generic/proof-utils.el:
+ windows-of-buffer -> get-buffer-window-list GNU name
+
+ * generic/proof-shell.el:
+ Inspect quit-flag when displaying tracing output; send an interrupt to the prover if set.
+
+ * generic/proof-shell.el:
+ Redisplay during tracing output on XEmacs
+
+ * html/projects.html, html/download.html, html/gallery.php, html/links.html, html/main.html, html/oldnews.html:
+ Fix link to feedback page
+
+2002-01-14 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * etc/isar/trace_simp.thy: tuned;
+
+ * etc/isar/trace_simp.thy:
+ some test cases for trace_simp output;
+
+2002-01-11 David Aspinall <da@proofgeneral.org>
+
+ * COPYING: Fix numbering
+
+ * CHANGES: Fix number
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+2002-01-11 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+2001-12-27 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/Example.thy: tuned;
+
+ * isa/isabelle-system.el:
+ trace_rules flag;
+
+ * isar/BUGS, isa/README, isar/README, isar/todo:
+ updated;
+
+ * generic/README: fixed spelling;
+
+2001-12-21 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar.el:
+ do not set proof-shell-quit-cmd (admits persistent sessions);
+
+2001-12-12 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/interface, isa/interface:
+ incorporate smart X11 font installation (used to be in isatool installfonts);
+
+2001-12-11 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * html/develdownload.php, html/main.html:
+ Be politically correct about FSF GNU Emacs; update to mention version 21.
+
+ * html/news.html, html/oldnews.html:
+ fix links to devel download.
+
+ * ChangeLog: Updated.
+
+ * html/news.html:
+ News item about Emacs 21 support
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * CHANGES:
+ Note about Emacs 21 support and font lock.
+
+ * generic/proof-utils.el:
+ Protect XEmacs only code
+
+ * generic/proof-site.el:
+ Fix test for GNU 21
+
+ * generic/proof-script.el:
+ Change to font-lock support routines.
+
+ * generic/proof-menu.el:
+ Disable customize-menu-create for Emacs 21.
+
+ * generic/proof-utils.el:
+ Rework font-lock variable munging to work in GNU Emacs 21 also.
+
+ * generic/proof-shell.el: Missing paren
+
+ * generic/proof-config.el:
+ Remove double setting, leave test setting in.
+
+ * generic/proof-shell.el:
+ Simplify -goals-config-done and -response-config-done to use current buffer. Kill trace buffer with other associated buffers, and set specifiers similarly for multiple frames.
+
+ * generic/proof-config.el:
+ Added proof-trace-output-fontify-enable
+
+ * CHANGES: Note of Emacs 21 support
+
+ * generic/proof-toolbar.el:
+ Add support for toolbars on Emacs 21.
+
+ * generic/proof-splash.el:
+ Add support for Emacs 21 image display.
+
+ * generic/proof-site.el:
+ Add proof-running-on-Emacs21 flag.
+
+ * generic/proof-menu.el:
+ Allow toolbar toggle for GNU Emacs 21.
+
+ * html/features.html, generic/proof-config.el:
+ Toolbar allowed in GNU Emacs 21
+
+ * generic/proof-compat.el:
+ Add proof-emacs-imagep function for GNU Emacs 21.
+
+2001-12-11 David Aspinall <da@proofgeneral.org>
+
+ * html/develdownload.php, html/main.html:
+ Be politically correct about FSF GNU Emacs; update to mention version 21.
+
+ * html/news.html, html/oldnews.html:
+ fix links to devel download.
+
+ * ChangeLog: Updated.
+
+ * html/news.html:
+ News item about Emacs 21 support
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * CHANGES:
+ Note about Emacs 21 support and font lock.
+
+ * generic/proof-utils.el:
+ Protect XEmacs only code
+
+ * generic/proof-site.el:
+ Fix test for GNU 21
+
+ * generic/proof-script.el:
+ Change to font-lock support routines.
+
+ * generic/proof-menu.el:
+ Disable customize-menu-create for Emacs 21.
+
+ * generic/proof-utils.el:
+ Rework font-lock variable munging to work in GNU Emacs 21 also.
+
+ * generic/proof-shell.el: Missing paren
+
+ * generic/proof-config.el:
+ Remove double setting, leave test setting in.
+
+ * generic/proof-shell.el:
+ Simplify -goals-config-done and -response-config-done to use current buffer. Kill trace buffer with other associated buffers, and set specifiers similarly for multiple frames.
+
+ * generic/proof-config.el:
+ Added proof-trace-output-fontify-enable
+
+ * CHANGES: Note of Emacs 21 support
+
+ * generic/proof-toolbar.el:
+ Add support for toolbars on Emacs 21.
+
+ * generic/proof-splash.el:
+ Add support for Emacs 21 image display.
+
+ * generic/proof-site.el:
+ Add proof-running-on-Emacs21 flag.
+
+ * generic/proof-menu.el:
+ Allow toolbar toggle for GNU Emacs 21.
+
+ * html/features.html, generic/proof-config.el:
+ Toolbar allowed in GNU Emacs 21
+
+ * generic/proof-compat.el:
+ Add proof-emacs-imagep function for GNU Emacs 21.
+
+2001-12-11 David Aspinall <da@proofgeneral.org>
+
+ * html/news.html:
+ News item about Emacs 21 support
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * CHANGES:
+ Note about Emacs 21 support and font lock.
+
+ * generic/proof-utils.el:
+ Protect XEmacs only code
+
+ * generic/proof-site.el:
+ Fix test for GNU 21
+
+ * generic/proof-script.el:
+ Change to font-lock support routines.
+
+ * generic/proof-menu.el:
+ Disable customize-menu-create for Emacs 21.
+
+ * generic/proof-utils.el:
+ Rework font-lock variable munging to work in GNU Emacs 21 also.
+
+ * generic/proof-shell.el: Missing paren
+
+ * generic/proof-config.el:
+ Remove double setting, leave test setting in.
+
+ * generic/proof-shell.el:
+ Simplify -goals-config-done and -response-config-done to use current buffer. Kill trace buffer with other associated buffers, and set specifiers similarly for multiple frames.
+
+ * generic/proof-config.el:
+ Added proof-trace-output-fontify-enable
+
+ * CHANGES: Note of Emacs 21 support
+
+ * generic/proof-toolbar.el:
+ Add support for toolbars on Emacs 21.
+
+ * generic/proof-splash.el:
+ Add support for Emacs 21 image display.
+
+ * generic/proof-site.el:
+ Add proof-running-on-Emacs21 flag.
+
+ * generic/proof-menu.el:
+ Allow toolbar toggle for GNU Emacs 21.
+
+ * html/features.html, generic/proof-config.el:
+ Toolbar allowed in GNU Emacs 21
+
+ * generic/proof-compat.el:
+ Add proof-emacs-imagep function for GNU Emacs 21.
+
+2001-12-11 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * CHANGES:
+ Note about Emacs 21 support and font lock.
+
+ * generic/proof-utils.el:
+ Protect XEmacs only code
+
+ * generic/proof-site.el:
+ Fix test for GNU 21
+
+ * generic/proof-script.el:
+ Change to font-lock support routines.
+
+ * generic/proof-menu.el:
+ Disable customize-menu-create for Emacs 21.
+
+ * generic/proof-utils.el:
+ Rework font-lock variable munging to work in GNU Emacs 21 also.
+
+ * generic/proof-shell.el: Missing paren
+
+ * generic/proof-config.el:
+ Remove double setting, leave test setting in.
+
+ * generic/proof-shell.el:
+ Simplify -goals-config-done and -response-config-done to use current buffer. Kill trace buffer with other associated buffers, and set specifiers similarly for multiple frames.
+
+ * generic/proof-config.el:
+ Added proof-trace-output-fontify-enable
+
+ * CHANGES: Note of Emacs 21 support
+
+ * generic/proof-toolbar.el:
+ Add support for toolbars on Emacs 21.
+
+ * generic/proof-splash.el:
+ Add support for Emacs 21 image display.
+
+ * generic/proof-site.el:
+ Add proof-running-on-Emacs21 flag.
+
+ * generic/proof-menu.el:
+ Allow toolbar toggle for GNU Emacs 21.
+
+ * html/features.html, generic/proof-config.el:
+ Toolbar allowed in GNU Emacs 21
+
+ * generic/proof-compat.el:
+ Add proof-emacs-imagep function for GNU Emacs 21.
+
+2001-12-10 David Aspinall <da@proofgeneral.org>
+
+ * generic/proof-utils.el, generic/proof-shell.el:
+ Add handling of proof-trace-buffer.
+
+ * generic/proof.el:
+ Added proof-trace-buffer.
+
+ * generic/proof-utils.el, generic/proof-shell.el:
+ Dont return a fontified string in proof-response-buffer-display.
+
+2001-12-05 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * generic/proof-shell.el:
+ proof-release-lock: do not touch proof-shell-spill-output-buffer;
+ proof-shell-spill-output-begin: reuse existing buffer;
+
+ * isar/isar.el:
+ activate proof-shell-spill-output-regexp;
+
+2001-12-04 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * CHANGES: Update for 3.4pre
+
+ * html/devel.html:
+ Update mailing list address (point to web page)
+
+2001-12-04 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * doc/PG-adapting.texi:
+ update from make process;
+
+ * doc/ProofGeneral.texi, isar/isar.el:
+ isar specific commands for bold/sup/sub;
+
+ * isa/x-symbol-isabelle.el:
+ added symbols for alternative 0..9;
+
+2001-12-04 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * CHANGES: Update for 3.4pre
+
+ * html/devel.html:
+ Update mailing list address (point to web page)
+
+2001-12-04 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * doc/PG-adapting.texi:
+ update from make process;
+
+ * doc/ProofGeneral.texi, isar/isar.el:
+ isar specific commands for bold/sup/sub;
+
+ * isa/x-symbol-isabelle.el:
+ added symbols for alternative 0..9;
+
+2001-12-01 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/x-symbol-isabelle.el:
+ \<euro> symbol;
+ use previously defined x-symbol-isabelle-user-table (or nil);
+ x-symbol-user-table achieves electric |- and |= symbols;
+
+2001-11-24 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar.el:
+ proof-shell-spill-output-regexp temporarily disabled;
+
+2001-11-20 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar.el:
+ set proof-shell-spill-output-regexp;
+ isar-activate-scripting: proof-syn-cd (why is this here needed?);
+
+2001-11-13 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/interface, isar/interface:
+ option -k for logic specific isar-keywords file;
+
+2001-11-08 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/x-symbol-isabelle.el:
+ added \<index> symbol;
+
+2001-11-07 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/x-symbol-isabelle.el:
+ added \<lozenge> and \<struct>;
+
+ * isar/isar-syntax.el:
+ updated isar-goals-font-lock-keywords;
+
+2001-10-24 David Aspinall <da@proofgeneral.org>
+
+ * html/main.html:
+ Fix missing arg to get.
+ Add Paul Roziere as req'd by Christopphe Raffalli
+
+2001-10-13 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar-syntax.el:
+ isar-goals-font-lock-keywords: more general goal pattern;
+
+2001-10-08 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * CHANGES: Add back note.
+
+2001-10-08 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * CHANGES: Add back note.
+
+2001-10-04 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar.el:
+ added isar-help-induct-rules;
+
+2001-10-04 David Aspinall <da@proofgeneral.org>
+
+ * CHANGES: Remove note for devel
+
+ * generic/proof-toolbar.el:
+ Fix fudged enabler to call button function interactively.
+
+2001-09-26 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/x-symbol-isabelle.el:
+ support \<^bold> control symbols;
+
+ * generic/proof-config.el:
+ fixed spelling;
+
+2001-09-24 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * coq/coq.el:
+ Add Lemma to exclusion for coq-goal-command-p.
+
+ * doc/PG-adapting.texi: Update magic
+
+ * doc/docstring-magic.el: New line
+
+ * generic/proof-config.el:
+ Fix error in docs of stop-silent-command, and name of pre-shell-start-hook.
+
+ * doc/ProofGeneral.texi:
+ Another bug reporter
+
+ * generic/proof-shell.el:
+ Implement Robert Schnecks idea to help Coq display whole of goals output.
+
+ * CHANGES: Devel release is tweaked 3.3
+
+2001-09-24 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * coq/coq.el:
+ Add Lemma to exclusion for coq-goal-command-p.
+
+ * doc/PG-adapting.texi: Update magic
+
+ * doc/docstring-magic.el: New line
+
+ * generic/proof-config.el:
+ Fix error in docs of stop-silent-command, and name of pre-shell-start-hook.
+
+ * doc/ProofGeneral.texi:
+ Another bug reporter
+
+ * generic/proof-shell.el:
+ Implement Robert Schnecks idea to help Coq display whole of goals output.
+
+ * CHANGES: Devel release is tweaked 3.3
+
+2001-09-13 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * doc/PG-adapting.texi:
+ Link uref nicely
+
+ * doc/ProofGeneral.texi:
+ Minor improvements
+
+ * doc/ProofGeneral.texi:
+ Updates from an old printout of the manual
+
+ * todo: updated
+
+ * doc/PG-adapting.texi:
+ Updates from an old printout of the manual
+
+ * ChangeLog: Updated.
+
+ * html/Kit/Makefile: New files.
+
+ * html/Kit/dtd/pgip.dtd, html/Kit/dtd/pgml.dtd:
+ Updated from Kit repo
+
+ * html/download.html: Fix link
+
+ * html/smallpage.php:
+ Fix two more gaping holes letting people examine whole filesystem (also fixed in server anyway)
+
+ * html/feedback, html/feedback.html, html/develdownload, html/develdownload.html, html/kit.php, html/kit, html/kit.html:
+ PHP in php, html and no extn link to php
+
+ * ChangeLog: Updated.
+
+ * html/htmlshow.php:
+ Fix two more gaping holes letting people examine whole filesystem
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/feedback: Feedback quick link
+
+ * CHANGES: No changes msg
+
+ * html/kit.html, html/mailinglist.html, html/develdownload.html, html/doc.html, html/feedback.html, html/kit, html/.htaccess:
+ Try to fix PHP/html nonsense, by disabling SSI and enabling php for .html files
+
+2001-09-13 David Aspinall <da@proofgeneral.org>
+
+ * doc/PG-adapting.texi:
+ Link uref nicely
+
+ * doc/ProofGeneral.texi:
+ Minor improvements
+
+ * doc/ProofGeneral.texi:
+ Updates from an old printout of the manual
+
+ * todo: updated
+
+ * doc/PG-adapting.texi:
+ Updates from an old printout of the manual
+
+ * ChangeLog: Updated.
+
+ * html/Kit/Makefile: New files.
+
+ * html/Kit/dtd/pgip.dtd, html/Kit/dtd/pgml.dtd:
+ Updated from Kit repo
+
+ * html/download.html: Fix link
+
+ * html/smallpage.php:
+ Fix two more gaping holes letting people examine whole filesystem (also fixed in server anyway)
+
+ * html/feedback, html/feedback.html, html/develdownload, html/develdownload.html, html/kit.php, html/kit, html/kit.html:
+ PHP in php, html and no extn link to php
+
+ * ChangeLog: Updated.
+
+ * html/htmlshow.php:
+ Fix two more gaping holes letting people examine whole filesystem
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/feedback: Feedback quick link
+
+ * CHANGES: No changes msg
+
+ * html/kit.html, html/mailinglist.html, html/develdownload.html, html/doc.html, html/feedback.html, html/kit, html/.htaccess:
+ Try to fix PHP/html nonsense, by disabling SSI and enabling php for .html files
+
+2001-09-13 David Aspinall <da@proofgeneral.org>
+
+ * html/Kit/Makefile: New files.
+
+ * html/Kit/dtd/pgip.dtd, html/Kit/dtd/pgml.dtd:
+ Updated from Kit repo
+
+ * html/download.html: Fix link
+
+ * html/smallpage.php:
+ Fix two more gaping holes letting people examine whole filesystem (also fixed in server anyway)
+
+ * html/feedback, html/feedback.html, html/develdownload, html/develdownload.html, html/kit.php, html/kit, html/kit.html:
+ PHP in php, html and no extn link to php
+
+ * ChangeLog: Updated.
+
+ * html/htmlshow.php:
+ Fix two more gaping holes letting people examine whole filesystem
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/feedback: Feedback quick link
+
+ * CHANGES: No changes msg
+
+ * html/kit.html, html/mailinglist.html, html/develdownload.html, html/doc.html, html/feedback.html, html/kit, html/.htaccess:
+ Try to fix PHP/html nonsense, by disabling SSI and enabling php for .html files
+
+2001-09-13 David Aspinall <da@proofgeneral.org>
+
+ * html/htmlshow.php:
+ Fix two more gaping holes letting people examine whole filesystem
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/feedback: Feedback quick link
+
+ * CHANGES: No changes msg
+
+ * html/kit.html, html/mailinglist.html, html/develdownload.html, html/doc.html, html/feedback.html, html/kit, html/.htaccess:
+ Try to fix PHP/html nonsense, by disabling SSI and enabling php for .html files
+
+2001-09-13 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/feedback: Feedback quick link
+
+ * CHANGES: No changes msg
+
+ * html/kit.html, html/mailinglist.html, html/develdownload.html, html/doc.html, html/feedback.html, html/kit, html/.htaccess:
+ Try to fix PHP/html nonsense, by disabling SSI and enabling php for .html files
+
+2001-09-10 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * etc/release-log.txt:
+ Note about re-rel 3.3
+
+ * html/download.html, html/news.html:
+ Update release dates
+
+ * todo: Update todo
+
+ * doc/ProofGeneral.texi:
+ Remove spurious comment at start
+
+2001-09-10 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar-syntax.el:
+ isar-goals-font-lock-keywords: corollary;
+
+2001-09-10 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * etc/release-log.txt:
+ Note about re-rel 3.3
+
+ * html/download.html, html/news.html:
+ Update release dates
+
+ * todo: Update todo
+
+ * doc/ProofGeneral.texi:
+ Remove spurious comment at start
+
+2001-09-10 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar-syntax.el:
+ isar-goals-font-lock-keywords: corollary;
+
+2001-09-09 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * ChangeLog: Updated.
+
+ * html/hits, html/hits.html:
+ Renamed file
+
+ * Makefile.devel:
+ Fixup copying of releasename link
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel: Finished shift to 3.4
+
+ * html/kit: Link to kit.php
+
+ * html/kit.html, html/kit.php:
+ File determination nonsense
+
+ * html/download.html:
+ Change over to some .php files.
+
+ * CHANGES:
+ Backtrack to previous CHANGES file for now.
+
+ * coq/README, lego/README:
+ Coq/lego confusion
+
+ * coq/BUGS:
+ Bug in new parsing for coq, mention
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel: Update for 3.4pre
+
+ * html/footer.html:
+ Remove validation stamp from footer, since its a lie.
+
+ * CHANGES: No changes yet
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/download.html: Trim page a bit
+
+ * html/news.html, html/oldnews.html:
+ Announce 3.3
+
+ * html/doc.html: Release 3-3.
+
+ * etc/release-log.txt:
+ Release date of 3-3.
+
+ * html/download.html:
+ Mention paper letter registrations.
+
+ * html/download.html:
+ Remove to be released line
+
+ * doc/PG-adapting.texi: Update docs.
+
+2001-09-09 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * ChangeLog: Updated.
+
+ * html/hits, html/hits.html:
+ Renamed file
+
+ * Makefile.devel:
+ Fixup copying of releasename link
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel: Finished shift to 3.4
+
+ * html/kit: Link to kit.php
+
+ * html/kit.html, html/kit.php:
+ File determination nonsense
+
+ * html/download.html:
+ Change over to some .php files.
+
+ * CHANGES:
+ Backtrack to previous CHANGES file for now.
+
+ * coq/README, lego/README:
+ Coq/lego confusion
+
+ * coq/BUGS:
+ Bug in new parsing for coq, mention
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel: Update for 3.4pre
+
+ * html/footer.html:
+ Remove validation stamp from footer, since its a lie.
+
+ * CHANGES: No changes yet
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/download.html: Trim page a bit
+
+ * html/news.html, html/oldnews.html:
+ Announce 3.3
+
+ * html/doc.html: Release 3-3.
+
+ * etc/release-log.txt:
+ Release date of 3-3.
+
+ * html/download.html:
+ Mention paper letter registrations.
+
+ * html/download.html:
+ Remove to be released line
+
+ * doc/PG-adapting.texi: Update docs.
+
+2001-09-09 David Aspinall <da@proofgeneral.org>
+
+ * html/hits, html/hits.html:
+ Renamed file
+
+ * Makefile.devel:
+ Fixup copying of releasename link
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel: Finished shift to 3.4
+
+ * html/kit: Link to kit.php
+
+ * html/kit.html, html/kit.php:
+ File determination nonsense
+
+ * html/download.html:
+ Change over to some .php files.
+
+ * CHANGES:
+ Backtrack to previous CHANGES file for now.
+
+ * coq/README, lego/README:
+ Coq/lego confusion
+
+ * coq/BUGS:
+ Bug in new parsing for coq, mention
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel: Update for 3.4pre
+
+ * html/footer.html:
+ Remove validation stamp from footer, since its a lie.
+
+ * CHANGES: No changes yet
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/download.html: Trim page a bit
+
+ * html/news.html, html/oldnews.html:
+ Announce 3.3
+
+ * html/doc.html: Release 3-3.
+
+ * etc/release-log.txt:
+ Release date of 3-3.
+
+ * html/download.html:
+ Mention paper letter registrations.
+
+ * html/download.html:
+ Remove to be released line
+
+ * doc/PG-adapting.texi: Update docs.
+
+2001-09-09 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel: Finished shift to 3.4
+
+ * html/kit: Link to kit.php
+
+ * html/kit.html, html/kit.php:
+ File determination nonsense
+
+ * html/download.html:
+ Change over to some .php files.
+
+ * CHANGES:
+ Backtrack to previous CHANGES file for now.
+
+ * coq/README, lego/README:
+ Coq/lego confusion
+
+ * coq/BUGS:
+ Bug in new parsing for coq, mention
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel: Update for 3.4pre
+
+ * html/footer.html:
+ Remove validation stamp from footer, since its a lie.
+
+ * CHANGES: No changes yet
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/download.html: Trim page a bit
+
+ * html/news.html, html/oldnews.html:
+ Announce 3.3
+
+ * html/doc.html: Release 3-3.
+
+ * etc/release-log.txt:
+ Release date of 3-3.
+
+ * html/download.html:
+ Mention paper letter registrations.
+
+ * html/download.html:
+ Remove to be released line
+
+ * doc/PG-adapting.texi: Update docs.
+
+2001-09-09 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel: Update for 3.4pre
+
+ * html/footer.html:
+ Remove validation stamp from footer, since its a lie.
+
+ * CHANGES: No changes yet
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/download.html: Trim page a bit
+
+ * html/news.html, html/oldnews.html:
+ Announce 3.3
+
+ * html/doc.html: Release 3-3.
+
+ * etc/release-log.txt:
+ Release date of 3-3.
+
+ * html/download.html:
+ Mention paper letter registrations.
+
+ * html/download.html:
+ Remove to be released line
+
+ * doc/PG-adapting.texi: Update docs.
+
+2001-09-09 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/download.html: Trim page a bit
+
+ * html/news.html, html/oldnews.html:
+ Announce 3.3
+
+ * html/doc.html: Release 3-3.
+
+ * etc/release-log.txt:
+ Release date of 3-3.
+
+ * html/download.html:
+ Mention paper letter registrations.
+
+ * html/download.html:
+ Remove to be released line
+
+ * doc/PG-adapting.texi: Update docs.
+
+2001-09-06 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/interface, isar/interface:
+ tuned usage;
+
+2001-09-05 David Aspinall <da@proofgeneral.org>
+
+ * doc/ProofGeneral.texi:
+ Mention pg-toggle-visibility and its keybinding
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/devel.html, generic/proof-site.el, html/develdownload.php:
+ Set version tag for new release.
+
+ * generic/pg-metadata.el: Incomplete
+
+ * doc/ProofGeneral.texi: Todo
+
+ * CHANGES, todo:
+ Updated
+
+ * generic/proof-menu.el:
+ Add keybindings for new commands for moving/navigating spans.
+
+ * generic/proof-script.el:
+ Fix problem with C-x C-v by copying buffer-file-name. Add children property to control spans.
+
+ * generic/pg-user.el:
+ Improved span moving and navigation commands.
+
+2001-09-05 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/devel.html, generic/proof-site.el, html/develdownload.php:
+ Set version tag for new release.
+
+ * generic/pg-metadata.el: Incomplete
+
+ * doc/ProofGeneral.texi: Todo
+
+ * CHANGES, todo:
+ Updated
+
+ * generic/proof-menu.el:
+ Add keybindings for new commands for moving/navigating spans.
+
+ * generic/proof-script.el:
+ Fix problem with C-x C-v by copying buffer-file-name. Add children property to control spans.
+
+ * generic/pg-user.el:
+ Improved span moving and navigation commands.
+
+2001-09-04 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/Example.thy: tuned proof text;
+ added script version;
+
+ * isa/interface, isar/interface:
+ added option -P: actually start Proof General (default true);
+
+2001-09-04 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/pg-xml.el:
+ Issue parsing messages
+
+ * generic/pg-user.el:
+ Add commands to move spans up/down. Enable features only if experimental flag set
+
+ * generic/proof-script.el:
+ Nested proof spans are duplicable
+
+ * generic/proof-config.el:
+ Add experimental features setting
+
+ * Makefile: Delete rogue elcs
+
+ * CHANGES, INSTALL:
+ Updates
+
+2001-09-04 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/README: tuned;
+
+ * isa/README, isar/README:
+ no need to adjust the path to bash on the first line (due to /usr/bin/env);
+
+2001-09-04 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/pg-xml.el:
+ Issue parsing messages
+
+ * generic/pg-user.el:
+ Add commands to move spans up/down. Enable features only if experimental flag set
+
+ * generic/proof-script.el:
+ Nested proof spans are duplicable
+
+ * generic/proof-config.el:
+ Add experimental features setting
+
+ * Makefile: Delete rogue elcs
+
+ * CHANGES, INSTALL:
+ Updates
+
+2001-09-04 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/README: tuned;
+
+ * isa/README, isar/README:
+ no need to adjust the path to bash on the first line (due to /usr/bin/env);
+
+2001-09-03 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * README.devel: Text
+
+ * ChangeLog: Trim dups
+
+ * README.windows: Add author
+
+ * TODO, CHANGES:
+ Updated
+
+ * isa/Example.ML:
+ Accidental commit; revert to original.
+
+ * isar/isar.el:
+ Set proof-goal-with-hole-regexp
+
+ * generic/proof-config.el:
+ Change colour of locked region.
+
+ * generic/proof-shell.el:
+ Fix bracket bug.
+
+ * generic/proof-script.el:
+ Show/hide all proofs: add redisplay for FSF
+ Use new functions pg-set-span-helphighlights and pg-span-name
+ to set help echo, balloon help, mouse highlight, and context
+ menu.
+
+ * generic/proof-depends.el:
+ Use pg-set-span-helphightlights for unhighlighting.
+
+ * generic/pg-user.el:
+ Generalise context menu for other spans; grey out show/hide when unavailable.
+
+ * html/main.html: Join paras
+
+ * ChangeLog: Updated.
+
+ * html/features.html: Text
+
+ * html/features.html:
+ Fix link to screenshot
+
+ * html/doc.html: Improve layout
+
+ * doc/PG-adapting.texi, doc/ProofGeneral.texi:
+ Update version numbers, time stamps.
+
+ * html/download.html:
+ Typo. Update Emacs version to 20.7.
+
+ * ChangeLog: Updated.
+
+ * html/oldrel.php: Update branch
+
+ * html/download.html: PHP file
+
+ * html/oldrel.html, html/oldrel.php:
+ Renamed file
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/download.html:
+ Please try devel version
+
+ * bin/proofgeneral, demoisa/demoisa.el:
+ Accidental update; revert to previous
+
+ * demoisa/README: Rearrange
+
+ * twelf/twelf.el, twelf/x-symbol-twelf.el, twelf/twelf-old.el, plastic/todo, twelf/example.elf, twelf/README, twelf/twelf-font.el, plastic/plastic.el, plastic/plastic-syntax.el, plastic/test.lf, phox/phox.el, plastic/README, phox/phox-outline.el, phox/phox-sym-lock.el, phox/phox-tags.el, phox/example.phx, phox/phox-extraction.el, phox/phox-font.el, phox/phox-fun.el, lego/readonly/readonly.l, papers/README, phox/README, lego/legotags, lego/todo, lego/x-symbol-lego.el, lego/example2.l, lego/lego.el, lego/lego-syntax.el, lego/BUGS, lego/example.l, lego/README, isar/todo, isar/isar.el, isar/isar-keywords.el, isar/isar-syntax.el, isar/BUGS, isar/Example.thy, isar/interface, isar/README, isa/todo, isa/x-symbol-isabelle.el, isa/isabelle-system.el, isa/thy-mode.el, isa/isa.el, isa/interface, isa/interface-setup.el, isa/isa-syntax.el, isa/depends.ML, isa/Example2.ML, isa/README, isa/BUGS, isa/Example.ML, isa/Example.thy, isa/Example-Xsym.ML, images/gimp/.cvsignore, images/gimp/scripts/proofgeneral.scm, images/use.8bit.xpm, images/use.xcf, images/use.xpm, images/undo.8bit.xpm, images/undo.xcf, images/undo.xpm, images/retract.xpm, images/state.8bit.xpm, images/state.xcf, images/state.xpm, images/restart.xpm, images/retract.8bit.xpm, images/retract.xcf, images/qed.xpm, images/restart.8bit.xpm, images/restart.xcf, images/pgicon.png, images/pgmini.xpm, images/qed.8bit.xpm, images/qed.xcf, images/pg-text.xcf, images/pg-text.8bit.gif, images/pg-text.gif, images/pg-text.jpg, images/next.xcf, images/next.xpm, images/notes.txt, images/next.8bit.xpm, images/lego-badge.xcf, images/isabelle_transparent.8bit.gif, images/isabelle_transparent.gif, images/isabelle_transparent.xcf, images/isabelle-badge.xcf, images/info.xpm, images/interrupt.8bit.xpm, images/interrupt.xcf, images/interrupt.xpm, images/help.xpm, images/info.8bit.xpm, images/info.xcf, images/goto.xcf, images/goto.xpm, images/help.8bit.xpm, images/help.xcf, images/goto.8bit.xpm, images/goal_large.xcf, images/goal.8bit.xpm, images/goal.xcf, images/goal.xpm, images/find.xpm, images/fireworks.xcf, images/find.8bit.xpm, images/find.xcf, images/context.xpm, images/coq-badge.xcf, images/command.xcf, images/command.xpm, images/context.8bit.xpm, images/context.xcf, images/abort.xpm, images/blank.xcf, images/command.8bit.xpm, images/abort.8bit.xpm, images/abort.xcf, images/README, images/ProofGeneral.jpg, images/ProofGeneral.xcf, images/ProofGeneral.8bit.gif, images/ProofGeneral.gif, images/.cvsignore, images/Makefile, html/projects/test.html, html/projects/thybrowse.html, html/projects/webreplay.html, html/projects/xmlpgip.html, html/projects/pgip.html, html/projects/pgml.html, html/projects/reelcase.html, html/projects/scrgen.html, html/projects/hol.html, html/projects/isapbp.html, html/projects/mm.html, html/projects/outline.html, html/projects/coqfile.html, html/projects/coqpbp.html, html/projects/corba.html, html/projects/acs.html, html/papers/pgtalk.pdf, html/papers/pgoutline.ps.gz, html/papers/pgoutline.pdf, html/images/whole-man.jpg, html/images/whole-man-thumb.jpg, html/images/silverrule.gif, html/images/vh40.gif, html/images/whip.jpg, html/images/whip-thumb.jpg, html/images/pg-text.gif, html/images/portrait.jpg, html/images/portrait-thumb.jpg, html/images/pg-lego-console.png, html/images/pg-lego-screenshot.png, html/images/pg-lego-thumb.png, html/images/pg-isar-thumb.png, html/images/pg-lego-console-thumb.png, html/images/pg-isar-screenshot.png, html/images/pg-isa-screenshot.png, html/images/pg-isa-thumb.png, html/images/pg-coq-thumb.png, html/images/isabelle.gif, html/images/lego-badge.gif, html/images/pg-coq-screenshot.png, html/images/canvaswallpaper.jpg, html/images/coq-badge.gif, html/images/coqlogo4.gif, html/images/coqlogo4.xcf, html/images/isabelle-badge.gif, html/images/bullethole.gif, html/images/PG-small.jpg, html/images/ProofGeneral.jpg, html/images/.cvsignore, html/images/IsaPGscreen.jpg, .cvsignore, html/Kit/dtd/pgip.dtd, html/Kit/dtd/pgml.dtd, html/smallpage.php, html/screenshot.html, html/smallheader.html, html/smallpage.html, html/proofgen.css, html/register, html/register.html, html/screenshot, html/oldnews.html, html/oldrel.html, html/projects.html, html/news, html/news.html, html/notes.txt, html/main, html/main.html, html/mission.html, html/links, html/links.html, html/mailinglist, html/mailinglist.html, html/index.php, html/index.shtml, html/kit, html/kit.html, html/htmlshow.html, html/htmlshow.php, html/gallery.php, html/header.html, html/head.html, html/hits.html, html/fileshow.php, html/footer.html, html/functions.php3, html/gallery, html/features.html, html/feedback.html, html/feedback.php, html/download, html/download.html, html/elispmarkup.php3, html/features, html/develdownload.php, html/doc, html/doc.html, html/develdownload.html, html/cvsweb.conf, html/devel, html/devel.html, html/counter.php3, html/cvsweb.cgi, html/about, html/about.html, html/.cvsignore, html/ProofGeneralPortrait.eps.gz, hol98/example.sml, hol98/hol98.el, hol98/todo, hol98/x-symbol-hol98.el, generic/span.el, generic/texi-docstring-magic.el, hol98/README, generic/span-extent.el, generic/span-overlay.el, generic/proof.el, generic/proof-x-symbol.el, generic/proof-utils.el, generic/proof-syntax.el, generic/proof-system.el, generic/proof-toolbar.el, generic/proof-splash.el, generic/proof-site.el, generic/proof-shell.el, generic/proof-script.el, generic/proof-indent.el, generic/proof-menu.el, generic/proof-depends.el, generic/proof-easy-config.el, generic/proof-config.el, generic/proof-autoloads.el, generic/proof-compat.el, generic/pg-pgip.el, generic/pg-user.el, generic/pg-xml.el, etc/pgkit/xmltest1.xml, etc/pgkit/xmltest2.xml, generic/_pkg.el, generic/README, etc/patches/duplicated-short-messages-fix.txt, etc/patches/fix-attempt-for-eager-cleaning.txt, etc/lego/multiple/C.l, etc/lego/multiple/D.l, etc/lego/multiple/README, etc/lego/multiple/A.l, etc/lego/multiple/B.l, etc/lego/unsaved-goals.l, etc/lego/error-eg.l, etc/lego/lego-site.el, etc/lego/long-line-backslash.l, etc/isar/multiple/README, etc/lego/GoalGoal.l, etc/isar/multiple/A.thy, etc/isar/multiple/B.thy, etc/isar/multiple/C.thy, etc/isar/multiple/D.thy, etc/isar/bad1.thy, etc/isar/bad2.thy, etc/isar/README, etc/isar/XEmacsSyntacticContextProb.thy, etc/demoisa/README, etc/isar/Parsing.thy, etc/demoisa/A.ML, etc/demoisa/B.ML, etc/demoisa/C.ML, etc/demoisa/D.ML, etc/isa/multiple/foobar/foo.ML, etc/isa/thy/test.ML, etc/isa/multiple/D.thy, etc/isa/multiple/Err.ML, etc/isa/multiple/Err.thy, etc/isa/multiple/README, etc/isa/multiple/B.thy, etc/isa/multiple/C.ML, etc/isa/multiple/C.thy, etc/isa/multiple/D.ML, etc/isa/multiple/A.ML, etc/isa/multiple/A.thy, etc/isa/multiple/B.ML, etc/isa/depends/Usedepends.ML, etc/isa/depends/Usedepends.thy, etc/isa/depends/Fib.ML, etc/isa/depends/Fib.thy, etc/isa/depends/Primes.ML, etc/isa/depends/Primes.thy, etc/isa/\backslashname/test.ML, etc/isa/\backslashname/test.thy, etc/isa/long-line-backslash.ML, etc/isa/message-test.ML, etc/isa/settings.ML, etc/isa/xsym.ML, etc/coq/multiple/c.v, etc/isa/goal-matching.ML, etc/coq/multiple/a.v, etc/coq/multiple/b.v, etc/coq/multiple/.cvsignore, etc/coq/multiple/README, etc/coq/unnamed_thm.v, etc/testing-log.txt, etc/proofgeneral-domain.txt, etc/release-log.txt, etc/screenshot-notes.txt, etc/test-schedule.txt, etc/doc-notes.txt, etc/junk.el, etc/profiling.txt, etc/bug-notes.txt, etc/cvs-tips.txt, etc/debugging-tips.txt, etc/announce, etc/README, etc/TESTS, etc/ProofGeneral.menu, etc/ProofGeneral.spec, doc/dir, doc/docstring-magic.el, doc/localdir, doc/README.doc, doc/ProofGeneral.jpg, doc/ProofGeneral.texi, doc/Makefile.doc, doc/PG-adapting.texi, doc/.cvsignore, doc/Makefile, demoisa/demoisa-easy.el, demoisa/demoisa.el, coq/todo, coq/x-symbol-coq.el, demoisa/README, coq/coqtags, coq/example.v, coq/coq.el, coq/BUGS, coq/coq-syntax.el, coq/README, acl2/example.acl2, acl2/x-symbol-acl2.el, bin/proofgeneral, acl2/acl2.el, acl2/README, todo, README.devel, README.windows, REGISTER, TODO, Makefile.xemacs, README, Makefile, Makefile.devel, FAQ, INSTALL, ChangeLog, COPYING, BUGS, CHANGES, AUTHORS:
+ Updating branch
+
+ * doc/ProofGeneral.texi:
+ Note of what to do
+
+ * generic/proof-script.el: Formatting
+
+ * html/features.html:
+ Mention hiding proofs.
+
+ * etc/ProofGeneral.spec:
+ Add specific READMEs.
+
+ * etc/cvs-tips.txt:
+ Note of secure alt to no password
+
+ * etc/release-log.txt:
+ Ready for release
+
+ * etc/announce: Update for 3.3
+
+ * plastic/README, twelf/README, isa/README, isar/README, lego/README, phox/README, hol98/README, coq/README, generic/README, acl2/README:
+ Add specific install instrs, rearrange.
+
+ * INSTALL:
+ Move specific install instructions into subdirs
+
+ * isa/isa.el:
+ Add settings for testing trace buffers.
+
+ * CHANGES:
+ Note about tracing buffers for developers
+
+ * generic/proof-shell.el:
+ Added handling of tracing buffers using proof-shell-spill-output-regexp.
+
+ * generic/proof-config.el:
+ Added proof-shell-spill-output-regexp
+
+2001-09-03 David Aspinall <da@proofgeneral.org>
+
+ * README.devel: Text
+
+ * ChangeLog: Trim dups
+
+ * README.windows: Add author
+
+ * TODO, CHANGES:
+ Updated
+
+ * isa/Example.ML:
+ Accidental commit; revert to original.
+
+ * isar/isar.el:
+ Set proof-goal-with-hole-regexp
+
+ * generic/proof-config.el:
+ Change colour of locked region.
+
+ * generic/proof-shell.el:
+ Fix bracket bug.
+
+ * generic/proof-script.el:
+ Show/hide all proofs: add redisplay for FSF
+ Use new functions pg-set-span-helphighlights and pg-span-name
+ to set help echo, balloon help, mouse highlight, and context
+ menu.
+
+ * generic/proof-depends.el:
+ Use pg-set-span-helphightlights for unhighlighting.
+
+ * generic/pg-user.el:
+ Generalise context menu for other spans; grey out show/hide when unavailable.
+
+ * html/main.html: Join paras
+
+ * ChangeLog: Updated.
+
+ * html/features.html: Text
+
+ * html/features.html:
+ Fix link to screenshot
+
+ * html/doc.html: Improve layout
+
+ * doc/PG-adapting.texi, doc/ProofGeneral.texi:
+ Update version numbers, time stamps.
+
+ * html/download.html:
+ Typo. Update Emacs version to 20.7.
+
+ * ChangeLog: Updated.
+
+ * html/oldrel.php: Update branch
+
+ * html/download.html: PHP file
+
+ * html/oldrel.html, html/oldrel.php:
+ Renamed file
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/download.html:
+ Please try devel version
+
+ * bin/proofgeneral, demoisa/demoisa.el:
+ Accidental update; revert to previous
+
+ * demoisa/README: Rearrange
+
+ * twelf/twelf.el, twelf/x-symbol-twelf.el, twelf/twelf-old.el, plastic/todo, twelf/example.elf, twelf/README, twelf/twelf-font.el, plastic/plastic.el, plastic/plastic-syntax.el, plastic/test.lf, phox/phox.el, plastic/README, phox/phox-outline.el, phox/phox-sym-lock.el, phox/phox-tags.el, phox/example.phx, phox/phox-extraction.el, phox/phox-font.el, phox/phox-fun.el, lego/readonly/readonly.l, papers/README, phox/README, lego/legotags, lego/todo, lego/x-symbol-lego.el, lego/example2.l, lego/lego.el, lego/lego-syntax.el, lego/BUGS, lego/example.l, lego/README, isar/todo, isar/isar.el, isar/isar-keywords.el, isar/isar-syntax.el, isar/BUGS, isar/Example.thy, isar/interface, isar/README, isa/todo, isa/x-symbol-isabelle.el, isa/isabelle-system.el, isa/thy-mode.el, isa/isa.el, isa/interface, isa/interface-setup.el, isa/isa-syntax.el, isa/depends.ML, isa/Example2.ML, isa/README, isa/BUGS, isa/Example.ML, isa/Example.thy, isa/Example-Xsym.ML, images/gimp/.cvsignore, images/gimp/scripts/proofgeneral.scm, images/use.8bit.xpm, images/use.xcf, images/use.xpm, images/undo.8bit.xpm, images/undo.xcf, images/undo.xpm, images/retract.xpm, images/state.8bit.xpm, images/state.xcf, images/state.xpm, images/restart.xpm, images/retract.8bit.xpm, images/retract.xcf, images/qed.xpm, images/restart.8bit.xpm, images/restart.xcf, images/pgicon.png, images/pgmini.xpm, images/qed.8bit.xpm, images/qed.xcf, images/pg-text.xcf, images/pg-text.8bit.gif, images/pg-text.gif, images/pg-text.jpg, images/next.xcf, images/next.xpm, images/notes.txt, images/next.8bit.xpm, images/lego-badge.xcf, images/isabelle_transparent.8bit.gif, images/isabelle_transparent.gif, images/isabelle_transparent.xcf, images/isabelle-badge.xcf, images/info.xpm, images/interrupt.8bit.xpm, images/interrupt.xcf, images/interrupt.xpm, images/help.xpm, images/info.8bit.xpm, images/info.xcf, images/goto.xcf, images/goto.xpm, images/help.8bit.xpm, images/help.xcf, images/goto.8bit.xpm, images/goal_large.xcf, images/goal.8bit.xpm, images/goal.xcf, images/goal.xpm, images/find.xpm, images/fireworks.xcf, images/find.8bit.xpm, images/find.xcf, images/context.xpm, images/coq-badge.xcf, images/command.xcf, images/command.xpm, images/context.8bit.xpm, images/context.xcf, images/abort.xpm, images/blank.xcf, images/command.8bit.xpm, images/abort.8bit.xpm, images/abort.xcf, images/README, images/ProofGeneral.jpg, images/ProofGeneral.xcf, images/ProofGeneral.8bit.gif, images/ProofGeneral.gif, images/.cvsignore, images/Makefile, html/projects/test.html, html/projects/thybrowse.html, html/projects/webreplay.html, html/projects/xmlpgip.html, html/projects/pgip.html, html/projects/pgml.html, html/projects/reelcase.html, html/projects/scrgen.html, html/projects/hol.html, html/projects/isapbp.html, html/projects/mm.html, html/projects/outline.html, html/projects/coqfile.html, html/projects/coqpbp.html, html/projects/corba.html, html/projects/acs.html, html/papers/pgtalk.pdf, html/papers/pgoutline.ps.gz, html/papers/pgoutline.pdf, html/images/whole-man.jpg, html/images/whole-man-thumb.jpg, html/images/silverrule.gif, html/images/vh40.gif, html/images/whip.jpg, html/images/whip-thumb.jpg, html/images/pg-text.gif, html/images/portrait.jpg, html/images/portrait-thumb.jpg, html/images/pg-lego-console.png, html/images/pg-lego-screenshot.png, html/images/pg-lego-thumb.png, html/images/pg-isar-thumb.png, html/images/pg-lego-console-thumb.png, html/images/pg-isar-screenshot.png, html/images/pg-isa-screenshot.png, html/images/pg-isa-thumb.png, html/images/pg-coq-thumb.png, html/images/isabelle.gif, html/images/lego-badge.gif, html/images/pg-coq-screenshot.png, html/images/canvaswallpaper.jpg, html/images/coq-badge.gif, html/images/coqlogo4.gif, html/images/coqlogo4.xcf, html/images/isabelle-badge.gif, html/images/bullethole.gif, html/images/PG-small.jpg, html/images/ProofGeneral.jpg, html/images/.cvsignore, html/images/IsaPGscreen.jpg, .cvsignore, html/Kit/dtd/pgip.dtd, html/Kit/dtd/pgml.dtd, html/smallpage.php, html/screenshot.html, html/smallheader.html, html/smallpage.html, html/proofgen.css, html/register, html/register.html, html/screenshot, html/oldnews.html, html/oldrel.html, html/projects.html, html/news, html/news.html, html/notes.txt, html/main, html/main.html, html/mission.html, html/links, html/links.html, html/mailinglist, html/mailinglist.html, html/index.php, html/index.shtml, html/kit, html/kit.html, html/htmlshow.html, html/htmlshow.php, html/gallery.php, html/header.html, html/head.html, html/hits.html, html/fileshow.php, html/footer.html, html/functions.php3, html/gallery, html/features.html, html/feedback.html, html/feedback.php, html/download, html/download.html, html/elispmarkup.php3, html/features, html/develdownload.php, html/doc, html/doc.html, html/develdownload.html, html/cvsweb.conf, html/devel, html/devel.html, html/counter.php3, html/cvsweb.cgi, html/about, html/about.html, html/.cvsignore, html/ProofGeneralPortrait.eps.gz, hol98/example.sml, hol98/hol98.el, hol98/todo, hol98/x-symbol-hol98.el, generic/span.el, generic/texi-docstring-magic.el, hol98/README, generic/span-extent.el, generic/span-overlay.el, generic/proof.el, generic/proof-x-symbol.el, generic/proof-utils.el, generic/proof-syntax.el, generic/proof-system.el, generic/proof-toolbar.el, generic/proof-splash.el, generic/proof-site.el, generic/proof-shell.el, generic/proof-script.el, generic/proof-indent.el, generic/proof-menu.el, generic/proof-depends.el, generic/proof-easy-config.el, generic/proof-config.el, generic/proof-autoloads.el, generic/proof-compat.el, generic/pg-pgip.el, generic/pg-user.el, generic/pg-xml.el, etc/pgkit/xmltest1.xml, etc/pgkit/xmltest2.xml, generic/_pkg.el, generic/README, etc/patches/duplicated-short-messages-fix.txt, etc/patches/fix-attempt-for-eager-cleaning.txt, etc/lego/multiple/C.l, etc/lego/multiple/D.l, etc/lego/multiple/README, etc/lego/multiple/A.l, etc/lego/multiple/B.l, etc/lego/unsaved-goals.l, etc/lego/error-eg.l, etc/lego/lego-site.el, etc/lego/long-line-backslash.l, etc/isar/multiple/README, etc/lego/GoalGoal.l, etc/isar/multiple/A.thy, etc/isar/multiple/B.thy, etc/isar/multiple/C.thy, etc/isar/multiple/D.thy, etc/isar/bad1.thy, etc/isar/bad2.thy, etc/isar/README, etc/isar/XEmacsSyntacticContextProb.thy, etc/demoisa/README, etc/isar/Parsing.thy, etc/demoisa/A.ML, etc/demoisa/B.ML, etc/demoisa/C.ML, etc/demoisa/D.ML, etc/isa/multiple/foobar/foo.ML, etc/isa/thy/test.ML, etc/isa/multiple/D.thy, etc/isa/multiple/Err.ML, etc/isa/multiple/Err.thy, etc/isa/multiple/README, etc/isa/multiple/B.thy, etc/isa/multiple/C.ML, etc/isa/multiple/C.thy, etc/isa/multiple/D.ML, etc/isa/multiple/A.ML, etc/isa/multiple/A.thy, etc/isa/multiple/B.ML, etc/isa/depends/Usedepends.ML, etc/isa/depends/Usedepends.thy, etc/isa/depends/Fib.ML, etc/isa/depends/Fib.thy, etc/isa/depends/Primes.ML, etc/isa/depends/Primes.thy, etc/isa/\backslashname/test.ML, etc/isa/\backslashname/test.thy, etc/isa/long-line-backslash.ML, etc/isa/message-test.ML, etc/isa/settings.ML, etc/isa/xsym.ML, etc/coq/multiple/c.v, etc/isa/goal-matching.ML, etc/coq/multiple/a.v, etc/coq/multiple/b.v, etc/coq/multiple/.cvsignore, etc/coq/multiple/README, etc/coq/unnamed_thm.v, etc/testing-log.txt, etc/proofgeneral-domain.txt, etc/release-log.txt, etc/screenshot-notes.txt, etc/test-schedule.txt, etc/doc-notes.txt, etc/junk.el, etc/profiling.txt, etc/bug-notes.txt, etc/cvs-tips.txt, etc/debugging-tips.txt, etc/announce, etc/README, etc/TESTS, etc/ProofGeneral.menu, etc/ProofGeneral.spec, doc/dir, doc/docstring-magic.el, doc/localdir, doc/README.doc, doc/ProofGeneral.jpg, doc/ProofGeneral.texi, doc/Makefile.doc, doc/PG-adapting.texi, doc/.cvsignore, doc/Makefile, demoisa/demoisa-easy.el, demoisa/demoisa.el, coq/todo, coq/x-symbol-coq.el, demoisa/README, coq/coqtags, coq/example.v, coq/coq.el, coq/BUGS, coq/coq-syntax.el, coq/README, acl2/example.acl2, acl2/x-symbol-acl2.el, bin/proofgeneral, acl2/acl2.el, acl2/README, todo, README.devel, README.windows, REGISTER, TODO, Makefile.xemacs, README, Makefile, Makefile.devel, FAQ, INSTALL, ChangeLog, COPYING, BUGS, CHANGES, AUTHORS:
+ Updating branch
+
+ * doc/ProofGeneral.texi:
+ Note of what to do
+
+ * generic/proof-script.el: Formatting
+
+ * html/features.html:
+ Mention hiding proofs.
+
+ * etc/ProofGeneral.spec:
+ Add specific READMEs.
+
+ * etc/cvs-tips.txt:
+ Note of secure alt to no password
+
+ * etc/release-log.txt:
+ Ready for release
+
+ * etc/announce: Update for 3.3
+
+ * plastic/README, twelf/README, isa/README, isar/README, lego/README, phox/README, hol98/README, coq/README, generic/README, acl2/README:
+ Add specific install instrs, rearrange.
+
+ * INSTALL:
+ Move specific install instructions into subdirs
+
+ * isa/isa.el:
+ Add settings for testing trace buffers.
+
+ * CHANGES:
+ Note about tracing buffers for developers
+
+ * generic/proof-shell.el:
+ Added handling of tracing buffers using proof-shell-spill-output-regexp.
+
+ * generic/proof-config.el:
+ Added proof-shell-spill-output-regexp
+
+2001-09-02 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+2001-09-02 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+2001-08-31 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/interface, isar/interface:
+ handle relative heap paths gracefully;
+
+ * isar/isar-keywords.el:
+ back to *official* Isabelle99-2 (later Isabelle dists will provide
+ their own copy of this file);
+
+2001-08-31 David Aspinall <da@proofgeneral.org>
+
+ * CHANGES: Improved explanation
+
+ * doc/ProofGeneral.texi:
+ Something about dependencies feature
+
+ * CHANGES:
+ Added note about dependency feature.
+
+ * generic/proof-depends.el:
+ (Almost) complete rewrite
+
+ * generic/proof-autoloads.el: Updated
+
+ * generic/proof-script.el:
+ Move theorem dependency code into proof-depends.el.
+
+ Added 'controlspan property to proof body spans: action will be
+ controlled from the control span. (The 'goalsave is the parent).
+
+ Replace 'highlight face with 'proof-mouse-highlight-face throughout.
+
+ * generic/pg-user.el:
+ Added copy command, call to dependency menu if proof-depends is loaded.
+
+ * isa/depends.ML:
+ Add simulations of more qed commands, also sort and uniquify dependencies.
+
+ * generic/proof-config.el:
+ Add new proof-mouse-highlight-face to use instead of default. Fix dependency faces.
+
+2001-08-31 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar-keywords.el:
+ new commands (proof terms, code generator);
+
+2001-08-31 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Remove duplicate entries
+
+ * generic/proof-config.el:
+ Add faces for theorem dependencies.
+
+ * etc/coq/multiple/README: Explanation
+
+ * AUTHORS: Add DvO to list
+
+ * AUTHORS: Add Christophe to list
+
+ * coq/coq.el:
+ Add auto-compile-vos experimental setting for automatic multiple files.
+
+ * BUGS: Remove minibuffer bug
+
+ * isa/thy-mode.el:
+ Fix for names of functions in proof-depends
+
+ * isa/isa.el:
+ Add setting for turning on theorem dependency tracking
+
+ * isa/depends.ML:
+ Update for Isabelle99-2
+
+ * generic/proof-depends.el, generic/proof-script.el:
+ Clean up of proof-depends
+
+ * generic/proof-menu.el:
+ Skip settings which have no PA command in proof-assistant-settings-cmd
+
+ * generic/proof-shell.el:
+ Add proof-shell-kill-function-hooks
+
+2001-08-30 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/interface, isar/interface:
+ include ISABELLE_HOME_USER/etc/isar-keywords.el or
+ ISABELLE_HOME/etc/isar-keywords.el if available;
+
+ * isa/README, isar/README, isar/todo:
+ updated;
+
+ * generic/proof-script.el:
+ pg-add-proof-element: removed accidential (?) dynamic scoping on
+ proofbodyspan;
+ handle proof-script-integral-proofs;
+
+ * generic/proof-config.el:
+ added proof-script-integral-proofs ("Whether the complete text after a
+ goal confines the actual proof.");
+
+ * isar/isar.el:
+ proof-script-integral-proofs t;
+
+2001-08-30 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * CHANGES: Clarify 6.3.1 for multi file
+
+ * isa/isabelle-system.el:
+ Fix interrupt hook for PolyML 4 in recent Isabelle
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/proof-shell.el:
+ Add reassurance to interrupt warning to make Markus happier.
+
+ * html/download.html:
+ Note about XEmacs 21 and x-symbol
+
+ * isa/isabelle-system.el:
+ Set proof-shell-pre-interrupt-hook for PolyML (not just PolyML 3).
+
+ * CHANGES:
+ More about invisible proofs and multiple files in Coq. X-symbol compat
+
+ * generic/proof-x-symbol.el:
+ Updates for recent version of X-symbol, which has no file called x-symbol-autoloads.
+
+ * generic/proof-menu.el:
+ Add :eval form for defpacustom to define PA-specific PG settings as well as PA settings.
+
+ * generic/proof.el:
+ Add variable proof-previous-script-buffer
+
+ * generic/proof-script.el:
+ fixes for FSF Emacs for searching for goal span (don't call goal-command-p on empty string). Fix bug in add-proof-element for disappearing proofs setting. Add setting of proof-previous-script-buffer when scripting deactivated
+
+ * generic/proof-compat.el:
+ Added implementation of remassq for FSF Emacs
+
+ * generic/pg-user.el:
+ pg-insert-last-output-as-comment strips special annotations from last output before inserting as comment.
+
+2001-08-30 David Aspinall <da@proofgeneral.org>
+
+ * CHANGES: Clarify 6.3.1 for multi file
+
+ * isa/isabelle-system.el:
+ Fix interrupt hook for PolyML 4 in recent Isabelle
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/proof-shell.el:
+ Add reassurance to interrupt warning to make Markus happier.
+
+ * html/download.html:
+ Note about XEmacs 21 and x-symbol
+
+ * isa/isabelle-system.el:
+ Set proof-shell-pre-interrupt-hook for PolyML (not just PolyML 3).
+
+ * CHANGES:
+ More about invisible proofs and multiple files in Coq. X-symbol compat
+
+ * generic/proof-x-symbol.el:
+ Updates for recent version of X-symbol, which has no file called x-symbol-autoloads.
+
+ * generic/proof-menu.el:
+ Add :eval form for defpacustom to define PA-specific PG settings as well as PA settings.
+
+ * generic/proof.el:
+ Add variable proof-previous-script-buffer
+
+ * generic/proof-script.el:
+ fixes for FSF Emacs for searching for goal span (don't call goal-command-p on empty string). Fix bug in add-proof-element for disappearing proofs setting. Add setting of proof-previous-script-buffer when scripting deactivated
+
+ * generic/proof-compat.el:
+ Added implementation of remassq for FSF Emacs
+
+ * generic/pg-user.el:
+ pg-insert-last-output-as-comment strips special annotations from last output before inserting as comment.
+
+2001-08-28 David Aspinall <da@proofgeneral.org>
+
+ * doc/PG-adapting.texi, doc/ProofGeneral.texi:
+ Fix web page for kit
+
+2001-08-28 Pierre Courtieu <courtieu@lri.fr>
+
+ * doc/ProofGeneral.texi:
+ added something in the doc about coq-version-is-V7.
+
+ * coq/coq.el:
+ Added something in the doc about coq-version-is-V7, and made the setting of
+ this variable more trustable with (concat coq-prog-name "-v").
+
+2001-08-28 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/proof-script.el:
+ Change of proof span type back to goalsave fix
+
+ * lego/lego.el, coq/coq.el, phox/phox-fun.el, isar/isar.el:
+ Change of proof span type back to goalsave
+
+ * generic/proof-splash.el:
+ Remove dependent setting of timeout, since bin calls different fn now.
+
+ * bin/proofgeneral:
+ Call function which always waits to prevent odd mode selection bug.
+
+ * generic/proof-splash.el: Trivial
+
+ * generic/proof-splash.el:
+ Remove mention of toolbar variable. Make timeouts vary according to how started.
+
+ * generic/proof-splash.el:
+ Timeout happens as intended now, while loading some parts of PG.
+
+ * html/header.html, html/proofgen.css:
+ Improve stylesheet syntax, make menubar smaller
+
+2001-08-17 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/proof-script.el:
+ Trim visibility implementation:
+ - remove visibility specs and script portion records during undo
+ - clear visibility specs on restart
+
+ * generic/span-extent.el, generic/span-overlay.el:
+ Add span-delete-action hook
+
+ * CHANGES: Minibuffer contents bug fix
+
+ * generic/proof-utils.el:
+ Fix bug in proof-display-and-keep-buffer which had resulted in switching minibuffer windows buffer.
+
+2001-08-16 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * doc/ProofGeneral.texi:
+ Document visibility control
+
+ * html/devel.html:
+ Add link to browse files
+
+ * html/download.html:
+ Add link to browse package
+
+ * html/develdownload.php:
+ Add link to individual files
+
+ * CHANGES:
+ Move visibility item up, removed "in progress"
+
+ * generic/proof-shell.el:
+ Switch back to using goalsave spans in PBP code
+
+ * generic/proof-config.el, generic/proof-toolbar.el:
+ Add hide/show commands instead of make proofs visible
+
+ * generic/proof-script.el:
+ Generate intermediate proof span for contents of proof; other becomes 'goalsave again. Add idiom property.
+
+ * generic/pg-user.el:
+ Function name fixes, use idiom property in span for popup menu name.
+
+2001-08-15 David Aspinall <da@proofgeneral.org>
+
+ * html/gallery.php:
+ Fix screenshots link
+
+ * html/gallery: Fix again.
+
+ * html/gallery: Fix link
+
+2001-08-10 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * CHANGES: Explain symptom properly
+
+ * generic/proof-script.el:
+ Use proof-looking-at-syntactic-context function from proof-syntax, as suggested by Markus
+
+ * generic/proof-syntax.el:
+ Found another instance of buffer-syntactic-context
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel:
+ Put all in dist except pgkit
+
+ * README:
+ Rearrange list of assistants, note REGISTER.
+
+ * FAQ: Remove note about 3.1
+
+ * BUGS: Comment about win32 XEmacs
+
+ * generic/proof-compat.el:
+ Workaround for buffer-syntactic-context bug in XEmacs 21.1
+
+ * generic/proof-script.el, isar/isar.el:
+ Change buffer-syntactic-context -> proof-buffer-syntactic-context
+
+ * etc/isar/XEmacsSyntacticContextProb.thy:
+ Bug test case, note workaround date
+
+ * etc/isar/XEmacsSyntacticContextProb.thy:
+ Bug test case
+
+ * CHANGES:
+ Note of bug fix for buffer-syntactic-context
+
+2001-08-09 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/x-symbol-isabelle.el:
+ fixed potential regexp typo (!?);
+
+2001-08-03 David Aspinall <da@proofgeneral.org>
+
+ * CHANGES:
+ Note about improved win32 support
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/fileshow.php:
+ Fix link back to fileshow.php
+
+ * html/fileshow.html: Renamed file
+
+ * html/main.html: Fix screenshot link
+
+2001-08-01 David Aspinall <da@proofgeneral.org>
+
+ * doc/ProofGeneral.texi, doc/PG-adapting.texi:
+ Update last updated, copyright
+
+ * README.windows: Formatting
+
+ * README: Update for 3.3
+
+ * ChangeLog: Updated.
+
+ * html/screenshot.html, html/about.html, html/oldnews.html:
+ Fix links to gallery
+
+ * html/gallery.html: Deleted files.
+
+ * html/gallery: Renamed file
+
+ * html/gallery.html: Moved to .php
+
+ * html/about.html: Fix typo
+
+ * html/gallery.php, html/gallery.html:
+ Renamed file
+
+ * html/news.html: Added news
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/devel.html, generic/proof-site.el, html/develdownload.php:
+ Set version tag for new release.
+
+ * generic/proof-autoloads.el:
+ Regenerate to remove Christophes patch
+
+ * generic/proof-compat.el, generic/proof-site.el:
+ Moved compat hack to proof-site
+
+ * generic/proof-toolbar.el:
+ Revert to removing and re-adding specifiers for toolbar,
+ so that enablers work at least as well as they did before...
+
+ * generic/proof-compat.el:
+ Add a dummy version of package-provide for FSFEmacs.
+
+2001-07-25 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * generic/proof-autoloads.el, generic/proof-splash.el, README.windows:
+ *** empty log message ***
+
+ * phox/phox.el, phox/phox-sym-lock.el, phox/phox-fun.el, generic/proof-splash.el, generic/proof-toolbar.el:
+ Various changes for win32 compatibility
+
+2001-07-23 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/proof-menu.el:
+ Prevent error msg in proof-display-some-buffers if response dead.
+
+ * generic/proof-shell.el:
+ Bug report from Robert Schneck. Make proof-shell-restart start shell. Goals display convention, not hack.
+
+2001-07-09 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * todo:
+ TODO for proof-ass fixing added.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * generic/proof-toolbar.el:
+ Clean for compile
+
+ * generic/proof-menu.el:
+ Clean for compile: new autload
+
+ * generic/proof-autoloads.el: Refresh
+
+ * generic/pg-xml.el, generic/pg-user.el:
+ Clean-up compile
+
+ * generic/proof-compat.el:
+ Add require for arch flags, cleaner compilation.
+
+ * generic/pg-pgip.el:
+ Fix some bugs shown by byte comp
+
+ * generic/proof-autoloads.el:
+ Updated autoloads
+
+ * generic/_pkg.el:
+ Package file (old attempt -- not working)
+
+2001-06-22 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * phox/phox.el:
+ *** empty log message ***
+
+2001-05-29 David Aspinall <da@proofgeneral.org>
+
+ * html/main.html: Fix Coq link.
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/develdownload.php, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * isa/Example.ML: Remove extra proof."
+
+ * generic/proof-splash.el:
+ Display screen only if called interactively
+
+ * doc/ProofGeneral.texi:
+ AF2 -> PhoX name change
+
+ * etc/ProofGeneral.spec:
+ Add REGISTER to doc files.
+
+ * COPYING: Date 2001
+
+ * html/features.html:
+ Fix layout and typo.
+
+ * html/mailinglist.html:
+ Include PHP file
+
+ * REGISTER:
+ Note about mailing list and registration.
+
+ * html/mailinglist, html/mailinglist.php:
+ Renamed file
+
+ * html/mailinglist.html, html/mailinglist.php:
+ PHP version. Also dont mention junk filters.
+
+2001-05-18 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar-keywords.el:
+ preliminary addition of "corollary";
+
+2001-05-16 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/devel.html, generic/proof-site.el, html/develdownload.php:
+ Set version tag for new release.
+
+ * doc/ProofGeneral.texi: Minor
+
+ * bin/proofgeneral:
+ Run the display splash command
+
+ * generic/proof-config.el:
+ Moved splash settings and basic custom groups elsewhere
+
+ * CHANGES: splash changes.
+
+ * generic/proof-site.el:
+ Move loading of compatibility flag, autoloads, basic customization groups here.
+
+ * generic/proof.el:
+ Move autoloads loads to proof-site, invoke (proof-splash-message)
+
+ * generic/proof-compat.el:
+ Move emacs version compatibility flags to proof-site.el
+
+ * generic/proof-splash.el:
+ Move configuration from proof-config here. Make proof-splash-message display logo or print message.
+
+ * etc/README:
+ Doc of spec and menu, patch now removed
+
+2001-05-08 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.menu:
+ Fix case to match Mandrake menu.
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.menu: Fix quotes.
+
+ * html/functions.php3:
+ Repair link via htmlshow.php
+
+ * doc/PG-adapting.texi:
+ Change info dir entry to appear next to Proof General entry.
+
+ * ChangeLog: Updated.
+
+ * html/develdownload.php:
+ Set version tag for new release.
+
+ * Makefile.devel:
+ Change DEVELDOWNLOAD to edit correct file
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec:
+ Add a line to clear out build root.
+
+ * ChangeLog: Updated.
+
+ * Makefile.devel:
+ Forgot to make BUILD dir.
+
+ * ChangeLog: Updated.
+
+ * Makefile.devel:
+ Fix cut and past tab error
+
+ * Makefile.devel:
+ rpm target: Clean out rpmtopdir, and make subdirs again. Get full path to tar file
+
+ * ChangeLog: Updated.
+
+ * Makefile.devel:
+ Clean out NAME, force link.
+
+ * ChangeLog: Updated.
+
+ * Makefile.devel:
+ Include a few files from etc in the distribution, esp .spec file
+
+ * etc/ProofGeneral.menu:
+ *** empty log message ***
+
+ * etc/ProofGeneral.patch:
+ Deleted files.
+
+ * ChangeLog: Updated.
+
+ * doc/ProofGeneral.texi:
+ Fix section title for makeinfo
+
+ * etc/ProofGeneral.spec, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * Makefile.devel:
+ Dont make SRPM any more. Use rpm -tb to build binary package from tarball
+
+ * CHANGES: Updates
+
+ * etc/ProofGeneral.spec:
+ Updates, removal of patch so that rpm -ta works
+
+ * doc/ProofGeneral.texi:
+ Updates for 3.3
+
+ * generic/proof-utils.el:
+ Fixes for fontification in Xemacs 21.4
+
+ * generic/proof-site.el, generic/proof-syntax.el, generic/proof-shell.el, generic/proof-easy-config.el, generic/proof-indent.el, generic/proof-menu.el, generic/proof-config.el, generic/pg-pgip.el, generic/pg-user.el, generic/pg-xml.el, generic/proof-compat.el:
+ Copyright date updated
+
+ * generic/README:
+ Add Markus to list of authors
+
+ * html/main.html:
+ preliminary -> experimental
+
+ * html/develdownload.php:
+ No longer distrib SRPM
+
+ * html/news.html: New news item
+
+2001-05-03 David Aspinall <da@proofgeneral.org>
+
+ * generic/proof-splash.el:
+ change for Emacs compatibility and FSF/Xemacs update. Copyright update.
+
+ * generic/proof-script.el:
+ Emacs fix (extent->span). Copyright update.
+
+2001-05-01 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * doc/ProofGeneral.texi, doc/Makefile.doc, doc/PG-adapting.texi:
+ Try to disable image for now
+
+ * etc/ProofGeneral.spec, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+ * html/devel.html: Change link to kit
+
+ * html/download.html:
+ Change link to register page
+
+ * html/feedback.html, html/index.shtml:
+ Include php file
+
+ * html/register, html/kit:
+ Register and kit shortcuts
+
+ * html/develdownload.html:
+ Include php file
+
+ * html/functions.php3:
+ Link to php files instead of html
+
+ * html/links, html/main, html/news, html/about, html/devel, html/doc, html/download, html/features:
+ Include php instead of html
+
+ * html/smallpage.php, html/htmlshow.php, html/index.php, html/develdownload.php, html/feedback.php, html/fileshow.php:
+ Rename some html files php
+
+ * html/index.html: Deleted files.
+
+2001-04-10 Pierre Courtieu <courtieu@lri.fr>
+
+ * coq/coq.el:
+ Modification of proof-script-command-end-regexp to allow commands
+ ended by ".eof"
+
+2001-03-20 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * html/main.html: Fixes to main page
+
+ * html/footer.html:
+ Change to my canonical www.dcs web address
+
+ * html/main.html:
+ Remove proofgeneral.org on main page
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/devel.html, generic/proof-site.el, html/develdownload.html:
+ Set version tag for new release.
+
+ * BUGS:
+ strange buffer selection bug reported by Markus
+
+ * doc/PG-adapting.texi: Updated magic
+
+2001-03-20 Pierre Courtieu <courtieu@lri.fr>
+
+ * coq/coq.el:
+ Added the config var proof-script-command-end-regexp fot coq V7.
+
+2001-03-20 David Aspinall <da@proofgeneral.org>
+
+ * doc/Makefile.doc:
+ Use PS fonts in PS file
+
+ * generic/proof-shell.el:
+ Remove temporary comments
+
+ * generic/proof-config.el:
+ Fix docstring
+
+ * html/feedback.html, html/footer.html, html/functions.php3:
+ Changes to use proofgen@dcs for now instead of broken proofgeneral.org
+
+ * html/main.html: Fix to Coq web page
+
+2001-03-19 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * phox/phox-font.el:
+ *** empty log message ***
+
+2001-02-26 Pierre Courtieu <courtieu@lri.fr>
+
+ * coq/coq.el:
+ minor change in coq.el to allow to force version of coq, with variable
+ coq-version-is-V7
+
+2001-02-20 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * phox/phox.el, phox/example.phx, phox/phox-extraction.el, phox/phox-fun.el, phox/phox-tags.el, html/develdownload.html, html/devel.html, phox/README, generic/proof-site.el, etc/ProofGeneral.spec:
+ *** empty log message ***
+
+2001-02-08 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * phox/phox-font.el:
+ *** empty log message ***
+
+2001-02-07 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, html/devel.html, html/develdownload.html, generic/proof-site.el:
+ Set version tag for new release.
+
+2001-02-07 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * phox/phox.el, phox/phox-font.el, phox/phox-fun.el, phox/phox-tags.el, phox/phox-extraction.el:
+ *** empty log message ***
+
+2001-02-06 David Aspinall <da@proofgeneral.org>
+
+ * etc/ProofGeneral.spec, html/develdownload.html, html/devel.html, generic/proof-site.el:
+ Set version tag for new release.
+
+2001-02-02 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * phox/phox-font.el:
+ *** empty log message ***
+
+2001-02-01 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * doc/ProofGeneral.texi:
+ updated thms_containing;
+
+2001-02-01 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * phox/phox-sym-lock.el, phox/phox.el, phox/phox-font.el:
+ *** empty log message ***
+
+2001-01-24 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/x-symbol-isabelle.el:
+ renamed \<ll> to \<lless> and \<gg> to \<ggreater>;
+
+2001-01-18 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar.el:
+ proof-xsym-deactivate-command: use Library.gen_rems (op =) to avoid \\\\;
+
+2001-01-18 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * phox/phox-extraction.el, phox/phox.el, phox/phox-fun.el, phox/phox-tags.el:
+ *** empty log message ***
+
+2001-01-12 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/isa.el: proof-string-match;
+
+2001-01-12 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * isa/isa.el:
+ Fix loading thy mode fist problem: require proof-script since context
+ menus are now added for response/goals buffer, which requires proof mode.
+
+2001-01-12 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/isabelle-system.el, isar/isar.el, isar/isar-syntax.el:
+ proof-string-match;
+
+2001-01-12 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/isabelle-system.el, isar/isar.el, isar/isar-syntax.el:
+ proof-string-match;
+
+2001-01-11 Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+
+ * phox/phox.el:
+ *** empty log message ***
+
+2001-01-11 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * generic/proof-shell.el, generic/pg-xml.el, generic/proof-script.el:
+ fixed format strings in message, error, etc.
+
+2001-01-10 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar-syntax.el:
+ proper font-lock of isar-keywords-proof-heading;
+
+ * isa/x-symbol-isabelle.el:
+ added \<wrong>;
+
+2001-01-09 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isa/x-symbol-isabelle.el:
+ added \<cedilla>, \<dieresis>, \<acute>, \<hungarumlaut>;
+
+2001-01-05 David Aspinall <da@proofgeneral.org>
+
+ * ChangeLog: Updated.
+
+ * etc/ProofGeneral.spec, generic/proof-site.el, html/develdownload.html, html/devel.html:
+ Set version tag for new release.
+
+2001-01-03 Markus Wenzel <wenzelm@informatik.tu-muenchen.de>
+
+ * isar/isar-keywords.el:
+ added "recdef_tc";
+
diff --git a/FAQ b/FAQ
new file mode 100644
index 00000000..2bad392e
--- /dev/null
+++ b/FAQ
@@ -0,0 +1,80 @@
+FAQs for Proof General
+======================
+
+$Id$
+
+For latest version, see http://www.proofgeneral.org/ProofGeneral/FAQ
+
+-----------------------------------------------------------------
+
+Q. I'm afraid I got stuck very early on. I sent the following line:
+ by (swap_res_tac [psubsetI] 1;
+ Notice that I forgot the right bracket. The line went pink, the
+ buffer went read-only and nothing I tried would let me fix the
+ error.
+
+A. The proof process is waiting for more input, but Proof General
+ doesn't realise this and waits for a response. You
+ should type something in the proof shell, or interrupt the process
+ with C-c C-c or the Stop button.
+
+-----------------------------------------------------------------
+
+Q. How can I keep the Proof General option settings across sessions?
+
+A. Simply use the ordinary XEmacs menu: Options -> Save Options
+
+ In FSF Emacs, you can do M-x customize-save-customized
+ or use the Custom->Save menu in a customize buffer.
+
+-----------------------------------------------------------------
+
+
+Q. I'm using Proof General for prover X, then I load a file for prover Y.
+ The buffer doesn't enter the mode for prover Y. Why not?
+
+A. Unfortunately the architecture of Proof General is designed so
+ that you can only use one prover at a time in the same Emacs
+ session. If you want to run more than one prover at a time,
+ you have to run more than one Emacs.
+
+-----------------------------------------------------------------
+
+
+Q. How do I use Proof General for Isabelle/Isar instead of Isabelle classic?
+
+A. There are several ways:
+
+ 1. Use the Isabelle settings mechanism, invoke with "Isabelle"
+ 2. Set the environment variable PROOFGENERAL_ASSISTANTS=isar
+ before starting Emacs.
+ 3. Put the line (* -*- isar -*- *) at the top of your Isar files.
+
+ Unfortunately Isabelle/Isar and Isabelle classic are two quite
+ separate Proof General instances. Ideally they should be
+ combined into one, if anyone fancies some elisp hacking...
+
+
+-----------------------------------------------------------------
+
+Q. When using X-Symbol, why do I sometimes see funny characters like
+ \233 in the buffer?
+
+A. These are part of the 8 bit character codes used by X Symbol to
+ get symbols from particular fonts. Sometimes X-Symbol forgets to
+ fontify the buffer properly to make it use the right fonts.
+ To fix, type M-x x-font-lock-fontify-buffer or M-x x-symbol-fontify.
+ If that doesn't work, type M-x font-lock-mode twice to turn
+ font-lock off then on. Or reload the file.
+
+ Note that X-Symbol is more robust when used with XEmacs/Mule.
+
+ Read the X-Symbol documentation for (much) more information.
+
+-----------------------------------------------------------------
+
+Q. Can I join any mailing lists for Proof General?
+
+A. Of course, email "majordomo@dcs.ed.ac.uk" with the
+ lines "subscribe proofgeneral" or "subscribe proofgeneral-devel"
+ in the message body.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 00000000..6b12657f
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,168 @@
+Instructions for installing Proof General
+=========================================
+
+This file describes what to do to run Proof General.
+Please let us know if you have problems trying to install it.
+
+Unpack this distribution somewhere. It will create a top-level
+directory containing Proof General, called Proof-General-<something>.
+Put this line in your .emacs file:
+
+ (load-file "<proofgeneral-home>/generic/proof-site.el")
+
+Where <proofgeneral-home> is replaced by the full path name to
+Proof-General-<something>. If you prefer not to edit .emacs,
+you can use the script in bin/proofgeneral to launch Emacs with
+Proof General loaded.
+
+The command above will set the Emacs load path and add auto-loads for
+the assistants below:
+
+ .v Coq files
+ .l LEGO files
+ .thy Isabelle files
+ .ML Isabelle files
+ .phx PhoX files
+ .sml HOL98 files
+ .elf Twelf files
+ .acl2 ACL2 files
+
+When you load a file with one of these extensions, the corresponding
+Proof General mode will be entered.
+
+In case of difficulty, please check the documentation in doc/, the
+notes below, the README file for each prover, and the file BUGS.
+
+If none of these files t help, then contact us via the address below.
+
+ - David Aspinall.
+
+
+ Proof General maintainer <support@proofgeneral.org>
+ LFCS,
+ Division Of Informatics,
+ University of Edinburgh.
+ Edinburgh.
+
+ http://www.proofgeneral.org
+
+
+
+----------------------------------------------------------------------
+
+Detailed installation Notes for Proof General
+=============================================
+
+
+RPM package.
+------------
+
+If you have the RPM file, this is the line you should add to your
+.emacs file:
+
+ (load-file "/usr/share/emacs/ProofGeneral/generic/proof-site.el")
+
+
+
+Running on Windows
+------------------
+
+We recommend XEmacs compiled for Windows, see http://www.xemacs.org
+
+Unpack the Proof General tar or zip file, and rename the folder to
+"ProofGeneral" to remove the version number. Put a line like this:
+
+ (load-file "c:\\ProofGeneral\\generic\\proof-site.el")
+
+into .emacs. You should put .emacs in value of HOME if you set that,
+or else in directory you installled XEmacs in, e.g.
+c:\Program Files\XEmacs\.emacs
+
+See also README.windows
+
+
+Dependency on Other Emacs Packages
+----------------------------------
+
+Proof General relies on several other Emacs packages, which are
+probably already supplied with your version of Emacs. If not,
+you will need to find them. Note that XEmacs is now being unbundled,
+so you may need to select packages (or package groups) specially.
+These are the packages that you need to use Proof General:
+
+ ESSENTIAL:
+ * cl-macs
+ * comint
+ * custom
+ * font-lock
+
+ OPTIONAL:
+ * outline
+ * func-menu
+ * X Symbol
+
+
+
+Byte Compilation.
+-----------------
+
+Compilation of the Emacs lisp files improves efficiency but can
+sometimes cause compatibility problems. It is not properly supported
+in this release, because testing for these compatibility problems
+takes too much time. If you want to experiment nonetheless, you can
+compile Proof General by typing 'make' in the directory where you
+installed it. This will result in lots of warnings and error messages
+most of which can be ignored. Some files cannot be properly
+byte-compiled at the moment because they contain settings which depend
+on run-time; these will be deleted by the Makefile. Use 'make clean'
+to remove all .elc files in case of problems. Check the Makefile sets
+EMACS to your Emacs executable.
+
+
+Site-wide Installation
+----------------------
+
+If you are installing Proof General site-wide, you can put the
+components in the standard directories of the filesystem if you
+prefer, providing the variables in proof-site.el are adjusted
+accordingly. Make sure that the generic and assistant-specific elisp
+files are kept in subdirectories of proof-home so that the autoload
+directory calculations are correct.
+
+To save every user needing the line in their .emacs file, you can put
+that into a site-wide file like default.el. Read the Emacs manual for
+details.
+
+
+Removing support for unwanted provers
+-------------------------------------
+
+You cannot run more than one instance of Proof General at a time:
+e.g. if you're using Coq, you won't be able to run LEGO scripts.
+
+If there are some assistants supported that you never want to use,
+you can remove them from the variable `proof-assistants`
+to prevent Proof General autoloading for files with particular
+extensions. This may be useful if you want to use other modes for
+those files, for example, you may want sml-mode for .ML files or
+Verilog mode for .v files.
+
+The easiest way to do this (and other customization of Proof General)
+is via the Customize mechanism, see the menu:
+
+ Options -> Customize -> Emacs -> External -> Proof General
+
+or, after loading Proof General, in a proof script buffer
+
+ Proof-General -> Customize
+
+You may need extra customization depending on the proof assistant (for
+example, the name of the proof assistant binary). See the menu
+
+ Proof-General -> Customize -> <Name of Assistant>
+
+and the manual for more details.
+
+
+
+$Id$
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..aed482e0
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,118 @@
+##
+## Makefile for Proof General.
+##
+## Author: David Aspinall <da@dcs.ed.ac.uk>
+##
+## make - do "compile" and "scripts" targets
+## make compile - make .elc's in a single session
+## make all - make .elc's in separate sessions
+## make scripts - edit paths in isabelle interface scripts,
+## legotags and coqtags
+##
+## $Id$
+##
+###########################################################################
+
+
+ELISP_DIRS = generic lego coq isa isar plastic demoisa hol98 phox twelf acl2
+# FIXME: automate the emacs choice to be xemacs if it can be
+# found, otherwise emacs.
+BATCHEMACS=xemacs -batch -q -no-site-file
+
+PWD=$(shell pwd)
+BASH_SCRIPTS = isa/interface isar/interface
+PERL_SCRIPTS = lego/legotags coq/coqtags
+
+# FIXME: would rather set load path in Elisp,
+# but seems tricky to do only during compilation.
+# Another idea: put a function in proof-site to
+# output the compile-time load path and
+# ELISP_DIRS so these are set just in that one
+# place.
+BYTECOMP = $(BATCHEMACS) -eval '(setq load-path (append (list "$(PWD)/generic" "$(PWD)/lego" "$(PWD)/coq" "$(PWD)/isa" "$(PWD)/isar" "$(PWD)/plastic") load-path))' -f batch-byte-compile
+
+EL=$(shell for f in $(ELISP_DIRS); do ls $$f/*.el; done)
+ELC=$(EL:.el=.elc)
+
+BROKENELC=proof-toolbar.elc proof-menu.elc proof-indent.elc proof-x-symbol.elc
+
+.SUFFIXES: .el .elc
+
+default: compile scripts
+
+##
+## compile : byte compile files in working directory:
+## Clearout old .elc's and re-compile in a
+## single Emacs process. This is faster than make all,
+## but can have artefacts because of context between
+## compiles.
+##
+compile:
+ @echo "*************************************************"
+ @echo " Byte compiling..."
+ @echo "*************************************************"
+ (rm -f $(ELC); $(BYTECOMP) $(EL))
+ rm -f $(BROKENELC)
+ @echo "*************************************************"
+ @echo " Finished."
+ @echo "*************************************************"
+
+all: $(ELC)
+
+.el.elc:
+ $(BYTECOMP) $*.el
+ rm -f $(BROKENELC)
+
+##
+## scripts: try to patch bash and perl scripts with correct paths
+##
+scripts: bashscripts perlscripts
+
+bashscripts:
+ @(bash="`which bash`"; \
+ if [ -z "$$bash" ]; then \
+ echo "Could not find bash - bash paths not checked" >&2; \
+ exit 0; \
+ fi; \
+ for i in $(BASH_SCRIPTS); do \
+ sed "s|^#.*!.*/bin/bash.*$$|#!$$bash|" < $$i > .tmp \
+ && cat .tmp > $$i; \
+ done; \
+ rm -f .tmp)
+
+perlscripts:
+ @(perl="`which perl`"; \
+ if [ -z "$$perl" ]; then \
+ echo "Could not find perl - perl paths not checked" >&2; \
+ exit 0; \
+ fi; \
+ for i in $(PERL_SCRIPTS); do \
+ sed "s|^#.*!.*/bin/perl.*$$|#!$$perl|" < $$i > .tmp \
+ && cat .tmp > $$i; \
+ done; \
+ rm -f .tmp)
+
+clean:
+ rm -f $(ELC) *~ */*~ .\#* */.\#*
+ (cd doc; $(MAKE) clean)
+
+
+##
+## This special target lets us use targets defined
+## in developer's makefile Makefile.devel conveniently,
+## via make devel.<target>
+##
+
+devel.%:
+ make -f Makefile.devel $*
+
+##
+## Similarly for xemacs Makefile.
+##
+
+xemacs.%:
+ make -f Makefile.xemacs $*
+
+
+
+
diff --git a/Makefile.devel b/Makefile.devel
new file mode 100644
index 00000000..722585fa
--- /dev/null
+++ b/Makefile.devel
@@ -0,0 +1,532 @@
+##
+## Makefile for Proof General development.
+##
+## Author: David Aspinall <da@dcs.ed.ac.uk>
+##
+## Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+##
+## Developer use only, not part of distribution.
+##
+## make clean - remove intermediate files
+## make distclean - remove all generated files
+##
+## make ChangeLog - make ChangeLog from CVS sources
+## make tags - update TAGS file for Elisp sources
+## make autoloads - update autoloads
+##
+## make tag - tag the CVS sources with CVS_RELEASENAME
+## make untag - remove tag CVS_RELEASENAME from the sources
+## make dist - make a distribution from sources with above tag
+## make rpm - make RPM packages based on etc/ProofGeneral.spec
+##
+## make release - make tag, dist, and install it in RELEASEDIR.
+## make releaseall - make release, local installation and rpmrelease.
+##
+## make distinstall - install distribution build by 'make dist'
+## into DISTINSTALLDIR.
+##
+## make links - add some links which help testing web pages
+## from the html directory, and ensure that the
+##
+##
+## make releaseclean - clean up after 'make dist' 'make rpmrelease'.
+##
+##
+## Notes:
+## Use 'make untag' before re-trying if 'make releaseall' fails and files
+## are changed. This will make sure tags move to correct files
+## NB: this may create duplicate ChangeLog entries for current day,
+## watch out!
+## Use 'make releaseclean' if giving up, to remove temp dirs.
+##
+## No facility to edit html to make a full release in this makefile.
+## Too much effort for infrequenty used function.
+## Must edit download.html and doc.html by hand, then run
+##
+## make releaseall VERSION=2.0
+##
+## Or similar to make the required version.
+##
+## To customize the tags in case of a re-release with the same official
+## version:
+##
+## make releaseall VERSION=2.0 FULLVERSION=2.0.1
+##
+## NB: if this release is made from an old branch, beware that html
+## files (news!) etc, will all be downgraded. To fix, make a
+## development release immediately afterwards.
+##
+## $Id$
+##
+###########################################################################
+
+# Names and real mail addresses of developers
+# Arguments for rcs2log for ChangeLog target
+
+DEVELOPERS=\
+-u "da David Aspinall da@proofgeneral.org" \
+-u "markus Markus Wenzel wenzelm@informatik.tu-muenchen.de" \
+-u "pier Pierre Courtieu courtieu@lri.fr" \
+-u "crr Christophe Raffalli Christophe.Raffalli@univ-savoie.fr" \
+-u "pxc Paul Callaghan P.C.Callaghan@durham.ac.uk" \
+-u "patrl Patrick Loiseleur Patrick.Loiseleur@lri.fr" \
+-u "tms Thomas Kleymann tms@dcs.ed.ac.uk" \
+-u "djs Dilip Sequiera djs@dcs.ed.ac.uk" \
+-u "hhg Healfdene Goguen hhg@dcs.ed.ac.uk"
+
+
+
+# PRERELEASE_PREFIX is used to match PRERELEASE_TAG in sed
+# line in tag target below, which edits $(DOWNLOADHTML)
+PRERELEASE_PREFIX=3\.4pre
+PRERELEASE_TAG=3.4pre$(shell date "+%y%m%d")
+PREREL_TAG_FILE=prereltag.txt
+
+DOWNLOADHTML=develdownload.php
+DOWNLOADINFOHTML=devel.html
+
+# This is used for full releases to control the tag name
+# and distribution name. No editing of html is done
+# when PRERELEASE_TAG != VERSION
+VERSION=$(PRERELEASE_TAG)
+
+# Date stamp used in file if we're making a full release.
+DATEMSG=$(shell if [ $(PRERELEASE_TAG) = $(VERSION) ]; then echo; else date "+ on %a %e %b %Y"; fi)
+
+
+NAME = ProofGeneral
+LATESTNAME = $(NAME)-latest
+DEVELLATESTNAME = $(NAME)-devel-latest
+
+VERSIONVARIABLE=proof-general-version
+VERSIONFILE=proof-site.el
+
+# Full version number defaults to ordinary version number.
+FULLVERSION=$(VERSION)
+
+# NB: CVS tags can't have points in them.
+# Substitute points for hyphens.
+CVS_VERSION=$(shell echo $(FULLVERSION) | sed 's/\./-/g')
+
+# Name of tar file and RPM file.
+RELEASENAME = $(NAME)-$(VERSION)
+DEVELRELEASENAME = $(NAME)-$(VERSION)-devel
+CVS_RELEASENAME = Release-$(CVS_VERSION)
+
+# Where to release (i.e. copy) a new distribution to
+RELEASEDIR = /home/proofgen/www/
+
+# How to make the release "live". (Could be "true" to do nothing).
+# GOLIVE="scp -r $RELEASEDIR tweed:/home/proofgen/www"
+GOLIVE=true
+
+CVSNAME = ProofGeneral
+
+# Remote commands to use CVS in server mode and install files.
+# With these settings the build can be done remotely.
+# CVSROOT = :ext:$(USER)@$(MACHINE).dcs.ed.ac.uk:/home/proofgen/src
+# CVSROOT = /home/proofgen/src
+# CVS_RSH=ssh
+MACHINE=scar
+CVSROOT = :ext:da@$(MACHINE).dcs.ed.ac.uk:/home/proofgen/src
+
+# Emacs for batch compiling
+BATCHEMACS=xemacs -batch -q -no-site-file
+
+# GNU version of tar, please
+TAR=tar
+# zip utility
+ZIP=zip
+
+# For recursive make
+DEVELMAKE=make -f Makefile.devel
+
+# Files not to include the distribution area or tarball
+NONDISTFILES=.cvsignore */.cvsignore html Makefile.devel Makefile.xemacs doc/notes.txt doc/ProofGeneral.dvi doc/PG-adapting.dvi doc/ProofGeneralPortrait.eps* images/*.xcf images/notes.txt images/gimp images/Makefile etc/lego etc/coq etc/demoisa etc/isa etc/isar etc/lego etc/patches etc/pgkit etc/*.txt pgkit
+
+# Files not to include in the ordinary distribution tarball, but left
+# in the server's copy of the distribution.
+# NB: these are *patterns* to exclude rather than files!
+# I would rather have files themselves to exclude, but
+# seems to be no way.
+IGNOREDFILES=ProofGeneral*/Makefile.devel ProofGeneral*/todo ProofGeneral*/ChangeLog ProofGeneral*/doc/ProofGeneral.dvi ProofGeneral*/doc/ProofGeneral.ps.gz ProofGeneral*/doc/ProofGeneral.pdf ProofGeneral*/doc/PG-adapting.ps.gz ProofGeneral*/doc/PG-adapting.pdf ProofGeneral/*/todo
+
+# Temporary directory to to build a distribution in
+DISTBUILDIR = /tmp/ProofGeneralRelease
+
+# Temporary RPM topdir for building packages as non-root user.
+RPMTOPDIR=/tmp/$(NAME)-rpm
+# rpm 3.0 has changed rc file beyond recognition.
+# now wants a macro file included and stuck in ~/.rpmmacros.
+# Alternative is to use --define from command line.
+# RPMRC=$(RPMTOPDIR)/rpmrc
+# RPM=rpm --rcfile $(RPMRC)
+RPM=rpm --define '_topdir $(RPMTOPDIR)'
+
+RELEASENAMETAR = $(RELEASENAME).tar
+RELEASENAMETARGZ = $(RELEASENAMETAR).gz
+RELEASENAMEZIP = $(RELEASENAME).zip
+# What the RPM should be called.
+RELEASENAMERPM = $(RELEASENAME)-1.noarch.rpm
+
+DEVELRELEASENAMETAR = $(DEVELRELEASENAME).tar
+DEVELRELEASENAMETARGZ = $(DEVELRELEASENAMETAR).gz
+
+# Files not kept under cvs to clean away.
+FILES_NONCVS = TAGS
+
+# Where to install a distribution
+# DISTINSTALLDIR=/usr/local/share/elisp/proofgeneral
+# value for dcs.ed.ac.uk:
+DISTINSTALLDIR=/export/local/share/elisp
+
+# Copied from distributed Makefile
+ELISP_DIRS=generic lego coq isa isar plastic demoisa hol98 phox twelf acl2
+SUBDIRS=$(ELISP_DIRS) etc doc html images
+
+PWD=$(shell pwd)
+
+BYTECOMP = $(BATCHEMACS) -eval '(setq load-path (append (list "$(PWD)/generic" "$(PWD)/lego" "$(PWD)/coq" "$(PWD)/isa" "$(PWD)/isar") load-path))' -f batch-byte-compile
+
+EL=$(shell for f in $(ELISP_DIRS); do ls $$f/*.el; done)
+ELC=$(EL:.el=.elc)
+
+.SUFFIXES: .el .elc
+
+.el.elc:
+ $(BYTECOMP) $*.el
+
+%.gz: %
+ gzip -f $*
+
+FORCE:
+
+# Targets to pre-compile for distribution
+# Slightly dodgy to include elisp compile here, because
+# it can be incompatible across emacs versions.
+alldist: distdocs
+
+
+############################################################
+#
+# Make tags file
+#
+tags: $(EL)
+ etags $(EL) doc/ProofGeneral.texi > TAGS
+
+
+
+############################################################
+#
+# Add recent messages to ChangeLog. CVSROOT must be set correctly.
+#
+ChangeLog: FORCE
+ rcs2log -h "dcs.ed.ac.uk" $(DEVELOPERS) | sed 's|/home/proofgen/src/ProofGeneral/||g' > ChangeLog.prefix
+ mv ChangeLog ChangeLog.old
+ cat ChangeLog.prefix ChangeLog.old > ChangeLog
+ rm ChangeLog.prefix ChangeLog.old
+
+############################################################
+#
+# Clean up intermediate files
+#
+clean:
+ (cd doc; $(MAKE) clean)
+ (cd images; $(MAKE) clean)
+ rm -f doc/ProofGeneralPortrait.eps.gz
+ rm -f html/ProofGeneral
+
+
+
+############################################################
+#
+# Clean up intermediate files, all generated files
+# and Emacs backups, CVS temps
+#
+distclean: clean
+ find . \( -name '*~' -o -name '#*#' -o -name '\.\#*' \) -print | xargs rm -f
+ (cd doc; $(MAKE) distclean)
+ (cd images; $(MAKE) distclean)
+
+############################################################
+#
+# Clean up all non-cvs files.
+#
+cvsclean: clean
+ rm -rf $(FILES_NONCVS)
+ (cd doc; $(MAKE) distclean)
+ (cd images; $(MAKE) cvsclean)
+
+
+############################################################
+#
+# autoloads in generic/
+#
+autoloads: $(EL)
+ $(BATCHEMACS) -eval '(setq autoload-package-name "proof" generated-autoload-file "$(PWD)/generic/proof-autoloads.el")' -f batch-update-autoloads generic/
+
+
+
+############################################################
+#
+# Documentation
+#
+doc: FORCE
+ (cd doc; $(MAKE) doc)
+
+distdocs: FORCE
+ (cd doc; ln -s ../html/ProofGeneralPortrait.eps.gz .; $(MAKE) dist)
+
+############################################################
+#
+# Images
+#
+images: FORCE
+ (cd images; $(MAKE) images)
+
+
+
+
+############################################################
+##
+## tag: tag the CVS sources of working directory with CVS_RELEASENAME,
+## set version stamp in proof-site.el and ProofGeneral.spec
+## to VERSION, and edit $(DOWNLOADHTML) and $(DOWNLOADINFOHTML)
+## if VERSION matches PRERELEASE_TAG.
+##
+tag:
+ @echo "*************************************************"
+ @echo " Tagging sources... (rerun if CVS source dirty)"
+ @echo "*************************************************"
+# Update the sources, this is almost always what we want to do.
+ if [ -z "$(NOCVS)" ] && [ -n "`cvs -n -q update`" ]; then cvs update -d; exit 1; fi
+# Tag proof-site.el and ProofGeneral.spec
+ (cd generic; mv $(VERSIONFILE) $(VERSIONFILE).old; sed -e 's/defconst $(VERSIONVARIABLE) \".*\"/defconst $(VERSIONVARIABLE) \"Proof General Version $(FULLVERSION). Released by da$(DATEMSG).\"/g' $(VERSIONFILE).old > $(VERSIONFILE); rm $(VERSIONFILE).old)
+ (cd etc; mv ProofGeneral.spec ProofGeneral.spec.old; sed -e 's/Version:.*$$/Version: $(VERSION)/g' ProofGeneral.spec.old > ProofGeneral.spec; rm ProofGeneral.spec.old)
+# Edit $(DOWNLOADHTML) only for prereleases.
+# Careful: the sed command below relies on previous value of PRERELEASE_TAG.
+ if [ $(PRERELEASE_TAG) = $(VERSION) ]; then \
+ (cd html; mv $(DOWNLOADHTML) $(DOWNLOADHTML).old; sed -e 's|ProofGeneral-$(PRERELEASE_PREFIX)......|ProofGeneral-$(PRERELEASE_TAG)|g' $(DOWNLOADHTML).old > $(DOWNLOADHTML); rm $(DOWNLOADHTML).old); \
+ (cd html; mv $(DOWNLOADINFOHTML) $(DOWNLOADINFOHTML).old; sed -e 's|ProofGeneral-$(PRERELEASE_PREFIX)......|ProofGeneral-$(PRERELEASE_TAG)|g' $(DOWNLOADINFOHTML).old > $(DOWNLOADINFOHTML); rm $(DOWNLOADINFOHTML).old) \
+ fi
+# This hack to SOURCE: name is only needed because we have an obsolete version
+# of rpm installed on standard machines at dcs.ed, and we have to build with
+# that version. Otherwise we could use the %{version} macro in the spec file.
+ (cd etc; mv ProofGeneral.spec ProofGeneral.spec.old; sed -e 's/ProofGeneral-.*.tar.gz/$(RELEASENAMETARGZ)/g' ProofGeneral.spec.old > ProofGeneral.spec; rm ProofGeneral.spec.old)
+ (cd etc; mv ProofGeneral.spec ProofGeneral.spec.old; sed -e 's/ProofGeneral-.*.zip/$(RELEASENAMEZIP)/g' ProofGeneral.spec.old > ProofGeneral.spec; rm ProofGeneral.spec.old)
+ if [ -z "$(NOCVS)" ]; then cvs commit -m"Set version tag for new release." generic/$(VERSIONFILE) html/$(DOWNLOADHTML) html/$(DOWNLOADINFOHTML) etc/ProofGeneral.spec; fi
+ if [ -z "$(NOCVS)" ]; then cvs tag "$(CVS_RELEASENAME)"; fi
+
+############################################################
+##
+## untag: Remove the CVS_RELEASENAME tag from the CVS sources.
+##
+
+untag:
+ cvs tag -d "$(CVS_RELEASENAME)"
+
+
+############################################################
+##
+## dist: make a distribution in DISTBUILDIR from CVS sources
+## Builds for user-distribution, from sources tagged
+## with CVS_RELEASENAME.
+## Moves html files to parent directory, removes
+## non-distributed files.
+##
+dist:
+ @echo "*************************************************"
+ @echo " Cleaning dist build directory..."
+ @echo "*************************************************"
+ rm -rf $(DISTBUILDIR)
+ mkdir -p $(DISTBUILDIR)
+ @echo "*************************************************"
+ @echo " Running cvs export .."
+ @echo "*************************************************"
+ if [ -z "$(NOCVS)" ]; then \
+ (cd $(DISTBUILDIR); cvs export -kv -r "$(CVS_RELEASENAME)" -d $(RELEASENAME) $(CVSNAME)); \
+ else \
+ mkdir -p $(DISTBUILDIR)/$(RELEASENAME); \
+ cp -pr . $(DISTBUILDIR)/$(RELEASENAME); \
+ fi
+ @echo "*************************************************"
+ @echo " Running 'make alldist' for new release .."
+ @echo "*************************************************"
+ (cd $(DISTBUILDIR)/$(RELEASENAME); $(DEVELMAKE) alldist)
+ (cd $(DISTBUILDIR)/$(RELEASENAME); $(DEVELMAKE) clean)
+ @echo "*************************************************"
+# @echo " Copying doc files .."
+# @echo "*************************************************"
+# (cp -pr $(DISTBUILDIR)/$(RELEASENAME)/doc $(DISTBUILDIR))
+ @echo "*************************************************"
+ @echo " Moving html files .."
+ @echo "*************************************************"
+ (cd $(DISTBUILDIR)/$(RELEASENAME)/html; mv * ../..)
+ @echo "*************************************************"
+ @echo " Cleaning non-distributed files .."
+ @echo "*************************************************"
+ (cd $(DISTBUILDIR)/$(RELEASENAME); rm -rf $(NONDISTFILES))
+ @echo "*************************************************"
+ @echo " Making compressed tar file..."
+ @echo "*************************************************"
+ for f in $(IGNOREDFILES); do echo $$f >> ignoredfiles; done
+ (cd $(DISTBUILDIR); ln -sf $(RELEASENAME) $(NAME))
+ $(TAR) cvzf $(DISTBUILDIR)/$(RELEASENAMETARGZ) -C $(DISTBUILDIR) $(RELEASENAME) $(NAME) -X ignoredfiles
+ rm -f ignoredfiles
+ @echo "*************************************************"
+ @echo " Making zip file..."
+ @echo "*************************************************"
+ (cd $(DISTBUILDIR); for f in $(IGNOREDFILES); do echo $$f >> ignoredfiles; done)
+ (cd $(DISTBUILDIR); $(ZIP) -r $(RELEASENAMEZIP) $(RELEASENAME) -x@ignoredfiles)
+ rm -f ignoredfiles
+ @echo "*************************************************"
+ @echo " Finished making dist."
+ @echo "*************************************************"
+
+############################################################
+##
+## develdist: make a distribution for developers from
+## raw CVS sources, updating the ChangeLog.
+##
+develdist:
+ @echo "*************************************************"
+ @echo " Making developer distribution..."
+ @echo "*************************************************"
+ mkdir -p $(DISTBUILDIR)
+ if [ -z "$(NOCVS)" ]; then \
+ (make devel.ChangeLog; cvs commit -m"Updated." ChangeLog; cd $(DISTBUILDIR); cvs export -kv -r "$(CVS_RELEASENAME)" -d $(DEVELRELEASENAME) $(CVSNAME)) \
+ else \
+ mkdir -p $(DISTBUILDIR)/$(DEVELRELEASENAME); \
+ cp -pr . $(DISTBUILDIR)/$(DEVELRELEASENAME); \
+ fi
+ $(TAR) cvzf $(DISTBUILDIR)/$(DEVELRELEASENAMETARGZ) -C $(DISTBUILDIR) $(DEVELRELEASENAME)
+
+
+############################################################
+##
+## release:
+## tag the CVS sources, and make a distribution.
+## Then install the distribution in RELEASEDIR
+## WARNING: RELEASEDIR is not cleaned, but files there
+## with same names will be overwritten.
+## Moreover, a link ProofGeneral -> ProofGeneral-<version>
+## is made.
+##
+release: distclean tag dist develdist
+ mkdir -p $(RELEASEDIR)
+# clean destination a bit. NB: link RELEASENAME->NAME is copied,
+# so we remove that too.
+ (cd $(RELEASEDIR); rm -f $(NAME); rm -rf $(RELEASENAME))
+ cp -pfdr $(DISTBUILDIR)/* $(RELEASEDIR)
+ (cd $(RELEASEDIR); ln -sf $(RELEASENAMETARGZ) $(LATESTNAME).tar.gz)
+ (cd $(RELEASEDIR); ln -sf $(RELEASENAMEZIP) $(LATESTNAME).zip)
+ (cd $(RELEASEDIR); ln -sf $(RELEASENAME)-1.noarch.rpm $(LATESTNAME).noarch.rpm)
+ (cd $(RELEASEDIR); ln -sf $(DEVELRELEASENAMETARGZ) $(DEVELLATESTNAME).tar.gz)
+ (cd $(RELEASEDIR); echo $(PRERELEASE_TAG) > $(PREREL_TAG_FILE))
+ @echo "*************************************************"
+ @echo " Finished installing dist."
+ @echo "*************************************************"
+
+
+############################################################
+##
+## rpm:
+## Build an RPM binary package from the recently made distribution
+## using the tarball. (Any user could do this)
+##
+##
+rpm:
+ rm -rf $(RPMTOPDIR)
+ mkdir -p $(RPMTOPDIR)/RPMS
+ mkdir -p $(RPMTOPDIR)/SPECS
+ mkdir -p $(RPMTOPDIR)/SOURCES
+ mkdir -p $(RPMTOPDIR)/BUILD
+ $(RPM) -tb $(DISTBUILDIR)/$(RELEASENAMETARGZ)
+
+############################################################
+##
+## rpmrelease:
+## Build and install RPM package into RELEASEDIR.
+##
+rpmrelease: rpm
+ cp -pf $(RPMTOPDIR)/RPMS/noarch/* $(RELEASEDIR)
+
+############################################################
+##
+## releaseclean:
+## Clean up temporary directories after building dist/release.
+##
+releaseclean:
+ rm -rf $(DISTBUILDIR) $(RPMTOPDIR)
+
+############################################################
+##
+## fakereleaseall:
+## Do everything, but don't access CVS. Just for
+## testing on non-live system, really.
+##
+##
+fakereleaseall:
+ $(MAKE) -f Makefile.devel release rpmrelease releaseclean golive NOCVS="no"
+
+############################################################
+##
+## releaseall:
+## Do everything!
+##
+## For now, don't do distinstall any more: this only works
+## for the DCS Sun machines.
+##
+releaseall: release rpmrelease releaseclean golive
+
+############################################################
+##
+## golive:
+## Execute golive command.
+##
+golive:
+ $(GOLIVE)
+
+############################################################
+##
+## releasefinal:
+## Do everything for a final release based on a pre-release.
+## Don't use
+##
+releasefinal: release rpmrelease distinstall releaseclean
+
+
+############################################################
+##
+## distinstall:
+## Do everything for a local release.
+##
+distall: distclean tag dist distinstall releaseclean
+
+
+
+############################################################
+#
+# distinstall:
+# Install distribution from $(DISTBUILDIR) into DISTINSTALLDIR
+# Clean out DISTINSTALLDIR first.
+# NB! Simple install, no attempt to put info files, etc, in
+# special places.
+#
+distinstall:
+ rm -rf $(DISTINSTALLDIR)/$(NAME)
+ mkdir -p $(DISTINSTALLDIR)
+ (cd $(DISTINSTALLDIR); \
+ $(TAR) -xpzf $(DISTBUILDIR)/$(RELEASENAMETARGZ); \
+ mv $(RELEASENAME) $(NAME))
+
+############################################################
+#
+# links:
+#
+# Make some handy links for developers.
+#
+links:
+ ln -sf ../html/ProofGeneralPortrait.eps.gz doc
+ ln -sf ../../ProofGeneral html
+
diff --git a/Makefile.xemacs b/Makefile.xemacs
new file mode 100644
index 00000000..04d34381
--- /dev/null
+++ b/Makefile.xemacs
@@ -0,0 +1,14 @@
+##
+## Makefile for Proof General XEmacs package.
+##
+## Author: David Aspinall <da@dcs.ed.ac.uk>
+##
+## Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+##
+## $Id$
+##
+## Developer use only, not part of distribution.
+##
+## make pkg - Make XEmacs format package of Proof General
+##
+
diff --git a/README b/README
new file mode 100644
index 00000000..070a5be6
--- /dev/null
+++ b/README
@@ -0,0 +1,69 @@
+Proof General --- Organize your proofs!
+=======================================
+
+Proof General is a generic Emacs interface for proof assistants.
+
+This is version 3.3 of Proof General.
+(Check the About screen for precise version number).
+
+The aim of the Proof General project is to provide a powerful and
+configurable interfaces which help user-interaction with interactive
+proof assistants. Proof General targets power users rather than
+novices, but we include general user interface niceties, such as
+toolbar and menus, which make use easier for all.
+
+Please help us with this aim! Configure Proof General for your proof
+assistant, by adding features at the generic level wherever possible.
+Send ideas, comments, patches, code to feedback@proofgeneral.org
+
+See INSTALL for installation details.
+
+See COPYING for license details.
+
+See REGISTER for registration information (please register).
+
+See doc/ for documentation of Proof General.
+
+For notes on the supported assistants, see the README files
+in the subdirectories:
+
+ acl2/ ACL2
+ phox/ PhoX
+ coq/ Coq
+ demoisa/ Demonstration instance for Isabelle
+ hol98/ HOL 98
+ isa/ Isabelle
+ isar/ Isabelle/Isar
+ lego/ LEGO
+ plastic/ Plastic
+ twelf/ Twelf
+ pgkit/ PG Kit [ in development release only ]
+
+ generic/ Generic basis for Proof General
+
+Check BUGS files for problems and issues, in this directory, and for
+specific issues, in each prover subdirectory. Please report bugs
+not mentioned in any of these files to bugs@proofgeneral.org
+
+For the latest news and downloads, or to join the user or developer
+mailing list for Proof General, visit Proof General on the web
+at: http://www.proofgeneral.org
+
+David Aspinall <da@proofgeneral.org>
+August 2001.
+
+-----
+
+NEWSFLASH: Proof General has been Emacs based so far, but plans are
+afoot to liberate it from the points and parentheses of Emacs Lisp.
+The successor framework, Proof General Kit, proposes that proof assistants
+use a *standard* XML-based protocol for interactive proof, dubbed
+PGIP. PGIP will allow a middleware layer for many interactive proof
+tools and interface components (including Emacs). The design of PGIP
+was made possible by the present Emacs-based Proof General framework.
+For more on Proof General Kit, see http://www.proofgeneral.org/kit.html
+
+
+
+
+
diff --git a/README.devel b/README.devel
new file mode 100644
index 00000000..a0517bcb
--- /dev/null
+++ b/README.devel
@@ -0,0 +1,96 @@
+-*- outline -*-
+
+* Developers Notes for Proof General
+====================================
+
+David Aspinall, March 2000.
+
+$Id$
+
+Notes here about development conventions and compatibility
+issues. Please read if you contribute to Proof General!
+
+
+** Project planning
+
+We don't use any rigorous planning mechanisms, but please use and
+maintain the simple "todo" lists. They can include lists of things to
+do as well as notes about outstanding bugs, etc. Each item is
+classified with a priority. What usually happens is that either
+something is fixed quickly, or its priority gradually decreases,
+saving much time not implementing unimportant things!
+
+Items which are based on bug/problem reports by users are given a
+higher priority by default (unless to fix them would be unreasonably
+difficult).
+
+In the top-level directory, todo holds the list of things to do in the
+generic Elisp basis and for other generic parts of the project. Each
+proof assistant then has its own todo file.
+
+
+** Coding Standards
+
+When writing your modes, please follow the Emacs Lisp Conventions
+See the Emacs Lisp reference manual, node Style Tips.
+
+** Testing
+
+Ideally, we would have an automated test suite for Proof General.
+Emacs Lisp is certainly flexible to have such a thing, but it would
+take some effort to set it up. Although automated tests could test
+functions and states for the right values, a user interface ultimately
+needs some human checks that visible appearances and user-input behave
+as expected.
+
+At the moment, we rely on the tiny example files included for each
+proof system as simple tests that basic scripting works. Multiple
+file scripting is more complex (involving cooperation with the
+prover). Some test cases should be provided in etc/<PA> as has been
+done for Lego and Isabelle.
+
+
+** Standards for each instance of PG
+
+We include a README file and low-level todo file for each prover.
+
+
+** Using custom library
+
+Please use the custom library for all variable declarations, apart
+from very low-level variables. Follow the customize group conventions
+laid out in generic/proof-config.el
+
+
+** Compatibility with different Emacsen
+
+One of the greatest problems in developing Proof General is
+maintaining compatibility across different versions of Emacs.
+
+XEmacs is the primary development (and use) platform, but we'd like to
+maintain compatibility with FSF Emacs, and the Japanicised versions of
+that. The development policy is for the main codebase to be written
+for the latest stable version of XEmacs. We follow XEmacs advice on
+removing obsolete function calls.
+
+Hopefully one day we may have a proper test suite and mechanism to
+test across different versions of Emacs. For the time being, follow
+the following tips.
+
+*** Compatibility hacks collected in proof-compat.el
+
+ - This file contains implementations/emulations of functions to
+ provide uniformity between different Emacs versions. If you
+ use a function specific to XEmacs or newer versions, consider adding
+ a conditional definition of it here to support other versions
+ for a while.
+
+*** Common Lisp macros -- Japan Emacsen have older versions
+
+ - Use (dolist (var list) body), not (dolist (var list result) body).
+
+
+
+** CVS tips
+
+ See etc/cvs-tips.txt
diff --git a/README.windows b/README.windows
new file mode 100644
index 00000000..fb4d1b37
--- /dev/null
+++ b/README.windows
@@ -0,0 +1,12 @@
+
+Proof General now works under Windows with the following restrictions:
+
+- Only tested with PhoX mode.
+
+- Only tested with XEmacs for win32 version 21.1.9 and 21.4.3 (not
+ tested with XEmacs cygwin or any other version)
+
+- Toolbar: enablers do not work so the buttons are always active
+
+
+[ Christoph Rafalli <Christophe.Raffalli@univ-savoie.fr>, 1.8.01 ] \ No newline at end of file
diff --git a/REGISTER b/REGISTER
new file mode 100644
index 00000000..e315a71e
--- /dev/null
+++ b/REGISTER
@@ -0,0 +1,12 @@
+Please register your use of Proof General on the web at:
+
+ http://www.proofgeneral.org/register
+
+The information provided will only be used to help provide a case for
+support for Proof General in the future.
+
+There is also an opportunity to join the mailing list from this page.
+To add or remove yourself from the mailing list after registering, go
+to:
+
+ http://www.proofgeneral.org/mailinglist
diff --git a/TODO b/TODO
new file mode 100644
index 00000000..f163c797
--- /dev/null
+++ b/TODO
@@ -0,0 +1,52 @@
+This is our brief list of planned things to do to Proof General.
+
+$Id$
+
+See also the Proof General projects page on the web, under the
+development section of the home page. Also, see the appendix "Plans
+and Ideas" in the manual, and for low-level detail, the file "todo" in
+the developer release.
+
+Please send any suggestions, comments, or offers of help to
+proofgen@dcs.ed.ac.uk. Thanks!
+
+
+Plans for upcoming versions
+---------------------------
+
+* Support more proof assistants
+
+* Add a browser mode for browsing script files
+ and/or theory data-structures in the prover.
+
+* More flexible goals buffer mode to allow menus of
+ common proof commands.
+
+* Unified context (right-button) menu in and out of spans.
+ Including paste option and other editing commands.
+
+* Implement ideas in the Proof General White Paper.
+ (See the Development section of the web page for a link).
+
+* A more flexible way of choosing which instance of PG we want,
+ allowing matches on the buffer before choosing the mode function.
+
+* Isabelle PG: Non-blocking for .thy loading from .ML files.
+
+* Generic adjusting of pretty-printer line width (currently implemented
+ in several instances)
+
+* Queue manipulation improvment: allow to extend or reduce
+ during processing, with fewer "Proof Process Busy" messages.
+
+* Improve process handling: disable interrupts and/or catch errors at
+ crucial points in code so that C-g can safely be used during script
+ processing. Handle deleted buffers smoothly.
+
+* Implement "Atomic Command Sequence" idea, or something like
+ it. To allow more flexible understanding of undo behaviour
+ of proof assistants. Alternative is to base markup of
+ undoable regions on proof assistant output or messages.
+
+* Make an XEmacs package
+
diff --git a/acl2/README b/acl2/README
new file mode 100644
index 00000000..fbe93440
--- /dev/null
+++ b/acl2/README
@@ -0,0 +1,22 @@
+ACL2 Proof General, for ACL2.
+
+Written by David Aspinall.
+
+Status: alpha; unsupported
+Maintainer: volunteer required
+ACL2 version: Tested briefly with acl2.5
+ACL2 homepage: http://www.cs.utexas.edu/users/moore/acl2
+
+========================================
+
+This is the absolute bare beginnings of a PG instance for ACL2.
+At the moment, only basic script management is configured.
+
+I have written this in the hope that somebody from the ACL2 community
+will adopt it, maintain and improve it, and thus turn it into a proper
+instantiation of Proof General.
+
+
+
+$Id$
+
diff --git a/acl2/acl2.el b/acl2/acl2.el
new file mode 100644
index 00000000..90a4486b
--- /dev/null
+++ b/acl2/acl2.el
@@ -0,0 +1,71 @@
+;; acl2.el Basic Proof General instance for ACL2
+;;
+;; Copyright (C) 2000 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; Needs improvement!
+;;
+;; See the README file in this directory for information.
+
+
+(require 'proof-easy-config) ; easy configure mechanism
+(require 'proof-syntax) ; functions for making regexps
+
+(setq auto-mode-alist ; ACL2 uses two file extensions
+ (cons ; Only grab .lisp extension after
+ (cons "\\.lisp$" 'acl2-mode) ; an acl2 file has been loaded
+ auto-mode-alist))
+
+(proof-easy-config 'acl2 "ACL2"
+ proof-assistant-home-page "http://www.cs.utexas.edu/users/moore/acl2"
+ proof-prog-name "acl2"
+
+ proof-script-sexp-commands t
+ proof-comment-start ";"
+ proof-comment-start ";"
+
+ proof-shell-annotated-prompt-regexp "ACL2[ !]*>+"
+
+ proof-shell-error-regexp "^Error: "
+ proof-shell-interrupt-regexp "Correctable error: Console interrupt."
+ proof-shell-prompt-pattern "ACL2[ !]*>+"
+
+ proof-shell-quit-cmd ":q" ;; FIXME: followed by C-d.
+ proof-shell-restart-cmd "#." ;; FIXME: maybe not?
+ proof-info-command ":help"
+
+ ;;
+ ;; Syntax table entries for proof scripts (FIXME: incomplete)
+ ;;
+ proof-script-syntax-table-entries
+ '(?\[ "(] "
+ ?\] "([ "
+ ?\( "() "
+ ?\) ")( "
+ ?. "w"
+ ?_ "w"
+ ?\' "' "
+ ?` "' "
+ ?, "' "
+ ?\| "."
+ ?\; "< "
+ ?\n "> "
+ )
+
+ ;; End of easy config.
+ )
+
+;; Interrupts and errors enter another loop; break out of it
+(add-hook
+ 'proof-shell-handle-error-or-interrupt-hook
+ (lambda () (proof-shell-insert ":q" nil)))
+
+
+
+(warn "ACL2 Proof General is incomplete! Please help improve it!
+Read the manual, make improvements and send them to feedback@proofgeneral.org")
+
+(provide 'acl2)
diff --git a/acl2/example.acl2 b/acl2/example.acl2
new file mode 100644
index 00000000..a493ab1a
--- /dev/null
+++ b/acl2/example.acl2
@@ -0,0 +1,13 @@
+;; Example proof script for ACL2 Proof General.
+;;
+;; $Id$
+;;
+
+(defthm assoc->assoc-equal
+ (equal (assoc x a)
+ (assoc-equal x a)))
+
+(defthm assoc->assoc-equal
+ (equal (assoc x a)
+ (assoc-equal x a)))
+
diff --git a/acl2/x-symbol-acl2.el b/acl2/x-symbol-acl2.el
new file mode 100644
index 00000000..b532d708
--- /dev/null
+++ b/acl2/x-symbol-acl2.el
@@ -0,0 +1,85 @@
+;; x-symbol-acl2.el
+;;
+;; David Aspinall, adapted from file supplied by David von Obheimb
+;;
+;; $Id$
+;;
+
+(defvar x-symbol-acl2-symbol-table
+ '((longarrowright () "->" "\\<longrightarrow>")
+ (longarrowdblright () "==>" "\\<Longrightarrow>")
+ (logicaland () "/\\" "\\<and>")
+ (logicalor () "\\/" "\\<or>")
+ (equivalence () "<->" "\\<equiv>")
+ (existential1 () "EX" "\\<exists>")
+ (universal1 () "ALL" "\\<forall>")
+ ;; some naughty ones, but probably what you'd like
+ ;; (a mess in words like "searching" "philosophy" etc!!)
+ (Gamma () "Gamma" "\\<Gamma>")
+ (Delta () "Delta" "\\<Delta>")
+ (Theta () "Theta" "\\<Theta>")
+ (Lambda () "Lambda" "\\<Lambda>")
+ (Pi () "Pi" "\\<Pi>")
+ (Sigma () "Sigma" "\\<Sigma>")
+ (Phi () "Phi" "\\<Phi>")
+ (Psi () "Psi" "\\<Psi>")
+ (Omega () "Omega" "\\<Omega>")
+ (alpha () "alpha" "\\<alpha>")
+ (beta () "beta" "\\<beta>")
+ (gamma () "gamma" "\\<gamma>")
+ (delta () "delta" "\\<delta>")
+ (epsilon1 () "epsilon" "\\<epsilon>")
+ (zeta () "zeta" "\\<zeta>")
+ (eta () "eta" "\\<eta>")
+ (theta1 () "theta" "\\<theta>")
+ (kappa1 () "kappa" "\\<kappa>")
+ (lambda () "lambda" "\\<lambda>")
+; (mu () "mu" "\\<mu>")
+; (nu () "nu" "\\<nu>")
+; (xi () "xi" "\\<xi>")
+; (pi () "pi" "\\<pi>")
+ (rho () "rho" "\\<rho>")
+ (sigma () "sigma" "\\<sigma>")
+ (tau () "tau" "\\<tau>")
+ (phi1 () "phi" "\\<phi>")
+; (chi () "chi" "\\<chi>")
+ (psi () "psi" "\\<psi>")
+ (omega () "omega" "\\<omega>")))
+
+;; All the stuff X-Symbol complains about
+(defvar x-symbol-acl2-master-directory 'ignore)
+(defvar x-symbol-acl2-image-searchpath '("./"))
+(defvar x-symbol-acl2-image-cached-dirs '("images/" "pictures/"))
+(defvar x-symbol-acl2-image-keywords nil)
+(defvar x-symbol-acl2-font-lock-keywords nil)
+(defvar x-symbol-acl2-header-groups-alist nil)
+(defvar x-symbol-acl2-class-alist
+ '((VALID "Acl2 Symbol" (x-symbol-info-face))
+ (INVALID "no Acl2 Symbol" (red x-symbol-info-face))))
+(defvar x-symbol-acl2-class-face-alist nil)
+(defvar x-symbol-acl2-electric-ignore nil)
+(defvar x-symbol-acl2-required-fonts nil)
+(defvar x-symbol-acl2-case-insensitive nil)
+;; Setting token shape prevents "philosophy" example, but still
+;; problems, e.g. delphi, false1. (Pierre)
+(defvar x-symbol-acl2-token-shape '(?_ "[A-Za-z]+" . "[A-Za-z_]"))
+(defvar x-symbol-acl2-table x-symbol-acl2-symbol-table)
+(defun x-symbol-acl2-default-token-list (tokens) tokens)
+(defvar x-symbol-acl2-token-list 'x-symbol-acl2-default-token-list)
+(defvar x-symbol-acl2-input-token-ignore nil)
+
+;; internal stuff
+(defvar x-symbol-acl2-exec-specs nil)
+(defvar x-symbol-acl2-menu-alist nil)
+(defvar x-symbol-acl2-grid-alist nil)
+(defvar x-symbol-acl2-decode-atree nil)
+(defvar x-symbol-acl2-decode-alist nil)
+(defvar x-symbol-acl2-encode-alist nil)
+(defvar x-symbol-acl2-nomule-decode-exec nil)
+(defvar x-symbol-acl2-nomule-encode-exec nil)
+
+(warn "Acl2 support for X-Symbol is highly incomplete! Please help improve it!
+Send improvements to x-symbol-acl2.el to proofgen@proofeneral.org")
+
+
+(provide 'x-symbol-acl2)
diff --git a/bin/proofgeneral b/bin/proofgeneral
new file mode 100644
index 00000000..8276f9bf
--- /dev/null
+++ b/bin/proofgeneral
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Simple shell script for launching Proof General.
+#
+# Uses XEmacs in preference to Emacs
+#
+# You must edit PGHOME to the directory where (the lisp files of)
+# Proof General is installed.
+#
+# $Id$
+#
+
+PGHOME=/usr/share/emacs/ProofGeneral
+#PGHOME=~/ProofGeneral
+
+if which xemacs > /dev/null; then
+ EMACS=xemacs
+else
+ EMACS=emacs
+fi
+
+$EMACS -q -l $PGHOME/generic/proof-site.el -f proof-splash-display-screen "$@"
diff --git a/coq/BUGS b/coq/BUGS
new file mode 100644
index 00000000..daf31a4d
--- /dev/null
+++ b/coq/BUGS
@@ -0,0 +1,27 @@
+-*- mode:outline -*-
+
+* Coq Proof General Bugs
+
+See also ../BUGS for generic bugs.
+
+** With new syntax in Coq 7, comments at end of files cannot be processed.
+
+Leads to annoying retract/process questions when switching buffers.
+Workaround: don't use a comment as the last line of the buffer, for now.
+
+
+** coqtags doesn't find all declarations.
+
+It cannot handle lists e.g., with "Parameter x,y:nat" it only tags x
+but not y. [The same problem exists for legotags] Workaround: don't
+rely too much on the etags mechanism.
+
+** User defined tactics cannot be retracted.
+
+ Workaround: you may need to retract to the beginning of the proof.
+
+** Coq Proof General does not know about Coq's Section mechanism.
+
+** Surely others that aren't mentioned here...
+
+ Please report them to proofgen@dcs.ed.ac.uk.
diff --git a/coq/README b/coq/README
new file mode 100644
index 00000000..f9626a25
--- /dev/null
+++ b/coq/README
@@ -0,0 +1,38 @@
+Coq Proof General
+
+Originally written by Healfdene Goguen.
+Later contributions by Patrick Loiseleur, Pierre Courtieu,
+ David Aspinall
+
+Status: supported
+Maintainer: Pierre Courtieu
+Coq version: 6.3, 6.3.1, 7.0
+Coq homepage: http://pauillac.inria.fr/coq/assis-eng.html
+
+========================================
+
+Coq Proof General has experimental multiple file handling for 6.3
+versions. It does not have support for proof by pointing.
+
+There is support for X Symbol, but not using a proper token language.
+
+There is a tags program, coqtags.
+
+========================================
+
+Installation notes:
+
+Check the values of coq-tags and coq-prog-name in coq.el to see that
+they correspond to the paths for coqtop and the library on your system.
+
+Install coqtags in a standard place or add <proof-home>/coq to your PATH.
+NB: You may need to change the path to perl at the top of the file.
+
+Generate a TAGS file for the library by running
+ coqtags `find . -name \*.v -print`
+in the root directory of the library, $COQTOP/theories.
+
+
+========================================
+
+$Id$
diff --git a/coq/coq-syntax.el b/coq/coq-syntax.el
new file mode 100644
index 00000000..898cc17d
--- /dev/null
+++ b/coq/coq-syntax.el
@@ -0,0 +1,354 @@
+;; coq-syntax.el Font lock expressions for Coq
+;; Copyright (C) 1997, 1998 LFCS Edinburgh.
+;; Authors: Thomas Kleymann and Healfdene Goguen
+;; Maintainer: Patrick Loiseleur <Patrick.Loiseleur@lri.fr>
+
+;; $Id$
+
+(require 'proof-syntax)
+
+;; ----- keywords for font-lock.
+
+(defvar coq-keywords-decl
+ '(
+"Axiom[s]?"
+"Hypotheses"
+"Hypothesis"
+"Parameter[s]?"
+;; da: 3.2 I added Section here, to try to fix undo for Sections working
+;; better.
+;;Pierre : Chapter also
+"Chapter"
+"Section"
+"Variable[s]?"
+"Global\\s-+Variable"
+;;added tactic def here because it needs Reset to be undone correctly
+"Tactic\\s-+Definition"
+))
+
+(defvar coq-keywords-defn
+ '(
+"CoFixpoint"
+"CoInductive"
+"Fixpoint"
+"Inductive"
+"Inductive\\s-+Set"
+"Inductive\\s-+Prop"
+"Inductive\\s-+Type"
+"Mutual\\s-+Inductive"
+"Record"
+"Scheme"
+))
+
+(defvar coq-keywords-goal
+ '(
+"Correctness"
+"Definition"
+"Fact"
+"Goal"
+"Lemma"
+"Local"
+"Remark"
+"Theorem"
+))
+
+(defvar coq-keywords-save
+ '(
+"Defined"
+"Save"
+"Qed"
+))
+
+(defvar coq-keywords-kill-goal '(
+"Abort"
+))
+;; commands that have to be counted when undoing
+(defvar coq-keywords-undoable-commands
+ '(
+"Focus"
+))
+
+
+(defvar coq-keywords-not-undoable-commands
+ '(
+"(*" ;;Pierre comments must not be undone
+"Add\\s-+ML\\s-+Path"
+"AddPath"
+"Begin\\s-+Silent"
+"Cd"
+"Check"
+"Class"
+"Coercion"
+"DelPath"
+"End"
+"End\\s-+Silent"
+"Eval"
+"Extraction"
+;; moving this to coq-keywords-undoable-commands
+;;"Focus"
+"Grammar"
+"Hints\\s-+Resolve"
+"Hints\\s-+Immediate"
+"Hints\\s-+Unfold"
+"HintRewrite"
+"Hint"
+"Infix"
+"Initialize"
+"Implicit\\s-+Arguments\\s-+On"
+"Implicit\\s-+Arguments\\s-+Off"
+"Load"
+"Local\\s-+Coercion"
+"Locate\\s-+File"
+"Locate\\s-+Library"
+"Locate"
+"Opaque"
+"Print\\s-+Classes"
+"Print\\s-+Coercions"
+"Print\\s-+Graph"
+"Print\\s-+Grammar"
+"Print\\s-+HintDb"
+"Print\\s-+Hint"
+"Print\\s-+LoadPath"
+"Print\\s-+ML\\s-+Path"
+"Print\\s-+ML\\s-+Modules"
+"Print"
+"Proof"
+"Pwd"
+"Require\\s-+Export"
+"Require\\s-+Import"
+"Require"
+"Reset"
+"Search"
+"SearchIsos"
+;; da: testing moving this
+;; "Section"
+"Show\\s-+Programs"
+"Show\\s-+Proof"
+"Show\\s-+Script"
+"Show"
+"Syntax"
+;;Pierre: moving this to coq-keywords-decl
+;;"Tactic\\s-+Definition"
+"Transparent"
+))
+
+
+(defvar coq-keywords-commands
+ (append coq-keywords-not-undoable-commands coq-keywords-undoable-commands)
+ "All commands keyword")
+
+
+
+(defvar coq-tactics
+ '(
+"Absurd"
+"Apply"
+"Assumption"
+"Auto"
+"AutoRewrite"
+"Case"
+"Change"
+"Clear"
+"Cofix"
+"Compute"
+"Constructor"
+"Contradiction"
+"Cut"
+"DHyp"
+"DInd"
+"Decompose"
+"Dependent\\s-+Inversion_clear"
+"Dependent\\s-+Inversion"
+"Destruct"
+"Discriminate"
+"Double"
+"EApply"
+"EAuto"
+"Elim"
+"Exact"
+"Exists"
+"Fix"
+"Generalize"
+"Hnf"
+"Induction"
+"Injection"
+"Intro[s]?"
+"Intuition"
+"Inversion_clear"
+"Inversion"
+"LApply"
+"Left"
+"Linear"
+"Load"
+"Omega"
+"Pattern"
+"Program_all"
+"Program"
+"Prolog"
+"Realizer"
+"Red"
+"Reflexivity"
+"Replace"
+"Rewrite"
+"Right"
+"Ring"
+"Simplify_eq"
+"Simpl"
+"Specialize"
+"Split"
+"Symmetry"
+"Tauto"
+"Transitivity"
+"Trivial"
+"Unfold"
+))
+
+(defvar coq-keywords
+ (append coq-keywords-goal coq-keywords-save coq-keywords-decl
+ coq-keywords-defn coq-keywords-commands)
+ "All keywords in a Coq script")
+
+(defvar coq-tacticals
+ '(
+ "Abstract"
+ "Do"
+ "Idtac"
+ "Orelse"
+ "Repeat"
+ "Try")
+ "Keywords for tacticals in a Coq script")
+
+(defvar coq-reserved
+ '(
+ "as"
+ "ALL"
+ "Cases"
+ "EX"
+ "else"
+ "end"
+ "Fix"
+ "if"
+ "in"
+ "let"
+ "of"
+ "then"
+ "using"
+ "with"
+ )
+ "Reserved keyworkds of Coq")
+
+(defvar coq-symbols
+ '(
+ "|"
+ ":"
+ ";"
+ ","
+ "("
+ ")"
+ "["
+ "]"
+ "{"
+ "}"
+ ":="
+ "=>"
+ "->"
+ "."
+ )
+ "Punctuation Symbols used by Coq")
+
+;; ----- regular expressions
+(defvar coq-error-regexp "^\\(Error\\|Discarding\\|Syntax error\\|System Error\\|Anomaly\\|Uncaught exception\\|Toplevel input\\)"
+ "A regular expression indicating that the Coq process has identified
+ an error.")
+
+(defvar coq-id proof-id)
+
+(defvar coq-ids (proof-ids coq-id))
+
+(defun coq-first-abstr-regexp (paren)
+ (concat paren "\\s-*\\(" coq-ids "\\)\\s-*:"))
+
+(defun coq-next-abstr-regexp ()
+ (concat ";[ \t]*\\(" coq-ids "\\)\\s-*:"))
+
+(defvar coq-font-lock-terms
+ (list
+
+ ;; lambda binders
+ (list (coq-first-abstr-regexp "\\[") 1 'proof-declaration-name-face)
+
+ ;; Pi binders
+ (list (coq-first-abstr-regexp "(") 1 'proof-declaration-name-face)
+
+ ;; second, third, etc. abstraction for Lambda of Pi binders
+ (list (coq-next-abstr-regexp) 1 'proof-declaration-name-face)
+
+ ;; Kinds
+ (cons "\\<Prop\\>\\|\\<Set\\>\\|\\<Type\\>" 'font-lock-type-face))
+
+ "*Font-lock table for Coq terms.")
+
+;; According to Coq, "Definition" is both a declaration and a goal.
+;; It is understood here as being a goal. This is important for
+;; recognizing global identifiers, see coq-global-p.
+(defconst coq-save-command-regexp
+ (proof-anchor-regexp (proof-ids-to-regexp coq-keywords-save)))
+(defconst coq-save-with-hole-regexp
+ (concat "\\(" (proof-ids-to-regexp coq-keywords-save)
+ "\\)\\s-+\\(" coq-id "\\)\\s-*\."))
+(defconst coq-goal-command-regexp
+ (proof-anchor-regexp (proof-ids-to-regexp coq-keywords-goal)))
+(defconst coq-goal-with-hole-regexp
+ (concat "\\(" (proof-ids-to-regexp coq-keywords-goal)
+ "\\)\\s-+\\(" coq-id "\\)\\s-*[:]?"))
+ ;; Papageno : ce serait plus propre d'omettre le `:'
+ ;; uniquement pour Correctness
+ ;; et pour Definition f [x,y:nat] := body
+(defconst coq-decl-with-hole-regexp
+ (concat "\\(" (proof-ids-to-regexp coq-keywords-decl)
+ "\\)\\s-+\\(" coq-ids "\\)\\s-*[:]"))
+(defconst coq-defn-with-hole-regexp
+ (concat "\\(" (proof-ids-to-regexp coq-keywords-defn)
+ "\\)\\s-+\\(" coq-id "\\)\\s-*[:]"))
+
+(defvar coq-font-lock-keywords-1
+ (append
+ coq-font-lock-terms
+ (list
+ (cons (proof-ids-to-regexp coq-keywords) 'font-lock-keyword-face)
+ (cons (proof-ids-to-regexp coq-tactics) 'proof-tactics-name-face)
+ (cons (proof-ids-to-regexp coq-tacticals) 'proof-tacticals-name-face)
+ (cons (proof-ids-to-regexp coq-reserved) 'font-lock-type-face)
+ (cons "============================" 'font-lock-keyword-face)
+ (cons "Subtree proved!" 'font-lock-keyword-face)
+ (cons "subgoal [0-9]+ is:" 'font-lock-keyword-face)
+ (list "^\\([^ \n]+\\) \\(is defined\\)"
+ (list 2 'font-lock-keyword-face t)
+ (list 1 'font-lock-function-name-face t))
+
+ (list coq-goal-with-hole-regexp 2 'font-lock-function-name-face)
+ (list coq-decl-with-hole-regexp 2 'proof-declaration-name-face)
+ (list coq-defn-with-hole-regexp 2 'font-lock-function-name-face)
+ (list coq-save-with-hole-regexp 2 'font-lock-function-name-face))))
+
+(defun coq-init-syntax-table ()
+ "Set appropriate values for syntax table in current buffer."
+
+ (modify-syntax-entry ?\$ ".")
+ (modify-syntax-entry ?\/ ".")
+ (modify-syntax-entry ?\\ ".")
+ (modify-syntax-entry ?+ ".")
+ (modify-syntax-entry ?- ".")
+ (modify-syntax-entry ?= ".")
+ (modify-syntax-entry ?% ".")
+ (modify-syntax-entry ?< ".")
+ (modify-syntax-entry ?> ".")
+ (modify-syntax-entry ?\& ".")
+ (modify-syntax-entry ?_ "w")
+ (modify-syntax-entry ?\' "_")
+ (modify-syntax-entry ?\| ".")
+ (modify-syntax-entry ?\* ". 23")
+ (modify-syntax-entry ?\( "()1")
+ (modify-syntax-entry ?\) ")(4"))
+
+(provide 'coq-syntax)
diff --git a/coq/coq.el b/coq/coq.el
new file mode 100644
index 00000000..8a71696f
--- /dev/null
+++ b/coq/coq.el
@@ -0,0 +1,720 @@
+;; coq.el Major mode for Coq proof assistant
+;; Copyright (C) 1994 - 1998 LFCS Edinburgh.
+;; Author: Healfdene Goguen
+;; Maintainer: Pierre Courtieu <courtieu@lri.fr>
+
+;; $Id$
+
+(require 'proof)
+(require 'coq-syntax)
+
+;; Configuration
+
+(setq tags-always-exact t) ; Tags is unusable with Coq library otherwise:
+
+(defun coq-library-directory ()
+ (let ((c (substring (shell-command-to-string "coqtop -where") 0 -1 )))
+ (if (string-match c "not found")
+ "/usr/local/lib/coq"
+ c)))
+
+
+(defcustom coq-tags (concat (coq-library-directory) "/theories/TAGS")
+ "the default TAGS table for the Coq library"
+ :type 'string
+ :group 'coq)
+
+(defconst coq-interrupt-regexp "User Interrupt."
+ "Regexp corresponding to an interrupt")
+
+(defcustom coq-default-undo-limit 100
+ "Maximum number of Undo's possible when doing a proof."
+ :type 'number
+ :group 'coq)
+
+;; ----- web documentation
+
+(defcustom coq-www-home-page "http://coq.inria.fr/"
+ "Coq home page URL."
+ :type 'string
+ :group 'coq)
+
+;; ----- coq specific menu
+
+;; Pierre: I add Print Check and PrintHint
+;; maybe Print and Check should be buttons ?
+(defpgdefault menu-entries
+ '(["Print..." coq-Print t]
+ ["Check..." coq-Check t]
+ ["Hints" coq-PrintHint t]
+ ["Intros..." coq-Intros t]
+ ["Show ith goal..." coq-Show t]
+ ["Apply" coq-Apply t]
+ ["Search isos/pattern..." coq-SearchIsos t]
+ ["Begin Section..." coq-begin-Section t]
+ ["End Section" coq-end-Section t]
+ ["Compile" coq-Compile t]))
+
+
+;; ----- coq-shell configuration options
+
+(defcustom coq-prog-name "coqtop -emacs"
+ "*Name of program to run as Coq."
+ :type 'string
+ :group 'coq)
+
+;; Command to initialize the Coq Proof Assistant
+(defconst coq-shell-init-cmd
+ (format "Set Undo %s." coq-default-undo-limit))
+
+
+;;Pierre: we will have both versions V6 and V7 during a while
+;; the test with "coqtop -v" can be skipped if the variable
+;; coq-version-is-V7 is already set (usefull for people
+;; dealing with several version of coq)
+(if (boundp 'coq-version-is-V7) () ; if this variable is bound, do nothing
+ (setq coq-version-is-V7 ; else test with "coqtop -v"
+ (if (string-match "version 7" (shell-command-to-string (concat coq-prog-name " -v")))
+ (progn (message "coq is V7") t)
+ (progn (message "coq is not V7") nil))))
+
+;; Command to reset the Coq Proof Assistant
+;; Pierre: added Impl... because of a bug of Coq until V6.3
+;; (included). The bug is already fixed in the next version (V7). So
+;; we will backtrack this someday.
+(defconst coq-shell-restart-cmd
+ "Reset Initial.\n Implicit Arguments Off.")
+
+(defvar coq-shell-prompt-pattern (concat "^" proof-id " < ")
+ "*The prompt pattern for the inferior shell running coq.")
+
+;; FIXME da: this was disabled (set to nil) -- why?
+(defvar coq-shell-cd "Cd \"%s\"."
+ "*Command of the inferior process to change the directory.")
+
+(defvar coq-shell-abort-goal-regexp "Current goal aborted"
+ "*Regexp indicating that the current goal has been abandoned.")
+
+(defvar coq-shell-proof-completed-regexp "Subtree proved!"
+ "*Regular expression indicating that the proof has been completed.")
+
+(defvar coq-goal-regexp
+ "\\(============================\\)\\|\\(subgoal [0-9]+ is:\\)\n")
+
+;; ----- outline
+
+(defvar coq-outline-regexp
+ (concat "(\\*\\|" (proof-ids-to-regexp
+ '(
+"Tactic" "Axiom" "Parameter" "Parameters" "Variable" "Variables" "Syntax" "Grammar" "Syntactic" "Load" "Require" "Hint" "Hints" "Hypothesis" "Correctness" "Section" "Chapter" "Goal" "Lemma" "Theorem" "Fact" "Remark" "Record" "Inductive" "Mutual" "Definition" "Fixpoint" "Save" "Qed" "Defined" "End" "Coercion"))))
+
+(defvar coq-outline-heading-end-regexp "\\*\)\n\\|\\.\n")
+
+(defvar coq-shell-outline-regexp coq-goal-regexp)
+(defvar coq-shell-outline-heading-end-regexp coq-goal-regexp)
+
+(defconst coq-kill-goal-command "Abort.")
+(defconst coq-forget-id-command "Reset %s.")
+
+(defconst coq-undoable-commands-regexp (proof-ids-to-regexp (append coq-tactics coq-keywords-undoable-commands)))
+
+(defconst coq-not-undoable-commands-regexp (proof-ids-to-regexp (append coq-keywords-decl coq-keywords-not-undoable-commands)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Derived modes - they're here 'cos they define keymaps 'n stuff ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(eval-and-compile
+ (define-derived-mode coq-shell-mode proof-shell-mode
+ "coq-shell" nil
+ (coq-shell-mode-config)))
+
+(eval-and-compile
+ (define-derived-mode coq-response-mode proof-response-mode
+ "CoqResp" nil
+ (coq-response-config)))
+
+(eval-and-compile
+ (define-derived-mode coq-mode proof-mode
+ "coq" nil
+ (coq-mode-config)))
+
+(eval-and-compile
+ (define-derived-mode coq-goals-mode proof-goals-mode
+ "CoqGoals" nil
+ (coq-goals-mode-config)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Code that's coq specific ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun coq-set-undo-limit (undos)
+ (proof-shell-invisible-command (format "Set Undo %s." undos)))
+
+;;
+;; FIXME Papageno 05/1999: must take sections in account.
+;;
+;; Pierre modified the test with proof-string-match, this way new tactics
+;; can be undone (I also added "(*" in not-undoable-commands)
+(defun coq-count-undos (span)
+ "Count number of undos in a span, return the command needed to undo that far."
+ (let ((ct 0) str i)
+ (if (and span (prev-span span 'type)
+ (not (eq (span-property (prev-span span 'type) 'type) 'comment))
+ (coq-goal-command-p
+ (span-property (prev-span span 'type) 'cmd)))
+ "Restart."
+ (while span
+ (setq str (span-property span 'cmd))
+ (cond ((eq (span-property span 'type) 'vanilla)
+ (if (not (proof-string-match coq-not-undoable-commands-regexp str))
+ (setq ct (+ 1 ct))))
+ ((eq (span-property span 'type) 'pbp)
+ (cond ((not (proof-string-match coq-not-undoable-commands-regexp str))
+ (setq i 0)
+ (while (< i (length str))
+ (if (= (aref str i) proof-terminal-char)
+ (setq ct (+ 1 ct)))
+ (setq i (+ 1 i))))
+ (t nil))))
+ (setq span (next-span span 'type)))
+ (concat "Undo " (int-to-string ct) "."))))
+
+(defconst coq-keywords-decl-defn-regexp
+ (proof-ids-to-regexp (append coq-keywords-decl coq-keywords-defn))
+ "Declaration and definition regexp.")
+
+;; FIXME da: this one function breaks the nice configuration of Proof General:
+;; would like to have proof-goal-regexp instead.
+;; Unfortunately Coq allows "Definition" and friends to perhaps have a goal,
+;; so it appears more difficult than just a proof-goal-regexp setting.
+;; Future improvement may simply to be allow a function value for
+;; proof-goal-regexp.
+
+(defun coq-goal-command-p (str)
+ "Decide whether argument is a goal or not"
+ (and (proof-string-match coq-goal-command-regexp str)
+ (not (proof-string-match "Definition.*:=" str))
+ (not (proof-string-match "Lemma.*:=" str))))
+
+;; TODO : add the stuff to handle the "Correctness" command
+
+(defun coq-find-and-forget (span)
+ (let (str ans)
+ (while (and span (not ans))
+ (setq str (span-property span 'cmd))
+ (cond
+
+ ((eq (span-property span 'type) 'comment))
+
+ ((eq (span-property span 'type) 'goalsave)
+ ;; Note da 6.10.99: in Lego and Isabelle, it's trivial to
+ ;; forget an unnamed theorem. Coq really does use the
+ ;; identifier "Unnamed_thm", though! So we don't need
+ ;; this test:
+ ;; (unless (eq (span-property span 'name) proof-unnamed-theorem-name)
+ (setq ans (format coq-forget-id-command (span-property span 'name))))
+
+ ((proof-string-match (concat "\\`\\(" coq-keywords-decl-defn-regexp
+ "\\)\\s-*\\(" proof-id
+ ;; da: PG 3.1: I added "." here to try
+ ;; to get undo for Section working.
+ ;; (also changes in coq-syntax)
+ ;; Coq users will have to tell me if it
+ ;; works better now or not?
+ ;; At least I can do C-c C-r in files
+ ;; with Section in them. But problem
+ ;; with closure still present:
+ ;; Section .. End Section should be
+ ;; atomic!
+ "\\)\\s-*[\\[,:.]") str)
+ (setq ans (format coq-forget-id-command (match-string 2 str))))
+
+ ;; If it's not a goal but it contains "Definition" then it's a
+ ;; declaration
+ ;; Pierre : I suppressed the ":" here, since
+ ;; "Definition foo [x:bar]..." is allowed
+ ((and (not (coq-goal-command-p str))
+ (proof-string-match
+ (concat "Definition\\s-+\\(" proof-id "\\)\\s-*") str))
+ (setq ans (format coq-forget-id-command (match-string 2 str)))))
+
+ (setq span (next-span span 'type)))
+
+ (or ans proof-no-command)))
+
+(defvar coq-current-goal 1
+ "Last goal that emacs looked at.")
+
+(defun coq-goal-hyp ()
+ (cond
+ ((looking-at "============================\n")
+ (goto-char (match-end 0))
+ (cons 'goal (int-to-string coq-current-goal)))
+ ((looking-at "subgoal \\([0-9]+\\) is:\n")
+ (goto-char (match-end 0))
+ (cons 'goal (match-string 1))
+ (setq coq-current-goal (string-to-int (match-string 1))))
+ ((looking-at proof-shell-assumption-regexp)
+ (cons 'hyp (match-string 1)))
+ (t nil)))
+
+;;
+;; This code is broken
+;;
+; (defun coq-lift-global (glob-span)
+; "This function lifts local lemmas from inside goals out to top level."
+; (let (start (next (span-at 1 'type)) str (goal-p nil))
+; (while (and next (and (not (eq next glob-span)) (not goal-p)))
+; (if (and (eq (span-property next 'type) 'vanilla)
+; (funcall proof-goal-command-p (span-property next 'cmd)))
+; (setq goal-p t)
+; (setq next (next-span next 'type))))
+
+; (if (and next (not (eq next glob-span)))
+; (progn
+; (proof-unlock-locked)
+; (setq str (buffer-substring (span-start glob-span)
+; (span-end glob-span)))
+; (delete-region (span-start glob-span) (span-end glob-span))
+; (goto-char (span-start next))
+; (setq start (point))
+; (insert str "\n")
+; (set-span-endpoints glob-span start (point))
+; (set-span-start next (point))
+; (proof-lock-unlocked)))))
+
+(defun coq-state-preserving-p (cmd)
+ (not (proof-string-match coq-undoable-commands-regexp cmd)))
+
+(defun coq-global-p (cmd)
+ (or (proof-string-match coq-keywords-decl-defn-regexp cmd)
+ (and (proof-string-match
+ (concat "Definition\\s-+\\(" coq-id "\\)\\s-*:") cmd)
+ (proof-string-match ":=" cmd))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Commands specific to coq ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun coq-SearchIsos ()
+ "Search a term whose type is isomorphic to given type
+This is specific to coq-mode."
+ (interactive)
+ (let (cmd)
+ (proof-shell-ready-prover)
+ (setq cmd (read-string
+ (if coq-version-is-V7 "SearchPattern: " "SearchIsos: ")
+ nil 'proof-minibuffer-history))
+ (proof-shell-invisible-command
+ (format (if coq-version-is-V7 "SearchPattern %s."
+ "SearchIsos %s.") cmd))))
+
+
+(defun coq-Print ()
+ "Ask for an ident and print the corresponding term"
+ (interactive)
+ (let (cmd)
+ (proof-shell-ready-prover)
+ (setq cmd (read-string "Print: " nil 'proof-minibuffer-history))
+ (proof-shell-invisible-command
+ (format "Print %s." cmd))))
+
+(defun coq-Check ()
+ "Ask for a term and print its type"
+ (interactive)
+ (let (cmd)
+ (proof-shell-ready-prover)
+ (setq cmd (read-string "Check: " nil 'proof-minibuffer-history))
+ (proof-shell-invisible-command
+ (format "Check %s." cmd))))
+
+(defun coq-Show ()
+ "Ask for a number i and show the ith goal"
+ (interactive)
+ (let (cmd)
+ (proof-shell-ready-prover)
+ (setq cmd (read-string "Show Goal number: " nil 'proof-minibuffer-history))
+ (proof-shell-invisible-command
+ (format "Show %s." cmd))))
+
+(defun coq-PrintHint ()
+ "Print all hints applicable to the current goal"
+ (interactive)
+ (proof-shell-invisible-command "Print Hint."))
+
+
+(defun coq-end-Section ()
+ "Ends a Coq section."
+ (interactive)
+ (let ((count 1)) ; The number of section already "Ended" + 1
+ (let ((section
+ (save-excursion
+ (progn
+ (while (and (> count 0)
+ (search-backward-regexp
+ "Chapter\\|Section\\|End" 0 t))
+ (if (char-equal (char-after (point)) ?E)
+ (setq count (1+ count))
+ (setq count (1- count))))
+ (buffer-string
+ (progn (beginning-of-line) (forward-word 1) (point))
+ (progn (end-of-line) (point)))))))
+ (insert (concat "End" section)))))
+
+(defun coq-Compile ()
+ "compiles current buffer"
+ (interactive)
+ (let* ((n (buffer-name))
+ (l (string-match ".v" n)))
+ (compile (concat "make " (substring n 0 l) ".vo"))))
+
+(proof-defshortcut coq-Intros "Intros " [(control ?i)])
+(proof-defshortcut coq-Apply "Apply " [(control ?a)])
+(proof-defshortcut coq-begin-Section "Section " [(control ?s)])
+
+(define-key coq-keymap [(control ?e)] 'coq-end-Section)
+(define-key coq-keymap [(control ?m)] 'coq-Compile)
+(define-key coq-keymap [(control ?o)] 'coq-SearchIsos)
+(define-key coq-keymap [(control ?p)] 'coq-Print)
+(define-key coq-keymap [(control ?c)] 'coq-Check)
+(define-key coq-keymap [(control ?h)] 'coq-PrintHint)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Indentation ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; FIXME mmw: code disabled; Is the new indentation scheme general
+;; enough to handle Coq as well?
+
+;;; "Case" is represented by 'c' on the stack, and
+;;; "CoInductive" is represented by 'C'.
+;(defun coq-stack-to-indent (stack)
+; (cond
+; ((null stack) 0)
+; ((null (car (car stack)))
+; (nth 1 (car stack)))
+; (t (let ((col (save-excursion
+; (goto-char (nth 1 (car stack)))
+; (current-column))))
+; (cond
+; ((eq (car (car stack)) ?c)
+; (save-excursion (move-to-column (current-indentation))
+; (cond
+; ((eq (char-after (point)) ?|) (+ col 3))
+; ((proof-looking-at "end") col)
+; (t (+ col 5)))))
+; ((or (eq (car (car stack)) ?I) (eq (car (car stack)) ?C))
+; (+ col (if (eq ?| (save-excursion
+; (move-to-column (current-indentation))
+; (char-after (point)))) 2 4)))
+; (t (1+ col)))))))
+;
+;(defun coq-parse-indent (c stack)
+; (cond
+; ((eq c ?C)
+; (cond ((proof-looking-at "Case")
+; (cons (list ?c (point)) stack))
+; ((proof-looking-at "CoInductive")
+; (forward-char (length "CoInductive"))
+; (cons (list c (- (point) (length "CoInductive"))) stack))
+; (t stack)))
+; ((and (eq c ?e) (proof-looking-at "end") (eq (car (car stack)) ?c))
+; (cdr stack))
+;
+; ((and (eq c ?I) (proof-looking-at "Inductive"))
+; (forward-char (length "Inductive"))
+; (cons (list c (- (point) (length "Inductive"))) stack))
+;
+; ((and (eq c ?.) (or (eq (car (car stack)) ?I) (eq (car (car stack)) ?C)))
+; (cdr stack))
+;
+; (t stack)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; To guess the command line options ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun coq-guess-command-line (filename)
+ "Guess the right command line options to compile FILENAME using `make -n'"
+ (let ((dir (file-name-directory filename)))
+ (if (file-exists-p (concat dir "Makefile"))
+ (let*
+ ((compiled-file (concat (substring
+ filename 0
+ (string-match ".v$" filename)) ".vo"))
+ (command (shell-command-to-string
+ (concat "cd " dir ";"
+ "gmake -n -W " filename " " compiled-file
+ "| sed s/coqc/coqtop/"))))
+ (concat
+ (substring command 0 (string-match " [^ ]*$" command))
+ " -emacs"))
+ coq-prog-name)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Coq shell startup and exit hooks ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun coq-pre-shell-start ()
+ (setq proof-prog-name coq-prog-name)
+ (setq proof-mode-for-shell 'coq-shell-mode)
+ (setq proof-mode-for-goals 'coq-goals-mode)
+ (setq proof-mode-for-response 'coq-response-mode)
+)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Configuring proof and pbp mode and setting up various utilities ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun coq-mode-config ()
+
+ (setq proof-terminal-char ?\.)
+ (setq proof-script-command-end-regexp
+ (if coq-version-is-V7 "[.]\\([ \t\n\r]\\)\\|[.]\\'" "[.]"))
+ (setq proof-comment-start "(*")
+ (setq proof-comment-end "*)")
+ (setq proof-unnamed-theorem-name "Unnamed_thm") ; Coq's default name
+
+ (setq proof-assistant-home-page coq-www-home-page)
+
+ (setq proof-mode-for-script 'coq-mode)
+
+ (setq proof-guess-command-line 'coq-guess-command-line)
+
+ ;; Commands sent to proof engine
+ (setq proof-showproof-command "Show."
+ proof-context-command "Print All."
+ proof-goal-command "Goal %s."
+ proof-save-command "Save %s."
+ proof-find-theorems-command "Search %s."
+;; FIXME da: Does Coq have a help or about command?
+;; proof-info-command "Help"
+ proof-kill-goal-command coq-kill-goal-command)
+
+ (setq proof-goal-command-p 'coq-goal-command-p
+ proof-count-undos-fn 'coq-count-undos
+ proof-find-and-forget-fn 'coq-find-and-forget
+ proof-goal-hyp-fn 'coq-goal-hyp
+ proof-state-preserving-p 'coq-state-preserving-p
+ proof-global-p 'coq-global-p)
+
+ (setq proof-save-command-regexp coq-save-command-regexp
+ proof-save-with-hole-regexp coq-save-with-hole-regexp
+ proof-goal-with-hole-regexp coq-goal-with-hole-regexp)
+
+ (setq
+ proof-indent-close-offset -1
+ proof-indent-any-regexp
+ (proof-regexp-alt (proof-ids-to-regexp
+ (append (list "Cases" "end") coq-keywords)) "\\s(" "\\s)")
+ proof-indent-enclose-regexp "|"
+ proof-indent-open-regexp
+ (proof-regexp-alt (proof-ids-to-regexp '("Cases")) "\\s(")
+ proof-indent-close-regexp
+ (proof-regexp-alt (proof-ids-to-regexp '("end")) "\\s)"))
+
+
+ ;; (setq proof-auto-multiple-files t) ; until Coq has real support
+ ;; da: Experimental support for multiple files based on discussions
+ ;; at TYPES 2000.
+ ;; (Pierre, please fix this as Coq users would like, and for Coq V7 !)
+ (setq coq-proof-shell-inform-file-processed-cmd
+ "Reset Initial. Compile Module %m.")
+ ;; FIXME da: Coq is rather quiet when reading files with "Load <foo>."
+ ;; and sometimes even Require seems quiet? PG would like some guarantees
+ ;; that messages are issued. Also, the code to guess the complete file
+ ;; name is flaky, would be better if Coq displayed full path info for PG.
+ (setq coq-proof-shell-process-file
+ ;; FIXME da: Coq output Reinterning message should not
+ ;; be suppressed by "Begin Silent" for PG, and should be
+ ;; marked by eager annotation (special char).
+ ;; For Coq 7, we should get rid of 8 bit chars in PG, too.
+ (cons "Reinterning \\(.+\\)\\.\\.\\.done"
+ (lambda (str)
+ (let*
+ ((modname (match-string 1 str))
+ ;; FIXME: next lines will return a directory but maybe
+ ;; not right one if proof-script-buffer happens to be nil!
+ (buf (or proof-script-buffer
+ proof-previous-script-buffer))
+ (dir (if (buffer-live-p buf)
+ (with-current-buffer buf
+ default-directory)
+ ;; This next guess is pretty hopeless.
+ default-directory)))
+ (message (concat dir modname ".v"))
+ (concat dir modname ".v")))))
+
+ (setq coq-proof-shell-inform-file-retracted-cmd
+ ;; da: This is a HORRIBLE fragile hack! Instead of issuing a
+ ;; command to the prover we have to run a "coqdep" command to
+ ;; find out the dependencies.
+ (lambda (fname)
+ (let*
+ ;; Assume buffer is in correct directory, assume current directory
+ ;; is writeable, assume we have GNU make, etc, etc.
+ ;; I hope Coq V7 will provide this operation for us as
+ ;; a builtin (it should print out a series of messages which
+ ;; are matched by proof-shell-retract-files-regexp, one for
+ ;; each dependency).
+ ;; [In fact, I think this is what should happen when
+ ;; Require is undone]
+ ((depstr
+ (substring (shell-command-to-string
+ (concat
+ "coqdep *.v | grep "
+ (file-name-nondirectory
+ (file-name-sans-extension fname)) ".v"
+ " | awk '{print $1}' | sed 's/.vo:/.v/'")) 0 -1))
+ (deps (split-string depstr))
+ (current-included proof-included-files-list))
+ ;; Now hack the proof-included-files-list to remove the
+ ;; dependencies of the retracted file and remove the
+ ;; locked regions
+ ;; FIXME: this is too low-level delving in PG. Should
+ ;; do with proof-shell-retract-files-regexp really.
+ (mapcar (lambda (dep)
+ (setq proof-included-files-list
+ (delete (file-truename dep)
+ proof-included-files-list)))
+ deps)
+ (proof-restart-buffers
+ (proof-files-to-buffers
+ (set-difference current-included
+ proof-included-files-list)))
+ ;; Return a comment thingy inserted into the shell
+ ;; buffer to help debugging.
+ (format "Print (* Proof General ran coqdep command for %s, result: %s. Removed files: %s *)" fname depstr deps))))
+
+
+ ;;Coq V7 changes this
+ (setq proof-shell-start-silent-cmd
+ (if coq-version-is-V7 "Set Silent." "Begin Silent.")
+ proof-shell-stop-silent-cmd
+ (if coq-version-is-V7 "Unset Silent." "End Silent."))
+; (setq proof-shell-start-silent-cmd "Begin Silent."
+; proof-shell-stop-silent-cmd "End Silent.")
+
+ (coq-init-syntax-table)
+
+;; font-lock
+
+ (setq font-lock-keywords coq-font-lock-keywords-1)
+
+ (setq proof-font-lock-zap-commas t) ; enable the painful hack
+
+ (proof-config-done)
+
+;; outline
+
+ (make-local-variable 'outline-regexp)
+ (setq outline-regexp coq-outline-regexp)
+
+ (make-local-variable 'outline-heading-end-regexp)
+ (setq outline-heading-end-regexp coq-outline-heading-end-regexp)
+
+;; tags
+ (and (boundp 'tag-table-alist)
+ (setq tag-table-alist
+ (append '(("\\.v$" . coq-tags)
+ ("coq" . coq-tags))
+ tag-table-alist)))
+
+ (setq blink-matching-paren-dont-ignore-comments t)
+
+;; hooks and callbacks
+
+ (add-hook 'proof-pre-shell-start-hook 'coq-pre-shell-start nil t))
+
+
+
+(defun coq-shell-mode-config ()
+ (setq
+ proof-shell-prompt-pattern coq-shell-prompt-pattern
+ proof-shell-cd-cmd coq-shell-cd
+ proof-shell-filename-escapes '(("\\\\" . "\\\\") ("\"" . "\\\""))
+ proof-shell-abort-goal-regexp coq-shell-abort-goal-regexp
+ proof-shell-proof-completed-regexp coq-shell-proof-completed-regexp
+ proof-shell-error-regexp coq-error-regexp
+ proof-shell-interrupt-regexp coq-interrupt-regexp
+ proof-shell-assumption-regexp coq-id
+ proof-shell-first-special-char ?\360
+ proof-shell-wakeup-char ?\371 ; done: prompt
+ ;; The next three represent path annotation information
+ proof-shell-start-char ?\372 ; not done
+ proof-shell-end-char ?\373 ; not done
+ proof-shell-field-char ?\374 ; not done
+ proof-shell-goal-char ?\375 ; done
+ proof-shell-eager-annotation-start "\376\\|\\[Reinterning"
+ proof-shell-eager-annotation-start-length 12
+ proof-shell-eager-annotation-end "\377\\|done\\]" ; done
+ proof-shell-annotated-prompt-regexp
+ (concat proof-shell-prompt-pattern
+ (char-to-string proof-shell-wakeup-char)) ; done
+ proof-shell-result-start "\372 Pbp result \373"
+ proof-shell-result-end "\372 End Pbp result \373"
+ proof-shell-start-goals-regexp "[0-9]+ subgoals?"
+ proof-shell-end-goals-regexp proof-shell-annotated-prompt-regexp
+ proof-shell-init-cmd ; (concat
+ coq-shell-init-cmd
+ ; Coq has no global settings?
+ ; (proof-assistant-settings-cmd))
+ proof-shell-restart-cmd coq-shell-restart-cmd
+ proof-analyse-using-stack t
+ ;; proof-lift-global 'coq-lift-global
+ )
+
+ (coq-init-syntax-table)
+ (setq font-lock-keywords coq-font-lock-keywords-1)
+
+ (proof-shell-config-done))
+
+(defun coq-goals-mode-config ()
+ (setq pbp-change-goal "Show %s.")
+ (setq pbp-error-regexp coq-error-regexp)
+ (coq-init-syntax-table)
+ (setq font-lock-keywords coq-font-lock-keywords-1)
+ (proof-goals-config-done))
+
+(defun coq-response-config ()
+ (coq-init-syntax-table)
+ (setq font-lock-keywords coq-font-lock-keywords-1)
+ (proof-response-config-done))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Flags and other settings for Coq.
+;;
+
+;; da: neither of these work very well.
+;; I think "time" must just be for special search isos top level,
+;; and "Focus" on works during a proof, so sending the setting
+;; at the start of a session is wrong.
+
+;(defpacustom time-search-isos nil
+; "Whether to display timing of SearchIsos in Coq."
+; :type 'boolean
+; :setting ("Time." . "Untime."))
+
+(defpacustom print-only-first-subgoal nil
+ "Whether to just print the first subgoal in Coq."
+ :type 'boolean
+ :setting ("Focus." . "Unfocus."))
+
+(defpacustom auto-compile-vos nil
+ "Whether to automatically compile vos and track dependencies."
+ :type 'boolean
+ :eval (if coq-auto-compile-vos
+ (setq proof-shell-inform-file-processed-cmd
+ coq-proof-shell-inform-file-processed-cmd
+ proof-shell-process-file
+ coq-proof-shell-process-file
+ proof-shell-inform-file-retracted-cmd
+ coq-proof-shell-inform-file-retracted-cmd)
+ (setq proof-shell-inform-file-processed-cmd nil
+ proof-shell-process-file nil
+ proof-shell-inform-file-retracted-cmd nil)))
+
+(provide 'coq)
diff --git a/coq/coqtags b/coq/coqtags
new file mode 100644
index 00000000..6731cc62
--- /dev/null
+++ b/coq/coqtags
@@ -0,0 +1,73 @@
+#!/usr/local/bin/perl
+#
+# Or perhaps: /usr/local/bin/perl
+#
+# # $Id$
+#
+undef $/;
+
+if($#ARGV<$[) {die "No Files\n";}
+open(tagfile,">TAGS") || die "Couldn't open TAGS: $!\n";
+
+while(<>)
+{
+ print "Tagging $ARGV\n";
+ $a=$_;
+ $cp=1;
+ $lp=1;
+ $tagstring="";
+
+ while(1)
+ {
+
+# ---- Get the next statement starting on a newline ----
+
+ if($a=~/^[ \t\n]*\(\*/)
+ { while($a=~/^\s*\(\*/)
+ { $d=1; $a=$'; $cp+=length $&; $lp+=(($wombat=$&)=~tr/\n/\n/);
+ while($d>0 && $a=~/\(\*|\*\)/)
+ { $a=$'; $cp+=2+length $`; $lp+=(($wombat=$`)=~tr/\n/\n/);
+ if($& eq "(*") {$d++} else {$d--};
+ }
+ if($d!=0) {die "Unbalanced Comment?";}
+ }
+ }
+
+ if($cp>1 && $a=~/.*\n/) {$a=$'; $cp+=length $&; $lp++;}
+ while($a=~/^\n/) {$cp++;$lp++;$a=$'}
+
+ if($a=~/^[^\.]*\./)
+ { $stmt=$&;
+ $newa=$';
+ $newcp=$cp+length $&;
+ $newlp=$lp+(($wombat=$&)=~tr/\n/\n/); }
+ else { last;}
+
+# ---- The above embarrasses itself if there are semicolons inside comments
+# ---- inside commands. Could do better.
+
+# print "----- (",$lp,",",$cp,")\n", $stmt, "\n";
+
+ if($stmt=~/^([ \t]*((Fact)|(Goal)|(Lemma)|(Remark)|(Theorem))\s+([\w\']+))\s*:/)
+ { $tagstring.=$1."\177".$8."\001".$lp.",".$cp."\n"; }
+
+ elsif($stmt=~/^([ \t]*((Axiom)|(Hypothesis)|(Parameter)|(Variable))\s+[\w\']+)/)
+ { do adddecs($stmt,$1) }
+
+ elsif($stmt=~/^([ \t]*((Definition)|(Fixpoint)|(Inductive))\s+[\w\']+)/)
+ { $tagstring.=$1."\177".$6."\001".$lp.",".$cp."\n"; }
+
+ $cp=$newcp; $lp=$newlp; $a=$newa;
+ }
+ print tagfile "\f\n".$ARGV.",".(length $tagstring)."\n".$tagstring;
+}
+close tagfile;
+
+sub adddecs {
+ $wk=$_[0];
+ $tag=$_[1];
+ $sep=",";
+ while($tst=($wk=~/\s*([\w\']+)\s*([,:\[])/) && $sep eq ",")
+ { $sep=$2; $tagstring.=$tag."\177".$1."\001".$lp.",".$cp."\n"; $wk=$'; }
+ 0;
+}
diff --git a/coq/example.v b/coq/example.v
new file mode 100644
index 00000000..5a3c5b59
--- /dev/null
+++ b/coq/example.v
@@ -0,0 +1,14 @@
+(*
+ Example proof script for Coq Proof General.
+
+ $Id$
+*)
+
+Goal (A,B:Prop)(A /\ B) -> (B /\ A).
+ Intros A B H.
+ Induction H.
+ Apply conj.
+ Assumption.
+ Assumption.
+Save and_comms.
+
diff --git a/coq/todo b/coq/todo
new file mode 100644
index 00000000..a78ffa40
--- /dev/null
+++ b/coq/todo
@@ -0,0 +1,78 @@
+-*- mode:outline -*-
+
+* Things to do for Coq
+
+See also ../todo for generic things to do, priority codes.
+
+
+** B See if there is a way to turn off the superfluous output of scripts
+
+ from Coq when inside ProofGeneral, i.e. output like this:
+
+ Intros A B G.
+ Induction G.
+ Apply conj.
+ Assumption.
+
+ Assumption.
+
+ and_comms is defined
+
+ In PG, only the last line is relevant!!
+ If it isn't possible to turn it off, can we send a suggestion
+ to the Coq implementors for the next version?
+
+** B Fix silly startup sychronization problem that displays
+ cwd on startup.
+
+** B C-c C-c breaks the coherence with prover state
+ (da: can somebody tell me if this is still true?
+ what problem specifically?)
+ Pierre: I never had this problem, it's all I can say
+
+** B Proof-by-Pointing [2 weeks]
+ da: Yves Bertot told me that his CtCoq proof-by-pointing code
+ is in the Coq kernel now, so would be useful for PG.
+ We need a Coq hacker to do this.
+ Perhaps for new version of Coq.
+ da: I have old version of code sent to my by Healf.
+ Pierre: Since the code is to be changed, I suggest that we
+ wait for V7.
+
+** C Improve X-Symbol support. Integrate with Coq syntax mechanism somehow?
+ pierre: Yes, the greatest would be to allow users to easily declare
+ new tokens/symbols and add new grammar rules (Coq allows this)
+ including the declared tokens. Indeed when I define the type set,
+ and its element emptyset, and predicate In, I want to be able to say
+ that emptyset and In are new tokens and asociate them with the right
+ symbols. I want to be able of that on the fly (maybe we can use the
+ 'File Variables' feature of Emacs). Another thing is that we may ask
+ Coq developers to be unicode compliant or something like that.
+
+
+** C Retraction in a Section should retract to the beginning of the whole
+ section. See the section "Granularity of
+ Atomic Commands" for a proposal on how to generalise the current
+ implementation so that it can also deal with sections.
+ [See also the LEGO problem with Discharge] (6h)
+
+** C Correct the C-c C-c bug (typing C-c C-c during the execution of a
+ tactic breaks the consitency with Coq)
+
+** C Fix the coq-lift-global code
+
+** D Add Patrick Loiseleur's commands to search for vernac or ml files.
+ (they are in a separate file that is part of Coq distrib.
+ should I really integrate that in PG ? Patrick)
+ (maybe not if they're orthogonal to PG, but might help users - da)
+
+** D Add coq-add-tactic with a tactic name, which adds that tactic to the
+ undoable tactics and to the font-lock. (2h)
+ Pierre: I fixed this I think, by making a non-undoable regexp
+ instead. This solves the problem of tactics that have been defined
+ in another file.
+
+** D Improve coqtags. It cannot handle lists e.g., with
+ Parameter x,y:nat
+ it only tags x but not y. [The same problem exists for legotags]
+
diff --git a/coq/x-symbol-coq.el b/coq/x-symbol-coq.el
new file mode 100644
index 00000000..be15d352
--- /dev/null
+++ b/coq/x-symbol-coq.el
@@ -0,0 +1,92 @@
+;; x-symbol-coq.el
+;;
+;; David Aspinall, adapted from file supplied by David von Obheimb
+;;
+;; $Id$
+;;
+
+(defvar x-symbol-coq-symbol-table
+ '((perpendicular () "False" "\\<bottom>")
+ (top () "True" "\\<top>")
+ (notsign () "~" "\\<not>")
+ (longarrowright () "->" "\\<longrightarrow>")
+ (logicaland () "/\\" "\\<and>")
+ (logicalor () "\\/" "\\<or>")
+ (equivalence () "<->" "\\<equiv>")
+ (existential1 () "EX" "\\<exists>")
+ ;; some naughty ones, but probably what you'd like
+ ;; (a mess in words like "searching" !!)
+ (Gamma () "Gamma" "\\<Gamma>")
+ (Delta () "Delta" "\\<Delta>")
+ (Theta () "Theta" "\\<Theta>")
+ (Lambda () "Lambda" "\\<Lambda>")
+ (Pi () "Pi" "\\<Pi>")
+ (Sigma () "Sigma" "\\<Sigma>")
+ (Phi () "Phi" "\\<Phi>")
+ (Psi () "Psi" "\\<Psi>")
+ (Omega () "Omega" "\\<Omega>")
+ (alpha () "alpha" "\\<alpha>")
+ (beta () "beta" "\\<beta>")
+ (gamma () "gamma" "\\<gamma>")
+ (delta () "delta" "\\<delta>")
+ (epsilon1 () "epsilon" "\\<epsilon>")
+ (zeta () "zeta" "\\<zeta>")
+ (eta () "eta" "\\<eta>")
+ (theta1 () "theta" "\\<theta>")
+ (kappa1 () "kappa" "\\<kappa>")
+ (lambda () "lambda" "\\<lambda>")
+; (mu () "mu" "\\<mu>")
+; (nu () "nu" "\\<nu>")
+; (xi () "xi" "\\<xi>")
+; (pi () "pi" "\\<pi>")
+ (rho () "rho" "\\<rho>")
+ (sigma () "sigma" "\\<sigma>")
+ (tau () "tau" "\\<tau>")
+ (phi1 () "phi" "\\<phi>")
+; (chi () "chi" "\\<chi>")
+ (psi () "psi" "\\<psi>")
+ (omega () "omega" "\\<omega>")))
+
+;; All the stuff X-Symbol complains about
+(defvar x-symbol-coq-master-directory 'ignore)
+(defvar x-symbol-coq-image-searchpath '("./"))
+(defvar x-symbol-coq-image-cached-dirs '("images/" "pictures/"))
+(defvar x-symbol-coq-image-keywords nil)
+(defvar x-symbol-coq-font-lock-keywords nil)
+(defvar x-symbol-coq-header-groups-alist nil)
+(defvar x-symbol-coq-class-alist
+ '((VALID "Coq Symbol" (x-symbol-info-face))
+ (INVALID "no Coq Symbol" (red x-symbol-info-face))))
+(defvar x-symbol-coq-class-face-alist nil)
+(defvar x-symbol-coq-electric-ignore nil)
+(defvar x-symbol-coq-required-fonts nil)
+(defvar x-symbol-coq-case-insensitive nil)
+
+;Pierre: let's try this, phi1 will be encoded, but not phia or
+;philosophy. problem: blaphi will be encoded,
+; other problem: false1 sholud not be encoded
+
+(defvar x-symbol-coq-token-shape '(?_ "[A-Za-z]+" . "[A-Za-z_]"))
+
+;(defvar x-symbol-coq-token-shape nil)
+
+(defvar x-symbol-coq-table x-symbol-coq-symbol-table)
+(defun x-symbol-coq-default-token-list (tokens) tokens)
+(defvar x-symbol-coq-token-list 'x-symbol-coq-default-token-list)
+(defvar x-symbol-coq-input-token-ignore nil)
+
+;; internal stuff
+(defvar x-symbol-coq-exec-specs nil)
+(defvar x-symbol-coq-menu-alist nil)
+(defvar x-symbol-coq-grid-alist nil)
+(defvar x-symbol-coq-decode-atree nil)
+(defvar x-symbol-coq-decode-alist nil)
+(defvar x-symbol-coq-encode-alist nil)
+(defvar x-symbol-coq-nomule-decode-exec nil)
+(defvar x-symbol-coq-nomule-encode-exec nil)
+
+(warn "Coq support for X-Symbol is highly incomplete! Please help improve it!
+Send improvements to x-symbol-coq.el to proofgen@dcs.ed.ac.uk")
+
+
+(provide 'x-symbol-coq)
diff --git a/demoisa/README b/demoisa/README
new file mode 100644
index 00000000..d478bcaf
--- /dev/null
+++ b/demoisa/README
@@ -0,0 +1,55 @@
+Example Proof General instance for Isabelle
+
+Written by David Aspinall.
+
+Status: supported as a demonstration only
+
+========================================
+
+
+ "Isabelle Proof General in 30 setqs"
+
+This is a whittled down version of Isabelle Proof General, supplied as
+an (almost) minimal demonstration of how to instantiate Proof General
+to a particular proof assistant. You can use this as a template to
+get support for a new assistant going. (I did for HOL Proof General).
+
+This mode uses the unadulterated terminal interface of Isabelle, to
+demonstrate that hacking the proof assistant is not necessary to get
+basic features working.
+
+And it really works! You you get a toolbar, menus, short-cut keys,
+script management for multiple files, a function menu, ability to
+run proof assistant remotely, etc, etc.
+
+To try it out, set in the shell PROOFGENERAL_ASSISTANTS=demoisa
+before invoking Emacs. (Of course, you need Isabelle installed).
+
+What's missing?
+
+ 1. A few handy commands (e.g. proof-find-theorems-command)
+ 2. Syntax settings and highlighting for proof scripts
+ 3. Indentation for proof scripts
+ 4. Special markup characters in output for robustness
+ 5. True script management for multiple files (automatic mode is used)
+ 6. Proof by pointing
+
+How easy is it to add all that?
+
+ 1. Trivial. 2. A table specifying syntax codes for characters
+ (strings, brackets, etc) and some regexps; depends on complexity
+ of syntax. 3. A bit of elisp to scan script; depends on
+ complexity of syntax. 4. Needs hacking in the proof assistant:
+ how hard is to hack your assistant to do this? 5. Depends on file
+ management mechanism in the prover, may need hacking there to send
+ messages. But automatic multiple files may be all you need anyway.
+ 6. Non trivial (but worth a go).
+
+See demoisa.el and demoisa-easy.el for more details.
+
+
+
+========================================
+
+$Id$
+
diff --git a/demoisa/demoisa-easy.el b/demoisa/demoisa-easy.el
new file mode 100644
index 00000000..8b1c76d8
--- /dev/null
+++ b/demoisa/demoisa-easy.el
@@ -0,0 +1,62 @@
+;; demoisa-easy.el Example Proof General instance for Isabelle
+;;
+;; Copyright (C) 1999 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; This is an alternative version of demoisa.el which uses the
+;; proof-easy-config macro to do the work of declaring derived modes,
+;; etc.
+;;
+;; This mechanism is in fact recommended for new instantiations of
+;; Proof General since it follows a regular pattern, and we can more
+;; easily adapt it in the future to new versions of Proof General.
+;; It is easy to augment with additional elisp functions and
+;; other settings.
+;;
+;; See demoisa.el and the Adapting Proof General manual for more
+;; documentation.
+;;
+;; To test this file you must rename it demoisa.el.
+;;
+
+(require 'proof-easy-config) ; easy configure mechanism
+
+(proof-easy-config
+ 'demoisa "Isabelle Demo"
+ proof-prog-name "isabelle"
+ proof-terminal-char ?\;
+ proof-comment-start "(*"
+ proof-comment-end "*)"
+ proof-goal-command-regexp "^Goal"
+ proof-save-command-regexp "^qed"
+ proof-goal-with-hole-regexp "qed_goal \"\\(\\(.*\\)\\)\""
+ proof-save-with-hole-regexp "qed \"\\(\\(.*\\)\\)\""
+ proof-non-undoables-regexp "undo\\|back"
+ proof-goal-command "Goal \"%s\";"
+ proof-save-command "qed \"%s\";"
+ proof-kill-goal-command "Goal \"PROP no_goal_set\";"
+ proof-showproof-command "pr()"
+ proof-undo-n-times-cmd "pg_repeat undo %s;"
+ proof-auto-multiple-files t
+ proof-shell-cd-cmd "cd \"%s\""
+ proof-shell-prompt-pattern "[ML-=#>]+>? "
+ proof-shell-interrupt-regexp "Interrupt"
+ proof-shell-start-goals-regexp "Level [0-9]"
+ proof-shell-end-goals-regexp "val it"
+ proof-shell-quit-cmd "quit();"
+ proof-assistant-home-page
+ "http://www.cl.cam.ac.uk/Research/HVG/Isabelle/"
+ proof-shell-annotated-prompt-regexp
+ "^\\(val it = () : unit\n\\)?ML>? "
+ proof-shell-error-regexp
+ "\\*\\*\\*\\|^.*Error:\\|^uncaught exception \\|^Exception- "
+ proof-shell-init-cmd
+ "fun pg_repeat f 0 = () | pg_repeat f n = (f(); pg_repeat f (n-1));"
+ proof-shell-proof-completed-regexp "^No subgoals!"
+ proof-shell-eager-annotation-start
+ "^\\[opening \\|^###\\|^Reading")
+
+(provide 'demoisa) \ No newline at end of file
diff --git a/demoisa/demoisa.el b/demoisa/demoisa.el
new file mode 100644
index 00000000..1740a100
--- /dev/null
+++ b/demoisa/demoisa.el
@@ -0,0 +1,157 @@
+;; demoisa.el Example Proof General instance for Isabelle
+;;
+;; Copyright (C) 1999 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; =================================================================
+;;
+;; See README in this directory for an introduction.
+;;
+;; Basic configuration is controlled by one line in `proof-site.el'.
+;; It has this line in proof-assistant-table:
+;;
+;; (demoisa "Isabelle Demo" "\\.ML$")
+;;
+;; From this it loads this file "demoisa/demoisa.el" whenever
+;; a .ML file is visited, and sets the mode to `demoisa-mode'
+;; (defined below).
+;;
+;; I've called this instance "Isabelle Demo Proof General" just to
+;; avoid confusion with the real "Isabelle Proof General" in case the
+;; demo gets loaded by accident.
+;;
+;; To make the line above take precedence over the real Isabelle mode
+;; later in the table, set PROOFGENERAL_ASSISTANTS=demoisa in the
+;; shell before starting Emacs (or customize proof-assistants).
+;;
+
+
+(require 'proof) ; load generic parts
+
+
+;; ======== User settings for Isabelle ========
+;;
+;; Defining variables using customize is pretty easy.
+;; You should do it at least for your prover-specific user options.
+;;
+;; proof-site provides us with two customization groups
+;; automatically: (based on the name of the assistant)
+;;
+;; 'isabelledemo - User options for Isabelle Demo Proof General
+;; 'isabelledemo-config - Configuration of Isabelle Proof General
+;; (constants, but may be nice to tweak)
+;;
+;; The first group appears in the menu
+;; ProofGeneral -> Customize -> Isabelledemo
+;; The second group appears in the menu:
+;; ProofGeneral -> Internals -> Isabelledemo config
+;;
+
+(defcustom isabelledemo-prog-name "isabelle"
+ "*Name of program to run Isabelle."
+ :type 'file
+ :group 'isabelledemo)
+
+(defcustom isabelledemo-web-page
+ "http://www.cl.cam.ac.uk/Research/HVG/isabelle.html"
+ "URL of web page for Isabelle."
+ :type 'string
+ :group 'isabelledemo-config)
+
+
+;;
+;; ======== Configuration of generic modes ========
+;;
+
+(defun demoisa-config ()
+ "Configure Proof General scripting for Isabelle."
+ (setq
+ proof-terminal-char ?\; ; ends every command
+ proof-comment-start "(*"
+ proof-comment-end "*)"
+ proof-goal-command-regexp "^Goal"
+ proof-save-command-regexp "^qed"
+ proof-goal-with-hole-regexp "qed_goal \"\\(\\(.*\\)\\)\""
+ proof-save-with-hole-regexp "qed \"\\(\\(.*\\)\\)\""
+ proof-non-undoables-regexp "undo\\|back"
+ proof-undo-n-times-cmd "pg_repeat undo %s;"
+ proof-showproof-command "pr()"
+ proof-goal-command "Goal \"%s\";"
+ proof-save-command "qed \"%s\";"
+ proof-kill-goal-command "Goal \"PROP no_goal_set\";"
+ proof-assistant-home-page isabelledemo-web-page
+ proof-auto-multiple-files t))
+
+
+(defun demoisa-shell-config ()
+ "Configure Proof General shell for Isabelle."
+ (setq
+ proof-shell-annotated-prompt-regexp "^\\(val it = () : unit\n\\)?ML>? "
+ proof-shell-cd-cmd "cd \"%s\""
+ proof-shell-prompt-pattern "[ML-=#>]+>? "
+ proof-shell-interrupt-regexp "Interrupt"
+ proof-shell-error-regexp "\\*\\*\\*\\|^.*Error:\\|^uncaught exception \\|^Exception- "
+ proof-shell-start-goals-regexp "Level [0-9]"
+ proof-shell-end-goals-regexp "val it"
+ proof-shell-proof-completed-regexp "^No subgoals!"
+ proof-shell-eager-annotation-start "^\\[opening \\|^###\\|^Reading"
+ proof-shell-init-cmd ; define a utility function, in a lib somewhere?
+ "fun pg_repeat f 0 = ()
+ | pg_repeat f n = (f(); pg_repeat f (n-1));"
+ proof-shell-quit-cmd "quit();"))
+
+
+
+;;
+;; ======== Defining the derived modes ========
+;;
+
+;; The name of the script mode is always <proofsym>-script,
+;; but the others can be whatever you like.
+;;
+;; The derived modes set the variables, then call the
+;; <mode>-config-done function to complete configuration.
+
+(define-derived-mode demoisa-mode proof-mode
+ "Isabelle Demo script" nil
+ (demoisa-config)
+ (proof-config-done))
+
+(define-derived-mode demoisa-shell-mode proof-shell-mode
+ "Isabelle Demo shell" nil
+ (demoisa-shell-config)
+ (proof-shell-config-done))
+
+(define-derived-mode demoisa-response-mode proof-response-mode
+ "Isabelle Demo response" nil
+ (proof-response-config-done))
+
+(define-derived-mode demoisa-goals-mode proof-goals-mode
+ "Isabelle Demo goals" nil
+ (proof-goals-config-done))
+
+;; The response buffer and goals buffer modes defined above are
+;; trivial. In fact, we don't need to define them at all -- they
+;; would simply default to "proof-response-mode" and "pbp-mode".
+
+;; A more sophisticated instantiation might set font-lock-keywords to
+;; add highlighting, or some of the proof by pointing markup
+;; configuration for the goals buffer.
+
+;; The final piece of magic here is a hook which configures settings
+;; to get the proof shell running. Proof General needs to know the
+;; name of the program to run, and the modes for the shell, response,
+;; and goals buffers.
+
+(add-hook 'proof-pre-shell-start-hook 'demoisa-pre-shell-start)
+
+(defun demoisa-pre-shell-start ()
+ (setq proof-prog-name isabelledemo-prog-name)
+ (setq proof-mode-for-shell 'demoisa-shell-mode)
+ (setq proof-mode-for-response 'demoisa-response-mode)
+ (setq proof-mode-for-goals 'demoisa-goals-mode))
+
+(provide 'demoisa)
diff --git a/doc/.cvsignore b/doc/.cvsignore
new file mode 100644
index 00000000..6a126a00
--- /dev/null
+++ b/doc/.cvsignore
@@ -0,0 +1,48 @@
+ProofGeneral.log
+ProofGeneral.dvi
+ProofGeneral.ps
+ProofGeneral.pdf
+ProofGeneral.ps.gz
+ProofGeneral.kys
+ProofGeneral.aux
+ProofGeneral.cp
+ProofGeneral.fn
+ProofGeneral.vr
+ProofGeneral.tp
+ProofGeneral.ky
+ProofGeneral.pg
+ProofGeneral.toc
+ProofGeneral.info
+ProofGeneral.cps
+ProofGeneral.fns
+ProofGeneral.vrs
+ProofGeneral.info-*
+ProofGeneral.txt
+ProofGeneral_*.html
+ProofGeneral_toc.html
+ProofGeneral_foot.html
+PG-adapting.log
+PG-adapting.dvi
+PG-adapting.ps
+PG-adapting.pdf
+PG-adapting.ps.gz
+PG-adapting.kys
+PG-adapting.aux
+PG-adapting.cp
+PG-adapting.fn
+PG-adapting.vr
+PG-adapting.tp
+PG-adapting.ky
+PG-adapting.pg
+PG-adapting.toc
+PG-adapting.info
+PG-adapting.cps
+PG-adapting.fns
+PG-adapting.vrs
+PG-adapting.info-*
+PG-adapting.txt
+PG-adapting_*.html
+PG-adapting_toc.html
+PG-adapting_foot.html
+ProofGeneralPortrait.eps
+ProofGeneralPortrait.pdf
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 00000000..2d008717
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,24 @@
+##
+## Makefile for Proof General doc directory.
+##
+## Author: David Aspinall <da@dcs.ed.ac.uk>
+##
+## Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+##
+## $Id$
+##
+###########################################################################
+##
+## Use:
+## make info,dvi,pdf,html - build respective docs from texi source.
+## make doc - make default kinds of doc (dvi, info).
+##
+###########################################################################
+
+default:
+ $(MAKE) doc
+
+%:
+ make -f Makefile.doc DOCNAME=PG-adapting MAKE="make -f Makefile.doc" $@
+ make -f Makefile.doc DOCNAME=ProofGeneral MAKE="make -f Makefile.doc" $@
+
diff --git a/doc/Makefile.doc b/doc/Makefile.doc
new file mode 100644
index 00000000..179ab779
--- /dev/null
+++ b/doc/Makefile.doc
@@ -0,0 +1,164 @@
+##
+## Makefile for Proof General doc directory.
+##
+## Author: David Aspinall <da@dcs.ed.ac.uk>
+##
+## Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+##
+## $Id$
+##
+###########################################################################
+##
+## Use:
+## make info,dvi,pdf,html - build respective docs from texi source.
+## make doc - make default kinds of doc (dvi, info).
+##
+###########################################################################
+
+
+MAKE = make -f Makefile.doc
+MAKEINFO = makeinfo
+TEXI2DVI = texi2dvi
+
+# `dviutils' package contains these useful utilities.
+# "make rearrange" will only be called if you have dviselect.
+DVISELECT = dviselect
+DVICONCAT = dviconcat
+
+
+# Assumes actual first two pages belong to titlepage
+TITLERANGE = =1,=2
+
+# Assumes that main document starts on third actual page
+MAINRANGE = =3,=4,3:
+
+TOC = :_1
+
+DVI2PS = dvips -Pcmz
+TEXI2PDF = texi2pdf
+TEXI2HTML = texi2html -expandinfo -number -split_chapter
+# FIXME: choose emacs automatically if xemacs not available
+EMACS = xemacs -batch
+
+TMPFILE=pgt
+
+.SUFFIXES: .texi .info .dvi .html .pdf .ps .eps .tiff .gz
+
+default: doc
+
+.texi.info:
+ $(MAKEINFO) $<
+
+.texi.dvi:
+ $(TEXI2DVI) $<
+ if `which $(DVISELECT) > /dev/null`; then $(MAKE) rearrange DOCNAME=$*; fi
+
+rearrange:
+ $(DVISELECT) -i $(DOCNAME).dvi -o $(DOCNAME).tmp1 $(TITLERANGE)
+ $(DVISELECT) -i $(DOCNAME).dvi -o $(DOCNAME).tmp2 $(MAINRANGE)
+ $(DVISELECT) -i $(DOCNAME).dvi -o $(DOCNAME).tmp3 $(TOC)
+ $(DVICONCAT) -o $(DOCNAME).dvi $(DOCNAME).tmp1 $(DOCNAME).tmp3 $(DOCNAME).tmp2
+ rm -f $(DOCNAME).tmp1 $(DOCNAME).tmp2 $(DOCNAME).tmp3
+
+.tiff.eps:
+ tiff2ps -e -w 3.48 -h 5 $*.tiff > $*.eps
+
+## FIXME: need to do page rearrangement here, too!
+.texi.pdf:
+ $(TEXI2PDF) $<
+
+.dvi.ps:
+ $(DVI2PS) $< -o $*.ps
+
+.texi.html:
+ $(TEXI2HTML) $<
+
+default: doc
+
+FORCE:
+
+ProofGeneral.txt:
+ echo > ProofGeneral.txt
+
+ProofGeneralPortrait.eps: FORCE
+# if [ -f ProofGeneralPortrait.eps.gz ]; then gunzip -c ProofGeneralPortrait.eps.gz > ProofGeneralPortrait.eps; fi
+ if [ -f ProofGeneralPortrait.eps ]; then \
+ sed 's/@clear haveeps/@set haveeps/g' $(DOCNAME).texi > $(TMPFILE); \
+ sed 's/@c image{ProofGeneralPortrait}/@image{ProofGeneralPortrait}/g' $(TMPFILE) > $(DOCNAME).texi; \
+ else \
+ sed 's/@set haveeps/@clear haveeps/g' $(DOCNAME).texi > $(TMPFILE); \
+ sed 's/@image{ProofGeneralPortrait}/@c image{ProofGeneralPortrait}/g' $(TMPFILE) > $(DOCNAME).texi; \
+ fi
+ rm -f $(TMPFILE)
+
+ProofGeneralPortrait.pdf:
+# if [ -f ProofGeneralPortrait.eps.gz ]; then gunzip -c ProofGeneralPortrait.eps.gz > ProofGeneralPortrait.eps; epstopdf ProofGeneralPortrait.eps; fi
+ if [ -f ProofGeneralPortrait.pdf ]; then \
+ sed 's/@clear haveeps/@set haveeps/g' $(DOCNAME).texi > $(TMPFILE); \
+ sed 's/@c image{ProofGeneralPortrait}/@image{ProofGeneralPortrait}/g' $(TMPFILE) > $(DOCNAME).texi; \
+ else \
+ sed 's/@set haveeps/@clear haveeps/g' $(DOCNAME).texi > $(TMPFILE); \
+ sed 's/@image{ProofGeneralPortrait}/@c image{ProofGeneralPortrait}/g' $(TMPFILE) > $(DOCNAME).texi; \
+ fi
+ rm -f $(TMPFILE)
+
+%.gz : %
+ gzip -f -9 $*
+
+##
+## doc : build info and dvi files from $(DOCNAME).texi
+##
+doc: dvi info
+
+
+##
+## all : build all documentation targets
+##
+all: dvi ps html info pdf
+
+##
+## dist: build distribution targets
+##
+dist: info html psz pdf
+
+dvi: ProofGeneralPortrait.eps $(DOCNAME).dvi
+ps: dvi $(DOCNAME).ps
+psz: ps $(DOCNAME).ps.gz
+pdf: ProofGeneralPortrait.pdf $(DOCNAME).pdf
+html: $(DOCNAME).html
+ ln -sf $(DOCNAME)_toc.html index.html
+info: ProofGeneral.txt $(DOCNAME).info
+
+# NB: for info, could make localdir automatically from
+# START-INFO-DIR-ENTRY / END-INFO-DIR-ENTRY.
+# Does some utility do this?
+
+##
+## clean: Remove subsidiary documentation files
+##
+clean:
+ rm -f ProofGeneral.txt ProofGeneralPortrait.eps ProofGeneralPortrait.pdf
+ rm -f $(DOCNAME).{cp,fn,vr,tp,ky,pg}
+ rm -f $(DOCNAME).{fns,vrs,cps,aux,log,toc,kys,cp0}
+ rm -f *~
+
+##
+## distclean: Remove documentation targets
+##
+distclean: clean
+ rm -f $(DOCNAME).info* $(DOCNAME).dvi $(DOCNAME)*.ps $(DOCNAME).pdf $(DOCNAME)*.html
+
+##
+## texi: update magic comments in texi from docstrings in code.
+## (developer use only!)
+##
+$(DOCNAME).texi: ../*/*.el
+ $(MAKE) magic
+magic:
+ $(EMACS) -l docstring-magic.el $(DOCNAME).texi -f texi-docstring-magic -f save-buffer
+
+
+
+
+
+
diff --git a/doc/PG-adapting.texi b/doc/PG-adapting.texi
new file mode 100644
index 00000000..0b947589
--- /dev/null
+++ b/doc/PG-adapting.texi
@@ -0,0 +1,3794 @@
+
+\def\fontdefs{\psfamily{bsf}{r}{c}{b}{b}{ri}{ri}{ro}{bo}\def\mainmagstep{1200}}
+\input texinfo
+@c TODO: setting for configuring proof hidden regions.
+@c
+@c
+@c $Id$
+@c
+@c NB: the first line of this file uses a non-standard TeXinfo
+@c hack to print in Serifa fonts. It has no effect if you don't have
+@c my hacked version of TeXinfo - da.
+@c
+@c
+@setfilename PG-adapting.info
+@settitle Adapting Proof General
+@setchapternewpage odd
+@paragraphindent 0
+@c A flag for whether to include the front image in the
+@c DVI file. You can download the front image from
+@c http://www.proofgeneral.org/ProofGeneralPortrait.eps.gz
+@c then put it into this directory and 'make dvi' (pdf,ps)
+@c will set the flag below automatically.
+@clear haveeps
+@iftex
+@afourpaper
+@end iftex
+
+@c
+@c Some URLs.
+@c FIXME: unfortunately, broken in buggy pdftexinfo.
+@c so removed for now.
+@set URLxsymbol http://www.fmi.uni-passau.de/~wedler/x-symbol/
+@set URLisamode http://zermelo.dcs.ed.ac.uk/~isamode
+@set URLpghome http://www.proofgeneral.org
+@set URLpglatestrpm http://www.proofgeneral.org/ProofGeneral-latest.noarch.rpm
+@set URLpglatesttar http://www.proofgeneral.org/ProofGeneral-latest.tar.gz
+@set URLpglatestdev http://www.proofgeneral.org/ProofGeneral-devel-latest.tar.gz
+@c
+@c
+
+@c
+@c IMPORTANT NOTE ABOUT THIS TEXINFO FILE:
+@c I've tried keep full node lines *out* of this file because Emacs makes a
+@c mess of updating them and they are a nuisance to do by hand.
+@c Instead, rely on makeinfo and friends to do the equivalent job.
+@c For this to work, we must follow each node
+@c immediately with a section command, i.e.:
+@c
+@c @node node-name
+@c <section-command>
+@c
+@c And each section with lower levels must have a menu command in
+@c it. Menu updating with Emacs is a bit better than node updating,
+@c but tends to delete the first section of the file in XEmacs!
+@c (it's better in GNU Emacs at the time of writing).
+@c
+@c
+@c reminder about references:
+@c @xref{node} blah start of sentence: See [ref]
+@c blah (@pxref{node}) blah bla (see [ref]), best at end of sentence
+@c @ref{node} without "see". Careful for info.
+
+
+@set version 3.3
+@set xemacsversion 21.4
+@set fsfversion 20.7
+@set last-update September 2001
+@set rcsid $Id$
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* Proof General Adapting: (PG-adapting). How to adapt Proof General for new provers
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@c
+@c MACROS
+@c
+@c define one here for a command with a key-binding?
+@c
+@c I like the idea, but it's maybe against the TeXinfo
+@c style to fix together a command and its key-binding.
+@c
+@c merge functions and variables into concept index.
+@c @syncodeindex fn cp
+@c @syncodeindex vr cp
+
+@c merge functions into variables index
+@c @syncodeindex fn vr
+
+@finalout
+@titlepage
+@title Adapting Proof General
+@subtitle Proof General --- Organize your proofs!
+@sp 1
+@subtitle Adapting Proof General @value{version} to new provers
+@subtitle @value{last-update}
+@subtitle @b{www.proofgeneral.org}
+
+@c nested ifs fail here completely, WHY?
+@iftex
+@ifset haveeps
+@c @vskip 1cm
+@c The .eps file takes 8.4M! A pity texi can't seem
+@c to deal with gzipped files? (goes down to 1.7M).
+@c But this still seems too much to put into the
+@c PG distribution just for an image on the manual page,
+@c so we take it out for now.
+@c Ideally would like some way of generating eps from
+@c the .jpg file.
+@c image{ProofGeneralPortrait}
+@end ifset
+@end iftex
+@author David Aspinall with T. Kleymann
+@page
+@vskip 0pt plus 1filll
+This manual and the program Proof General are
+Copyright @copyright{} 2000,2001 Proof General team, LFCS Edinburgh.
+
+
+@c
+@c COPYING NOTICE
+@c
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission notice
+identical to this one except for the removal of this paragraph (this
+paragraph not being relevant to the printed manual).
+@end ignore
+
+@sp 2
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+@sp 2
+
+This manual documents Proof General, Version @value{version}, for use
+with XEmacs @value{xemacsversion} and GNU Emacs @value{fsfversion}
+or later versions.
+
+Visit Proof General on the web at @code{http://www.proofgeneral.org}
+
+Version control: @code{@value{rcsid}}
+@end titlepage
+
+@page
+
+
+@ifinfo
+@node Top
+@top Proof General
+
+This file documents configuration mechanisms for version @value{version}
+of @b{Proof General}, a generic Emacs interface for proof assistants.
+
+Proof General @value{version} has been tested with XEmacs
+@value{xemacsversion} and GNU Emacs @value{fsfversion}. It is
+supplied ready customized for the proof assistants Coq, Lego,
+Isabelle, and HOL.
+
+This manual contains information for customizing to new proof
+assistants; see the user manual for details about how to use
+Proof General.
+
+@menu
+* Introduction::
+* Beginning with a new prover::
+* Menus and toolbar and user-level commands::
+* Proof script settings::
+* Proof shell settings::
+* Goals buffer settings::
+* Splash screen settings::
+* Global constants::
+* Handling multiple files::
+* Configuring Font Lock::
+* Configuring X-Symbol::
+* Writing more lisp code::
+* Internals of Proof General::
+* Plans and ideas::
+* Demonstration Instantiations::
+* Function Index::
+* Variable Index::
+* Concept Index::
+@end menu
+@end ifinfo
+
+@node Introduction
+@unnumbered Introduction
+
+Welcome to Proof General!
+
+Proof General a generic Emacs-based interface for proof assistants.
+
+This manual contains information for adapting Proof General to new proof
+assistants, and some sketches of the internal implementation. It is not
+intended for most ordinary users of the system.
+For full details about how to use Proof General, and information on its
+availability and installation, please see the main Proof General manual
+which should accompany this one.
+
+We positively encourage the support of new systems. Proof General has
+grown more flexible and useful as it has been adapted to more proof
+assistants.
+
+Typically, adding support for a new prover improves support for others,
+both because the code becomes more robust, and because new ideas are
+brought into the generic setting. Notice that the Proof General
+framework has been built as a "product line architecture": generality
+has been introduced step-by-step in a demand-driven way, rather than at
+the outset as a grand design. Despite this strategy, the interface has
+a surprisingly clean structure. The approach means that we fully expect
+hiccups when adding support for new assistants, so the generic core may
+need extension or modification. To support this we have an open
+development method: if you require changes in the generic support,
+please contact us (or make adjustments yourself and send them to us).
+
+Proof General has a home page at
+@uref{http://www.proofgeneral.org}. Visit this page
+for the latest version of the manuals, other documentation, system
+downloads, etc.
+
+
+@menu
+* Future::
+* Credits::
+@end menu
+
+@node Future
+@unnumberedsec Future
+@cindex Proof General Kit
+@cindex Future
+
+The aim of the Proof General project is to provide a powerful and
+configurable interfaces which help user-interaction with interactive
+proof assistants.
+
+The strategy Proof General uses is to targets power users rather than
+novices; other interfaces have often neglected this class of users. But
+we do include general user interface niceties, such as toolbar and
+menus, which make use easier for all.
+
+Proof General has been Emacs based so far, but plans are afoot to
+liberate it from the points and parentheses of Emacs Lisp. The
+successor project Proof General Kit proposes that proof assistants use a
+@i{standard} XML-based protocol for interactive proof, dubbed @b{PGIP}.
+
+PGIP enables middleware for interactive proof tools and interface
+components. Rather than configuring Proof General for your proof
+assistant, you will need to configure your proof assistant to understand
+PGIP. There is a similarity however; the design of PGIP was based
+heavily on the Emacs Proof General framework. This means that effort on
+customizing Emacs Proof General to a new proof assistant is worthwhile
+even in the light of PGIP: it will help you to understand Proof
+General's model of interaction, and moreover, we hope to use the Emacs
+customizations to provide experimental filters which allow supported
+provers to communicate using PGIP.
+
+At the time of writing, these ideas are in early stages. For latest
+details, or to become involved, see
+@uref{http://www.proofgeneral.org/kit, the Proof General Kit
+webpage}.
+
+
+@node Credits
+@unnumberedsec Credits
+
+David Aspinall put together and wrote most of this manual. Thomas
+Kleymann wrote some of the text in Chapter 8. Much of the content is
+generated automatically from Emacs docstrings, some of which have been
+written by other Proof General developers.
+
+
+
+@node Beginning with a new prover
+@chapter Beginning with a new prover
+
+Proof General has about 100 configuration variables which are set on a
+per-prover basis to configure the various features. It may sound like a
+lot but don't worry! Many of the variables occur in pairs (typically
+regular expressions matching the start and end of some text), and you
+can begin by setting just a fraction of the variables to get the basic
+features of script management working. The bare minimum for a working
+prototype is about 25 simple settings.
+
+For more advanced features you may need (or want) to write some Emacs
+Lisp. If you're adding new functionality please consider making it
+generic for different proof assistants, if appropriate. When writing
+your modes, please follow the Emacs Lisp conventions @inforef{Style
+Tips, ,lispref}.
+
+The configuration variables are declared in the file
+@file{generic/proof-config.el}. The details in the central part of this
+manual are based on the contents of that file, beginning in @ref{Menus and toolbar
+and user-level commands}, and continuing until @ref{Global constants}.
+Other chapters cover the details of configuring for multiple files and
+for supporting the other Emacs packages mentioned in the user manual
+(@i{Support for other Packages}). If you write additional Elisp code
+interfacing to Proof General, you can find out about some useful functions
+by reading @ref{Writing more lisp code}. The last chapter of this
+manual describes some of the internals of Proof General, in case you are
+interested, maybe because you need to extend the generic core to do
+something new.
+
+In the rest of this chapter we describe the general mechanisms for
+instantiating Proof General. We assume some knowledge of the content
+of the main Proof General manual.
+
+@menu
+* Overview of adding a new prover::
+* Demonstration instance and easy configuration::
+* Major modes used by Proof General::
+@end menu
+
+
+@node Overview of adding a new prover
+@section Overview of adding a new prover
+
+Each proof assistant supported has its own subdirectory under
+@code{proof-home-directory}, used to store a root elisp file and any
+other files needed to adapt the proof assistant for Proof General.
+
+@c Here we show how a minimal configuration of Proof General works for
+@c Isabelle, without any special changes to Isabelle.
+
+Here is how to go about adding support for a new prover.
+
+@enumerate
+@item Make a directory called @file{myassistant/} under the Proof General home
+directory @code{proof-home-directory}, to put the specific customization
+and associated files in.
+@item Add a file @file{myassistant.el} to the new directory.
+@item Edit @file{proof-site.el} to add a new entry to the
+ @code{proof-assistants-table} variable. The new entry should look
+like this:
+@lisp
+ (myassistant "My Proof Assistant" "\\.myasst$")
+@end lisp
+The first item is used to form the name of the internal variables for
+the new mode as well as the directory and file where it loads from. The
+second is a string, naming the proof assistant. The third item is a
+regular expression to match names of proof script files for this
+assistant. See the documentation of @code{proof-assistant-table} for
+more details.
+@item Define the new Proof General modes in @file{myassistant.el},
+ by setting configuration variables to customize the
+ behaviour of the generic modes.
+@end enumerate
+
+@c You could begin by setting a minimum number of the variables, then
+@c adjust the settings via the customize menus, under Proof-General ->
+@c Internals.
+
+@c TEXI DOCSTRING MAGIC: proof-assistant-table
+@defopt proof-assistant-table
+Proof General's table of supported proof assistants.@*
+Extend this table to add a new proof assistant.
+Each entry is a list of the form
+@lisp
+ (@var{symbol} @var{name} @var{automode-regexp})
+@end lisp
+The @var{name} is a string, naming the proof assistant.
+The @var{symbol} is used to form the name of the mode for the
+assistant, @samp{SYMBOL-mode}, run when files with @var{automode-regexp}
+are visited. @var{symbol} is also used to form the name of the
+directory and elisp file for the mode, which will be
+@lisp
+ @var{proof-home-directory}/@var{symbol}/@var{symbol}.el
+@end lisp
+where @samp{PROOF-HOME-DIRECTORY} is the value of the
+variable @code{proof-home-directory}.
+
+The default value is @code{((demoisa "Isabelle Demo" "\\.ML$") (isar "Isabelle/Isar" "\\.thy$") (isa "Isabelle" "\\.ML$\\|\\.thy$") (lego "LEGO" "\\.l$") (coq "Coq" "\\.v$") (phox "PhoX" "\\.phx$") (hol98 "HOL" "\\.sml$") (acl2 "ACL2" "\\.acl2$") (plastic "Plastic" "\\.lf$") (twelf "Twelf" "\\.elf$"))}.
+@end defopt
+
+
+The final step of the description above is where the work lies. There
+are two basic methods. You can write some Emacs lisp functions and
+define the modes using the macro @code{define-derived-mode}. Or you can
+use the new easy configuration mechanism of Proof General 3.0 described
+in the next section, which calls @code{define-derived-mode} for you.
+You still need to know which configuration variables should be set, and
+how to set them.
+
+The documentation below (and inside Emacs) should help with that, but
+the best way to begin might be to use an existing Proof General instance
+as an example.
+
+
+@node Demonstration instance and easy configuration
+@section Demonstration instance and easy configuration
+
+Proof General is supplied with a demonstration instance for Isabelle
+which configures the basic features. This is a whittled down version of
+Isabelle Proof General, which you can use as a template to get support
+for a new assistant going. Check the directory @file{demoisa} for the
+two files @file{demoisa.el} and @file{demoisa-easy.el}.
+
+The file @file{demoisa.el} follows the scheme described in @ref{Major
+modes used by Proof General}. It uses the Emacs Lisp macro
+@code{define-derived-mode} to define the four modes for a Proof General
+instance, by inheriting from the generic code. Settings which configure
+Proof General are made by functions called from within each mode, as
+appropriate.
+
+The file @file{demoisa-easy.el} uses a new simplified mechanism to
+achieve (virtually) the same result. It uses the macro
+@code{proof-easy-config} defined in @file{proof-easy-configl.el} to make
+all of the settings for the Proof General instance in one go, defining
+the derived modes automatically using a regular naming scheme. No lisp
+code is used in this file except the call to this macro. The minor
+difference in the end result is that all the variables are set at once,
+rather than inside each mode. But since the configuration variables are
+all global variables anyway, this makes no real difference.
+
+The macro @code{proof-easy-config} is called like this:
+@lisp
+ (proof-easy-config @var{myprover} "@var{MyProver}"
+ @var{config_1} @var{val_1}
+ ...
+ @var{config_n} @var{val_n})
+@end lisp
+The main body of the macro call is like the body of a @code{setq}. It
+contains pairs of variables and value settings. The first argument to
+the macro is a symbol defining the mode root, the second argument is a
+string defining the mode name. These should be the same as the first
+part of the entry in @code{proof-assistant-table} for your prover.
+@xref{Overview of adding a new prover}. After the call to
+@code{proof-easy-config}, the new modes @code{@var{myprover}-mode},
+@code{@var{myprover}-shell-mode}, @code{@var{myprover}-response-mode},
+and @code{@var{myprover}-goals-mode} will be defined. The configuration
+variables in the body will be set immediately.
+
+
+This mechanism is in fact recommended for new instantiations of
+Proof General since it follows a regular pattern, and we can more
+easily adapt it in the future to new versions of Proof General.
+
+Even Emacs Lisp experts should prefer the simplified mechanism. If you
+want to set some buffer-local variables in your Proof General modes, or
+invoke supporting lisp code, this can easily be done by adding functions
+to the appropriate mode hooks after the @code{proof-easy-config} call.
+For example, to add extra settings for the shell mode for
+@code{demoisa}, we could do this:
+@lisp
+ (defun demoisa-shell-extra-config ()
+ @var{extra configuration ...}
+ )
+ (add-hook 'demoisa-shell-mode-hook 'demoisa-shell-extra-config)
+@end lisp
+The function to do extra configuration @code{demoisa-shell-extra-config}
+is then called as the final step when @code{demoisa-shell-mode} is
+entered (be wary, this will be after the generic
+@code{proof-shell-config-done} is called, so it will be too late to set
+normal configuration variables which may be examined by
+@code{proof-shell-config-done}).
+
+
+@node Major modes used by Proof General
+@section Major modes used by Proof General
+
+There are four major modes used by Proof General, one for each type of
+buffer it handles. The buffer types are: script, shell, response and
+goals. Each of these has a generic mode, respectively:
+@code{proof-mode}, @code{proof-shell-mode}, @code{proof-response-mode},
+and @code{proof-goals-mode}.
+
+The pattern for defining the major mode for an instance of Proof General
+is to use @code{define-derived-mode} to define a specific mode to inherit from
+each generic one, like this:
+@lisp
+(define-derived-mode myass-shell-mode proof-shell-mode
+ "MyAss shell" nil
+ (myass-shell-config)
+ (proof-shell-config-done))
+@end lisp
+Where @code{myass-shell-config} is a function which sets the
+configuration variables for the shell (@pxref{Proof shell settings}).
+
+It's important that each of your modes invokes one of the functions
+ @code{proof-config-done},
+ @code{proof-shell-config-done},
+ @code{proof-response-config-done}, or
+ @code{proof-goals-config-done}
+once it has set its configuration variables. These functions
+finalize the configuration of the mode.
+
+For each mode, there is a configuration variable which names it so that
+Proof General can set buffers to the proper mode, or find buffers in
+that mode. These are documented below, and set like this:
+@lisp
+ (setq proof-mode-for-script 'myass-mode)
+@end lisp
+where @code{myass-mode} is your major mode for scripts, derived from
+@code{proof-mode}. You must set these variables before the proof shell
+is started; one way to do this is inside a function which is called from
+the hook @code{pre-shell-start-hook}. See the file @file{demoisa.el}
+for details of how to do this.
+
+For future instantiations, it is recommended to follow the standard
+scheme: @code{@var{PA}-mode}, @code{@var{PA}-shell-mode}, etc.
+
+@c TEXI DOCSTRING MAGIC: proof-mode-for-script
+@defvar proof-mode-for-script
+Mode for proof script buffers.@*
+This is used by Proof General to find out which buffers
+contain proof scripts.
+The regular name for this is <PA>-mode. If you use any of the
+convenience macros Proof General provides for defining commands
+etc, then you should stick to this name.
+Suggestion: this can be set in the script mode configuration.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-mode-for-shell
+@defvar proof-mode-for-shell
+Mode for proof shell buffers.@*
+Usually customised for specific prover.
+Suggestion: this can be set a function called by @samp{@code{proof-pre-shell-start-hook}}.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-mode-for-response
+@defvar proof-mode-for-response
+Mode for proof response buffer.@*
+Usually customised for specific prover.
+Suggestion: this can be set a function called by @samp{@code{proof-pre-shell-start-hook}}.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-mode-for-goals
+@defvar proof-mode-for-goals
+Mode for proof state display buffers.@*
+Usually customised for specific prover.
+Suggestion: this can be set a function called by @samp{@code{proof-pre-shell-start-hook}}.
+@end defvar
+
+@node Menus and toolbar and user-level commands
+@chapter Menus, toolbar, and user-level commands
+
+The variables described in this chapter configure the menus, toolbar,
+and user-level commands. They should be set in the script mode
+before @code{proof-config-done} is called. (Toolbar configuration must
+be made before @file{proof-toolbar.el} is loaded, which usually is
+triggered automatically by an attempt to display the toolbar).
+
+@menu
+* Settings for generic user-level commands::
+* Menu configuration::
+* Toolbar configuration::
+@end menu
+
+@node Settings for generic user-level commands
+@section Settings for generic user-level commands
+
+@c TEXI DOCSTRING MAGIC: proof-assistant-home-page
+@defvar proof-assistant-home-page
+Web address for information on proof assistant.@*
+Used for Proof General's help menu.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-context-command
+@defvar proof-context-command
+Command to display the context in proof assistant.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-info-command
+@defvar proof-info-command
+Command to ask for help or information in the proof assistant.@*
+String or fn. If a string, the command to use.
+If a function, it should return the command string to insert.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-showproof-command
+@defvar proof-showproof-command
+Command to display proof state in proof assistant.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-goal-command
+@defvar proof-goal-command
+Command to set a goal in the proof assistant. String or fn.@*
+If a string, the format character @samp{%s} will be replaced by the
+goal string.
+If a function, it should return the command string to insert.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-save-command
+@defvar proof-save-command
+Command to save a proved theorem in the proof assistant. String or fn.@*
+If a string, the format character @samp{%s} will be replaced by the
+theorem name.
+If a function, it should return the command string to insert.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-find-theorems-command
+@defvar proof-find-theorems-command
+Command to search for a theorem containing a given term. String or fn.@*
+If a string, the format character @samp{%s} will be replaced by the term.
+If a function, it should return the command string to insert.
+@end defvar
+
+
+
+@node Menu configuration
+@section Menu configuration
+
+As well as the generic Proof General menu, each proof assistant is
+provided with a specific menu which can have prover-specific commands.
+Proof General puts some default things on this menu, including the
+commands to start/stop the prover, and the user-extensible "Favourites"
+menu.
+
+@c TEXI DOCSTRING MAGIC: PA-menu-entries
+@defvar PA-menu-entries
+Extra entries for proof assistant specific menu. @*
+A list of menu items [@var{name} @var{callback} @var{enabler} ...]. See the documentation
+of @samp{@code{easy-menu-define}} for more details.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: PA-help-menu-entries
+@defvar PA-help-menu-entries
+Extra entries for help submenu for proof assistant specific help menu.@*
+A list of menu items [@var{name} @var{callback} @var{enabler} ...]. See the documentation
+of @samp{@code{easy-menu-define}} for more details.
+@end defvar
+
+
+@node Toolbar configuration
+@section Toolbar configuration
+
+Unlike the menus, Proof General has only one toolbar. For the "generic"
+aspect of Proof General to work well, we shouldn't change (the meaning
+of) the existing toolbar buttons too far. This would discourage people
+from experimenting with different proof assistants when they don't
+really know them, which is one of the advantages that Proof General
+brings.
+
+But in case it is hard to map some of the generic buttons
+onto functions in particular provers, and to allow extra
+buttons, there is a mechanism for adjustment.
+
+I used The Gimp to create the buttons for Proof General. The
+development distribution includes a button blank and some notes in
+@file{etc/notes.txt} about making new buttons.
+
+
+@c TEXI DOCSTRING MAGIC: proof-toolbar-entries-default
+@defvar proof-toolbar-entries-default
+Example value for proof-toolbar-entries. Also used to define Scripting menu.@*
+This gives a bare toolbar that works for any prover, providing the
+appropriate configuration variables are set.
+To add/remove prover specific buttons, adjust the @samp{<PA>-toolbar-entries}
+variable, and follow the pattern in @samp{@code{proof-toolbar}.el} for
+defining functions, images.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: PA-toolbar-entries
+@defvar PA-toolbar-entries
+List of entries for Proof General toolbar and Scripting menu.@*
+Format of each entry is (@var{token} @var{menuname} @var{tooltip} @var{enabler-p}).
+
+For each @var{token}, we expect an icon with base filename @var{token},
+a function proof-toolbar-<TOKEN>, and (optionally) an enabler
+proof-toolbar-<TOKEN>-enable-p.
+
+If @var{menuname} is nil, item will not appear on the scripting menu.
+
+If @var{tooltip} is nil, item will not appear on the toolbar.
+
+The default value is @samp{@code{proof-toolbar-entries-default}} which contains
+the standard Proof General buttons.
+@end defvar
+
+Here's an example of how to remove a button, from @file{af2.el}:
+@lisp
+(setq af2-toolbar-entries
+ (remassoc 'state af2-toolbar-entries))
+@end lisp
+
+
+
+@c defgroup proof-script
+@node Proof script settings
+@chapter Proof script settings
+
+The variables described in this chapter should be set in the script mode
+before @code{proof-config-done} is called. These variables configure
+recognition of commands in the proof script, and also control some of
+the behaviour of script management.
+
+
+@menu
+* Recognizing commands and comments::
+* Recognizing proofs::
+* Recognizing other elements::
+* Configuring undo behaviour::
+* Nested proofs::
+* Safe (state-preserving) commands::
+* Activate scripting hook::
+* Automatic multiple files::
+* Completions::
+@end menu
+
+
+@node Recognizing commands and comments
+@section Recognizing commands and comments
+
+The first four settings configure the generic parsing strategy for
+commands in the proof script. Usually only one of these three needs to
+be set. If the generic parsing functions are not flexible for your
+needs, you can supply a value for @code{proof-script-parse-function}.
+
+Note that for the generic functions to work properly, it is
+@strong{essential} that you set the syntax table for your mode properly,
+so that comments and strings are recognized. See the Emacs
+documentation to discover how to do this (particularly for the function
+@code{modify-syntax-entry}).
+
+@xref{Proof script mode}, for more details of the parsing
+functions.
+
+@c TEXI DOCSTRING MAGIC: proof-terminal-char
+@defvar proof-terminal-char
+Character which terminates every command sent to proof assistant. nil if none.
+
+To configure command recognition properly, you must set at least one
+of these: @samp{@code{proof-script-sexp-commands}}, @samp{@code{proof-script-command-end-regexp}},
+@samp{@code{proof-script-command-start-regexp}}, @samp{@code{proof-terminal-char}},
+or @samp{@code{proof-script-parse-function}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-script-sexp-commands
+@defvar proof-script-sexp-commands
+Non-nil if proof script has a LISP-like syntax, and commands are @code{top-level} sexps.@*
+You should set this variable in script mode configuration.
+
+To configure command recognition properly, you must set at least one
+of these: @samp{@code{proof-script-sexp-commands}}, @samp{@code{proof-script-command-end-regexp}},
+@samp{@code{proof-script-command-start-regexp}}, @samp{@code{proof-terminal-char}},
+or @samp{@code{proof-script-parse-function}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-script-command-start-regexp
+@defvar proof-script-command-start-regexp
+Regular expression which matches start of commands in proof script.@*
+You should set this variable in script mode configuration.
+
+To configure command recognition properly, you must set at least one
+of these: @samp{@code{proof-script-sexp-commands}}, @samp{@code{proof-script-command-end-regexp}},
+@samp{@code{proof-script-command-start-regexp}}, @samp{@code{proof-terminal-char}},
+or @samp{@code{proof-script-parse-function}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-script-command-end-regexp
+@defvar proof-script-command-end-regexp
+Regular expression which matches end of commands in proof script.@*
+You should set this variable in script mode configuration.
+
+To configure command recognition properly, you must set at least one
+of these: @samp{@code{proof-script-sexp-commands}}, @samp{@code{proof-script-command-end-regexp}},
+@samp{@code{proof-script-command-start-regexp}}, @samp{@code{proof-terminal-char}},
+or @samp{@code{proof-script-parse-function}}.
+@end defvar
+
+
+The next four settings configure the comment syntax. Notice that to get
+reliable behaviour of the parsing functions, you may need to modify the
+syntax table for your prover's mode. Read the Elisp manual for details
+about that.
+
+@c TEXI DOCSTRING MAGIC: proof-comment-start
+@defvar proof-comment-start
+String which starts a comment in the proof assistant command language.@*
+The script buffer's @code{comment-start} is set to this string plus a space.
+Moreover, comments are usually ignored during script management, and not
+sent to the proof process.
+
+You should set this variable for reliable working of Proof General,
+as well as @samp{@code{proof-comment-end}}.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-comment-start-regexp
+
+@defvar proof-comment-start-regexp
+Regexp which matches a comment start in the proof command language.
+
+The default value for this is set as (@code{regexp-quote} @code{proof-comment-start})
+but you can set this variable to something else more precise if necessary.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-comment-end
+@defvar proof-comment-end
+String which ends a comment in the proof assistant command language.@*
+The script buffer's @code{comment-end} is set to a space plus this string.
+See also @samp{@code{proof-comment-start}}.
+
+You should set this variable for reliable working of Proof General,
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-comment-end-regexp
+@defvar proof-comment-end-regexp
+Regexp which matches a comment end in the proof command language.
+
+The default value for this is set as (@code{regexp-quote} @code{proof-comment-end})
+but you can set this variable to something else more precise if necessary.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-case-fold-search
+@defvar proof-case-fold-search
+Value for @code{case-fold-search} when recognizing portions of proof scripts.@*
+Also used for completion, via @samp{@code{proof-script-complete}}.
+The default value is @samp{nil}. If your prover has a case @strong{insensitive}
+input syntax, @code{proof-case-fold-search} should be set to @samp{t} instead.
+NB: This setting is not used for matching output from the prover.
+@end defvar
+
+
+@node Recognizing proofs
+@section Recognizing proofs
+
+Up to three settings each may be supplied for recognizing goal-like and
+save-like commands. The @code{-with-hole-} settings are used to make a
+record of the name of the theorem proved, and also to build a default
+value for the rather complicated setting
+@code{proof-script-next-entity-regexps}, which activates the @i{function
+menu} feature.
+
+The @code{-p} subsidiary predicates were added to allow more
+discriminating behaviour for particular proof assistants. (This is a
+typical example of where the core framework needs some additional
+generalization, to simplify matters, and allow for a smooth handling of
+nested proofs; the present state is only part of the way there).
+
+
+@c TEXI DOCSTRING MAGIC: proof-goal-command-regexp
+@defvar proof-goal-command-regexp
+Matches a goal command in the proof script. @*
+This is used (1) to make the default value for @samp{@code{proof-goal-command-p}},
+used as an important part of script management to find the start
+of an atomic undo block, and (2) to construct the default
+for @samp{@code{proof-script-next-entity-regexps}} used for function menus.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-goal-with-hole-regexp
+@defvar proof-goal-with-hole-regexp
+Regexp which matches a command used to issue and name a goal.@*
+The name of the theorem is build from the variable
+@code{proof-goal-with-hole-result} using the same convention as
+@code{query-replace-regexp}.
+Used for setting names of goal..save regions and for default
+@code{function-menu} configuration in @code{proof-script-find-next-entity}.
+
+It's safe to leave this setting as nil.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-goal-command-p
+@defvar proof-goal-command-p
+A function to test: is this really a goal command?
+
+This is added as a more refined addition to @code{proof-goal-command-regexp},
+to solve the problem that Coq and some other provers can have goals which
+look like definitions, etc. (In the future we may generalize
+@code{proof-goal-command-regexp} instead).
+@end defvar
+
+
+@c TEXI DOCSTRING MAGIC: proof-save-command-regexp
+@defvar proof-save-command-regexp
+Matches a save command.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-save-with-hole-regexp
+@defvar proof-save-with-hole-regexp
+Regexp which matches a command to save a named theorem.@*
+The name of the theorem is build from the variable
+@code{proof-save-with-hole-result} using the same convention as
+@code{query-replace-regexp}.
+Used for setting names of goal..save and proof regions and for
+default @code{function-menu} configuration in @code{proof-script-find-next-entity}.
+
+It's safe to leave this setting as nil.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-completed-proof-behaviour
+@defvar proof-completed-proof-behaviour
+Indicates how Proof General treats commands beyond the end of a proof.@*
+Normally goal...save regions are "closed", i.e. made atomic for undo.
+But once a proof has been completed, there may be a delay before
+the "save" command appears --- or it may not appear at all. Unless
+nested proofs are supported, this can spoil the undo-behaviour in
+script management since once a new goal arrives the old undo history
+may be lost in the prover. So we allow Proof General to close
+off the goal..[save] region in more flexible ways.
+The possibilities are:
+@lisp
+ nil - nothing special; close only when a save arrives
+ @code{'closeany} - close as soon as the next command arrives, save or not
+ @code{'closegoal} - close when the next "goal" command arrives
+ @code{'extend} - keep extending the closed region until a save or goal.
+@end lisp
+If your proof assistant allows nested goals, it will be wrong to close
+off the portion of proof so far, so this variable should be set to nil.
+There is no built-in understanding of the undo behaviour of nested
+proofs; instead there is some support for un-nesting nested proofs in
+the @code{proof-lift-global} mechanism. (Of course, this is risky in case of
+nested contexts!)
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-really-save-command-p
+@defvar proof-really-save-command-p
+Is this really a save command?
+
+This is a more refined addition to @code{proof-save-command-regexp}.
+It should be a function taking a span and command as argument,
+and can be used to track nested proofs. (See what is done in
+isar/ for example). In the future, this setting should be
+removed when the generic core is extended to handle nested
+proofs smoothly.
+@end defvar
+
+
+@node Recognizing other elements
+@section Recognizing other elements
+
+To configure the @i{function menu} feature, there are a couple of
+settings. These can be used to recognize named proofs, and other
+elements in the proof script as well.
+
+@c TEXI DOCSTRING MAGIC: proof-script-next-entity-regexps
+@defvar proof-script-next-entity-regexps
+Regular expressions to help find definitions and proofs in a script.@*
+This is the list of the form
+@lisp
+ (@var{anyentity-regexp}
+ @var{discriminator-regexp} ... @var{discriminator-regexp})
+@end lisp
+The idea is that @var{anyentity-regexp} matches any named entity in the
+proof script, on a line where the name appears. This is assumed to be
+the start or the end of the entity. The discriminators then test
+which kind of entity has been found, to get its name. A
+@var{discriminator-regexp} has one of the forms
+@lisp
+ (@var{regexp} @var{matchnos})
+ (@var{regexp} @var{matchnos} @code{'backward} @var{backregexp})
+ (@var{regexp} @var{matchnos} @code{'forward} @var{forwardregexp})
+@end lisp
+If @var{regexp} matches the string captured by @var{anyentity-regexp}, then
+@var{matchnos} are the match numbers for the substrings which name the entity
+(these may be either a single number or a list of numbers).
+
+If @code{'backward} @var{backregexp} is present, then the start of the entity
+is found by searching backwards for @var{backregexp}.
+
+Conversely, if @code{'forward} @var{forwardregexp} is found, then the end of
+the entity is found by searching forwards for @var{forwardregexp}.
+
+Otherwise, the start and end of the entity will be the region matched
+by @var{anyentity-regexp}.
+
+This mechanism allows fairly complex parsing of the buffer, in
+particular, it allows for goal..save regions which are named
+only at the end. However, it does not parse strings,
+comments, or parentheses.
+
+This variable may not need to be set: a default value which should
+work for goal..saves is calculated from @code{proof-goal-with-hole-regexp},
+@code{proof-goal-command-regexp}, and @code{proof-save-with-hole-regexp}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-script-find-next-entity-fn
+@defvar proof-script-find-next-entity-fn
+Name of function to find next interesting entity in a script buffer.@*
+This is used to configure @code{func-menu}. The default value is
+@code{proof-script-find-next-entity}, which searches for the next entity
+based on fume-function-name-regexp which by default is set from
+@code{proof-script-next-entity-regexps}.
+
+The function should move point forward in a buffer, and return a cons
+cell of the name and the beginning of the entity's region.
+
+Note that @code{proof-script-next-entity-regexps} is set to a default value
+from @code{proof-goal-with-hole-regexp} and @code{proof-save-with-hole-regexp} in
+the function @code{proof-config-done}, so you may not need to worry about any
+of this. See whether function menu does something sensible by
+default.
+@end defvar
+
+@node Configuring undo behaviour
+@section Configuring undo behaviour
+
+The settings here are used to configure the way "undo" commands are
+calculated.
+
+@c TEXI DOCSTRING MAGIC: proof-non-undoables-regexp
+@defvar proof-non-undoables-regexp
+Regular expression matching commands which are @strong{not} undoable.@*
+Used in default functions @samp{@code{proof-generic-state-preserving-p}}
+and @samp{@code{proof-generic-count-undos}}. If you don't use those,
+may be left as nil.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-ignore-for-undo-count
+@defvar proof-ignore-for-undo-count
+Matcher for script commands to be ignored in undo count.@*
+May be left as nil, in which case it will be set to
+@samp{@code{proof-non-undoables-regexp}}.
+Used in default function @samp{@code{proof-generic-count-undos}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-count-undos-fn
+@defvar proof-count-undos-fn
+Function to calculate a command to issue undos to reach a target span.@*
+The function takes a span as an argument, and should return a string
+which is the command to undo to the target span. The target is
+guaranteed to be within the current (open) proof.
+This is an important function for script management.
+The default setting @samp{@code{proof-generic-count-undos}} is based on the
+settings @samp{@code{proof-non-undoables-regexp}} and
+@samp{@code{proof-non-undoables-regexp}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-generic-count-undos
+@defun proof-generic-count-undos span
+Count number of undos in a span, return command needed to undo that far.@*
+Command is set using @samp{@code{proof-undo-n-times-cmd}}.
+
+A default value for @samp{@code{proof-count-undos-fn}}.
+
+For this function to work properly, you must configure
+@samp{@code{proof-undo-n-times-cmd}} and @samp{@code{proof-ignore-for-undo-count}}.
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-find-and-forget-fn
+@defvar proof-find-and-forget-fn
+Function that returns a command to forget back to before its argument span.@*
+This setting is used to for retraction (undoing) in proof scripts.
+
+It should undo the effect of all settings between its target span
+up to (@code{proof-locked-end}). This may involve forgetting a number
+of definitions, declarations, or whatever.
+
+The special string @code{proof-no-command} means there is nothing to do.
+
+Important: the generic implementation @samp{@code{proof-generic-find-and-forget}}
+does nothing, it always returns @samp{@code{proof-no-command}}.
+
+This is an important function for script management.
+Study one of the existing instantiations for examples of how to write it,
+or leave it set to the default function @samp{@code{proof-generic-find-and-forget}}
+(which see).
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-generic-find-and-forget
+@defun proof-generic-find-and-forget span
+Calculate a forget/undo command to forget back to @var{span}.@*
+This is a long-range forget: we know that there is no
+open goal at the moment, so forgetting involves unbinding
+declarations, etc, rather than undoing proof steps.
+
+Currently this has a trivial implementation: it
+just returns @code{proof-no-command}, meaning @samp{do nothing}.
+
+Check the @code{lego-find-and-forget} or @code{coq-find-and-forget}
+functions for examples of how to write this function.
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-goal-hyp-fn
+@defvar proof-goal-hyp-fn
+Function which returns cons cell if point is at a goal/hypothesis.@*
+This is used to parse the proofstate output to mark it up for
+proof-by-pointing. It should return a cons or nil. First element of
+the cons is a symbol, @code{'goal'} or @code{'hyp'}. The second element is a
+string: the goal or hypothesis itself.
+
+If you leave this variable unset, no proof-by-pointing markup
+will be attempted.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-kill-goal-command
+@defvar proof-kill-goal-command
+Command to kill the currently open goal.@*
+You must set this (perhaps to a no-op) for script management to work.
+@end defvar
+
+
+@node Nested proofs
+@section Nested proofs
+
+Proof General doesn't yet have a flexible understanding of
+nested proofs, but can do something with them.
+
+@c TEXI DOCSTRING MAGIC: proof-global-p
+@defvar proof-global-p
+Whether a command is a global declaration. Predicate on strings or nil.@*
+This is used to handle nested goals allowed by some provers, by
+recognizing global declarations as candidates for rearranging the
+proof script.
+
+May be left as nil to disable this function.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-lift-global
+@defvar proof-lift-global
+Function which lifts local lemmas from inside goals out to top level.@*
+This function takes the local goalsave span as an argument. Leave this
+set this at @samp{nil} if the proof assistant does not support nested goals,
+or if you don't want to write a function to do move them around.
+@end defvar
+
+
+@node Safe (state-preserving) commands
+@section Safe (state-preserving) commands
+
+A proof command is "safe" if it can be issued away from the proof
+script. For this to work it should be state-preserving in the proof
+assistant (with respect to an on-going proof).
+
+@c TEXI DOCSTRING MAGIC: proof-state-preserving-p
+@defvar proof-state-preserving-p
+A predicate, non-nil if its argument (a command) preserves the proof state.@*
+If set, used by @code{proof-minibuffer-cmd} to filter out scripting
+commands which should be entered directly into the script itself.
+
+The default setting for this function, @samp{@code{proof-generic-state-preserving-p}}
+tests by negating the match on @samp{@code{proof-non-undoables-regexp}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-generic-state-preserving-p
+@defun proof-generic-state-preserving-p cmd
+Is @var{cmd} state preserving? Match on @code{proof-non-undoables-regexp}.
+@end defun
+
+
+@node Activate scripting hook
+@section Activate scripting hook
+
+
+@c TEXI DOCSTRING MAGIC: proof-activate-scripting-hook
+@defvar proof-activate-scripting-hook
+Hook run when a buffer is switched into scripting mode.@*
+The current buffer will be the newly active scripting buffer.
+
+This hook may be useful for synchronizing with the proof
+assistant, for example, to switch to a new theory
+(in case that isn't already done by commands in the proof
+script).
+
+When functions in this hook are called, the variable
+@samp{activated-interactively} will be non-nil if
+@code{proof-activate-scripting} was called interactively
+(rather than as a side-effect of some other action).
+If a hook function sends commands to the proof process,
+it should wait for them to complete (so the queue is cleared
+for scripting commands), unless activated-interactively is set.
+@end defvar
+
+
+@node Automatic multiple files
+@section Automatic multiple files
+
+@xref{Handling multiple files}, for more details about this
+setting.
+
+@c TEXI DOCSTRING MAGIC: proof-auto-multiple-files
+@defvar proof-auto-multiple-files
+Whether to use automatic multiple file management.@*
+If non-nil, Proof General will automatically retract a script file
+whenever another one is retracted which it depends on. It assumes
+a simple linear dependency between files in the order which
+they were processed.
+
+If your proof assistant has no management of file dependencies, or one
+which depends on a simple linear context, you may be able to use this
+setting to good effect. If the proof assistant has more complex
+file dependencies then you should configure it to communicate with
+Proof General about the dependencies rather than using this setting.
+@end defvar
+
+
+@node Completions
+@section Completions
+
+Proof General allows provers to create a @i{completion table} to help
+writing keywords and identifiers in proof scripts. This is documented
+in the main @i{Proof General} user manual but summarized here for (a
+different kind of) completion.
+
+Completions are filled in according to what has been recently typed,
+from a database of symbols. The database is automatically saved at the
+end of a session. Completion is usually a hand-wavy thing, so we don't
+make any attempt to maintain a precise completion table or anything.
+
+The completion table maintained by @file{complete.el} is initialized
+from @code{PA-completion-table} when @file{proof-script.el} is loaded.
+This is done with the function @code{proof-add-completions} which
+you may want to call at other times.
+
+
+@c TEXI DOCSTRING MAGIC: PA-completion-table
+@defvar PA-completion-table
+List of identifiers to use for completion for this proof assistant.@*
+Completion is activated with C-return.
+
+If this table is empty or needs adjusting, please make changes using
+@samp{@code{customize-variable}} and send suggestions to proofgen@@dcs.ed.ac.uk.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-add-completions
+@deffn Command proof-add-completions
+Add completions from <PA>-completion-table to completion database.@*
+Uses @samp{@code{add-completion}} with a negative number of uses and ancient
+last use time, to discourage saving these into the users database.
+@end deffn
+
+
+
+
+
+
+@node Proof shell settings
+@chapter Proof shell settings
+
+The variables in this chapter concern the proof shell mode, and are the
+largest group. They are split into several subgroups. The first
+subgroup are commands invoked at various points. The second subgroup of
+variables are concerned with matching the output from the proof
+assistant. The final subgroup contains various hooks which you can set
+to add lisp customization to Proof General in various points (some of
+them are also used internally for behaviour you may wish to adjust).
+
+Variables for configuring the proof shell are put into the customize
+group @code{proof-shell}.
+
+These should be set in the shell mode configuration, before
+@code{proof-shell-config-done} is called.
+
+To understand the way the proof assistant runs inside Emacs, you may
+want to refer to the @code{comint.el} (Command interpreter) package
+distributed with Emacs. This package controls several shell-like modes
+available in Emacs, including the @code{proof-shell-mode} and
+all specific shell modes derived from it.
+
+@menu
+* Proof shell commands::
+* Script input to the shell::
+* Settings for matching various output from proof process::
+* Settings for matching urgent messages from proof process::
+* Hooks and other settings::
+@end menu
+
+@node Proof shell commands
+@section Commands
+
+Settings in this section configure Proof General with commands
+to send to the prover to activate certain actions.
+
+@c TEXI DOCSTRING MAGIC: proof-prog-name
+@defvar proof-prog-name
+System command to run the proof assistant in the proof shell.@*
+Suggestion: this can be set in @code{proof-pre-shell-start-hook} from
+a variable which is in the proof assistant's customization
+group. This allows different proof assistants to coexist
+(albeit in separate Emacs sessions).
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-auto-terminate-commands
+
+@defvar proof-shell-auto-terminate-commands
+Non-nil if Proof General should try to add terminator to every command.@*
+If non-nil, whenever a command is sent to the prover using
+@samp{@code{proof-shell-invisible-command}}, Proof General will check to see if it
+ends with @code{proof-terminal-char}, and add it if not.
+If @code{proof-terminal-char} is nil, this has no effect.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-pre-sync-init-cmd
+@defvar proof-shell-pre-sync-init-cmd
+The command for configuring the proof process to gain synchronization.@*
+This command is sent before Proof General's synchronization
+mechanism is engaged, to allow customization inside the process
+to help gain syncrhonization (e.g. engaging special markup).
+
+It is better to configure the proof assistant for this purpose
+via command line options if possible, in which case this variable
+does not need to be set.
+
+See also @samp{@code{proof-shell-init-cmd}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-init-cmd
+@defvar proof-shell-init-cmd
+The command for initially configuring the proof process.@*
+This command is sent to the process as soon as synchronization is gained
+(when an annotated prompt is first recognized). It can be used to configure
+the proof assistant in some way, or print a welcome message
+(since output before the first prompt is discarded).
+
+See also @samp{@code{proof-shell-pre-sync-init-cmd}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-restart-cmd
+@defvar proof-shell-restart-cmd
+A command for re-initialising the proof process.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-quit-cmd
+@defvar proof-shell-quit-cmd
+A command to quit the proof process. If nil, send EOF instead.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-quit-timeout
+@defvar proof-shell-quit-timeout
+The number of seconds to wait after sending @code{proof-shell-quit-cmd}.@*
+After this timeout, the proof shell will be killed off more rudely.
+If your proof assistant takes a long time to clean up (for
+example writing persistent databases out or the like), you may
+need to bump up this value.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-cd-cmd
+@defvar proof-shell-cd-cmd
+Command to the proof assistant to change the working directory.@*
+The format character @samp{%s} is replaced with the directory, and
+the escape sequences in @samp{@code{proof-shell-filename-escapes}} are
+applied to the filename.
+
+This setting is used to define the function @code{proof-cd} which
+changes to the value of (@code{default-directory}) for script buffers.
+For files, the value of (@code{default-directory}) is simply the
+directory the file resides in.
+
+NB: By default, @code{proof-cd} is called from @code{proof-activate-scripting-hook},
+so that the prover switches to the directory of a proof
+script every time scripting begins.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-start-silent-cmd
+@defvar proof-shell-start-silent-cmd
+Command to turn prover goals output off when sending many script commands.@*
+If non-nil, Proof General will automatically issue this command
+to help speed up processing of long proof scripts.
+See also @code{proof-shell-stop-silent-cmd}.
+NB: terminator not added to command.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-stop-silent-cmd
+@defvar proof-shell-stop-silent-cmd
+Command to turn prover output on. @*
+If non-nil, Proof General will automatically issue this command
+to help speed up processing of long proof scripts.
+See also @code{proof-shell-start-silent-cmd}.
+NB: Terminator not added to command.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-silent-threshold
+@defvar proof-shell-silent-threshold
+Number of waiting commands in the proof queue needed to trigger silent mode.@*
+Default is 2, but you can raise this in case switching silent mode
+on or off is particularly expensive (or make it ridiculously large
+to disable silent mode altogether).
+@end defvar
+@xref{Handling multiple files},
+for more details about the final two settings in this group,
+
+
+@c TEXI DOCSTRING MAGIC: proof-shell-inform-file-processed-cmd
+@defvar proof-shell-inform-file-processed-cmd
+Command to the proof assistant to tell it that a file has been processed.@*
+The format character @samp{%s} is replaced by a complete filename for a
+script file which has been fully processed interactively with
+Proof General. See @samp{@code{proof-format-filename}} for other possibilities
+to process the filename.
+
+This setting used to interface with the proof assistant's internal
+management of multiple files, so the proof assistant is kept aware of
+which files have been processed. Specifically, when scripting
+is deactivated in a completed buffer, it is added to Proof General's
+list of processed files, and the prover is told about it by
+issuing this command.
+
+If this is set to nil, no command is issued.
+
+See also: @code{proof-shell-inform-file-retracted-cmd},
+@code{proof-shell-process-file}, @code{proof-shell-compute-new-files-list}.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-inform-file-retracted-cmd
+@defvar proof-shell-inform-file-retracted-cmd
+Command to the proof assistant to tell it that a file has been retracted.@*
+The format character @samp{%s} is replaced by a complete filename for a
+script file which Proof General wants the prover to consider as not
+completely processed. See @samp{@code{proof-format-filename}} for other
+possibilities to process the filename.
+
+This is used to interface with the proof assistant's internal
+management of multiple files, so the proof assistant is kept aware of
+which files have been processed. Specifically, when scripting
+is activated, the file is removed from Proof General's list of
+processed files, and the prover is told about it by issuing this
+command. The action may cause the prover in turn to suggest to
+Proof General that files depending on this one are
+also unlocked.
+
+If this is set to nil, no command is issued.
+
+See also: @code{proof-shell-inform-file-processed-cmd},
+@code{proof-shell-process-file}, @code{proof-shell-compute-new-files-list}.
+@end defvar
+
+
+@node Script input to the shell
+@section Script input to the shell
+
+Generally, commands from the proof script are sent verbatim to the proof
+process running in the proof shell. For historical reasons, carriage
+returns are stripped by default. You can set
+@code{proof-shell-strip-crs-from-input} to adjust that. For more
+sophisticated pre-processing of the sent string, you may like to set
+@code{proof-shell-insert-hook}.
+
+@c TEXI DOCSTRING MAGIC: proof-shell-strip-crs-from-input
+@defvar proof-shell-strip-crs-from-input
+If non-nil, replace carriage returns in every input with spaces.@*
+This is enabled by default: it is appropriate for some systems
+because several CR's can result in several prompts, which may mess
+up the display (or even worse, the synchronization).
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-insert-hook
+@defvar proof-shell-insert-hook
+Hooks run by @code{proof-shell-insert} before inserting a command.@*
+Can be used to configure the proof assistant to the interface in
+various ways -- for example, to observe or alter the commands sent to
+the prover, or to sneak in extra commands to configure the prover.
+
+This hook is called inside a @code{save-excursion} with the @code{proof-shell-buffer}
+current, just before inserting and sending the text in the
+variable @samp{string}. The hook can massage @samp{string} or insert additional
+text directly into the @code{proof-shell-buffer}.
+Before sending @samp{string}, it will be stripped of carriage returns.
+
+Additionally, the hook can examine the variable @samp{action}. It will be
+a symbol, set to the callback command which is executed in the proof
+shell filter once @samp{string} has been processed. The @samp{action} variable
+suggests what class of command is about to be inserted:
+@lisp
+ @code{'proof-done-invisible} A non-scripting command
+ @code{'proof-done-advancing} A "forward" scripting command
+ @code{'proof-done-retracting} A "backward" scripting command
+@end lisp
+Caveats: You should be very careful about setting this hook. Proof
+General relies on a careful synchronization with the process between
+inputs and outputs. It expects to see a prompt for each input it
+sends from the queue. If you add extra input here and it causes more
+prompts than expected, things will break! Extending the variable
+@samp{string} may be safer than inserting text directly, since it is
+stripped of carriage returns before being sent.
+
+Example uses:
+@var{lego} uses this hook for setting the pretty printer width if
+the window width has changed;
+Plastic uses it to remove literate-style markup from @samp{string}.
+The x-symbol support uses this hook to convert special characters
+into tokens for the proof assistant.
+@end defvar
+
+
+
+
+
+
+@node Settings for matching various output from proof process
+@section Settings for matching various output from proof process
+
+
+@c TEXI DOCSTRING MAGIC: proof-shell-wakeup-char
+@defvar proof-shell-wakeup-char
+A special character which terminates an annotated prompt.@*
+Set to nil if proof assistant does not support annotated prompts.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-first-special-char
+@defvar proof-shell-first-special-char
+First special character.@*
+Codes above this character can have special meaning to Proof General,
+and are stripped from the prover's output strings.
+Leave unset if no special characters are being used.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-prompt-pattern
+@defvar proof-shell-prompt-pattern
+Proof shell's value for comint-prompt-pattern, which see.@*
+This pattern is just for interaction in comint (shell buffer).
+You don't really need to set it.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-annotated-prompt-regexp
+@defvar proof-shell-annotated-prompt-regexp
+Regexp matching a (possibly annotated) prompt pattern.@*
+Output is grabbed between pairs of lines matching this regexp.
+To help matching you may be able to annotate the proof assistant
+prompt with a special character not appearing in ordinary output.
+The special character should appear in this regexp, and should
+be the value of @code{proof-shell-wakeup-char}.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-abort-goal-regexp
+@defvar proof-shell-abort-goal-regexp
+Regexp matching output from an aborted proof.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-error-regexp
+@defvar proof-shell-error-regexp
+Regexp matching an error report from the proof assistant.
+
+We assume that an error message corresponds to a failure in the last
+proof command executed. So don't match mere warning messages with
+this regexp. Moreover, an error message should not be matched as an
+eager annotation (see @code{proof-shell-eager-annotation-start}) otherwise it
+will be lost.
+
+Error messages are considered to begin from @code{proof-shell-error-regexp}
+and continue until the next prompt.
+
+The engine matches interrupts before errors, see @code{proof-shell-interrupt-regexp}.
+
+It is safe to leave this variable unset (as nil).
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-interrupt-regexp
+@defvar proof-shell-interrupt-regexp
+Regexp matching output indicating the assistant was interrupted.@*
+We assume that an interrupt message corresponds to a failure in the last
+proof command executed. So don't match mere warning messages with
+this regexp. Moreover, an interrupt message should not be matched as an
+eager annotation (see @code{proof-shell-eager-annotation-start}) otherwise it
+will be lost.
+
+The engine matches interrupts before errors, see @code{proof-shell-error-regexp}.
+
+It is safe to leave this variable unset (as nil).
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-proof-completed-regexp
+@defvar proof-shell-proof-completed-regexp
+Regexp matching output indicating a finished proof.
+
+When output which matches this regexp is seen, we clear the goals
+buffer in case this is not also marked up as a @samp{goals} type of
+message.
+
+We also enable the QED function (save a proof) and will automatically
+close off the proof region if another goal appears before a save
+command.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-start-goals-regexp
+@defvar proof-shell-start-goals-regexp
+Regexp matching the start of the proof state output.@*
+This is an important setting. Output between @samp{@code{proof-shell-start-goals-regexp}}
+and @samp{@code{proof-shell-end-goals-regexp}} will be pasted into the goals buffer
+and possibly analysed further for proof-by-pointing markup.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-end-goals-regexp
+@defvar proof-shell-end-goals-regexp
+Regexp matching the end of the proof state output, or nil.@*
+If nil, just use the rest of the output following @code{proof-shell-start-goals-regexp}.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-assumption-regexp
+@defvar proof-shell-assumption-regexp
+A regular expression matching the name of assumptions.
+
+At the moment, this setting is not used in the generic Proof General.
+
+In the future it will be used for a generic implementation for @samp{@code{proof-goal-hyp-fn}},
+used to help parse the goals buffer to annotate it for proof by pointing.
+@end defvar
+
+
+
+@node Settings for matching urgent messages from proof process
+@section Settings for matching urgent messages from proof process
+
+Among the various dialogue messages that the proof assistant outputs
+during proof, Proof General can consider certain messages to be
+"urgent". When processing many lines of a proof, Proof General will
+normally supress the output, waiting until the final message appears
+before displaying anything to the user. Urgent messages escape this:
+typically they include messages that the prover wants the user to
+notice, for example, perhaps, file loading messages, or timing
+statistics.
+
+So that Proof General notices, these urgent messages should be marked-up
+with "eager" annotations.
+
+@c TEXI DOCSTRING MAGIC: proof-shell-eager-annotation-start
+@defvar proof-shell-eager-annotation-start
+Eager annotation field start. A regular expression or nil.@*
+An eager annotation indicates to Proof General that some following output
+should be displayed (or processed) immediately and not accumulated for
+parsing later.
+
+It is nice to recognize (starts of) warnings or file-reading messages
+with this regexp. You must also recognize any special messages
+from the prover to PG with this regexp (e.g. @samp{@code{proof-shell-clear-goals-regexp}},
+@samp{@code{proof-shell-retract-files-regexp}}, etc.)
+
+See also @samp{@code{proof-shell-eager-annotation-start-length}},
+@samp{@code{proof-shell-eager-annotation-end}}.
+
+Set to nil to disable this feature.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-eager-annotation-start-length
+
+@defvar proof-shell-eager-annotation-start-length
+Maximum length of an eager annotation start. @*
+Must be set to the maximum length of the text that may match
+@samp{@code{proof-shell-eager-annotation-start}} (at least 1).
+If this value is too low, eager annotations may be lost!
+
+This value is used internally by Proof General to optimize the process
+filter to avoid unnecessary searching.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-eager-annotation-end
+@defvar proof-shell-eager-annotation-end
+Eager annotation field end. A regular expression or nil.@*
+An eager annotation indicates to Emacs that some following output
+should be displayed or processed immediately.
+
+See also @samp{@code{proof-shell-eager-annotation-start}}.
+
+It is nice to recognize (ends of) warnings or file-reading messages
+with this regexp. You must also recognize (ends of) any special messages
+from the prover to PG with this regexp (e.g. @samp{@code{proof-shell-clear-goals-regexp}},
+@samp{@code{proof-shell-retract-files-regexp}}, etc.)
+
+The default value is "\n" to match up to the end of the line.
+@end defvar
+
+
+The default action for urgent messages is to display them in the
+response buffer, highlighted. But we also allow for some control
+messages, issued from the proof assistant to Proof General and not
+intended for the user to see. These are recognized in the same way as
+urgent messages (marked with eager annotations), so they will
+be acted on as soon as they are issued by the prover.
+
+
+@c TEXI DOCSTRING MAGIC: proof-shell-clear-response-regexp
+@defvar proof-shell-clear-response-regexp
+Regexp matching output telling Proof General to clear the response buffer.@*
+This feature is useful to give the prover more control over what output
+is shown to the user. Set to nil to disable.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-clear-goals-regexp
+@defvar proof-shell-clear-goals-regexp
+Regexp matching output telling Proof General to clear the goals buffer.@*
+This feature is useful to give the prover more control over what output
+is shown to the user. Set to nil to disable.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-set-elisp-variable-regexp
+@defvar proof-shell-set-elisp-variable-regexp
+Regexp matching output telling Proof General to set some variable.@*
+This allows the proof assistant to configure Proof General directly
+and dynamically.
+
+If the regexp matches output from the proof assistant, there should be
+two match strings: (@code{match-string} 1) should be the name of the elisp
+variable to be set, and (@code{match-string} 2) should be the value of the
+variable (which will be evaluated as a lisp expression).
+
+A good markup for the second string is to delimit with #'s, since
+these are not valid syntax for elisp evaluation.
+
+Elisp errors will be trapped when evaluating; set
+@code{proof-show-debug-messages} to be informed when this happens.
+
+Example uses are to adjust PG's internal copies of proof assistant's
+settings, or to make automatic dynamic syntax adjustments in Emacs to
+match changes in theory, etc.
+
+If you pick a dummy variable name (e.g. @samp{proof-dummy-setting}) you
+can just evaluation arbitrary elisp expressions for their side
+effects, to adjust menu entries, or even launch auxiliary programs.
+But use with care -- there is no protection against catastrophic elisp!
+
+This setting could also be used to move some configuration settings
+from PG to the prover, but this is not really supported (most settings
+must be made before this mechanism will work). In future, the PG
+standard protocol, @var{pgip}, will use this mechanism for making all
+settings.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-theorem-dependency-list-regexp
+@defvar proof-shell-theorem-dependency-list-regexp
+Regexp matching output telling Proof General what the dependencies are. @*
+This is so that the dependent theorems can be highlighted somehow.
+Set to nil to disable.
+This is an experimental feature, currently work-in-progress.
+@end defvar
+
+Two important control messages are recognized by
+@code{proof-shell-process-file} and
+@code{proof-shell-retract-files-regexp}, used for synchronizing Proof
+General with a file loading mechanism built into the proof assistant.
+@xref{Handling multiple files}, for more details about how to use the
+final three settings described here.
+
+@vindex proof-included-files-list
+@c TEXI DOCSTRING MAGIC: proof-shell-process-file
+@defvar proof-shell-process-file
+A pair (@var{regexp} . @var{function}) to match a processed file name.
+
+If @var{regexp} matches output, then the function @var{function} is invoked on the
+output string chunk. It must return the name of a script file (with
+complete path) that the system has successfully processed. In
+practice, @var{function} is likely to inspect the match data. If it returns
+the empty string, the file name of the scripting buffer is used
+instead. If it returns nil, no action is taken.
+
+Care has to be taken in case the prover only reports on compiled
+versions of files it is processing. In this case, @var{function} needs to
+reconstruct the corresponding script file name. The new (true) file
+name is added to the front of @samp{@code{proof-included-files-list}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-retract-files-regexp
+@defvar proof-shell-retract-files-regexp
+Matches a message that the prover has retracted a file.
+
+At this stage, Proof General's view of the processed files is out of
+date and needs to be updated with the help of the function
+@samp{@code{proof-shell-compute-new-files-list}}.
+@end defvar
+@vindex proof-included-files-list
+
+@c TEXI DOCSTRING MAGIC: proof-shell-compute-new-files-list
+@defvar proof-shell-compute-new-files-list
+Function to update @samp{proof-included-files list}.
+
+It needs to return an up to date list of all processed files. Its
+output is stored in @samp{@code{proof-included-files-list}}. Its input is the
+string of which @samp{@code{proof-shell-retract-files-regexp}} matched a
+substring. In practice, this function is likely to inspect the
+previous (global) variable @samp{@code{proof-included-files-list}} and the match
+data triggered by @samp{@code{proof-shell-retract-files-regexp}}.
+@end defvar
+
+
+
+@node Hooks and other settings
+@section Hooks and other settings
+
+@c TEXI DOCSTRING MAGIC: proof-shell-filename-escapes
+@defvar proof-shell-filename-escapes
+A list of escapes that are applied to %s for filenames.@*
+A list of cons cells, car of which is string to be replaced
+by the cdr.
+For example, when directories are sent to Isabelle, HOL, and Coq,
+they appear inside ML strings and the backslash character and
+quote characters must be escaped. The setting
+@lisp
+ '(("@var{\\\\}" . "@var{\\\\}")
+ ("\"" . "\\\""))
+@end lisp
+achieves this. This does not apply to @var{lego}, which does not
+need backslash escapes and does not allow filenames with
+quote characters.
+
+This setting is used inside the function @samp{@code{proof-format-filename}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-process-connection-type
+@defvar proof-shell-process-connection-type
+The value of @code{process-connection-type} for the proof shell.@*
+Set non-nil for ptys, nil for pipes.
+The default (and preferred) option is to use pty communication.
+However there is a long-standing backslash/long line problem with
+Solaris which gives a mess of ^G characters when some input is sent
+which has a in the 256th position.
+So we select pipes by default if it seems like we're on Solaris.
+We do not force pipes everywhere because this risks loss of data.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-pre-shell-start-hook
+@defvar proof-pre-shell-start-hook
+Hooks run before proof shell is started.@*
+Suggestion: set this to a function which configures just these proof
+shell variables:
+@lisp
+ @code{proof-prog-name}
+ @code{proof-mode-for-shell}
+ @code{proof-mode-for-response}
+ @code{proof-mode-for-goals}
+@end lisp
+This is the bare minimum needed to get a shell buffer and
+its friends configured in the function @code{proof-shell-start}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-handle-error-or-interrupt-hook
+@defvar proof-shell-handle-error-or-interrupt-hook
+Run after an error or interrupt has been reported in the response buffer.@*
+Hook functions may inspect @samp{@code{proof-shell-error-or-interrupt-seen}} to
+determine whether the cause was an error or interrupt.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-pre-interrupt-hook
+@defvar proof-shell-pre-interrupt-hook
+Run immediately after @samp{@code{comint-interrupt-subjob}} is called.@*
+This hook is added to allow customization for Poly/ML and other
+systems where the system queries the user before returning to
+the top level. For Poly/ML it can be used to send the string "f",
+for example.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-process-output-system-specific
+@defvar proof-shell-process-output-system-specific
+Set this variable to handle system specific output.@*
+Errors, start of proofs, abortions of proofs and completions of
+proofs are recognised in the function @samp{@code{proof-shell-process-output}}.
+All other output from the proof engine is simply reported to the
+user in the @var{response} buffer.
+
+To catch further special cases, set this variable to a pair of
+functions '(condf . actf). Both are given (cmd string) as arguments.
+@samp{cmd} is a string containing the currently processed command.
+@samp{string} is the response from the proof system. To change the
+behaviour of @samp{@code{proof-shell-process-output}}, (condf cmd string) must
+return a non-nil value. Then (actf cmd string) is invoked.
+
+See the documentation of @samp{@code{proof-shell-process-output}} for the required
+output format.
+@end defvar
+
+
+
+
+
+@node Goals buffer settings
+@chapter Goals buffer settings
+
+The goals buffer settings allow configuration of Proof General for proof
+by pointing or similar features.
+See the Proof General @uref{http://www.proofgeneral.org/doc, documentation web page}
+for a link to the technical report ECS-LFCS-97-368 which hints
+at how to use these settings.
+
+@c At the moment these settings are disabled.
+
+@c TEXI DOCSTRING MAGIC: pbp-change-goal
+@defvar pbp-change-goal
+Command to change to the goal @samp{%s}
+@end defvar
+@c TEXI DOCSTRING MAGIC: pbp-goal-command
+@defvar pbp-goal-command
+Command informing the prover that @samp{@code{pbp-button-action}} has been@*
+requested on a goal.
+@end defvar
+@c TEXI DOCSTRING MAGIC: pbp-hyp-command
+@defvar pbp-hyp-command
+Command informing the prover that @samp{@code{pbp-button-action}} has been@*
+requested on an assumption.
+@end defvar
+@c TEXI DOCSTRING MAGIC: pbp-error-regexp
+@defvar pbp-error-regexp
+Regexp indicating that the proof process has identified an error.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-result-start
+@defvar proof-shell-result-start
+Regexp matching start of an output from the prover after pbp commands.@*
+In particular, after a @samp{@code{pbp-goal-command}} or a @samp{@code{pbp-hyp-command}}.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-result-end
+@defvar proof-shell-result-end
+Regexp matching end of output from the prover after pbp commands.@*
+In particular, after a @samp{@code{pbp-goal-command}} or a @samp{@code{pbp-hyp-command}}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-start-char
+@defvar proof-shell-start-char
+Starting special for a subterm markup.@*
+Subsequent characters with values @strong{below} @code{proof-shell-first-special-char}
+are assumed to be subterm position indicators. Subterm markups should
+be finished with @code{proof-shell-end-char}.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-end-char
+@defvar proof-shell-end-char
+Finishing special for a subterm markup.@*
+See documentation of @code{proof-shell-start-char}.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-goal-char
+@defvar proof-shell-goal-char
+Mark for goal.
+
+This setting is also used to see if proof-by-pointing features
+are configured. If it is unset, some of the code
+for parsing the prover output is disabled.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-shell-field-char
+@defvar proof-shell-field-char
+Annotated field end
+@end defvar
+
+
+@node Splash screen settings
+@chapter Splash screen settings
+
+The splash screen can be configured, in a rather limited way.
+
+@c TEXI DOCSTRING MAGIC: proof-splash-time
+@defvar proof-splash-time
+Minimum number of seconds to display splash screen for.@*
+The splash screen may be displayed for a couple of seconds longer than
+this, depending on how long it takes the machine to initialise
+Proof General.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-splash-contents
+@defvar proof-splash-contents
+Evaluated to configure splash screen displayed when entering Proof General.@*
+A list of the screen contents. If an element is a string or an image
+specifier, it is displayed centred on the window on its own line.
+If it is nil, a new line is inserted.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-splash-extensions
+@defvar proof-splash-extensions
+Prover specific extensions of splash screen.@*
+These are evaluated and appended to @samp{@code{proof-splash-contents}}.
+@end defvar
+
+
+
+
+
+
+@node Global constants
+@chapter Global constants
+
+The settings here are internal constants used by Proof General.
+You don't need to configure these for your proof assistant
+unless you want to modify or extend the defaults.
+
+@c TEXI DOCSTRING MAGIC: proof-general-name
+@defvar proof-general-name
+Proof General name used internally and in menu titles.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-general-home-page
+@defopt proof-general-home-page
+Web address for Proof General
+
+The default value is @code{"http://www.proofgeneral.org"}.
+@end defopt
+@c TEXI DOCSTRING MAGIC: proof-universal-keys
+@defvar proof-universal-keys
+List of key-bindings made for the script, goals and response buffer. @*
+Elements of the list are tuples @samp{(k . f)}
+where @samp{k} is a @code{key-binding} (vector) and @samp{f} the designated function.
+@end defvar
+
+
+
+@node Handling multiple files
+@chapter Handling multiple files
+@cindex Multiple files
+
+Large proof developments are typically spread across multiple files.
+Many provers support such developments by keeping track of dependencies
+and automatically processing scripts. Proof General supports this
+mechanism. The user's point of view is considered in the user manual.
+Here, we describe the more technical nitty gritty. This is what you
+need to know when you customise another proof assistant to work with
+Proof General.
+
+Documentation for the configuration settings mentioned here appears in
+the previous sections, this section is intended to help explain the use
+of those settings.
+
+Proof General maintains a list @code{proof-included-files-list} of files
+which it thinks have been processed by the proof assistant. When a file
+which is on this list is visited in Emacs, it will be coloured entirely
+blue to indicate that it has been processed. No editing of the file
+will be allowed (unless @code{proof-strict-read-only} allows it).
+
+
+@c TEXI DOCSTRING MAGIC: proof-included-files-list
+@defvar proof-included-files-list
+List of files currently included in proof process.@*
+This list contains files in canonical truename format
+(see @samp{@code{file-truename}}).
+
+Whenever a new file is being processed, it gets added to this list
+via the @code{proof-shell-process-file} configuration settings.
+When the prover retracts a file, this list is resynchronised via the
+@code{proof-shell-retract-files-regexp} and @code{proof-shell-compute-new-files-list}
+configuration settings.
+
+Only files which have been @strong{fully} processed should be included here.
+Proof General itself will automatically add the filenames of a script
+buffer which has been completely read when scripting is deactivated.
+It will automatically remove the filename of a script buffer which
+is completely unread when scripting is deactivated.
+
+NB: Currently there is no generic provision for removing files which
+are only partly read-in due to an error, so ideally the proof assistant
+should only output a processed message when a file has been successfully
+read.
+@end defvar
+
+The way that @code{proof-included-files-list} is maintained is the key
+to multiple file management. (But you should not set this variable
+directly, it is managed via the configuration settings).
+
+@vindex proof-shell-process-file
+@vindex proof-shell-retract-files-regexp
+@vindex proof-shell-compute-new-files-list
+
+There is a range of strategies for managing multiple files. Ideally,
+file dependencies should be managed by the proof assistant. Proof
+General will use the prover's low-level commands to process a whole file
+and its requirements non-interactively, without going through script
+management. So that the user knows which files have been processed, the
+proof assistant should issue messages which Proof General can recognize
+(``file @code{foo} has been processed'') --- see
+@code{proof-shell-process-file}. When the user wants to edit a file
+which has been processed, the file must be retracted (unlocked). The
+proof assistant should provide a command corresponding to this action,
+which undoes a given file and all its dependencies. As each file is
+undone, a message should be issued which Proof General can recognize
+(``file @code{foo} has been undone'') -- see
+@code{proof-shell-retract-files-regexp}. (The function
+@code{proof-shell-compute-new-files-list} should be set to calculate the
+new value for @code{proof-included-files-list} after a retract message
+has been seen).
+
+
+@c The key idea is that we leave it to the specific proof assistant to
+@c worry about managing multiple files, as far as possible. Whenever the
+@c proof assistant processes or retracts a file it must clearly say so, so
+@c that Proof General can register this.
+
+As well as this communication from the assistant to Proof General about
+processed or retracted files, Proof General can communicate the other
+way: it will tell the proof assistant when it has processed or retracted
+a file via script management. This is because during script management,
+the proof assistant may not be aware that it is actually dealing with a
+file of proof commands (rather than just terminal input).
+
+Proof General will provide this information in two special instances.
+First, when scripting is turned off in a file that has been completely
+processed, Proof General will tell the proof assistant using
+@code{proof-shell-inform-file-processed-cmd}. Second, when scripting is
+turned on in a file which is completely processed, Proof General will
+tell the proof assistant to reconsider: the file should not be
+considered completely processed yet. This uses the setting
+@code{proof-shell-inform-file-retracted-cmd}. This second case might
+lead to a series of messages from the prover telling Proof General to
+unlock files which depend on the present one, again via
+@code{proof-shell-retract-files-regexp}.
+
+What we have described so far is the ideal case, but it may require some
+support from the proof assistant to set up (for example, if file-level
+undo is not normally supported, or the messages during file processing
+are not suitable). Moreover, some proof assistants may not have file
+handling with dependencies, or may have a particularly simple case of a
+linear context: each file depends on all the ones processed before it.
+Proof General allows you a shortcut to get automatic management of
+multiple files in these cases by setting the flag
+@code{proof-auto-multiple-files}. This setting is probably an
+approximation to the right thing for any proof assistant. More files
+than necessary will be retracted if the prover has a tree-like file
+dependency rather than a linear one.
+
+@vindex proof-shell-eager-annotation-start
+@vindex proof-shell-eager-annotation-end
+Finally, we should mention how Proof General recognizes file processing
+messages from the proof assistant. Proof General considers @var{output}
+delimited by the the two regular expressions
+@code{proof-shell-eager-annotation-start} and
+@code{proof-shell-eager-annotation-end} as being important. It displays
+the @var{output} in the Response buffer and analyses the contents
+further. Among other important messages characterised by these regular
+expressions (warnings, errors, or information), the prover can tell the
+interface whenever it processes or retracts a file.
+
+
+To summarize, the settings for multiple file management that may be
+customized are as follows. To recognize file-processing,
+@code{proof-shell-process-file}. To recognize messages about file
+undoing, @code{proof-shell-retract-files-regexp} and
+@code{proof-shell-compute-new-files-list}. @xref{Settings for matching
+urgent messages from proof process}. To tell the prover about files
+handled with script management, use
+ @code{proof-shell-inform-file-processed-cmd} and
+ @code{proof-shell-inform-file-retracted-cmd}. @xref{Proof shell
+ commands}. Finally, set the flag @code{proof-auto-multiple-files}
+for a automatic approximation to multiple file handling.
+@xref{Proof script settings}.
+
+
+@node Configuring Font Lock
+@chapter Configuring Font Lock
+@cindex font lock
+
+Support for Font Lock in Proof General is described in the user manual
+(see the @i{Syntax highlighting} section). To configure Font Lock for a
+new proof assistant, you need to set the variable
+@code{font-lock-keywords} in each of the mode functions you want
+highlighting for. Proof General will automatically install these
+settings, and enable Font Lock minor mode (for syntax highlighting as
+you type) in script buffers.
+
+@c nope: too big. TEXI DOCSTRING MAGIC: font-lock-keywords
+To understand its format, check the documentation of
+@code{font-lock-keywords} inside Emacs.
+
+Proof General has a special hack for simplifying font lock settings
+@code{proof-font-lock-zap-commas}, but it is recommended to restrict to
+using the @code{font-lock-keywords} setting if possible.
+
+
+@c TEXI DOCSTRING MAGIC: proof-font-lock-zap-commas
+@defvar proof-font-lock-zap-commas
+If non-nil, enable a font-lock hack which unfontifies commas.@*
+If you fontify variables inside lists like [a,b,c] by matching
+on the brackets @samp{[} and @samp{]}, you may take objection to the commas
+being coloured as well. In that case, enable this hack which
+will magically restore the commas to the default font for you.
+
+The hack is rather painful and forces immediate fontification of
+files on loading (no lazy, caching locking). It is unreliable
+under GNU Emacs, to boot.
+
+@var{lego} and Coq enable it by tradition.
+@end defvar
+
+
+
+
+@node Configuring X-Symbol
+@chapter Configuring X-Symbol
+@cindex X-Symbol
+
+The X-Symbol package is described in the Proof General user manual. To
+configure X-Symbol for Proof General, you must understand a little bit
+of how X-Symbol works: read the documentation that is supplied with it.
+
+The basic task is to set up a @i{token language} for your proof
+assistant. If your assistant is stored in the subdirectory
+@var{myprover}, the token language will be called @var{myprover} and be
+defined in a file @file{x-symbol-@var{myprover}.el} which is
+automatically loaded by X-Symbol. The name of the token language mode
+will be @code{@var{myprover}sym}.
+
+Proof General will check that the file @file{x-symbol-@var{myprover}.el}
+exists and set up X-Symbol to load it. The token language file must
+define a number of standard settings, and X-Symbol will give warnings if
+any of them are missing.
+
+Apart from the token language file, there are several settings for
+X-Symbol which you can set in the usual configuration file
+@file{@var{myprover}.el}. These settings are optional.
+
+@c There's also proof-xsym-font-lock-keywords, but I don't
+@c really know what this setting is good for.
+
+@c TEXI DOCSTRING MAGIC: proof-xsym-activate-command
+@defvar proof-xsym-activate-command
+Command to activate token input/output for X-Symbol.@*
+If non-nil, this command is sent to the proof assistant when
+X-Symbol support is activated.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-xsym-deactivate-command
+@defvar proof-xsym-deactivate-command
+Command to deactivate token input/output for X-Symbol.@*
+If non-nil, this command is sent to the proof assistant when
+X-Symbol support is deactivated.
+@end defvar
+
+We expect tokens to be used uniformly, so that along with each script
+mode buffer, the response buffer and goals buffer also invoke X-Symbol
+to display special characters in the same token language. This happens
+automatically. If you want additional modes to use X-Symbol with the
+token language for your proof assistant, you can set
+@code{proof-xsym-extra-modes}.
+
+@c TEXI DOCSTRING MAGIC: proof-xsym-extra-modes
+@defvar proof-xsym-extra-modes
+List of additional mode names to use X-Symbol with Proof General tokens.@*
+These modes will have X-Symbol enabled for the proof assistant token language,
+in addition to the four modes for Proof General (script, shell, response, pbp).
+
+Set this variable if you want additional modes to also display
+tokens (for example, editing documentation or source code files).
+@end defvar
+
+
+
+@node Writing more lisp code
+@chapter Writing more lisp code
+
+You may want to add some extra features to your instance of Proof
+General which are not supported in the generic core. To do this, you
+can use the settings described above, plus a small number of fundamental
+functions in Proof General which you can consider as exported in the
+generic interface. Be careful using more functions than are mentioned
+here because the internals of Proof General may change between versions.
+
+@menu
+* Default values for generic settings::
+* Adding prover-specific configurations::
+* Useful variables::
+* Useful functions and macros::
+@end menu
+
+@node Default values for generic settings
+@section Default values for generic settings
+
+Several generic settings are defined using @code{defpgcustom} in
+@file{proof-config.el}. This introduces settings of the form
+@code{<PA>-name} for each proof assistant @var{PA}.
+
+To set the default value for these settings in prover-specific cases,
+you should use the special @code{defpgdefault} macro:
+
+@c TEXI DOCSTRING MAGIC: defpgdefault
+@deffn Macro defpgdefault
+Set default for the proof assistant specific variable <PA>@var{-sym} to @var{value}.@*
+This should be used in prover-specific code to alter the default values
+for prover specific settings.
+
+Usage: (defpgdefault SYM @var{value})
+@end deffn
+
+In your prover-specific code you can simply use the setting
+@code{<PA>-sym} directly, i.e., write @code{myprover-home-page}.
+
+In the generic code, you can use a macro, writing @code{(proof-ass
+home-page)} to refer to the @code{<PA>-home-page} setting for the
+currently running instance of Proof General.
+
+@xref{Configuration variable mechanisms}, for more details on this
+mechanism.
+
+
+@node Adding prover-specific configurations
+@section Adding prover-specific configurations
+
+Apart from the generic settings, your prover instance will probably need
+some specific customizable settings.
+
+Defining new prover-specific settings using customize is pretty easy.
+You should do it at least for your prover-specific user options.
+
+The code in @file{proof-site.el} provides each prover with two
+customization groups automatically (based on the name of the assistant):
+@code{<PA>} for user options for prover @var{PA}
+and
+@code{<PA>-config} for configuration of prover @var{PA}.
+Typically @code{<PA>-config} holds settings which are
+constants but which may be nice to tweak.
+
+The first group appears in the menu
+@lisp
+ ProofGeneral -> Customize -> <PA>
+@end lisp
+The second group appears in the menu:
+@lisp
+ ProofGeneral -> Internals -> <PA> config
+@end lisp
+
+A typical use of @code{defcustom} looks like this:
+@lisp
+(defcustom myprover-search-page
+ "http://findtheorem.myprover.org"
+ "URL of search web page for myprover."
+ :type 'string
+ :group 'myprover-config)
+@end lisp
+This introduces a new customizable setting, which you might use to make
+a menu entry, for example. The default value is the string
+@code{"http://findtheorem.myprover.org"}.
+
+
+
+
+
+
+@node Useful variables
+@section Useful variables
+
+In @file{proof-compat}, two architecture flags are defined. These can
+be used to write conditional pieces of code for different Emacs and
+operating systems.
+
+
+@c TEXI DOCSTRING MAGIC: proof-running-on-XEmacs
+
+@defvar proof-running-on-XEmacs
+Non-nil if Proof General is running on XEmacs.
+@end defvar
+@c TEXI DOCSTRING MAGIC: proof-running-on-win32
+
+
+
+
+@defvar proof-running-on-win32
+Non-nil if Proof General is running on a win32 system.
+@end defvar
+@node Useful functions and macros
+@section Useful functions and macros
+
+The recommended functions you may invoke are these:
+
+@itemize @bullet
+@item Any of the interactive commands (i.e. anything you
+ can invoke with @kbd{M-x}, including all key-bindings)
+@item Any of the internal functions and macros mentioned below
+@end itemize
+
+To insert text into the current (usually script) buffer, the function
+@code{proof-insert} is useful. There's also a handy macro
+@code{proof-defshortcut} for defining shortcut functions using it.
+
+
+@c TEXI DOCSTRING MAGIC: proof-insert
+@defun proof-insert text
+Insert @var{text} into the current buffer.@*
+@var{text} may include these special characters:
+@lisp
+ %p - place the point here after input
+@end lisp
+Any other %-prefixed character inserts itself.
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-defshortcut
+@deffn Macro proof-defshortcut
+Define shortcut function FN to insert @var{string}, optional keydef KEY.@*
+This is intended for defining proof assistant specific functions.
+@var{string} is inserted using @samp{@code{proof-insert}}, which see.
+KEY is added onto @code{proof-assistant} map.
+@end deffn
+The function @code{proof-shell-invisible-command} is a useful utility
+for sending a single command to the process. You should use this to
+implement user-level or internal functions rather than attempting to
+directly manipulate the proof action list, or insert into the shell
+buffer.
+
+@c TEXI DOCSTRING MAGIC: proof-shell-invisible-command
+@defun proof-shell-invisible-command cmd &optional wait
+Send @var{cmd} to the proof process. @*
+Automatically add @code{proof-terminal-char} if necessary, examining
+proof-shell-no-auto-terminate-commands.
+By default, let the command be processed asynchronously.
+But if optional @var{wait} command is non-nil, wait for processing to finish
+before and after sending the command.
+If @var{wait} is an integer, wait for that many seconds afterwards.
+@end defun
+
+There are several handy macros to help you define functions
+which invoke @code{proof-shell-invisible-command}.
+
+@c TEXI DOCSTRING MAGIC: proof-definvisible
+@deffn Macro proof-definvisible
+Define function FN to send @var{string} to proof assistant, optional keydef KEY.@*
+This is intended for defining proof assistant specific functions.
+@var{string} is sent using @code{proof-shell-invisible-command}, which see.
+KEY is added onto @code{proof-assistant} map.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-define-assistant-command
+@deffn Macro proof-define-assistant-command
+Define command FN to send string @var{body} to proof assistant, based on @var{cmdvar}.@*
+@var{body} defaults to @var{cmdvar}, a variable.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-define-assistant-command-witharg
+@deffn Macro proof-define-assistant-command-witharg
+Define command FN to prompt for string @var{cmdvar} to proof assistant.@*
+@var{cmdvar} is a function or string. Automatically has history.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-format-filename
+
+
+
+
+
+
+@defun proof-format-filename string filename
+Format @var{string} by replacing quoted chars by escaped version of @var{filename}.
+
+%e uses the canonicalized expanded version of filename (including
+directory, using @code{default-directory} -- see @samp{@code{expand-file-name}}).
+
+%r uses the unadjusted (possibly relative) version of @var{filename}.
+
+%m ('module') uses the basename of the file, without directory
+or extension.
+
+%s means the same as %e.
+
+Using %e can avoid problems with dumb proof assistants who don't
+understand ~, for example.
+
+For all these cases, the escapes in @samp{@code{proof-shell-filename-escapes}}
+are processed.
+
+If @var{string} is in fact a function, instead invoke it on @var{filename} and
+return the resulting (string) value.
+@end defun
+@node Internals of Proof General
+@chapter Internals of Proof General
+
+This chapter sketches some of the internal functions and variables of
+Proof General, to help developers who wish to understand or modify the
+code.
+
+Most of the documentation below is generated automatically from the
+comments in the code. Because Emacs lisp is interpreted and
+self-documenting, the best way to find your way around the source is
+inside Emacs once Proof General is loaded. Read the source files, and
+use functions such as @kbd{C-h v} and @kbd{C-h f}.
+
+The code is split into files. The following sections document the
+important files, kept in the @file{generic/} subdirectory.
+
+@menu
+* Spans::
+* Configuration variable mechanisms::
+* Proof General site configuration::
+* Global variables::
+* Proof script mode::
+* Proof shell mode::
+* Debugging::
+@end menu
+
+
+
+@node Spans
+@section Spans
+@cindex spans
+@cindex extents
+@cindex overlays
+
+@dfn{Spans} are an abstraction of XEmacs @dfn{extents} used to help
+bridge the gulf between GNU Emacs and XEmacs. In GNU Emacs, spans are
+implemented using @dfn{overlays}.
+
+See the files @file{span-extent.el} and @file{span-overlay.el} for the
+implementation of the common interface in each case.
+
+@node Proof General site configuration
+@section Proof General site configuration
+@cindex installation directories
+@cindex site configuration
+
+The file @file{proof-site.el} contains the initial configuration for
+Proof General for the site (or user) and the choice of provers.
+
+The first part of the configuration is to set
+@code{proof-home-directory} to the directory that @file{proof-site.el}
+is located in, or to the variable of the environment variable
+@code{PROOFGENERAL_HOME} if that is set.
+
+@c TEXI DOCSTRING MAGIC: proof-home-directory
+@defvar proof-home-directory
+Directory where Proof General is installed. Ends with slash.@*
+Default value taken from environment variable @samp{PROOFGENERAL_HOME} if set,
+otherwise based on where the file @samp{proof-site.el} was loaded from.
+You can use customize to set this variable.
+@end defvar
+
+@c They're no longer options.
+@c The default value for @code{proof-home-directory} mentioned above is the
+@c one for the author's system, it won't be the same for you!
+
+Further directory variables allow the files of Proof General to be split
+up and installed across a system if need be, rather than under the
+@code{proof-home-directory} root.
+
+@c TEXI DOCSTRING MAGIC: proof-images-directory
+@defvar proof-images-directory
+Where Proof General image files are installed. Ends with slash.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-info-directory
+@defvar proof-info-directory
+Where Proof General Info files are installed. Ends with slash.
+@end defvar
+
+
+
+@cindex mode stub
+After defining these settings, we define a @dfn{mode stub} for each
+proof assistant enabled. The mode stub will autoload Proof General for
+the right proof assistant when a file is visited with the corresponding
+extension. The proof assistants enabled are the ones listed
+in the @code{proof-assistants} setting.
+
+@c TEXI DOCSTRING MAGIC: proof-assistants
+@defopt proof-assistants
+Choice of proof assistants to use with Proof General.@*
+A list of symbols chosen from: @code{'demoisa} @code{'isar} @code{'isa} @code{'lego} @code{'coq} @code{'phox} @code{'hol98} @code{'acl2} @code{'plastic} @code{'twelf}.
+Each proof assistant defines its own instance of Proof General,
+providing session control, script management, etc. Proof General
+will be started automatically for the assistants chosen here.
+To avoid accidently invoking a proof assistant you don't have,
+only select the proof assistants you (or your site) may need.
+
+You can select which proof assistants you want by setting this
+variable before @samp{proof-site.el} is loaded, or by setting
+the environment variable @samp{PROOFGENERAL_ASSISTANTS} to the
+symbols you want, for example "lego isa". Or you can
+edit the file @samp{proof-site.el} itself.
+
+Note: to change proof assistant, you must start a new Emacs session.
+
+The default value is @code{nil}.
+@end defopt
+
+The file @file{proof-site.el} also defines a version variable.
+
+@c TEXI DOCSTRING MAGIC: proof-general-version
+@defvar proof-general-version
+Version string identifying Proof General release.
+@end defvar
+
+
+
+@node Configuration variable mechanisms
+@section Configuration variable mechanisms
+@cindex conventions
+@cindex user options
+@cindex configuration
+@cindex settings
+
+The file @file{proof-config.el} defines the configuration variables for
+Proof General, including instantiation parameters and user options. See
+previous chapters for details of its contents. Here we mention some
+conventions for declaring user options.
+
+Global user options and instantiation parameters are declared using
+@code{defcustom} as usual. User options should have `@code{*}' as the
+first character of their docstrings (standard Emacs convention) and live
+in the customize group @code{proof-user-options}. See
+@file{proof-config.el} for the groups for instantiation parameters.
+
+User options which are generic (having separate instances for each
+prover) and instantiation parameters (by definition generic) can be
+declared using the special macro @code{defpgcustom}. It is used in the
+same way as @code{defcustom}, except that the symbol declared will
+automatically be prefixed by the current proof assistant symbol.
+
+@c TEXI DOCSTRING MAGIC: defpgcustom
+@deffn Macro defpgcustom
+Define a new customization variable <PA>@var{-sym} for the current proof assistant.@*
+The function proof-assistant-<SYM> is also defined, which can be used in the
+generic portion of Proof General to set and retrieve the value for the current p.a.
+Arguments as for @samp{defcustom}, which see.
+
+Usage: (defpgcustom SYM &rest @var{args}).
+@end deffn
+
+In specific instances of Proof General, the macro @code{defpgdefault}
+can be used to give a default value for a generic setting.
+
+@c TEXI DOCSTRING MAGIC: defpgdefault
+@deffn Macro defpgdefault
+Set default for the proof assistant specific variable <PA>@var{-sym} to @var{value}.@*
+This should be used in prover-specific code to alter the default values
+for prover specific settings.
+
+Usage: (defpgdefault SYM @var{value})
+@end deffn
+
+All new instantiation variables are best declared using the
+@code{defpgcustom} mechanism (old code may be converted gradually).
+Customizations which are liable to be different for different instances
+of Proof General are also best declared in this way. An example is the
+use of X Symbol, controlled by @code{@emph{PA}-x-symbol-enable}, since
+it works poorly or not at all with some provers.
+
+To access the generic settings, the following four functions and
+macros are useful.
+
+@c TEXI DOCSTRING MAGIC: proof-ass
+@deffn Macro proof-ass
+Return the value for SYM for the current prover.
+@end deffn
+@c TEXI DOCSTRING MAGIC: proof-ass-sym
+@deffn Macro proof-ass-sym
+Return the symbol for SYM for the current prover. SYM not evaluated.
+@end deffn
+@c TEXI DOCSTRING MAGIC: proof-ass-symv
+@defun proof-ass-symv sym
+Return the symbol for @var{sym} for the current prover. @var{sym} is evaluated.
+@end defun
+
+If changing a user option setting amounts to more than just setting a
+variable (it may have some dynamic effect), we can set the
+@code{custom-set} property for the variable to the function
+@code{proof-set-value} which does an ordinary @code{set-default} to set
+the variable, and then calls a function with the same name as the
+variable, to do whatever is necessary according to the new value for the
+variable.
+
+There are several settings which can be switched on or off by the user,
+which use this @code{proof-set-value} mechanism. They are controlled by
+boolean variables with names like @code{proof-@var{foo}-enable}, and
+appear at the start of the customize group @code{proof-user-options}.
+They should be edited by the user through the customization mechanism,
+and set in the code using @code{customize-set-variable}.
+
+In @code{proof-utils.el} there is a handy macro,
+@code{proof-deftoggle}, which constructs an interactive function
+for toggling boolean customize settings. We can use this to make an
+interactive function @code{proof-@var{foo}-toggle} to put on a menu or
+bind to a key, for example.
+
+This general scheme is followed as far as possible, to give uniform
+behaviour and appearance for boolean user options, as well as
+interfacing properly with the @code{customize} mechanism.
+
+@c TEXI DOCSTRING MAGIC: proof-set-value
+@defun proof-set-value sym value
+Set a customize variable using @code{set-default} and a function.@*
+We first call @samp{@code{set-default}} to set @var{sym} to @var{value}.
+Then if there is a function @var{sym} (i.e. with the same name as the
+variable @var{sym}), it is called to take some dynamic action for the new
+setting.
+
+If there is no function @var{sym}, we try stripping
+@code{proof-assistant-symbol} and adding "proof-" instead to get
+a function name. This extends @code{proof-set-value} to work with
+generic individual settings.
+
+The dynamic action call only happens when values @strong{change}: as an
+approximation we test whether proof-config is fully-loaded yet.
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-deftoggle
+@deffn Macro proof-deftoggle
+Define a function VAR-toggle for toggling a boolean customize setting VAR.@*
+The toggle function uses @code{customize-set-variable} to change the variable.
+@var{othername} gives an alternative name than the default <VAR>-toggle.
+The name of the defined function is returned.
+@end deffn
+@node Global variables
+@section Global variables
+
+Global variables are defined in @file{proof.el}. The same file defines
+a few utility functions and some triggers to load in the other files.
+
+@c TEXI DOCSTRING MAGIC: proof-script-buffer
+@defvar proof-script-buffer
+The currently active scripting buffer or nil if none.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-buffer
+@defvar proof-shell-buffer
+Process buffer where the proof assistant is run.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-response-buffer
+@defvar proof-response-buffer
+The response buffer.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-goals-buffer
+@defvar proof-goals-buffer
+The goals buffer.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-buffer-type
+@defvar proof-buffer-type
+Symbol indicating the type of this buffer: @code{'script}, @code{'shell}, @code{'pbp}, or @code{'response}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-included-files-list
+@defvar proof-included-files-list
+List of files currently included in proof process.@*
+This list contains files in canonical truename format
+(see @samp{@code{file-truename}}).
+
+Whenever a new file is being processed, it gets added to this list
+via the @code{proof-shell-process-file} configuration settings.
+When the prover retracts a file, this list is resynchronised via the
+@code{proof-shell-retract-files-regexp} and @code{proof-shell-compute-new-files-list}
+configuration settings.
+
+Only files which have been @strong{fully} processed should be included here.
+Proof General itself will automatically add the filenames of a script
+buffer which has been completely read when scripting is deactivated.
+It will automatically remove the filename of a script buffer which
+is completely unread when scripting is deactivated.
+
+NB: Currently there is no generic provision for removing files which
+are only partly read-in due to an error, so ideally the proof assistant
+should only output a processed message when a file has been successfully
+read.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-proof-completed
+@defvar proof-shell-proof-completed
+Flag indicating that a completed proof has just been observed.@*
+If non-nil, the value counts the commands from the last command
+of the proof (starting from 1).
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-error-or-interrupt-seen
+@defvar proof-shell-error-or-interrupt-seen
+Flag indicating that an error or interrupt has just occurred.@*
+Set to @code{'error} or @code{'interrupt} if one was observed from the proof
+assistant during the last group of commands.
+@end defvar
+
+
+@node Proof script mode
+@section Proof script mode
+
+The file @file{proof-script.el} contains the main code for proof script
+mode, as well as definitions of menus, key-bindings, and user-level
+functions.
+
+Proof scripts have two important variables for the locked and queue
+regions. These variables are local to each script buffer (although we
+only really need one queue span in total rather than one per buffer).
+
+@c TEXI DOCSTRING MAGIC: proof-locked-span
+@defvar proof-locked-span
+The locked span of the buffer.@*
+Each script buffer has its own locked span, which may be detached
+from the buffer.
+Proof General allows buffers in other modes also to be locked;
+these also have a non-nil value for this variable.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-queue-span
+@defvar proof-queue-span
+The queue span of the buffer. May be detached if inactive or empty.
+@end defvar
+
+Various utility functions manipulate and examine the spans. An
+important one is @code{proof-init-segmentation}.
+
+@c TEXI DOCSTRING MAGIC: proof-init-segmentation
+@defun proof-init-segmentation
+Initialise the queue and locked spans in a proof script buffer.@*
+Allocate spans if need be. The spans are detached from the
+buffer, so the regions are made empty by this function.
+Also clear list of script portions.
+@end defun
+
+For locking files loaded by a proof assistant, we use the next function.
+
+@c TEXI DOCSTRING MAGIC: proof-complete-buffer-atomic
+@defun proof-complete-buffer-atomic buffer
+Make sure @var{buffer} is marked as completely processed, completing with a single step.
+
+If buffer already contains a locked region, only the remainder of the
+buffer is closed off atomically.
+
+This works for buffers which are not in proof scripting mode too,
+to allow other files loaded by proof assistants to be marked read-only.
+@end defun
+
+Atomic locking is instigated by the next function, which uses the
+variables @code{proof-included-files-list} documented earlier
+(@pxref{Handling multiple files} and @pxref{Global variables}).
+
+@c TEXI DOCSTRING MAGIC: proof-register-possibly-new-processed-file
+@defun proof-register-possibly-new-processed-file file &optional informprover noquestions
+Register a possibly new @var{file} as having been processed by the prover.
+
+If @var{informprover} is non-nil, the proof assistant will be told about this,
+to co-ordinate with its internal file-management. (Otherwise we assume
+that it is a message from the proof assistant which triggers this call).
+In this case, the user will be queried to save some buffers, unless
+@var{noquestions} is non-nil.
+
+No action is taken if the file is already registered.
+
+A warning message is issued if the register request came from the
+proof assistant and Emacs has a modified buffer visiting the file.
+@end defun
+
+An important pair of functions activate and deactivate scripting for the
+current buffer. A change in the state of active scripting can trigger
+various actions, such as starting up the proof assistant, or altering
+@code{proof-included-files-list}.
+
+@c TEXI DOCSTRING MAGIC: proof-activate-scripting
+@deffn Command proof-activate-scripting &optional nosaves queuemode
+Ready prover and activate scripting for the current script buffer.
+
+The current buffer is prepared for scripting. No changes are
+necessary if it is already in Scripting minor mode. Otherwise, it
+will become the new active scripting buffer, provided scripting
+can be switched off in the previous active scripting buffer
+with @samp{@code{proof-deactivate-scripting}}.
+
+Activating a new script buffer may be a good time to ask if the
+user wants to save some buffers; this is done if the user
+option @samp{@code{proof-query-file-save-when-activating-scripting}} is set
+and provided the optional argument @var{nosaves} is non-nil.
+
+The optional argument @var{queuemode} relaxes the test for a
+busy proof shell to allow one which has mode @var{queuemode}.
+In all other cases, a proof shell busy error is given.
+
+Finally, the hooks @samp{@code{proof-activate-scripting-hook}} are run.
+This can be a useful place to configure the proof assistant for
+scripting in a particular file, for example, loading the
+correct theory, or whatever. If the hooks issue commands
+to the proof assistant (via @samp{@code{proof-shell-invisible-command}})
+which result in an error, the activation is considered to
+have failed and an error is given.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-deactivate-scripting
+@deffn Command proof-deactivate-scripting &optional forcedaction
+Deactivate scripting for the active scripting buffer.
+
+Set @code{proof-script-buffer} to nil and turn off the modeline indicator.
+No action if there is no active scripting buffer.
+
+We make sure that the active scripting buffer either has no locked
+region or a full locked region (everything in it has been processed).
+If this is not already the case, we question the user whether to
+retract or assert, or automatically take the action indicated in the
+user option @samp{@code{proof-auto-action-when-deactivating-scripting}.}
+
+If the scripting buffer is (or has become) fully processed, and it is
+associated with a file, it is registered on
+@samp{@code{proof-included-files-list}}. Conversely, if it is (or has become)
+empty, we make sure that it is @strong{not} registered. This is to be
+certain that the included files list behaves as we might expect with
+respect to the active scripting buffer, in an attempt to harmonize
+mixed scripting and file reading in the prover.
+
+This function either succeeds, fails because the user refused to
+process or retract a partly finished buffer, or gives an error message
+because retraction or processing failed. If this function succeeds,
+then @code{proof-script-buffer} is nil afterwards.
+
+The optional argument @var{forcedaction} overrides the user option
+@samp{@code{proof-auto-action-when-deactivating-scripting}} and prevents
+questioning the user. It is used to make a value for
+the @code{kill-buffer-hook} for scripting buffers, so that when
+a scripting buffer is killed it is always retracted.
+@end deffn
+
+The function @code{proof-segment-up-to} is the main one used for parsing
+the proof script buffer. There are several variants of this function
+available corresponding to different parsing strategies; the appropriate
+one is aliased to @code{proof-segment-up-to} according to which
+configuration variables have been set. If only
+@code{proof-script-command-end-regexp} or @code{proof-terminal-char} are set,
+then the default is @code{proof-segment-up-to-cmdend}. If
+@code{proof-script-command-start-regexp} is set, the choice is
+@code{proof-segment-up-to-cmdstart}.
+
+@c TEXI DOCSTRING MAGIC: proof-segment-up-to-cmdend
+@defun proof-segment-up-to-cmdend pos &optional next-command-end
+Parse the script buffer from end of locked to @var{pos}.@*
+Return a list of (type, string, int) tuples.
+
+Each tuple denotes the command and the position of its terminator,
+type is one of @code{'comment}, or @code{'cmd}. @code{'unclosed-comment} may be consed onto
+the start if the segment finishes with an unclosed comment.
+
+If optional @var{next-command-end} is non-nil, we include the command
+which continues past @var{pos}, if any.
+
+This version is used when @samp{@code{proof-script-command-end-regexp}} is set.
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-segment-up-to-cmdstart
+@defun proof-segment-up-to-cmdstart pos &optional next-command-end
+Parse the script buffer from end of locked to @var{pos}.@*
+Return a list of (type, string, int) tuples.
+
+Each tuple denotes the command and the position of its terminator,
+type is one of @code{'comment}, or @code{'cmd}.
+
+If optional @var{next-command-end} is non-nil, we include the command
+which continues past @var{pos}, if any. (NOT @var{implemented} IN @var{this} @var{version}).
+
+This version is used when @samp{@code{proof-script-command-start-regexp}} is set.
+@end defun
+
+
+The function @code{proof-semis-to-vanillas} is used to convert
+a parsed region of the script into a series of commands to
+be sent to the proof assistant.
+
+@c TEXI DOCSTRING MAGIC: proof-semis-to-vanillas
+@defun proof-semis-to-vanillas semis &optional callback-fn
+Convert a sequence of terminator positions to a set of vanilla extents.@*
+Proof terminator positions @var{semis} has the form returned by
+the function proof-segment-up-to.
+Set the callback to @var{callback-fn} or @code{'proof-done-advancing} by default.
+@end defun
+
+The function @code{proof-assert-until-point} is the main one used to
+process commands in the script buffer. It's actually used to implement
+the assert-until-point, electric terminator keypress, and
+find-next-terminator behaviours. In different cases we want different
+things, but usually the information (i.e. are we inside a comment) isn't
+available until we've actually run @code{proof-segment-up-to (point)},
+hence all the different options when we've done so.
+
+@c TEXI DOCSTRING MAGIC: proof-assert-until-point
+@defun proof-assert-until-point &optional unclosed-comment-fun ignore-proof-process-p
+Process the region from the end of the locked-region until point.@*
+Default action if inside a comment is just process as far as the start of
+the comment.
+
+If you want something different, put it inside
+@var{unclosed-comment-fun}. If @var{ignore-proof-process-p} is set, no commands
+will be added to the queue and the buffer will not be activated for
+scripting.
+@end defun
+
+@code{proof-assert-next-command} is a variant of this function.
+
+@c TEXI DOCSTRING MAGIC: proof-assert-next-command
+@deffn Command proof-assert-next-command &optional unclosed-comment-fun ignore-proof-process-p dont-move-forward for-new-command
+Process until the end of the next unprocessed command after point.@*
+If inside a comment, just process until the start of the comment.
+
+If you want something different, put it inside @var{unclosed-comment-fun}.
+If @var{ignore-proof-process-p} is set, no commands will be added to the queue.
+Afterwards, move forward to near the next command afterwards, unless
+@var{dont-move-forward} is non-nil. If @var{for-new-command} is non-nil,
+a space or newline will be inserted automatically.
+@end deffn
+
+The main command for retracting parts of a script is
+@code{proof-retract-until-point}.
+
+@c TEXI DOCSTRING MAGIC: proof-retract-until-point
+@defun proof-retract-until-point &optional delete-region
+Set up the proof process for retracting until point.@*
+In particular, set a flag for the filter process to call
+@samp{@code{proof-done-retracting}} after the proof process has successfully
+reset its state.
+If @var{delete-region} is non-nil, delete the region in the proof script
+corresponding to the proof command sequence.
+If invoked outside a locked region, undo the last successfully processed
+command.
+@end defun
+
+To clean up when scripting is stopped, a script buffer is killed, or the
+proof assistant exits, we use the functions
+@code{proof-restart-buffers} and
+@code{proof-script-remove-all-spans-and-deactivate}.
+
+@c TEXI DOCSTRING MAGIC: proof-restart-buffers
+@defun proof-restart-buffers buffers
+Remove all extents in @var{buffers} and maybe reset @samp{@code{proof-script-buffer}}.@*
+No effect on a buffer which is nil or killed. If one of the buffers
+is the current scripting buffer, then @code{proof-script-buffer}
+will deactivated.
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-script-remove-all-spans-and-deactivate
+@defun proof-script-remove-all-spans-and-deactivate
+Remove all spans from scripting buffers via @code{proof-restart-buffers}.
+@end defun
+
+
+@c
+@c SECTION: Proof Shell Mode
+@c
+@node Proof shell mode
+@section Proof shell mode
+@cindex proof shell mode
+@cindex comint-mode
+
+The proof shell mode code is in the file @file{proof-shell.el}. Proof
+shell mode is defined to inherit from @code{comint-mode} using
+@code{define-derived-mode} near the end of the file. The bulk of the
+code in the file is concerned with sending code to and from the shell,
+and processing output for the associated buffers (goals and response).
+
+Good process handling is a tricky issue. Proof General attempts to
+manage the process strictly, by maintaining a queue of commands to send
+to the process. Once a command has been processed, another one is
+popped off the queue and sent.
+
+There are several important internal variables which control
+interaction with the process.
+
+@c TEXI DOCSTRING MAGIC: proof-shell-busy
+@defvar proof-shell-busy
+A lock indicating that the proof shell is processing.@*
+When this is non-nil, @code{proof-shell-ready-prover} will give
+an error.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-marker
+@defvar proof-marker
+Marker in proof shell buffer pointing to previous command input.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-action-list
+@defvar proof-action-list
+A list of@*
+@lisp
+ (@var{span} @var{command} @var{action})
+@end lisp
+triples, which is a queue of things to do.
+See the functions @samp{@code{proof-start-queue}} and @samp{proof-exec-loop}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-analyse-using-stack
+@defvar proof-analyse-using-stack
+Choice of syntax tree encoding for terms.
+
+If nil, prover is expected to make no optimisations.
+If non-nil, the pretty printer of the prover only reports local changes.
+For @var{lego} 1.3.1 use @samp{nil}, for Coq 6.2, use @samp{t}.
+@end defvar
+
+
+The function @code{proof-shell-start} is used to initialise a shell
+buffer and the associated buffers.
+
+@c TEXI DOCSTRING MAGIC: proof-shell-start
+@deffn Command proof-shell-start
+Initialise a shell-like buffer for a proof assistant.
+
+Also generates goal and response buffers.
+Does nothing if proof assistant is already running.
+@end deffn
+
+The function @code{proof-shell-kill-function} performs the converse
+function of shutting things down; it is used as a hook function for
+@code{kill-buffer-hook}. Then no harm occurs if the user kills the
+shell directly, or if it is done more cautiously via
+@code{proof-shell-exit}. The function @code{proof-shell-restart} allows
+a less drastic way of restarting scripting, other than killing and
+restarting the process.
+
+@c TEXI DOCSTRING MAGIC: proof-shell-kill-function
+@defun proof-shell-kill-function
+Function run when a proof-shell buffer is killed.@*
+Attempt to shut down the proof process nicely and
+clear up all the locked regions and state variables.
+Value for @code{kill-buffer-hook} in shell buffer.
+Also called by @code{proof-shell-bail-out} if the process is
+exited by hand (or exits by itself).
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-shell-exit
+@deffn Command proof-shell-exit
+Query the user and exit the proof process.
+
+This simply kills the @code{proof-shell-buffer} relying on the hook function
+@code{proof-shell-kill-function} to do the hard work.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-shell-bail-out
+@defun proof-shell-bail-out process event
+Value for the process sentinel for the proof assistant process.@*
+If the proof assistant dies, run @code{proof-shell-kill-function} to
+cleanup and remove the associated buffers. The shell buffer is
+left around so the user may discover what killed the process.
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-shell-restart
+@deffn Command proof-shell-restart
+Clear script buffers and send @code{proof-shell-restart-cmd}.@*
+All locked regions are cleared and the active scripting buffer
+deactivated.
+
+If the proof shell is busy, an interrupt is sent with
+@code{proof-interrupt-process} and we wait until the process is ready.
+
+The restart command should re-synchronize Proof General with the proof
+assistant, without actually exiting and restarting the proof assistant
+process.
+
+It is up to the proof assistant how much context is cleared: for
+example, theories already loaded may be "cached" in some way,
+so that loading them the next time round only performs a re-linking
+operation, not full re-processing. (One way of caching is via
+object files, used by Lego and Coq).
+@end deffn
+
+@c
+@c INPUT
+@c
+@subsection Input to the shell
+
+Input to the proof shell via the queue region is managed by the
+functions @code{proof-start-queue} and @code{proof-shell-exec-loop}.
+
+@c TEXI DOCSTRING MAGIC: proof-start-queue
+@defun proof-start-queue start end alist
+Begin processing a queue of commands in @var{alist}.@*
+If @var{start} is non-nil, @var{start} and @var{end} are buffer positions in the
+active scripting buffer for the queue region.
+
+This function calls @samp{@code{proof-append-alist}}.
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-append-alist
+
+@defun proof-append-alist alist &optional queuemode
+Chop off the vacuous prefix of the command queue @var{alist} and queue it.@*
+For each @samp{@code{proof-no-command}} item at the head of the list, invoke its
+callback and remove it from the list.
+
+Append the result onto @samp{@code{proof-action-list}}, and if the proof
+shell isn't already busy, grab the lock with @var{queuemode} and
+start processing the queue.
+
+If the proof shell is busy when this function is called,
+then @var{queuemode} must match the mode of the queue currently
+being processed.
+@end defun
+@vindex proof-action-list
+@c TEXI DOCSTRING MAGIC: proof-shell-exec-loop
+@defun proof-shell-exec-loop
+Process the @code{proof-action-list}.
+
+@samp{@code{proof-action-list}} contains a list of (@var{span} @var{command} @var{action}) triples.
+
+If this function is called with a non-empty @code{proof-action-list}, the
+head of the list is the previously executed command which succeeded.
+We execute (@var{action} @var{span}) on the first item, then (@var{action} @var{span}) on any
+following items which have @code{proof-no-command} as their cmd components.
+If a there is a next command after that, send it to the process. If
+the action list becomes empty, unlock the process and remove the queue
+region.
+
+The return value is non-nil if the action list is now empty.
+@end defun
+
+Input is actually inserted into the shell buffer and sent to the process
+by the low-level function @code{proof-shell-insert}.
+
+@c TEXI DOCSTRING MAGIC: proof-shell-insert
+@defun proof-shell-insert string action
+Insert @var{string} at the end of the proof shell, call @code{comint-send-input}.
+
+First call @code{proof-shell-insert-hook}. The argument @var{action} may be
+examined by the hook to determine how to process the @var{string} variable.
+
+Then strip @var{string} of carriage returns before inserting it and updating
+@code{proof-marker} to point to the end of the newly inserted text.
+
+Do not use this function directly, or output will be lost. It is only
+used in @code{proof-append-alist} when we start processing a queue, and in
+@code{proof-shell-exec-loop}, to process the next item.
+@end defun
+
+
+When Proof General is processing a queue of commands, the lock
+is managed using a couple of utility functions. You should
+not need to use these directly.
+
+
+@c TEXI DOCSTRING MAGIC: proof-grab-lock
+
+@defun proof-grab-lock &optional queuemode
+Grab the proof shell lock, starting the proof assistant if need be.@*
+Runs @code{proof-state-change-hook} to notify state change.
+Clears the @code{proof-shell-error-or-interrupt-seen} flag.
+If @var{queuemode} is supplied, set the lock to that value.
+@end defun
+@c TEXI DOCSTRING MAGIC: proof-release-lock
+
+
+
+
+
+
+
+@defun proof-release-lock &optional err-or-int
+Release the proof shell lock, with error or interrupt flag @var{err-or-int}.@*
+Clear @code{proof-shell-busy}, and set @code{proof-shell-error-or-interrupt-seen}
+to err-or-int.
+@end defun
+
+
+@c
+@c OUTPUT
+@c
+@subsection Output from the shell
+
+Two main functions deal with output, @code{proof-shell-process-output}
+and @code{proof-shell-process-urgent-message}. In effect we consider
+the output to be two streams intermingled: the "urgent" messages which
+have "eager" annotations, as well as the ordinary ruminations from the
+prover.
+
+The idea is to conceal as much irrelevant information from the user as
+possible; only the remaining output between prompts and after the last
+urgent message will be a candidate for the goal or response buffer. The
+internal variable @code{proof-shell-urgent-message-marker} tracks the
+last urgent message seen.
+
+When output is grabbed from the prover process, it is stored into
+@code{proof-shell-last-output}, and its type is stored in
+@code{proof-shell-last-output-kind}. Output which is deferred
+or possibly discarded until the queue is empty is copied into
+@code{proof-shell-delayed-output}, with type
+@code{proof-shell-delayed-output-kind}.
+
+
+@c TEXI DOCSTRING MAGIC: proof-shell-last-output
+@defvar proof-shell-last-output
+A record of the last string seen from the proof system.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-last-output-kind
+@defvar proof-shell-last-output-kind
+A symbol denoting the type of the last output string from the proof system.@*
+Specifically:
+@lisp
+ @code{'interrupt} An interrupt message
+ @code{'error} An error message
+ @code{'abort} A proof abort message
+ @code{'loopback} A command sent from the PA to be inserted into the script
+ @code{'response} A response message
+ @code{'goals} A goals (proof state) display
+ @code{'systemspecific} Something specific to a particular system,
+ -- see @samp{@code{proof-shell-process-output-system-specific}}
+@end lisp
+The output corresponding to this will be in @code{proof-shell-last-output}.
+
+See also @samp{@code{proof-shell-proof-completed}} for further information about
+the proof process output, when ends of proofs are spotted.
+
+This variable can be used for instance specific functions which want
+to examine @code{proof-shell-last-output}.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-delayed-output
+@defvar proof-shell-delayed-output
+A copy of @code{proof-shell-last-output} held back for processing at end of queue.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-delayed-output-kind
+@defvar proof-shell-delayed-output-kind
+A copy of proof-shell-last-output-lind held back for processing at end of queue.
+@end defvar
+@vindex proof-action-list
+
+@c TEXI DOCSTRING MAGIC: proof-shell-process-output
+@defun proof-shell-process-output cmd string
+Process shell output (resulting from @var{cmd}) by matching on @var{string}.@*
+@var{cmd} is the first part of the @code{proof-action-list} that lead to this
+output. The result of this function is a pair (@var{symbol} @var{newstring}).
+
+Here is where we recognizes interrupts, abortions of proofs, errors,
+completions of proofs, and proof step hints (proof by pointing results).
+They are checked for in this order, using
+@lisp
+ @code{proof-shell-interrupt-regexp}
+ @code{proof-shell-error-regexp}
+ @code{proof-shell-abort-goal-regexp}
+ @code{proof-shell-proof-completed-regexp}
+ @code{proof-shell-result-start}
+@end lisp
+All other output from the proof engine will be reported to the user in
+the response buffer by setting @code{proof-shell-delayed-output} to a cons
+cell of ('insert . @var{text}) where @var{text} is the text string to be inserted.
+
+Order of testing is: interrupt, abort, error, completion.
+
+To extend this function, set @code{proof-shell-process-output-system-specific}.
+
+The "aborted" case is intended for killing off an open proof during
+retraction. Typically it matches the message caused by a
+@code{proof-kill-goal-command}. It simply inserts the word "Aborted" into
+the response buffer. So it is expected to be the result of a
+retraction, rather than the indication that one should be made.
+
+This function sets @samp{@code{proof-shell-last-output}} and @samp{@code{proof-shell-last-output-kind}},
+which see.
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-shell-urgent-message-marker
+@defvar proof-shell-urgent-message-marker
+Marker in proof shell buffer pointing to end of last urgent message.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: proof-shell-process-urgent-message
+@defun proof-shell-process-urgent-message message
+Analyse urgent @var{message} for various cases.@*
+Cases are: included file, retracted file, cleared response buffer,
+variable setting or dependency list.
+If none of these apply, display @var{message}.
+
+@var{message} should be a string annotated with
+@code{proof-shell-eager-annotation-start}, @code{proof-shell-eager-annotation-end}.
+@end defun
+
+The main processing point which triggers other actions is
+@code{proof-shell-filter}.
+
+@c TEXI DOCSTRING MAGIC: proof-shell-filter
+@defun proof-shell-filter str
+Filter for the proof assistant shell-process.@*
+A function for @code{comint-output-filter-functions}.
+
+Deal with output and issue new input from the queue.
+
+Handle urgent messages first. As many as possible are processed,
+using the function @samp{@code{proof-shell-process-urgent-messages}}.
+
+Otherwise wait until an annotated prompt appears in the input.
+If @code{proof-shell-wakeup-char} is set, wait until we see that in the
+output chunk @var{str}. This optimizes the filter a little bit.
+
+If a prompt is seen, run @code{proof-shell-process-output} on the output
+between the new prompt and the last input (position of @code{proof-marker})
+or the last urgent message (position of
+@code{proof-shell-urgent-message-marker}), whichever is later.
+For example, in this case:
+@lisp
+ PROMPT> @var{input}
+ @var{output-1}
+ @var{urgent-message}
+ @var{output-2}
+ PROMPT>
+@end lisp
+@code{proof-marker} is set after @var{input} by @code{proof-shell-insert} and
+@code{proof-shell-urgent-message-marker} is set after @var{urgent-message}.
+Only @var{output-2} will be processed. For this reason, error
+messages and interrupt messages should @strong{not} be considered
+urgent messages.
+
+Output is processed using @code{proof-shell-filter-process-output}.
+
+The first time that a prompt is seen, @code{proof-marker} is
+initialised to the end of the prompt. This should
+correspond with initializing the process. The
+ordinary output before the first prompt is ignored (urgent messages,
+however, are always processed; hence their name).
+@end defun
+
+@c TEXI DOCSTRING MAGIC: proof-shell-filter-process-output
+@defun proof-shell-filter-process-output string
+Subroutine of @code{proof-shell-filter} to process output @var{string}.
+
+Appropriate action is taken depending on the what
+@code{proof-shell-process-output} returns: maybe handle an interrupt, an
+error, or deal with ordinary output which is a candidate for the goal
+or response buffer. Ordinary output is only displayed when the proof
+action list becomes empty, to avoid a confusing rapidly changing
+output.
+
+After processing the current output, the last step undertaken
+by the filter is to send the next command from the queue.
+@end defun
+
+
+
+
+
+
+@c
+@c SECTION: Debugging
+@c
+@node Debugging
+@section Debugging
+@cindex debugging
+
+@c FIXME: better to have general hints on Elisp earlier, plus some
+@c links to helpful docs.
+
+To debug Proof General, it may be helpful to set the
+configuration variable @code{proof-show-debug-messages}.
+
+@c TEXI DOCSTRING MAGIC: proof-show-debug-messages
+@defopt proof-show-debug-messages
+Whether to display debugging messages in the response buffer.@*
+If non-nil, debugging messages are displayed in the response giving
+information about what Proof General is doing.
+To avoid erasing the messages shortly after they're printed,
+you should set @samp{@code{proof-tidy-response}} to nil.
+
+The default value is @code{nil}.
+@end defopt
+
+For more information about debugging Emacs lisp, consult the Emacs Lisp
+Reference Manual. I recommend using the source-level debugger
+@code{edebug}.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@c
+@c
+@c APPENDIX: Plans and ideas
+@c
+@c
+@node Plans and ideas
+@appendix Plans and ideas
+
+This appendix contains some tentative plans and ideas for improving
+Proof General.
+
+This appendix is no longer extended: instead we keep a list of Proof
+General projects on the web, and forthcoming plans and ideas in the
+@file{TODO} and @file{todo} files included in the ordinary and
+developers PG distributions, respectively. Once the items mentioned
+below are implemented, they will be removed from here.
+
+Please send us contributions to our wish lists, or better still, an
+offer to implement something from them!
+
+@menu
+* Proof by pointing and similar features::
+* Granularity of atomic command sequences::
+* Browser mode for script files and theories::
+@end menu
+
+@node Proof by pointing and similar features
+@section Proof by pointing and similar features
+@cindex proof by pointing
+
+This is a note by David Aspinall about proof by pointing and similar
+features.
+
+Proof General already supports proof by pointing, and experimental
+support is provided in LEGO. We would like to extend this support to
+other proof assistants. Unfortunately, proof by pointing requires
+rather heavy support from the proof assistant. There are two aspects to
+the support:
+@itemize @bullet
+@item term structure mark-up
+@item proof by pointing command generation
+@end itemize
+Term structure mark-up is useful in itself: it allows the user to
+explore the structure of a term using the mouse (the smallest
+subexpression that the mouse is over is highlighted), and easily copy
+subterms from the output to a proof script.
+
+Command generation for proof by pointing is usually specific to a
+particular logic in use, if we hope to generate a good proof command
+unambiguously for any particular click. However, Proof General could
+easily be generalised to offer the user a context-sensitive choice of
+next commands to apply, which may be more useful in practice, and a
+worthy addition to Proof General.
+
+Implementors of new proof assistants should be encouraged to consider
+supporting term-structure mark up from the start. Command generation
+should be something that the logic-implementor can specify in some way.
+
+Of the supported provers, we can certainly hope for proof-by-pointing
+support from Coq, since the CtCoq proof-by-pointing code has been moved
+into the Coq kernel lately. I hope the Coq community can encourage
+somebody to do this.
+
+
+@node Granularity of atomic command sequences
+@section Granularity of atomic command sequences
+@c @cindex Granularity of Atomic Sequences
+@c @cindex Retraction
+@c @cindex Goal
+@cindex ACS (Atomic Command Sequence)
+
+This is a proposal by Thomas Kleymann for generalising the way Proof
+General handles sequences of proof commands (see @i{Goal-save
+sequences} in the user manual), particularly to make retraction more flexible.
+
+The blue region of a script buffer contains the initial segment of
+the proof script which has been processed successfully. It consists of
+atomic sequences of commands (ACS). Retraction is supported to the
+beginning of every ACS. By default, every command is an ACS. But the
+granularity of atomicity should be able to be adjusted.
+
+This is essential when arbitrary retraction is not supported. Usually,
+after a theorem has been proved, one may only retract to the start of
+the goal. One needs to mark the proof of the theorem as an ACS. At
+present, support for goal-save sequences (see @i{Goal-save sequences} in
+the user manual), has been hard wired. No other ACS are currently
+supported. We propose the following to overcome this deficiency:
+
+@vtable @code
+@item proof-atomic-sequents-list
+is a list of instructions for setting up ACSs. Each instruction is a
+list of the form @code{(@var{end} @var{start} &optional
+@var{forget-command})}. @var{end} is a regular expression to recognise
+the last command in an ACS. @var{start} is a function. Its input is the
+last command of an ACS. Its output is a regular expression to recognise
+the first command of the ACS. It is evaluated once and, starting with the
+command matched by @var{end}, the output is
+successively matched against previously processed commands until a match
+occurs (or the beginning of the current buffer is reached). The region
+determined by (@var{start},@var{end}) is locked as an ACS. Optionally,
+the ACS is annotated with the actual command to retract the ACS. This is
+computed by applying @var{forget-command} to the first and last command
+of the ACS.
+
+For convenience one might also want to allow @var{start} to be the
+symbol @samp{t} as a convenient short-hand for @code{'(lambda (str)
+".")} which always matches.
+@end vtable
+
+@node Browser mode for script files and theories
+@section Browser mode for script files and theories
+
+This is a proposal by David Aspinall for a browser window.
+
+A browser window should provide support for browsing script files and
+theories. We should be able to inspect data in varying levels of
+detail, perhaps using outlining mechanisms. For theories, it would be
+nice to query the running proof assistant. This may require support
+from the assistant in the form of output which has been specially
+marked-up with an SGML like syntax, for example.
+
+A browser would be useful to:
+@itemize @bullet
+@item Provide impoverished proof assistants with a browser
+@item Extend the uniform interface of Proof General to theory browsing
+@item Interact closely with proof script writing
+@end itemize
+The last point is the most important. We should be able to integrate a
+search mechanism for proofs of similar theorems, theorems containing
+particular constants, etc.
+
+
+
+
+@c
+@c
+@c APPENDIX: Demonstration instantiation for Isabelle
+@c
+@c
+@node Demonstration Instantiations
+@appendix Demonstration Instantiations
+
+This appendix contains the code for the two demonstration
+instantiations of Proof General, for Isabelle.
+
+These instantiations make an almost-bare minimum of settings to get
+things working. To add embellishments, you should refer to
+the instantiations for other systems distributed with
+Proof General.
+
+@menu
+* demoisa-easy.el::
+* demoisa.el::
+@end menu
+
+@node demoisa-easy.el
+@section demoisa-easy.el
+
+@lisp
+@c FIXME: MAGIC NEEDED TO INCLUDE FILE VERBATIM
+@c @includeverbatim ../demoisa/demoisa-easy.el
+;; demoisa-easy.el Example Proof General instance for Isabelle
+;;
+;; Copyright (C) 1999 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; This is an alternative version of demoisa.el which uses the
+;; proof-easy-config macro to do the work of declaring derived modes,
+;; etc.
+;;
+;; See demoisa.el and the Proof General manual for more documentation.
+;;
+;; To test this file you must rename it demoisa.el.
+;;
+
+(require 'proof-easy-config) ; easy configure mechanism
+
+(proof-easy-config
+ 'demoisa "Isabelle Demo"
+ proof-prog-name "isabelle"
+ proof-terminal-char ?\;
+ proof-comment-start "(*"
+ proof-comment-end "*)"
+ proof-goal-command-regexp "^Goal"
+ proof-save-command-regexp "^qed"
+ proof-goal-with-hole-regexp "qed_goal \"\\(\\(.*\\)\\)\""
+ proof-save-with-hole-regexp "qed \"\\(\\(.*\\)\\)\""
+ proof-non-undoables-regexp "undo\\|back"
+ proof-goal-command "Goal \"%s\";"
+ proof-save-command "qed \"%s\";"
+ proof-kill-goal-command "Goal \"PROP no_goal_set\";"
+ proof-showproof-command "pr()"
+ proof-undo-n-times-cmd "pg_repeat undo %s;"
+ proof-auto-multiple-files t
+ proof-shell-cd-cmd "cd \"%s\""
+ proof-shell-prompt-pattern "[ML-=#>]+>? "
+ proof-shell-interrupt-regexp "Interrupt"
+ proof-shell-start-goals-regexp "Level [0-9]"
+ proof-shell-end-goals-regexp "val it"
+ proof-shell-quit-cmd "quit();"
+ proof-assistant-home-page
+ "http://www.cl.cam.ac.uk/Research/HVG/Isabelle/"
+ proof-shell-annotated-prompt-regexp
+ "^\\(val it = () : unit\n\\)?ML>? "
+ proof-shell-error-regexp
+ "\\*\\*\\*\\|^.*Error:\\|^uncaught exception \\|^Exception- "
+ proof-shell-init-cmd
+ "fun pg_repeat f 0 = () | pg_repeat f n = (f(); pg_repeat f (n-1));"
+ proof-shell-proof-completed-regexp "^No subgoals!"
+ proof-shell-eager-annotation-start
+ "^\\[opening \\|^###\\|^Reading")
+
+(provide 'demoisa)
+@end lisp
+
+@node demoisa.el
+@section demoisa.el
+
+@lisp
+@c FIXME: MAGIC NEEDED TO INCLUDE FILE VERBATIM
+@c @includeverbatim ../demoisa/demoisa-easy.el
+;; demoisa.el Example Proof General instance for Isabelle
+;;
+;; Copyright (C) 1999 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; =================================================================
+;;
+;; See README in this directory for an introduction.
+;;
+;; Basic configuration is controlled by one line in `proof-site.el'.
+;; It has this line in proof-assistant-table:
+;;
+;; (demoisa "Isabelle Demo" "\\.ML$")
+;;
+;; From this it loads this file "demoisa/demoisa.el" whenever
+;; a .ML file is visited, and sets the mode to `demoisa-mode'
+;; (defined below).
+;;
+;; I've called this instance "Isabelle Demo Proof General" just to
+;; avoid confusion with the real "Isabelle Proof General" in case the
+;; demo gets loaded by accident.
+;;
+;; To make the line above take precedence over the real Isabelle mode
+;; later in the table, set PROOFGENERAL_ASSISTANTS=demoisa in the
+;; shell before starting Emacs (or customize proof-assistants).
+;;
+
+
+(require 'proof) ; load generic parts
+
+
+;; ======== User settings for Isabelle ========
+;;
+;; Defining variables using customize is pretty easy.
+;; You should do it at least for your prover-specific user options.
+;;
+;; proof-site provides us with two customization groups
+;; automatically: (based on the name of the assistant)
+;;
+;; 'isabelledemo - User options for Isabelle Demo Proof General
+;; 'isabelledemo-config - Configuration of Isabelle Proof General
+;; (constants, but may be nice to tweak)
+;;
+;; The first group appears in the menu
+;; ProofGeneral -> Customize -> Isabelledemo
+;; The second group appears in the menu:
+;; ProofGeneral -> Internals -> Isabelledemo config
+;;
+
+(defcustom isabelledemo-prog-name "isabelle"
+ "*Name of program to run Isabelle."
+ :type 'file
+ :group 'isabelledemo)
+
+(defcustom isabelledemo-web-page
+ "http://www.cl.cam.ac.uk/Research/HVG/isabelle.html"
+ "URL of web page for Isabelle."
+ :type 'string
+ :group 'isabelledemo-config)
+
+
+;;
+;; ======== Configuration of generic modes ========
+;;
+
+(defun demoisa-config ()
+ "Configure Proof General scripting for Isabelle."
+ (setq
+ proof-terminal-char ?\; ; ends every command
+ proof-comment-start "(*"
+ proof-comment-end "*)"
+ proof-goal-command-regexp "^Goal"
+ proof-save-command-regexp "^qed"
+ proof-goal-with-hole-regexp "qed_goal \"\\(\\(.*\\)\\)\""
+ proof-save-with-hole-regexp "qed \"\\(\\(.*\\)\\)\""
+ proof-non-undoables-regexp "undo\\|back"
+ proof-undo-n-times-cmd "pg_repeat undo %s;"
+ proof-showproof-command "pr()"
+ proof-goal-command "Goal \"%s\";"
+ proof-save-command "qed \"%s\";"
+ proof-kill-goal-command "Goal \"PROP no_goal_set\";"
+ proof-assistant-home-page isabelledemo-web-page
+ proof-auto-multiple-files t))
+
+
+(defun demoisa-shell-config ()
+ "Configure Proof General shell for Isabelle."
+ (setq
+ proof-shell-annotated-prompt-regexp "^\\(val it = () : unit\n\\)?ML>? "
+ proof-shell-cd-cmd "cd \"%s\""
+ proof-shell-prompt-pattern "[ML-=#>]+>? "
+ proof-shell-interrupt-regexp "Interrupt"
+ proof-shell-error-regexp "\\*\\*\\*\\|^.*Error:\\|^uncaught exception \\|^Exception- "
+ proof-shell-start-goals-regexp "Level [0-9]"
+ proof-shell-end-goals-regexp "val it"
+ proof-shell-proof-completed-regexp "^No subgoals!"
+ proof-shell-eager-annotation-start "^\\[opening \\|^###\\|^Reading"
+ proof-shell-init-cmd ; define a utility function, in a lib somewhere?
+ "fun pg_repeat f 0 = ()
+ | pg_repeat f n = (f(); pg_repeat f (n-1));"
+ proof-shell-quit-cmd "quit();"))
+
+
+
+;;
+;; ======== Defining the derived modes ========
+;;
+
+;; The name of the script mode is always <proofsym>-script,
+;; but the others can be whatever you like.
+;;
+;; The derived modes set the variables, then call the
+;; <mode>-config-done function to complete configuration.
+
+(define-derived-mode demoisa-mode proof-mode
+ "Isabelle Demo script" nil
+ (demoisa-config)
+ (proof-config-done))
+
+(define-derived-mode demoisa-shell-mode proof-shell-mode
+ "Isabelle Demo shell" nil
+ (demoisa-shell-config)
+ (proof-shell-config-done))
+
+(define-derived-mode demoisa-response-mode proof-response-mode
+ "Isabelle Demo response" nil
+ (proof-response-config-done))
+
+(define-derived-mode demoisa-goals-mode proof-goals-mode
+ "Isabelle Demo goals" nil
+ (proof-goals-config-done))
+
+;; The response buffer and goals buffer modes defined above are
+;; trivial. In fact, we don't need to define them at all -- they
+;; would simply default to "proof-response-mode" and "pbp-mode".
+
+;; A more sophisticated instantiation might set font-lock-keywords to
+;; add highlighting, or some of the proof by pointing markup
+;; configuration for the goals buffer.
+
+;; The final piece of magic here is a hook which configures settings
+;; to get the proof shell running. Proof General needs to know the
+;; name of the program to run, and the modes for the shell, response,
+;; and goals buffers.
+
+(add-hook 'proof-pre-shell-start-hook 'demoisa-pre-shell-start)
+
+(defun demoisa-pre-shell-start ()
+ (setq proof-prog-name isabelledemo-prog-name)
+ (setq proof-mode-for-shell 'demoisa-shell-mode)
+ (setq proof-mode-for-response 'demoisa-response-mode)
+ (setq proof-mode-for-goals 'demoisa-goals-mode))
+
+(provide 'demoisa)
+@end lisp
+
+
+
+
+@node Function Index
+@unnumbered Function and Command Index
+@printindex fn
+
+@node Variable Index
+@unnumbered Variable and User Option Index
+@printindex vr
+
+@c Nothing in this one!
+@c @node Keystroke Index
+@c @unnumbered Keystroke Index
+@c @printindex ky
+
+@node Concept Index
+@unnumbered Concept Index
+@printindex cp
+
+@page
+@contents
+@bye
+
+
diff --git a/doc/ProofGeneral.jpg b/doc/ProofGeneral.jpg
new file mode 100644
index 00000000..6d5bfbfe
--- /dev/null
+++ b/doc/ProofGeneral.jpg
Binary files differ
diff --git a/doc/ProofGeneral.texi b/doc/ProofGeneral.texi
new file mode 100644
index 00000000..dc455ce0
--- /dev/null
+++ b/doc/ProofGeneral.texi
@@ -0,0 +1,4126 @@
+\def\fontdefs{\psfamily{bsf}{r}{c}{b}{b}{ri}{ri}{ro}{bo}\def\mainmagstep{1200}}
+\input texinfo
+@c
+@c $Id$
+@c
+@c NB: the first line of this file uses a non-standard TeXinfo
+@c hack to print in Serifa fonts. It has no effect if you don't have
+@c my hacked version of TeXinfo - da.
+@c
+@c
+@setfilename ProofGeneral.info
+@settitle Proof General
+@setchapternewpage odd
+@paragraphindent 0
+@c A flag for whether to include the front image in the
+@c DVI file. You can download the front image from
+@c http://www.proofgeneral.org/ProofGeneralPortrait.eps.gz
+@c then put it into this directory and 'make dvi' (pdf,ps)
+@c will set the flag below automatically.
+@clear haveeps
+@iftex
+@afourpaper
+@end iftex
+
+@c
+@c Some URLs.
+@c FIXME: unfortunately, broken in buggy pdftexinfo.
+@c so removed for now.
+@set URLxsymbol http://www.fmi.uni-passau.de/~wedler/x-symbol/
+@set URLisamode http://www.proofgeneral.org/~isamode
+@set URLpghome http://www.proofgeneral.org
+@set URLpglatestrpm http://www.proofgeneral.org/ProofGeneral-latest.noarch.rpm
+@set URLpglatesttar http://www.proofgeneral.org/ProofGeneral-latest.tar.gz
+@set URLpglatestdev http://www.proofgeneral.org/ProofGeneral-devel-latest.tar.gz
+@c
+@c
+
+@c
+@c IMPORTANT NOTES ABOUT THIS TEXINFO FILE:
+@c I've tried keep full node lines *out* of this file because Emacs makes a
+@c mess of updating them and they are a nuisance to do by hand.
+@c Instead, rely on makeinfo and friends to do the equivalent job.
+@c For this to work, we must follow each node
+@c immediately with a section command, i.e.:
+@c
+@c @node node-name
+@c <section-command>
+@c
+@c And each section with lower levels must have a menu command in
+@c it. Menu updating with Emacs is a bit better than node updating,
+@c but tends to delete the first section of the file in XEmacs!
+@c (it's better in GNU Emacs at the time of writing).
+@c
+@c LINE BREAKS: For html generated from this to look good, it is
+@c important that there are lots of line breaks/blank lines, esp
+@c after @enddefn's and similar. Otherwise text flows on the same
+@c paragraph but gets coloured wrongly with Netscape's handling of
+@c style sheets.
+@c
+@c reminder about references:
+@c @xref{node} blah start of sentence: See [ref]
+@c blah (@pxref{node}) blah bla (see [ref]), best at end of sentence
+@c @ref{node} without "see". Careful for info.
+@c
+
+@set version 3.4pre
+@set xemacsversion 21.4
+@set fsfversion 20.7
+@set last-update December 2001
+@set rcsid $Id$
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* Proof General: (ProofGeneral). Organize your proofs with Emacs!
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@c
+@c MACROS
+@c
+@c define one here for a command with a key-binding?
+@c
+@c I like the idea, but it's maybe against the TeXinfo
+@c style to fix together a command and its key-binding.
+@c
+@c merge functions and variables into concept index.
+@c @syncodeindex fn cp
+@c @syncodeindex vr cp
+
+@c merge functions into variables index
+@c @syncodeindex fn vr
+
+@finalout
+@titlepage
+@title Proof General
+@subtitle Organize your proofs!
+@sp 1
+@subtitle User Manual for Proof General @value{version}
+@subtitle @value{last-update}
+@subtitle @b{www.proofgeneral.org}
+
+@c nested ifs fail here completely, WHY?
+@iftex
+@ifset haveeps
+@c @vskip 1cm
+@c The .eps file takes 8.4M! A pity texi can't seem
+@c to deal with gzipped files? (goes down to 1.7M).
+@c But this still seems too much to put into the
+@c PG distribution just for an image on the manual page,
+@c so we take it out for now.
+@c Ideally would like some way of generating eps from
+@c the .jpg file.
+@c image{ProofGeneralPortrait}
+@end ifset
+@end iftex
+@author David Aspinall with H. Goguen, T. Kleymann and D. Sequeira
+
+@page
+@vskip 0pt plus 1filll
+This manual and the program Proof General are
+Copyright @copyright{} 1998-2001 Proof General team, LFCS Edinburgh.
+
+@c
+@c COPYING NOTICE
+@c
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission notice
+identical to this one except for the removal of this paragraph (this
+paragraph not being relevant to the printed manual).
+@end ignore
+
+@sp 2
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+@sp 2
+
+This manual documents Proof General, Version @value{version}, for use
+with XEmacs @value{xemacsversion} and GNU Emacs @value{fsfversion}
+or later versions.
+
+@sp 1
+
+Visit Proof General on the web at @code{http://www.proofgeneral.org}
+
+@sp 1
+
+@code{@value{rcsid}}
+@end titlepage
+
+@page
+
+
+@ifinfo
+@node Top
+@top Proof General
+
+This file documents version @value{version} of @b{Proof General}, a
+generic Emacs interface for proof assistants.
+
+Proof General @value{version} has been tested with XEmacs
+@value{xemacsversion} and GNU Emacs @value{fsfversion}. It is
+supplied ready customized for the proof assistants PhoX, Coq, Lego,
+Isabelle, and HOL.
+
+@menu
+* Preface::
+* Introducing Proof General::
+* Basic Script Management::
+* Proof by Pointing::
+* Advanced Script Management::
+* Support for other Packages::
+* Hints and Tips::
+* Customizing Proof General::
+* LEGO Proof General::
+* Coq Proof General::
+* Isabelle Proof General::
+* HOL Proof General::
+@c * PhoX Proof General::
+* Obtaining and Installing::
+* Known bugs and workarounds::
+* References::
+* Function Index::
+* Variable Index::
+* Keystroke Index::
+* Concept Index::
+@end menu
+@end ifinfo
+
+@node Preface
+@unnumbered Preface
+
+Welcome to Proof General!
+
+This preface has some news about the current release series, as well as
+some history about previous releases, and acknowledgements to those who
+have helped along the way.
+
+Proof General has a home page at
+@uref{http://www.proofgeneral.org}.
+Visit this page for the latest version of this manual,
+other documentation, system downloads, etc.
+
+
+@menu
+* Latest news for 3.3::
+* Future::
+* Old News for 3.2::
+* Old News for 3.1::
+* Old News for 3.0::
+* History before 3.0::
+* Credits::
+@end menu
+
+@node Latest news for 3.3
+@unnumberedsec Latest news for 3.3
+@cindex news
+
+Proof General 3.3 includes a few feature additions, but mainly the focus
+has been on compatibility improvements for new versions of provers (in
+particular, Coq 7), and new versions of emacs (in particular, XEmacs
+21.4).
+
+One new feature is control over visibility of completed proofs,
+@xref{Visibility of completed proofs}. Another new feature is the
+tracking of theorem dependencies inside Isabelle. A context-sensitive
+menu (right-button on proof scripts) provides facility for browsing the
+ancestors and child theorems of a theorem, and highlighting them. The
+idea of this feature is that it can help you untangle and rearrange big
+proof scripts, by seeing which parts are interdependent. The implementation
+is provisional and not documented yet in the body of this manual. It only
+works for the "classic" version of Isabelle99-2.
+
+See the @file{CHANGES} file in the distribution for more complete
+details of changes since 3.2.
+
+
+@node Future
+@unnumberedsec Future
+@cindex Proof General Kit
+@cindex Future
+
+The aim of the Proof General project is to provide a powerful and
+configurable interfaces which help user-interaction with interactive
+proof assistants.
+
+The strategy Proof General uses is to targets power users rather than
+novices; other interfaces have often neglected this class of users. But
+we do include general user interface niceties, such as toolbar and
+menus, which make use easier for all.
+
+Proof General has been Emacs based so far, but plans are afoot to
+liberate it from the points and parentheses of Emacs Lisp. The
+successor project Proof General Kit proposes that proof assistants use a
+@i{standard} XML-based protocol for interactive proof, dubbed @b{PGIP}.
+
+PGIP will enable middleware for interactive proof tools and interface
+components. Rather than configuring Proof General for your proof
+assistant, you will need to configure your proof assistant to understand
+PGIP. There is a similarity however; the design of PGIP was based
+heavily on the Emacs Proof General framework.
+
+For more details, see
+@uref{http://www.proofgeneral.org/kit, the Proof General Kit webpage}.
+
+
+
+@node Old News for 3.2
+@unnumberedsec Old News for 3.2
+@cindex news
+
+Proof General 3.2 introduced several new features and some bug fixes.
+One noticeable new feature is the addition of a prover-specific menu for
+each of the supported provers. This menu has a ``favourites'' feature
+that you can use to easily define new functions. Please contribute
+other useful functions (or suggestions) for things you
+would like to appear on these menus.
+
+Because of the new menus and to make room for more commands, we have
+made a new key map for prover specific functions. These now all begin
+with @kbd{C-c C-a}. This has changed a few key bindings slightly.
+
+Another new feature is the addition of prover-specific completion
+tables, to encourage the use of Emacs's completion facility, using
+@kbd{C-RET}. @xref{Support for completion}, for full details.
+
+A less obvious new feature is support for turning the proof assistant
+output on and off internally, to improve efficiency when processing
+large scripts. This means that more of your CPU cycles can be spent on
+proving theorems.
+
+Adapting for new proof assistants continues to be made more flexible,
+and easier in several places. This has been motivated by adding
+experimental support for some new systems. One new system which had
+good support added in a very short space of time is @b{PhoX} (see
+@uref{http://www.lama.univ-savoie.fr/~RAFFALLI/af2.html, the PhoX home
+page} for more information). PhoX joins the rank of officially
+supported Proof General instances, thanks to its developer Christophe
+Raffalli.
+
+Breaking the manual into two pieces was overdue: now all details on
+adapting Proof General, and notes on its internals, are in the
+@i{Adapting Proof General} manual. You should find a copy of that
+second manual close to wherever you found this one; consult the
+Proof General home page if in doubt.
+
+The internal code of Proof General has been significantly overhauled for
+this version, which should make it more robust and readable. The
+generic code has an improved file structure, and there is support for
+automatic generation of autoload functions. There is also a new
+mechanism for defining prover-specific customization and instantiation
+settings which fits better with the customize library. These settings
+are named in the form @code{@i{PA}-setting-name} in the documentation;
+you replace @i{PA} by the symbol for the proof assistant you are
+interested in. @xref{Customizing Proof General}, for details.
+
+Finally, important bug fixes include the robustification against
+@code{write-file} (@kbd{C-x C-w}), @code{revert-buffer}, and friends.
+These are rather devious functions to use during script management, but
+Proof General now tries to do the right thing if you're deviant enough
+to try them out!
+
+Work on this release was undertaken by David Aspinall between
+May-September 2000, and includes contributions from Markus Wenzel,
+Pierre Courtieu, and Christophe Raffalli. Markus added some Isar
+documentation to this manual.
+
+
+@node Old News for 3.1
+@unnumberedsec Old News for 3.1
+@cindex news
+
+Proof General 3.1 (released March 2000) is a bug-fix improvement over
+version 3.0. There are some minor cosmetic improvements, but large
+changes have been held back to ensure stability. This release solves a
+few minor problems which came to light since the final testing stages
+for 3.0. It also solves some compatibility problems, so now it works
+with various versions of Emacs which we hadn't tested with before
+(non-mule GNU Emacs, certain Japanese Emacs versions).
+
+We're also pleased to announce HOL Proof General, a new instance of
+Proof General for HOL98. This is supplied as a "technology
+demonstration" for HOL users in the hope that somebody from the HOL
+community will volunteer to adopt it and become a maintainer and
+developer. (Otherwise, work on HOL Proof General will not continue).
+
+Apart from that there are a few other small improvements. Check the
+CHANGES file in the distribution for full details.
+
+The HOL98 support and much of the work on Proof General 3.1 was
+undertaken by David Aspinall while he was visiting ETL, Osaka, Japan,
+supported by the British Council and ETL.
+
+
+@node Old News for 3.0
+@unnumberedsec Old News for 3.0
+
+Proof General 3.0 (released November 1999) has many improvements over
+2.x releases.
+
+First, there are usability improvements. The toolbar was somewhat
+impoverished before. It now has twice as many buttons, and includes all
+of the useful functions used during proof which were previously hidden
+on the menu, or even only available as key-presses. Key-bindings have
+been re-organized, users of previous versions may notice. The menu has
+been redesigned and coordinated with the toolbar, and now gives easy
+access to more of the features of Proof General. Previously several
+features were only likely to be discovered by those keen enough to read
+this manual!
+
+Second, there are improvements, extensions, and bug fixes in the generic
+basis. Proofs which are unfinished and not explicitly closed by a
+``save'' type command are supported by the core, if they are allowed by
+the prover. The design of switching the active scripting buffer has
+been streamlined. The management of the queue of commands waiting to be
+sent to the shell has been improved, so there are fewer unnecessary
+"Proof Process Busy!" messages. The support for scripting with multiple
+files was improved so that it behaves reliably with Isabelle99; file
+reading messages can be communicated in both directions now. The proof
+shell filter has been optimized to give hungry proof assistants a better
+share of CPU cycles. Proof-by-pointing has been resurrected; even
+though LEGO's implementation is incomplete, it seems worth maintaining
+the code in Proof General so that the implementors of other proof
+assistants are encouraged to provide support. For one example, we can
+certainly hope for support in Coq, since the CtCoq proof-by-pointing
+code has been moved into the Coq kernel lately. We need a volunteer
+from the Coq community to help to do this.
+
+An important new feature in Proof General 3.0 is support for
+@uref{http://www.fmi.uni-passau.de/~wedler/x-symbol/,X-Symbol},
+which means that real logical symbols, Greek letters,
+etc can be displayed during proof development, instead of their ASCII
+approximations. This makes Proof General a more serious competitor to
+native graphical user interfaces.
+
+Finally, Proof General has become much easier to adapt to new provers
+--- it fails gracefully (or not at all!) when particular configuration
+variables are unset, and provides more default settings which work
+out-of-the-box. An example configuration for Isabelle is provided,
+which uses just 25 or so simple settings.
+
+This manual has been updated and extended for Proof General 3.0.
+Amongst other improvements, it has a better description of how to add
+support for a new prover.
+
+See the @code{CHANGES} file in the distribution for more information
+about the latest improvements in Proof General. Developers should check
+the @code{ChangeLog} in the developer's release for detailed comments on
+internal changes.
+
+Most of the work for Proof General 3.0 has been done by David Aspinall.
+Markus Wenzel helped with Isabelle support, and provided invaluable
+feedback and testing, especially for the improvements to multiple file
+handling. Pierre Courtieu took responsibility from Patrick Loiseleur
+for Coq support, although the improvements in both the Coq and LEGO code
+for this release were made by David Aspinall. Markus Wenzel also
+provided support for his Isar language, a new proof language for
+Isabelle. David von Oheimb helped to develop and debug the generic
+version of his X-Symbol patch which he originally provided for Isabelle.
+
+A new instantiation of Proof General is being worked on for
+@emph{Plastic}, a proof assistant being developed at the University of
+Durham.
+
+
+
+@node History before 3.0
+@unnumberedsec History before 3.0
+@cindex @code{lego-mode}
+@cindex history
+
+It all started some time in 1994. There was no Emacs interface for LEGO.
+Back then, Emacs militants worked directly with the Emacs shell to
+interact with the LEGO system.
+
+David Aspinall convinced Thomas Kleymann that programming in
+Emacs Lisp wasn't so difficult after all. In fact, Aspinall had already
+implemented an Emacs interface for Isabelle with bells and whistles,
+called @uref{http://www.proofgeneral.org/~isamode,Isamode}. Soon
+after, the package @code{lego-mode} was born. Users were able to develop
+proof scripts in one buffer. Support was provided to automatically send
+parts of the script to the proof process. The last official version with
+the name @code{lego-mode} (1.9) was released in May 1995.
+
+
+@cindex proof by pointing
+@cindex CtCoq
+@cindex Centaur
+The interface project really took off the ground in November 1996. Yves
+Bertot had been working on a sophisticated user interface for the Coq
+system (CtCoq) based on the generic environment Centaur. He visited the
+Edinburgh LEGO group for a week to transfer proof-by-pointing
+technology. Even though proof-by-pointing is an inherently
+structure-conscious algorithm, within a week, Yves Bertot, Dilip Sequeira
+and Thomas Kleymann managed to implement a first prototype of
+proof-by-pointing in the Emacs interface for LEGO [BKS97].
+
+@cindex structure editor
+@cindex script management
+
+Perhaps we could reuse even more of the CtCoq system. It being a
+structure editor did no longer seem to be such an obstacle. Moreover,
+to conveniently use proof-by-pointing in actual developments, one would
+need better support for script management.
+
+@cindex generic
+In 1997, Dilip Sequeira implemented script management in our Emacs
+interface for LEGO following the recipe in
+[BT98]. Inspired by the project CROAP, the
+implementation made some effort to be generic. A working prototype was
+demonstrated at UITP'97.
+
+In October 1997, Healfdene Goguen ported @code{lego-mode} to Coq. Part
+of the generic code in the @code{lego} package was outsourced (and made
+more generic) in a new package called @code{proof}. Dilip Sequeira
+provided some LEGO-specific support for handling multiple files and
+wrote a few manual pages. The system was reasonably robust and we
+shipped out the package to friends.
+
+In June 1998, David Aspinall reentered the picture by providing an
+instantiation for Isabelle. Actually, our previous version wasn't quite
+as generic as we had hoped. Whereas LEGO and Coq are similar systems in
+many ways, Isabelle was really a different beast. Fierce re-engineering
+and various usability improvements were provided by Aspinall and
+Kleymann to make it easier to instantiate to new proof systems. The
+major technical improvement was a truly generic extension of script
+management to work across multiple files.
+
+It was time to come up with a better name than just @code{proof}
+mode. David Aspinall suggested @emph{Proof General} and set about
+reorganizing the file structure to disentangle the Proof General project
+from LEGO at last. He cooked up some images and bolted on a toolbar, so
+a naive user can replay proofs without knowing a proof assistant
+language or even Emacs hot-keys. He also designed some web pages, and
+wrote most of this manual.
+
+Proof General 2.0 was the first official release of the improved
+program, made in December 1998.
+
+Version 2.1 was released in August 1999. It was used at the Types
+Summer School held in Giens, France in September 1999 (see
+@uref{http://www-sop.inria.fr/types-project/types-sum-school.html}).
+About 50 students learning Coq, Isabelle, and LEGO used Proof General
+for all three systems. This experience provided invaluable feedback and
+encouragement to make the improvements now in Proof General 3.0.
+
+@c Why not adapt Proof General to your favourite proof assitant?
+
+
+
+@node Credits
+@unnumberedsec Credits
+@cindex @code{lego-mode}
+@cindex maintenance
+
+The main developers of Proof General have been:
+
+@itemize @bullet
+@item @b{David Aspinall},
+@item @b{Healfdene Goguen},
+@item @b{Thomas Kleymann} and
+@item @b{Dilip Sequeira}.
+@end itemize
+
+LEGO Proof General (the successor of @code{lego-mode}) was crafted by
+Thomas Kleymann and Dilip Sequeira.
+@c
+It is presently maintained by David Aspinall and
+Paul Callaghan @i{<P.C.Callaghan@@durham.ac.uk>}.
+@c
+Coq Proof General was crafted by Healfdene Goguen, with
+later contributions from Patrick Loiseleur.
+It is now maintained by Pierre Courtieu @i{<courtieu@@lri.fr>}.
+@c
+Isabelle Proof General was crafted and is being maintained by David
+Aspinall @i{<da@@dcs.ed.ac.uk>}. It has benefited greatly from tweaks
+and suggestions by Markus Wenzel @i{<wenzelm@@informatik.tu-muenchen.de>},
+who crafted and maintains Isabelle/Isar Proof General. Markus also
+added Proof General support inside Isabelle. David von Oheimb supplied
+the original patches for X-Symbol support.
+
+The generic base for Proof General was developed by Kleymann, Sequeira,
+Goguen and Aspinall. It follows some of the ideas used in Project
+@uref{http://www.inria.fr/croap/,CROAP}. The project to implement a
+proof mode for LEGO was initiated in 1994 and coordinated until October
+1998 by Thomas Kleymann, becoming generic along the way. In October
+1998, the project became Proof General and has been managed by David
+Aspinall since then.
+
+This manual was written by David Aspinall and Thomas Kleymann. Some
+words found their way here from the user documentation of LEGO mode,
+prepared by Dilip Sequeira. Healfdene Goguen supplied some text for Coq
+Proof General. Since Proof General 2.0, this manual has been maintained
+and improved by David Aspinall. Pierre Courtieu wrote the section on
+file variables.
+
+The Proof General project has benefited from funding by EPSRC
+(Applications of a Type Theory Based Proof Assistant), the EC (Types for
+Proofs and Programs) and the support of the LFCS. Version 3.1 was
+prepared whilst David Aspinall was visiting ETL, Japan, supported by the
+British Council.
+
+For testing and feedback for older versions of Proof General, thanks go
+to Rod Burstall, Martin Hofmann, and James McKinna, and some of those
+who continued to help with the latest 3.x series, named next.
+
+@c FIXME HERE!
+During the development of Proof General 3.x releases,
+many people helped provide testing and other feedback,
+including the Proof General maintainers,
+Paul Callaghan, Pierre Courtieu, and Markus Wenzel, and other folk who
+tested pre-releases or sent bug reports, including
+Pascal Brisset,
+Martin Buechi,
+Matt Fairtlough,
+Kim Hyung Ho,
+Pierre Lescanne,
+John Longley,
+Tobias Nipkow,
+Leonor Prensa Nieto,
+David von Oheimb,
+Randy Pollack,
+Robert R. Schneck,
+Sebastian Skalberg,
+and
+Mike Squire. Thanks to all of you!
+
+
+
+
+@c
+@c CHAPTER: Introduction
+@c
+@node Introducing Proof General
+@chapter Introducing Proof General
+@cindex proof assistant
+@cindex Proof General
+
+@c would like the logo on the title page really but
+@c it doesn't seem to work there for html.
+@ifhtml
+<IMG SRC="ProofGeneral.jpg" ALT="[ Proof General logo ]" >
+@end ifhtml
+
+@dfn{Proof General} is a generic Emacs interface for interactive proof
+assistants,@footnote{A @dfn{proof assistant} is a computerized helper for
+developing mathematical proofs. For short, we sometimes call it a
+@dfn{prover}, although we always have in mind an interactive system
+rather than a fully automated theorem prover.} developed at the LFCS in
+the University of Edinburgh. It works best under XEmacs, but can also
+be used with GNU Emacs.
+
+You do not have to be an Emacs militant to use Proof General!
+
+The interface is designed to be very easy to use. You develop your
+proof script@footnote{A @dfn{proof script} is a sequence of commands
+ which constructs a proof, usually stored in a file.}
+ in-place rather than line-by-line and later reassembling the pieces.
+Proof General keeps track of which proof steps have been processed by
+the prover, and prevents you editing them accidently. You can undo
+steps as usual.
+
+The aim of Proof General is to provide a powerful and configurable
+interface for numerous interactive proof assistants. We target Proof
+General mainly at intermediate or expert users, so that the interface
+should be useful for large proof developments.
+
+Please help us!
+
+Send us comments, suggestsions, or (the best) patches to improve support
+for your chosen proof assistant. Contact us at
+@code{proofgen@@dcs.ed.ac.uk}.
+
+If your chosen proof assistant isn't supported, read the accompanying
+@i{Adapting Proof General} manual to find out how to configure PG for a
+new prover.
+
+@menu
+* Quick start guide::
+* Features of Proof General::
+* Supported proof assistants::
+* Prerequisites for this manual::
+* Organization of this manual::
+@end menu
+
+
+
+
+@node Quick start guide
+@section Quick start guide
+
+Proof General may have been installed for you already. If so, when you
+visit a proof script file for your proof assistant, the corresponding
+Proof General mode will be invoked automatically:
+@multitable @columnfractions .3 .3 .4
+@item @b{Prover} @tab @b{Extensions} @tab @b{Mode}
+@item LEGO @tab @file{.l} @tab @code{lego-mode}
+@item Coq @tab @file{.v} @tab @code{coq-mode}
+@item Isabelle @tab @file{.thy},@file{.ML} @tab @code{isa-mode}
+@item Isabelle/Isar @tab @file{.thy} @tab @code{isar-mode}
+@item Phox @tab @file{.phx} @tab @code{phox-mode}
+@item HOL98 @tab @file{.sml} @tab @code{hol98-mode}
+@end multitable
+(The exact list of Proof Assistants supported may vary according to the
+version of Proof General and its local configuration). You can also
+invoke the mode command directly, e.g., type @kbd{M-x lego-mode}, to
+turn a buffer into a lego script buffer.
+
+You'll find commands to process the proof script are available from the
+toolbar, menus, and keyboard. Type @kbd{C-h m} to get a list of the
+keyboard shortcuts for the current mode. The commands available should
+be easy to understand, but the rest of this manual describes them in
+some detail.
+
+The proof assistant itself is started automatically inside Emacs as an
+"inferior" process when you ask for some of the proof script to be
+processed. You can also start the proof assistant directly with the
+menu command "Start proof assistant".
+
+To follow an example use of Proof General on a LEGO proof,
+@pxref{Walkthrough example in LEGO}. If you know the syntax for proof
+scripts in another theorem prover, you can easily adapt the details
+given there.
+
+If Proof General has not already been installed, you should insert the
+line:
+@lisp
+ (load "@var{proof-general-home}/generic/proof-site.el")
+@end lisp
+into your @file{~/.emacs} file, where @var{proof-general-home} is the
+top-level directory that was created when Proof General was unpacked.
+
+@xref{Obtaining and Installing}, if you need more
+information.
+
+
+@node Features of Proof General
+@section Features of Proof General
+@cindex Features
+@cindex Why use Proof General?
+
+Why would you want to use Proof General?
+
+@c FIXME: would like to keep this synched with web page, really.
+@c but web page needs extra markup.
+
+Proof General is designed to be useful for novices and expert users
+alike. It will be useful to you if you use a proof assistant, and you'd
+like an interface with the following features: simplified interaction,
+script management, multiple file scripting, a script editing mode, proof
+by pointing, toolbar and menus, syntax highlighting, real symbols,
+functions menu, tags, and finally, adaptability.
+
+Here is an outline of some of these features. Look in the contents
+page or index of this manual to find out about the others!
+
+@itemize @bullet
+@item @i{Simplified interaction}@*
+ Proof General is designed for proof assistants which have a
+ command-line shell interpreter. When using Proof General, the proof
+ assistant's shell is hidden from the user. Communication takes
+ place via three buffers (Emacs text widgets).
+Communication takes place via three buffers. The @dfn{script
+buffer} holds input, the commands to construct a proof. The @dfn{goals
+buffer} displays the current list of subgoals to be solved. The
+@dfn{response buffer} displays other output from the proof assistant.
+By default, only two of these three buffers are displayed.
+This means that the user normally only sees the output from the most
+recent interaction, rather than a screen full of output from the proof
+assistant.
+
+Proof General does not commandeer the proof assistant shell: the user
+still has complete access to it if necessary.
+
+For more details, @pxref{Summary of Proof General buffers}
+and @pxref{Display customization}.
+
+
+@item @i{Script management}@*
+Proof General colours proof script regions blue when they have
+been processed by the prover, and colours regions red when the prover is
+currently processing them. The appearance of Emacs buffers always
+matches the proof assistant's state. Coloured parts of the buffer cannot
+be edited. Proof General has functions for @emph{asserting} or
+@emph{retracting} parts of a proof script, which alters the coloured
+regions.
+
+For more details, @pxref{Basic Script Management},
+@ref{Script processing commands},
+and @ref{Advanced Script Management}.
+@item @i{Script editing mode}@*
+Proof General provides useful facilities for editing proof scripts,
+including syntax hilighting and a menu to jump to particular goals,
+definitions, or declarations.
+Special editing functions send lines of proof script to the proof
+assistant, or undo previous proof steps.
+
+For more details, @pxref{Script editing commands},
+and @ref{Script processing commands}.
+@item @i{Toolbar and menus}@*
+A script buffer has a toolbar with navigation buttons for processing
+parts of the proof script. A menu provides further functions for
+operations in the proof assistant, as well as customization of Proof
+General.
+
+For more details, @pxref{Toolbar commands}, @ref{Proof assistant
+commands}, and @ref{Customizing Proof General}.
+
+@item @i{Proof by pointing}@*
+Proof General has support for proof-by-pointing and similar features.
+Proof by pointing allows you to click on a subterm of a goal to be
+proved, and automatically apply an appropriate proof rule or tactic.
+Proof by pointing is specific to the proof assistant (and logic) in use;
+therefore it is configured mainly on the proof assistant side. If you
+would like to see proof by pointing support for Proof General in a
+particular proof assistant, petition the developers of the proof
+assistant to provide it.
+@c Proof General expects to parse
+@c term-structure annotations on the output syntax of the prover.
+@c It uses these to construct a message to the prover indicating
+@c where the user has clicked, and the proof assistant can
+@c response with a suggested tactic.
+@end itemize
+
+
+@node Supported proof assistants
+@section Supported proof assistants
+
+Proof General comes ready-customized for these proof assistants:
+
+@c FLAG VERSIONS HERE
+@itemize @bullet
+@item
+@b{LEGO Proof General} for LEGO Version 1.3.1@*
+@xref{LEGO Proof General}, for more details.
+@item
+@b{Coq Proof General} for Coq Version 6.3@*
+@xref{Coq Proof General}, for more details.
+@item
+@b{Isabelle Proof General} for Isabelle99-1@*
+@xref{Isabelle Proof General}, for more details.
+@item
+@b{Isabelle/Isar Proof General} for Isabelle99-1@*
+@xref{Isabelle Proof General}, and documentation supplied with
+Isabelle for more details.
+@b{HOL Proof General} for HOL98@*
+@xref{HOL Proof General}, for more details.
+@end itemize
+Proof General is designed to be generic, so if you know how
+to write regular expressions, you can make:
+@itemize @bullet
+@item
+@b{Your Proof General} for your favourite proof assistant.@*
+For more details of how to make Proof General work
+with another proof assistant,
+see the accompanying manual @i{Adapting Proof General}.
+@end itemize
+The exact list of Proof Assistants supported may vary according to the
+version of Proof General you have and its local configuration; only the
+standard instances documented in this manual are listed above.
+
+Note that there is some variation between the features supported by
+different instances of Proof General. The main variation is proof by
+pointing, which is only supported in LEGO at the moment. For advanced
+features like this, some extensions to the output routines of the proof
+assistant are required, typically. If you like Proof General, please
+help us by asking the implementors of your favourite proof assistant to
+support Proof General as much as possible.
+
+@node Prerequisites for this manual
+@section Prerequisites for this manual
+@cindex Meta
+@cindex Alt
+@cindex key sequences
+
+This manual assumes that you understand a little about using Emacs, for
+example, switching between buffers using @kbd{C-x b} and understanding
+that a key sequence like @kbd{C-x b} means "control with x, followed by b".
+A key sequence like @kbd{M-z} means "meta with z". (@key{Meta} may be
+labelled @key{Alt} on your keyboard).
+
+The manual also assumes you have a basic understanding of your proof
+assistant and the language and files it uses for proof scripts. But
+even without this, Proof General is not useless: you can use the
+interface to @emph{replay} proof scripts for any proof assistant without
+knowing how to start it up or issue commands, etc. This is the beauty
+of a common interface mechanism.
+
+To get more from Proof General and adapt it to your liking, it helps to
+know a little bit about how Emacs lisp packages can be customized via
+the Customization mechanism. It's really easy to use. For details,
+@pxref{How to customize}. @inforef{Easy customization, ,(xemacs)},
+for documentation in XEmacs.
+
+To get the absolute most from Proof General, to improve it or to adapt
+it for new provers, you'll need to know a little bit of Emacs lisp.
+Emacs is self-documenting, so you can begin from @kbd{C-h} and find out
+everything! Here are some useful commands:
+
+@table @asis
+@item @kbd{C-h i}
+@code{info}
+@item @kbd{C-h m}
+@code{describe-mode}
+@item @kbd{C-h b}
+@code{describe-bindings}
+@item @kbd{C-h f}
+@code{describe-function}
+@item @kbd{C-h v}
+@code{describe-variable}
+@end table
+
+
+@node Organization of this manual
+@section Organization of this manual
+
+This manual covers the user-level view and customization of Proof
+General. The accompanying @i{Adapting Proof General} manual considers
+adapting Proof General to new proof assistants, and documents some of
+the internals of Proof General.
+
+Three appendices of this manual contain some details about obtaining and
+installing Proof General and some known bugs. The contents of these
+final chapters is also covered in the files @file{INSTALL} and
+@file{BUGS} contained in the distribution. Refer to those files
+for the latest information.
+
+The manual concludes with some references and indexes. See the table of
+contents for full details.
+
+
+
+
+
+
+
+@c
+@c CHAPTER: Basic Script Management
+@c
+@node Basic Script Management
+@chapter Basic Script Management
+
+This chapter is an introduction to using the script management
+facilities of Proof General. We begin with a quick walkthrough example,
+then describe the concepts and functions in more detail.
+
+@menu
+* Walkthrough example in LEGO::
+* Proof scripts::
+* Script buffers::
+* Summary of Proof General buffers::
+* Script editing commands::
+* Script processing commands::
+* Proof assistant commands::
+* Toolbar commands::
+* Interrupting during trace output::
+@end menu
+
+@node Walkthrough example in LEGO
+@section Walkthrough example in LEGO
+
+Here's a short example in LEGO to see how script management is used.
+The file you are asked to type below is included in the distribution as
+@file{lego/example.l}. If you're not using LEGO, substitute some lines
+from a simple proof for your proof assistant, or consult the file
+called something like @file{foo/example.foo} for proof assistant Foo.
+
+This walkthrough is keyboard based, but you could easily use the toolbar
+and menu functions instead. The best way to learn Emacs key bindings is
+by using the menus. You'll find the keys named below listed on the
+menus.
+
+@itemize @bullet
+@item
+First, find a new file by @kbd{C-x C-f} and typing as the filename
+@file{example.l}. This should load LEGO Proof General and the toolbar
+and Proof General menus will appear. You should have an empty buffer
+displayed.
+@end itemize
+
+The notation @kbd{C-x C-f} means control key with `x' followed by
+control key with `f'. This is a standard notation for Emacs key
+bindings, used throughout this manual. This function also
+appears on the @code{File} menu of Emacs. The remaining commands
+used will be on the @code{Proof-General} menu.
+
+If you're not using LEGO, you must choose a different file extension,
+appropriately for your proof assistant. If you don't know what to use,
+see the previous chapter for the list of supported assistants and file
+extensions.
+
+@itemize @bullet
+@item
+Turn on @dfn{electric terminator} by typing @kbd{C-c ;} and
+enter:
+@lisp
+Module example Import lib_logic;
+@end lisp
+This first command defines a file header and tells LEGO to use logic;
+these steps are usually not necessary in other proof assistants.
+@end itemize
+
+Electric terminator sends commands to the proof assistant as you type
+them. The exact key binding is based on the terminator used for your
+proof assistant, but you can always check the menu if you're not sure.
+
+Electric terminator mode is popular, but not enabled by default because
+of the principle of least surprise. You can customize Proof General to
+enable it everytime if you want, @xref{Customizing Proof General}. In
+XEmacs, this is particularly easy: just use the menu item @code{Options
+-> Save Options} to save some common options while using Proof General.
+
+The @code{Module} command should now be lit in pink (or inverse video if
+you don't have a colour display). As LEGO imports each module, a line
+will appear in the minibuffer showing the creation of context
+marks. Eventually the command should turn blue, indicating that LEGO has
+successfully processed it.
+
+@itemize @bullet
+@item
+Next type (on a new line if you like):
+@lisp
+Goal bland_commutes: @{A,B:Prop@} (and A B) -> (and B A);
+@end lisp
+@end itemize
+
+The goal should be displayed in the goals buffer.
+
+@itemize @bullet
+@item
+Now type:
+@lisp
+Intros;
+@end lisp
+@end itemize
+This will update the goals buffer.
+
+But whoops! That was the wrong command.
+
+@itemize @bullet
+@item
+Press @kbd{C-c C-BS} to pretend that didn't happen.
+@end itemize
+Note: @kbd{BS} means the backspace key. This key press sends an undo
+command to LEGO, and deletes the @code{Intros;} command from the proof
+script. If you just want to undo without deleting, you can type
+@kbd{C-c C-u} instead, or use the toolbar navigation button.
+
+@itemize @bullet
+@item
+Instead, let's try:
+@lisp
+intros; andI;
+@end lisp
+We've used the conjunction-introduction rule.
+
+To finish off, use these commands:
+@lisp
+Refine H; intros; Immed; Refine H; intros; Immed;
+@end lisp
+@end itemize
+Now you should see LEGO display the QED message.
+
+@itemize @bullet
+@item
+Finally, type:
+@lisp
+Save bland_commutes;
+@end lisp
+@end itemize
+
+This last command closes the proof and saves the proved theorem.
+
+Moving the mouse pointer over the locked region now reveals that the
+entire proof has been aggregated into a single segment. This reflects
+the fact that LEGO has thrown away the history of the proof, so if we
+want to undo now, the whole proof must be retracted.
+
+@itemize @bullet
+@item
+Suppose we decide to call the goal something more sensible. Move the
+cursor up into the locked region, somewhere between @samp{Goal} and
+@samp{Save}, enter @kbd{C-c C-RET}.
+@end itemize
+
+You see that the locked segment for the whole proof is now unlocked (and
+uncoloured): it is transferred back into the editing region.
+
+The command @kbd{C-c C-RET} moves the end of the locked region to the
+cursor position, sending undoing commands or proof commands as
+necessary.
+
+@itemize @bullet
+@item
+Now correct the goal name, for example:
+@lisp
+Goal and_commutes: @{A,B:Prop@} (and A B) -> (and B A);
+@end lisp
+Move the cursor to the end of the buffer, and
+type @kbd{C-c C-RET} again.
+@end itemize
+
+Proof General queues the commands for processing and executes them one
+by one. You should see the proof turn pink, then quickly command by
+command it is turned blue. The progress of pink to blue can be
+much slower with long and complicated proofs!
+
+
+
+@node Proof scripts
+@section Proof scripts
+@cindex proof script
+@cindex scripting
+
+A @dfn{proof script} is a sequence of commands which constructs
+definitions, declarations, theories, and proofs in a proof
+assistant. Proof General is designed to work with text-based
+@i{interactive} proof assistants, where the mode of working is usually a
+dialogue between the human and the proof assistant.
+
+Primitive interfaces for proof assistants simply present a @dfn{shell}
+(command interpreter) view of this dialogue: the human repeatedly types
+commands to the shell until the proof is completed. The system responds
+at each step, perhaps with a new list of subgoals to be solved, or
+perhaps with a failure report. Proof General manages the dialogue to
+show the human only the information which is relevant at each step.
+
+Often we want to keep a record of the proof commands used to prove a
+theorem, to build up a library of proved results. An easy way to store
+a proof is to keep a text file which contains a proof script; proof
+assistants usually provide facilities to read a proof script from a file
+instead of the terminal. Using the file, we can @dfn{replay} the proof
+script to prove the theorem again.
+@c Re-playing a proof script is a non-interactive procedure,
+@c since it is supposed to succeed.
+
+Using only a primitive shell interface, it can be tedious to construct
+proof scripts with cut-and-paste. Proof General helps out by issuing
+commands directly from a proof script file, while it is being written
+and edited. Proof General can also be used conveniently to replay a
+proof step-by-step, to see the progress at each stage.
+@c developing them in proof script files.
+
+@dfn{Scripting} is the process of building up a proof script file or
+replaying a proof. When scripting, Proof General sends proof commands
+to the proof assistant one at a time, and prevents you from editing
+commands which have been successfully completed by the proof assistant,
+to keep synchronization. Regions of the proof script are analysed
+based on their syntax and the behaviour of the proof assistant after each
+proof command.
+
+
+@node Script buffers
+@section Script buffers
+@cindex script buffer
+@cindex proof script mode
+
+A @dfn{script buffer} is a buffer displaying a proof script. Its Emacs
+mode is particular to the proof assistant you are using (but it inherits
+from @dfn{proof-mode}).
+
+
+A script buffer is divided into three regions: @emph{locked},
+@emph{queue} and @emph{editing}. The proof commands
+in the script buffer can include a number of
+@emph{Goal-save sequences}.
+
+@menu
+* Locked queue and editing regions::
+* Goal-save sequences::
+* Active scripting buffer::
+@end menu
+
+
+@node Locked queue and editing regions
+@subsection Locked, queue, and editing regions
+@cindex Locked region
+@cindex Queue region
+@cindex Editing region
+@cindex blue text
+@cindex pink text
+
+
+The three regions that a script buffer is divided into are: @c
+
+@itemize @bullet
+@item The @emph{locked} region, which appears in blue (underlined on monochrome
+displays) and contains commands which have been sent to the proof
+process and verified. The commands in the locked region cannot be
+edited.
+
+@item The @emph{queue} region, which appears in pink (inverse video) and contains
+commands waiting to be sent to the proof process. Like those in the
+locked region, these commands can't be edited.
+
+@item The @emph{editing} region, which contains the commands the user is working
+on, and can be edited as normal Emacs text.
+@end itemize
+
+These three regions appear in the buffer in the order above; that is,
+the locked region is always at the start of the buffer, and the editing
+region always at the end. The queue region only exists if there is input
+waiting to be processed by the proof process.
+
+Proof General has two fundamental operations which transfer commands
+between these regions: @emph{assertion} (or processing) and
+@emph{retraction} (or undoing).
+
+@cindex Assertion
+@strong{Assertion} causes commands from the editing region to be
+transferred to the queue region and sent one by one to the proof
+process. If the command is accepted, it is transferred to the locked
+region, but if an error occurs it is signalled to the user, and the
+offending command is transferred back to the editing region together
+with any remaining commands in the queue.
+
+Assertion corresponds to processing proof commands, and makes the locked
+region grow.
+
+@cindex Retraction
+@strong{Retraction} causes commands to be transferred from the locked
+region to the editing region (again via the queue region) and the
+appropriate 'undo' commands to be sent to the proof process.
+
+Retraction corresponds to undoing commands, and makes the locked region
+shrink. For details of the commands
+available for doing assertion and retraction,
+@xref{Script processing commands}.
+
+
+@node Goal-save sequences
+@subsection Goal-save sequences
+@cindex goal
+@cindex save
+@cindex goal-save sequences
+
+A proof script contains a sequence of commands used to prove one or more
+theorems.
+
+As commands in a proof script are transferred to the locked region, they
+are aggregated into segments which constitute the smallest units which
+can be undone. Typically a segment consists of a declaration or
+definition, or all the text from a @dfn{goal} command to the
+corresponding @dfn{save} command, or the individual commands in the
+proof of an unfinished goal. As the mouse moves over the the region,
+the segment containing the pointer will be highlighted.
+
+Proof General therefore assumes that the proof script has a series of
+proofs which look something like this:
+@lisp
+ goal @var{mythm} is @var{G}
+ @dots{}
+ save theorem @var{mythm}
+@end lisp
+interspersed with comments, definitions, and the like. Of course, the
+exact syntax and terminology will depend on the proof assistant you use.
+
+The name @var{mythm} can appear in a menu for the proof script to help
+quickly find a proof (@pxref{Support for function menus}).
+
+@c Proof General recognizes the goal-save sequences in proof scripts.
+@c once a goal-save region has been fully processed by the proof assistant,
+@c it is treated as atomic when undoing proof steps. This reflects the
+@c fact that most proof assistants discard the history of a proof once a it
+@c is completed or once a new proof is begun.
+
+
+@node Active scripting buffer
+@subsection Active scripting buffer
+@cindex active scripting buffer
+
+You can edit as many script buffers as you want simultaneously, but only
+one buffer at a time can be used to process a proof script
+incrementally: this is the @dfn{active scripting buffer}.
+
+The active scripting buffer has a special indicator: the word
+@code{Scripting} appears in its mode line.
+
+When you use a scripting command, it will automatically turn a buffer
+into the active scripting mode. You can also do this by hand, via the
+menu command 'Toggle Scripting' or the key @kbd{C-c C-s}.
+
+@table @asis
+@item @kbd{C-c C-s}
+@code{proof-toggle-active-scripting}
+@end table
+
+When active scripting mode is turned on, several things may happen to
+get ready for scripting (exactly what happens depends on which proof
+assistant you are using and some user settings). First, the proof
+assistant is started if it is not already running. Second, a command is
+sent to the proof assistant to change directory to the directory of the
+current buffer. If the current buffer corresponds to a file, this is
+the directory the file lives in. This is in case any scripting commands
+refer to files in the same directory as the script. The third thing
+that may happen is that you are prompted to save some unsaved buffers.
+This is in case any scripting commands may read in files which you are
+editing. Finally, some proof assistants may automatically read in
+files which the current file depends on implicitly. In Isabelle, for
+example, there is an implicit dependency between a @code{.ML} script
+file and a @code{.thy} theory file which defines its theory.
+
+If you have a partly processed scripting buffer and use @kbd{C-c C-s},
+or you attempt to use script processing in a new buffer, Proof General
+will ask you if you want to retract what has been proved so far,
+@code{Scripting incomplete in buffer myproof.l, retract?}
+or if you want to process the remainder of the active buffer,
+@code{Completely process buffer myproof.l instead?}
+before you can start scripting in a new buffer. If you refuse to do
+either, Proof General will give an error message:
+@code{Cannot have more than one active scripting buffer!}.
+
+To turn off active scripting, the buffer must be completely processed
+(all blue), or completely unprocessed. There are two reasons for this.
+First, it would certainly be confusing if it were possible to split
+parts of a proof arbitrarily between different buffers; the dependency
+between the commands would be lost and it would be tricky to replay the
+proof.@footnote{Some proof assistants provide some level of support for
+switching between multiple concurrent proofs, but Proof General does not
+use this. Generally the exact context for such proofs is hard to define
+to easily split them into multiple files.} Second, we want to interface
+with file management in the proof assistant. Proof General assumes that
+a proof assistant may have a notion of which files have been processed,
+but that it will only record files that have been @i{completely}
+processed. For more explanation of the handling of multiple files,
+@xref{Switching between proof scripts}.
+
+@c TEXI DOCSTRING MAGIC: proof-toggle-active-scripting
+@deffn Command proof-toggle-active-scripting &optional arg
+Toggle active scripting mode in the current buffer.@*
+With @var{arg}, turn on scripting iff @var{arg} is positive.
+@end deffn
+
+
+
+
+@node Summary of Proof General buffers
+@section Summary of Proof General buffers
+@cindex shell buffer
+@cindex goals buffer
+@cindex response buffer
+@cindex proof by pointing
+
+Proof General manages several kinds of buffers in Emacs. Here is a
+summary of the different kinds of buffers you will use when developing
+proofs.
+
+@itemize @bullet
+@item The @dfn{proof shell buffer} is an Emacs shell buffer
+ used to run your proof assistant. Usually it is hidden from view
+ (but @pxref{Escaping script management}).
+ Communication with the proof shell takes place via two or three
+ intermediate buffers.
+@item A @dfn{script buffer}, as we have explained, is a buffer for editing a
+ proof script. The @dfn{active scripting buffer} is the script buffer
+ which is currently being used to send commands to the proof shell.
+@item The @dfn{goals buffer} displays the list of subgoals to be
+ solved for a proof in progress. During a proof it is usually
+ displayed together with the script buffer.
+ The goals buffer has facility for @dfn{proof-by-pointing}.
+@item The @dfn{response buffer} displays other output from the proof
+ assistant, for example error messages or informative messages.
+ The response buffer is displayed whenever Proof General puts
+ a new message in it.
+@item The @dfn{trace buffer} is a special version of the response
+ buffer. It may be used to display unusual debugging output from the
+ prover, for example, tracing proof tactics or rewriting procedures.
+ This buffer is also displayed whenever Proof General puts a new message
+ in it (although it may be quickly replaced with the response or goals
+ buffer in two-buffer mode).
+@end itemize
+
+Normally Proof General will automatically reveal and hide the goals and
+response buffers as necessary during scripting. However there are ways
+to customize the way the buffers are displayed (@pxref{Display
+customization}).
+
+The menu @code{Proof General -> Buffers} provides a convenient way to
+display or switch to one of the four buffers: active scripting, goals,
+response, or shell.
+
+@c When
+@c Proof General sees an error in the shell buffer, it will highlight the
+@c error and display the buffer automatically.
+
+
+@c This facility was not added:
+@c
+@c Optionally, the goals buffer and script buffer can be identified
+@c @pxref{Identify goals and response}. The disadvantage of this is that
+@c the goals display can be replaced by other messages, so you must ask for
+@c it to be refreshed. The advantage is that it is simpler to deal with
+@c fewer Emacs buffers.
+
+
+
+@node Script editing commands
+@section Script editing commands
+
+Proof General provides a few functions for editing proof scripts. The
+generic functions mainly consist of commands to navigate within the
+script. Specific proof assistant code may add more to these basics.
+
+@findex indent-for-tab-command
+@vindex proof-script-indent
+Indentation is controlled by the user option @code{proof-script-indent}
+(@pxref{User options}). When indentation is enabled, Proof General
+will indent lines of proof script with the usual Emacs functions,
+particularly @kbd{TAB}, @code{indent-for-tab-command}.
+@c FIXME: remove when indentation is fixed.
+Unfortunately, indentation in Proof General @value{version} is somewhat
+slow. Therefore with large proof scripts, we recommend
+@code{proof-script-indent} is turned off.
+
+Here are the commands for moving around in a proof script,
+with their default key-bindings:
+@kindex C-c C-a
+@kindex C-c C-e
+@kindex C-c C-.
+@table @kbd
+@item C-c C-a
+@code{proof-goto-command-start}
+@item C-c C-e
+@code{proof-goto-command-end}
+@item C-c C-.
+@code{proof-goto-end-of-locked}
+@end table
+
+@c TEXI DOCSTRING MAGIC: proof-goto-command-start
+@deffn Command proof-goto-command-start
+Move point to start of current (or final) command of the script.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-goto-command-end
+@deffn Command proof-goto-command-end
+Set point to end of command at point.
+@end deffn
+
+@vindex proof-terminal-char
+The variable @code{proof-terminal-char} is a prover-specific character
+to terminate proof commands. LEGO and Isabelle use a semicolon,
+@samp{;}. Coq employs a full-stop @samp{.}.
+
+@c TEXI DOCSTRING MAGIC: proof-goto-end-of-locked
+@deffn Command proof-goto-end-of-locked &optional switch
+Jump to the end of the locked region, maybe switching to script buffer.@*
+If interactive or @var{switch} is non-nil, switch to script buffer first.
+@end deffn
+
+During the course of a large proof, it may be useful to copy previous
+commands. As you move the mouse over previous portions of the script,
+you'll notice that each proof command is highlighted individually.
+(Once a goal...save sequence is ``closed'', the whole sequence is
+highlighted). There is a useful mouse binding for copying the
+highlighted command under the mouse:
+
+@kindex C-button1
+@table @kbd
+@item C-button1
+@code{proof-mouse-track-insert}
+@end table
+
+@c TEXI DOCSTRING MAGIC: proof-mouse-track-insert
+
+
+@deffn Command proof-mouse-track-insert event
+Copy highlighted command under the mouse to point. Ignore comments.@*
+If there is no command under the mouse, behaves like @code{mouse-track-insert}.
+@end deffn
+Read the documentation in Emacs to find out about the normal behaviour
+of @code{proof-mouse-track-insert}, if you don't already know what it
+does.
+
+
+@node Script processing commands
+@section Script processing commands
+@kindex C-c C-n
+@kindex C-c C-u
+@kindex C-c C-BS
+@kindex C-c C-b
+@kindex C-c C-r
+@kindex C-c C-RET
+@cindex prefix argument
+
+Here are the commands for asserting and retracting portions of the proof
+script, together with their default key-bindings. Sometimes assertion
+and retraction commands can only be issued when the queue is empty. You
+will get an error message @code{Proof Process Busy!} if you try to
+assert or retract when the queue is being processed.@footnote{In fact,
+this is an unnecessary restriction imposed by the original design of
+Proof General. There is nothing to stop future versions of Proof
+General allowing the queue region to be extended or shrunk, whilst the
+prover is processing it. Proof General 3.0 already relaxes the original
+design, by allowing successive assertion commands without complaining.}
+
+@table @kbd
+@item C-c C-n
+@code{proof-assert-next-command-interactive}
+@item C-c C-u
+@code{proof-undo-last-successful-command}
+@item C-c C-BS
+@code{proof-undo-and-delete-successful-command}
+@item C-c C-RET
+@code{proof-goto-point}
+@item C-c C-b
+@code{proof-process-buffer}
+@item C-c C-r
+@code{proof-retract-buffer}
+@item C-c @var{terminator-character}
+@code{proof-electric-terminator-toggle}
+@end table
+
+The last command, @code{proof-electric-terminator-toggle}, is triggered
+using the character which terminates proof commands for your proof
+assistant's script language. For LEGO and Isabelle, use @kbd{C-c ;},
+for Coq, use @kbd{C-c .}. This not really a script processing
+command. Instead, if enabled, it causes subsequent key presses of
+@kbd{;} or @kbd{.} to automatically activate
+@code{proof-assert-next-command-interactive} for convenience.
+
+Rather than use a file command inside the proof assistant to read a
+proof script, a good reason to use @kbd{C-c C-b}
+(@code{proof-process-buffer}) is that with a faulty proof script (e.g.,
+a script you are adapting to prove a different theorem), Proof General
+will stop exactly where the proof script fails, showing you the error
+message and the last processed command. So you can easily continue
+development from exactly the right place in the script.
+
+Here is the full set of script processing commands.
+
+@c TEXI DOCSTRING MAGIC: proof-assert-next-command-interactive
+@deffn Command proof-assert-next-command-interactive
+Process until the end of the next unprocessed command after point.@*
+If inside a comment, just process until the start of the comment.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-undo-last-successful-command
+@deffn Command proof-undo-last-successful-command
+Undo last successful command at end of locked region.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-undo-and-delete-last-successful-command
+@deffn Command proof-undo-and-delete-last-successful-command
+Undo and delete last successful command at end of locked region.@*
+Useful if you typed completely the wrong command.
+Also handy for proof by pointing, in case the last proof-by-pointing
+command took the proof in a direction you don't like.
+
+Notice that the deleted command is put into the Emacs kill ring, so
+you can use the usual @samp{yank} and similar commands to retrieve the
+deleted text.
+@end deffn
+
+
+@c TEXI DOCSTRING MAGIC: proof-goto-point
+@deffn Command proof-goto-point
+Assert or retract to the command at current position.@*
+Calls @code{proof-assert-until-point} or @code{proof-retract-until-point} as
+appropriate.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-process-buffer
+@deffn Command proof-process-buffer
+Process the current (or script) buffer, and maybe move point to the end.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-retract-buffer
+@deffn Command proof-retract-buffer
+Retract the current buffer, and maybe move point to the start.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-electric-terminator-toggle
+@deffn Command proof-electric-terminator-toggle arg
+Toggle @samp{@code{proof-electric-terminator-enable}}. With @var{arg}, turn on iff ARG>0.@*
+This function simply uses @code{customize-set-variable} to set the variable.
+It was constructed with @samp{@code{proof-deftoggle-fn}}.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-assert-until-point-interactive
+@deffn Command proof-assert-until-point-interactive
+Process the region from the end of the locked-region until point.@*
+Default action if inside a comment is just process as far as the start of
+the comment.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-retract-until-point-interactive
+@deffn Command proof-retract-until-point-interactive &optional delete-region
+Tell the proof process to retract until point.@*
+If invoked outside a locked region, undo the last successfully processed
+command. If called with a prefix argument (@var{delete-region} non-nil), also
+delete the retracted region from the proof-script.
+@end deffn
+
+As experienced Emacs users will know, a @i{prefix argument} is a numeric
+argument supplied by some key sequence typed before a command key
+sequence. You can supply a specific number by typing @key{Meta} with
+the digits, or a ``universal'' prefix of @kbd{C-u}. See
+@inforef{Arguments, ,(xemacs)} for more details. Several Proof General
+commands, like @code{proof-retract-until-point-interactive}, may accept
+a @i{prefix argument} to adjust their behaviour somehow.
+
+
+@node Proof assistant commands
+@section Proof assistant commands
+@kindex C-c C-p
+@kindex C-c C-h
+@kindex C-c C-c
+@kindex C-c C-v
+@kindex C-c C-f
+@kindex C-c C-t
+
+There are several commands for interacting with the proof assistant away
+from a proof script. Here are the key-bindings and functions.
+
+@table @kbd
+@item C-c C-l
+@code{proof-display-some-buffers}
+@item C-c C-p
+@code{proof-prf}
+@item C-c C-t
+@code{proof-ctxt}
+@item C-c C-h
+@code{proof-help}
+@item C-c C-f
+@code{proof-find-theorems}
+@item C-c C-c
+@code{proof-interrupt-process}
+@item C-c C-v
+@code{proof-minibuffer-cmd}
+@end table
+
+
+@c TEXI DOCSTRING MAGIC: proof-display-some-buffers
+@deffn Command proof-display-some-buffers
+Display the reponse or goals buffer, toggling between them.@*
+Also move point to the end of the response buffer.
+If in three window or multiple frame mode, display both buffers.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-prf
+@deffn Command proof-prf
+Show the current proof state.@*
+Issues a command to the assistant based on @code{proof-showproof-command}.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-ctxt
+@deffn Command proof-ctxt
+Show the current context.@*
+Issues a command to the assistant based on @code{proof-context-command}.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-help
+@deffn Command proof-help
+Show a help or information message from the proof assistant.@*
+Typically, a list of syntax of commands available.
+Issues a command to the assistant based on @code{proof-info-command}.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-find-theorems
+@deffn Command proof-find-theorems arg
+Search for items containing given constants.@*
+Issues a command based on @var{arg} to the assistant, using @code{proof-find-theorems-command}.
+The user is prompted for an argument.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-interrupt-process
+@deffn Command proof-interrupt-process
+Interrupt the proof assistant. Warning! This may confuse Proof General.@*
+This sends an interrupt signal to the proof assistant, if Proof General
+thinks it is busy.
+
+This command is risky because when an interrupt is trapped in the
+proof assistant, we don't know whether the last command succeeded or
+not. The assumption is that it didn't, which should be true most of
+the time, and all of the time if the proof assistant has a careful
+handling of interrupt signals.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-minibuffer-cmd
+@deffn Command proof-minibuffer-cmd cmd
+Prompt for a command in the minibuffer and send it to proof assistant.@*
+The command isn't added to the locked region.
+
+If a prefix arg is given and there is a selected region, that is
+pasted into the command. This is handy for copying terms, etc from
+the script.
+
+If @samp{@code{proof-strict-state-preserving}} is set, and @samp{@code{proof-state-preserving-p}}
+is configured, then the latter is used as a check that the command
+will be safe to execute, in other words, that it won't ruin
+synchronization. If when applied to the command it returns false,
+then an error message is given.
+
+@var{warning}: this command risks spoiling synchronization if the test
+@samp{@code{proof-state-preserving-p}} is not configured, if it is
+only an approximate test, or if @samp{@code{proof-strict-state-preserving}}
+is off (nil).
+@end deffn
+
+As if the last two commands weren't risky enough, there's also a command
+which explicitly adjusts the end of the locked region, to be used in
+extreme circumstances only. @xref{Escaping script management}.
+
+There are a few commands for stopping, starting, and restarting the
+proof assistant process which have menu entries but no key-bindings.
+As with any Emacs command, you can invoke these with @kbd{M-x}.
+
+Here's a tip: if you accidently kill one of the Proof General special
+buffers (goals or response), exiting the proof assistant and restarting
+it will solve the problem.
+
+@c TEXI DOCSTRING MAGIC: proof-shell-start
+@deffn Command proof-shell-start
+Initialise a shell-like buffer for a proof assistant.
+
+Also generates goal and response buffers.
+Does nothing if proof assistant is already running.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-shell-restart
+@deffn Command proof-shell-restart
+Clear script buffers and send @code{proof-shell-restart-cmd}.@*
+All locked regions are cleared and the active scripting buffer
+deactivated.
+
+If the proof shell is busy, an interrupt is sent with
+@code{proof-interrupt-process} and we wait until the process is ready.
+
+The restart command should re-synchronize Proof General with the proof
+assistant, without actually exiting and restarting the proof assistant
+process.
+
+It is up to the proof assistant how much context is cleared: for
+example, theories already loaded may be "cached" in some way,
+so that loading them the next time round only performs a re-linking
+operation, not full re-processing. (One way of caching is via
+object files, used by Lego and Coq).
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-shell-exit
+@deffn Command proof-shell-exit
+Query the user and exit the proof process.
+
+This simply kills the @code{proof-shell-buffer} relying on the hook function
+@code{proof-shell-kill-function} to do the hard work.
+@end deffn
+
+
+
+@node Toolbar commands
+@section Toolbar commands
+
+The toolbar provides a selection of functions for asserting and
+retracting portions of the script, issuing non-scripting commands, and
+inserting "goal" and "save" type commands. The latter functions are not
+available on keys, but are available from the from the menu, or via
+@kbd{M-x}, as well as the toolbar.
+
+@c TEXI DOCSTRING MAGIC: proof-issue-goal
+@deffn Command proof-issue-goal arg
+Write a goal command in the script, prompting for the goal.@*
+Issues a command based on @var{arg} to the assistant, using @code{proof-goal-command}.
+The user is prompted for an argument.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-issue-save
+@deffn Command proof-issue-save arg
+Write a save/qed command in the script, prompting for the theorem name.@*
+Issues a command based on @var{arg} to the assistant, using @code{proof-save-command}.
+The user is prompted for an argument.
+@end deffn
+
+
+@node Interrupting during trace output
+@section Interrupting during trace output
+
+If your prover generates output which is recognized as tracing output in
+Proof General, you may need to know about a special provision for
+interrupting the prover process.
+@c %
+If the trace output is voluminous, perhaps looping, it may be difficult
+to interrupt with the ordinary @kbd{C-c C-c}
+(@code{proof-interrupt-process}) or the corresponding button/menu. In
+this case, you should try Emacs's @b{quit key}, @kbd{C-g}. This will
+cause a quit in any current editing commands, as usual, but during
+tracing output it will also send an interrupt signal to the prover.
+Hopefully this will stop the tracing output, and Emacs should catch up
+after a short delay.
+
+Here's an explanation of the reason for this special provision. When
+large volumes of output from the prover arrive quickly in Emacs, as
+typically is the case during tracing (especially tracing looping
+tactics!), Emacs may hog the CPU and spend all its time updating the
+display with the trace output. This is especially the case when
+features like output fontification and X-Symbol display are active. If
+this happens, ordinary user input in Emacs is not processed, and it
+becomes difficult to do normal editing. The root of the problem is that
+Emacs runs in a single thread, and pending process output is dealt with
+before pending user input. Whether or not you see this problem depends
+partly on the processing power of your machine (or CPU available to
+Emacs when the prover is running). One way to test is to start an Emacs
+shell with @kbd{M-x shell} and type a command such as @code{yes} which
+produces output indefinitely. Now see if you can interrupt the process!
+(Warning --- on slower machines especially, this can cause lockups, so
+use a fresh Emacs.)
+
+
+
+@c
+@c CHAPTER: Proof by Pointing
+@c
+@node Proof by Pointing
+@chapter Proof by Pointing
+
+This chapter describes what you can do from inside the goals buffer,
+providing support for these features exists for your proof assistant.
+As of Proof General 3.0, it only exists for LEGO. If you would like to
+see proof by pointing support for Proof General in another proof
+assistant, please petition the developers of that proof assistant to
+provide it!
+
+@menu
+* Goals buffer commands::
+@end menu
+
+@node Goals buffer commands
+@section Goals buffer commands
+
+When you are developing a proof, the input focus (Emacs cursor) is
+usually on the script buffer. Therefore Proof General binds mouse
+buttons for commands in the goals buffer, to avoid the need to move the
+cursor between buffers.
+
+The mouse bindings are these:
+
+@table @kbd
+@item button2
+@code{pbp-button-action}
+@item C-button2
+@code{proof-undo-and-delete-last-successful-command}
+@item button3
+@code{pbp-yank-subterm}
+@end table
+
+Where @kbd{button2} indicates the middle mouse button, and @kbd{button3}
+indicates the right hand mouse button.
+
+The idea is that you can automatically construct parts of a proof by
+clicking. Using the middle mouse button asks the proof assistant to try
+to do a step in the proof, based on where you click. If you don't like
+the command which was inserted into the script, you can use the control
+key with the middle button to undo the step, and delete it from your
+script.
+
+Note that proof-by-pointing may construct several commands in one go.
+These are sent back to the proof assistant altogether and appear as a
+single step in the proof script. However, if the proof is later
+replayed (without using PBP), the proof-by-pointing constructions will
+be considered as separate proof commands, as usual.
+
+@c TEXI DOCSTRING MAGIC: pbp-button-action
+
+@deffn Command pbp-button-action event
+Construct a proof-by-pointing command based on the mouse-click @var{event}.@*
+This function should be bound to a mouse button in the Proof General
+goals buffer.
+
+The @var{event} is used to find the smallest subterm around a point. A
+position code for the subterm is sent to the proof assistant, to ask
+it to construct an appropriate proof command. The command which is
+constructed will be inserted at the end of the locked region in the
+proof script buffer, and immediately sent back to the proof assistant.
+If it succeeds, the locked region will be extended to cover the
+proof-by-pointing command, just as for any proof command the
+user types by hand.
+@end deffn
+
+Proof-by-pointing uses markup describing the term structure of the
+concrete syntax output by the proof assistant. This markup is useful in
+itself: it allows you to explore the structure of a term using the mouse
+(the smallest subexpression that the mouse is over is highlighted), and
+easily copy subterms from the output to a proof script.
+
+The right-hand mouse button provides this convenient way to copy
+subterms from the goals buffer, using the function
+@code{pbp-yank-subterm}.
+
+@c TEXI DOCSTRING MAGIC: pbp-yank-subterm
+
+@deffn Command pbp-yank-subterm event
+Copy the subterm indicated by the mouse-click @var{event}.@*
+This function should be bound to a mouse button in the Proof General
+goals buffer.
+
+The @var{event} is used to find the smallest subterm around a point. The
+subterm is copied to the @code{kill-ring}, and immediately yanked (copied)
+into the current buffer at the current cursor position.
+
+In case the current buffer is the goals buffer itself, the yank
+is not performed. Then the subterm can be retrieved later by an
+explicit yank.
+@end deffn
+@c Proof General expects to parse
+@c term-structure annotations on the output syntax of the prover.
+@c It uses these to construct a message to the prover indicating
+@c where the user has clicked, and the proof assistant can
+@c response with a suggested tactic.
+
+
+
+
+
+@c
+@c CHAPTER: Advanced Script Management
+@c
+@node Advanced Script Management
+@chapter Advanced Script Management
+@cindex Multiple Files
+
+If you are working with large proof developments, you may want to know
+about the advanced script management features of Proof General covered
+in this chapter.
+
+Large developments may contain files with many long proofs. Proof
+General provides functions that let you hide completed proofs from view,
+temporarily.
+
+Large proof developments are typically spread across various files which
+depend on each other in some way. Proof General knows enough about the
+dependencies to allow script management across multiple files.
+With large developments particularly, users may occasionally need to
+escape from script management, in case Proof General loses
+synchronization with the proof assistant. Proof General provides
+you with several escape mechanisms if you want to do this.
+
+@menu
+* Visibility of completed proofs::
+* Switching between proof scripts::
+* View of processed files ::
+* Retracting across files::
+* Asserting across files::
+* Automatic multiple file handling::
+* Escaping script management::
+@end menu
+
+@node Visibility of completed proofs
+@section Visibility of completed proofs
+@cindex Visibility of proofs
+
+Large developments may consist of large files with many proofs.
+To help see what has been proved without the detail of the
+proof itself, Proof General can hide completed proofs.
+
+You can toggle the visibility of a proof by using a context sensitive
+menu triggered by @b{clicking the right mouse button on a completed
+proof}, or the key @kbd{C-c v}, which runs @code{pg-toggle-visibility}.
+
+
+You can also select the ``disappearing proofs'' mode from the menu,
+@lisp
+ Proof-General -> Options -> Disappearing Proofs
+@end lisp
+This automatically hides each proof as it is completed by the
+proof assistant.
+
+Finally, two menu commands in the main Proof-General menu,
+@emph{Show proofs} and @emph{Hide proofs} apply to all the completed
+proofs in the buffer.
+
+Notice that by design, this feature only applies to completed proofs,
+@emph{after} they have been processed by the proof assistant. When
+files are first visited in Proof General, no information is stored about
+proof boundaries.
+
+The relevant elisp functions and settings are mentioned below.
+
+@c TEXI DOCSTRING MAGIC: pg-toggle-visibility
+@deffn Command pg-toggle-visibility
+Toggle visibility of region under point.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: pg-show-all-proofs
+@deffn Command pg-show-all-proofs
+Display all completed proofs in the buffer.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: pg-hide-all-proofs
+@deffn Command pg-hide-all-proofs
+Hide all completed proofs in the buffer.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-disappearing-proofs
+@defopt proof-disappearing-proofs
+Non-nil causes Proof General to hide proofs as they are completed.
+
+The default value is @code{nil}.
+@end defopt
+
+
+@node Switching between proof scripts
+@section Switching between proof scripts
+@cindex Switching between proof scripts
+
+Basic modularity in large proof developments can be achieved by
+splitting proof scripts across various files. Let's assume that you are
+in the middle of a proof development. You are working on a soundness
+proof of Hoare Logic in a file called@footnote{The suffix may depend of
+the specific proof assistant you are using e.g, LEGO's proof script
+files have to end with @file{.l}.} @file{HSound.l}. It
+depends on a number of other files which develop underlying
+concepts e.g. syntax and semantics of expressions, assertions,
+imperative programs. You notice that the current lemma is too difficult
+to prove because you have forgotten to prove some more basic properties
+about determinism of the programming language. Or perhaps a previous
+definition is too cumbersome or even wrong.
+
+At this stage, you would like to visit the appropriate file, say
+@file{sos.l} and retract to where changes are required. Then, using
+script management, you want to develop some more basic theory in
+@file{sos.l}. Once this task has been completed (possibly involving
+retraction across even earlier files) and the new development has been
+asserted, you want to switch back to @file{HSound.l} and replay to the
+point you got stuck previously.
+
+Some hours (or days) later you have completed the soundness proof and
+are ready to tackle new challenges. Perhaps, you want to prove a
+property that builds on soundness or you want to prove an orthogonal
+property such as completeness.
+
+Proof General lets you do all of this while maintaining the consistency
+between proof script buffers and the state of the proof assistant.
+However, you cannot have more than one buffer where only a fraction of
+the proof script contains a locked region. Before you can employ script
+management in another proof script buffer, you must either fully assert
+or retract the current script buffer.
+
+@node View of processed files
+@section View of processed files
+
+Proof General tries to be aware of all files that the proof assistant
+has processed or is currently processing. In the best case, it relies
+on the proof assistant explicitly telling it whenever it processes a new
+file which corresponds@footnote{For example, LEGO generates additional
+compiled (optimised) proof script files for efficiency.} to a file
+containing a proof script.
+
+If the current proof script buffer depends on background material from
+other files, proof assistants typically process these files
+automatically. If you visit such a file, the whole file is locked as
+having been processed in a single step. From the user's point of view,
+you can only retract but not assert in this buffer. Furthermore,
+retraction is only possible to the @emph{beginning} of the buffer.
+@c This isn't strictly true, is it? We lock off buffers atomically,
+@c but spans in them to start with stay there. (Only meaningful
+@c for reading currently active scripting file)
+
+Unlike a script buffer that has been processed step-by-step via Proof
+General, automatically loaded script buffers do not pass through a
+``red'' phase to indicate that they are currently being processed. This
+is a limitation of the present implementation. Proof General locks a
+buffer as soon as it sees the appropriate message from the proof
+assistant. Different proof assistants may use different messages:
+either @emph{early locking} when processing a file begins (e.g. LEGO) or
+@emph{late locking} when processing a file ends (e.g. Isabelle).
+
+With @emph{early locking}, you may find that a script which has only
+been partly processed (due to an error or interrupt, for example), is
+wrongly completely locked by Proof General. Visit the file and retract
+back to the start to fix this.
+
+With @emph{late locking}, there is the chance that you can break
+synchronization by editing a file as it is being read by the proof
+assistant, and saving it before processing finishes.
+
+In fact, there is a general problem of editing files which may be
+processed by the proof assistant automatically. Synchronization can be
+broken whenever you have unsaved changes in a proof script buffer and
+the proof assistant processes the corresponding file. (Of course, this
+problem is familiar from program development using separate editors
+and compilers). The good news is that Proof General can detect the
+problem and flashes up a warning in the response buffer. You can then
+visit the modified buffer, save it and retract to the beginning. Then
+you are back on track.
+
+
+
+@c only true for LEGO!
+@c If the proof assistant is not happy with the script and
+@c complains with an error message, the buffer will still be marked as
+@c having been completely processed. Sorry. You need to visit the
+@c troublesome file, retract (which will always retract to the beginning of
+@c the file) and debug the problem e.g., by asserting all of the buffer
+@c under the supervision of Proof General, see @ref{Script processing
+@c commands}.
+
+
+@node Retracting across files
+@section Retracting across files
+@cindex Retraction
+
+Make sure that the current script buffer has either been completely
+asserted or retracted (Proof General enforces this). Then you can
+retract proof scripts in a different file. Simply visit a file that has
+been processed earlier and retract in it, using the retraction commands
+from @pxref{Script processing commands}. Apart from removing parts of the
+locked region in this buffer, all files which depend on it will be
+retracted (and thus unlocked) automatically. Proof General reminds you
+that now is a good time to save any unmodified buffers.
+
+@node Asserting across files
+@section Asserting across files
+@cindex Assertion
+
+Make sure that the current script buffer has either been completely
+asserted or retracted. Then you can assert proof scripts in a different
+file. Simply visit a file that contains no locked region and assert some
+command with the usual assertion commands, @pxref{Script processing
+commands}. Proof General reminds you that now is a good time to save any
+unmodified buffers. This is particularly useful as assertion may cause
+the proof assistant to automatically process other files.
+
+
+@node Automatic multiple file handling
+@section Automatic multiple file handling
+
+To make it easier to adapt Proof General for a proof assistant, there is
+another possibility for multiple file support --- that it is provided
+automatically by Proof General and not integrated with the
+file-management system of the proof assistant.
+
+In this case, Proof General assumes that the only files processed are
+the ones it has sent to the proof assistant itself. Moreover, it
+(conservatively) assumes that there is a linear dependency between files
+in the order they were processed.
+
+If you only have automatic multiple file handling, you'll find that any
+files loaded directly by the proof assistant are @emph{not} locked when
+you visit them in Proof General. Moreover, if you retract a file it may
+retract more than is strictly necessary (because it assumes a linear
+dependency).
+
+For further technical details of the ways multiple file scripting is
+configured, see @i{Handling multiple files} in
+the @i{Adapting Proof General} manual.
+
+
+
+@node Escaping script management
+@section Escaping script management
+@cindex Shell
+
+Occasionally you may want to review the dialogue of the entire session
+with the proof assistant, or check that it hasn't done something
+unexpected. Experienced users may also want to directly communicate
+with the proof assistant rather than sending commands via the
+minibuffer, @pxref{Proof assistant commands}.
+
+Although the proof shell is usually hidden from view, it is run in a
+buffer which provides the usual full editing and history facilities of
+Emacs shells (see the package @file{comint.el} distributed with your
+version of Emacs). You can switch to it using the menu:
+
+@lisp
+ Proof-General -> Buffers -> Shell
+@end lisp
+
+@b{Warning:} you can probably cause confusion by typing in the shell
+buffer! Proof General may lose track of the state of the proof
+assistant. Output from the assistant is only fully monitored when Proof
+General is in control of the shell.
+
+When in control, Proof General watches the output from the proof
+assistant to guess when a file is loaded or when a proof step is taken
+or undone. What happens when you type in the shell buffer directly
+depends on how complete the communication is between Proof General and
+the prover (which depends on the particular instantiation of Proof
+General).
+
+If synchronization is lost, you have two options to resynchronize. If
+you are lucky, it might suffice to use the key:
+
+@table @kbd
+@item C-c C-z
+@code{proof-frob-locked-end}
+@end table
+
+This command is disabled by default, to protect novices using it
+accidently.
+
+If @code{proof-frob-locked-end} does not work, you will need to restart
+script management altogether (@pxref{Proof assistant commands}).
+
+@c TEXI DOCSTRING MAGIC: proof-frob-locked-end
+@deffn Command proof-frob-locked-end
+Move the end of the locked region backwards to regain synchronization.@*
+Only for use by consenting adults.
+
+This command can be used to repair synchronization in case something
+goes wrong and you want to tell Proof General that the proof assistant
+has processed less of your script than Proof General thinks.
+
+You should only use it to move the locked region to the end of
+a proof command.
+@end deffn
+
+
+@node Support for other Packages
+@chapter Support for other Packages
+
+Proof General makes some configuration for other Emacs packages which
+provide various useful facilities that can make your editing
+more effective.
+
+Sometimes this configuration is purely at the proof assistant specific
+level (and so not necessarily available), and sometimes it is made using
+Proof General settings.
+
+When adding support for a new proof assistant, we suggest that these
+other packages are supported, as a convention.
+
+The packages currently supported are
+@code{font-lock},
+@code{x-symbol},
+@code{func-menu},
+@code{outline-mode},
+@code{completion},
+and @code{etags}.
+
+
+@menu
+* Syntax highlighting::
+* X-Symbol support::
+* Support for function menus::
+* Support for outline mode::
+* Support for completion::
+* Support for tags::
+@end menu
+
+@node Syntax highlighting
+@section Syntax highlighting
+@vindex lego-mode-hooks
+@vindex coq-mode-hooks
+@vindex isa-mode-hooks
+@cindex font lock
+@cindex colour
+@c Proof General specifics
+
+Proof script buffers are decorated (or @i{fontified}) with colours, bold
+and italic fonts, etc, according to the syntax of the proof language and
+the settings for @code{font-lock-keywords} made by the proof assistant
+specific portion of Proof General. Moreover, Proof General usually
+decorates the output from the proof assistant, also using
+@code{font-lock}.
+
+In XEmacs, fontification is automatically turned on. To automatically
+switch on fontification in GNU Emacs 20.4, you may need to engage
+@code{M-x global-font-lock-mode}. The old mechanism of adding hooks to
+the mode hooks (@code{lego-mode-hooks}, @code{coq-mode-hooks}, etc) is
+no longer recommended; it should not be needed in latest Emacs versions
+which have more flexible customization.
+
+Fontification for output is controlled by a separate switch in Proof
+General. Set @code{proof-output-fontify-enable} to @code{nil} if you
+don't want the output from your proof assistant to be fontified
+according to the setting of @code{font-lock-keywords} in the proof
+assistant specific portion of Proof General. @xref{User options}.
+
+By the way, the choice of colour, font, etc, for each kind of markup is
+fully customizable in Proof General. Each @emph{face} (Emacs
+terminology) controlled by its own customization setting.
+You can display a list of all of them using the customize
+menu:
+@lisp
+Proof General -> Customize -> Faces -> Proof Faces.
+@end lisp
+
+
+@node X-Symbol support
+@section X-Symbol support
+@cindex real symbols
+@cindex X-Symbols
+@cindex Greek letters
+@cindex logical symbols
+@cindex mathematical symbols
+
+The X-Symbol package displays characters from a variety of fonts in
+Emacs buffers, automatically converting between codes for special
+characters and @i{tokens} which are character sequences stored in files.
+
+Proof General uses X-Symbol to allow interaction between the user and
+the proof assistant to use tokens, yet appear to be using special
+characters. So proof scripts and proofs can be processed with real
+mathematical symbols, Greek letters, etc.
+
+You will be able to enable X-Symbol support if you have installed the
+X-Symbol package and support has been provided in Proof General for a
+token language for your proof assistant.
+The X-Symbol package is available from
+@uref{http://www.fmi.uni-passau.de/~wedler/x-symbol/}.
+
+Notice that for proper symbol support, the proof assistant needs to have
+a special @i{token language}, or a special character set, to use
+symbols. In this case, the proof assistant will output, and accept as
+input, tokens like @code{\longrightarrow}, which display as the
+corresponding symbols. However, for proof assistants which do not have
+such token support, we can use "fake" symbol support quite effectively,
+displaying ordinary character sequences such as @code{-->} with symbols.
+The only problem with this hack is that it can cause surprising results,
+when you really want character sequences instead of, for example, Greek
+letters!
+
+@c @xref{Configuring X-Symbol}, for notes about how to configure
+@c a proof assistant to use X-Symbol in Proof General.
+
+
+@node Support for function menus
+@section Support for function menus
+@vindex proof-goal-with-hole-regexp
+@cindex func-menu
+@cindex fume-func
+
+The Emacs package @code{func-menu} (formerly called @code{fume-func}) is
+a handy facility to make a menu from the names of entities declared in a
+buffer. Proof General configures @code{func-menu} so that you can
+quickly jump to particular proofs in a script buffer. (This is done
+with the configuration variables @code{proof-goal-with-hole-regexp} and
+@code{proof-save-with-hole-regexp}.)
+@c , @pxref{Proof script mode} for further details.
+
+If you want to use function menu, you can simply select "Function menu"
+from the Proof General menu, or type @kbd{M-x function-menu}.
+
+Although the package is distributed with XEmacs, it is not enabled by
+default every time you visit a buffer. To enable it by default
+(i.e. avoid typing @code{M-x function-menu}), you should find the file
+@file{func-menu.el} and follow the instructions there.
+
+GNU Emacs 20.4 does not have the function menu library built in, but you
+may be able to download it from the elisp archives. A similar mode
+which is supported is @code{imenu}, also in XEmacs. Proof General would
+be grateful if anyone can send patches for using @code{imenu}
+as an alternative to function menu.
+
+
+@node Support for outline mode
+@section Support for outline mode
+@cindex outline mode
+
+Proof General configures Emacs variables (@code{outline-regexp} and
+@code{outline-heading-end-regexp}) so that outline minor mode can be
+used on proof script files. The headings taken for outlining are the
+"goal" statements at the start of goal-save sequences,
+@pxref{Goal-save sequences}. If you want to use @code{outline} to hide
+parts of the proof script in the @emph{locked} region, you need to disable
+@code{proof-strict-read-only}.
+
+Use @kbd{M-x outline-minor-mode} to turn on outline minor mode.
+Functions for navigating, hiding, and revealing the proof script are
+available in menus.
+
+See @inforef{Outline Mode, ,(xemacs)} for more information about
+outline mode.
+
+@node Support for completion
+@section Support for completion
+@cindex completion
+
+You might find the @emph{completion} facility of Emacs useful when
+you're using Proof General. The key @kbd{C-RET} is defined to invoke
+the @code{complete} command. Pressing @kbd{C-RET} cycles through
+completions displaying hints in the minibuffer.
+
+Completions are filled in according to what has been recently typed,
+from a database of symbols. The database is automatically saved at
+the end of a session.
+
+Proof General has the additional facility for setting a completion table
+for each supported proof assistant, which gets loaded into the
+completion database automatically. Ideally the completion table would
+be set from the running process according to the identifiers available
+are within the particular context of a script file. But until this is
+available, this table may be set to contain a number of standard
+identifiers available for your proof assistant.
+
+The setting @code{@emph{PA}-completion-table} holds the list of
+identifiers for a proof assistant. The function
+@code{proof-add-completions} adds these into the completion
+database.
+
+@c TEXI DOCSTRING MAGIC: PA-completion-table
+@defvar PA-completion-table
+List of identifiers to use for completion for this proof assistant.@*
+Completion is activated with C-return.
+
+If this table is empty or needs adjusting, please make changes using
+@samp{@code{customize-variable}} and send suggestions to proofgen@@dcs.ed.ac.uk.
+@end defvar
+
+The completion facility uses a library @file{completion.el} which
+usually ships with XEmacs and GNU Emacs, and supplies the
+@code{complete} function.
+
+@c FIXME: edited from default.
+@c NOT DOCSTRING MAGIC: complete
+@deffn Command complete
+Fill out a completion of the word before point. @*
+Point is left at end. Consecutive calls rotate through all possibilities.
+Prefix args:
+@table @kbd
+@item C-u
+leave point at the beginning of the completion, not the end.
+@item a number
+rotate through the possible completions by that amount
+@item 0
+same as -1 (insert previous completion)
+@end table
+See the comments at the top of @samp{completion.el} for more info.
+@end deffn
+
+
+@node Support for tags
+@section Support for tags
+@cindex tags
+
+An Emacs "tags table" is a description of how a multi-file system is
+broken up into files. It lists the names of the component files and the
+names and positions of the functions (or other named subunits) in each
+file. Grouping the related files makes it possible to search or replace
+through all the files with one command. Recording the function names
+and positions makes possible the @kbd{M-.} command which finds the
+definition of a function by looking up which of the files it is in.
+
+Some instantiations of Proof General (currently LEGO and Coq) are
+supplied with external programs (@file{legotags} and @file{coqtags}) for
+making tags tables. For example, invoking @samp{coqtags *.v} produces a
+file @file{TAGS} for all files @samp{*.v} in the current
+directory. Invoking @samp{coqtags `find . -name \*.v`} produces a file
+@file{TAGS} for all files ending in @samp{.v} in the current directory
+structure. Once a tag table has been made for your proof developments,
+you can use the Emacs tags mechanisms to find tags, and complete symbols
+from tags table.
+
+One useful key-binding you might want to make is to set the usual
+tags completion key @kbd{M-tab} to run @code{tag-complete-symbol} to use
+completion from names in the tag table. To set this binding in Proof
+General script buffers, put this code in your @file{.emacs} file:
+@lisp
+(add-hook 'proof-mode-hook
+ (lambda () (local-set-key '(meta tab) 'tag-complete-symbol)))
+@end lisp
+Since this key-binding interferes with a default binding that users may
+already have customized (or may be taken by the window manager), Proof
+General doesn't do this automatically.
+
+Apart from completion, there are several other operations on tags. One
+common one is replacing identifiers across all files using
+@code{tags-query-replace}. For more information on how to use tags,
+@inforef{Tags, ,(xemacs)}.
+
+To use tags for completion at the same time as the completion mechanism
+mentioned already, you can use the command @kbd{M-x add-completions-from-tags-table}.
+
+@c TEXI DOCSTRING MAGIC: add-completions-from-tags-table
+
+
+@deffn Command add-completions-from-tags-table
+Add completions from the current tags table.
+@end deffn
+@node Hints and Tips
+@chapter Hints and Tips
+
+Apart from the packages officially supported in Proof General, many.
+many other features of Emacs are useful when using Proof General, even
+though they need no specific configuration for Proof General. It is
+worth taking a bit of time to explore the Emacs manual to find out about
+them.
+
+Here we provide some hints and tips for a couple of Emacs features which
+users have found valuable with Proof General. Further contributions to
+this chapter are welcomed!
+
+@menu
+* Using file variables::
+* Using abbreviations::
+@end menu
+
+
+@node Using file variables
+@section Using file variables
+@cindex file variables
+
+A very convenient way to customize file-specific variables is to use the
+File Variables (@inforef{File Variables, ,xemacs}). This feature of
+Emacs allows to specify the values to use for certain Emacs variables
+when a file is loaded. Those values are written as a list at the end of
+the file.
+
+For example, in projects involving multiple directories, it is often
+useful to set the variables @code{proof-prog-name} and
+@code{compile-command} for each file. Here is an example for Coq users:
+for the file @file{.../dir/bar/foo.v}, if you want Coq to be started
+with the path @code{.../dir/theories/} added in the libraries path
+(@code{"-I"} option), you can put at the end of @file{foo.v}:
+@lisp
+
+(*
+ Local Variables:
+ coq-prog-name: "coqtop -emacs -full -I ../theories"
+ End:
+*)
+@end lisp
+
+That way the good command is called when the scripting starts in
+@file{foo.v}. Notice that the command argument @code{"-I ../theories"}
+is specific to the file @file{foo.v}, and thus if you set it via the
+configuration tool, you will need to do it each time you load this
+file. On the contrary with this method, Emacs will do this operation
+automatically.
+
+Extending the previous example, if the makefile for @file{foo.v} is
+located in directory @file{.../dir/}, you can add the right compile
+command:
+
+@lisp
+(*
+ Local Variables:
+ coq-prog-name: "coqtop -emacs -full -I ../theories"
+ compile-command: "make -C .. -k bar/foo.vo"
+ End:
+*)
+@end lisp
+
+And then the right call to make will be done if you use the @kbd{M-x
+compile} command. Notice that the lines are commented in order to be
+ignored by the proof assistant. It is possible to use this mechanism for
+any other buffer local variable. @inforef{File Variables,
+,xemacs}.
+
+
+
+@node Using abbreviations
+@section Using abbreviations
+
+A very useful package of Emacs supports automatic expansions of
+abbreviations as you type, @inforef{Abbrevs, ,(xemacs)}.
+
+Proof General has no special support for abbreviations, we just mention
+it here to encourage its use. For example, the proof assistant Coq has
+many command strings that are long, such as ``Reflexivity,''
+``Inductive,'' ``Definition'' and ``Discriminate.'' Here is the
+Coq Proof General author's suggested abbreviations for Coq:
+@lisp
+"assn" 0 "Assumption"
+"ax" 0 "Axiom"
+"coern" 0 "Coercion"
+"cofixpt" 0 "CoFixpt"
+"coindv" 0 "CoInductive"
+"constr" 0 "Constructor"
+"contradn" 0 "Contradiction"
+"defn" 0 "Definition"
+"discr" 0 "Discriminate"
+"extrn" 0 "Extraction"
+"fixpt" 0 "Fixpoint"
+"genz" 0 "Generalize"
+"hypo" 0 "Hypothesis"
+"immed" 0 "Immediate"
+"indn" 0 "Induction"
+"indv" 0 "Inductive"
+"injn" 0 "Injection"
+"intn" 0 "Intuition"
+"invn" 0 "Inversion"
+"pmtr" 0 "Parameter"
+"refly" 0 "Reflexivity"
+"rmk" 0 "Remark"
+"specz" 0 "Specialize"
+"symy" 0 "Symmetry"
+"thm" 0 "Theorem"
+"transpt" 0 "Transparent"
+"transy" 0 "Transitivity"
+"trivial" 0 "Trivial"
+"varl" 0 "Variable"
+@end lisp
+
+The above list was taken from the file that Emacs saves between
+sessions. The easiest way to configure abbreviations is as you write,
+by using the key presses @kbd{C-x a g} (@code{add-global-abbrev}) or
+@kbd{C-x a i g} (@code{inverse-add-global-abbrev}). To enable expansion
+of abbreviations, the @code{Abbrev} minor mode, type @kbd{M-x
+abbrev-mode RET}. See the Emacs manual for more details.
+
+
+
+
+
+
+@node Customizing Proof General
+@chapter Customizing Proof General
+@cindex Customization
+
+
+There are two ways of customizing Proof General: it can be customized
+for a user's preferences using a particular proof assistant, or it can
+be customized by a developer to add support for a new proof assistant.
+The latter kind of customization we call instantiation, or
+@emph{adapting}. See the @i{Adapting Proof General} manual for how to do
+this. Here we cover the user-level customization for Proof General.
+
+There are two kinds of user-level settings in Proof General:
+@itemize @bullet
+@item Settings that apply @emph{globally} to all proof assistants.
+@item those that can be adjusted for each proof assistant @emph{individually}.
+@end itemize
+The first sort have names beginning with @code{proof-}. The second sort
+have names which begin with a symbol corresponding to the proof
+assistant: for example, @code{isa-}, @code{coq-}, etc. The symbol is
+the root of the mode name. @xref{Quick start guide}, for a table of the
+supported modes. To stand for an arbitrary proof assistant, we write
+@code{@emph{PA}-} for these names.
+
+In this chapter we only consider the generic settings: ones which apply
+to all proof assistants (globally or individually). The support for a
+particular proof assistant may provide extra individual customization
+settings not available in other proof assistants. See the chapters
+covering each assistant for details of those settings.
+
+
+@menu
+* Basic options::
+* How to customize::
+* Display customization::
+* User options::
+* Changing faces::
+* Tweaking configuration settings::
+@end menu
+
+@node Basic options
+@section Basic options
+
+Proof General has some common options which you can toggle directly from
+the menu:
+@lisp
+ Proof-General -> Options
+@end lisp
+The effect of changing one of these options will be seen immediately (or
+in the next proof step). The window-control options
+on this menu are described shortly. @xref{Display customization}.
+
+To save the current settings, use the usual Emacs save options command,
+for XEmacs on the menu:
+@lisp
+ Options -> Save Options
+@end lisp
+or @code{M-x customize-save-customized}.
+
+The options on this sub-menu are also available in the complete user
+customization options group for Proof General. For this you need
+to know a little bit about how to customize in Emacs.
+
+
+@node How to customize
+@section How to customize
+@cindex Using Customize
+@cindex Emacs customization library
+
+Proof General uses the Emacs customization library to provide a friendly
+interface. You can access all the customization settings for Proof
+General via the menu:
+@lisp
+ Proof-General -> Customize
+@end lisp
+
+Using the customize facility is straightforward. You can select the
+setting to customize via the menus, or with @code{M-x
+customize-variable}. When you have selected a setting, you are shown a
+buffer with its current value, and facility to edit it. Once you have
+edited it, you can use the special buttons @var{set}, @var{save} and
+@var{done}. You must use one of @var{set} or @var{save} to get any
+effect. The @var{save} button stores the setting in your @file{.emacs}
+file. In XEmacs, the menu item @code{Options -> Save Options} saves all
+settings you have edited.
+
+A technical note. In the customize menus, the variable names mentioned
+later in this chapter may be abbreviated --- the "@code{proof}-" or
+similar prefixes are omitted. Also, some of the option settings may
+have more descriptive names (for example, @var{on} and @var{off}) than
+the low-level lisp values (non-@code{nil}, @code{nil}) which are
+mentioned in this chapter. These features make customize rather more
+friendly than raw lisp.
+
+You can also access the customize settings for Proof General from
+other (non-script) buffers. In XEmacs, the menu path is:
+@lisp
+ Options -> Customize -> Emacs -> External -> Proof General
+@end lisp
+in XEmacs. In GNU Emacs, use the menu:
+@lisp
+ Help -> Customize -> Top-level Customization Group
+@end lisp
+and select the @code{External} and then @code{Proof-General} groups.
+
+The complete set of customization settings will only be available after
+Proof General has been fully loaded. Proof General is fully loaded when
+you visit a script file for the first time, or if you type @kbd{M-x
+load-library RET proof RET}.
+
+For more help with customize, see @inforef{Easy Customization, ,xemacs}.
+
+
+
+@node Display customization
+@section Display customization
+@cindex display customization
+@cindex multiple windows
+@cindex buffer display customization
+@cindex frames
+@cindex multiple frames
+@cindex three-buffer interaction
+
+By default, Proof General displays two buffers during scripting, in a
+split window on the display. One buffer is the script buffer. The
+other buffer is either the goals buffer (e.g. @code{*isabelle-goals*})
+or the response buffer (@code{*isabelle-response*}). Proof General
+switches between these last two automatically.
+
+Proof General allows several ways to customize this default display
+model.
+
+If your screen is large enough, you may prefer to display all three of
+the interaction buffers at once. This is useful, for example, to see
+output from the @code{proof-find-theorems} command at the same time as
+the subgoal list. Set the user option @code{proof-dont-switch-windows} to
+make Proof General keep both the goals and response buffer displayed.
+
+@c TEXI DOCSTRING MAGIC: proof-dont-switch-windows
+@defopt proof-dont-switch-windows
+Whether response and goals buffers have dedicated windows.@*
+If non-nil, Emacs windows displaying messages from the prover will not
+be switchable to display other windows.
+
+This option can help manage your display.
+
+Setting this option triggers a three-buffer mode of interaction where
+the goals buffer and response buffer are both displayed, rather than
+the two-buffer mode where they are switched between. It also prevents
+Emacs automatically resizing windows between proof steps.
+
+If you use several frames (the same Emacs in several windows on the
+screen), you can force a frame to stick to showing the goals or
+response buffer.
+
+For single frame use this option may be inconvenient for
+experienced Emacs users.
+
+The default value is @code{nil}.
+@end defopt
+
+Sometimes during script management, there is no response from the proof
+assistant to some command. In this case you might like the empty
+response window to be hidden so you have more room to see the proof
+script. The setting @code{proof-delete-empty-windows} helps you do this.
+
+@c TEXI DOCSTRING MAGIC: proof-delete-empty-windows
+@defopt proof-delete-empty-windows
+If non-nil, automatically remove windows when they are cleaned.@*
+For example, at the end of a proof the goals buffer window will
+be cleared; if this flag is set it will automatically be removed.
+If you want to fix the sizes of your windows you may want to set this
+variable to @code{'nil'} to avoid windows being deleted automatically.
+If you use multiple frames, only the windows in the currently
+selected frame will be automatically deleted.
+
+The default value is @code{nil}.
+@end defopt
+This option only has an effect when you have set
+@code{proof-dont-switch-windows}.
+
+If you are working on a machine with a window system, you can use Emacs
+to manage several @i{frames} on the display, to keep the goals buffer
+displayed in a fixed place on your screen and in a certain font, for
+example. A convenient way to do this is via the user option
+@c TEXI DOCSTRING MAGIC: proof-multiple-frames-enable
+
+@defopt proof-multiple-frames-enable
+Whether response and goals buffers have separate frames.@*
+If non-nil, Emacs will make separate frames (screen windows) for
+the goals and response buffers, by altering the Emacs variable
+@samp{@code{special-display-regexps}}.
+
+The default value is @code{nil}.
+@end defopt
+Multiple frames work best when @code{proof-delete-empty-windows} is off
+and @code{proof-dont-switch-windows} is on.
+
+
+@node User options
+@section User options
+@c Index entries for each option 'concept'
+@cindex User options
+@cindex Strict read-only
+@cindex Query program name
+@cindex Dedicated windows
+@cindex Remote host
+@cindex Toolbar follow mode
+@cindex Toolbar disabling
+@cindex Toolbar button enablers
+@cindex Proof script indentation
+@cindex Indentation
+@cindex Remote shell
+@cindex Running proof assistant remotely
+@c @cindex formatting proof script
+
+Here is the complete set of user options for Proof General, apart from
+the three display options mentioned above.
+
+User options can be set via the customization system already mentioned,
+via the old-fashioned @code{M-x edit-options} mechanism, or simply by
+adding @code{setq}'s to your @file{.emacs} file. The first approach is
+strongly recommended.
+
+Unless mentioned, all of these settings can be changed dynamically,
+without needing to restart Emacs to see the effect. But you must use
+customize to be sure that Proof General reconfigures itself properly.
+
+@c TEXI DOCSTRING MAGIC: proof-splash-enable
+@defopt proof-splash-enable
+If non-nil, display a splash screen when Proof General is loaded.
+
+The default value is @code{t}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-electric-terminator-enable
+@defopt proof-electric-terminator-enable
+If non-nil, use electric terminator mode.@*
+If electric terminator mode is enabled, pressing a terminator will
+automatically issue @samp{@code{proof-assert-next-command}} for convenience,
+to send the command straight to the proof process. If the command
+you want to send already has a terminator character, you don't
+need to delete the terminator character first. Just press the
+terminator somewhere nearby. Electric!
+
+The default value is @code{nil}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-toolbar-enable
+@defopt proof-toolbar-enable
+If non-nil, display Proof General toolbar for script buffers.@*
+NB: the toolbar is only available with XEmacs and GNU Emacs>=21.
+
+The default value is @code{t}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: PA-x-symbol-enable
+@defopt PA-x-symbol-enable
+Whether to use x-symbol in Proof General for this assistant.@*
+If you activate this variable, whether or not you really get x-symbol
+support depends on whether your proof assistant supports it and
+whether X-Symbol is installed in your Emacs.
+
+The default value is @code{nil}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-output-fontify-enable
+@defopt proof-output-fontify-enable
+Whether to fontify output from the proof assistant.@*
+If non-nil, output from the proof assistant will be highlighted
+in the goals and response buffers.
+(This is providing @code{font-lock-keywords} have been set for the
+buffer modes).
+
+The default value is @code{t}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-strict-read-only
+@defopt proof-strict-read-only
+Whether Proof General is strict about the read-only region in buffers.@*
+If non-nil, an error is given when an attempt is made to edit the
+read-only region. If nil, Proof General is more relaxed (but may give
+you a reprimand!).
+
+If you change @code{proof-strict-read-only} during a session, you must
+use the "Restart" button (or M-x @code{proof-shell-restart}) before
+you can see the effect in buffers.
+
+The default value for @code{proof-strict-read-only} depends on which
+version of Emacs you are using. In GNU Emacs, strict read only is buggy
+when it used in conjunction with font-lock, so it is disabled by default.
+
+The default value is @code{strict}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-toolbar-use-button-enablers
+@defopt proof-toolbar-use-button-enablers
+If non-nil, toolbars buttons may be enabled/disabled automatically.@*
+Toolbar buttons can be automatically enabled/disabled according to
+the context. Set this variable to nil if you don't like this feature
+or if you find it unreliable.
+
+Notes:
+* Toolbar enablers are only available with XEmacs 21 and later.
+* With this variable nil, buttons do nothing when they would
+otherwise be disabled.
+* If you change this variable it will only be noticed when you
+next start Proof General.
+* The default value for XEmacs built for solaris is nil, because
+of unreliabilities with enablers there.
+
+The default value is @code{t}.
+@end defopt
+
+@c This one removed: proof-auto-retract
+
+@c TEXI DOCSTRING MAGIC: proof-query-file-save-when-activating-scripting
+@defopt proof-query-file-save-when-activating-scripting
+If non-nil, query user to save files when activating scripting.
+
+Often, activating scripting or executing the first scripting command
+of a proof script will cause the proof assistant to load some files
+needed by the current proof script. If this option is non-nil, the
+user will be prompted to save some unsaved buffers in case any of
+them corresponds to a file which may be loaded by the proof assistant.
+
+You can turn this option off if the save queries are annoying, but
+be warned that with some proof assistants this may risk processing
+files which are out of date with respect to the loaded buffers!
+
+The default value is @code{t}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: PA-script-indent
+@defopt PA-script-indent
+If non-nil, enable indentation code for proof scripts.
+
+The default value is @code{t}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-one-command-per-line
+@defopt proof-one-command-per-line
+If non-nil, format for newlines after each proof command in a script.@*
+This option is not fully-functional at the moment.
+
+The default value is @code{nil}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-prog-name-ask
+@defopt proof-prog-name-ask
+If non-nil, query user which program to run for the inferior process.
+
+The default value is @code{nil}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-prog-name-guess
+@defopt proof-prog-name-guess
+If non-nil, use @samp{@code{proof-guess-command-line}} to guess @code{proof-prog-name}.@*
+This option is compatible with @code{proof-prog-name-ask}.
+No effect if @code{proof-guess-command-line} is nil.
+
+The default value is @code{nil}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-tidy-response
+@defopt proof-tidy-response
+Non-nil indicates that the response buffer should be cleared often.@*
+The response buffer can be set either to accumulate output, or to
+clear frequently.
+
+With this variable non-nil, the response buffer is kept tidy by
+clearing it often, typically between successive commands (just like the
+goals buffer).
+
+Otherwise the response buffer will accumulate output from the prover.
+
+The default value is @code{t}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-show-debug-messages
+@defopt proof-show-debug-messages
+Whether to display debugging messages in the response buffer.@*
+If non-nil, debugging messages are displayed in the response giving
+information about what Proof General is doing.
+To avoid erasing the messages shortly after they're printed,
+you should set @samp{@code{proof-tidy-response}} to nil.
+
+The default value is @code{nil}.
+@end defopt
+
+
+@c ******* NON-BOOLEANS *******
+
+@c TEXI DOCSTRING MAGIC: proof-follow-mode
+@defopt proof-follow-mode
+Choice of how point moves with script processing commands.@*
+One of the symbols: @code{'locked}, @code{'follow}, @code{'ignore}.
+
+If @code{'locked}, point sticks to the end of the locked region.
+If @code{'follow}, point moves just when needed to display the locked region end.
+If @code{'ignore}, point is never moved after movement commands or on errors.
+
+If you choose @code{'ignore}, you can find the end of the locked using
+@samp{M-x @code{proof-goto-end-of-locked}}.
+
+The default value is @code{locked}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-auto-action-when-deactivating-scripting
+@defopt proof-auto-action-when-deactivating-scripting
+If @code{'retract} or @code{'process}, do that when deactivating scripting.
+
+With this option set to @code{'retract} or @code{'process}, when scripting
+is turned off in a partly processed buffer, the buffer will be
+retracted or processed automatically.
+
+With this option unset (nil), the user is questioned instead.
+
+Proof General insists that only one script buffer can be partly
+processed: all others have to be completely processed or completely
+unprocessed. This is to make sure that handling of multiple files
+makes sense within the proof assistant.
+
+NB: A buffer is completely processed when all non-whitespace is
+locked (coloured blue); a buffer is completely unprocessed when there
+is no locked region.
+
+The default value is @code{nil}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-script-command-separator
+@defopt proof-script-command-separator
+String separating commands in proof scripts.@*
+For example, if a proof assistant prefers one command per line, then
+this string should be set to a newline. Otherwise it should be
+set to a space.
+
+The default value is @code{" "}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: proof-rsh-command
+@defopt proof-rsh-command
+Shell command prefix to run a command on a remote host. @*
+For example,
+@lisp
+ ssh bigjobs
+@end lisp
+Would cause Proof General to issue the command @samp{ssh bigjobs isabelle}
+to start Isabelle remotely on our large compute server called @samp{bigjobs}.
+
+The protocol used should be configured so that no user interaction
+(passwords, or whatever) is required to get going.
+
+The default value is @code{""}.
+@end defopt
+
+
+
+
+@node Changing faces
+@section Changing faces
+
+The fonts and colours that Proof General uses are configurable. If you
+alter faces through the customize menus (or the command @kbd{M-x
+customize-face}), only the particular kind of display in use (colour
+window system, monochrome window system, console, @dots{}) will be
+affected. This means you can keep separate default settings for each
+different display environment where you use Proof General.
+
+As well as the faces listed below, Proof General may use the regular
+@code{font-lock-} faces (eg @code{font-lock-keyword-face},
+@code{font-lock-variable-name-face}, etc) for fontifying the proof
+script or proof assistant output. These can be altered to your taste
+just as easily, but note that changes will affect all other modes
+which use them!
+
+
+@c TEXI DOCSTRING MAGIC: proof-queue-face
+@deffn Face proof-queue-face
+Face for commands in proof script waiting to be processed.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-locked-face
+@deffn Face proof-locked-face
+Face for locked region of proof script (processed commands).
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-error-face
+@deffn Face proof-error-face
+Face for error messages from proof assistant.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-warning-face
+@deffn Face proof-warning-face
+Face for warning messages.@*
+Warning messages can come from proof assistant or from Proof General itself.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-debug-message-face
+@deffn Face proof-debug-message-face
+Face for debugging messages from Proof General.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-declaration-name-face
+@deffn Face proof-declaration-name-face
+Face for declaration names in proof scripts.@*
+Exactly what uses this face depends on the proof assistant.
+@end deffn
+
+
+@c TEXI DOCSTRING MAGIC: proof-tacticals-name-face
+@deffn Face proof-tacticals-name-face
+Face for names of tacticals in proof scripts.@*
+Exactly what uses this face depends on the proof assistant.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: proof-eager-annotation-face
+@deffn Face proof-eager-annotation-face
+Face for important messages from proof assistant.
+@end deffn
+
+@c Maybe this detail of explanation belongs in the internals,
+@c with just a hint here.
+The slightly bizarre name of the last face comes from the idea that
+while large amounts of output are being sent from the prover, some
+messages should be displayed to the user while the bulk of the output is
+hidden. The messages which are displayed may have a special annotation
+to help Proof General recognize them, and this is an "eager" annotation
+in the sense that it should be processed as soon as it is observed by
+Proof General.
+
+
+
+
+@node Tweaking configuration settings
+@section Tweaking configuration settings
+
+This section is a note for advanced users.
+
+Configuration settings are the per-prover customizations of Proof
+General. These are not intended to be adjusted by the user. But
+occasionally you may like to test changes to these settings to improve
+the way Proof General works. You may want to do this when a proof
+assistant has a flexible proof script language in which one can define
+new tactics or even operations, and you want Proof General to recognize
+some of these which the default settings don't mention. So please feel
+free to try adjusting the configuration settings and report to us if you
+find better default values than the ones we have provided.
+
+The configuration settings appear in the customization group
+@code{prover-config}, or via the menu
+@lisp
+ Proof-General -> Internals -> Prover Config
+@end lisp
+
+One basic example of a setting you may like to tweak is:
+
+@c TEXI DOCSTRING MAGIC: proof-assistant-home-page
+@defvar proof-assistant-home-page
+Web address for information on proof assistant.@*
+Used for Proof General's help menu.
+@end defvar
+
+Most of the others are more complicated. For more details of the
+settings, see @i{Adapting Proof General} for full details. To browse
+the settings, you can look through the customization groups
+@code{prover-config}, @code{proof-script} and @code{proof-shell}. The
+group @code{proof-script} contains the configuration variables for
+scripting, and the group @code{proof-shell} contains those for
+interacting with the proof assistant.
+
+Unfortunately, although you can use the customization mechanism to set
+and save these variables, saving them may have no practical effect
+because the default settings are mostly hard-wired into the proof
+assistant code. Ones we expect may need changing appear as proof
+assistant specific configurations. For example,
+@code{proof-assistant-home-page} is set in the LEGO code from the value
+of the customization setting @code{lego-www-home-page}. At present
+there is no easy way to save changes to other configuration variables
+across sessions, other than by editing the source code. (In future
+versions of Proof General, we plan to make all configuration
+settings editable in Customize, by shadowing the settings as
+prover specific ones using the @code{@emph{PA}-} mechanism).
+@c Please contact us if this proves to be a problem for any variable.
+
+
+
+
+@c
+@c CHAPTER: LEGO Proof General
+@c
+@node LEGO Proof General
+@chapter LEGO Proof General
+@cindex LEGO Proof General
+
+LEGO proof script mode is a mode derived from proof script mode for
+editing LEGO scripts. An important convention is that proof script
+buffers @emph{must} start with a module declaration. If the proof script
+buffer's file name is @file{fermat.l}, then it must commence with a
+declaration of the form
+
+@lisp
+Module fermat;
+@end lisp
+
+If, in the development of the module @samp{fermat}, you require material
+from other module e.g., @samp{lib_nat} and @samp{galois}, you need to
+specify this dependency as part of the module declaration:
+
+@lisp
+Module fermat Import lib_nat galois;
+@end lisp
+
+No need to worry too much about efficiency. When you retract back to a
+module declaration to add a new import item, LEGO does not actually
+retract the previously imported modules. Therefore, reasserting the
+extended module declaration really only processes the newly imported
+modules.
+
+Using the LEGO Proof General, you never ever need to use administrative
+LEGO commands such as @samp{Forget}, @samp{ForgetMark}, @samp{KillRef},
+@samp{Load}, @samp{Make}, @samp{Reload} and @samp{Undo} again
+@footnote{And please, don't even think of including those in your LEGO
+proof script!}. You can concentrate on your actual proof developments.
+Script management in Proof General will invoke the appropriate commands
+for you. Proving with LEGO has never been easier.
+
+@menu
+* LEGO specific commands::
+* LEGO tags::
+* LEGO customizations::
+@end menu
+
+
+@node LEGO specific commands
+@section LEGO specific commands
+
+In addition to the commands provided by the generic Proof General (as
+discussed in the previous sections) the LEGO Proof General provides a
+few extensions. In proof scripts, there are some abbreviations for
+common commands:
+
+@kindex C-c C-a C-i
+@kindex C-c C-a C-I
+@kindex C-c C-a C-R
+@table @kbd
+@item C-c C-a C-i
+intros
+@item C-c C-a C-I
+Intros
+@item C-c C-a C-R
+Refine
+@end table
+
+@node LEGO tags
+@section LEGO tags
+
+You
+might want to ask your local system administrator to tag the directories
+@file{lib_Prop}, @file{lib_Type} and @file{lib_TYPE} of the LEGO
+library. See @ref{Support for tags}, for further details on tags.
+
+
+
+@node LEGO customizations
+@section LEGO customizations
+
+We refer to chapter @ref{Customizing Proof General}, for an introduction
+to the customisation mechanism. In addition to customizations at the
+generic level, for LEGO you can also customize:
+
+@c TEXI DOCSTRING MAGIC: lego-tags
+@defopt lego-tags
+The directory of the @var{tags} table for the @var{lego} library
+
+The default value is @code{"/usr/lib/lego/lib_Type/"}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: lego-www-home-page
+@defvar lego-www-home-page
+Lego home page URL.
+@end defvar
+
+@c We don't worry about the following for now. These are too obscure.
+@c lego-indent
+@c lego-test-all-name
+
+@c We also don't document any of the internal variables which have been
+@c set to configure the generic Proof General and which the user should
+@c not tamper with
+
+
+@node Coq Proof General
+@chapter Coq Proof General
+
+Coq Proof General is an instantiation of Proof General for the Coq proof
+assistant. It supports most of the generic features of Proof General,
+but does not have integrated file management or proof-by-pointing yet.
+
+@menu
+* Coq-specific commands::
+* Coq-specific variables::
+* Editing multiple proofs::
+* User-loaded tactics::
+@end menu
+
+
+@node Coq-specific commands
+@section Coq-specific commands
+@kindex C-c C-a C-i
+@kindex C-c C-a C-a
+@kindex C-c C-a C-s
+@kindex C-c C-a C-e
+@kindex C-c C-a C-o
+
+Coq Proof General supplies the following key-bindings:
+@table @kbd
+@item C-c C-a C-i
+Inserts ``Intros ''
+@item C-c C-a C-a
+Inserts ``Apply ''
+@item C-c C-a C-s
+Inserts ``Section ''
+@item C-c C-a C-e
+Inserts ``End <section-name>.'' (this should work well with nested sections).
+@item C-c C-a C-o
+Prompts for a SearchIsos argument.
+@end table
+
+@node Coq-specific variables
+@section Coq-specific variables
+@kindex coq-version-is-V7
+
+The variable
+@lisp
+ coq-version-is-V7
+@end lisp
+is used to force version of Coq, if it is t, then Coq is considered in
+version 7, if it is nil, then Coq is considered in an old version
+(V6). You should not have to set this variable, since ProofGeneral sets
+it by doing the shell command:
+@lisp
+ (concat coq-prog-name "-v")
+@end lisp
+
+If you have problems with different versions of Coq, you can set this
+variable in your config file (before ProofGeneral is loaded).
+
+@node Editing multiple proofs
+@section Editing multiple proofs
+
+Coq allows the user to enter top-level commands while editing a proof
+script. For example, if the user realizes that the current proof will
+fail without an additional axiom, he or she can add that axiom to the
+system while in the middle of the proof. Similarly, the user can
+nest lemmas, beginning a new lemma while in the middle of an earlier
+one, and as the lemmas are proved or their proofs aborted they are
+popped off a stack.
+
+Coq Proof General supports this feature of Coq. Top-level commands
+entered while in a proof are promoted immediately above the outermost
+active proof. If new lemmas are started, Coq Proof General lets the user
+work on the proof of the new lemma, and when the lemma is finished the
+full proof of that lemma is promoted. This is supported to any nesting
+depth that Coq allows.
+
+@b{Special note:} this feature is disabled since version 3.0 because the
+implementation was unreliable. (Patches to improve the code in
+@file{coq.el} are welcome).
+
+@node User-loaded tactics
+@section User-loaded tactics
+
+Another feature that Coq allows is the extension of the grammar of the
+proof assistant by new tactic commands. This feature interacts with the
+proof script management of Proof General, because Proof General needs to
+know when a tactic is called that alters the proof state.
+
+Unfortunately, Coq Proof General does not currently support tactic
+extension in Coq. When the user tries to retract across an extended
+tactic in a script, the algorithm for calculating how far to undo does
+not recognize the extension, and so the proof buffer and Coq are not
+synchronized.
+
+Until this feature is incorporated into Coq Proof General, the user can
+use C-c C-v to resynchronize. For example, if the user does C-c C-u to
+move the point back past one extended tactic, he or she can type C-c C-v
+``Undo 1.'' This then undoes the tactic that Proof General failed to
+recognize.
+
+
+
+
+
+
+
+@c Sorry, there is currently very little specific documentation written for
+@c Coq Proof General. If any Coq user would like to contribute, please send
+@c a message to @code{proofgen@@dcs.ed.ac.uk}.
+
+@c Type @kbd{C-h C-m} to get a list of all Coq specific commands and
+@c browse the customize menus to find out what customization
+@c options there are for Coq.
+
+
+
+@c
+@c CHAPTER: Isabelle Proof General
+@c
+
+@node Isabelle Proof General
+@chapter Isabelle Proof General
+@cindex Isabelle Proof General
+
+Isabelle Proof General supports all major generic features of Proof
+General, including integration with Isabelle's theory loader for proper
+automatic multiple file handling. Only support for tags and
+proof-by-pointing is missing.
+
+It is very important to note that there are actually two different
+versions of Isabelle Proof General: for ``classic'' Isabelle and for
+Isabelle/Isar. An old-style Isabelle theory typically consists of
+@file{.thy} and correspondent @file{.ML} files, while Isabelle/Isar
+theories usually have a new-style @file{.thy} only, which has a slightly
+different syntax and may contain both definitions and proofs.
+
+While Isabelle is able to manage both classic and Isar theories at the
+same time (the theory loader determines the source format
+automatically), Proof General does @b{not} admit to work on both kinds
+of Isabelle source files at the same time! Proof General treats
+@code{isa} and @code{isar} as different instances; there is no way to
+switch modes once Proof General has been started.
+
+The classic version of Isabelle Proof General includes a mode for
+editing theory files taken from David Aspinall's Isamode interface, see
+@uref{http://www.proofgeneral.org/~isamode}. Detailed documentation for
+the theory file mode is included with @code{Isamode}, there are some
+notes on the special functions available and customization settings
+below.
+
+Note that in ``classic'' Isabelle, @file{.thy} files contain definitions
+and declarations for a theory, while @file{.ML} contain proof scripts.
+So most of Proof General's functions only make sense in @file{.ML}
+files, and there is no toolbar and only a short menu for @file{.thy} files.
+
+In Isabelle/Isar, on the other hand, @file{.thy} files contain proofs as
+well as definitions for theories, so scripting takes place there and you
+see the usual toolbar and scripting functions of Proof General.
+
+The default Emacs mode setup of Proof General prefers the @code{isa}
+version over @code{isar}. To load the Isabelle/Isar, you can set the
+environment variable @code{PROOFGENERAL_ASSISTANTS=isar} before starting
+Emacs in order to prevent loading of the classic Isabelle theory file.
+Another way of selecting Isar is to put a special modeline like this:
+@lisp
+ (* -*- isar -*- *)
+@end lisp
+near the top of your Isabelle/Isar @file{.thy} files (or at least, the
+first file you visit). This Emacs feature overrides the default choice
+of mode based on the file extension.
+
+Isabelle provides yet another way to invoke Proof General, including
+additional means to select either version. The standard installation of
+Isabelle makes the @code{isar} version of Proof General its default user
+interface: running plain @code{Isabelle} starts an Emacs session with
+Isabelle/Isar Proof General; giving an option @code{-I false} refers to
+the classic version instead. The defaults may be changed by editing the
+Isabelle settings, see the Isabelle documentation for details.
+
+@menu
+* Classic Isabelle::
+* Isabelle/Isar::
+@end menu
+
+@node Classic Isabelle
+@section Classic Isabelle
+@cindex Classic Isabelle
+
+Proof General for classic Isabelle primarily manages @file{.ML} files
+containing proof scripts. There is a separate mode for editing
+old-style @file{.thy} files, which supports batch mode only.
+
+@menu
+* ML files::
+* Theory files::
+* General commands for Isabelle::
+* Specific commands for Isabelle::
+* Isabelle customizations::
+@end menu
+
+@node ML files
+@subsection ML files
+@cindex ML files (in Isabelle)
+@cindex Isabelle proof scripts
+
+In Isabelle, ML files are used to hold proof scripts, as well as
+definitions of tactics, proof procedures, etc. So ML files are the
+normal domain of Proof General. But there are some things to be wary
+of.
+
+Proof General does not understand full ML syntax, so ideally you should
+only use Proof General's scripting commands on @file{.ML} files which
+contain proof commands (no ML functions, structures, etc).
+
+If you do use files with Proof General which declare functions,
+structures, etc, you should be okay provided your code doesn't include
+non top-level semi-colons (which will confuse Proof General's simplistic
+parser), and provided all value declarations (and other non proof-steps)
+occur outside proofs. This is because within proofs, Proof General
+considers every ML command to be a proof step which is undoable.
+
+For example, do this:
+@lisp
+ structure S = struct
+ val x = 3
+ val y = 4
+ end;
+@end lisp
+instead of this:
+@lisp
+ structure S = struct
+ val x = 3;
+ val y = 4;
+ end
+@end lisp
+In the second case, just the first binding in the structure body will be
+sent to Isabelle and Proof General will wait indefinitely.
+
+And do this:
+@lisp
+ val intros1 = REPEAT (resolve_tac [impI,allI] 1);
+ Goal "Q(x) --> (ALL x. P(x) --> P(x))";
+ br impI 1;
+ by intros1;
+ ba 1;
+ qed "mythm";
+@end lisp
+instead of this:
+@lisp
+ Goal "Q(x) --> (ALL x. P(x) --> P(x))";
+ br impI 1;
+ val intros1 = REPEAT (resolve_tac [impI,allI] 1);
+ by intros1;
+ ba 1;
+ qed "mythm";
+@end lisp
+In the last case, when you undo, Proof General wrongly considers the
+@code{val} declaration to be a proof step, and it will issue an
+@code{undo} to Isabelle to undo it. This leads to a loss of
+synchronization. To fix things when this happens, simply retract to
+some point before the @code{Goal} command and rearrange your script.
+
+Having ML as a top-level, Isabelle even lets you redefine the entire
+proof command language, which will certainly confuse Proof General.
+Stick to using the standard functions, tactics, and tacticals and there
+should be no problems. (In fact, there should be no problems provided
+you don't use your own "goal" or "qed" forms, which Proof General
+recognizes. As the example above shows, Proof General makes no
+attempt to recognize arbitrary tactic applications).
+
+
+@node Theory files
+@subsection Theory files
+@cindex Theory files (in Isabelle)
+@cindex ML files (in Isabelle)
+
+As well as locking ML files, Isabelle Proof General locks theory files
+when they are loaded. Theory files are always completely locked or
+completely unlocked, because they are processed atomically.
+
+Proof General tries to load the theory file for a @file{.ML} file
+automatically before you start scripting. This relies on new support
+especially for Proof General built into Isabelle99's theory loader.
+
+However, because scripting cannot begin until the theory is loaded, and
+it should not begin if an error occurs during loading the theory, Proof
+General @strong{blocks} waiting for the theory loader to finish. If you
+have a theory file which takes a long time to load, you might want to
+load it directly, from the @file{.thy} buffer. Extra commands are
+provided in theory mode for this:
+
+@c FIXME: should say something about this:
+@c This can cause confusion in the theory loader later,
+@c especially with @code{update()}. To be safe, try to use just the Proof
+@c General interface, and report any repeatable problems to
+@c @code{isabelle@dcs.ed.ac.uk}.
+
+@c Compared to Isamode's theory editing mode, some of the functions and key
+@c bindings for interacting with Isabelle have been removed, and two new
+@c functions are available.
+
+The key @kbd{C-c C-b} (@code{isa-process-thy-file}) will cause Isabelle
+to read the theory file being edited. This causes the file and all its
+children (both theory and ML files) to be read. Any top-level ML file
+associated with this theory file is @emph{not} read, in contrast
+with the @code{use_thy} command of Isabelle.
+
+The key @kbd{C-c C-u} (@code{isa-retract-thy-file}) will retract
+(unlock) the theory file being edited. This unlocks the file and all
+its children (theory and ML files); no changes occur in Isabelle itself.
+
+@c TEXI DOCSTRING MAGIC: isa-process-thy-file
+@deffn Command isa-process-thy-file file
+Process the theory file @var{file}. If interactive, use @code{buffer-file-name}.
+@end deffn
+
+@c TEXI DOCSTRING MAGIC: isa-retract-thy-file
+@deffn Command isa-retract-thy-file file
+Retract the theory file @var{file}. If interactive, use @code{buffer-file-name}.@*
+To prevent inconsistencies, scripting is deactivated before doing this.
+So if scripting is active in an ML file which is not completely processed,
+you will be asked to retract the file or process the remainder of it.
+@end deffn
+
+
+@node General commands for Isabelle
+@subsection General commands for Isabelle
+
+This section has some notes on the instantiation of the generic part of
+Proof General for Isabelle. (The generic part of Proof General applies
+to all proof assistants supported, and is described in detail in the
+rest of this manual).
+
+@strong{Find theorems}. This toolbar/menu command invokes a special
+version of @code{thms_containing}. To give several constants, separate
+their names with commas.
+
+@node Specific commands for Isabelle
+@subsection Specific commands for Isabelle
+
+This section mentions some commands which are added specifically
+to the Isabelle Proof General instance.
+
+@cindex Switching to theory files
+@kindex C-c C-o
+
+In Isabelle proof script mode, @kbd{C-c C-o} (@code{thy-find-other-file})
+finds and switches to the associated theory file, that is, the file with
+the same base name but extension @file{.thy} swapped for @file{.ML}.
+
+The same function (and key-binding) switches back to an ML file from the
+theory file.
+
+
+@c TEXI DOCSTRING MAGIC: thy-find-other-file
+@deffn Command thy-find-other-file &optional samewindow
+Find associated .ML or .thy file.@*
+Finds and switch to the associated ML file (when editing a theory file)
+or theory file (when editing an ML file).
+If @var{samewindow} is non-nil (interactively, with an optional argument)
+the other file replaces the one in the current window.
+@end deffn
+
+
+
+
+@node Isabelle customizations
+@subsection Isabelle customizations
+
+Here are some of the user options specific to Isabelle. You can set
+these as usual with the customization mechanism.
+
+@c TEXI DOCSTRING MAGIC: isabelle-web-page
+@defvar isabelle-web-page
+URL of web page for Isabelle.
+@end defvar
+
+
+@c @unnumberedsubsec Theory file editing customization
+
+@c TEXI DOCSTRING MAGIC: thy-use-sml-mode
+@defopt thy-use-sml-mode
+If non-nil, invoke @code{sml-mode} inside "ML" section of theory files.@*
+This option is left-over from Isamode. Really, it would be more
+useful if the script editing mode of Proof General itself could be based
+on @code{sml-mode}, but at the moment there is no way to do this.
+
+The default value is @code{nil}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: thy-indent-level
+@defopt thy-indent-level
+Indentation level for Isabelle theory files. An integer.
+
+The default value is @code{2}.
+@end defopt
+
+@c TEXI DOCSTRING MAGIC: thy-sections
+@defvar thy-sections
+Names of theory file sections and their templates.@*
+Each item in the list is a pair of a section name and a template.
+A template is either a string to insert or a function. Useful functions are:
+@lisp
+ @code{thy-insert-header}, @code{thy-insert-class}, @code{thy-insert-default-sort},
+ @code{thy-insert-const}, @code{thy-insert-rule}.
+@end lisp
+The nil template does nothing.
+You can add extra sections to theory files by extending this variable.
+@end defvar
+
+@c TEXI DOCSTRING MAGIC: thy-template
+@defvar thy-template
+Template for theory files.@*
+Contains a default selection of sections in a traditional order.
+You can use the following format characters:
+
+@samp{%t} --- replaced by theory name.
+
+@samp{%p} --- replaced by names of parents, separated by @samp{+} characters.
+@end defvar
+
+@c ideal for above:
+@c @defopt thy-template
+@c Template for theory files.
+@c Contains a default selection of sections in a traditional order.
+@c You can use the following format characters:
+@c @code{%t} -- replaced by theory name
+@c @code{%p} -- replaced by names of parents, separated by @code{+}'s
+@c @end defopt
+
+
+@node Isabelle/Isar
+@section Isabelle/Isar
+@cindex Isabelle/Isar
+
+Proof General for Isabelle/Isar manages new-style @file{.thy} files,
+which may contain both definitions and proofs (human readable proof
+texts as well as traditional scripts following the Isar syntax).
+
+The syntax of Isabelle/Isar input is technically simple, enabling Proof
+General to provide reliable control over incremental execution of the
+text. Thus it is very hard to let Proof General lose synchronization
+with the Isabelle/Isar process. The caveats of @file{.ML} files
+discussed for the classic Isabelle version (@pxref{Classic Isabelle}) do
+@b{not} apply here.
+
+@menu
+* General commands for Isabelle/Isar::
+* Specific commands for Isabelle/Isar::
+@end menu
+
+@node General commands for Isabelle/Isar
+@subsection General commands for Isabelle/Isar
+
+@strong{Find theorems}. This toolbar/menu command invokes
+@code{thms_containing}. Several term arguments may be given, separated
+by white space as usual in Isar.
+
+@node Specific commands for Isabelle/Isar
+@subsection Specific commands for Isabelle/Isar
+@kindex C-c C-a h A
+@kindex C-c C-a h C
+@kindex C-c C-a h S
+@kindex C-c C-a h T
+@kindex C-c C-a h a
+@kindex C-c C-a h b
+@kindex C-c C-a h c
+@kindex C-c C-a h f
+@kindex C-c C-a h i
+@kindex C-c C-a h m
+@kindex C-c C-a h o
+@kindex C-c C-a h t
+
+The Isabelle/Isar instance of Proof General supplies several specific
+help key bindings; these functions are offered within the prover help
+menu as well.
+
+@table @kbd
+@item C-c C-a h A
+Shows available antiquotation commands and options.
+@item C-c C-a h C
+Shows the current Classical Reasoner context.
+@item C-c C-a h S
+Shows the current Simplifier context.
+@item C-c C-a h T
+Shows the current set of transitivity rules (for calculational reasoning).
+@item C-c C-a h a
+Shows attributes available in current theory context.
+@item C-c C-a h b
+Shows all local term bindings.
+@item C-c C-a h c
+Shows all named local contexts (cases).
+@item C-c C-a h f
+Shows all local facts.
+@item C-c C-a h i
+Shows inner syntax of the current theory context (for types and terms).
+@item C-c C-a h m
+Shows proof methods available in current theory context.
+@item C-c C-a h o
+Shows all available commands of Isabelle/Isar's outer syntax.
+@item C-c C-a h t
+Shows theorems stored in the current theory node.
+@end table
+
+@kindex C-c C-a b
+@kindex C-c C-a u
+@kindex C-c C-a l
+
+The following shortcuts insert control sequences into the text,
+modifying the appearance of individual symbols (single letters,
+mathematical entities etc.); the X-Symbol package will provide immediate
+visual feedback.
+
+@table @kbd
+@item C-c C-a b
+Inserts "\<^bold>"
+@item C-c C-a u
+Inserts "\<^sup>"
+@item C-c C-a l
+Inserts "\<^sub>"
+@end table
+
+Command termination via `@code{;}' is an optional feature of Isar
+syntax. Neither Isabelle/Isar nor Proof General require semicolons to
+do their job. The following command allows to get rid of command
+terminators in existing texts.
+
+@c TEXI DOCSTRING MAGIC: isar-strip-terminators
+@deffn Command isar-strip-terminators
+Remove explicit Isabelle/Isar command terminators @samp{;} from the buffer.
+@end deffn
+
+@c
+@c CHAPTER: HOL Proof General
+@c
+
+@node HOL Proof General
+@chapter HOL Proof General
+@cindex HOL Proof General
+
+HOL Proof General is a "technology demonstration" of Proof General for
+HOL98. This means that only a basic instantiation has been provided,
+and that it is not yet supported as a maintained instantiation of Proof
+General.
+
+HOL Proof General has basic script management support, with a little bit
+of decoration of scripts and output. It does not rely on a modified
+version of HOL, so the pattern matching may be fragile in certain cases.
+Support for multiple files deduces dependencies automatically, so there
+is no interaction with the HOL make system yet.
+
+See the @file{example.sml} file for a demonstration proof script
+which works with Proof General.
+
+Note that HOL proof scripts often use batch-oriented single step tactic
+proofs, but Proof General does not (yet) offer an easy way to edit these
+kind of proofs. They will replay simply as a single step proof and you
+will need to convert from the interactive to batch form as usual if you
+wish to obtain batch proofs. Also note that Proof General does not
+contain an SML parser, so there can be problems if you write complex ML
+in proof scripts. @xref{ML files}, for the same issue with Isabelle.
+
+HOL Proof General may work with variants of HOL other than HOL98, but is
+untested. Probably a few of the settings would need to be changed in a
+simple way, to cope with small differences in output between the
+systems. (Please let us know if you modify the HOL98 version for
+another variant of HOL).
+
+Hopefully somebody from the HOL community is willing to adopt HOL Proof
+General and support and improve it. Please volunteer! It needn't be a
+large or heavy committment.
+
+
+
+@c
+@c
+@c APPENDIX: Obtaining and Installing
+@c
+@c
+@node Obtaining and Installing
+@appendix Obtaining and Installing
+
+Proof General has its own
+@uref{http://www.proofgeneral.org,home page} hosted at
+Edinburgh. Visit this page for the latest news!
+
+@menu
+* Obtaining Proof General::
+* Installing Proof General from tarball::
+* Installing Proof General from RPM package::
+* Setting the names of binaries::
+* Notes for syssies::
+@end menu
+
+
+@node Obtaining Proof General
+@section Obtaining Proof General
+
+You can obtain Proof General from the URL
+@example
+@uref{http://www.proofgeneral.org}.
+@end example
+
+The distribution is available in three forms
+@itemize @bullet
+@item A source tarball, @*
+@uref{http://www.proofgeneral.org/ProofGeneral-devel-latest.tar.gz}
+@item A Linux RPM package (for any architecture), @*
+@uref{http://www.proofgeneral.org/ProofGeneral-latest.noarch.rpm}
+@item A developer's tarball, @*
+@uref{http://www.proofgeneral.org/ProofGeneral-devel-latest.tar.gz}
+@end itemize
+
+Both the source tarball and the RPM package include the generic elisp
+code, code for LEGO, Coq, and Isabelle, installation instructions
+(reproduced below) and this documentation.
+
+The developer's tarball contains our full source tree, including all of
+the elisp and documentation, along with our low-level list of things to
+do, sources for the images, some make files used to generate the release
+itself from our CVS repository, and some test files. Developers
+interested in accessing our CVS repository directly should contact
+@code{proofgen@@dcs.ed.ac.uk}.
+
+@c was Installing Proof General from @file{.tar.gz}
+@node Installing Proof General from tarball
+@section Installing Proof General from tarball
+
+Copy the distribution to some directory @var{mydir}.
+Unpack it there. For example:
+@example
+# cd @var{mydir}
+# gunzip ProofGeneral-@var{version}.tar.gz
+# tar -xpf ProofGeneral-@var{version}.tar
+@end example
+If you downloaded the version called @var{latest}, you'll find it
+unpacks to a numeric version number.
+
+Proof General will now be in some subdirectory of @var{mydir}. The name
+of the subdirectory will depend on the version number of Proof General.
+For example, it might be @file{ProofGeneral-2.0}. It's convenient to
+link it to a fixed name:
+@example
+# ln -sf ProofGeneral-2.0 ProofGeneral
+@end example
+Now put this line in your @file{.emacs} file:
+@lisp
+ (load-file "@var{mydir}/ProofGeneral/generic/proof-site.el")
+@end lisp
+
+@node Installing Proof General from RPM package
+@section Installing Proof General from RPM package
+
+To install an RPM package you need to be root. Then type
+@example
+# rpm -Uvh ProofGeneral-latest.noarch.rpm
+@end example
+
+Now add the line:
+@lisp
+ (load-file "/usr/share/emacs/ProofGeneral/generic/proof-site.el")
+@end lisp
+to your @file{.emacs} or the site-wide initialisation file
+@file{site-start.el}.
+
+@node Setting the names of binaries
+@section Setting the names of binaries
+
+The @code{load-file} command you have added will load @file{proof-site}
+which sets the Emacs load path for Proof General and add auto-loads and
+modes for the supported assistants.
+
+The default names for proof assistant binaries may work on your system.
+If not, you will need to set the appropriate variables. The easiest way
+to do this (and most other customization of Proof General) is via the
+Customize mechanism, see the menu item:
+@example
+ Proof-General -> Customize -> @var{Name of Assistant} -> Prog Name
+@end example
+The Proof-General menu is available from script buffers after Proof
+General is loaded. To load it manually, type
+@lisp
+ M-x load-library RET proof RET
+@end lisp
+
+If you do not want to use customize, simply add a line like this:
+@lisp
+ (setq coq-prog-name "/usr/bin/coqtop -emacs")
+@end lisp
+to your @file{.emacs} file.
+
+
+
+@node Notes for syssies
+@section Notes for syssies
+
+Here are some more notes for installing Proof General in more complex
+ways. Only attempt things in this section if you really understand what
+you're doing.
+
+@unnumberedsubsec Byte compilation
+
+Compilation of the Emacs lisp files improves efficiency but can
+sometimes cause compatibility problems, especially if you use more than
+one version of Emacs with the same @code{.elc} files. Furthermore, we
+develop Proof General with source files so may miss problems with the
+byte compiled versions. If you discover problems using the
+byte-compiled @code{.elc} files which aren't present using the source
+@code{.el} files, please report them to us.
+
+You can compile Proof General by typing @code{make} in the directory
+where you installed it.
+
+
+@unnumberedsubsec Site-wide installation
+
+If you are installing Proof General site-wide, you can put the
+components in the standard directories of the filesystem if you prefer,
+providing the variables in @file{proof-site.el} are adjusted
+accordingly (see @i{Proof General site configuration} in
+@i{Adapting Proof General} for more details). Make sure that
+the @file{generic/} and assistant-specific elisp files are kept in
+subdirectories (@file{coq/}, @file{isa.}, @file{lego.}) of
+@code{proof-home-directory} so that the autoload directory calculations
+are correct.
+
+To prevent every user needing to edit their own @file{.emacs} files, you
+can put the @code{load-file} command to load @file{proof-site.el} into
+@file{site-start.el} or similar. Consult the Emacs documentation for more
+details if you don't know where to find this file.
+
+@unnumberedsubsec Removing support for unwanted provers
+
+You cannot run more than one instance of Proof General at a time: so if
+you're using Coq, visiting an @file{.ML} file will not load Isabelle
+Proof General, and the buffer remains in fundamental mode. If there are
+some assistants supported that you never want to use, you can adjust the
+variable @code{proof-assistants} in @file{proof-site.el} to remove the
+extra autoloads. This is advisable in case the extensions clash with
+other Emacs modes, for example @code{sml-mode} for @file{.ML} files, or
+Verilog mode for @file{.v} files.
+
+See @i{Proof General site configuration} in @i{Adapting Proof General},
+to find out how to disable support for provers you don't use.
+
+@c Via the Customize mechanism, see the menu:
+@c @example
+@c Options -> Customize -> Emacs -> External -> Proof General
+@c @end example
+@c or, after loading Proof General, in a proof script buffer
+@c @example
+@c Proof-General -> Customize
+@c @end example
+
+
+
+@c
+@c
+@c APPENDIX: Known bugs and workarounds
+@c
+@c
+@node Known bugs and workarounds
+@appendix Known bugs and workarounds
+
+We mention a few of the known problems with the generic portion of Proof
+General here. This is not a description of all bugs/problems known.
+Please consult the file
+@uref{http://www.proofgeneral.org/ProofGeneral/BUGS,@file{BUGS}} in the
+distribution for more detailed and up-to-date information. @*
+
+If you discover a problem which isn't mentioned in @file{BUGS}, please
+let us know by sending a note to @code{proofgen@@dcs.ed.ac.uk}.
+
+@menu
+* Bugs at the generic level::
+@end menu
+
+@node Bugs at the generic level
+@section Bugs at the generic level
+
+@subsection Undo in XEmacs
+
+When @code{proof-strict-read-only} is non-nil, ordinary undo in the
+script buffer can edit the "uneditable region" in XEmacs. This doesn't
+happen in GNU Emacs. Test case: Insert some nonsense text after the
+locked region. Kill the line. Process to the next command. Press
+@kbd{C-x u}, nonsense text appears in locked region.
+
+@strong{Workaround:} be careful with undo.
+
+@subsection Font locking and read-only in GNU Emacs
+
+When @code{proof-strict-read-only} is set and font lock is switched on,
+spurious "Region read only" errors are given which break font lock.
+
+@strong{Workaround:} turn off @code{proof-strict-read-only}, font lock,
+or for the best of all possible worlds, switch to XEmacs.
+
+
+@subsection Pressing keyboard quit @kbd{C-g}
+
+Using @kbd{C-g} can leave script management in a mess. The code is not
+properly protected from Emacs interrupts.
+
+@strong{Workaround:} Don't type @kbd{C-g} while script management is
+processing. If you do, use @code{proof-shell-restart} to restart
+the system.
+
+@c da: Removed 11.12.98: since PG handles this gracefully now,
+@c I no longer consider it a bug really.
+@c @subsection One prover at a time
+@c You can't use more than one proof assistant at a time in the same Emacs
+@c session. Attempting to load Proof General for a second prover will
+@c fail, leaving a buffer in fundamental mode instead of the Proof General
+@c mode for proof scripts.
+
+@c @strong{Workaround:} stick to one prover per Emacs session, make sure
+@c that the @code{proof-assistants} variable only enables Proof General
+@c for the provers you need.
+
+
+@node References
+@unnumbered References
+
+A short overview of the Proof General system is described in the
+note:
+@itemize @bullet
+@item @b{[Asp00]}
+David Aspinall.
+@i{Proof General: A Generic Tool for Proof Development}.
+Tools and Algorithms for the Construction and
+Analysis of Systems, Proc TACAS 2000. LNCS 1785.
+@end itemize
+
+Script management as used in Proof General is described in the paper:
+
+@itemize @bullet
+@item @b{[BT98]}
+Yves Bertot and Laurent Th@'ery. @i{A generic approach to building
+user interfaces for theorem provers}. Journal of
+Symbolic Computation, 25(7), pp. 161-194, February 1998.
+@end itemize
+
+Proof General has support for proof by pointing, as described in the
+document:
+
+@itemize @bullet
+@item @b{[BKS97]}
+Yves Bertot, Thomas Kleymann-Schreiber and Dilip Sequeira. @i{Implementing
+Proof by Pointing without a
+Structure Editor}. LFCS Technical Report ECS-LFCS-97-368. Also published as Rapport de recherche de
+l'INRIA Sophia Antipolis RR-3286
+@end itemize
+
+
+
+
+@node Function Index
+@unnumbered Function and Command Index
+@printindex fn
+
+@node Variable Index
+@unnumbered Variable and User Option Index
+@printindex vr
+
+@node Keystroke Index
+@unnumbered Keystroke Index
+@printindex ky
+
+@node Concept Index
+@unnumbered Concept Index
+@printindex cp
+
+@page
+@contents
+@bye
+
+
diff --git a/doc/README.doc b/doc/README.doc
new file mode 100644
index 00000000..e350baea
--- /dev/null
+++ b/doc/README.doc
@@ -0,0 +1,38 @@
+Proof General Documentation
+===========================
+
+The distribution may include pre-built documentation for
+your convenience. Otherwise you will need to run
+
+ make info
+ make dvi
+ make pdf
+ make html
+
+according to what format you'd like. Everything is generated
+from the master Texinfo files ProofGeneral.texi and PG-adapting.texi,
+so you'll need the proper tools for conversion. Check Makefile.doc
+for details.
+
+Front Image for Manual
+----------------------
+If you want a front image on the printed dvi/gs manuals, you need to
+have the ProofGeneral.eps file in this directory. You can download a
+compressed version from
+
+http://www.proofgeneral.org/ProofGeneral/doc/ProofGeneral.eps.gz
+
+This file is not included with the distribution because it is rather
+large (1.6M).
+
+Instead of downloading, you may be able to generate an alternative eps
+from the included ProofGeneral.jpg file using an image manipulation
+program such as gimp or Imagemagick. This will give you a slightly
+different (and degraded) image compared to the distributed one
+mentioned above.
+
+Running "made dvi" will adjust the Texinfo file to make the front
+page blank if there is no ProofGeneral.eps file available.
+
+David Aspinall.
+August 2000.
diff --git a/doc/dir b/doc/dir
new file mode 100644
index 00000000..134485ff
--- /dev/null
+++ b/doc/dir
@@ -0,0 +1,19 @@
+$Id$
+This is the file .../info/dir, which contains the topmost node of the
+Info hierarchy. The first time you invoke Info you start off
+looking at that node, which is (dir)Top.
+
+File: dir Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "?" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs topic, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Theorem proving
+* Proof General: (ProofGeneral). Organize your proofs with Emacs!
diff --git a/doc/docstring-magic.el b/doc/docstring-magic.el
new file mode 100644
index 00000000..a3328b20
--- /dev/null
+++ b/doc/docstring-magic.el
@@ -0,0 +1,67 @@
+;; doc/docstring-magic.el -- hack for using texi-docstring-magic.
+;;
+;; Copyright (C) 1998 LFCS Edinburgh.
+;; Author: David Aspinall
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; Ensure that non-compiled versions of everything are loaded.
+;;
+;; $Id$
+;;
+(setq load-path
+ (append '("../generic/") load-path))
+(load "proof-site.el")
+(require 'proof-autoloads)
+(require 'proof-compat)
+(require 'proof-utils)
+
+;; FIXME: Loading several prover files at once is a bit of a problem
+;; with new config mechanism.
+;; Could abstract more code in proof-site.el to avoid duplication here.
+(let ((assistants (mapcar (function car) proof-assistant-table)))
+ ; assume not customized
+ (while assistants
+ (let*
+ ((assistant (car assistants)) ; compiler bogus warning here
+ (nameregexp
+ (or
+ (cdr-safe
+ (assoc assistant
+ proof-assistant-table))
+ (error "proof-site: symbol " (symbol-name assistant)
+ "is not in proof-assistant-table")))
+ (assistant-name (car nameregexp))
+ (sname (symbol-name assistant))
+ (elisp-file sname))
+ (proof-ready-for-assistant assistant-name assistant)
+ ;; Must load proof-config each time to define proof assistant
+ ;; specific variables
+ (setq features (delete 'proof-config features))
+ (load "proof-config.el")
+ (load-library elisp-file)
+ (setq assistants (cdr assistants)))))
+
+;; Now a fake proof assistant to document the automatically
+;; specific variables
+(proof-ready-for-assistant "PROOF ASSISTANT" 'PA)
+(setq features (delete 'proof-config features))
+(load "proof-config.el")
+
+
+;; These next few are autoloaded usually
+(load "thy-mode.el")
+(load "proof-menu.el")
+(load "proof-toolbar.el")
+(load "proof-script.el")
+(load "proof-shell.el")
+
+;; A couple of comint symbols are mentioned in the docs
+(require 'comint)
+;; Also completion
+(require 'completion)
+
+;; Set some symbols to make markup happen
+(setq sml-mode 'markup-hack)
+(setq func-menu 'markup-hack)
+
+(load "texi-docstring-magic.el")
diff --git a/doc/localdir b/doc/localdir
new file mode 100644
index 00000000..2b366965
--- /dev/null
+++ b/doc/localdir
@@ -0,0 +1,3 @@
+Theorem proving
+* Proof General: (ProofGeneral). Organize your proofs with Emacs!
+* Adapting Proof General: (PG-adapting). How to adapt Proof General for new provers
diff --git a/etc/ProofGeneral.menu b/etc/ProofGeneral.menu
new file mode 100644
index 00000000..5f1022cd
--- /dev/null
+++ b/etc/ProofGeneral.menu
@@ -0,0 +1,7 @@
+?package(ProofGeneral):\
+ needs=X11\
+ section="Applications/Sciences/Computer science"\
+ title="Proof General"\
+ longtitle="A generic interface for interactive theorem provers"\
+ command="/usr/bin/proofgeneral"\
+ icon="pgicon.png"
diff --git a/etc/ProofGeneral.spec b/etc/ProofGeneral.spec
new file mode 100644
index 00000000..89605785
--- /dev/null
+++ b/etc/ProofGeneral.spec
@@ -0,0 +1,110 @@
+Summary: Proof General, Emacs interface for Proof Assistants
+Name: ProofGeneral
+Version: 3.4pre020214
+Release: 1
+Group: Applications/Editors/Emacs
+Copyright: LFCS, University of Edinburgh
+Url: http://www.proofgeneral.org/
+Packager: David Aspinall <da@dcs.ed.ac.uk>
+Source: http://www.proofgeneral.org/ProofGeneral-3.4pre020214.tar.gz
+BuildRoot: /tmp/ProofGeneral-root
+PreReq: /sbin/install-info
+Prefixes: /usr/share/emacs /usr/bin /usr/info
+BuildArchitectures: noarch
+
+%description
+Proof General is a generic Emacs interface for proof assistants,
+suitable for use by pacifists and Emacs militants alike.
+It is supplied ready-customized for LEGO, Coq, and Isabelle.
+You can adapt Proof General to other proof assistants if you know a
+little bit of Emacs Lisp.
+
+To use Proof General, use the command `proofgeneral', which launches
+XEmacs (or Emacs) for you, or add the line:
+
+ (load-file "/usr/share/emacs/ProofGeneral/generic/proof-site.el")
+
+to your .emacs file so Proof General is available whenever
+you run Emacs.
+
+%changelog
+* Fri May 4 2001 David Aspinall <da@dcs.ed.ac.uk>
+- Changelog in CVS now; official spec file developed with source.
+
+%prep
+%setup
+
+%build
+[ -n "${RPM_BUILD_ROOT}" ] && rm -rf ${RPM_BUILD_ROOT}
+
+%install
+mkdir -p ${RPM_BUILD_ROOT}/usr/share/emacs/ProofGeneral
+
+# Put binaries in proper place
+mkdir -p ${RPM_BUILD_ROOT}/usr/bin
+mv bin/proofgeneral lego/legotags coq/coqtags ${RPM_BUILD_ROOT}/usr/bin
+
+# Put info file in proper place, compress it.
+mkdir -p ${RPM_BUILD_ROOT}/usr/info
+mv doc/ProofGeneral.info doc/ProofGeneral.info-* ${RPM_BUILD_ROOT}/usr/info
+mv doc/PG-adapting.info doc/PG-adapting.info-* ${RPM_BUILD_ROOT}/usr/info
+gzip ${RPM_BUILD_ROOT}/usr/info/ProofGeneral.info ${RPM_BUILD_ROOT}/usr/info/ProofGeneral.info-*
+gzip ${RPM_BUILD_ROOT}/usr/info/PG-adapting.info ${RPM_BUILD_ROOT}/usr/info/PG-adapting.info-*
+# Remove duff bits
+rm -f doc/dir doc/localdir
+
+# Put icons and menu entry into suitable place (at least for Mandrake)
+mkdir -p ${RPM_BUILD_ROOT}/usr/share/icons/mini
+cp images/pgmini.xpm ${RPM_BUILD_ROOT}/usr/share/icons/mini
+cp images/pgicon.png ${RPM_BUILD_ROOT}/usr/share/icons
+mkdir -p ${RPM_BUILD_ROOT}/usr/lib/menu
+mv etc/ProofGeneral.menu ${RPM_BUILD_ROOT}/usr/lib/menu/ProofGeneral
+
+cp -pr phox acl2 twelf coq lego isa isar hol98 images generic ${RPM_BUILD_ROOT}/usr/share/emacs/ProofGeneral
+
+%clean
+if [ "X" != "${RPM_BUILD_ROOT}X" ]; then
+ rm -rf $RPM_BUILD_ROOT
+fi
+
+%post
+/sbin/install-info /usr/info/ProofGeneral.info.* /usr/info/dir
+/sbin/install-info /usr/info/PG-adapting.info.* /usr/info/dir
+
+%preun
+/sbin/install-info --delete /usr/info/ProofGeneral.info.* /usr/info/dir
+/sbin/install-info --delete /usr/info/PG-adapting.info.* /usr/info/dir
+
+%files
+%attr(-,root,root) %doc AUTHORS BUGS CHANGES COPYING INSTALL README README.devel REGISTER doc/* */README
+%attr(-,root,root) /usr/info/ProofGeneral.info.*
+%attr(-,root,root) /usr/info/ProofGeneral.info-*.*
+%attr(-,root,root) /usr/info/PG-adapting.info.*
+%attr(-,root,root) /usr/info/PG-adapting.info-*.*
+%attr(-,root,root) /usr/bin/proofgeneral
+%attr(-,root,root) /usr/bin/coqtags
+%attr(-,root,root) /usr/bin/legotags
+%attr(-,root,root) /usr/share/icons/pgicon.png
+%attr(-,root,root) /usr/share/icons/mini/pgmini.xpm
+%attr(-,root,root) /usr/lib/menu/ProofGeneral
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral/images
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral/generic
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral/coq
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral/lego
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral/isa
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral/isar
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral/hol98
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral/phox
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral/acl2
+%attr(0755,root,root) %dir /usr/share/emacs/ProofGeneral/twelf
+%attr(-,root,root) /usr/share/emacs/ProofGeneral/images/*
+%attr(-,root,root) /usr/share/emacs/ProofGeneral/generic/*
+%attr(-,root,root) /usr/share/emacs/ProofGeneral/coq/*
+%attr(-,root,root) /usr/share/emacs/ProofGeneral/lego/*
+%attr(-,root,root) /usr/share/emacs/ProofGeneral/isa/*
+%attr(-,root,root) /usr/share/emacs/ProofGeneral/isar/*
+%attr(-,root,root) /usr/share/emacs/ProofGeneral/hol98/*
+%attr(-,root,root) /usr/share/emacs/ProofGeneral/phox/*
+%attr(-,root,root) /usr/share/emacs/ProofGeneral/acl2/*
+%attr(-,root,root) /usr/share/emacs/ProofGeneral/twelf/*
diff --git a/etc/README b/etc/README
new file mode 100644
index 00000000..2e88cdf6
--- /dev/null
+++ b/etc/README
@@ -0,0 +1,31 @@
+Files in this directory (not all part of standard distribution - some only in devel)
+=====================================================================================
+
+ProofGeneral.spec For building the Proof General RPM.
+ Use "rpm -tb" to build from tarball.
+
+ProofGeneral.menu Menu file for some Linux versions.
+ Install in /usr/lib/menu.
+
+announce Announcement
+
+lego Files for testing LEGO Proof General
+isa Isabelle Proof General
+isar Isar PG
+demoisa Isabelle Demo PG
+
+
+README this file
+
+example test protocol for example proof scripts
+
+notes.txt Misc notes
+
+bug-notes.txt Test cases for Emacs or PG bugs
+cvs-tips.txt Notes on cvs with PG project
+debugging-tips.txt Notes on debugging
+profiling.txt profiling
+
+testing-log.txt Notes on tests carried out
+
+release-log.txt A record of official releases \ No newline at end of file
diff --git a/etc/TESTS b/etc/TESTS
new file mode 100644
index 00000000..222e5958
--- /dev/null
+++ b/etc/TESTS
@@ -0,0 +1,95 @@
+Some test cases for Proof General.
+==================================
+
+See testing-log.txt for log of tests conducted.
+Please add to that file!
+
+
+22.3.00 FILENAME ESCAPES PROBLEM [All provers, probably]
+========================================================
+
+ Filename substitution %s in settings including proof-shell-cd-cmd,
+ proof-shell-inform-file-{retracted,processed}-cmd, may need
+ to add escape characters peculiar to the proof assistant syntax.
+
+ Test cases:
+
+ ln -s ProofGeneral \\backslash
+ ln -s ProofGeneral \"quote
+
+ Then try scripting with example files for each prover,
+ i.e. \"quote/coq/example.v, etc.
+
+
+1.2.99 FILE RECOGNITION PROBLEM [Isabelle]
+===========================================
+
+ Bug in regexp caused ML files to be recognized as
+ theory files when "thy" appeared in path.
+ Test case in etc/isa/thy/test.ML.
+
+
+15.1.99 LONG-LINE AND BACKSLASH PROBLEM ON SOLARIS
+===================================================
+
+ Test that etc/isa/long-line-backslash.ML can be processed
+ successfully.
+
+
+16.12.98 KILLING THE PROOF PROCESS
+==================================
+
+ Process some proof script buffer. Invoke
+
+ M-x proof-shell-exit
+
+ Process should exit cleanly.
+
+11.12.98 RUDELY KILLING THE ACTIVE SCRIPTING BUFFER
+====================================================
+
+ Start scripting with some buffer, after
+ having processed another buffer.
+
+ Kill it when scripting is only partly finished.
+
+ Scripting should be cleanly turned off and it
+ should be possible to resume retraction in the
+ first buffer.
+
+ Moreover, this ensures that if the file is on the included
+ files list, yet has been only partly processed (e.g. because
+ Undo steps were taken), then it will be retracted and
+ removed from the included files list.
+
+ FIXME: Using C-x C-v to revert to saved version doesn't
+ seem to work because it renames the buffer or something.
+
+8.12.98 INHIBIT VARIABLES
+==========================
+
+ Test with proof-splash-inhibit=t
+
+ Test with proof-toolbar-inhibit=t
+
+
+8.12.98 SCRIPTING FOR BUFFERS WITHOUT FILES.
+=============================================
+
+ Switch to a fresh buffer FOO which doesn't visit a file.
+ Do M-x isa-mode RET.
+ Should succeed.
+ Try asserting commands, e.g. Goal "P-->P";
+
+ Switch to another fresh buffer BAR, turn on isa-mode.
+ Should succeed again.
+ Try asserting commands here, e.g. Goal "Q&Q --> Q";
+ Should give error "Cannot have more than one active scripting buffer".
+
+ Exit emacs. Should query whether we want to save these
+ scripting buffers (maybe XEmacs only).
+
+
+
+
+
diff --git a/etc/announce b/etc/announce
new file mode 100644
index 00000000..1dbda9ff
--- /dev/null
+++ b/etc/announce
@@ -0,0 +1,78 @@
+To: coq-club@pauillac.inria.fr,
+ isabelle-users@cl.cam.ac.uk,
+ lego-club@dcs.ed.ac.uk,
+ uitp@dcs.gla.ac.uk,
+ bra-types@cs.chalmers.se,
+ info-hol@leopard.cs.byu.edu,
+ pvs@csl.sri.com,
+ qed@mcs.anl.gov,
+ theorem-provers@ai.mit.edu,
+ types@cis.upenn.edu,
+ formal-methods@cs.uidaho.edu,
+ reliable_computing@interval.usl.edu,
+ prog-lang@diku.dk
+
+ Also newsgroups:
+ comp.lang.ml
+ comp.lang.functional
+ gnu.emacs.sources
+ comp.emacs.xemacs
+ comp.os.linux.announce
+ freshmeat.net
+
+tag for comp.lang.ml, comp.lang.functional:
+
+[Posted here because ML and functional languages generally are
+ traditional for implementing interactive theorem provers.
+ Implementors of such systems may be interested in Proof General.
+ Apologies for multiple copies]
+
+
+
+
+Subject: Proof General --- Version 3.3 release
+
+ Announcing Proof General Version 3.3
+ A Generic Emacs interface for Interactive Proof Assistants
+ http://www.proofgeneral.org
+
+ contact: David Aspinall <da@proofgeneral.org>
+
+Proof General is a generic (X)Emacs interface for proof assistants.
+It can be instantiated for the proof assistant of your choice, and is
+supplied ready-customised for Isabelle, Coq, LEGO, and PhoX, and,
+experimentally, for HOL, Twelf, and ACL2.
+
+Proof General includes these features, amongst others:
+
+. Script management: proof assistant state reflected in editor
+. Toolbar and menus: commands for building and replaying proofs
+. Syntax highlighting of proof scripts and prover output; hiding proofs
+. Display of real logical symbols, greek letters, etc
+. Simplified communication: proof assistant verbosity hidden
+. Menu for jumping to theorems in a proof script
+. Provision to easily run proof assistant on a remote host
+. Works on any platform Emacs does, in window system or plain console
+
+Summary of changes since 3.2:
+
+. Visibility control for completed proofs
+. Dependency browsing/highlighting (currently Isabelle only)
+. Bug fixes
+. Compatibility improvements: XEmacs 21.4, Coq 7, Windows
+
+For details of changes since 3.2, see
+http://www.proofgeneral.org/fileshow.php?file=ProofGeneral-3.3%2FCHANGES
+
+For the latest user manual, see http://www.proofgeneral.org/doc
+
+Proof General needs a recent version of Emacs to run with, and it much
+prefers XEmacs to FSF GNU Emacs. Proof General 3.3 has been tested
+with XEmacs 21.4 and Emacs 20.7. (It may work back to XEmacs 20.4 and
+Emacs 20.2, though).
+
+Installing Proof General is easy. Why not give it a try?
+
+ - David Aspinall <da@dcs.ed.ac.uk>
+ September 2001.
+
diff --git a/etc/bug-notes.txt b/etc/bug-notes.txt
new file mode 100644
index 00000000..c4aaf21d
--- /dev/null
+++ b/etc/bug-notes.txt
@@ -0,0 +1,48 @@
+-*- outline -*-
+
+$Id$
+
+Test cases for PG and/or Emacs bugs.
+
+----------------
+
+* Coq, and others bug: synchronization not gained until second line.
+
+Test in Coq buffer:
+
+ Print foo.
+
+Should give error, but PG ignores it and colours command blue.
+Similar errors for some other provers.
+
+[ Now fixed in 3.2pre ]
+
+
+
+
+----------------
+
+* XEmacs bug: buffer-syntactic-context-depth returns weird values
+
+Seems to depend on previous history. Test in Coq buffer:
+
+ X
+ (* comment one *)
+ Y
+ (* comment two *)
+ Z
+
+Evaluate (buffer-syntactic-context-depth) at X, Y, then Z.
+Values 0, 1, 2. Evaluate at point Y. Now get 0.
+Perhaps caches previous value, and bases parse on moving point
+forwards from previous value? Anyway, doesn't do well with
+block comments. Also bad with line comments, use same test
+case with buffer in lisp mode, except with lisp comments.
+
+Shame, would be nice to use this to help parse lisp-like
+syntax for PAs, fitting in with present scheme.
+
+
+
+
+
diff --git a/etc/coq/multiple/.cvsignore b/etc/coq/multiple/.cvsignore
new file mode 100644
index 00000000..41995687
--- /dev/null
+++ b/etc/coq/multiple/.cvsignore
@@ -0,0 +1 @@
+*.vo
diff --git a/etc/coq/multiple/README b/etc/coq/multiple/README
new file mode 100644
index 00000000..48f64110
--- /dev/null
+++ b/etc/coq/multiple/README
@@ -0,0 +1,27 @@
+New in 3.3: experimental proper handling of multiple files.
+ Not expected to be robust, see comments in coq.el
+ Should be improved for new versions of Coq 7, I hope!
+ Test also for automatic compilation.
+
+Expected behaviour:
+
+ 1) At the end of scripting foo.v (i.e. when activing scripting is
+ switched off), "Reset Initial. Compile Module <foo>" is
+ automatically issued. This clears the context and writes a .vo file,
+ to keep your .vo files up to date. It means that when using PG Coq,
+ you should use the correct commands ("Require foo.") to load all
+ the modules you depend on, so that scripting can continue in the
+ next file.
+
+ 2) PG tracks file dependencies by noticing "Reinterning" messages
+ from Coq. When a file "b.v" is processed which has a "Require a",
+ command, PG will try to find "a.v" and will automatically lock
+ it. (This part of the process is fragile, for two reasons: it
+ is hard to find the directory for a.v, since Coq doesn't report
+ it, and the reinterning message is only issued the first time the
+ file is reinterned).
+
+ 3) When a file is retracted, PG attempts to automatically unlock
+ all the dependent files, by issuing a coqdep command to determine
+ the dependencies. (This is a rather nasty hack, it's hoped for
+ the future that Coq will support this functionality directly).
diff --git a/etc/coq/multiple/a.v b/etc/coq/multiple/a.v
new file mode 100644
index 00000000..253db19d
--- /dev/null
+++ b/etc/coq/multiple/a.v
@@ -0,0 +1,11 @@
+(* Simple tests for multiple file handling *)
+
+Goal (A,B:Prop)(and A B) -> (and B A).
+Intros A B H.
+Induction H.
+Apply conj.
+Assumption.
+Assumption.
+Save and_comms_a.
+
+
diff --git a/etc/coq/multiple/b.v b/etc/coq/multiple/b.v
new file mode 100644
index 00000000..55c89b76
--- /dev/null
+++ b/etc/coq/multiple/b.v
@@ -0,0 +1,11 @@
+(* Simple tests for multiple file handling *)
+
+Goal (A,B:Prop)(and A B) -> (and B A).
+Intros A B H.
+Induction H.
+Apply conj.
+Assumption.
+Assumption.
+Save and_comms_b.
+
+
diff --git a/etc/coq/multiple/c.v b/etc/coq/multiple/c.v
new file mode 100644
index 00000000..490c3250
--- /dev/null
+++ b/etc/coq/multiple/c.v
@@ -0,0 +1,14 @@
+(* Simple tests for multiple file handling *)
+
+Require a.
+Require b.
+
+Goal (A,B:Prop)(and A B) -> (and B A).
+Intros A B H.
+Induction H.
+Apply conj.
+Assumption.
+Assumption.
+Save and_comms_c.
+
+
diff --git a/etc/coq/unnamed_thm.v b/etc/coq/unnamed_thm.v
new file mode 100644
index 00000000..2bd82b7b
--- /dev/null
+++ b/etc/coq/unnamed_thm.v
@@ -0,0 +1,30 @@
+(*
+ Test for Unnamed_thm
+
+ $Id$
+*)
+
+(* Coq calls this "Unamed_thm", so must forget it like any other *)
+
+(* test: do, undo, then check shell buffer to see "Reset Unnamed_thm" *)
+
+Goal (A,B:Prop)(and A B) -> (and B A).
+Intros A B H.
+Induction H.
+Apply conj.
+Assumption.
+Assumption.
+Save.
+
+(* Odd side effect: two unnamed theorems in a row are not possible! *)
+
+Goal (A,B:Prop)(and A B) -> (and B A).
+Intros A B H.
+Induction H.
+Apply conj.
+Assumption.
+Assumption.
+Save.
+
+
+
diff --git a/etc/cvs-tips.txt b/etc/cvs-tips.txt
new file mode 100644
index 00000000..495aef3c
--- /dev/null
+++ b/etc/cvs-tips.txt
@@ -0,0 +1,113 @@
+Using CVS to access Proof General repository
+============================================
+
+Here are some notes on how to access the PG repository remotely
+using CVS, using ssh with an account at dcs.ed.ac.uk
+
+
+1. First configure ssh so that you can do `ssh ssh.dcs.ed.ac.uk'
+without a password (or passphrase). For this you need to run
+ssh-keygen and give an empty passphrase. Then you need to copy
+your ~/.ssh/identity.pub at home into ~/.ssh/authorized_keys at
+dcs.ed.
+
+(NB: a more secure alternative would be to use ssh-agent to provide
+your passphrase as needed. The point is that you don't want to
+keep typing passwords on every CVS command).
+
+2. The CVS repository for PG is in ~proofgen/src at dcs.ed.ac.uk To
+use this, you need to set CVSROOT and CVS_RSH. I use the script below
+(the last line isn't essential but makes the settings inside a running
+emacs too)
+
+3. Where you want to develop PG, do:
+
+ cvs checkout ProofGeneral
+
+ Inside the ProofGeneral directory, to retrieve the latest updates,
+ do:
+
+ cvs update
+
+ To commit some changes to file <filename>, do:
+
+ cvs commit -m"<message here>" <filename>
+
+
+See "man cvs" for (much) more.
+
+#! /bin/bash
+MACHINE=ssh
+export CVSROOT=:ext:da@$MACHINE.dcs.ed.ac.uk:/home/proofgen/src
+export CVS_RSH=ssh
+export EDITOR=gnuclient
+gnudoit '(setenv "CVSROOT" ":ext:da@$MACHINE.dcs.ed.ac.uk:/home/proofgen/src")' '(setenv "CVS_RSH" "ssh")' '(message "set environment for CVS to /home/proofgen/src !")'
+
+
+
+-----------------------------------------------------------------
+
+Making a branch to patch a previous release:
+============================================
+
+ cvs checkout -r Release-3-1-3 ProofGeneral
+ cd ProofGeneral
+ cvs tag -b Release-3-1-branch
+ # Drop this repo, has sticky tag for 3-1-3.
+ cd .. ; cvs release -d ProofGeneral
+ # Get new one
+ cvs checkout -r Release-3-1-branch ProofGeneral
+ cd ProofGeneral
+ patch ... blah ...
+ cvs commit ... blah ..
+
+Then make release as ~proofgen:
+
+ mkdir oldbranch
+ cd oldbranch
+ cvs checkout -r Release-3-1-branch ProofGeneral
+ make devel.releaseall VERSION=3.1 FULLVERSION=3.1.99
+
+NB: See warning in Makefile.devel about this (it will
+downgrade web pages).
+
+Then perhaps merge in branch changes into main stream:
+
+ cd projects/proofgen/ProofGeneral
+ cvs update -jRelease-3-1-branch
+
+NB: this merging will always create conficts with
+$Id$ tags in source. (Is there a way to avoid this?)
+
+
+-----------------------------------------------------------------
+
+Overriding the CVS/Root setting temporarily:
+============================================
+
+ Use
+ cvs -d $CVSROOT
+
+NB: This doesn't alter CVS/Root, but uses NEWROOT in preference.
+($CVSROOT does not overide CVS/Root at all).
+
+Useful command:
+
+ alias cvs='cvs -d $CVSROOT'
+
+to force this behaviour.
+
+This is needed to solve "localssh.dcs" versus "ssh.dcs" problem.
+
+
+-----------------------------------------------------------------
+
+Moving to a new branch
+======================
+
+ find * -path '*/CVS' -prune -o -path 'CVS' -prune -o -print | tr '\n' '\0' | xargs -0 cvs commit -m"Updating branch" -f -r 4.0
+
+(The tr is needed because of some nasty filenames, e.g. etc/isa/\backslashname)
+
+
+
diff --git a/etc/debugging-tips.txt b/etc/debugging-tips.txt
new file mode 100644
index 00000000..a2650754
--- /dev/null
+++ b/etc/debugging-tips.txt
@@ -0,0 +1,10 @@
+Tips for Debugging Proof General -- David Aspinall, Oct 1999.
+--------------------------------
+
+Make these settings:
+
+ (setq proof-tidy-response nil) ; response buffer never clears
+ (setq proof-show-debug-messages t) ; debug messages appear in response buffer
+
+And use the standard elisp package "edebug" to single-step at source
+level, and set breakpoints in code.
diff --git a/etc/demoisa/A.ML b/etc/demoisa/A.ML
new file mode 100644
index 00000000..69126156
--- /dev/null
+++ b/etc/demoisa/A.ML
@@ -0,0 +1 @@
+1; \ No newline at end of file
diff --git a/etc/demoisa/B.ML b/etc/demoisa/B.ML
new file mode 100644
index 00000000..85fa53ce
--- /dev/null
+++ b/etc/demoisa/B.ML
@@ -0,0 +1 @@
+2; \ No newline at end of file
diff --git a/etc/demoisa/C.ML b/etc/demoisa/C.ML
new file mode 100644
index 00000000..33fefea4
--- /dev/null
+++ b/etc/demoisa/C.ML
@@ -0,0 +1 @@
+3; \ No newline at end of file
diff --git a/etc/demoisa/D.ML b/etc/demoisa/D.ML
new file mode 100644
index 00000000..06b33ae0
--- /dev/null
+++ b/etc/demoisa/D.ML
@@ -0,0 +1 @@
+4; \ No newline at end of file
diff --git a/etc/demoisa/README b/etc/demoisa/README
new file mode 100644
index 00000000..be06a076
--- /dev/null
+++ b/etc/demoisa/README
@@ -0,0 +1,11 @@
+This is a test for automatic multiple file handling.
+
+Assert each of A.ML, B.ML, C.ML, D.ML in turn.
+
+Then retract B.ML.
+
+D.ML and C.ML should be automatically retracted.
+
+Set proof-tidy-response=nil to track what happens.
+
+ - da.
diff --git a/etc/doc-notes.txt b/etc/doc-notes.txt
new file mode 100644
index 00000000..0cf83b88
--- /dev/null
+++ b/etc/doc-notes.txt
@@ -0,0 +1,196 @@
+Developers' Notes about Documentation
+-------------------------------------
+
+
+
+
+* Plan for outline of improved documentation. (Completed)
+
+ Terminology: I suggest "proof mode" should become "proof script
+ mode", aka "the proof script mode of Proof General". We should
+ be careful here, e.g. present docs speak of buffers in proof
+ mode, etc, but no buffer is directly in that mode, which is
+ confusing to the users, at least!
+
+ 1. Introduction [da]
+ 1.1 Quick start guide
+ 1.2 Feature list, xref'd to later chaps.
+ 1.2 Supported Proof Assistants, xref'd too.
+ Support for new instances, xref'd to later chaps.
+
+ 2. Basics of script management [da]
+
+ 2.1 What a proof script is
+ 2.2 Locked region and queue region
+ 2.3 Script processing commands
+ 2.4 Toolbar commands
+ 2.5 Other commands
+ 2.4 Walkthrough example [maybe in appendix?]
+
+ 3. Advanced script management [done]
+ 3.1 Proof General's view of processed files
+ 3.2 Switching between proof scripts
+ 3.3 Retracting across files
+ 3.4 Handy hints and tips (e.g. C-c C-b stuff?)
+ 3.5 Using the proof shell
+ [ 3.6 Re-synchronizing with the proof assistant - if added ]
+
+ 4. Customizing Proof General [da]
+ 4.1 Setting user options, what they are:
+ proof-splash-inhibit
+ etc.
+ 4.2 Using proof assistant on another machine
+ 4.3 Examining configuration settings (xref'd later)
+
+ 5. LEGO Proof General [done]
+ 5.1 LEGO commands
+ 5.2 LEGO customizations
+
+ 6. Coq Proof General [anon]
+ 6.1 Coq commands
+ 6.2 Coq customizations
+
+ 7. Isabelle Proof General [da]
+ 7.1 Isabelle commands
+ 7.2 Isabelle customizations
+ 7.3 Notes about multiple files
+
+ 8. Adapting Proof General to New Provers [da]
+ 8.1 Files and directories. Skeleton code.
+ 8.2 Settings for proof scripts
+ 8.3 Settings for proof shell
+ -- Special annotations
+
+ 9. Internals of Proof General. [tms]
+ 9.1 Proof script mode:
+ - fontification hacks
+ - spans in locked region
+ 9.2 Proof shell mode
+ - proof-action-list
+ - proof-shell-exec-loop
+ - proof-shell-output-filter
+ - eager annotations
+
+ 10. Credits and history [done]
+
+ APPENDIX
+
+ A. Obtaining and installing the software [da]
+ B. Known bugs [done]
+ C. Future ideas and plans [da]
+
+
+*********
+
+Support for Function Menus
+
+fume-func is a handy package which makes a menu from the function
+declarations in a buffer. Proof General configures fume-func so
+that you can quickly jump to particular proofs in a script buffer.
+
+If you want to use fume-func, you may need to enable it for
+yourself. It is distributed with XEmacs (and FSF GNU Emacs)
+but by not enabled by default. To enable it you should find
+the file func-menu.el and follow the instructions there.
+At the time of writing, the current version of XEmacs is 20.4 and
+it has these instructions:
+
+(require 'func-menu)
+(define-key global-map 'f8 'function-menu)
+(add-hook 'find-file-hooks 'fume-add-menubar-entry)
+(define-key global-map "\C-cl" 'fume-list-functions)
+(define-key global-map "\C-cg" 'fume-prompt-function-goto)
+(define-key global-map '(shift button3) 'mouse-function-menu)
+(define-key global-map '(meta button1) 'fume-mouse-function-goto)
+
+If you have any other version of Emacs, you should check the
+fume-func.el file
+
+
+
+*********
+
+
+Isabelle with multiple files.
+
+Proper multiple file support only works for .ML files which are read
+via the theory loader, with use_thy. If you want to load .ML files
+which aren't associated with theories, it's best to use a dummy
+theory, see [Reference to Isabelle manual]
+
+
+*****************************************************************
+
+Notes for writing a paper describing Proof General
+-------------------------------------------------
+
+
+Thesis/introduction
+===================
+
+As programming languages have evolved, environments for developing and
+debugging programs have also improved. However, discounting various
+"visual" programming languages, a program is usually still a piece of
+text which can be directly edited by a programmer, a situation which
+hasn't changed since the early days when VDUs replaced punched cards.
+
+Similarly, whilst the history of languages for proof assistants is
+much shorter, we believe that a proof script, describing the
+operations needed to construct a proof, will remain the fundamental
+form of input for proof systems.
+
+...
+- interactive proof assistants geared to developing proof scripts
+ interactively, but may not come with integrated editing support.
+ Problem of shell-like interaction is that input has to be
+ tediously reassembled after or during proof to get a successful
+ proof script.
+
+- script management [refs] aims to make this process easier.
+
+
+
+Aspects of design
+=================
+
+- Generic. Fits inside Emacs architecture. (Compare with comint).
+
+- Extensive use of Emacs Customization mechanism to make it easy
+ to set/inspect configuration as well as user-options.
+
+- Script management with multiple files
+
+
+Seen one proof assistant, use them all
+======================================
+
+- Same interface for different underlying systems
+
+- Compare: web technology, where "browsing" works for
+ different protocols: http, ftp, etc
+
+- Anyone can use Proof General to browse and replay proofs from
+ other systems, without needing to know how to invoke
+ the system, etc.
+
+- However, proof script language and output remains particular to
+ each prover. It would be another (interesting) project to attempt to
+ map input and output into an interchange format for proof systems.
+
+
+
+A Specification for a proof assistant interface
+===============================================
+
+The settings to instantiate Proof General can be seen as a set of
+requirements for a proof assistant interface.
+
+
+
+Example of API design guidlines
+===============================
+
+1. Use a different prompt for continued lines during input
+communication. Helps parsing output.
+
+
diff --git a/etc/isa/\backslashname/test.ML b/etc/isa/\backslashname/test.ML
new file mode 100644
index 00000000..0691e38e
--- /dev/null
+++ b/etc/isa/\backslashname/test.ML
@@ -0,0 +1,11 @@
+(* Scripting here tests quotation mechanism for filenames. *)
+
+(* At the moment this trips a bug in Isabelle which objects
+ to filename of this directory.
+
+ Easy way to test for other provers is with a link,
+ \bizzare \\<rightarrow> ProofGeneral/ then load \bizarre/coq/example.v, etc
+
+*)
+
+val a = 1;
diff --git a/etc/isa/\backslashname/test.thy b/etc/isa/\backslashname/test.thy
new file mode 100644
index 00000000..2ca5331f
--- /dev/null
+++ b/etc/isa/\backslashname/test.thy
@@ -0,0 +1 @@
+test = Pure
diff --git a/etc/isa/depends/Fib.ML b/etc/isa/depends/Fib.ML
new file mode 100644
index 00000000..eba2f0e0
--- /dev/null
+++ b/etc/isa/depends/Fib.ML
@@ -0,0 +1,106 @@
+(* Title: HOL/ex/Fib
+ ID: $Id$
+ Author: Lawrence C Paulson
+ Copyright 1997 University of Cambridge
+
+Fibonacci numbers: proofs of laws taken from
+
+ R. L. Graham, D. E. Knuth, O. Patashnik.
+ Concrete Mathematics.
+ (Addison-Wesley, 1989)
+*)
+
+
+(** The difficulty in these proofs is to ensure that the induction hypotheses
+ are applied before the definition of "fib". Towards this end, the
+ "fib" equations are not added to the simpset and are applied very
+ selectively at first.
+**)
+
+Delsimps fib.Suc_Suc;
+
+val [fib_Suc_Suc] = fib.Suc_Suc;
+val fib_Suc3 = read_instantiate [("x", "(Suc ?n)")] fib_Suc_Suc;
+
+(*Concrete Mathematics, page 280*)
+Goal "fib (Suc (n + k)) = fib(Suc k) * fib(Suc n) + fib k * fib n";
+by (res_inst_tac [("u","n")] fib.induct 1);
+(*Simplify the LHS just enough to apply the induction hypotheses*)
+by (asm_full_simp_tac
+ (simpset() addsimps [inst "x" "Suc(?m+?n)" fib_Suc_Suc]) 3);
+by (ALLGOALS
+ (asm_simp_tac (simpset() addsimps
+ ([fib_Suc_Suc, add_mult_distrib, add_mult_distrib2]))));
+qed "fib_add";
+
+
+Goal "fib (Suc n) ~= 0";
+by (res_inst_tac [("u","n")] fib.induct 1);
+by (ALLGOALS (asm_simp_tac (simpset() addsimps [fib_Suc_Suc])));
+qed "fib_Suc_neq_0";
+
+(* Also add 0 < fib (Suc n) *)
+Addsimps [fib_Suc_neq_0, [neq0_conv, fib_Suc_neq_0] MRS iffD1];
+
+Goal "0<n ==> 0 < fib n";
+by (rtac (not0_implies_Suc RS exE) 1);
+by Auto_tac;
+qed "fib_gr_0";
+
+(*Concrete Mathematics, page 278: Cassini's identity.
+ It is much easier to prove using integers!*)
+Goal "int (fib (Suc (Suc n)) * fib n) = \
+\ (if n mod 2 = 0 then int (fib(Suc n) * fib(Suc n)) - #1 \
+\ else int (fib(Suc n) * fib(Suc n)) + #1)";
+by (res_inst_tac [("u","n")] fib.induct 1);
+by (simp_tac (simpset() addsimps [fib_Suc_Suc, mod_Suc]) 2);
+by (simp_tac (simpset() addsimps [fib_Suc_Suc]) 1);
+by (asm_full_simp_tac
+ (simpset() addsimps [fib_Suc_Suc, add_mult_distrib, add_mult_distrib2,
+ mod_Suc, zmult_int RS sym] @ zmult_ac) 1);
+qed "fib_Cassini";
+
+
+
+(** Towards Law 6.111 of Concrete Mathematics **)
+
+Goal "gcd(fib n, fib (Suc n)) = 1";
+by (res_inst_tac [("u","n")] fib.induct 1);
+by (asm_simp_tac (simpset() addsimps [fib_Suc3, gcd_commute, gcd_add2]) 3);
+by (ALLGOALS (simp_tac (simpset() addsimps [fib_Suc_Suc])));
+qed "gcd_fib_Suc_eq_1";
+
+val gcd_fib_commute =
+ read_instantiate_sg (sign_of thy) [("m", "fib m")] gcd_commute;
+
+Goal "gcd(fib m, fib (n+m)) = gcd(fib m, fib n)";
+by (simp_tac (simpset() addsimps [gcd_fib_commute]) 1);
+by (case_tac "m=0" 1);
+by (Asm_simp_tac 1);
+by (clarify_tac (claset() addSDs [not0_implies_Suc]) 1);
+by (simp_tac (simpset() addsimps [fib_add]) 1);
+by (asm_simp_tac (simpset() addsimps [add_commute, gcd_non_0]) 1);
+by (asm_simp_tac (simpset() addsimps [gcd_non_0 RS sym]) 1);
+by (asm_simp_tac (simpset() addsimps [gcd_fib_Suc_eq_1, gcd_mult_cancel]) 1);
+qed "gcd_fib_add";
+
+Goal "m <= n ==> gcd(fib m, fib (n-m)) = gcd(fib m, fib n)";
+by (rtac (gcd_fib_add RS sym RS trans) 1);
+by (Asm_simp_tac 1);
+qed "gcd_fib_diff";
+
+Goal "0<m ==> gcd (fib m, fib (n mod m)) = gcd (fib m, fib n)";
+by (res_inst_tac [("n","n")] less_induct 1);
+by (stac mod_if 1);
+by (Asm_simp_tac 1);
+by (asm_simp_tac (simpset() addsimps [gcd_fib_diff, mod_geq,
+ not_less_iff_le, diff_less]) 1);
+qed "gcd_fib_mod";
+
+(*Law 6.111*)
+Goal "fib(gcd(m,n)) = gcd(fib m, fib n)";
+by (res_inst_tac [("m","m"),("n","n")] gcd_induct 1);
+by (Asm_simp_tac 1);
+by (asm_full_simp_tac (simpset() addsimps [gcd_non_0]) 1);
+by (asm_full_simp_tac (simpset() addsimps [gcd_commute, gcd_fib_mod]) 1);
+qed "fib_gcd";
diff --git a/etc/isa/depends/Fib.thy b/etc/isa/depends/Fib.thy
new file mode 100644
index 00000000..9272ed8c
--- /dev/null
+++ b/etc/isa/depends/Fib.thy
@@ -0,0 +1,17 @@
+(* Title: ex/Fib
+ ID: $Id$
+ Author: Lawrence C Paulson, Cambridge University Computer Laboratory
+ Copyright 1997 University of Cambridge
+
+The Fibonacci function. Demonstrates the use of recdef.
+*)
+
+Fib = Usedepends + Divides + Primes +
+
+consts fib :: "nat => nat"
+recdef fib "less_than"
+ zero "fib 0 = 0"
+ one "fib 1 = 1"
+ Suc_Suc "fib (Suc (Suc x)) = fib x + fib (Suc x)"
+
+end
diff --git a/etc/isa/depends/Primes.ML b/etc/isa/depends/Primes.ML
new file mode 100644
index 00000000..102419da
--- /dev/null
+++ b/etc/isa/depends/Primes.ML
@@ -0,0 +1,197 @@
+(* Title: HOL/ex/Primes.ML
+ ID: $Id$
+ Author: Christophe Tabacznyj and Lawrence C Paulson
+ Copyright 1996 University of Cambridge
+
+The "divides" relation, the greatest common divisor and Euclid's algorithm
+
+See H. Davenport, "The Higher Arithmetic". 6th edition. (CUP, 1992)
+*)
+
+eta_contract:=false;
+
+(************************************************)
+(** Greatest Common Divisor **)
+(************************************************)
+
+(*** Euclid's Algorithm ***)
+
+
+val [gcd_eq] = gcd.simps;
+
+
+val prems = goal thy
+ "[| !!m. P m 0; \
+\ !!m n. [| 0<n; P n (m mod n) |] ==> P m n \
+\ |] ==> P (m::nat) (n::nat)";
+by (res_inst_tac [("u","m"),("v","n")] gcd.induct 1);
+by (case_tac "n=0" 1);
+by (asm_simp_tac (simpset() addsimps prems) 1);
+by Safe_tac;
+by (asm_simp_tac (simpset() addsimps prems) 1);
+qed "gcd_induct";
+
+
+Goal "gcd(m,0) = m";
+by (Simp_tac 1);
+qed "gcd_0";
+Addsimps [gcd_0];
+
+Goal "0<n ==> gcd(m,n) = gcd (n, m mod n)";
+by (Asm_simp_tac 1);
+qed "gcd_non_0";
+
+Delsimps gcd.simps;
+
+Goal "gcd(m,1) = 1";
+by (simp_tac (simpset() addsimps [gcd_non_0]) 1);
+qed "gcd_1";
+Addsimps [gcd_1];
+
+(*gcd(m,n) divides m and n. The conjunctions don't seem provable separately*)
+Goal "(gcd(m,n) dvd m) & (gcd(m,n) dvd n)";
+by (res_inst_tac [("m","m"),("n","n")] gcd_induct 1);
+by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [gcd_non_0])));
+by (blast_tac (claset() addDs [dvd_mod_imp_dvd]) 1);
+qed "gcd_dvd_both";
+
+bind_thm ("gcd_dvd1", gcd_dvd_both RS conjunct1);
+bind_thm ("gcd_dvd2", gcd_dvd_both RS conjunct2);
+
+
+(*Maximality: for all m,n,f naturals,
+ if f divides m and f divides n then f divides gcd(m,n)*)
+Goal "(f dvd m) --> (f dvd n) --> f dvd gcd(m,n)";
+by (res_inst_tac [("m","m"),("n","n")] gcd_induct 1);
+by (ALLGOALS (asm_full_simp_tac (simpset() addsimps[gcd_non_0, dvd_mod])));
+qed_spec_mp "gcd_greatest";
+
+(*Function gcd yields the Greatest Common Divisor*)
+Goalw [is_gcd_def] "is_gcd (gcd(m,n)) m n";
+by (asm_simp_tac (simpset() addsimps [gcd_greatest, gcd_dvd_both]) 1);
+qed "is_gcd";
+
+(*uniqueness of GCDs*)
+Goalw [is_gcd_def] "[| is_gcd m a b; is_gcd n a b |] ==> m=n";
+by (blast_tac (claset() addIs [dvd_anti_sym]) 1);
+qed "is_gcd_unique";
+
+(*USED??*)
+Goalw [is_gcd_def]
+ "[| is_gcd m a b; k dvd a; k dvd b |] ==> k dvd m";
+by (Blast_tac 1);
+qed "is_gcd_dvd";
+
+(** Commutativity **)
+
+Goalw [is_gcd_def] "is_gcd k m n = is_gcd k n m";
+by (Blast_tac 1);
+qed "is_gcd_commute";
+
+Goal "gcd(m,n) = gcd(n,m)";
+by (rtac is_gcd_unique 1);
+by (rtac is_gcd 2);
+by (asm_simp_tac (simpset() addsimps [is_gcd, is_gcd_commute]) 1);
+qed "gcd_commute";
+
+Goal "gcd(gcd(k,m),n) = gcd(k,gcd(m,n))";
+by (rtac is_gcd_unique 1);
+by (rtac is_gcd 2);
+by (rewtac is_gcd_def);
+by (blast_tac (claset() addSIs [gcd_dvd1, gcd_dvd2]
+ addIs [gcd_greatest, dvd_trans]) 1);
+qed "gcd_assoc";
+
+Goal "gcd(0,m) = m";
+by (stac gcd_commute 1);
+by (rtac gcd_0 1);
+qed "gcd_0_left";
+
+Goal "gcd(1,m) = 1";
+by (stac gcd_commute 1);
+by (rtac gcd_1 1);
+qed "gcd_1_left";
+Addsimps [gcd_0_left, gcd_1_left];
+
+
+(** Multiplication laws **)
+
+(*Davenport, page 27*)
+Goal "k * gcd(m,n) = gcd(k*m, k*n)";
+by (res_inst_tac [("m","m"),("n","n")] gcd_induct 1);
+by (Asm_full_simp_tac 1);
+by (case_tac "k=0" 1);
+ by (Asm_full_simp_tac 1);
+by (asm_full_simp_tac
+ (simpset() addsimps [mod_geq, gcd_non_0, mod_mult_distrib2]) 1);
+qed "gcd_mult_distrib2";
+
+Goal "gcd(m,m) = m";
+by (cut_inst_tac [("k","m"),("m","1"),("n","1")] gcd_mult_distrib2 1);
+by (Asm_full_simp_tac 1);
+qed "gcd_self";
+Addsimps [gcd_self];
+
+Goal "gcd(k, k*n) = k";
+by (cut_inst_tac [("k","k"),("m","1"),("n","n")] gcd_mult_distrib2 1);
+by (Asm_full_simp_tac 1);
+qed "gcd_mult";
+Addsimps [gcd_mult];
+
+Goal "[| gcd(k,n)=1; k dvd (m*n) |] ==> k dvd m";
+by (subgoal_tac "m = gcd(m*k, m*n)" 1);
+by (etac ssubst 1 THEN rtac gcd_greatest 1);
+by (ALLGOALS (asm_simp_tac (simpset() addsimps [gcd_mult_distrib2 RS sym])));
+qed "relprime_dvd_mult";
+
+Goalw [prime_def] "[| p: prime; ~ p dvd n |] ==> gcd (p, n) = 1";
+by (cut_inst_tac [("m","p"),("n","n")] gcd_dvd_both 1);
+by Auto_tac;
+qed "prime_imp_relprime";
+
+(*This theorem leads immediately to a proof of the uniqueness of factorization.
+ If p divides a product of primes then it is one of those primes.*)
+Goal "[| p: prime; p dvd (m*n) |] ==> p dvd m | p dvd n";
+by (blast_tac (claset() addIs [relprime_dvd_mult, prime_imp_relprime]) 1);
+qed "prime_dvd_mult";
+
+
+(** Addition laws **)
+
+Goal "gcd(m, m+n) = gcd(m,n)";
+by (res_inst_tac [("n1", "m+n")] (gcd_commute RS ssubst) 1);
+by (rtac (gcd_eq RS trans) 1);
+by Auto_tac;
+by (asm_simp_tac (simpset() addsimps [mod_add_self1]) 1);
+by (stac gcd_commute 1);
+by (stac gcd_non_0 1);
+by Safe_tac;
+qed "gcd_add";
+
+Goal "gcd(m, n+m) = gcd(m,n)";
+by (asm_simp_tac (simpset() addsimps [add_commute, gcd_add]) 1);
+qed "gcd_add2";
+
+Goal "gcd(m, k*m+n) = gcd(m,n)";
+by (induct_tac "k" 1);
+by (asm_simp_tac (simpset() addsimps [gcd_add, add_assoc]) 2);
+by (Simp_tac 1);
+qed "gcd_add_mult";
+
+
+(** More multiplication laws **)
+
+Goal "gcd(m,n) dvd gcd(k*m, n)";
+by (blast_tac (claset() addIs [gcd_greatest, dvd_trans,
+ gcd_dvd1, gcd_dvd2]) 1);
+qed "gcd_dvd_gcd_mult";
+
+Goal "gcd(k,n) = 1 ==> gcd(k*m, n) = gcd(m,n)";
+by (rtac dvd_anti_sym 1);
+by (rtac gcd_dvd_gcd_mult 2);
+by (rtac ([relprime_dvd_mult, gcd_dvd2] MRS gcd_greatest) 1);
+by (stac mult_commute 2);
+by (rtac gcd_dvd1 2);
+by (stac gcd_commute 1);
+by (asm_simp_tac (simpset() addsimps [gcd_assoc RS sym]) 1);
+qed "gcd_mult_cancel";
diff --git a/etc/isa/depends/Primes.thy b/etc/isa/depends/Primes.thy
new file mode 100644
index 00000000..fac39463
--- /dev/null
+++ b/etc/isa/depends/Primes.thy
@@ -0,0 +1,33 @@
+(* Title: HOL/ex/Primes.thy
+ ID: $Id$
+ Author: Christophe Tabacznyj and Lawrence C Paulson
+ Copyright 1996 University of Cambridge
+
+The Greatest Common Divisor and Euclid's algorithm
+
+The "simpset" clause in the recdef declaration used to be necessary when the
+two lemmas where not part of the default simpset.
+*)
+
+Primes = Main +
+
+
+consts
+ is_gcd :: [nat,nat,nat]=>bool (*gcd as a relation*)
+ gcd :: "nat*nat=>nat" (*Euclid's algorithm *)
+ coprime :: [nat,nat]=>bool
+ prime :: nat set
+
+recdef gcd "measure ((%(m,n).n) ::nat*nat=>nat)"
+(* simpset "simpset() addsimps [mod_less_divisor, zero_less_eq]" *)
+ "gcd (m, n) = (if n=0 then m else gcd(n, m mod n))"
+
+defs
+ is_gcd_def "is_gcd p m n == p dvd m & p dvd n &
+ (ALL d. d dvd m & d dvd n --> d dvd p)"
+
+ coprime_def "coprime m n == gcd(m,n) = 1"
+
+ prime_def "prime == {p. 1<p & (ALL m. m dvd p --> m=1 | m=p)}"
+
+end
diff --git a/etc/isa/depends/Usedepends.ML b/etc/isa/depends/Usedepends.ML
new file mode 100644
index 00000000..7557d6e8
--- /dev/null
+++ b/etc/isa/depends/Usedepends.ML
@@ -0,0 +1,3 @@
+use "~/ProofGeneral/isa/depends.ML";
+
+
diff --git a/etc/isa/depends/Usedepends.thy b/etc/isa/depends/Usedepends.thy
new file mode 100644
index 00000000..4f8eb516
--- /dev/null
+++ b/etc/isa/depends/Usedepends.thy
@@ -0,0 +1,5 @@
+(* dummy theory to load depends.ML *)
+theory Usedepends = Main:
+end
+
+
diff --git a/etc/isa/goal-matching.ML b/etc/isa/goal-matching.ML
new file mode 100644
index 00000000..843e2ca5
--- /dev/null
+++ b/etc/isa/goal-matching.ML
@@ -0,0 +1,10 @@
+(*
+ Test case sent by David von Oheimb.
+ Bug in matching case-insensitively meant that
+ the SELECT_GOAL line was considered a goal.
+*)
+
+Goal "x";
+by (SELECT_GOAL all_tac 1);
+
+
diff --git a/etc/isa/long-line-backslash.ML b/etc/isa/long-line-backslash.ML
new file mode 100644
index 00000000..66435c1b
--- /dev/null
+++ b/etc/isa/long-line-backslash.ML
@@ -0,0 +1,20 @@
+(*
+
+ long-line-backslash.ML
+
+ Test for long lines with backslashes in them.
+ Cause problem with pty communication where line length
+ is limited to 256 characters sometimes (e.g. on Solaris).
+
+*)
+
+val nasty_string="\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\";
+
+(* Test subsequent commands can be processed *)
+
+val one = 1;
+val two = 2;
+val three = 3;
+
+(* Test something with eager annotations *)
+
diff --git a/etc/isa/message-test.ML b/etc/isa/message-test.ML
new file mode 100644
index 00000000..4afd7120
--- /dev/null
+++ b/etc/isa/message-test.ML
@@ -0,0 +1,16 @@
+(* Testing different kinds of markup in Isabelle output *)
+
+(* ordinary output between prompts *)
+print "ordinary";
+print "ordinary\n"; (* final newline no difference *)
+
+(* eager annotation: displayed as soon as it's seen *)
+writeln "eager to be seen!";
+
+print "more ordinary\n";
+
+Goal "P-->P";
+
+(* C-c RET to here should show eager annotation, as well as
+ updating goals buffer properly. *)
+error "something went wrong";
diff --git a/etc/isa/multiple/A.ML b/etc/isa/multiple/A.ML
new file mode 100644
index 00000000..771a5f1a
--- /dev/null
+++ b/etc/isa/multiple/A.ML
@@ -0,0 +1,11 @@
+(* Scripting buffer for theory A *)
+
+1;
+
+(* A few commands so that we can test partial-retraction. *)
+
+2;
+
+3;
+
+
diff --git a/etc/isa/multiple/A.thy b/etc/isa/multiple/A.thy
new file mode 100644
index 00000000..fc585327
--- /dev/null
+++ b/etc/isa/multiple/A.thy
@@ -0,0 +1,7 @@
+(*
+ File: /home/da/proofgen/ProofGeneral/etc/isa/multiple/A.thy
+ Theory Name: A
+ Logic Image: Pure
+*)
+
+A = Pure
diff --git a/etc/isa/multiple/B.ML b/etc/isa/multiple/B.ML
new file mode 100644
index 00000000..e0226516
--- /dev/null
+++ b/etc/isa/multiple/B.ML
@@ -0,0 +1,4 @@
+(* Scripting buffer for theory B *)
+
+val b = 0;
+val b1 = 1;
diff --git a/etc/isa/multiple/B.thy b/etc/isa/multiple/B.thy
new file mode 100644
index 00000000..a896bca2
--- /dev/null
+++ b/etc/isa/multiple/B.thy
@@ -0,0 +1,7 @@
+(*
+ File: /home/da/proofgen/ProofGeneral/etc/isa/multiple/B.thy
+ Theory Name: B
+ Logic Image: Pure
+*)
+
+B = Pure
diff --git a/etc/isa/multiple/C.ML b/etc/isa/multiple/C.ML
new file mode 100644
index 00000000..4ad965a2
--- /dev/null
+++ b/etc/isa/multiple/C.ML
@@ -0,0 +1,4 @@
+(* Scripting buffer for theory C *)
+
+val c1 = 4;
+val c = 5;
diff --git a/etc/isa/multiple/C.thy b/etc/isa/multiple/C.thy
new file mode 100644
index 00000000..3316eaee
--- /dev/null
+++ b/etc/isa/multiple/C.thy
@@ -0,0 +1,10 @@
+(*
+ File: /home/da/proofgen/ProofGeneral/etc/isa/multiple/C.thy
+ Theory Name: C
+ Logic Image: Pure
+*)
+
+theory C = A + B
+files "foobar/foo.ML":
+
+end
diff --git a/etc/isa/multiple/D.ML b/etc/isa/multiple/D.ML
new file mode 100644
index 00000000..76dd89c1
--- /dev/null
+++ b/etc/isa/multiple/D.ML
@@ -0,0 +1,3 @@
+(* Scripting buffer for theory D *)
+
+val it = ();
diff --git a/etc/isa/multiple/D.thy b/etc/isa/multiple/D.thy
new file mode 100644
index 00000000..afacc20e
--- /dev/null
+++ b/etc/isa/multiple/D.thy
@@ -0,0 +1,7 @@
+(*
+ File: /home/da/proofgen/ProofGeneral/etc/isa/multiple/D.thy
+ Theory Name: D
+ Logic Image: Pure
+*)
+
+D = Pure
diff --git a/etc/isa/multiple/Err.ML b/etc/isa/multiple/Err.ML
new file mode 100644
index 00000000..177da5ce
--- /dev/null
+++ b/etc/isa/multiple/Err.ML
@@ -0,0 +1,5 @@
+(* Test to see that scripting is *not* turned on
+ if an error occurs during activation
+*)
+
+val x = 1;
diff --git a/etc/isa/multiple/Err.thy b/etc/isa/multiple/Err.thy
new file mode 100644
index 00000000..d36a5af2
--- /dev/null
+++ b/etc/isa/multiple/Err.thy
@@ -0,0 +1,3 @@
+(* Dummy file to cause an error in use_thy *)
+
+Err = blah \ No newline at end of file
diff --git a/etc/isa/multiple/README b/etc/isa/multiple/README
new file mode 100644
index 00000000..8ffa6fba
--- /dev/null
+++ b/etc/isa/multiple/README
@@ -0,0 +1,102 @@
+Test files for multiple file handling with Isabelle.
+
+
+Test schedule
+=============
+
+[C depends on A and B, D is independent]
+
+Notation: A means that buffer A.l is unlocked
+ A+ means that buffer A.l is partly locked
+ A* means that buffer A.l is locked
+ ? means that behaviour might be different for proof systems
+ with non-linear contexts
+
+Borrowed from Thomas's lego tests: (v 1.2)
+
+ 1) visit A.ML EFFECTS A
+ 2) visit C.ML EFFECTS A C
+ 3) assert C EFFECTS A* C*
+ 4) visit B.ML,B.thy,C.thy EFFECTS A* B* C* C.thy* B.thy*
+ 5) visit D.ML,D.thy EFFECTS A* B* C* D D.thy
+ 6) retract to middle of B EFFECTS A* B C D B.thy* (*thy remains locked*)
+ 7) assert first command of B EFFECTS A* B+ C D
+ 8) assert C EFFECTS A* B+ C D [error message, correctly]
+ 9) assert B EFFECTS A* B* C D
+10) assert D EFFECTS A* B* C D* D.thy*
+11) retract B EFFECTS A* B C D? [D* D.thy* for Isabelle]
+12) assert C EFFECTS A* B* C* D?
+13) retract B EFFECTS A* B C D? [B.thy* D*,D.thy* again]
+14) assert B EFFECTS A* B* C D?
+15) assert C EFFECTS A* B* C* D? [everything locked]
+ BROKEN 11.12.98: B.ML *may* not be locked?
+
+16) retract to middle of B EFFECTS A* B+ C D?
+ BROKEN! Now retracts whole thing.
+14) M-x proof-shell-restart EFFECTS A B C D
+
+
+MORE TESTS NEEDED FOR ISABELLE:
+===============================
+
+Should test assertion of theory files, and watch what happens to ML files.
+
+Because of theory loader's odd behaviour, must watch what happens
+to ML files of autoloaded children.
+
+
+1) visit example.ML, example.thy EFFECT: ML thy
+2) assert .ML EFFECT: ML* thy*
+3) retract thy EFFECT: ML thy
+
+
+1) visit example.ML, example.thy ML thy
+2) assert thy ML* thy* (reads theory too)
+
+
+(* Test case for outdating a child theory *)
+
+1) assert C.thy A*, B*, C*
+2) retract B.thy A*
+3) edit B.thy to touch timestamp
+4) assert B.thy A*, B*, C Message: "C out of date"
+5) assert C.thy A*, B*, C*
+
+
+(* Test case for removing a dependency from a theory:
+ this automatically unlocks the orphaned theory,
+ is this right??
+*)
+
+1) assert C.thy A*, B*, C*
+2) retract C.thy A*, B*, C
+3) edit C.thy to C=A, remove dependency on B
+4) assert C.thy A*, B, C* (B automatically unlocked)
+
+
+
+
+
+-----------------------------------------------------------------
+
+Question:
+
+We assert script A.
+We assert script B.
+Can we retract to middle of A? Yes, we should be able to!
+
+
+
+-----------------------------------------------------------------
+
+Tester:
+
+Visit A.ML. Assert partly.
+
+Visit C.thy. Assert it.
+
+This should lock remainder of A.ML, since it has now been read
+completely.
+
+
+
diff --git a/etc/isa/multiple/foobar/foo.ML b/etc/isa/multiple/foobar/foo.ML
new file mode 100644
index 00000000..25084a22
--- /dev/null
+++ b/etc/isa/multiple/foobar/foo.ML
@@ -0,0 +1,4 @@
+
+val foo = "foo";
+
+val bar = 1;
diff --git a/etc/isa/settings.ML b/etc/isa/settings.ML
new file mode 100644
index 00000000..3250f9ca
--- /dev/null
+++ b/etc/isa/settings.ML
@@ -0,0 +1,21 @@
+(*
+ Simple test for variable setting mechanism ML -> PG.
+ This kind of protocol is included in PGIP for setting config variables.
+ Here we can use it for executing arbitrary elisp, in fact (eek!)
+*)
+
+fun pg_setvar var exp = writeln ("Proof General, please set the variable " ^ var ^ " to: #" ^ exp ^ "#.");
+
+pg_setvar "wag" "(+ 33 44)"; (* C-h v wag RET gives 77 *)
+
+fun pgset var = pg_setvar var "t";
+fun pgreset var = pg_setvar var "nil";
+
+pgset "isa-show-types"; (* sets show-types in menu *)
+
+(* What might be nice is to override 'set' 'reset' fuctions to mirror
+ settings in PG automatically, but then we'd need to retrieve the
+ names of the ML values from the 'set' and 'reset' functions... *)
+
+(* test failure case: prints a debug message if proof-show-debug-messages<>nil *)
+pg_setvar "wig" "blah 12 x12"
diff --git a/etc/isa/thy/test.ML b/etc/isa/thy/test.ML
new file mode 100644
index 00000000..6a434570
--- /dev/null
+++ b/etc/isa/thy/test.ML
@@ -0,0 +1,5 @@
+(* Test case for wrong file type
+ bug report by jv@ddre.dk
+
+ This file should be ML, not theory!
+*) \ No newline at end of file
diff --git a/etc/isa/xsym.ML b/etc/isa/xsym.ML
new file mode 100644
index 00000000..797bad69
--- /dev/null
+++ b/etc/isa/xsym.ML
@@ -0,0 +1,18 @@
+(* a few token characters to exercise X-Symbol *)
+
+Goal "A \\<and> B \\<longrightarrow> B \\<and> A";
+by (rtac impI 1);
+by (etac conjE 1);
+by (rtac conjI 1);
+by (assume_tac 1);
+by (assume_tac 1);
+qed "and_comms";
+
+3;
+
+4;
+
+print "hello";
+
+writeln "hello";
+error "hello";
diff --git a/etc/isar/CommentParsingBug.thy b/etc/isar/CommentParsingBug.thy
new file mode 100644
index 00000000..e279fb68
--- /dev/null
+++ b/etc/isar/CommentParsingBug.thy
@@ -0,0 +1,3 @@
+(**)(**)
+theory Scratch = Main:
+
diff --git a/etc/isar/Parsing.thy b/etc/isar/Parsing.thy
new file mode 100644
index 00000000..4bd7e0a3
--- /dev/null
+++ b/etc/isar/Parsing.thy
@@ -0,0 +1,37 @@
+(* Not really a theory of parsing, but a test of Proof General's
+ parsing for Isabelle/Isar.... *)
+
+(* First, start with successive comments before a real command *)
+
+theory Parsing = Main:
+
+(* Then a comment *after* a command. Also one which mentions
+ the names of commands, such as theory or theorem or proof itself,
+ never mind thus assume end qed. *)
+
+text {* Isar theories can have arbitrary literal text,
+ so the text must be ignored as well; thus. *}
+
+(* Let's do my favourite proof. *)
+
+theorem and_comms: "A & B --> B & A"
+proof
+ assume "A & B" (* it's "important" that we test "strings" I guess *)
+ thus "B & A"
+ proof
+ assume A B (* blah boo bah *)
+ show ?thesis (* bah boo bah *)
+ ..
+ qed
+qed
+
+(* Now the end of file is coming up. Funny things happen
+ because PG only knows how commands start, not how they end.
+*)
+
+end
+(* That's the final command and it includes any text which follows it.
+ An oddity is that if there is a syntax error - unclosed comment
+ or whatever, after the last end, PG will say that it can't find
+ a complete command! *)
+
diff --git a/etc/isar/README b/etc/isar/README
new file mode 100644
index 00000000..b2f5ffb2
--- /dev/null
+++ b/etc/isar/README
@@ -0,0 +1,8 @@
+bad1.thy:
+ Bug test case: parser would silently skip bad command "foo".
+ Resolved as of 13.9.00
+
+bad2.thy:
+ Bug test case: synchronization problem on starting Isar process,
+ doesn't catch the first error.
+ Resolved as of 17.9.00
diff --git a/etc/isar/XEmacsSyntacticContextProb.thy b/etc/isar/XEmacsSyntacticContextProb.thy
new file mode 100644
index 00000000..d910a6ba
--- /dev/null
+++ b/etc/isar/XEmacsSyntacticContextProb.thy
@@ -0,0 +1,20 @@
+(* Demonstrates a bug with XEmacs 21.1: after procesing, between
+ two terms, buffer-syntactic-context returns "string".
+ But _before_ processing, it correctly returns "nil".
+ Even when regions are removed, still get "string" returned
+ after processing started.
+
+ Bug doesn't occur in GNU Emacs (using imp of buffer-syntactic context
+ provided in proof-compat.el), nor in XEmacs 21.4
+
+ Workaround added Fri Aug 10 13:55:28 BST 2001
+*)
+
+theory XEmacsSyntacticContextProb = Main:
+
+term "
+(f x)"
+
+term "(f x)"
+
+end
diff --git a/etc/isar/bad1.thy b/etc/isar/bad1.thy
new file mode 100644
index 00000000..a355389f
--- /dev/null
+++ b/etc/isar/bad1.thy
@@ -0,0 +1,3 @@
+(*foo*)
+foo
+end
diff --git a/etc/isar/bad2.thy b/etc/isar/bad2.thy
new file mode 100644
index 00000000..11fecd77
--- /dev/null
+++ b/etc/isar/bad2.thy
@@ -0,0 +1 @@
+theory A = unknown:
diff --git a/etc/isar/multiple/A.thy b/etc/isar/multiple/A.thy
new file mode 100644
index 00000000..7ad1ddf6
--- /dev/null
+++ b/etc/isar/multiple/A.thy
@@ -0,0 +1,7 @@
+
+theory A = Pure:;
+
+consts foo :: 'a;
+consts bar :: 'a;
+
+end;
diff --git a/etc/isar/multiple/B.thy b/etc/isar/multiple/B.thy
new file mode 100644
index 00000000..2828c655
--- /dev/null
+++ b/etc/isar/multiple/B.thy
@@ -0,0 +1,4 @@
+
+theory B = Pure:;
+
+end;
diff --git a/etc/isar/multiple/C.thy b/etc/isar/multiple/C.thy
new file mode 100644
index 00000000..d295f55a
--- /dev/null
+++ b/etc/isar/multiple/C.thy
@@ -0,0 +1,5 @@
+(* -*- isar -*- *)
+
+theory C = A + B:;
+
+end;
diff --git a/etc/isar/multiple/D.thy b/etc/isar/multiple/D.thy
new file mode 100644
index 00000000..ed405e30
--- /dev/null
+++ b/etc/isar/multiple/D.thy
@@ -0,0 +1,4 @@
+
+theory D = Pure:;
+
+end;
diff --git a/etc/isar/multiple/README b/etc/isar/multiple/README
new file mode 100644
index 00000000..ad57b449
--- /dev/null
+++ b/etc/isar/multiple/README
@@ -0,0 +1,3 @@
+
+Test files for multiple file handling with Isabelle/Isar
+(see also isa/multiple/README).
diff --git a/etc/isar/trace_simp.thy b/etc/isar/trace_simp.thy
new file mode 100644
index 00000000..430d37f5
--- /dev/null
+++ b/etc/isar/trace_simp.thy
@@ -0,0 +1,18 @@
+
+theory trace_simp = Main:
+
+text {*
+ this produces massive amount of simplifier trace, but terminates
+ eventually: *}
+
+ML {* set trace_simp *}
+ML {* reset quick_and_dirty *}
+
+datatype ord = Zero | Succ ord | Limit "nat => ord"
+
+
+text {* this one loops forever *}
+
+lemma "ALL x. f x = g(f(g(x))) ==> f [] = f [] @ []"
+ apply simp
+
diff --git a/etc/junk.el b/etc/junk.el
new file mode 100644
index 00000000..1ca27608
--- /dev/null
+++ b/etc/junk.el
@@ -0,0 +1,157 @@
+;;; junk.el
+;;;
+;;; $Id$
+;;;
+;;; Bits and pieces of code
+;;; removed from main PG (or never added).
+;;; Left here in case they're useful later.
+;;;
+;;; Also some testing code.
+;;;
+
+;;; TESTING FRAGMENTS
+
+;;; special display regexps
+(setq special-display-regexps
+ (cons "\\*isabelle-\\(goals\\|response\\)\\*"
+ special-display-regexps))
+
+
+;;; dump str to buffer ug for testing.
+(defun ugit (str)
+ (save-excursion
+ (set-buffer (get-buffer-create "ug"))
+ (goto-char (point-max))
+ (insert str)
+ (newline)
+ (newline)))
+
+
+
+
+;;; OLD CODE
+
+(defun proof-set-toggle (sym value)
+ "Try to set a boolean variable <blah>-enable using function <blah>-toggle."
+ (save-match-data
+ (let* ((nm (symbol-name sym))
+ (i (string-match "-enable" nm))
+ (tgfn (if i (intern (concat (substring nm 0 i) "-toggle")))))
+ (if (and tgfn (fboundp tgfn))
+ (funcall tgfn (if value 1 0))))))
+
+
+;; Was in proof-shell.el
+(defun proof-shell-popup-eager-annotation ()
+ "Process urgent messages.
+Eager annotations are annotations which the proof system produces
+while it's doing something (e.g. loading libraries) to say how much
+progress it's made. Obviously we need to display these as soon as they
+arrive."
+;; FIXME: highlight eager annotation-end : fix proof-shell-handle-output
+;; to highlight whole string.
+ (let ((str (proof-shell-handle-output
+ proof-shell-eager-annotation-start
+ proof-shell-eager-annotation-end
+ 'proof-eager-annotation-face))
+ (proof-shell-message str))))
+
+
+; (cond
+; ((string-match "FSF" emacs-version)
+; ;; setting font-lock-defaults explicitly is required by FSF Emacs
+; ;; 20.2's version of font-lock
+; (make-local-variable 'font-lock-defaults)
+; (setq font-lock-defaults '(font-lock-keywords)))
+; ;; In XEmacs, we must make a new variable to hold
+; ;; the defaults.
+; ;; (FIXME: this makes toggling font-lock robust now, before
+; ;; it was ropy. Should check whether this is the right
+; ;; was for FSF too).
+; (t
+; (let
+; ((flks (intern (concat (symbol-name major-mode)
+; "-font-lock-defaults"))))
+; ;; Take a copy of current font-lock-keywords to make them
+; ;; the default in future. Then font-lock-mode can be
+; ;; safely switched on and off.
+; (set flks font-lock-keywords)
+; (make-local-variable 'proof-font-lock-defaults)
+; (setq proof-font-lock-defaults font-lock-keywords)
+; (setq font-lock-defaults '(proof-font-lock-defaults)))))
+ ; (put major-mode 'font-lock-defaults (list flks)))))
+
+
+
+;; was is proof-shell, never used.
+(defun proof-shell-strip-eager-annotation-specials (string)
+ "Strip special eager annotations from STRING, returning cleaned up string.
+The input STRING should be annotated with expressions matching
+proof-shell-eager-annotation-start and eager-annotation-end.
+We only strip specials from the annotations."
+ (let* ((mstart (progn
+ (string-match proof-shell-eager-annotation-start string)
+ (match-end 0)))
+ (mend (string-match proof-shell-eager-annotation-end string))
+ (msg (substring string mstart mend))
+ (strtan (substring string 0 mstart))
+ (endan (substring string mend)))
+ (concat
+ (proof-shell-strip-special-annotations strtan)
+ msg
+ (proof-shell-strip-special-annotations endan))))
+
+
+
+;; 2. proof-find-and-forget-fn
+;;
+;; This calculates undo operations outwith a proof. If we retract
+;; before a "Goal" command, proof-kill-goal-command is sent, followed
+;; by whatever is calculated by this function.
+;;
+;; Isabelle has no concept of a linear context, and you can happily
+;; redeclare values in ML. So forgetting back to the declaration of a
+;; particular something makes no real sense.
+;; The function is given a trivial implementation in this case.
+;;
+;; Find LEGO or Coq's implementation of this function to see how to
+;; write it for proof assistants that can do this.
+
+
+
+;; FIXME: this is supposed to be a handy way of swapping
+;; between goals and response buffer. Never mind.
+;(defun proof-bury-buffer-after (buf)
+; (if (and (string-match "XEmacs" emacs-version) ; XEmacs speciality
+; (buffer-live-p buf))
+; (bury-buffer (current-buffer) buf)
+; (bury-buffer)))
+
+;(defun proof-bury-buffer-after-goals ()
+; (interactive)
+; (proof-bury-buffer-after proof-goals-buffer))
+
+
+
+;(defun proof-bury-buffer-after-response ()
+; (interactive)
+; (if proof-response-buffer
+; (with-current-buffer proof-response-buffer
+; (proof-bury-buffer-after proof-goals-buffer))))
+
+
+
+;; This was added in proof-config.el.
+;;
+;; Better strategy to be less zippy about adding hooks is this:
+;;
+;; 1. Only add a hook if it is needed in *generic* code
+;; 2. Only add a hook if it seems likely to be needed for different
+;; provers, with different effects.
+;;
+;; This hook doesn't meet criteria!
+
+(defcustom proof-xsym-toggle-hook '(proof-x-symbol-toggle-clean-buffers)
+ "Hooks run when X-Symbol support is turned on or off."
+ :type 'string
+ :group 'proof-x-symbol)
diff --git a/etc/lego/GoalGoal.l b/etc/lego/GoalGoal.l
new file mode 100644
index 00000000..c4826e0d
--- /dev/null
+++ b/etc/lego/GoalGoal.l
@@ -0,0 +1,13 @@
+Module GoalGoal;
+
+Goal first : {A:Prop}A->A;
+intros; Immed;
+(* no Save *)
+
+Goal second : {A:Prop}A->A;
+intros; Immed;
+Save second;
+(* asserting until here caused Proof General to swap first and second.
+This is a bug for LEGO. Thanks to Martin Hofmann for pointing this
+out. An obvious bug fix would be to make the function
+proof-lift-global Coq specific. *) \ No newline at end of file
diff --git a/etc/lego/error-eg.l b/etc/lego/error-eg.l
new file mode 100644
index 00000000..f6872c90
--- /dev/null
+++ b/etc/lego/error-eg.l
@@ -0,0 +1,16 @@
+Init LF;
+
+[prop:Type];
+[prf:prop->Type];
+[type:Type];
+[el:type->Type];
+
+[FA : {A:type}((el A) -> prop) -> prop];
+[LL : {A:type}{P:(el A) -> prop}
+ ({x:el A}prf(P(x)))->
+ (********************************)
+ prf(FA A P)];
+
+[P_FA : {A:type}{P:(el A) -> prop}{C_FA:prf(FA A P) -> prop}
+ ((g:{x:el A}prf(P(x)))prf(C_FA(LL A P g))) ->
+ {z:prf(FA A P)}prf(C_FA(z))]; \ No newline at end of file
diff --git a/etc/lego/lego-site.el b/etc/lego/lego-site.el
new file mode 100644
index 00000000..55098331
--- /dev/null
+++ b/etc/lego/lego-site.el
@@ -0,0 +1,23 @@
+;;; lego-site.el Site-specific Emacs support for LEGO
+;;; Copyright (C) 1998 LFCS Edinburgh
+;;; Author: Thomas Kleymann <T.Kleymann@ed.ac.uk>
+;;; Maintainer: lego@dcs.ed.ac.uk
+
+(let ((version (getenv "PROOFGENERAL")))
+ (cond ((not version) ;default
+ (setq load-path
+ (cons "/usr/local/share/elisp/script-management" load-path))
+ (setq load-path
+ (cons "/usr/local/share/elisp/script-management/lego" load-path))
+ (setq auto-mode-alist (cons '("\\.l$" . lego-mode) auto-mode-alist))
+ (autoload 'lego-mode "lego" "Major mode for editing Lego proof scripts." t))
+ ((string= version "ancient")
+ (setq load-path (cons "/usr/local/share/elisp/lego" load-path))
+ (setq auto-mode-alist (cons '("\\.l$" . lego-mode) auto-mode-alist))
+ (autoload 'lego-mode "lego" "Major mode for editing Lego proof scripts." t)
+ (autoload 'lego-shell "lego" "Inferior shell invoking lego." t))
+ ((string= version "latest")
+ (load-file "/usr/local/share/elisp/ProofGeneral/generic/proof-site.el"))))
+
+
+ \ No newline at end of file
diff --git a/etc/lego/long-line-backslash.l b/etc/lego/long-line-backslash.l
new file mode 100644
index 00000000..c85dcdc6
--- /dev/null
+++ b/etc/lego/long-line-backslash.l
@@ -0,0 +1,22 @@
+(*
+
+ long-line-backslash.l
+
+ Test for long lines with backslashes in them.
+ Cause problem with pty communication where line length
+ is limited to 256 characters sometimes (e.g. on Solaris).
+
+*)
+
+echo "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\";
+
+(* Test subsequent commands can be processed *)
+
+[one = Prop];
+[two = Prop -> Prop];
+[three = Prop -> two];
+
+(* Test something with eager annotations *)
+
+Make "/usr/local/share/lego/lib-alpha/lib_Type/lib_logic";
+
diff --git a/etc/lego/multiple/A.l b/etc/lego/multiple/A.l
new file mode 100644
index 00000000..d45f8db8
--- /dev/null
+++ b/etc/lego/multiple/A.l
@@ -0,0 +1 @@
+Module A; \ No newline at end of file
diff --git a/etc/lego/multiple/B.l b/etc/lego/multiple/B.l
new file mode 100644
index 00000000..3a8df7b2
--- /dev/null
+++ b/etc/lego/multiple/B.l
@@ -0,0 +1,4 @@
+(* B.l Module with a comment *)
+Module B;
+
+[prop = Prop]; \ No newline at end of file
diff --git a/etc/lego/multiple/C.l b/etc/lego/multiple/C.l
new file mode 100644
index 00000000..5a3afdd6
--- /dev/null
+++ b/etc/lego/multiple/C.l
@@ -0,0 +1 @@
+Module C Import A B; \ No newline at end of file
diff --git a/etc/lego/multiple/D.l b/etc/lego/multiple/D.l
new file mode 100644
index 00000000..b794253b
--- /dev/null
+++ b/etc/lego/multiple/D.l
@@ -0,0 +1 @@
+Module D; \ No newline at end of file
diff --git a/etc/lego/multiple/README b/etc/lego/multiple/README
new file mode 100644
index 00000000..11f2152a
--- /dev/null
+++ b/etc/lego/multiple/README
@@ -0,0 +1,33 @@
+Handling of Multiple Files
+==========================
+
+[C depends on A and B]
+
+Notation: A means that buffer A.l is unlocked
+ A+ means that buffer A.l is partly locked
+ A* means that buffer A.l is locked
+ ? means that behaviour might be different for proof systems
+ with non-linear contexts
+
+
+Test Protocol
+-------------
+
+ 1) visit A.l EFFECTS A
+ 2) visit C.l EFFECTS A C
+ 3) assert C EFFECTS A* C*
+ 4) visit B.l EFFECTS A* B* C*
+ 5) visit D.l EFFECTS A* B* C* D
+ 6) retract to middle of B EFFECTS A* B C D
+ 7) assert first command of B EFFECTS A* B+ C D
+ 8) assert C EFFECTS A* B+ C D [error message]
+ 9) assert B EFFECTS A* B* C D
+10) assert D EFFECTS A* B* C D*
+11) retract B EFFECTS A* B C D?
+12) assert C EFFECTS A* B* C* D?
+13) retract B EFFECTS A* B C D?
+14) assert B EFFECTS A* B* C D?
+15) assert C EFFECTS A* B* C* D?
+16) retract to middle of B EFFECTS A* B+ C D?
+14) M-x proof-shell-restart EFFECTS A B C D
+
diff --git a/etc/lego/unsaved-goals.l b/etc/lego/unsaved-goals.l
new file mode 100644
index 00000000..dd9c9646
--- /dev/null
+++ b/etc/lego/unsaved-goals.l
@@ -0,0 +1,54 @@
+(*
+ Some test cases for closing off unsaved goals,
+ and the setting proof-completed-proof-behaviour.
+
+ David Aspinall, November 1999.
+
+ Things work fairly well in lego with
+
+ proof-completed-proof-behaviour='closeany
+
+ In that case, undoing/redoing later declarations
+ (E and F) following the completed proof works okay, and
+ in the absence of declarations, things work fine.
+
+ Declarations in LEGO are global, and forgetting a
+ declaration when a proof is still open (even if complete)
+ aborts the proof! So a proper handling would need to
+ trigger a *further* retraction when the "Forget D" is
+ issued undoing the definition of D. Never mind.
+
+ With proof-completed-proof-behaviour='closegoal or 'extend,
+ undoing the first goal doesn't forget the declarations.
+
+ This file even causes internal errors in LEGO!
+
+ Warning: forgetting a finished proof
+
+ LEGO detects unexpected exception named "InfixInternal"
+
+ Test with undoing and redoing, and various settings
+ for proof-completed-proof-behaviour
+*)
+
+
+
+Module unsaved Import lib_logic;
+
+Goal {A,B:Prop}(and A B) -> (and B A);
+intros;
+Refine H;
+intros;
+andI;
+Immed;
+[D = Type];
+[E = Type];
+[F = Type];
+
+Goal {A,B:Prop}(and A B) -> (and B A);
+intros;
+Refine H;
+intros;
+andI;
+Immed;
+
diff --git a/etc/patches/duplicated-short-messages-fix.txt b/etc/patches/duplicated-short-messages-fix.txt
new file mode 100644
index 00000000..45b8727f
--- /dev/null
+++ b/etc/patches/duplicated-short-messages-fix.txt
@@ -0,0 +1,107 @@
+This change should have gone into 3.0, but I forgot to make the
+setting and so it missed testing.
+
+Minor bug without it is that Isabelle (others?) will sometimes
+display messages less than 10 characters long twice, since
+the urgent message scanner gets moved too far back.
+
+Sould probably also add this fix in proof-shell/proof-shell-insert:
+
+ ;; FIXME: possible improvement. Make for post 3.0 releases
+ ;; in case of problems.
+ ;; (set-marker proof-shell-urgent-message-marker (point))
+ ;; (set-marker proof-shell-urgent-message-scanner (point))
+
+ - da.
+
+
+
+
+? etc/duplicated-short-messages-fix.txt
+Index: coq/coq.el
+===================================================================
+RCS file: /home/proofgen/src/ProofGeneral/coq/coq.el,v
+retrieving revision 3.0
+diff -c -r3.0 coq.el
+*** coq.el 1999/11/17 20:39:08 3.0
+--- coq.el 1999/11/29 13:22:14
+***************
+*** 502,507 ****
+--- 502,508 ----
+ proof-shell-field-char ?\374 ; not done
+ proof-shell-goal-char ?\375 ; done
+ proof-shell-eager-annotation-start "\376" ; done
++ proof-shell-eager-annotation-start-length 1
+ proof-shell-eager-annotation-end "\377" ; done
+ proof-shell-annotated-prompt-regexp
+ (concat proof-shell-prompt-pattern
+Index: isa/isa.el
+===================================================================
+RCS file: /home/proofgen/src/ProofGeneral/isa/isa.el,v
+retrieving revision 3.4
+diff -c -r3.4 isa.el
+*** isa.el 1999/11/29 12:14:05 3.4
+--- isa.el 1999/11/29 13:22:15
+***************
+*** 172,177 ****
+--- 172,178 ----
+ proof-shell-quit-cmd "quit();"
+
+ proof-shell-eager-annotation-start "\360\\|\362"
++ proof-shell-eager-annotation-start-length 1
+ proof-shell-eager-annotation-end "\361\\|\363"
+
+ ;; Some messages delimited by eager annotations
+Index: isar/isar.el
+===================================================================
+RCS file: /home/proofgen/src/ProofGeneral/isar/isar.el,v
+retrieving revision 3.1
+diff -c -r3.1 isar.el
+*** isar.el 1999/11/18 15:00:57 3.1
+--- isar.el 1999/11/29 13:22:15
+***************
+*** 250,255 ****
+--- 250,256 ----
+ proof-shell-restart-cmd "ProofGeneral.restart;"
+ proof-shell-quit-cmd (isar-verbatim "quit();")
+
++ proof-shell-eager-annotation-start-length 1
+ proof-shell-eager-annotation-start "\360\\|\362"
+ proof-shell-eager-annotation-end "\361\\|\363"
+
+Index: lego/lego.el
+===================================================================
+RCS file: /home/proofgen/src/ProofGeneral/lego/lego.el,v
+retrieving revision 3.1
+diff -c -r3.1 lego.el
+*** lego.el 1999/11/24 21:48:24 3.1
+--- lego.el 1999/11/29 13:22:16
+***************
+*** 453,458 ****
+--- 453,459 ----
+ proof-shell-field-char ?\374
+ proof-shell-goal-char ?\375
+ proof-shell-eager-annotation-start "\376"
++ proof-shell-eager-annotation-start-length 1
+ proof-shell-eager-annotation-end "\377"
+ proof-shell-annotated-prompt-regexp "Lego> \371"
+ proof-shell-result-start "\372 Pbp result \373"
+Index: plastic/plastic.el
+===================================================================
+RCS file: /home/proofgen/src/ProofGeneral/plastic/plastic.el,v
+retrieving revision 3.1
+diff -c -r3.1 plastic.el
+*** plastic.el 1999/11/22 18:52:47 3.1
+--- plastic.el 1999/11/29 13:22:16
+***************
+*** 538,543 ****
+--- 538,546 ----
+ proof-shell-field-char ?\374
+ proof-shell-goal-char ?\375
+ proof-shell-eager-annotation-start "\376"
++ ;; FIXME da: if p-s-e-a-s is implemented, you should set
++ ;; proof-shell-eager-annotation-start-length=1 to
++ ;; avoid possibility of duplicating short messages.
+ proof-shell-eager-annotation-end "\377"
+
+ proof-shell-annotated-prompt-regexp "LF> \371"
diff --git a/etc/patches/fix-attempt-for-eager-cleaning.txt b/etc/patches/fix-attempt-for-eager-cleaning.txt
new file mode 100644
index 00000000..519df708
--- /dev/null
+++ b/etc/patches/fix-attempt-for-eager-cleaning.txt
@@ -0,0 +1,66 @@
+Patch below doesn't work because it examines the head of the
+proof-action-list which is empty by the time
+proof-handle-delayed-output gets called!
+
+Best thing may be to temporarily extend
+proof-handle-delayed-output-hook with a function to clear the erase
+flag... BUT can't remove it from proof-shell-done-invisible,
+because that's too early!!! Argh.
+
+Maybe we need a special test in the exec loop for just one element in
+the action list, and then call the callback *after* handling delayed
+output?
+
+Um. Not for 3.0, then.
+
+
+
+
+*** ProofGeneral.prev/generic/proof-shell.el Thu Nov 18 13:07:33 1999
+--- ProofGeneral/generic/proof-shell.el Thu Nov 18 13:03:25 1999
+***************
+*** 676,682 ****
+ ;; Erase the response buffer if need be, maybe also removing the
+ ;; window. Indicate that it should be erased before the next
+ ;; output.
+! (proof-shell-maybe-erase-response t t)
+
+ (set-buffer proof-goals-buffer)
+
+--- 676,684 ----
+ ;; Erase the response buffer if need be, maybe also removing the
+ ;; window. Indicate that it should be erased before the next
+ ;; output.
+! (proof-shell-maybe-erase-response
+! (or proof-shell-erase-response-flag t) ; preserve invisible cmd o/p
+! t)
+
+ (set-buffer proof-goals-buffer)
+
+***************
+*** 829,835 ****
+ (unless proof-shell-leave-annotations-in-output
+ (setq str (proof-shell-strip-special-annotations str)))
+
+! (proof-shell-maybe-erase-response t nil)
+ (proof-response-buffer-display str)
+ (proof-display-and-keep-buffer proof-response-buffer))
+ ;;
+--- 831,847 ----
+ (unless proof-shell-leave-annotations-in-output
+ (setq str (proof-shell-strip-special-annotations str)))
+
+! (proof-shell-maybe-erase-response
+! ;; Magical detection of invisible commands, whose output
+! ;; gets preserved specially.
+! (if (and
+! (not (eq proof-shell-erase-response-flag 'invisible))
+! (eq (nth 2 (car-safe proof-action-list))
+! 'proof-shell-done-invisible))
+! 'invisible
+! t) ; erase next time, probably
+! t) ; clean.
+!
+ (proof-response-buffer-display str)
+ (proof-display-and-keep-buffer proof-response-buffer))
+ ;;
diff --git a/etc/pgkit/xmltest1.xml b/etc/pgkit/xmltest1.xml
new file mode 100644
index 00000000..08ff0984
--- /dev/null
+++ b/etc/pgkit/xmltest1.xml
@@ -0,0 +1,3 @@
+<a>test a<b>test b<c>test</c></b>end test a</a>
+
+
diff --git a/etc/pgkit/xmltest2.xml b/etc/pgkit/xmltest2.xml
new file mode 100644
index 00000000..cfc8b1e8
--- /dev/null
+++ b/etc/pgkit/xmltest2.xml
@@ -0,0 +1,23 @@
+<root>
+ <q req_id="default_id"/>
+ <p fixed="bad fixed value" enum="bad enum"/>
+ <p>
+ <b/>
+ <c>
+ <unexpected/>
+ <undefined/>
+ </c>
+ <q req_id="unreferenced_id"/>
+ </p>
+ <n nmtoken="1bad nmtoken"/>
+ <n nmtoken="default_nmtoken"/>
+ <n/>
+ <nn nmtokens="1bad nmtokens"/>
+ <nn nmtokens="default_nmtoken"/>
+ <nn/>
+ <bad_id bad_idref="1bad ID"/>
+ <bad_id/>
+ <bad_ent bad_ent="1bad ENTITY"/>
+ <bad_ent/>
+ <empty>text in empty</empty>
+</root>
diff --git a/etc/profiling.txt b/etc/profiling.txt
new file mode 100644
index 00000000..434b0bfd
--- /dev/null
+++ b/etc/profiling.txt
@@ -0,0 +1,397 @@
+Notes on Profiling Proof General in XEmacs [da]
+------------------------------------------------
+
+M-x clear-profiling-info
+Eval: (profile (proof-toolbar-next) (proof-shell-wait))
+M-x profile-results
+
+NB: Must ignore calls to accept-process-output and sit-for, these
+ are from proof-shell-wait (only).
+
+
+Testing by processing first line of src/HOL/Real/ROOT.ML (i.e. loading
+RealDef)
+
+Best case scenarios:
+
+ * Running Isabelle in ordinary shell buffer in Emacs, PIII:
+ ~8% Emacs (PIII), ~90% SML if shell hidden
+ ~15% X, ~25% xemacs, ~60% SML if shell displayed!
+
+ * Running Isabelle in xterm:
+ ~3% xterm, ~2% X, 95% SML if xterm hidden
+ ~4% xterm, ~16% X, 90% SML if xterm revealed
+
+
+Before optimization:
+
+ * CPU time split about 70%/30% (Cel 366) or 65%/35% (PIII 500) SML/xemacs
+
+
+
+
+
+
+
+
+Sample Runs. Tue Oct 5
+-----------------------
+
+[On Cel 366 64M]
+
+
+Function Name Ticks %/Total Call Count
+=================================== ===== ======= ==========
+(in redisplay) 1183 44.947
+re-search-forward 901 34.233 8061
+sit-for 159 6.041 11919
+comint-output-filter 93 3.533 3596
+accept-process-output 43 1.634 11919
+string-match 34 1.292 7300
+font-lock-pre-idle-hook 30 1.140 25261
+insert-before-markers 28 1.064 3597
+let 14 0.532 10853
+map-extents 13 0.494 539
+(in garbage collection) 10 0.380
+byte-code 9 0.342 25376
+while 8 0.304 3648
+setq 7 0.266 8299
+comint-postoutput-scroll-to-bottom 7 0.266 3597
+next-window 6 0.228 7194
+put-nonduplicable-text-property 5 0.190 1166
+marker-position 5 0.190 14389
+goto-char 5 0.190 14097
+walk-windows 4 0.152 3597
+window-minibuffer-p 4 0.152 3597
+proof-toolbar-refresh 4 0.152 3686
+and 4 0.152 11162
+selected-window 3 0.114 14390
+window-start 3 0.114 3596
+proof-shell-filter 3 0.114 3597
+itimer-time-difference 3 0.114 546
+#<compiled-function (window) "...(134)" [window-buffer window current window-point process-mark process scroll t all this selected others string set-window-point comint-scroll-show-maximum-output pos-visible-in-window-p recenter floatp floor window-height 1 -1 sit-for 0] 4> 3 0.114 7194
+#<compiled-function (place &optional x) "...(29)" [place setq x + 1+ callf 1] 5 553442> 3 0.114 1298
+process-buffer 3 0.114 3596
+point 3 0.114 7382
+or 3 0.114 7256
+comint-watch-for-password-prompt 3 0.114 3597
+save-excursion 2 0.076 3655
+proof-shell-process-urgent-messages 2 0.076 3597
+marker-buffer 2 0.076 3596
+font-lock-fontify-keywords-region 2 0.076 45
+process-mark 2 0.076 7208
+redisplay-echo-area 2 0.076 23
+if 2 0.076 18901
+buffer-name 1 0.038 3650
+erase-buffer 1 0.038 26
+pos-visible-in-window-p 1 0.038 1
+window-buffer 1 0.038 7195
+self-insert-command 1 0.038 14
+< 1 0.038 4300
+itimer-timer-driver 1 0.038 182
+font-lock-fontify-glumped-region 1 0.038 31
+get-buffer-process 1 0.038 3633
+char-to-string 1 0.038 3597
+save-current-buffer 1 0.038 17
+insert-string 1 0.038 23
+--------------------------------------------------------------------
+Total 2632 100.00
+
+
+One tick = 1 ms
+
+
+[On PIII 256M] top shows roughly 65% SML / 35% xemacs.
+
+Function Name Ticks %/Total Call Count
+====================================== ===== ======= ==========
+(in redisplay) 3529 55.166
+re-search-forward 1520 23.761 31627
+sit-for 356 5.565 33870
+comint-output-filter 265 4.143 12980
+accept-process-output 125 1.954 33870
+font-lock-pre-idle-hook 67 1.047 73094
+insert-before-markers 51 0.797 12981
+(in garbage collection) 46 0.719
+string-match 44 0.688 27686
+byte-code 27 0.422 74822
+let 23 0.360 39724
+#<compiled-function (window) "...(134)" [window-buffer window current window-point process-mark process scroll t all this selected others string set-window-point comint-scroll-show-maximum-output pos-visible-in-window-p recenter floatp floor window-height 1 -1 sit-for 0] 4> 21 0.328 25962
+selected-window 20 0.313 51951
+comint-postoutput-scroll-to-bottom 19 0.297 12981
+setq 15 0.234 39971
+if 15 0.234 72709
+walk-windows 13 0.203 12981
+proof-toolbar-refresh 13 0.203 14429
+marker-position 12 0.188 51925
+proof-shell-filter 12 0.188 12981
+goto-char 12 0.188 53685
+run-hook-with-args 12 0.188 13219
+next-window 11 0.172 25962
+and 9 0.141 40761
+save-excursion 8 0.125 13756
+buffer-name 7 0.109 13783
+window-buffer 7 0.109 26077
+log-message 7 0.109 237
+process-mark 7 0.109 26208
+point 7 0.109 27554
+while 7 0.109 13727
+#<compiled-function (place &optional x) "...(29)" [place setq x + 1+ callf 1] 5 553442> 6 0.094 11268
+char-to-string 6 0.094 12981
+force-mode-line-update 6 0.094 12980
+< 5 0.078 19216
+itimer-run-expired-timers 4 0.063 415
+aref 4 0.063 11953
+get-buffer-process 4 0.063 13290
+proof-shell-process-urgent-messages 4 0.063 12981
+redisplay-echo-area 4 0.063 238
+insert-string 4 0.063 238
+font-lock-fontify-keywords-region 4 0.063 740
+window-minibuffer-p 3 0.047 12981
+window-start 3 0.047 12980
+marker-buffer 3 0.047 12980
+process-buffer 3 0.047 12980
+featurep 3 0.047 2120
+comint-watch-for-password-prompt 3 0.047 12981
+set-buffer 2 0.031 259
+or 2 0.031 26285
+font-lock-after-change-function-1 2 0.031 494
+font-lock-default-fontify-region 2 0.031 740
+event-over-toolbar-p 1 0.016 107
+get-buffer 1 0.016 433
+extent-object 1 0.016 988
+itimerp 1 0.016 9136
+itimer-is-idle 1 0.016 3735
+set-extent-property 1 0.016 1024
+make-string 1 0.016 247
+next-single-property-change 1 0.016 246
+expand-file-name 1 0.016 96
+incf 1 0.016 11268
+center-to-window-line 1 0.016 9
+proof-done-advancing 1 0.016 2
+itimer-time-difference 1 0.016 1660
+itimer-timer-driver 1 0.016 415
+1+ 1 0.016 11268
+length 1 0.016 249
+append-message 1 0.016 238
+concat 1 0.016 246
+proof-shell-strip-special-annotations 1 0.016 246
+proof-shell-process-urgent-message 1 0.016 246
+buffer-substring 1 0.016 493
+save-current-buffer 1 0.016 248
+newline 1 0.016 246
+insert 1 0.016 249
+current-time 1 0.016 831
+match-beginning 1 0.016 247
+font-lock-append-text-property 1 0.016 246
+progn 1 0.016 1034
+proof-response-buffer-display 1 0.016 246
+font-lock-fontify-syntactically-region 1 0.016 740
+font-lock-fontify-glumped-region 1 0.016 494
+#<compiled-function (buffer &rest body) "...(8)" [save-current-buffer set-buffer buffer body] 3 540150> 1 0.016 248
+font-lock-after-change-function 1 0.016 494
+-----------------------------------------------------------------------
+Total 6397 100.00
+
+
+One tick = 1 ms
+
+
+*** After some optimization attempt in proof-shell-process-urgent-messages,
+ to remove re-search-forward hog:
+
+[Cel 366]
+
+Function Name Ticks %/Total Call Count
+=================================== ===== ======= ==========
+accept-process-output 3279 62.374 1047436
+(in redisplay) 919 17.481
+sit-for 547 10.405 1047435
+re-search-forward 134 2.549 8950
+while 110 2.092 3648
+comint-output-filter 65 1.236 3347
+(in garbage collection) 24 0.457
+font-lock-pre-idle-hook 18 0.342 14166
+insert-before-markers 15 0.285 3348
+string-match 10 0.190 7376
+let 9 0.171 7010
+#<compiled-function (window) "...(134)" [window-buffer window current window-point process-mark process scroll t all this selected others string set-window-point comint-scroll-show-maximum-output pos-visible-in-window-p recenter floatp floor window-height 1 -1 sit-for 0] 4> 9 0.171 6696
+setq 6 0.114 12598
+byte-code 5 0.095 14879
+#<compiled-function (place &optional x) "...(29)" [place setq x + 1+ callf 1] 5 553442> 5 0.095 4762
+and 5 0.095 10936
+comint-postoutput-scroll-to-bottom 5 0.095 3348
+log-message 4 0.076 98
+save-excursion 3 0.057 3655
+itimerp 3 0.057 14128
+selected-window 3 0.057 13403
+next-window 3 0.057 6696
+point 3 0.057 10722
+proof-toolbar-refresh 3 0.057 3942
+if 3 0.057 23233
+font-lock-default-unfontify-region 3 0.057 295
+walk-windows 2 0.038 3348
+event-window 2 0.038 658
+buffer-name 2 0.038 3670
+erase-buffer 2 0.038 105
+put-nonduplicable-text-property 2 0.038 590
+window-start 2 0.038 3347
+null 2 0.038 3352
+marker-position 2 0.038 13393
+marker-buffer 2 0.038 3347
+itimer-time-difference 2 0.038 2223
+- 2 0.038 3350
+font-lock-fontify-keywords-region 2 0.038 295
+goto-char 2 0.038 14092
+buffer-substring 2 0.038 196
+redisplay-echo-area 2 0.038 104
+run-hook-with-args 2 0.038 3447
+comint-watch-for-password-prompt 2 0.038 3348
+event-over-vertical-divider-p 1 0.019 254
+event-glyph-extent 1 0.019 329
+get-buffer 1 0.019 255
+pointer-image-instance-p 1 0.019 985
+barf-if-buffer-read-only 1 0.019 98
+extent-at 1 0.019 87
+itimer-value 1 0.019 6175
+pos-visible-in-window-p 1 0.019 4
+expand-file-name 1 0.019 192
+file-truename 1 0.019 104
+center-to-window-line 1 0.019 4
+proof-shell-process-urgent-messages 1 0.019 3348
+proof-shell-filter 1 0.019 3348
+set-marker 1 0.019 3429
+itimer-run-expired-timers 1 0.019 247
+< 1 0.019 5950
+min 1 0.019 3428
+1- 1 0.019 3428
+display-message 1 0.019 99
+font-lock-fontify-glumped-region 1 0.019 197
+get-buffer-process 1 0.019 6791
+process-mark 1 0.019 10124
+default-mouse-motion-handler 1 0.019 329
+char-to-string 1 0.019 3348
+save-current-buffer 1 0.019 99
+newline 1 0.019 98
+or 1 0.019 3490
+#<compiled-function (buffer &rest body) "...(8)" [save-current-buffer set-buffer buffer body] 3 540150> 1 0.019 99
+font-lock-unfontify-region 1 0.019 295
+specifier-instance 1 0.019 329
+--------------------------------------------------------------------
+Total 5257 100.00
+
+
+One tick = 1 ms
+
+
+[PIII] split now about 70%/30%
+
+Function Name Ticks %/Total Call Count
+====================================== ===== ======= ==========
+(in redisplay) 3638 72.082
+sit-for 358 7.093 34176
+comint-output-filter 247 4.894 12963
+accept-process-output 132 2.615 34176
+font-lock-pre-idle-hook 70 1.387 74389
+insert-before-markers 67 1.328 12964
+string-match 50 0.991 27655
+(in garbage collection) 43 0.852
+#<compiled-function (window) "...(134)" [window-buffer window current window-point process-mark process scroll t all this selected others string set-window-point comint-scroll-show-maximum-output pos-visible-in-window-p recenter floatp floor window-height 1 -1 sit-for 0] 4> 29 0.575 25928
+re-search-forward 25 0.495 18630
+comint-postoutput-scroll-to-bottom 24 0.476 12964
+byte-code 22 0.436 76129
+selected-window 20 0.396 51883
+walk-windows 19 0.376 12964
+let 18 0.357 13746
+next-window 16 0.317 25928
+proof-toolbar-refresh 13 0.258 14445
+while 13 0.258 13710
+proof-shell-filter 11 0.218 12964
+process-mark 11 0.218 39137
+save-excursion 10 0.198 13741
+setq 10 0.198 27010
+and 9 0.178 27701
+goto-char 8 0.159 27695
+run-hook-with-args 8 0.159 13211
+if 7 0.139 33491
+font-lock-fontify-keywords-region 6 0.119 740
+#<compiled-function (place &optional x) "...(29)" [place setq x + 1+ callf 1] 5 553442> 6 0.119 11268
+get-buffer-process 6 0.119 26242
+char-to-string 6 0.119 12964
+redisplay-echo-area 6 0.119 253
+specifier-instance 6 0.119 656
+itimerp 5 0.099 5713
+1- 5 0.099 13209
+point 5 0.099 27523
+buffer-name 4 0.079 13766
+current-buffer 4 0.079 13210
+window-start 4 0.079 12963
+< 4 0.079 6236
+itimer-timer-driver 4 0.079 380
+default-mouse-motion-handler 4 0.079 656
+featurep 4 0.079 2693
+force-mode-line-update 4 0.079 12963
+comint-watch-for-password-prompt 4 0.079 12964
+proof-shell-process-urgent-messages 3 0.059 12964
+font-lock-fontify-syntactically-region 3 0.059 740
+incf 3 0.059 11268
+marker-position 3 0.059 12968
+set-marker 3 0.059 13210
+itimer-time-difference 3 0.059 1140
+process-buffer 3 0.059 12963
+event-window 2 0.040 1312
+window-minibuffer-p 2 0.040 12964
+window-buffer 2 0.040 26524
+- 2 0.040 12967
+move-to-left-margin 2 0.040 246
+remove-message 2 0.040 253
+event-buffer 2 0.040 656
+font-lock-default-unfontify-region 2 0.040 740
+font-lock-after-change-function 2 0.040 494
+buffer-substring 2 0.040 493
+insert-string 2 0.040 253
+event-over-modeline-p 1 0.020 537
+event-glyph-extent 1 0.020 656
+set-syntax-table 1 0.020 740
+pointer-image-instance-p 1 0.020 1913
+extent-start-position 1 0.020 494
+make-extent 1 0.020 527
+detach-extent 1 0.020 495
+extent-at 1 0.020 363
+itimer-value 1 0.020 2660
+itimer-is-idle 1 0.020 2280
+set-extent-property 1 0.020 1024
+highlight-extent 1 0.020 656
+pos-visible-in-window-p 1 0.020 9
+glyph-property-instance 1 0.020 656
+get-text-property 1 0.020 492
+put-nonduplicable-text-property 1 0.020 1480
+next-single-property-change 1 0.020 246
+quote 1 0.020 13798
+marker-buffer 1 0.020 12963
+itimer-run-expired-timers 1 0.020 380
+aset 1 0.020 5280
+log-message 1 0.020 246
+min 1 0.020 13209
+current-left-margin 1 0.020 246
+display-message 1 0.020 246
+fw-frame 1 0.020 656
+font-lock-fontify-region 1 0.020 740
+font-lock-append-text-property 1 0.020 246
+substring 1 0.020 247
+proof-response-buffer-display 1 0.020 246
+delq 1 0.020 246
+syntactically-sectionize 1 0.020 740
+format 1 0.020 238
+proof-file-truename 1 0.020 88
+newline 1 0.020 246
+store-match-data 1 0.020 742
+proof-zap-commas-region 1 0.020 494
+specifierp 1 0.020 656
+log-message-filter 1 0.020 246
+-----------------------------------------------------------------------
+Total 5047 100.00
+
+
+One tick = 1 ms
+
diff --git a/etc/proofgeneral-domain.txt b/etc/proofgeneral-domain.txt
new file mode 100644
index 00000000..7b5b3c48
--- /dev/null
+++ b/etc/proofgeneral-domain.txt
@@ -0,0 +1,29 @@
+Notes about proofgeneral.org
+----------------------------
+
+Hosted by freeparking.co.uk.
+
+Sign up 20th Sep 2000, 2 years for £29.95
+
+mail.proofgeneral.org is freeparking's mail handler
+www.proofgeneral.org is zermelo.dcs.ed.ac.uk
+
+ DNS zone:
+
+ proofgeneral.org A 129.215.96.75
+
+Email aliases:
+--------------
+
+support proofgen@dcs.ed.ac.uk
+feedback proofgen@dcs.ed.ac.uk
+bugs proofgen@dcs.ed.ac.uk
+users proofgeneral@dcs.ed.ac.uk
+devel proofgeneral-devel@dcs.ed.ac.uk
+majordomo majordomo@dcs.ed.ac.uk
+da da@dcs.ed.ac.uk
+
+
+
+
+
diff --git a/etc/release-log.txt b/etc/release-log.txt
new file mode 100644
index 00000000..8c9c3986
--- /dev/null
+++ b/etc/release-log.txt
@@ -0,0 +1,68 @@
+9.9.01 3.3 Release 3-3 based on branch 6.0
+ (repeated 10.9.01 to fix doc build)
+
+--------------------
+
+02.10.00 3.2 Release 3-2 based on branch 5.0
+
+--------------------
+
+25.05.00 3.1.6 Release 3-1-6, from Release-3-1-branch
+ Button enablers are not used by default on XEmacs/Solaris.
+ When button enablers disabled, don't use itimer or after-change hook.
+
+9.05.00 3.1.5 Release 3-1-5, from Release-3-1-branch
+ Improved proof-find-theorems-command for Isabelle
+ (allow multiple constants separated by commas).
+
+28.04.00 3.1.4 Release 3-1-4, from Release-3-1-branch
+ Applied patch sent by Mike Squire, fix accident in previous fix.
+ (Isabelle theory retraction file paths)
+
+04.04.00 3.1.3 Release 3-1-3
+ Fixed two problems with Isabelle theory loader interface
+ (first introduced accidently in 3.1, second a bug/issue in Isabelle)
+ Markus's continuing Isar syntax patches.
+ Updated some copyright notices.
+
+24.03.00 3.1.2 Release 3-1-2
+ Small improvement to HOL support.
+
+24.03.00 3.1.1 Release 3-1-1
+ Added more fixes for Isabelle and Windows.
+ Fixes for Windows, using proper colours, etc.
+ Markus's Isar syntax patches.
+
+23.03.00 3.1 Release 3-1
+ First version of 3.1 release
+
+--------------------
+
+
+30.11.99 3.0.3 Release-3-0-3
+ Full version now in version stamp.
+
+29.11.99 3.0.2 Release-3-0-2
+ Added some more key-bindings and menu entries to
+ Isabelle's theory file mode.
+
+26.11.99 3.0 Release 3-0
+ First attempt at 3.0 release
+
+ 3.0.1 Release-3-0-1
+ Fixed problem with proof-shell-proof-completed-regexp
+ in Isabelle.
+
+
+--------------------
+
+
+25.8.99 2.1.3 Release-2-1-3
+ Fixed RPM package to include isar/
+
+24.8.99 2.1.2 Release-2-1-2
+ Official release Proof General 2.1
+
+23.8.99 2.1.1 Release-2-1-1
+ First release of Proof General version 2.1.
+ Missing Isar and with broken version stamp (2.1pre990820)
diff --git a/etc/screenshot-notes.txt b/etc/screenshot-notes.txt
new file mode 100644
index 00000000..3a0daff6
--- /dev/null
+++ b/etc/screenshot-notes.txt
@@ -0,0 +1,36 @@
+Screenshot notes.
+=================
+
+All in 80x40 sized XEmacs.
+
+* Isabelle: Dagstuhl HOLCF example. Show theory file on screen too.
+
+* Isar: Example Group.thy is modified version with extra X-Symbol line:
+
+syntax (xsymbols)
+ "op *" :: "['a::times, 'a] => 'a" (infixl "\\<bullet>" 70);
+
+And uses of * replaced with \\<bullet>.
+
+* Coq: Example from Sorting library. Multiple frame mode, X-Symbols,
+also with Netscape.
+
+Most shots scaled to 0.2 or thereabouts to give nice sized thumbnail.
+
+
+
+
+
+
+-----------------------------------------------------------------
+
+Regenerating screen shot in html/IsaPGscreen.jpg:
+
+ 30x80 sized XEmacs. Visit isa/example.ML.
+ Click on "next" button four times.
+ Drag middle modeline to display whole proof script.
+ Move point to end of locked region.
+ Grab with gimp, Xtns -> Screen Shot.
+ Save with default quality settings.
+
+----------------------------------------------------------------- \ No newline at end of file
diff --git a/etc/test-schedule.txt b/etc/test-schedule.txt
new file mode 100644
index 00000000..700cf5ca
--- /dev/null
+++ b/etc/test-schedule.txt
@@ -0,0 +1,19 @@
+Some test schedules for Proof General
+=====================================
+
+$Id$
+
+(in progress)
+
+--------------------
+
+Desirable tests:
+
+* Settings mechanism; PROOFGENERAL_ASSISTANTS vs .emacs and
+ customize-set-variable, interaction with Isabelle startup
+ scripts.
+
+
+
+
+
diff --git a/etc/testing-log.txt b/etc/testing-log.txt
new file mode 100644
index 00000000..324284d4
--- /dev/null
+++ b/etc/testing-log.txt
@@ -0,0 +1,142 @@
+Fri Mar 24 15:40:10 GMT 2000 da
+
+ Tested Proof General on win32 (NT4sp6) with Isabelle, Coq and
+ XEmacs 21.1.9.
+
+ Problems: Isabelle bombs on paths containing chars like \ : $
+ XEmacs barfs on reading some files in PG, why??
+ e.g. coq/coq.el
+
+ Can fix this by reloading coq stuff again.
+
+ A few probs remain, e.g. toolbar enablers for undo are
+ flaky.
+
+
+Wed Mar 22 13:45:34 GMT 2000 da
+
+ Tested file name quoting problem with Coq, Isabelle, LEGO.
+
+ \ quoting triggers bug in Isabelle (complaint about pathname)
+ " quoting not allowed in LEGO, \ quoting not needed.
+ Coq works well with either.
+
+
+
+--------
+
+Wed Nov 17 13:43:11 GMT 1999
+
+ Tested compiled version. Seems to work well for XEmacs!
+ Also for FSF Emacs! So long as using their own elc's.
+
+Tue Nov 16 15:28:51 GMT 1999
+
+ Tested automatic multiple file handling: see etc/demoisa
+
+ Tested FSF Emacs, after fixing several things.
+
+ Tested proof by pointing in LEGO. Fixes for bugs,
+ empty pbp response, and added a useful click
+ (C-button 3) for undoing and deleting the last
+ pbp command. Can now prove example.l by PBP.
+ Proof-by-pointing lives!
+
+Thu Nov 11 19:05:39 GMT 1999
+
+ Tested response buffer display: see isa/message-test.ML
+ Made output more regular by removing spurious space/newline
+ after every prompt, and padding response buffer with
+ newlines when messages aren't newline terminated.
+
+ Testing window management for multiple frames. Could find no
+ evidence of old bug message in code about with
+ special-display-regexps, script buffer gets made into
+ dedicated buffer. Removed the comment.
+
+Mon Aug 23 19:00:26 BST 1999 da
+
+ Summary of tests today:
+
+ Proof General 2.0: sanity check.
+ Okay with XEmacs 20.4, lego 1.3.1 and Isabelle 98p1.
+ Strange overlay disappearing problem with FSF Emacs 20.2,
+ so must be X Server or architecture anomaly that causes
+ different display order.
+
+ Today's Proof General.
+
+ 1. With Isabelle 98p1, no go.
+ 2. Same show-stopper as above with Emacs 20.2 and 20.3.
+ Argh! I'm really fed up of FSF Emacs, it goes wrong
+ even when "nothing" has changed.
+ 3. With current Isabelle (or, at least, 99pre180899).
+ 4. Using x-symbol. No success, and a big mess (rebinds M-x !!?)
+
+Thu Jan 21 14:27:36 GMT 1999 da
+
+ Quick test for pipe communication with emacs 20.3.
+ Used C-c C-n and C-c C-u on example.ML file in
+ Isabelle successfully.
+
+ (Tested 990115 prerelease with piped communication
+ patch in XEmacs already, for LEGO and Isabelle).
+
+Wed Dec 16 15:45:53 GMT 1998 da
+
+ Quick test of Coq mode.
+
+ xemacs -q -l ProofGeneral/generic/proof-site.el
+
+ (setq proof-rsh-command "ssh hope")
+
+ Assertion and retraction commands work as far as I can
+ tell. Using toolbar on file coq/example.v
+
+
+Wed Dec 16 12:25:00 GMT 1998 tms
+
+ Clarification of entry "Mon Dec 14 15:02:52 GMT 1998 da"
+
+ The problem with LEGOVERSION "alpha" can also be reproduced with
+ lego 1.3.1 (and XEmacs 20.4 or FSF Emacs 20.2) and the file
+ lego/example2.l which accesses a module in a non-writable directory.
+ You need to set chmod u-w readonly yourself; CVS doesn't like
+ non-writable directories)
+ It is a LEGO specific problem. LEGO forgets about annotations
+ sometimes. This has been reported to lego@dcs.ed.ac.uk .
+
+
+Wed Dec 16 12:25:00 GMT 1998 tms
+
+ On scar, tested Emacs 20.2.1 with lego 1.3.1 via "ssh craro",
+ LEGOVERSION "std"
+
+ emacs-20.2 -eval '(progn (load
+ "/home/tms/emacs/ProofGeneral/generic/proof-site.el")(setq
+ proof-rsh-command "ssh craro"))' lego/example.l
+
+ Pressing C-c C-n crashes Emacs: Fatal error (11).Segmentation fault
+
+ This must be a problem with my .emacs file. Including -q in the
+ options, everyting seems to work just fine. Still, this is somewhat
+ concerning.
+
+
+Mon Dec 14 15:02:52 GMT 1998 da
+
+ Tested Emacs 20.2.1 with lego 1.3 via "ssh hope",
+ with lego 1.3.1 via "ssh craro", LEGOVERSION "std"
+
+ Both successfully process example.l
+
+ With lego 1.3.1 via "ssh craro", LEGOVERSION "alpha",
+ processing gets stuck, never reports "imports done".
+ Is this a bug or problem with LEGO installation?
+
+ Bugs:
+ Killing off process shell via proof-shell-exit.
+ Killing proof script buffer gives error.
+
+
+
diff --git a/generic/README b/generic/README
new file mode 100644
index 00000000..4cf61435
--- /dev/null
+++ b/generic/README
@@ -0,0 +1,15 @@
+Proof General
+
+The code in this directory implements the generic basis
+of Proof General.
+
+It was written by Thomas Kleymann, Dilip Sequeira, Healfdene Goguen,
+David Aspinall, and Markus Wenzel.
+
+Several other people helped with contributions and modifications, see
+individual credits in the code or summary in the Proof General manual.
+
+Contributions to the generic basis are welcome!
+
+$Id$
+
diff --git a/generic/_pkg.el b/generic/_pkg.el
new file mode 100644
index 00000000..97a893ec
--- /dev/null
+++ b/generic/_pkg.el
@@ -0,0 +1,4 @@
+;;;###autoload
+(package-provide 'ProofGeneral
+ :version "3.3pre010320"
+ :type 'regular)
diff --git a/generic/pg-metadata.el b/generic/pg-metadata.el
new file mode 100644
index 00000000..21cbac9c
--- /dev/null
+++ b/generic/pg-metadata.el
@@ -0,0 +1,112 @@
+;; pg-metadata.el Persistant storage of metadata for proof scripts
+;;
+;; Copyright (C) 2001 LFCS Edinburgh.
+;; Author: David Aspinall
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; Status: incomplete; experimental
+;;
+;; TODO:
+;; - add file dependency information to proof scripts individually
+;; (can approximate from the transitive closure that is included files list)
+;;
+
+(require 'pg-xml)
+
+;; Variables
+
+(defcustom pg-metadata-default-directory "~/.proofgeneral/"
+ "*Directory for storing metadata information about proof scripts."
+ :type 'file
+ :group 'proof-user-options)
+
+(defface proof-preparsed-span
+ (proof-face-specs
+ (:background "lightgoldenrodyellow")
+ (:background "darkgoldenrod")
+ (:underline t))
+ "*Face for pre-parsed regions of proof script (unprocessed commands)."
+ :group 'proof-faces)
+
+
+;; Utility functions
+
+(defun pg-metadata-filename-for (filename)
+ "Compute a revised FILENAME for storing corresponding metadata."
+ ;; We replace directory separators with double underscores.
+ ;; Clashes are possible, hopefully unlikely.
+ (concat
+ (file-name-as-directory pg-metadata-default-directory)
+ (replace-in-string
+ (file-name-sans-extension filename)
+ (regexp-quote (char-to-string directory-sep-char))
+ "__")
+ ".pgm"))
+
+
+;; Main code
+
+(defun pg-write-metadata-file (buffer)
+ "Write meta data for a script buffer BUFFER."
+ ;; FIXME: should check buffer has been saved
+ (if (buffer-file-name buffer)
+ (let* ((scriptfile (buffer-file-name buffer))
+ (modtime (nth 5 (file-attributes scriptfile)))
+ (metadatafile (pg-metadata-filename-for scriptfile))
+ (metadatabuf (find-file-noselect metadatafile 'nowarn))
+ (span (span-at (point-min) 'type)))
+ type)
+ (pg-xml-begin-write)
+ (pg-xml-openelt 'script-file
+ (list (list 'filename scriptfile)
+ (list 'filedate modtime)))
+ (pg-xml-closeelt)
+ (while span
+ (let ((type (span-property span 'type))
+ (name (span-property span 'name))
+ (start (span-start span))
+ (end (span-end span)))
+ (pg-xml-openelt
+ 'span
+ (list (list 'type type)
+ (list 'name name)
+ (list 'start start)
+ (list 'end end)))
+ ;; Include the span contents: can recover script file
+ ;; from this. (Could even display script using special
+ ;; display functions?)
+ (pg-xml-writetext (buffer-substring start end buffer))
+ (pg-xml-closeelt))
+ (setq span (next-span 'type)))
+ (with-current-buffer metadatabuf
+ (delete-region (point-min) (point-max))
+ (insert (pg-xml-doc))
+ (write-file metadatafile))))
+
+
+;(defun pg-read-metadata-file (buffer)
+; "Read meta data for a script file BUFFER, and reconstitute spans.
+;Spans are only reconstituted for positions after (proof-unprocessed-begin),
+;and providing that the meta-data file is older than the script file."
+; (if (buffer-file-name buffer)
+; (let* ((scriptfile (buffer-file-name buffer))
+; (modtime (nth 5 (file-attributes scriptfile)))
+; (metadatafile (pg-metadata-filename-for scriptfile))
+; (metadatabuf (find-file-noselect metadatafile 'nowarn))
+; (metadata (pg-xml-parse-buffer metadatabuf)))
+
+; (span (span-at (point-min) 'type)))
+; type)
+
+
+(provide 'pg-metadata)
+;; pg-metadata.el ends here.
+
+
+
+
+
+
+ \ No newline at end of file
diff --git a/generic/pg-pgip.el b/generic/pg-pgip.el
new file mode 100644
index 00000000..327000d6
--- /dev/null
+++ b/generic/pg-pgip.el
@@ -0,0 +1,130 @@
+;; pg-pgip.el Functions for processing PGIP for Proof General
+;;
+;; Copyright (C) 200-2001 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; Proof General Kit uses PGIP, an XML-message protocol
+;; for interactive proof. This file contains functions
+;; to process PGIP commands sent from the proof assistant.
+;;
+
+(defun pg-pgip-process-cmd (pgip)
+ "Process the command in PGIP, which should be parsed XML according to pg-xml-parse-*."
+ (while (pgip)
+ (let ((elt (caar pgip))
+ (attrs (cdar pgip)))
+ (cond
+ ;; <pgip>
+ ((eq elt 'pgip)) ;; ignore pgip attributes for now
+ ;; <usespgml>
+ ((eq elt 'usespgml)
+ (message "Received usespgml message, version %s"
+ (pg-pgip-get-version "usespgml" attrs)))
+ ;; <haspref>
+ ((eq elt 'haspref)
+ (pg-pgip-haspref attrs) ;; (cadr pgip))
+ (setq pgip (cdr pgip)))
+ ;; <prefval>
+ ((eq elt 'prefval)
+ )
+ ;; <idtable>
+ ((eq elt 'idtable)
+ )
+ ;; <addid>
+ ((eq elt 'addid)
+ )
+ ;; <delid>
+ ((eq elt 'delid)
+ )
+ ;; <menuadd>
+ ((eq elt 'menuadd)
+ )
+ ((eq elt 'menudel)
+ ))
+ ;; Move on to next element
+ (setq pgip (cdr pgip)))))
+
+(defun pg-pgip-haspref (attrs)
+ "Issue a defpacustom from a <haspref> element with attributes ATTRS"
+ (let*
+ ((type (pg-pgip-get-type attrs))
+ (default (or (pg-pgip-get-attr "haspref" "default" attrs t)
+ ;; If no default is supplied, make one
+ (pg-pgip-default-for type)))
+ (kind (intern
+ (or
+ (pg-pgip-get-attr "haspref" "kind" attrs t)
+ ;; Default to kind user
+ "user")))
+ (name (intern (pg-pgip-get-attr "haspref" "name")))
+ (subst (pg-pgip-subst-for type))
+ (setting (concat "<pgip><setpref name=\"" name "\">" subst "</setpref></pgip>")))
+ (eval
+ (list 'defpacustom name default
+ ;; FIXME: better docstring
+ "Setting configured by <haspref> PGIP message"
+ :type type
+ :setting setting))))
+
+(defun pg-pgip-default-for (type)
+ "Synthesize a default value for type TYPE."
+ (cond
+ ((eq type 'boolean) nil)
+ ((eq type 'integer) 0)
+ ((eq type 'string) "")
+ ((eq (car-safe type) 'choice)
+ (car-safe (cdr-safe type)))
+ (t
+ (error "pg-pgip-default-for: unrecognized type passed in"))))
+
+(defun pg-pgip-subst-for (type)
+ "Return a substitution string for type TYPE."
+ (cond
+ ((eq type 'boolean) "%b")
+ ((eq type 'integer) "%i")
+ (t "%s")))
+
+(defun pg-pgip-get-type (attrs)
+ "Extract and check type value from ATTRS. Normalize to custom format."
+ (let ((rawtype (pg-pgip-get-attr "haspref" "type" attrs)))
+ (cond
+ ((string-match "choice(\\(.*\\))" rawtype)
+ (let* ((choiceslist (match-string 1 rawtype))
+ (choices (split-string choiceslist "[ \f\t\n\r\v]*,[ \f\t\n\r\v]*")))
+ (list 'choice choices)))
+ ((equal rawtype "boolean")
+ 'boolean)
+ ((equal rawtype "int")
+ 'integer)
+ ((equal rawtype "nat") ;; nat treated as int
+ 'integer)
+ ((equal rawtype "string")
+ 'string)
+ (t
+ (error "pg-pgip-get-type: unrecognized type %s" rawtype)))))
+
+
+;; Auxiliary functions for parsing
+
+(defun pg-pgip-get-attr (elt attrnm attrs &optional optional)
+ (let ((vrs (assoc attrnm attrs)))
+ (if optional
+ vrs
+ (or vrs
+ (error "Didn't find %s attribute in %s element" attrnm elt)))))
+
+(defun pg-pgip-get-version (elt attrs &optional optional)
+ (pg-pgip-get-attr elt "version" attrs optional))
+
+
+
+
+
+
+
+;; End of `pg-pgip.el'
+
+
diff --git a/generic/pg-user.el b/generic/pg-user.el
new file mode 100644
index 00000000..7b22ad48
--- /dev/null
+++ b/generic/pg-user.el
@@ -0,0 +1,918 @@
+;; pg-user.el User level commands for Proof General
+;;
+;; Copyright (C) 2000-2001 LFCS Edinburgh.
+;; Author: David Aspinall and others
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;;
+
+(require 'proof-config) ; for proof-follow-mode
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; first a couple of helper functions
+;;
+
+(defmacro proof-maybe-save-point (&rest body)
+ "Save point according to proof-follow-mode, execute BODY."
+ `(if (eq proof-follow-mode 'locked)
+ (progn
+ ,@body)
+ (save-excursion
+ ,@body)))
+
+(defun proof-maybe-follow-locked-end ()
+ "Maybe point to the make sure the locked region is displayed."
+ (if (eq proof-follow-mode 'follow)
+ (proof-goto-end-of-queue-or-locked-if-not-visible)))
+
+
+;;
+;; Doing commands
+;;
+
+(defun proof-assert-next-command-interactive ()
+ "Process until the end of the next unprocessed command after point.
+If inside a comment, just process until the start of the comment."
+ (interactive)
+ (proof-with-script-buffer
+ (proof-maybe-save-point
+ (goto-char (proof-queue-or-locked-end))
+ (proof-assert-next-command))
+ (proof-maybe-follow-locked-end)))
+
+(defun proof-process-buffer ()
+ "Process the current (or script) buffer, and maybe move point to the end."
+ (interactive)
+ (proof-with-script-buffer
+ (proof-maybe-save-point
+ (goto-char (point-max))
+ (proof-assert-until-point-interactive))
+ (proof-maybe-follow-locked-end)))
+
+
+;;
+;; Undoing commands
+;;
+
+(defun proof-undo-last-successful-command ()
+ "Undo last successful command at end of locked region."
+ (interactive)
+ (proof-undo-last-successful-command-1))
+
+(defun proof-undo-and-delete-last-successful-command ()
+ "Undo and delete last successful command at end of locked region.
+Useful if you typed completely the wrong command.
+Also handy for proof by pointing, in case the last proof-by-pointing
+command took the proof in a direction you don't like.
+
+Notice that the deleted command is put into the Emacs kill ring, so
+you can use the usual `yank' and similar commands to retrieve the
+deleted text."
+ (interactive)
+ (proof-undo-last-successful-command-1 'delete)
+ ;; FIXME want to do this here for 3.3, for nicer behaviour
+ ;; when deleting.
+ ;; Unfortunately nasty problem with read only flag when
+ ;; inserting at (proof-locked-end) sometimes behaves as if
+ ;; point is inside locked region (prob because span is
+ ;; [ ) and not [ ] -- why??).
+ ;; (proof-script-new-command-advance)
+ )
+
+;; No direct key-binding for this one: C-c C-u was too dangerous,
+;; when used quickly it's too easy to accidently delete!
+(defun proof-undo-last-successful-command-1 (&optional delete)
+ "Undo last successful command at end of locked region.
+If optional DELETE is non-nil, the text is also deleted from
+the proof script."
+ (interactive "P")
+ (proof-with-script-buffer
+ (proof-maybe-save-point
+ (unless (proof-locked-region-empty-p)
+ (let ((lastspan (span-at-before (proof-locked-end) 'type)))
+ (if lastspan
+ (progn
+ (goto-char (span-start lastspan))
+ (proof-retract-until-point delete))
+ (error "Nothing to undo!")))))
+ (proof-maybe-follow-locked-end)))
+
+(defun proof-retract-buffer ()
+ "Retract the current buffer, and maybe move point to the start."
+ (interactive)
+ (proof-with-script-buffer
+ (proof-maybe-save-point
+ (goto-char (point-min))
+ (proof-retract-until-point-interactive))
+ (proof-maybe-follow-locked-end)))
+
+(defun proof-retract-current-goal ()
+ "Retract the current proof, and move point to its start."
+ (interactive)
+ (proof-maybe-save-point
+ (let
+ ((span (proof-last-goal-or-goalsave)))
+ (if (and span (not (eq (span-property span 'type) 'goalsave))
+ (< (span-end span) (proof-unprocessed-begin)))
+ (progn
+ (goto-char (span-start span))
+ (proof-retract-until-point-interactive)
+ (proof-maybe-follow-locked-end))
+ (error "Not proving")))))
+
+;;
+;; Interrupt
+;;
+
+(defun proof-interrupt-process ()
+ "Interrupt the proof assistant. Warning! This may confuse Proof General.
+This sends an interrupt signal to the proof assistant, if Proof General
+thinks it is busy.
+
+This command is risky because when an interrupt is trapped in the
+proof assistant, we don't know whether the last command succeeded or
+not. The assumption is that it didn't, which should be true most of
+the time, and all of the time if the proof assistant has a careful
+handling of interrupt signals."
+ (interactive)
+ (unless (proof-shell-live-buffer)
+ (error "Proof Process Not Started!"))
+ (unless proof-shell-busy
+ (error "Proof Process Not Active!"))
+ (with-current-buffer proof-shell-buffer
+ ;; Just send an interrrupt.
+ ;; Action on receiving one is triggered in proof-shell
+ (comint-interrupt-subjob)
+ (run-hooks 'proof-shell-pre-interrupt-hook)))
+
+
+;;
+;; Movement commands
+;;
+
+;; FIXME da: the next function is messy. Also see notes in 'todo'
+(defun proof-goto-command-start ()
+ "Move point to start of current (or final) command of the script."
+ (interactive)
+ (let* ((cmd (span-at (point) 'type))
+ (start (if cmd (span-start cmd))))
+ (if start
+ (progn
+ ;; BUG: only works for unclosed proofs.
+ (goto-char start))
+ (let ((semis (nth 1 (proof-segment-up-to (point) t))))
+ (if (eq 'unclosed-comment (car-safe semis))
+ (setq semis (cdr-safe semis)))
+ (if (nth 2 semis) ; fetch end point of previous command
+ (goto-char (nth 2 semis))
+ ;; no previous command: just next to end of locked
+ (goto-char (proof-locked-end)))))
+ ;; Oddities of this function: if we're beyond the last proof
+ ;; command, it jumps back to the last command. Could alter this
+ ;; by spotting that command end of last of semis is before
+ ;; point. Also, behaviour with comments is different depending
+ ;; on whether locked or not.
+ (skip-chars-forward " \t\n")))
+
+(defun proof-goto-command-end ()
+ "Set point to end of command at point."
+ (interactive)
+ (let ((cmd (span-at (point) 'type)))
+ (if cmd (goto-char (span-end cmd))
+; (and (re-search-forward "\\S-" nil t)
+; (proof-assert-until-point nil 'ignore-proof-process))
+ (proof-assert-next-command nil
+ 'ignore-proof-process
+ 'dontmoveforward))
+ (skip-chars-backward " \t\n")
+ (unless (eq (point) (point-min))
+ ;; should land on terminal char
+ (backward-char))))
+
+
+
+;;
+;; Mouse functions
+;;
+
+;; FIXME oddity here: with proof-follow-mode='locked, when retracting,
+;; point stays where clicked. When advancing, it moves. Might
+;; be nicer behaviour than actually moving point into locked region
+;; which is only useful for cut and paste, really.
+(defun proof-mouse-goto-point (event)
+ "Call proof-goto-point on the click position."
+ (interactive "e")
+ (proof-maybe-save-point
+ (mouse-set-point event)
+ (proof-goto-point)))
+
+
+;; FIXME da: this is an oddity. It copies the span, but does not
+;; send it, contrary to it's old name ("proof-send-span").
+;; Now made more general to behave like mouse-track-insert
+;; when not over a span.
+;; FIXME da: improvement would be to allow selection of part
+;; of command by dragging, as in ordinary mouse-track-insert.
+;; Maybe by setting some of the mouse track hooks.
+(defun proof-mouse-track-insert (event)
+ "Copy highlighted command under the mouse to point. Ignore comments.
+If there is no command under the mouse, behaves like mouse-track-insert."
+ (interactive "e")
+ (let ((str
+ (save-window-excursion
+ (save-excursion
+ (let* ((span (span-at (mouse-set-point event) 'type)))
+ (and
+ span
+ ;; Next test might be omitted to allow for non-script
+ ;; buffer copying (e.g. from spans in the goals buffer)
+ (eq (current-buffer) proof-script-buffer)
+ ;; Test for type=vanilla means that closed goal-save regions
+ ;; are not copied.
+ ;; PG 3.3: remove this test, why not copy full proofs?
+ ;; (wanted to remove tests for 'vanilla)
+ ;; (eq (span-property span 'type) 'vanilla)
+ ;; Finally, extracting the 'cmd part prevents copying
+ ;; comments, and supresses leading spaces, at least.
+ ;; Odd.
+ (span-property span 'cmd)))))))
+ ;; Insert copied command in original window,
+ ;; buffer, point position.
+ (if str
+ (insert str proof-script-command-separator)
+ (mouse-track-insert event))))
+
+
+
+
+;;
+;; Minibuffer non-scripting command
+;;
+
+(defvar proof-minibuffer-history nil
+ "History of proof commands read from the minibuffer")
+
+(defun proof-minibuffer-cmd (cmd)
+ "Prompt for a command in the minibuffer and send it to proof assistant.
+The command isn't added to the locked region.
+
+If a prefix arg is given and there is a selected region, that is
+pasted into the command. This is handy for copying terms, etc from
+the script.
+
+If `proof-strict-state-preserving' is set, and `proof-state-preserving-p'
+is configured, then the latter is used as a check that the command
+will be safe to execute, in other words, that it won't ruin
+synchronization. If when applied to the command it returns false,
+then an error message is given.
+
+WARNING: this command risks spoiling synchronization if the test
+`proof-state-preserving-p' is not configured, if it is
+only an approximate test, or if `proof-strict-state-preserving'
+is off (nil)."
+ (interactive
+ (list (read-string "Command: "
+ (if (and current-prefix-arg (region-exists-p))
+ (replace-in-string
+ (buffer-substring (region-beginning) (region-end))
+ "[ \t\n]+" " "))
+ 'proof-minibuffer-history)))
+ (if (and proof-strict-state-preserving
+ proof-state-preserving-p
+ (not (funcall proof-state-preserving-p cmd)))
+ (error "Command is not state preserving, I won't execute it!"))
+ (proof-shell-invisible-command cmd))
+
+
+;;
+;; Frobbing locked end
+;;
+
+;; A command for making things go horribly wrong - it moves the
+;; end-of-locked-region marker backwards, so user had better move it
+;; correctly to sync with the proof state, or things will go all
+;; pear-shaped.
+
+;; In fact, it's so risky, we'll disable it by default
+(if (if proof-running-on-XEmacs
+ (get 'proof-frob-locked-end 'disabled t)
+ ;; FSF code more approximate
+ (not (member 'disabled (symbol-plist 'proof-frob-locked-end))))
+ (put 'proof-frob-locked-end 'disabled t))
+
+(defun proof-frob-locked-end ()
+ "Move the end of the locked region backwards to regain synchronization.
+Only for use by consenting adults.
+
+This command can be used to repair synchronization in case something
+goes wrong and you want to tell Proof General that the proof assistant
+has processed less of your script than Proof General thinks.
+
+You should only use it to move the locked region to the end of
+a proof command."
+ (interactive)
+ (cond
+ (proof-shell-busy
+ (error "You can't use this command while %s is busy!" proof-assistant))
+ ((not (eq (current-buffer) proof-script-buffer))
+ (error "Must be in the active scripting buffer."))
+ ;; Sometimes may need to move point forwards, when locked region
+ ;; is editable.
+ ;; ((> (point) (proof-locked-end))
+ ;; (error "You can only move point backwards."))
+ ;; FIXME da: should move to a command boundary, really!
+ (t (proof-set-locked-end (point))
+ (delete-spans (proof-locked-end) (point-max) 'type))))
+
+
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; command history (unfinished)
+;;
+;; da: below functions for input history simulation are quick hacks.
+;; Could certainly be made more efficient.
+
+;(defvar proof-command-history nil
+; "History used by proof-previous-matching-command and friends.")
+
+;(defun proof-build-command-history ()
+; "Construct proof-command-history from script buffer.
+;Based on position of point."
+; ;; let
+; )
+
+;(defun proof-previous-matching-command (arg)
+; "Search through previous commands for new command matching current input."
+; (interactive))
+; ;;(if (not (memq last-command '(proof-previous-matching-command
+; ;; proof-next-matching-command)))
+; ;; Start a new search
+
+;(defun proof-next-matching-command (arg)
+; "Search through following commands for new command matching current input."
+; (interactive "p")
+; (proof-previous-matching-command (- arg)))
+
+;;
+;; end command history stuff
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Non-scripting proof assistant commands.
+;;;
+
+;;; These are based on defcustom'd settings so that users may
+;;; re-configure the system to their liking.
+
+
+;; FIXME: da: add more general function for inserting into the
+;; script buffer and the proof process together, and using
+;; a choice of minibuffer prompting (hated by power users, perfect
+;; for novices).
+;; TODO:
+;; Add named goals.
+;; Coherent policy for movement here and elsewhere based on
+;; proof-one-command-per-line user option.
+;; Coherent policy for sending to process after writing into
+;; script buffer. Could have one without the other.
+;; For example, may be more easy to edit complex goal string
+;; first in the script buffer. Ditto for tactics, etc.
+
+
+
+;;
+;; Helper macros and functions
+;;
+
+;; See put expression at end to give this indentation like while form
+(defmacro proof-if-setting-configured (var &rest body)
+ "Give error if a configuration setting VAR is unset, otherwise eval BODY."
+ `(if ,var
+ (progn ,@body)
+ (error "Proof General not configured for this: set %s"
+ ,(symbol-name var))))
+
+(defmacro proof-define-assistant-command (fn doc cmdvar &optional body)
+ "Define command FN to send string BODY to proof assistant, based on CMDVAR.
+BODY defaults to CMDVAR, a variable."
+ `(defun ,fn ()
+ ,(concat doc
+ (concat "\nIssues a command to the assistant based on "
+ (symbol-name cmdvar) ".")
+ "")
+ (interactive)
+ (proof-if-setting-configured ,cmdvar
+ (proof-shell-invisible-command ,(or body cmdvar)))))
+
+(defmacro proof-define-assistant-command-witharg (fn doc cmdvar prompt &rest body)
+ "Define command FN to prompt for string CMDVAR to proof assistant.
+CMDVAR is a function or string. Automatically has history."
+ `(progn
+ (defvar ,(intern (concat (symbol-name fn) "-history")) nil
+ ,(concat "History of arguments for " (symbol-name fn) "."))
+ (defun ,fn (arg)
+ ,(concat doc "\nIssues a command based on ARG to the assistant, using "
+ (symbol-name cmdvar) ".\n"
+ "The user is prompted for an argument.")
+ (interactive
+ (proof-if-setting-configured ,cmdvar
+ (if (stringp ,cmdvar)
+ (list (format ,cmdvar
+ (read-string
+ ,(concat prompt ": ") ""
+ ,(intern (concat (symbol-name fn) "-history")))))
+ (funcall ,cmdvar))))
+ ,@body)))
+
+(defun proof-issue-new-command (cmd)
+ "Insert CMD into the script buffer and issue it to the proof assistant.
+If point is in the locked region, move to the end of it first.
+Start up the proof assistant if necessary."
+ (proof-with-script-buffer
+ (if (proof-shell-live-buffer)
+ (if (proof-in-locked-region-p)
+ (proof-goto-end-of-locked t)))
+ (proof-script-new-command-advance)
+ ;; FIXME: fixup behaviour of undo here. Really want to temporarily
+ ;; disable undo for insertion. but (buffer-disable-undo) trashes
+ ;; whole undo list!
+ (insert cmd)
+ ;; FIXME: could do proof-indent-line here, but let's wait until
+ ;; indentation is fixed.
+ (proof-assert-until-point-interactive)))
+
+;;
+;; Commands which do not require a prompt and send an invisible
+;; command.
+;;
+
+(proof-define-assistant-command proof-prf
+ "Show the current proof state."
+ proof-showproof-command)
+(proof-define-assistant-command proof-ctxt
+ "Show the current context."
+ proof-context-command)
+(proof-define-assistant-command proof-help
+ "Show a help or information message from the proof assistant.
+Typically, a list of syntax of commands available."
+ proof-info-command)
+(proof-define-assistant-command proof-cd
+ "Change directory to the default directory for the current buffer."
+ proof-shell-cd-cmd
+ (proof-format-filename proof-shell-cd-cmd
+ ;; FSF fix: use default-directory rather than fn
+ default-directory))
+
+(defun proof-cd-sync ()
+ "If proof-shell-cd-cmd is set, do proof-cd and wait for prover ready.
+This is intended as a value for proof-activate-scripting-hook"
+ ;; The hook is set in proof-mode before proof-shell-cd-cmd may be set,
+ ;; so we explicitly test it here.
+ (if proof-shell-cd-cmd
+ (progn
+ (proof-cd)
+ (proof-shell-wait))))
+
+;;
+;; Commands which require an argument, and maybe affect the script.
+;;
+
+;; FIXME: maybe move these to proof-menu
+
+(proof-define-assistant-command-witharg proof-find-theorems
+ "Search for items containing given constants."
+ proof-find-theorems-command
+ "Find theorems containing"
+ (proof-shell-invisible-command arg))
+
+(proof-define-assistant-command-witharg proof-issue-goal
+ "Write a goal command in the script, prompting for the goal."
+ proof-goal-command
+ "Goal"
+ (let ((proof-one-command-per-line t)) ; Goals always start at a new line
+ (proof-issue-new-command arg)))
+
+(proof-define-assistant-command-witharg proof-issue-save
+ "Write a save/qed command in the script, prompting for the theorem name."
+ proof-save-command
+ "Save as"
+ (let ((proof-one-command-per-line t)) ; Saves always start at a new line
+ (proof-issue-new-command arg)))
+
+
+
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Electric terminator mode
+;;
+;; NB: only relevant for provers with a "terminal char" which
+;; terminates commands in proof scripts.
+
+;; Register proof-electric-terminator as a minor mode.
+
+(deflocal proof-electric-terminator nil
+ "Fake minor mode for electric terminator.")
+
+(or (assq 'proof-electric-terminator minor-mode-alist)
+ (setq minor-mode-alist
+ (append minor-mode-alist
+ (list '(proof-electric-terminator
+ (concat " " proof-terminal-string))))))
+
+;; This is a value used by custom-set property = proof-set-value.
+(defun proof-electric-terminator-enable ()
+ "Copy proof-electric-terminator-enable to all script mode copies of it.
+Make sure the modeline is updated to display new value for electric terminator."
+ (if proof-mode-for-script
+ (proof-map-buffers (proof-buffers-in-mode proof-mode-for-script)
+ (setq proof-electric-terminator
+ proof-electric-terminator-enable)))
+ (redraw-modeline))
+
+(proof-deftoggle proof-electric-terminator-enable proof-electric-terminator-toggle)
+
+(defun proof-electric-term-incomment-fn ()
+ "Used as argument to proof-assert-until-point."
+ ;; CAREFUL: (1) dynamic scoping here
+ ;; (2) needs this name to be recognized in
+ ;; proof-assert-until-point
+ (setq incomment t)
+ (if ins (backward-delete-char 1))
+ (goto-char mrk)
+ (insert proof-terminal-string))
+
+;; FIXME da: this function is a mess and needs rewriting.
+;; (proof-assert-until-point process needs cleaning up)
+;;
+;; What it should do:
+;; * parse FIRST. If we're inside a comment or string,
+;; then insert the terminator where we are. Otherwise
+;; can skip backwards and insert the terminator at the
+;; command end (perhaps optionally), and look for
+;; existing terminator.
+
+(defun proof-process-electric-terminator ()
+ "Insert the proof command terminator, and assert up to it.
+This is a little bit clever with placement of semicolons, and will
+try to avoid duplicating them in the buffer.
+When used in the locked region (and so with strict read only off), it
+always defaults to inserting a semi (nicer might be to parse for a
+comment, and insert or skip to the next semi)."
+ (let ((mrk (point)) ins incomment)
+ (if (< mrk (proof-locked-end))
+ ;; In locked region, just insert terminator without further ado
+ (insert proof-terminal-char)
+ ;; Otherwise, do other thing.
+ ;; Old idea: only shift terminator wildly if we're looking at
+ ;; whitespace. Why?
+ ;; (if (looking-at "\\s-\\|\\'\\|\\w")
+ (if (proof-only-whitespace-to-locked-region-p)
+ (error "There's nothing to do!"))
+
+ (if (not (= (char-after (point)) proof-terminal-char))
+ (progn
+ (forward-char) ;; immediately after command end.
+ (insert proof-terminal-string)
+ (setq ins t)))
+ (proof-assert-until-point 'proof-electric-term-incomment-fn)
+ (or incomment
+ (proof-script-next-command-advance)))))
+
+(defun proof-electric-terminator ()
+ "Insert the terminator, perhaps sending the command to the assistant.
+If proof-electric-terminator-enable is non-nil, the command will be
+sent to the assistant."
+ (interactive)
+ (if proof-electric-terminator-enable
+ (proof-process-electric-terminator)
+ (self-insert-command 1)))
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Completion based on <PA>-completion-table
+;;
+;; Requires completion.el package. Completion is usually
+;; a hand-wavy thing, so we don't make any attempt to maintain
+;; a precise completion table or anything.
+;;
+;; New in 3.2.
+;;
+(defun proof-add-completions ()
+ "Add completions from <PA>-completion-table to completion database.
+Uses `add-completion' with a negative number of uses and ancient
+last use time, to discourage saving these into the users database."
+ (interactive)
+ (require 'completion)
+ (mapcar (lambda (cmpl)
+ ;; completion gives error in this case; trapping
+ ;; the error here is tricky in FSF Emacs so duplicate
+ ;; the test.
+ (if (>= (length cmpl) completion-min-length)
+ (add-completion cmpl -1000 0)))
+ (proof-ass completion-table)))
+
+;; NB: completion table is expected to be set when proof-script
+;; is loaded! Can call proof-script-add-completions if the table
+;; is updated.
+(eval-after-load "completion"
+ '(proof-add-completions))
+
+(defun proof-script-complete (&optional arg)
+ "Like `complete' but case-fold-search set to proof-case-fold-search."
+ (interactive "*p")
+ (let ((case-fold-search proof-case-fold-search))
+ (complete arg)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Tags table building
+;;
+;; New in 3.3... or perhaps later.
+;;
+;; FIXME: incomplete. Add function to build tags table from
+;;
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Function to insert last prover output in comment.
+;; Requested/suggested by Christophe Raffalli
+;;
+
+(defun pg-insert-last-output-as-comment ()
+ "Insert the last output from the proof system as a comment in the proof script."
+ (interactive)
+ (if proof-shell-last-output
+ ;; There may be a system specific function to insert the comment
+ (if pg-insert-output-as-comment-fn
+ (pg-insert-output-as-comment-fn proof-shell-last-output)
+ ;; Otherwise the default behaviour is to use comment-region
+ (let ((beg (point)) end)
+ ;; proof-shell-strip-special-annotations: should be done
+ ;; for us in proof-fontify-region
+ (insert proof-shell-last-output)
+ ;; 3.4: add fontification. Questionable since comments will
+ ;; probably be re-highlighted, so colouration, especially
+ ;; based on removed specials, will be lost.
+ ;; X-Symbol conversion is useful, but a surprising nuisance
+ ;; to achieve, mainly because x-symbol doesn't give us back
+ ;; a useful pointer to end of region after converting, and
+ ;; character positions change.
+ ;; (FIXME: contact x-sym author about this).
+ ;; proof-fontify-region does this for us, now
+ (setq end (proof-fontify-region beg (point)))
+ (comment-region beg end)))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Span manipulation
+;;
+
+(defun pg-copy-span-contents (span)
+ "Copy contents of SPAN to kill ring, sans surrounding whitespace."
+ (copy-region-as-kill
+ (save-excursion
+ (goto-char (span-start span))
+ (skip-chars-forward " \t\n")
+ (point))
+ (save-excursion
+ (goto-char (span-end span))
+ (skip-chars-backward " \t\n")
+ (point)))
+ (own-clipboard (car kill-ring)))
+
+;; 3.3: these functions are experimental, in that they haven't
+;; been rigorously tested. They don't work well in FSF Emacs.
+
+(defun pg-numth-span-higher-or-lower (span num &optional noerr)
+ "Find NUM'th span after/before SPAN. NUM is positive for after."
+ (unless (and span (<= (span-end span) (proof-unprocessed-begin)))
+ (if noerr
+ nil
+ (error "No processed region under point")))
+ (let ((downflag (> num 0))
+ (num (abs num))
+ nextspan)
+ (while (and (> num 0)
+ (setq nextspan (if downflag
+ (next-span span 'type)
+ (prev-span span 'type)))
+ (if downflag
+ ;; If moving down, check we don't go beyond
+ ;; end of processed region
+ (<= (span-end span) (proof-unprocessed-begin))
+ t))
+ (setq num (1- num))
+ (setq span nextspan))
+ (if (= num 0)
+ span
+ (if noerr
+ nil
+ (error "No region to move past" num)))))
+
+(defun pg-control-span-of (span)
+ "Return the controlling span of SPAN, or SPAN itself."
+ (or (span-property span 'controlspan)
+ span))
+
+(defun pg-move-span-contents (span num)
+ "Move SPAN up/downwards in the buffer, past NUM spans.
+If NUM is negative, move upwards. Return new span."
+ ;; FIXME: maybe num arg is overkill, should only have 1?
+ (save-excursion
+ (let ((downflag (> num 0)) nextspan)
+ ;; Always move a control span instead; it contains
+ ;; children span which move together with it.
+ (setq span (pg-control-span-of span))
+ (setq nextspan (pg-numth-span-higher-or-lower span num))
+ ;; We're going to move the span to before/after nextspan.
+ ;; First make sure inserting there doesn't extend the span.
+ (if downflag
+ (set-span-property nextspan 'end-open t)
+ (set-span-property nextspan 'start-open t))
+ ;; When we delete the span, we want to duplicate it
+ ;; to recreate in the new position.
+ (set-span-property span 'duplicable 't)
+ (let* ((start (span-start span))
+ (end (span-end span))
+ (contents (buffer-substring start end))
+ ;; Locked end may move up when we delete
+ ;; region: we'll make sure to reset it
+ ;; again later, it shouldn't change.
+ ;; NB: (rely on singlethreadedness here, so
+ ;; lockedend doesn't move while in this code).
+ (lockedend (span-end proof-locked-span)))
+ (let ((inhibit-read-only t))
+ ;; FIXME: undo behaviour isn't quite right yet.
+ (undo-boundary)
+ (delete-region start end)
+ (let ((insertpos (if downflag
+ (span-end nextspan)
+ (span-start nextspan))))
+ (goto-char insertpos)
+ ;; Let XEmacs duplicate extents as needed, then repair
+ ;; their associations
+ (insert contents)
+ (let ((new-span
+ (span-at insertpos 'type)));should be one we deleted.
+ (set-span-property
+ new-span 'children
+ (append
+ (mapcar-spans 'pg-fixup-children-span
+ insertpos (point) 'type)))
+ (set-span-end proof-locked-span lockedend)
+ (undo-boundary)
+ new-span)))))))
+
+(defun pg-fixup-children-span (span)
+ (if (span-property span 'controlspan)
+ ;; WARNING: dynamic binding
+ (progn
+ (set-span-property span 'controlspan new-span)
+ (list span))))
+
+(defun pg-move-region-down (&optional num)
+ "Move the region under point downwards in the buffer, past NUM spans."
+ (interactive "p")
+ (let ((span (span-at (point) 'type)))
+ (and span
+ (goto-char (span-start
+ (pg-move-span-contents span num)))
+ (skip-chars-forward " \t\n"))))
+
+(defun pg-move-region-up (&optional num)
+ "Move the region under point upwards in the buffer, past NUM spans."
+ (interactive "p")
+ (pg-move-region-down (- num)))
+
+;; FIXME: not working right yet, sigh...
+(defun proof-forward-command (&optional num)
+ "Move forward to the start of the next proof region."
+ (interactive "p")
+ (skip-chars-forward " \t\n")
+ (let* ((span (or (span-at (point) 'type)
+ (and (skip-chars-backward " \t\n")
+ (> (point) (point-min))
+ (span-at (1- (point)) 'type))))
+ (nextspan (and span (pg-numth-span-higher-or-lower
+ (pg-control-span-of span) num 'noerr))))
+ (cond
+ ((and nextspan (> num 0))
+ (goto-char (span-start nextspan))
+ (skip-chars-forward " \t\n"))
+ ((and nextspan (< num 0))
+ (goto-char (span-end nextspan)))
+ ((and span (> num 0))
+ (goto-char (span-end span)))
+ ((and span (< num 0))
+ (goto-char (span-start span))))))
+
+(defun proof-backward-command (&optional num)
+ (interactive "p")
+ (proof-forward-command (- num)))
+
+
+
+
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Span menus and keymaps (maybe belongs in pg-menu)
+;;
+
+(defvar pg-span-context-menu-keymap
+ (let ((map (make-sparse-keymap
+ "Keymap for context-sensitive menus on spans")))
+ (define-key map [button3] 'pg-span-context-menu)
+ map))
+
+;; FIXME: TODO here:
+;;
+;; Check for a 'type which is one of the elements we know about
+;; (pgidioms).
+;;
+
+(defun pg-span-context-menu (event)
+ (interactive "e")
+ (select-window (event-window event))
+ (let ((span (span-at (event-point event) 'type))
+ cspan)
+ ;; Find controlling span
+ (while (setq cspan (span-property span 'controlspan))
+ (setq span cspan))
+ (let*
+ ((idiom (span-property span 'idiom))
+ (idiomnm (if idiom (symbol-name idiom)))
+ (portname (span-property span 'name)))
+ (popup-menu (pg-create-in-span-context-menu span idiomnm portname)))))
+
+(defun pg-toggle-visibility ()
+ "Toggle visibility of region under point."
+ (interactive)
+ (let* ((span (span-at (point) 'type))
+ (idiom (and span (span-property span 'idiom)))
+ (idiomnm (and idiom (symbol-name idiom)))
+ (portname (and span (span-property span 'name))))
+ (and portname idiomnm
+ (pg-toggle-element-visibility idiomnm portname))))
+
+
+(defun pg-create-in-span-context-menu (span idiom name)
+ "Create the dynamic context-sensitive menu for a span."
+ ;; FIXME: performance here, consider caching in the span itself?
+ ;; (or maybe larger menu spans which are associated with a menu).
+ ;; FIXME: treat proof and non-proof regions alike, could add
+ ;; visibility controls for non-proof regions also, redesigning
+ ;; idiom notion.
+ (append
+ (list (pg-span-name span))
+ (list (vector
+ "Show/hide"
+ (if idiom (list 'pg-toggle-element-visibility idiom name) idiom)
+ (not (not idiom))))
+ (list (vector
+ "Copy" (list 'pg-copy-span-contents span) t))
+ (if proof-experimental-features
+ (list (vector
+ "Move up" (list 'pg-move-span-contents span -1)
+ (pg-numth-span-higher-or-lower (pg-control-span-of span) -1 'noerr))))
+ (if proof-experimental-features
+ (list (vector
+ "Move down" (list 'pg-move-span-contents span 1)
+ (pg-numth-span-higher-or-lower (pg-control-span-of span) 1 'noerr))))
+ (if (and proof-experimental-features (featurep 'proof-depends))
+ (proof-dependency-in-span-context-menu span))))
+
+
+
+
+
+
+(provide 'pg-user)
+;; pg-user.el ends here.
diff --git a/generic/pg-xml.el b/generic/pg-xml.el
new file mode 100644
index 00000000..01fcec11
--- /dev/null
+++ b/generic/pg-xml.el
@@ -0,0 +1,252 @@
+;; pg-xml.el XML functions for Proof General
+;;
+;; Copyright (C) 2000-2001 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; XML functions for Proof General
+;;
+;; Proof General Kit uses PGIP, an XML-message protocol
+;; for interactive proof. The simple functions here allow
+;; parsing and writing of XML documents. Little attempt
+;; is made for efficiency, since PGIP documents are intended
+;; to be small. No attempt at validation or handling
+;; unicode characters is made.
+;;
+
+;; TODO:
+;; * Fix identifiers
+;; * Fix whitespace handling
+;; * Ignore prologues
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Parsing function: pg-xml-parse-buffer
+;;
+
+(defconst pg-xml-name "[a-zA-Z_:][a-zA-Z0-9._:-]*")
+(defconst pg-xml-space "[ \t\n ]")
+(defconst pg-xml-ref (concat "&" pg-xml-name ";")) ; FIXME: charrefs
+
+(defconst pg-xml-start-open-elt-regexp
+ (concat pg-xml-space "*" "<\\(" pg-xml-name "\\)"))
+(defconst pg-xml-end-open-elt-regexp
+ (concat pg-xml-space "*" "\\(/?\\)>"))
+(defconst pg-xml-close-elt-regexp
+ (concat pg-xml-space "*" "</\\(" pg-xml-name "\\)>"))
+(defconst pg-xml-attribute-regexp
+ (concat pg-xml-space "+" "\\(" pg-xml-name "\\)"))
+(defconst pg-xml-attribute-val-regexp
+ (concat pg-xml-space "*" "=" pg-xml-space "*"
+ "\"\\(\\([^<&\"]\\|" pg-xml-ref "\\)*\\)\"")) ; FIXME or 's
+(defconst pg-xml-comment-start-regexp "<!--")
+(defconst pg-xml-comment-end-regexp "-->")
+(defconst pg-xml-anymarkup-regexp "<")
+(defconst pg-xml-special-elts
+ '(xml)
+ "List of special elements which don't require closing.")
+
+(defvar xmlparse nil
+ "Used to store parse result.")
+
+(defun pg-xml-add-text (text)
+ "If TEXT is non empty, add it to subtree at top of `xmlparse'."
+ (unless (string-equal text "")
+ (setq xmlparse (cons (cons text (car xmlparse))
+ (cdr xmlparse)))))
+
+
+(defun pg-xml-parse-buffer (&optional buffer nomsg)
+ "Parse an XML documment in BUFFER (defaulting to current buffer).
+Return a lisp structure with symbols representing the element
+names, so that the result of parsing
+ <elt attr=\"blah\">text</elt>
+is
+ (elt ((attr . \"blah\")) (text))"
+ (unless nomsg
+ (message "Parsing %s..." (buffer-name buffer)))
+ (save-excursion
+ (if buffer (set-buffer buffer))
+ (goto-char (point-min))
+ (let ((xmlparse nil)
+ (pos (point))
+ openelts elt)
+ (unless (looking-at pg-xml-start-open-elt-regexp)
+ (warn "pg-xml-parse-buffer: Junk at start of document: %s"
+ (buffer-substring
+ (point-min)
+ (min (save-excursion
+ (re-search-forward pg-xml-anymarkup-regexp nil t)
+ (match-beginning 0))
+ (+ 10 (point-min))))))
+ (while (re-search-forward pg-xml-anymarkup-regexp nil t)
+ (goto-char (match-beginning 0))
+ (cond
+ ;; CASE 1: element opening
+ ((looking-at pg-xml-start-open-elt-regexp)
+ (setq elt (intern (match-string 1)))
+ ;; Add text before here to the parse, if non-empty
+ ;; FIXME: maybe unless last elt was opening too and
+ ;; only white space?
+ (pg-xml-add-text (buffer-substring pos (match-beginning 0)))
+ ;; Now look for any attributes
+ (goto-char (match-end 0))
+ (let ((attrs nil) attr)
+ (while (looking-at pg-xml-attribute-regexp)
+ (setq attr (intern (match-string 1)))
+ (goto-char (match-end 0))
+ (if (looking-at pg-xml-attribute-val-regexp)
+ (progn
+ (setq attr (cons attr (match-string 1)))
+ (goto-char (match-end 0))))
+ (setq attrs (cons attr attrs)))
+ ;; Retain order in document
+ (setq attrs (reverse attrs))
+ ;; Now we ought to be at the end of the element opening
+ (unless (looking-at pg-xml-end-open-elt-regexp)
+ (error "pg-xml-parse-buffer: Invalid XML in element opening %s"
+ (symbol-name elt)))
+ ;; Stack the element unless it's self closing
+ (if (> (length (match-string 1)) 0)
+ ;; Add element without nesting
+ (setq xmlparse (cons (cons (cons elt attrs)
+ (car xmlparse))
+ (cdr xmlparse)))
+ ;; Otherwise stack and nest
+ (setq openelts (cons elt openelts))
+ (setq xmlparse (cons (list (cons elt attrs))
+ xmlparse))))
+ (goto-char (match-end 0))
+ (setq pos (point)))
+
+ ;; CASE 2: element closing
+ ((looking-at pg-xml-close-elt-regexp)
+ (setq elt (intern (match-string 1)))
+ ;; It better be the top thing on the stack
+ (unless (eq elt (car-safe openelts))
+ (error "pg-xml-parse-buffer: Invalid XML at element closing </%s> (expected </%s>)"
+ (symbol-name elt)
+ (if openelts
+ (symbol-name (car openelts))
+ "no closing element")))
+ ;; Add text before here to the parse
+ (pg-xml-add-text (buffer-substring pos (match-beginning 0)))
+ ;; Unstack the element and close subtree
+ (setq openelts (cdr openelts))
+ (setq xmlparse (cons (cons
+ (reverse (car xmlparse))
+ (cadr xmlparse))
+ (cddr xmlparse)))
+ (goto-char (match-end 0))
+ (setq pos (point)))
+
+ ;; CASE 3: comment
+ ((looking-at pg-xml-comment-start-regexp)
+ (unless (re-search-forward pg-xml-comment-end-regexp nil t)
+ (error "pg-xml-parse-buffer: Unclosed comment beginning at line %s"
+ (1+ (count-lines (point-min) (point))))))))
+
+ ;; We'd better have nothing on the stack of open elements now.
+ (unless (null openelts)
+ (error "pg-xml-parse-buffer: Unexpected end of document, expected </%s>"
+ (symbol-name (car openelts))))
+ ;; And we'd better be at the end of the document.
+ (unless (and (looking-at "[ \t\n]*")
+ (eq (match-end 0) (point-max)))
+ (warn "pg-xml-parse-buffer: Junk at end of document: %s"
+ (buffer-substring (point)
+ (min (point-max) (+ 30 (point-max))))))
+ ;; Return the parse
+ ;; FIXME:
+ (unless nomsg
+ (message "Parsing %s...done" (buffer-name buffer)))
+ (caar xmlparse))))
+
+(defun pg-xml-parse-string (arg)
+ "Parse string in ARG, same as pg-xml-parse-buffer."
+ (let
+ ((tempbuffer (get-buffer-create " *xml-parse*")))
+ (save-excursion
+ (set-buffer tempbuffer)
+ (delete-region (point-min) (point-max))
+ (insert-string arg)
+ (pg-xml-parse-buffer))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Producing functions: state-based writing of an XML doc,
+;; built up in pg-xml-doc
+
+
+(defvar pg-xml-doc nil
+ "Current document being written")
+
+(defvar pg-xml-openelts nil
+ "Stack of openelements")
+
+(defvar pg-xml-indentp nil
+ "Whether to indent written XML documents")
+
+(defun pg-xml-begin-write ()
+ (setq pg-xml-doc nil
+ pg-xml-openelts nil))
+
+(defun pg-xml-indent ()
+ (if pg-xml-indentp
+ (substring "\n "
+ 1 (length pg-xml-openelts))
+ ""))
+
+(defun pg-xml-openelt (element &optional attributes)
+ (setq pg-xml-openelts (cons element pg-xml-openelts))
+ (let (string)
+ (setq string (concat (pg-xml-indent)
+ "<" (symbol-name element)))
+ (while attributes
+ (if (consp (car attributes))
+ (setq string (concat
+ string
+ " "
+ (symbol-name (caar attributes))
+ "="
+ (cdar attributes)))
+ (setq string (concat string
+ " " (symbol-name (car attributes)))))
+ (setq attributes (cdr attributes)))
+ (setq pg-xml-doc
+ (cons (concat string ">") pg-xml-doc))))
+
+(defun pg-xml-closeelt ()
+ (unless pg-xml-openelts
+ (error "pg-xml-closelt: no open elements"))
+ (setq pg-xml-doc
+ (cons
+ (concat
+ (pg-xml-indent)
+ "</" (symbol-name (car pg-xml-openelts)) ">")
+ pg-xml-doc))
+ (setq pg-xml-openelts (cdr pg-xml-openelts)))
+
+
+(defun pg-xml-writetext (text)
+ (setq pg-xml-doc (cons (concat (pg-xml-indent) text) pg-xml-doc)))
+
+(defun pg-xml-doc ()
+ (apply 'concat (reverse pg-xml-doc)))
+
+;; Test document:
+;;(progn
+;; (pg-xml-begin-write)
+;; (pg-xml-openelt 'root)
+;; (pg-xml-openelt 'a '((class . "1B")))
+;; (pg-xml-writetext "text a")
+;; (pg-xml-closeelt)
+;; (pg-xml-closeelt)
+;; (pg-xml-doc))
+
+(provide 'pg-xml)
+;; End of `pg-xml.el'
diff --git a/generic/proof-autoloads.el b/generic/proof-autoloads.el
new file mode 100644
index 00000000..4cffee2b
--- /dev/null
+++ b/generic/proof-autoloads.el
@@ -0,0 +1,191 @@
+;;; DO NOT MODIFY THIS FILE
+(if (featurep 'proof-autoloads) (error "Already loaded"))
+
+;;;### (autoloads nil "_pkg" "generic/_pkg.el")
+
+(package-provide 'ProofGeneral :version "3.3pre010320" :type 'regular)
+
+;;;***
+
+;;;### (autoloads (proof-thy-menu-define-deps proof-depends-process-dependencies) "old-proof-depends" "generic/old-proof-depends.el")
+
+(autoload 'proof-depends-process-dependencies "old-proof-depends" "\
+Process dependencies reported by prover, for NAME in span GSPAN.
+Called from `proof-done-advancing' when a save is processed and
+proof-last-theorem-dependencies is set." nil nil)
+
+(autoload 'proof-thy-menu-define-deps "old-proof-depends" nil nil nil)
+
+;;;***
+
+;;;### (autoloads (proof-depends-process-dependencies) "proof-depends" "generic/proof-depends.el")
+
+(autoload 'proof-depends-process-dependencies "proof-depends" "\
+Process dependencies reported by prover, for NAME in span GSPAN.
+Called from `proof-done-advancing' when a save is processed and
+proof-last-theorem-dependencies is set." nil nil)
+
+;;;***
+
+;;;### (autoloads (proof-easy-config) "proof-easy-config" "generic/proof-easy-config.el")
+
+(autoload 'proof-easy-config "proof-easy-config" "\
+Configure Proof General for proof-assistant using BODY as a setq body." nil 'macro)
+
+;;;***
+
+;;;### (autoloads (proof-indent-region proof-indent-line) "proof-indent" "generic/proof-indent.el")
+
+(autoload 'proof-indent-line "proof-indent" "\
+Indent current line of proof script, if indentation enabled." t nil)
+
+(autoload 'proof-indent-region "proof-indent" nil t nil)
+
+;;;***
+
+;;;### (autoloads (defpacustom proof-defpacustom-fn proof-defshortcut proof-menu-define-specific proof-menu-define-main proof-menu-define-keys) "proof-menu" "generic/proof-menu.el")
+
+(autoload 'proof-menu-define-keys "proof-menu" nil nil nil)
+
+(autoload 'proof-menu-define-main "proof-menu" nil nil nil)
+
+(autoload 'proof-menu-define-specific "proof-menu" nil nil nil)
+
+(autoload 'proof-defshortcut "proof-menu" "\
+Define shortcut function FN to insert STRING, optional keydef KEY.
+This is intended for defining proof assistant specific functions.
+STRING is inserted using `proof-insert', which see.
+KEY is added onto proof-assistant map." nil 'macro)
+
+(autoload 'proof-defpacustom-fn "proof-menu" "\
+As for macro `defpacustom' but evaluation arguments." nil nil)
+
+(autoload 'defpacustom "proof-menu" "\
+Define a setting NAME for the current proof assitant, default VAL.
+NAME can correspond to some internal setting, flag, etc, for the
+proof assistant, in which case a :setting and :type value should be provided.
+The :type of NAME should be one of 'integer, 'boolean, 'string.
+The customization variable is automatically in group `proof-assistant-setting.
+The function `proof-assistant-format' is used to format VAL.
+If NAME corresponds instead to a PG internal setting, then a form :eval to
+evaluate can be provided instead." nil 'macro)
+
+;;;***
+
+;;;### (autoloads nil "proof-script" "generic/proof-script.el")
+
+;;;***
+
+;;;### (autoloads (proof-next-error proof-shell-invisible-command proof-shell-wait proof-extend-queue proof-start-queue proof-shell-available-p proof-shell-live-buffer proof-shell-ready-prover) "proof-shell" "generic/proof-shell.el")
+
+(autoload 'proof-shell-ready-prover "proof-shell" "\
+Make sure the proof assistant is ready for a command.
+If QUEUEMODE is set, succeed if the proof shell is busy but
+has mode QUEUEMODE.
+Otherwise, if the shell is busy, give an error.
+No change to current buffer or point." nil nil)
+
+(autoload 'proof-shell-live-buffer "proof-shell" "\
+Return buffer of active proof assistant, or nil if none running." nil nil)
+
+(autoload 'proof-shell-available-p "proof-shell" "\
+Returns non-nil if there is a proof shell active and available.
+No error messages. Useful as menu or toolbar enabler." nil nil)
+
+(autoload 'proof-start-queue "proof-shell" "\
+Begin processing a queue of commands in ALIST.
+If START is non-nil, START and END are buffer positions in the
+active scripting buffer for the queue region.
+
+This function calls `proof-append-alist'." nil nil)
+
+(autoload 'proof-extend-queue "proof-shell" "\
+Extend the current queue with commands in ALIST, queue end END.
+To make sense, the commands should correspond to processing actions
+for processing a region from (buffer-queue-or-locked-end) to END.
+The queue mode is set to 'advancing" nil nil)
+
+(autoload 'proof-shell-wait "proof-shell" "\
+Busy wait for proof-shell-busy to become nil, or for TIMEOUT seconds.
+Needed between sequences of commands to maintain synchronization,
+because Proof General does not allow for the action list to be extended
+in some cases. May be called by proof-shell-invisible-command." nil nil)
+
+(autoload 'proof-shell-invisible-command "proof-shell" "\
+Send CMD to the proof process.
+Automatically add proof-terminal-char if necessary, examining
+proof-shell-no-auto-terminate-commands.
+By default, let the command be processed asynchronously.
+But if optional WAIT command is non-nil, wait for processing to finish
+before and after sending the command.
+If WAIT is an integer, wait for that many seconds afterwards." nil nil)
+
+(autoload 'proof-next-error "proof-shell" "\
+Jump to location of next error reported in the response buffer.
+
+A prefix arg specifies how many error messages to move;
+negative means move back to previous error messages.
+Just C-u as a prefix means reparse the error message buffer
+and start at the first error." t nil)
+
+;;;***
+
+;;;### (autoloads (proof-splash-message proof-splash-display-screen) "proof-splash" "generic/proof-splash.el")
+
+(autoload 'proof-splash-display-screen "proof-splash" "\
+Save window config and display Proof General splash screen.
+If TIMEOUT is non-nil, time out outside this function, definitely
+by end of configuring proof mode.
+Otherwise, timeout inside this function after 10 seconds or so." t nil)
+
+(autoload 'proof-splash-message "proof-splash" "\
+Make sure the user gets welcomed one way or another." t nil)
+
+;;;***
+
+;;;### (autoloads (proof-format) "proof-syntax" "generic/proof-syntax.el")
+
+(autoload 'proof-format "proof-syntax" "\
+Format a string by matching regexps in ALIST against STRING.
+ALIST contains (REGEXP . REPLACEMENT) pairs where REPLACEMENT
+may be a string or sexp evaluated to get a string." nil nil)
+
+;;;***
+
+;;;### (autoloads (proof-toolbar-setup) "proof-toolbar" "generic/proof-toolbar.el")
+
+(autoload 'proof-toolbar-setup "proof-toolbar" "\
+Initialize Proof General toolbar and enable it for current buffer.
+If proof-mode-use-toolbar is nil, change the current buffer toolbar
+to the default toolbar." t nil)
+
+;;;***
+
+;;;### (autoloads (proof-x-symbol-configure proof-x-symbol-mode proof-x-symbol-decode-region proof-x-symbol-enable) "proof-x-symbol" "generic/proof-x-symbol.el")
+
+(autoload 'proof-x-symbol-enable "proof-x-symbol" "\
+Turn on or off support for x-symbol, initializing if necessary.
+Calls proof-x-symbol-toggle-clean-buffers afterwards." nil nil)
+
+(autoload 'proof-x-symbol-decode-region "proof-x-symbol" "\
+Call (x-symbol-decode-region A Z), if x-symbol support is enabled.
+This converts tokens in the region into X-Symbol characters." nil nil)
+
+(autoload 'proof-x-symbol-mode "proof-x-symbol" "\
+Turn on/off x-symbol mode in current buffer, from proof-x-symbol-enable.
+The X-Symbol minor mode is only useful in buffers where symbol input
+takes place (it isn't used for output-only buffers)." t nil)
+
+(autoload 'proof-x-symbol-configure "proof-x-symbol" "\
+Configure the current buffer (goals or response) for X-Symbol." nil nil)
+
+;;;***
+
+;;;### (autoloads (texi-docstring-magic) "texi-docstring-magic" "generic/texi-docstring-magic.el")
+
+(autoload 'texi-docstring-magic "texi-docstring-magic" "\
+Update all texi docstring magic annotations in buffer." t nil)
+
+;;;***
+
+(provide 'proof-autoloads)
diff --git a/generic/proof-compat.el b/generic/proof-compat.el
new file mode 100644
index 00000000..74b53f69
--- /dev/null
+++ b/generic/proof-compat.el
@@ -0,0 +1,299 @@
+;; proof-comapt.el Operating system and Emacs version compatibility
+;;
+;; Copyright (C) 2000-2001 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk> and others
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; This file collects together compatibility hacks for different
+;; operating systems and Emacs versions. This is to help keep
+;; track of them.
+;;
+;; The development policy for Proof General is for the main codebase
+;; to be written for the latest stable version of XEmacs. We follow
+;; XEmacs advice on removing obsolete function calls.
+;;
+
+(require 'proof-site) ; for architecture flags
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; XEmacs compatibility
+;;;
+
+;; browse-url function isn't autoloaded in XEmacs 20.4
+(or (fboundp 'browse-url)
+ (autoload 'browse-url "browse-url"
+ "Ask a WWW browser to load URL." t))
+
+;; Compatibility with XEmacs 20.3/4
+(or (boundp 'path-separator)
+ (setq path-separator (if proof-running-on-win32 ";" ":")))
+(or (fboundp 'split-path)
+ (defun split-path (path)
+ "Explode a search path into a list of strings.
+The path components are separated with the characters specified
+with `path-separator'."
+ (split-string path (regexp-quote path-separator))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; GNU Emacs compatibility with XEmacs
+;;;
+
+(if proof-running-on-Emacs21
+ (defun proof-emacs-imagep (img)
+ "See if IMG is an Emacs 21 image descriptor."
+ (and (listp img) (eq (car img) 'image)))
+ ;; Otherwise, constant nil function
+ (defun proof-emacs-imagep (img)
+ "See if IMG is an Emacs 21 image descriptor (returns nil since not E21)."
+ nil))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; GNU Emacs compatibility
+;;;
+
+;; completion not autoloaded in FSF 20.6.1; we must call
+;; dynamic-completion-mode after loading it.
+(or (fboundp 'complete)
+ (autoload 'complete "completion"))
+(unless proof-running-on-XEmacs
+ (eval-after-load "completion"
+ '(dynamic-completion-mode)))
+
+
+;; These days cl is dumped with XEmacs (20.4,21.1) but not FSF Emacs
+;; 20.2. Would rather it was autoloaded but the autoloads are broken
+;; in FSF so we load it now.
+(require 'cl)
+
+;; Give a warning,
+(or (fboundp 'warn)
+(defun warn (str &rest args)
+ "Issue a warning STR. Defined by PG for FSF compatibility."
+ (apply 'message str args)
+ (sit-for 2)))
+
+;; Modeline redrawing (actually force-mode-line-update is alias on XEmacs)
+(or (fboundp 'redraw-modeline)
+(defun redraw-modeline (&rest args)
+ "Dummy function for Proof General on FSF Emacs."
+ (force-mode-line-update)))
+
+;; Interactive flag
+(or (fboundp 'noninteractive)
+ (defun noninteractive ()
+ "Dummy function for Proof General on FSF Emacs."
+ nil)) ;; pretend always interactive.
+
+;; Replacing in string (useful function from subr.el in XEmacs 21.1.9)
+(or (fboundp 'replace-in-string)
+(defun replace-in-string (str regexp newtext &optional literal)
+ "Replace all matches in STR for REGEXP with NEWTEXT string,
+ and returns the new string.
+Optional LITERAL non-nil means do a literal replacement.
+Otherwise treat \\ in NEWTEXT string as special:
+ \\& means substitute original matched text,
+ \\N means substitute match for \(...\) number N,
+ \\\\ means insert one \\."
+ ;; Not present in FSF
+ ;; (check-argument-type 'stringp str)
+ ;; (check-argument-type 'stringp newtext)
+ (let ((rtn-str "")
+ (start 0)
+ (special)
+ match prev-start)
+ (while (setq match (string-match regexp str start))
+ (setq prev-start start
+ start (match-end 0)
+ rtn-str
+ (concat
+ rtn-str
+ (substring str prev-start match)
+ (cond (literal newtext)
+ (t (mapconcat
+ (lambda (c)
+ (if special
+ (progn
+ (setq special nil)
+ (cond ((eq c ?\\) "\\")
+ ((eq c ?&)
+ (substring str
+ (match-beginning 0)
+ (match-end 0)))
+ ((and (>= c ?0) (<= c ?9))
+ (if (> c (+ ?0 (length
+ (match-data))))
+ ;; Invalid match num
+ (error "Invalid match num: %c" c)
+ (setq c (- c ?0))
+ (substring str
+ (match-beginning c)
+ (match-end c))))
+ (t (char-to-string c))))
+ (if (eq c ?\\) (progn (setq special t) nil)
+ (char-to-string c))))
+ newtext ""))))))
+ (concat rtn-str (substring str start)))))
+
+;; An implemenation of buffer-syntactic-context for FSF Emacs
+(defun proof-buffer-syntactic-context-emulate (&optional buffer)
+ "Return the syntactic context of BUFFER at point.
+If BUFFER is nil or omitted, the current buffer is assumed.
+The returned value is one of the following symbols:
+
+ nil ; meaning no special interpretation
+ string ; meaning point is within a string
+ comment ; meaning point is within a line comment"
+ (save-excursion
+ (if buffer (set-buffer buffer))
+ (let ((pp (parse-partial-sexp 1 (point))))
+ (cond
+ ((nth 3 pp) 'string)
+ ;; ((nth 7 pp) 'block-comment)
+ ;; "Stefan Monnier" <monnier+misc/news@rum.cs.yale.edu> suggests
+ ;; distinguishing between block comments and ordinary comments
+ ;; is problematic: not what XEmacs claims and different to what
+ ;; (nth 7 pp) tells us in FSF Emacs.
+ ((nth 4 pp) 'comment)))))
+
+
+;; In case Emacs is not aware of the function read-shell-command,
+;; we duplicate some code adjusted from minibuf.el distributed
+;; with XEmacs 21.1.9
+;;
+;; This code is still required as of FSF Emacs 20.6.1
+;;
+;; da: I think bothering with this just to give completion for
+;; when proof-prog-name-ask=t is rather a big overkill!
+;; Still, now it's here we'll leave it in as a pleasant surprise
+;; for FSF Emacs users.
+;;
+(or (fboundp 'read-shell-command)
+(defvar read-shell-command-map
+ (let ((map (make-sparse-keymap 'read-shell-command-map)))
+ (if (not (fboundp 'set-keymap-parents))
+ (if (fboundp 'set-keymap-parent)
+ ;; FSF Emacs 20.2
+ (set-keymap-parent map minibuffer-local-map)
+ ;; Earlier FSF Emacs
+ (setq map (append minibuffer-local-map map))
+ ;; XEmacs versions without read-shell-command?
+ (set-keymap-parents map minibuffer-local-map)))
+ (define-key map "\t" 'comint-dynamic-complete)
+ (define-key map "\M-\t" 'comint-dynamic-complete)
+ (define-key map "\M-?" 'comint-dynamic-list-completions)
+ map)
+ "Minibuffer keymap used by shell-command and related commands."))
+
+
+(or (fboundp 'read-shell-command)
+(defun read-shell-command (prompt &optional initial-input history)
+ "Just like read-string, but uses read-shell-command-map:
+\\{read-shell-command-map}"
+ (let ((minibuffer-completion-table nil))
+ (read-from-minibuffer prompt initial-input read-shell-command-map
+ nil (or history 'shell-command-history)))))
+
+
+;; Emulate a useful builtin from XEmacs.
+
+(or (fboundp 'remassq)
+(defun remassq (key alist)
+ "Delete any elements of ALIST whose car is `eq' to KEY.
+The modified ALIST is returned."
+;; The builtin version deletes by side-effect, but don't bother here.
+ (let (newalist)
+ (while alist
+ (unless (eq key (caar alist))
+ (setq newalist (cons (car alist) newalist)))
+ (setq alist (cdr alist)))
+ (nreverse newalist))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; A naughty hack to completion.el
+;;;
+;;; At the moment IMO completion too eagerly adds stuff to
+;;; its database: the completion-before-command function
+;;; makes every suffix be added as a completion!
+
+(eval-after-load "completion"
+'(defun completion-before-command ()
+ (if (and (symbolp this-command) (get this-command 'completion-function))
+ (funcall (get this-command 'completion-function)))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Old Emacs version compatibility
+;;;
+
+;; Create a menu from a customize group, for older/non-existent customize
+
+(or (fboundp 'customize-menu-create)
+(defun customize-menu-create (&rest args)
+ "Dummy function for PG; please upgrade your Emacs."
+ nil))
+
+(or (fboundp 'process-live-p)
+(defun process-live-p (obj)
+ "Return t if OBJECT is a process that is alive"
+ (memq (process-status proc) '(open run stop))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; General Emacs version compatibility
+;;;
+
+
+;; These are internal functions of font-lock, autoload policy
+;; differs between Emacs versions
+
+(or (fboundp 'font-lock-set-defaults)
+ (autoload 'font-lock-set-defaults "font-lock"))
+(or (fboundp 'font-lock-fontify-region)
+ (autoload 'font-lock-fontify-region "font-lock"))
+(or (fboundp 'font-lock-append-text-property)
+ (autoload 'font-lock-append-text-property "font-lock"))
+
+
+;; Handle buggy buffer-syntactic-context workaround in XEmacs 21.1,
+;; and FSF non-implementation.
+
+(cond
+ ((not (fboundp 'buffer-syntactic-context))
+ (defalias 'proof-buffer-syntactic-context
+ 'proof-buffer-syntactic-context-emulate))
+ ((string-match "21.1 .*XEmacs" emacs-version)
+ (defalias 'proof-buffer-syntactic-context
+ 'proof-buffer-syntactic-context-emulate))
+ (t
+ ;; Assume this version has a good implementation
+ (defalias 'proof-buffer-syntactic-context
+ 'buffer-syntactic-context)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Nasty: Emacs bug/problem fix section
+;;;
+
+
+;; Error in FSF emacs that this is undefined. I haven't time to
+;; investigate why.
+(unless proof-running-on-XEmacs
+ (defvar font-lock-preprocessor-face nil))
+
+
+
+;; End of proof-compat.el
+(provide 'proof-compat) \ No newline at end of file
diff --git a/generic/proof-config.el b/generic/proof-config.el
new file mode 100644
index 00000000..bdee9eac
--- /dev/null
+++ b/generic/proof-config.el
@@ -0,0 +1,2311 @@
+;; proof-config.el Proof General configuration for proof assistant
+;;
+;; Copyright (C) 1998-2001 LFCS Edinburgh.
+;; Authors: David Aspinall
+;;
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; This file declares all user options and prover-specific
+;; configuration variables for Proof General. The variables
+;; are used variously by the proof script mode and the
+;; proof shell mode, menus, and toolbar.
+;;
+;; To customize Proof General for a new proof assistant, you
+;; should read this file carefully!
+;;
+;; 1. User options
+;; 1b. Faces
+;;
+;; CONFIGURATION VARIABLES
+;; 2. Major modes
+;; 3. Menus, user-level commands, toolbar
+;; 4. Script mode configuration
+;; 5. Shell mode configuration
+;; 5a. commands
+;; 5b. regexps
+;; 5c. hooks and others
+;; 6. Goals buffer configuration
+;; [ 7. Splash screen settings -- moved to proof-splash.el now ]
+;; 8. X-Symbol support
+;; 9. Prover specific settings [NEW in 3.2 -- using new mechanism]
+;; 10. Global constants
+;;
+;; The user options don't need to be set on a per-prover basis,
+;; and the global constants probably should not be touched.
+;; The remaining variables in sections 2-9 should be set for
+;; each proof assistant. You don't need to set every variable
+;; for basic functionality; consult the manual for details of
+;; which ones are important.
+;;
+;; Customization groups and structure (sections in brackets)
+;;
+;; proof-general : Overall group
+;; proof-user-options : User options for Proof General (1)
+;; <ProverName> : User options for proof assistant (9)
+;; <ProverName->-internals : Internal settings for proof assistant (9)
+;;
+;; proof-general-internals : Internal settings of Proof General
+;; prover-config : Configuration for proof assistant (2,3)
+;; proof-script : settings for proof script mode (4)
+;; proof-shell : settings for proof shell mode (5)
+;; proof-goals : settings for goals buffer (6)
+;; proof-x-symbol : settings for X-Symbol (8)
+;; <Prover name>-config : Specific internal settings for a prover
+;;
+;; ==================================================
+;;
+;; Developers notes:
+;; i. When adding a new configuration variable, please
+;; (a) put it in the right customize group, and
+;; (b) add a magical comment in NewDoc.texi to document it!
+;; ii. Presently the customize library seems a bit picky over the
+;; :type property and some correct but complex types don't work
+;; properly.
+;; If the type is ill-formed, editing the whole group will be broken.
+;; Check after updates, by killing all customize buffers and
+;; invoking customize-group
+;;
+;; ==================================================
+
+(require 'proof-utils) ;; Macros used below
+
+
+;;
+;; 1. User options for proof mode
+;;
+;; The following variables are user options for Proof General.
+;; They appear in the 'proof' customize group and should
+;; *not* normally be touched by prover specific code.
+;;
+
+(defgroup proof-user-options nil
+ "User options for Proof General."
+ :group 'proof-general
+ :prefix "proof-")
+
+(defcustom proof-electric-terminator-enable nil
+ "*If non-nil, use electric terminator mode.
+If electric terminator mode is enabled, pressing a terminator will
+automatically issue `proof-assert-next-command' for convenience,
+to send the command straight to the proof process. If the command
+you want to send already has a terminator character, you don't
+need to delete the terminator character first. Just press the
+terminator somewhere nearby. Electric!"
+ :type 'boolean
+ :set 'proof-set-value
+ :group 'proof-user-options)
+
+(defcustom proof-toolbar-enable t
+ "*If non-nil, display Proof General toolbar for script buffers.
+NB: the toolbar is only available with XEmacs and GNU Emacs>=21."
+ :type 'boolean
+ :set 'proof-set-value
+ :group 'proof-user-options)
+
+(defpgcustom x-symbol-enable nil
+ "*Whether to use x-symbol in Proof General for this assistant.
+If you activate this variable, whether or not you really get x-symbol
+support depends on whether your proof assistant supports it and
+whether X-Symbol is installed in your Emacs."
+ :type 'boolean
+ :set 'proof-set-value
+ :group 'proof-user-options)
+
+(defcustom proof-output-fontify-enable t
+ "*Whether to fontify output from the proof assistant.
+If non-nil, output from the proof assistant will be highlighted
+in the goals and response buffers.
+(This is providing font-lock-keywords have been set for the
+buffer modes)."
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defcustom proof-trace-output-fontify-enable t ;; testing
+ ;; (not (and proof-running-on-XEmacs (>= emacs-major-version 21))) production
+ "*Whether to fontify output from the proof assistant during tracing.
+If non-nil and proof-output-fontify-enable is also non-nil,
+output from the proof assistant will be highlighted in the trace buffer.
+This is not recommended in XEmacs 21, since the font-lock parser
+is easily overloaded by large tracing output."
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defcustom proof-strict-state-preserving t
+ "*Whether Proof General is strict about the state preserving test.
+Proof General lets the user send arbitrary commands to the proof
+engine with `proof-minibuffer-cmd'. To attempt to preserve
+synchronization, there may be a test `proof-state-preserving-p'
+configured which prevents the user issuing certain commands
+directly (instead, they may only be entered as part of the script).
+
+Clever or arrogant users may want to avoid this test, which is
+done if this `proof-strict-state-preserving' is turned off (nil)."
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defcustom proof-strict-read-only
+ ;; For FSF Emacs, strict read only is buggy when used in
+ ;; conjunction with font-lock.
+ ;; The second conjunctive ensures that the expression is either
+ ;; `nil' or `strict' (and not 15!!).
+ (and proof-running-on-XEmacs 'strict)
+ "*Whether Proof General is strict about the read-only region in buffers.
+If non-nil, an error is given when an attempt is made to edit the
+read-only region. If nil, Proof General is more relaxed (but may give
+you a reprimand!).
+
+If you change proof-strict-read-only during a session, you must
+use the \"Restart\" button (or M-x proof-shell-restart) before
+you can see the effect in buffers.
+
+The default value for proof-strict-read-only depends on which
+version of Emacs you are using. In FSF Emacs, strict read only is buggy
+when it used in conjunction with font-lock, so it is disabled by default."
+ :type 'boolean
+ :group 'proof-user-options)
+
+
+(defcustom proof-dont-switch-windows nil
+ "*Whether response and goals buffers have dedicated windows.
+If non-nil, Emacs windows displaying messages from the prover will not
+be switchable to display other windows.
+
+This option can help manage your display.
+
+Setting this option triggers a three-buffer mode of interaction where
+the goals buffer and response buffer are both displayed, rather than
+the two-buffer mode where they are switched between. It also prevents
+Emacs automatically resizing windows between proof steps.
+
+If you use several frames (the same Emacs in several windows on the
+screen), you can force a frame to stick to showing the goals or
+response buffer.
+
+For single frame use this option may be inconvenient for
+experienced Emacs users."
+ ;; Did say:
+ ;; Moreover, this option may cause problems with multi-frame
+ ;; use because of a bug.
+ ;; but I can't find it as of 3.0pre201099.
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defcustom proof-multiple-frames-enable nil
+ "*Whether response and goals buffers have separate frames.
+If non-nil, Emacs will make separate frames (screen windows) for
+the goals and response buffers, by altering the Emacs variable
+`special-display-regexps'."
+ :type 'boolean
+ :set 'proof-set-value
+ :group 'proof-user-options)
+
+(defcustom proof-delete-empty-windows
+ nil
+ "*If non-nil, automatically remove windows when they are cleaned.
+For example, at the end of a proof the goals buffer window will
+be cleared; if this flag is set it will automatically be removed.
+If you want to fix the sizes of your windows you may want to set this
+variable to 'nil' to avoid windows being deleted automatically.
+If you use multiple frames, only the windows in the currently
+selected frame will be automatically deleted."
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defcustom proof-toolbar-use-button-enablers
+ (not
+ (or
+ ;; Disabled by default for win32 and solaris
+ proof-running-on-win32
+ (and (boundp 'system-configuration)
+ (string-match "sun-solaris" system-configuration))))
+ "*If non-nil, toolbars buttons may be enabled/disabled automatically.
+Toolbar buttons can be automatically enabled/disabled according to
+the context. Set this variable to nil if you don't like this feature
+or if you find it unreliable.
+
+Notes:
+* Toolbar enablers are only available with XEmacs 21 and later.
+* With this variable nil, buttons do nothing when they would
+otherwise be disabled.
+* If you change this variable it will only be noticed when you
+next start Proof General.
+* The default value for XEmacs built for solaris is nil, because
+of unreliabilities with enablers there."
+ :type 'boolean
+ :group 'proof-user-options)
+
+; (defcustom proof-auto-retract
+; nil
+; "*If non-nil, retract automatically when locked region is edited.
+; With this option active, the locked region will automatically be
+; unlocked when the user attempts to edit it. To make use of this
+; option, proof-strict-read-only should be turned off.
+
+; Note: this feature has not been implemented yet, it is only an idea."
+; :type 'boolean
+; :group 'proof-user-options)
+
+(defcustom proof-query-file-save-when-activating-scripting
+ t
+"*If non-nil, query user to save files when activating scripting.
+
+Often, activating scripting or executing the first scripting command
+of a proof script will cause the proof assistant to load some files
+needed by the current proof script. If this option is non-nil, the
+user will be prompted to save some unsaved buffers in case any of
+them corresponds to a file which may be loaded by the proof assistant.
+
+You can turn this option off if the save queries are annoying, but
+be warned that with some proof assistants this may risk processing
+files which are out of date with respect to the loaded buffers!"
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defpgcustom script-indent t
+ "*If non-nil, enable indentation code for proof scripts."
+ :type 'boolean
+ :group 'proof-user-options)
+
+;; FIXME: implement it! Use in indentation code.
+(defcustom proof-one-command-per-line
+ nil
+ "*If non-nil, format for newlines after each proof command in a script.
+This option is not fully-functional at the moment."
+ :type 'boolean
+ :group 'proof-user-options)
+
+
+(defcustom proof-prog-name-ask
+ nil
+ "*If non-nil, query user which program to run for the inferior process."
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defcustom proof-prog-name-guess
+ nil
+ "*If non-nil, use `proof-guess-command-line' to guess proof-prog-name.
+This option is compatible with proof-prog-name-ask.
+No effect if proof-guess-command-line is nil."
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defcustom proof-tidy-response
+ t
+ "*Non-nil indicates that the response buffer should be cleared often.
+The response buffer can be set either to accumulate output, or to
+clear frequently.
+
+With this variable non-nil, the response buffer is kept tidy by
+clearing it often, typically between successive commands (just like the
+goals buffer).
+
+Otherwise the response buffer will accumulate output from the prover."
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defcustom proof-show-debug-messages nil
+ "*Whether to display debugging messages in the response buffer.
+If non-nil, debugging messages are displayed in the response giving
+information about what Proof General is doing.
+To avoid erasing the messages shortly after they're printed,
+you should set `proof-tidy-response' to nil."
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defcustom proof-experimental-features nil
+ "*Whether to enable certain features regarded as experimental.
+As features are added to proof general but are not entirely robust,
+we only enable them if this flag is set. We encourage users to
+set this flag and test the features, but being aware that the
+features may be buggy (problem reports welcomed)."
+ :type 'boolean
+ :group 'proof-user-options)
+
+;;; NON BOOLEAN OPTIONS
+
+(defcustom proof-follow-mode 'locked
+ "*Choice of how point moves with script processing commands.
+One of the symbols: 'locked, 'follow, 'ignore.
+
+If 'locked, point sticks to the end of the locked region.
+If 'follow, point moves just when needed to display the locked region end.
+If 'ignore, point is never moved after movement commands or on errors.
+
+If you choose 'ignore, you can find the end of the locked using
+`M-x proof-goto-end-of-locked'."
+ :type '(choice
+ (const :tag "Follow locked region" locked)
+ (const :tag "Keep locked region displayed" follow)
+ (const :tag "Never move" ignore))
+ :group 'proof-user-options)
+
+(defcustom proof-auto-action-when-deactivating-scripting nil
+ "*If 'retract or 'process, do that when deactivating scripting.
+
+With this option set to 'retract or 'process, when scripting
+is turned off in a partly processed buffer, the buffer will be
+retracted or processed automatically.
+
+With this option unset (nil), the user is questioned instead.
+
+Proof General insists that only one script buffer can be partly
+processed: all others have to be completely processed or completely
+unprocessed. This is to make sure that handling of multiple files
+makes sense within the proof assistant.
+
+NB: A buffer is completely processed when all non-whitespace is
+locked (coloured blue); a buffer is completely unprocessed when there
+is no locked region."
+ :type '(choice
+ (const :tag "No automatic action; query user" nil)
+ (const :tag "Automatically retract" retract)
+ (const :tag "Automatically process" process))
+ :group 'proof-user-options)
+
+(defcustom proof-script-command-separator " "
+ "*String separating commands in proof scripts.
+For example, if a proof assistant prefers one command per line, then
+this string should be set to a newline. Otherwise it should be
+set to a space."
+ :type 'string
+ :group 'proof-user-options)
+
+(defcustom proof-rsh-command ""
+ "*Shell command prefix to run a command on a remote host.
+For example,
+
+ ssh bigjobs
+
+Would cause Proof General to issue the command `ssh bigjobs isabelle'
+to start Isabelle remotely on our large compute server called `bigjobs'.
+
+The protocol used should be configured so that no user interaction
+(passwords, or whatever) is required to get going."
+ :type 'string
+ :group 'proof-user-options)
+
+(defcustom proof-disappearing-proofs nil
+ "*Non-nil causes Proof General to hide proofs as they are completed."
+ :type 'boolean
+ :group 'proof-user-options)
+
+
+
+
+
+;;
+;; 1b. Faces.
+;;
+;; We ought to test that these work sensibly:
+;; a) with default colours
+;; b) with -rv
+;; c) on console
+;; d) on win32
+;; e) all above with FSF Emacs and XEmacs.
+;; But it's difficult to keep track of all that!
+;; Please report any bad/failing colour
+;; combinations to proofgen@dcs.ed.ac.uk
+;;
+;; Some of these faces aren't used by default in Proof General,
+;; but you can use them in font lock patterns for specific
+;; script languages.
+;;
+
+(defgroup proof-faces nil
+ "Faces used by Proof General."
+ :group 'proof-general
+ :prefix "proof-")
+
+(defmacro proof-face-specs (bl bd ow)
+ "Return a spec for `defface' with BL for light bg, BD for dark, OW o/w."
+ `(append
+ (apply 'append
+ (mapcar
+ (lambda (ty) (list
+ (list (list (list 'type ty) '(class color)
+ (list 'background 'light))
+ (quote ,bl))
+ (list (list (list 'type ty) '(class color)
+ (list 'background 'dark))
+ (quote ,bd))))
+ '(x mswindows gtk)))
+ (list (list t (quote ,ow)))))
+
+(defface proof-queue-face
+ (proof-face-specs
+ (:background "mistyrose")
+ (:background "mediumvioletred")
+ (:foreground "white" :background "black"))
+ "*Face for commands in proof script waiting to be processed."
+ :group 'proof-faces)
+
+(defface proof-locked-face
+ (proof-face-specs
+ (:background "lightcyan") ; was "lavender", then "lightsteelblue"
+ (:background "navy")
+ (:underline t))
+ "*Face for locked region of proof script (processed commands)."
+ :group 'proof-faces)
+
+(defface proof-declaration-name-face
+ (proof-face-specs
+ (:foreground "chocolate" :bold t)
+ (:foreground "orange" :bold t)
+ (:italic t :bold t))
+ "*Face for declaration names in proof scripts.
+Exactly what uses this face depends on the proof assistant."
+ :group 'proof-faces)
+
+;; FIXME da: are these defconsts still needed now we use defface?
+;; Answer: yes, for FSF Emacs they are.
+
+(defconst proof-declaration-name-face 'proof-declaration-name-face
+ "Expression that evaluates to a face.
+Required so that 'proof-declaration-name-face is a proper facename in
+both XEmacs 20.4 and Emacs 20.2's version of font-lock.")
+
+(defface proof-tacticals-name-face
+ (proof-face-specs
+ (:foreground "MediumOrchid3")
+ (:foreground "orchid")
+ (bold t))
+ "*Face for names of tacticals in proof scripts.
+Exactly what uses this face depends on the proof assistant."
+ :group 'proof-faces)
+
+(defconst proof-tacticals-name-face 'proof-tacticals-name-face
+ "Expression that evaluates to a face.
+Required so that 'proof-tacticals-name-face is a proper facename in
+both XEmacs 20.4 and Emacs 20.3's version of font-lock.")
+
+(defface proof-tactics-name-face
+ '((t
+ (bold t)))
+ "*Face for names of tactics in proof scripts.
+By default, they are printed with default face but the user
+may want to color them differently."
+ :group 'proof-faces)
+
+(defconst proof-tactics-name-face 'proof-tactics-name-face
+ "Expression that evaluates to a face.
+Required so that 'proof-tactics-name-face is a proper facename in
+both XEmacs 20.4 and Emacs 20.3's version of font-lock.")
+
+(defface proof-error-face
+ (proof-face-specs
+ (:background "salmon1" :bold t)
+ (:background "brown" :bold t)
+ (:bold t))
+ "*Face for error messages from proof assistant."
+ :group 'proof-faces)
+
+(defface proof-warning-face
+ (proof-face-specs
+ (:background "lemon chiffon")
+ (:background "orange2")
+ (:italic t))
+ "*Face for warning messages.
+Warning messages can come from proof assistant or from Proof General itself."
+ :group 'proof-faces)
+
+(defface proof-eager-annotation-face
+ (proof-face-specs
+ (:background "lightgoldenrod")
+ (:background "darkgoldenrod")
+ (:italic t))
+ "*Face for important messages from proof assistant."
+ :group 'proof-faces)
+
+(defface proof-debug-message-face
+ (proof-face-specs
+ (:foreground "Gray65")
+ (:background "Gray30")
+ (:italic t))
+ "*Face for debugging messages from Proof General."
+ :group 'proof-faces)
+
+(defface proof-boring-face
+ (proof-face-specs
+ (:foreground "Gray65")
+ (:background "Gray30")
+ (:italic t))
+ "*Face for boring text in proof assistant output."
+ :group 'proof-faces)
+
+(defface proof-mouse-highlight-face
+ (proof-face-specs
+ (:background "paleturquoise")
+ (:background "steelblue")
+ (:italic t))
+ "*General mouse highlighting face."
+ :group 'proof-faces)
+
+(defface proof-highlight-dependent-face
+ (proof-face-specs
+ (:background "orange")
+ (:background "darkorange")
+ (:italic t))
+ "*Face for showing (backwards) dependent parts."
+ :group 'proof-faces)
+
+(defface proof-highlight-dependency-face
+ (proof-face-specs
+ (:background "khaki")
+ (:background "peru")
+ (:italic t))
+ "*Face for showing (forwards) dependencies."
+ :group 'proof-faces)
+
+
+
+
+
+;;
+;; START OF CONFIGURATION VARIABLES
+;;
+;; Prelude
+;;
+
+(defgroup prover-config nil
+ "Configuration of Proof General for the prover in use."
+ :group 'proof-general-internals
+ :prefix "proof-")
+
+;; The variables in the "prover-config" (NB: not "proof config"!!)
+;; customize group are those which are intended to be set by the
+;; prover specific elisp, i.e. constants set on a per-prover basis.
+
+;; Putting these in a customize group is useful for documenting
+;; this type of variable, and for developing a new instantiation
+;; of Proof General.
+;; But it is *not* useful for final user-level customization!
+;; The reason is that saving these customizations across a session is
+;; not liable to work, because the prover specific elisp usually
+;; overrides with a series of setq's in <assistant>-mode-config type
+;; functions. This is why prover-config appears under the
+;; proof-general-internal group.
+
+
+
+
+
+
+
+
+;;
+;; 2. Major modes used by Proof General.
+;;
+;; The first three settings are used when starting a shell,
+;; so the must be set before a shell is started, so we
+;; know what modes are needed for each of the buffers.
+;; Hence the use of pre-shell-start-hook.
+
+(defcustom proof-mode-for-shell 'proof-shell-mode
+ "Mode for proof shell buffers.
+Usually customised for specific prover.
+Suggestion: this can be set a function called by `proof-pre-shell-start-hook'."
+ :type 'function
+ :group 'prover-config)
+
+(defcustom proof-mode-for-response 'proof-response-mode
+ "Mode for proof response buffer (and trace buffer, if used).
+Usually customised for specific prover.
+Suggestion: this can be set a function called by `proof-pre-shell-start-hook'."
+ :type 'function
+ :group 'prover-config)
+
+(defcustom proof-mode-for-goals 'proof-goals-mode
+ "Mode for proof state display buffers.
+Usually customised for specific prover.
+Suggestion: this can be set a function called by `proof-pre-shell-start-hook'."
+ :type 'function
+ :group 'prover-config)
+
+(defcustom proof-mode-for-script 'proof-mode
+ "Mode for proof script buffers.
+This is used by Proof General to find out which buffers
+contain proof scripts.
+The regular name for this is <PA>-mode. If you use any of the
+convenience macros Proof General provides for defining commands
+etc, then you should stick to this name.
+Suggestion: this can be set in the script mode configuration."
+ :type 'function
+ :group 'prover-config)
+
+(defcustom proof-guess-command-line nil
+ "Function to guess command line for proof assistant, given a filename.
+The function could take a filename as argument, run `make -n' to see
+how to compile the file non-interactively, then translate the result
+into an interactive invocation of the proof assistant with the same
+command line options. For an example, see coq/coq.el."
+ :type 'function
+ :group 'prover-config)
+
+
+
+;;
+;; 3. Configuration for menus, user-level commands, toolbar, etc.
+;;
+
+(defcustom proof-assistant-home-page ""
+ "Web address for information on proof assistant.
+Used for Proof General's help menu."
+ :type 'string
+ :group 'prover-config)
+
+(defcustom proof-context-command nil
+ "Command to display the context in proof assistant."
+ :type 'string
+ :group 'prover-config)
+
+(defcustom proof-info-command nil
+ "Command to ask for help or information in the proof assistant.
+String or fn. If a string, the command to use.
+If a function, it should return the command string to insert."
+ :type '(choice string function)
+ :group 'prover-config)
+
+(defcustom proof-showproof-command nil
+ "Command to display proof state in proof assistant."
+ :type 'string
+ :group 'prover-config)
+
+(defcustom proof-goal-command nil
+ "Command to set a goal in the proof assistant. String or fn.
+If a string, the format character `%s' will be replaced by the
+goal string.
+If a function, it should return the command string to insert."
+ :type '(choice string function)
+ :group 'prover-config)
+
+(defcustom proof-save-command nil
+ "Command to save a proved theorem in the proof assistant. String or fn.
+If a string, the format character `%s' will be replaced by the
+theorem name.
+If a function, it should return the command string to insert."
+ :type '(choice string function)
+ :group 'prover-config)
+
+(defcustom proof-find-theorems-command nil
+ "Command to search for a theorem containing a given term. String or fn.
+If a string, the format character `%s' will be replaced by the term.
+If a function, it should return the command string to insert."
+ :type '(choice string function)
+ :group 'prover-config)
+
+(defconst proof-toolbar-entries-default
+ `((state "Display proof state" "Display the current proof state" t)
+ (context "Display context" "Display the current context" t)
+ (goal "Start a new proof" "Start a new proof" t)
+ (retract "Retract buffer" "Retract (undo) whole buffer" t)
+ (undo "Undo step" "Undo the previous proof command" t)
+ (delete "Delete step" nil t)
+ (next "Next step" "Process the next proof command" t)
+ (use "Use buffer" "Process whole buffer" t)
+ (goto "Goto point" "Process or undo to the cursor position" t)
+ (restart "Restart scripting" "Restart scripting (clear all locked regions)" t)
+ (qed "Finish proof" "Close/save proved theorem" t)
+ (lockedend "Locked end" nil t)
+ (find "Find theorems" "Find theorems" t)
+ (show "Show proofs" nil t)
+ (hide "Hide proofs" nil t)
+ (command "Issue command" "Issue a non-scripting command" t)
+ (interrupt "Interrupt prover" "Interrupt the proof assistant (warning: may break synchronization)" t)
+ (info nil "Show online proof assistant information" t)
+ (help nil "Proof General manual" t))
+"Example value for proof-toolbar-entries. Also used to define Scripting menu.
+This gives a bare toolbar that works for any prover, providing the
+appropriate configuration variables are set.
+To add/remove prover specific buttons, adjust the `<PA>-toolbar-entries'
+variable, and follow the pattern in `proof-toolbar.el' for
+defining functions, images.")
+
+(defpgcustom toolbar-entries proof-toolbar-entries-default
+ "List of entries for Proof General toolbar and Scripting menu.
+Format of each entry is (TOKEN MENUNAME TOOLTIP ENABLER-P).
+
+For each TOKEN, we expect an icon with base filename TOKEN,
+a function proof-toolbar-<TOKEN>, and (optionally) an enabler
+proof-toolbar-<TOKEN>-enable-p.
+
+If MENUNAME is nil, item will not appear on the scripting menu.
+
+If TOOLTIP is nil, item will not appear on the toolbar.
+
+The default value is `proof-toolbar-entries-default' which contains
+the standard Proof General buttons.")
+
+(defcustom proof-assistant-true-value "true"
+ "String for true values in proof assistant, used for setting flags.
+Default is the string \"true\"."
+ :type 'string
+ :group 'prover-config)
+
+(defcustom proof-assistant-false-value "false"
+ "String for false values in proof assistant, used for setting flags.
+Default is the string \"false\"."
+ :type 'string
+ :group 'prover-config)
+
+(defcustom proof-assistant-format-int-fn 'int-to-string
+ "Function for converting integer values to ints in proof assistant.
+Used for configuring settings in proof assistant.
+Default is `int-to-string'."
+ :type 'function
+ :group 'prover-config)
+
+(defcustom proof-assistant-format-string-fn (lambda (value) value)
+ "Function for converting string values to strings in proof assistant.
+Used for configuring settings in proof assistant.
+Default is the identity function."
+ :type 'string
+ :group 'prover-config)
+
+(defcustom proof-assistant-setting-format nil
+ "Function for formatting setting strings for proof assistant.
+Setting strings are calculated by replacing a format character
+%b, %i, or %s in the :setting string in for each variable defined with
+`defpacustom', using the current value of that variable. This
+function is applied as a final step to do any extra markup, or
+conversion, etc. (No changes are done if nil)."
+ :type '(choice string nil)
+ :group 'prover-config)
+
+
+
+;;
+;; 4. Configuration for proof script mode
+;;
+
+;;
+;; The following variables should be set before proof-config-done
+;; is called. These configure the mode for the script buffer,
+;; including highlighting, etc.
+;;
+
+(defgroup proof-script nil
+ "Proof General configuration of scripting buffer mode."
+ :group 'prover-config
+ :prefix "proof-")
+
+(defcustom proof-terminal-char nil
+ "Character which terminates every command sent to proof assistant. nil if none.
+
+To configure command recognition properly, you must set at least one
+of these: `proof-script-sexp-commands', `proof-script-command-end-regexp',
+`proof-script-command-start-regexp', `proof-terminal-char',
+or `proof-script-parse-function'."
+ :type 'character
+ :group 'prover-config)
+
+(defcustom proof-script-sexp-commands nil
+ "Non-nil if proof script has a LISP-like syntax, and commands are top-level sexps.
+You should set this variable in script mode configuration.
+
+To configure command recognition properly, you must set at least one
+of these: `proof-script-sexp-commands', `proof-script-command-end-regexp',
+`proof-script-command-start-regexp', `proof-terminal-char',
+or `proof-script-parse-function'."
+ :type 'boolean
+ :group 'prover-config)
+
+(defcustom proof-script-command-end-regexp nil
+ "Regular expression which matches end of commands in proof script.
+You should set this variable in script mode configuration.
+
+To configure command recognition properly, you must set at least one
+of these: `proof-script-sexp-commands', `proof-script-command-end-regexp',
+`proof-script-command-start-regexp', `proof-terminal-char',
+or `proof-script-parse-function'."
+ :type 'string
+ :group 'prover-config)
+
+(defcustom proof-script-command-start-regexp nil
+ "Regular expression which matches start of commands in proof script.
+You should set this variable in script mode configuration.
+
+To configure command recognition properly, you must set at least one
+of these: `proof-script-sexp-commands', `proof-script-command-end-regexp',
+`proof-script-command-start-regexp', `proof-terminal-char',
+or `proof-script-parse-function'."
+ :type 'string
+ :group 'prover-config)
+
+
+(defcustom proof-script-use-new-parser nil
+ "Whether to use the new parsing mechanism, based on `proof-script-parse-function'.
+This is a stop-gap option in Proof General 3.2 added because
+the parsing functions went through several iterations and the final
+(but best) iteration was little tested."
+ :type 'boolean
+ :group 'prover-config)
+
+
+(defcustom proof-script-integral-proofs nil
+ "Whether the complete text after a goal confines the actual proof.
+
+In structured proof languages like Isabelle/Isar a theorem is
+established by a goal statement (with full information about the
+result, including name and statement), followed by a self-contained
+piece of text for the proof. The latter should be treated as an
+integral entity for purposes of hiding proof bodies etc.
+
+This variable is better set to nil for tactical provers (like Coq)
+where important information about the result is spread over the
+initial ``goal'' and the final ``save'' command."
+ :type 'boolean
+ :group 'prover-config)
+
+;; Unadvertised customization variable
+(defvar proof-script-fly-past-comments t
+ "*If non-nil, fly past comments when scripting, coalescing them into single spans.")
+
+
+
+(defcustom proof-script-parse-function nil
+ "A function which parses a portion of the proof script.
+It is called with the proof script as the current buffer, and
+point the position where the parse should begin. It should
+move point to the exact end of the next \"segment\", and return
+a symbol indicating what has been parsed:
+
+ 'comment for a comment
+ 'cmd for a proof script command
+ nil if there is no complete next segment in the buffer
+
+If this is left unset, it will be configured automatically to
+a generic function according to which of `proof-terminal-char'
+and its friends are set."
+ :type 'string
+ :group 'prover-config)
+
+
+(defcustom proof-comment-start ""
+ "String which starts a comment in the proof assistant command language.
+The script buffer's comment-start is set to this string plus a space.
+Moreover, comments are usually ignored during script management, and not
+sent to the proof process.
+
+You should set this variable for reliable working of Proof General,
+as well as `proof-comment-end'."
+ :type 'string
+ :group 'proof-script)
+
+(defcustom proof-comment-start-regexp nil
+ "Regexp which matches a comment start in the proof command language.
+
+The default value for this is set as (regexp-quote proof-comment-start)
+but you can set this variable to something else more precise if necessary."
+ :type 'string
+ :group 'proof-script)
+
+(defcustom proof-comment-end "\n"
+ "String which ends a comment in the proof assistant command language.
+The script buffer's comment-end is set to a space plus this string.
+See also `proof-comment-start'.
+
+You should set this variable for reliable working of Proof General,"
+ :type 'string
+ :group 'proof-script)
+
+(defcustom proof-comment-end-regexp nil
+ "Regexp which matches a comment end in the proof command language.
+
+The default value for this is set as (regexp-quote proof-comment-end)
+but you can set this variable to something else more precise if necessary."
+ :type 'string
+ :group 'proof-script)
+
+(defcustom pg-insert-output-as-comment-fn nil
+ "Function to insert last output as a comment. Passed output as arg.
+If left as nil, the default behaviour is to insert and call `comment-region'."
+ :type '(choice function nil)
+ :group 'proof-script)
+
+(defcustom proof-string-start-regexp "\""
+ "Matches the start of a quoted string in the proof assistant command language."
+ :type 'string
+ :group 'proof-script)
+
+(defcustom proof-string-end-regexp "\""
+ "Matches the end of a quoted string in the proof assistant command language."
+ :type 'string
+ :group 'proof-script)
+
+(defcustom proof-case-fold-search nil
+ "Value for case-fold-search when recognizing portions of proof scripts.
+Also used for completion, via `proof-script-complete'.
+The default value is `nil'. If your prover has a case *insensitive*
+input syntax, proof-case-fold-search should be set to `t' instead.
+NB: This setting is not used for matching output from the prover."
+ :type 'boolean :group
+ 'proof-script)
+
+(defcustom proof-save-command-regexp nil
+ "Matches a save command."
+ :type 'regexp
+ :group 'proof-script)
+
+(defcustom proof-save-with-hole-regexp nil
+ "Regexp which matches a command to save a named theorem.
+The name of the theorem is build from the variable
+proof-save-with-hole-result using the same convention as
+query-replace-regexp.
+Used for setting names of goal..save and proof regions and for
+default function-menu configuration in proof-script-find-next-entity.
+
+It's safe to leave this setting as nil."
+ :type 'regexp
+ :group 'proof-script)
+
+(defcustom proof-save-with-hole-result 2
+ "String or Int: how to build the theorem name after matching
+with proof-save-with-hole-regexp. If it is an int N use match-string
+to recover the value of the Nth parenthesis matched. If it is a string
+use replace-match. It the later case, proof-save-with-hole-regexp should
+match the entire command"
+
+ :type '(choice string int)
+ :group 'proof-script)
+
+;; FIXME: unify uses so that proof-anchor-regexp works sensibly
+(defcustom proof-goal-command-regexp nil
+ "Matches a goal command in the proof script.
+This is used (1) to make the default value for `proof-goal-command-p',
+used as an important part of script management to find the start
+of an atomic undo block, and (2) to construct the default
+for `proof-script-next-entity-regexps' used for function menus."
+ :type 'regexp
+ :group 'proof-script)
+
+(defcustom proof-goal-with-hole-regexp nil
+ "Regexp which matches a command used to issue and name a goal.
+The name of the theorem is build from the variable
+proof-goal-with-hole-result using the same convention as
+query-replace-regexp.
+Used for setting names of goal..save regions and for default
+function-menu configuration in proof-script-find-next-entity.
+
+It's safe to leave this setting as nil."
+ :type 'regexp
+ :group 'proof-script)
+
+(defcustom proof-goal-with-hole-result 2
+ "String or Int: how to build the theorem name after matching
+with proof-goal-with-hole-regexp. If it is an int N use match-string
+to recover the value of the Nth parenthesis matched. If it is a string
+use replace-match. It the later case, proof-goal-with-hole-regexp should
+match the entire command"
+
+ :type '(choice string int)
+ :group 'proof-script)
+
+(defcustom proof-non-undoables-regexp nil
+ "Regular expression matching commands which are *not* undoable.
+Used in default functions `proof-generic-state-preserving-p'
+and `proof-generic-count-undos'. If you don't use those,
+may be left as nil."
+ :type '(choice nil regexp)
+ :group 'proof-script)
+
+(defcustom proof-ignore-for-undo-count nil
+ "Matcher for script commands to be ignored in undo count.
+May be left as nil, in which case it will be set to
+`proof-non-undoables-regexp'.
+Used in default function `proof-generic-count-undos'."
+ :type '(choice nil regexp function)
+ :group 'proof-script)
+
+(defcustom proof-script-next-entity-regexps nil
+ "Regular expressions to help find definitions and proofs in a script.
+This is the list of the form
+
+ (ANYENTITY-REGEXP
+ DISCRIMINATOR-REGEXP ... DISCRIMINATOR-REGEXP)
+
+The idea is that ANYENTITY-REGEXP matches any named entity in the
+proof script, on a line where the name appears. This is assumed to be
+the start or the end of the entity. The discriminators then test
+which kind of entity has been found, to get its name. A
+DISCRIMINATOR-REGEXP has one of the forms
+
+ (REGEXP MATCHNOS)
+ (REGEXP MATCHNOS 'backward BACKREGEXP)
+ (REGEXP MATCHNOS 'forward FORWARDREGEXP)
+
+If REGEXP matches the string captured by ANYENTITY-REGEXP, then
+MATCHNOS are the match numbers for the substrings which name the entity
+(these may be either a single number or a list of numbers).
+
+If 'backward BACKREGEXP is present, then the start of the entity
+is found by searching backwards for BACKREGEXP.
+
+Conversely, if 'forward FORWARDREGEXP is found, then the end of
+the entity is found by searching forwards for FORWARDREGEXP.
+
+Otherwise, the start and end of the entity will be the region matched
+by ANYENTITY-REGEXP.
+
+This mechanism allows fairly complex parsing of the buffer, in
+particular, it allows for goal..save regions which are named
+only at the end. However, it does not parse strings,
+comments, or parentheses.
+
+This variable may not need to be set: a default value which should
+work for goal..saves is calculated from proof-goal-with-hole-regexp,
+proof-goal-command-regexp, and proof-save-with-hole-regexp."
+ :type 'sexp
+ ;; Bit tricky.
+ ;; (list (regexp :tag "Any entity matcher")
+ ;; (:inline t repeat (choice regexp (const 'backward) etc
+ :group 'proof-script)
+
+(defcustom proof-script-find-next-entity-fn
+ 'proof-script-find-next-entity
+ "Name of function to find next interesting entity in a script buffer.
+This is used to configure func-menu. The default value is
+proof-script-find-next-entity, which searches for the next entity
+based on fume-function-name-regexp which by default is set from
+proof-script-next-entity-regexps.
+
+The function should move point forward in a buffer, and return a cons
+cell of the name and the beginning of the entity's region.
+
+Note that proof-script-next-entity-regexps is set to a default value
+from proof-goal-with-hole-regexp and proof-save-with-hole-regexp in
+the function proof-config-done, so you may not need to worry about any
+of this. See whether function menu does something sensible by
+default."
+ :type 'function
+ :group 'proof-script)
+
+;; FIXME da: This next one is horrible. We clearly would rather
+;; have just proof-goal-command regexp instead. This was born to solve
+;; problem that Coq can have goals which look like definitions, etc.
+;; Perhaps we can generalise the matching to understand function
+;; values as well as regexps.
+;; FIXME: could just as easily give default value of
+;; proof-std-goal-command-p here, why not?
+(defcustom proof-goal-command-p 'proof-generic-goal-command-p
+ "A function to test: is this really a goal command?
+
+This is added as a more refined addition to proof-goal-command-regexp,
+to solve the problem that Coq and some other provers can have goals which
+look like definitions, etc. (In the future we may generalize
+proof-goal-command-regexp instead)."
+ :type 'function
+ :group 'proof-script)
+
+;; FIXME mmw: increasing the horror even more ...
+;; FIXME da: why do you need the span below? I would like to replace
+;; this mess by single config variables which are allowed to be
+;; regexps or functions, handled in proof-string-match.
+;; FIXME mmw: the span is required to scan backwards through the text,
+;; determining the depth of proof nesting.
+;; FIXME da: yuck! What I'd really like to replace the mess with is
+;; feedback from the proof assistant, saying "that was a save", etc.
+;; FIXME mmw: all we need is some tracking of the 'depth' of commands;
+;; Why not let PG track this as in spans, changing the value based
+;; on some regexps for 'open' / 'close' commands? This would basically
+;; move the code of isar-global-save-command-p to proof-done-advancing.
+;; FIXME da: sounds like a good idea, then that would give us a proper
+;; handling of nested proofs?
+;;
+(defcustom proof-really-save-command-p (lambda (span cmd) t)
+ "Is this really a save command?
+
+This is a more refined addition to proof-save-command-regexp.
+It should be a function taking a span and command as argument,
+and can be used to track nested proofs. (See what is done in
+isar/ for example). In the future, this setting should be
+removed when the generic core is extended to handle nested
+proofs smoothly."
+ :type 'function
+ :group 'proof-script)
+
+(defcustom proof-completed-proof-behaviour nil
+ "Indicates how Proof General treats commands beyond the end of a proof.
+Normally goal...save regions are \"closed\", i.e. made atomic for undo.
+But once a proof has been completed, there may be a delay before
+the \"save\" command appears --- or it may not appear at all. Unless
+nested proofs are supported, this can spoil the undo-behaviour in
+script management since once a new goal arrives the old undo history
+may be lost in the prover. So we allow Proof General to close
+off the goal..[save] region in more flexible ways.
+The possibilities are:
+
+ nil - nothing special; close only when a save arrives
+ 'closeany - close as soon as the next command arrives, save or not
+ 'closegoal - close when the next \"goal\" command arrives
+ 'extend - keep extending the closed region until a save or goal.
+
+If your proof assistant allows nested goals, it will be wrong to close
+off the portion of proof so far, so this variable should be set to nil.
+There is no built-in understanding of the undo behaviour of nested
+proofs; instead there is some support for un-nesting nested proofs in
+the proof-lift-global mechanism. (Of course, this is risky in case of
+nested contexts!)"
+ :type '(choice
+ (const :tag "Close on save only" nil)
+ (const :tag "Close next command" closeany)
+ (const :tag "Close next goal" closegoal)
+ (const :tag "Extend" ignore))
+ :group 'proof-script)
+
+(defcustom proof-lift-global nil
+ "Function which lifts local lemmas from inside goals out to top level.
+This function takes the local goalsave span as an argument. Leave this
+set this at `nil' if the proof assistant does not support nested goals,
+or if you don't want to write a function to do move them around."
+ :type 'function
+ ;; FIXME customize broken on choices with function in them?
+ ;; :type '(choice (const :tag "No local lemmas" nil) (function))
+ :group 'proof-script)
+
+(defcustom proof-count-undos-fn 'proof-generic-count-undos
+ "Function to calculate a command to issue undos to reach a target span.
+The function takes a span as an argument, and should return a string
+which is the command to undo to the target span. The target is
+guaranteed to be within the current (open) proof.
+This is an important function for script management.
+The default setting `proof-generic-count-undos' is based on the
+settings `proof-non-undoables-regexp' and
+`proof-non-undoables-regexp'."
+ :type 'function
+ :group 'proof-script)
+
+; Not yet implemented.
+;
+;(defcustom proof-atomic-sequence-lists nil
+; "list of instructions for setting up atomic sequences of commands (ACS).
+
+;Each instruction is
+;a list of the form `(END START &optional FORGET-COMMAND)'. END is a
+;regular expression to recognise the last command in an ACS. START
+;is a function. Its input is the last command of an ACS. Its output
+;is a regular exression to recognise the first command of the ACS.
+;It is evaluated once and the output is successively matched agains
+;previously processed commands until a match occurs (or the
+;beginning of the current buffer is reached). The region determined
+;by (START,END) is locked as an ACS. Optionally, the ACS is
+;annotated with the actual command to retract the ACS. This is
+;computed by applying FORGET-COMMAND to the first and last command
+;of the ACS."
+; ;; FIXME customize broken on choices with function in them?
+; ;;:type '(repeat (cons regexp function (choice (const nil) function)))
+; :type '(repeat (cons regexp function function))
+; :group 'proof-shell)
+
+
+(defconst proof-no-command "COMMENT"
+ "String used as a nullary action (send no command to the proof assistant).
+Only relevant for proof-find-and-forget-fn.")
+
+(defcustom proof-find-and-forget-fn 'proof-generic-find-and-forget
+ "Function that returns a command to forget back to before its argument span.
+This setting is used to for retraction (undoing) in proof scripts.
+
+It should undo the effect of all settings between its target span
+up to (proof-locked-end). This may involve forgetting a number
+of definitions, declarations, or whatever.
+
+The special string proof-no-command means there is nothing to do.
+
+Important: the generic implementation `proof-generic-find-and-forget'
+does nothing, it always returns `proof-no-command'.
+
+This is an important function for script management.
+Study one of the existing instantiations for examples of how to write it,
+or leave it set to the default function `proof-generic-find-and-forget'
+(which see)."
+ :type 'function
+ :group 'proof-script)
+
+(defcustom proof-goal-hyp-fn nil
+ "Function which returns cons cell if point is at a goal/hypothesis.
+This is used to parse the proofstate output to mark it up for
+proof-by-pointing. It should return a cons or nil. First element of
+the cons is a symbol, 'goal' or 'hyp'. The second element is a
+string: the goal or hypothesis itself.
+
+If you leave this variable unset, no proof-by-pointing markup
+will be attempted."
+ :type '(choice function nil)
+ :group 'proof-script)
+
+(defcustom proof-kill-goal-command ""
+ "Command to kill the currently open goal.
+You must set this (perhaps to a no-op) for script management to work."
+ :type 'string
+ :group 'proof-script)
+
+(defcustom proof-undo-n-times-cmd nil
+ "Command to undo n steps of the currently open goal.
+String or function.
+If this is set to a string, `%s' will be replaced by the number of
+undo steps to issue.
+If this is set to a function, it should return the appropriate
+command when called with an integer (the number of undo steps).
+
+This setting is used for the default `proof-generic-count-undos'.
+If you set `proof-count-undos-fn' to something else, there is no
+need to set this variable."
+ :type '(or string function)
+ :group 'proof-script)
+
+(defcustom proof-global-p nil
+ "Whether a command is a global declaration. Predicate on strings or nil.
+This is used to handle nested goals allowed by some provers, by
+recognizing global declarations as candidates for rearranging the
+proof script.
+
+May be left as nil to disable this function."
+ :type 'function
+ :group 'proof-script)
+
+(defcustom proof-state-preserving-p 'proof-generic-state-preserving-p
+ "A predicate, non-nil if its argument (a command) preserves the proof state.
+If set, used by proof-minibuffer-cmd to filter out scripting
+commands which should be entered directly into the script itself.
+
+The default setting for this function, `proof-generic-state-preserving-p'
+tests by negating the match on `proof-non-undoables-regexp'."
+ :type 'function
+ :group 'proof-script)
+
+(defcustom proof-activate-scripting-hook nil
+ "Hook run when a buffer is switched into scripting mode.
+The current buffer will be the newly active scripting buffer.
+
+This hook may be useful for synchronizing with the proof
+assistant, for example, to switch to a new theory
+(in case that isn't already done by commands in the proof
+script).
+
+When functions in this hook are called, the variable
+`activated-interactively' will be non-nil if
+proof-activate-scripting was called interactively
+(rather than as a side-effect of some other action).
+If a hook function sends commands to the proof process,
+it should wait for them to complete (so the queue is cleared
+for scripting commands), unless activated-interactively is set."
+ :type '(repeat function)
+ :group 'proof-script)
+
+;;
+;; Proof script indentation
+;;
+
+(defcustom proof-indent 2
+ "Amount of proof script indentation."
+ :type 'number
+ :group 'proof-script)
+
+(defcustom proof-indent-hang nil
+ "Enable 'hanging' indentation for proof script."
+ :type 'boolean
+ :group 'proof-script)
+
+(defcustom proof-indent-enclose-offset 1
+ "Extra offset for enclosing indentation syntax elements."
+ :type 'number
+ :group 'proof-script)
+
+(defcustom proof-indent-open-offset 1
+ "Extra offset for opening indentation syntax elements."
+ :type 'number
+ :group 'proof-script)
+
+(defcustom proof-indent-close-offset 1
+ "Extra offset for closing indentation syntax elements."
+ :type 'number
+ :group 'proof-script)
+
+(defcustom proof-indent-any-regexp "\\s(\\|\\s)"
+ "Regexp for *any* syntax element guiding proof script indentation."
+ :type 'string
+ :group 'proof-script)
+
+(defcustom proof-indent-inner-regexp nil
+ "Regexp for text within syntax elements of proof script indentation."
+ :type 'string
+ :group 'proof-script)
+
+(defcustom proof-indent-enclose-regexp nil
+ "Regexp for enclosing syntax elements of proof script indentation."
+ :type 'string
+ :group 'proof-script)
+
+(defcustom proof-indent-open-regexp "\\s("
+ "Regexp for opening syntax elements of proof script indentation."
+ :type 'string
+ :group 'proof-script)
+
+(defcustom proof-indent-close-regexp "\\s)"
+ "Regexp for closing syntax elements of proof script indentation."
+ :type 'string
+ :group 'proof-script)
+
+
+(defcustom proof-font-lock-zap-commas nil
+ "If non-nil, enable a font-lock hack which unfontifies commas.
+If you fontify variables inside lists like [a,b,c] by matching
+on the brackets `[' and `]', you may take objection to the commas
+being coloured as well. In that case, enable this hack which
+will magically restore the commas to the default font for you.
+
+The hack is rather painful and forces immediate fontification of
+files on loading (no lazy, caching locking). It is unreliable
+under FSF Emacs, to boot.
+
+LEGO and Coq enable it by tradition."
+ :type 'boolean
+ :group 'proof-script)
+
+(defcustom proof-script-font-lock-keywords nil
+ "Value of font-lock-keywords used to fontify proof scripts.
+This is currently used only by proof-easy-config mechanism,
+to set font-lock-keywords before calling proof-config-done.
+See also proof-{shell,resp,goals}-font-lock-keywords."
+ :type 'sexp
+ :group 'proof-script)
+
+
+
+
+
+;;
+;; 5. Configuration for proof shell
+;;
+;; The variables in this section concern the proof shell mode.
+;; The first group of variables are hooks invoked at various points.
+;; The second group of variables are concerned with matching the output
+;; from the proof assistant.
+;;
+;; Variables here are put into the customize group 'proof-shell'.
+;;
+;; These should be set in the shell mode configuration, again,
+;; before proof-shell-config-done is called.
+;;
+
+(defgroup proof-shell nil
+ "Settings for output from the proof assistant in the proof shell."
+ :group 'prover-config
+ :prefix "proof-shell-")
+
+
+;;
+;; 5a. commands
+;;
+
+(defcustom proof-prog-name nil
+ "System command to run the proof assistant in the proof shell.
+Suggestion: this can be set in proof-pre-shell-start-hook from
+a variable which is in the proof assistant's customization
+group. This allows different proof assistants to coexist
+(albeit in separate Emacs sessions)."
+ :type 'string
+ :group 'proof-shell)
+
+(defcustom proof-shell-auto-terminate-commands t
+ "Non-nil if Proof General should try to add terminator to every command.
+If non-nil, whenever a command is sent to the prover using
+`proof-shell-invisible-command', Proof General will check to see if it
+ends with proof-terminal-char, and add it if not.
+If proof-terminal-char is nil, this has no effect."
+ :type 'boolean
+ :group 'proof-shell)
+
+(defcustom proof-shell-pre-sync-init-cmd nil
+ "The command for configuring the proof process to gain synchronization.
+This command is sent before Proof General's synchronization
+mechanism is engaged, to allow customization inside the process
+to help gain syncrhonization (e.g. engaging special markup).
+
+It is better to configure the proof assistant for this purpose
+via command line options if possible, in which case this variable
+does not need to be set.
+
+See also `proof-shell-init-cmd'."
+ :type '(choice string (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-init-cmd nil
+ "The command for initially configuring the proof process.
+This command is sent to the process as soon as synchronization is gained
+(when an annotated prompt is first recognized). It can be used to configure
+the proof assistant in some way, or print a welcome message
+(since output before the first prompt is discarded).
+
+See also `proof-shell-pre-sync-init-cmd'."
+ :type '(choice string (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-restart-cmd ""
+ "A command for re-initialising the proof process."
+ :type '(choice string (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-quit-cmd nil
+ "A command to quit the proof process. If nil, send EOF instead."
+ :type '(choice string (const nil))
+ :group 'proof-shell)
+
+;; FIXME could add option to quiz user before rude kill.
+(defcustom proof-shell-quit-timeout 10
+ "The number of seconds to wait after sending proof-shell-quit-cmd.
+After this timeout, the proof shell will be killed off more rudely.
+If your proof assistant takes a long time to clean up (for
+example writing persistent databases out or the like), you may
+need to bump up this value."
+ :type '(choice string (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-cd-cmd nil
+ "Command to the proof assistant to change the working directory.
+The format character `%s' is replaced with the directory, and
+the escape sequences in `proof-shell-filename-escapes' are
+applied to the filename.
+
+This setting is used to define the function proof-cd which
+changes to the value of (default-directory) for script buffers.
+For files, the value of (default-directory) is simply the
+directory the file resides in.
+
+NB: By default, proof-cd is called from proof-activate-scripting-hook,
+so that the prover switches to the directory of a proof
+script every time scripting begins."
+ :type 'string
+ :group 'proof-shell)
+
+(defcustom proof-shell-start-silent-cmd nil
+ "Command to turn prover goals output off when sending many script commands.
+If non-nil, Proof General will automatically issue this command
+to help speed up processing of long proof scripts.
+See also proof-shell-stop-silent-cmd.
+NB: terminator not added to command."
+ :type '(choice string (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-stop-silent-cmd nil
+ "Command to turn prover output on.
+If non-nil, Proof General will automatically issue this command
+to help speed up processing of long proof scripts.
+See also proof-shell-start-silent-cmd.
+NB: Terminator not added to command."
+ :type '(choice string (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-silent-threshold 2
+ "Number of waiting commands in the proof queue needed to trigger silent mode.
+Default is 2, but you can raise this in case switching silent mode
+on or off is particularly expensive (or make it ridiculously large
+to disable silent mode altogether)."
+ :type 'integer
+ :group 'proof-shell)
+
+(defcustom proof-shell-inform-file-processed-cmd nil
+ "Command to the proof assistant to tell it that a file has been processed.
+The format character `%s' is replaced by a complete filename for a
+script file which has been fully processed interactively with
+Proof General. See `proof-format-filename' for other possibilities
+to process the filename.
+
+This setting used to interface with the proof assistant's internal
+management of multiple files, so the proof assistant is kept aware of
+which files have been processed. Specifically, when scripting
+is deactivated in a completed buffer, it is added to Proof General's
+list of processed files, and the prover is told about it by
+issuing this command.
+
+If this is set to nil, no command is issued.
+
+See also: proof-shell-inform-file-retracted-cmd,
+proof-shell-process-file, proof-shell-compute-new-files-list."
+ :type '(choice string (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-inform-file-retracted-cmd nil
+ "Command to the proof assistant to tell it that a file has been retracted.
+The format character `%s' is replaced by a complete filename for a
+script file which Proof General wants the prover to consider as not
+completely processed. See `proof-format-filename' for other
+possibilities to process the filename.
+
+This is used to interface with the proof assistant's internal
+management of multiple files, so the proof assistant is kept aware of
+which files have been processed. Specifically, when scripting
+is activated, the file is removed from Proof General's list of
+processed files, and the prover is told about it by issuing this
+command. The action may cause the prover in turn to suggest to
+Proof General that files depending on this one are
+also unlocked.
+
+If this is set to nil, no command is issued.
+
+See also: proof-shell-inform-file-processed-cmd,
+proof-shell-process-file, proof-shell-compute-new-files-list."
+ :type '(choice string (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-auto-multiple-files nil
+ "Whether to use automatic multiple file management.
+If non-nil, Proof General will automatically retract a script file
+whenever another one is retracted which it depends on. It assumes
+a simple linear dependency between files in the order which
+they were processed.
+
+If your proof assistant has no management of file dependencies, or one
+which depends on a simple linear context, you may be able to use this
+setting to good effect. If the proof assistant has more complex
+file dependencies then you should configure it to communicate with
+Proof General about the dependencies rather than using this setting."
+ :type 'boolean
+ :group 'proof-shell)
+
+
+
+
+;;
+;; 5b. Regexp variables for matching output from proof process.
+;;
+
+(defcustom proof-shell-prompt-pattern nil
+ "Proof shell's value for comint-prompt-pattern, which see.
+This pattern is just for interaction in comint (shell buffer).
+You don't really need to set it."
+ :type 'regexp
+ :group 'proof-shell)
+
+;; FIXME da: replace this with wakeup-regexp or prompt-regexp?
+;; May not need next variable.
+(defcustom proof-shell-wakeup-char nil
+ "A special character which terminates an annotated prompt.
+Set to nil if proof assistant does not support annotated prompts."
+ :type '(choice character (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-first-special-char nil
+ "First special character.
+Codes above this character can have special meaning to Proof General,
+and are stripped from the prover's output strings.
+Leave unset if no special characters are being used."
+ :type '(choice character (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-annotated-prompt-regexp nil
+ "Regexp matching a (possibly annotated) prompt pattern.
+Output is grabbed between pairs of lines matching this regexp.
+To help matching you may be able to annotate the proof assistant
+prompt with a special character not appearing in ordinary output.
+The special character should appear in this regexp, and should
+be the value of proof-shell-wakeup-char."
+ :type 'regexp
+ :group 'proof-shell)
+
+(defcustom proof-shell-abort-goal-regexp nil
+ "Regexp matching output from an aborted proof."
+ :type 'regexp
+ :group 'proof-shell)
+
+(defcustom proof-shell-error-regexp nil
+ "Regexp matching an error report from the proof assistant.
+
+We assume that an error message corresponds to a failure in the last
+proof command executed. So don't match mere warning messages with
+this regexp. Moreover, an error message should not be matched as an
+eager annotation (see proof-shell-eager-annotation-start) otherwise it
+will be lost.
+
+Error messages are considered to begin from proof-shell-error-regexp
+and continue until the next prompt.
+
+The engine matches interrupts before errors, see proof-shell-interrupt-regexp.
+
+It is safe to leave this variable unset (as nil)."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+(defcustom proof-shell-next-error-regexp nil
+ "Regular expression which matches an error message, perhaps with line/column.
+Used by `proof-next-error' to jump to line numbers causing
+errors during some batch processing of the proof assistant.
+(During \"manual\" script processing, script usually automatically
+jumps to the end of the locked region)
+
+Match number 2 should be the line number, if present.
+Match number 3 should be the column number, if present.
+
+The filename may be matched by `proof-shell-next-error-filename-regexp'."
+ :type 'string
+ :group 'proof-shell)
+
+(defcustom proof-shell-next-error-filename-regexp nil
+ "Used to locate a filename that an error message refers to.
+Used by `proof-next-error' to jump to locations causing
+errors during some batch processing of the proof assistant.
+(During \"manual\" script processing, the script usually automatically
+jumps to the end of the locked region).
+
+Match number 2 should be the file name, if present.
+
+Errors must first be matched by `proof-shell-next-error-regexp'
+(whether they contain a line number or not). The response buffer
+is then searched *backwards* for a regexp matching this variable,
+`proof-shell-next-error-filename-regexp'. (So if the
+filename appears after the line number, make the first regexp
+match the whole line). Finally
+`proof-shell-next-error-extract-filename'
+may be used to extract the filename from
+This regexp should be set to match messages also matched by
+`proof-shell-error-message-line-number-regexp'.
+Match number 1 should be the filename."
+ :type 'string
+ :group 'proof-shell)
+
+;; FIXME: generalize this to string-or-function scheme
+(defcustom proof-shell-next-error-extract-filename nil
+ "A string used to extract filename from error message. %s replaced.
+NB: this is only used if the match itself does not already correspond
+to a filename."
+ :type 'string
+ :group 'proof-shell)
+
+(defcustom proof-shell-interrupt-regexp nil
+ "Regexp matching output indicating the assistant was interrupted.
+We assume that an interrupt message corresponds to a failure in the last
+proof command executed. So don't match mere warning messages with
+this regexp. Moreover, an interrupt message should not be matched as an
+eager annotation (see proof-shell-eager-annotation-start) otherwise it
+will be lost.
+
+The engine matches interrupts before errors, see proof-shell-error-regexp.
+
+It is safe to leave this variable unset (as nil)."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+(defcustom proof-shell-proof-completed-regexp nil
+ "Regexp matching output indicating a finished proof.
+
+When output which matches this regexp is seen, we clear the goals
+buffer in case this is not also marked up as a `goals' type of
+message.
+
+We also enable the QED function (save a proof) and will automatically
+close off the proof region if another goal appears before a save
+command."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+(defcustom proof-shell-clear-response-regexp nil
+ "Regexp matching output telling Proof General to clear the response buffer.
+This feature is useful to give the prover more control over what output
+is shown to the user. Set to nil to disable."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+(defcustom proof-shell-clear-goals-regexp nil
+ "Regexp matching output telling Proof General to clear the goals buffer.
+This feature is useful to give the prover more control over what output
+is shown to the user. Set to nil to disable."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+(defcustom proof-shell-start-goals-regexp nil
+ "Regexp matching the start of the proof state output.
+This is an important setting. Output between `proof-shell-start-goals-regexp'
+and `proof-shell-end-goals-regexp' will be pasted into the goals buffer
+and possibly analysed further for proof-by-pointing markup."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+(defcustom proof-shell-end-goals-regexp nil
+ "Regexp matching the end of the proof state output, or nil.
+If nil, just use the rest of the output following proof-shell-start-goals-regexp."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+(defcustom proof-shell-eager-annotation-start nil
+ "Eager annotation field start. A regular expression or nil.
+An eager annotation indicates to Proof General that some following output
+should be displayed (or processed) immediately and not accumulated for
+parsing later.
+
+It is nice to recognize (starts of) warnings or file-reading messages
+with this regexp. You must also recognize any special messages
+from the prover to PG with this regexp (e.g. `proof-shell-clear-goals-regexp',
+`proof-shell-retract-files-regexp', etc.)
+
+See also `proof-shell-eager-annotation-start-length',
+`proof-shell-eager-annotation-end'.
+
+Set to nil to disable this feature."
+ :type '(choice regexp (const :tag "Disabled" nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-eager-annotation-start-length 10
+ "Maximum length of an eager annotation start.
+Must be set to the maximum length of the text that may match
+`proof-shell-eager-annotation-start' (at least 1).
+If this value is too low, eager annotations may be lost!
+
+This value is used internally by Proof General to optimize the process
+filter to avoid unnecessary searching."
+ :type 'integer
+ :group 'proof-shell)
+
+(defcustom proof-shell-eager-annotation-end "\n"
+ "Eager annotation field end. A regular expression or nil.
+An eager annotation indicates to Emacs that some following output
+should be displayed or processed immediately.
+
+See also `proof-shell-eager-annotation-start'.
+
+It is nice to recognize (ends of) warnings or file-reading messages
+with this regexp. You must also recognize (ends of) any special messages
+from the prover to PG with this regexp (e.g. `proof-shell-clear-goals-regexp',
+`proof-shell-retract-files-regexp', etc.)
+
+The default value is \"\\n\" to match up to the end of the line."
+ :type '(choice regexp (const :tag "Unset" nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-assumption-regexp nil
+ "A regular expression matching the name of assumptions.
+
+At the moment, this setting is not used in the generic Proof General.
+
+In the future it will be used for a generic implementation for `proof-goal-hyp-fn',
+used to help parse the goals buffer to annotate it for proof by pointing."
+ :type '(choice regexp (const :tag "Unset" nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-process-file nil
+ "A pair (REGEXP . FUNCTION) to match a processed file name.
+
+If REGEXP matches output, then the function FUNCTION is invoked on the
+output string chunk. It must return the name of a script file (with
+complete path) that the system has successfully processed. In
+practice, FUNCTION is likely to inspect the match data. If it returns
+the empty string, the file name of the scripting buffer is used
+instead. If it returns nil, no action is taken.
+
+Care has to be taken in case the prover only reports on compiled
+versions of files it is processing. In this case, FUNCTION needs to
+reconstruct the corresponding script file name. The new (true) file
+name is added to the front of `proof-included-files-list'."
+ :type '(choice (cons regexp function) (const nil))
+ :group 'proof-shell)
+
+
+;; FIXME da: why not amalgamate the next two into a single
+;; variable as above? Maybe because removing one
+;;
+
+(defcustom proof-shell-retract-files-regexp nil
+ "Matches a message that the prover has retracted a file.
+
+At this stage, Proof General's view of the processed files is out of
+date and needs to be updated with the help of the function
+`proof-shell-compute-new-files-list'."
+ :type '(choice regexp (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-compute-new-files-list nil
+ "Function to update `proof-included-files list'.
+
+It needs to return an up to date list of all processed files. Its
+output is stored in `proof-included-files-list'. Its input is the
+string of which `proof-shell-retract-files-regexp' matched a
+substring. In practice, this function is likely to inspect the
+previous (global) variable `proof-included-files-list' and the match
+data triggered by `proof-shell-retract-files-regexp'."
+ :type '(choice function (const nil))
+ :group 'proof-shell)
+
+(defcustom proof-shell-leave-annotations-in-output nil
+ "Flag indicating whether to strip annotations from output or not.
+\"annotations\" are special characters with the top bit set.
+If annotations are left in, they are made invisible and can be used
+to do syntax highlighting with font-lock."
+ :type 'boolean
+ :group 'proof-shell)
+
+(defcustom proof-shell-set-elisp-variable-regexp nil
+ "Regexp matching output telling Proof General to set some variable.
+This allows the proof assistant to configure Proof General directly
+and dynamically.
+
+If the regexp matches output from the proof assistant, there should be
+two match strings: (match-string 1) should be the name of the elisp
+variable to be set, and (match-string 2) should be the value of the
+variable (which will be evaluated as a lisp expression).
+
+A good markup for the second string is to delimit with #'s, since
+these are not valid syntax for elisp evaluation.
+
+Elisp errors will be trapped when evaluating; set
+proof-show-debug-messages to be informed when this happens.
+
+Example uses are to adjust PG's internal copies of proof assistant's
+settings, or to make automatic dynamic syntax adjustments in Emacs to
+match changes in theory, etc.
+
+If you pick a dummy variable name (e.g. `proof-dummy-setting') you
+can just evaluation arbitrary elisp expressions for their side
+effects, to adjust menu entries, or even launch auxiliary programs.
+But use with care -- there is no protection against catastrophic elisp!
+
+This setting could also be used to move some configuration settings
+from PG to the prover, but this is not really supported (most settings
+must be made before this mechanism will work). In future, the PG
+standard protocol, PGIP, will use this mechanism for making all
+settings."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+(defcustom proof-shell-match-pgip-cmd nil
+ "Regexp used to match PGIP command from proof assistant.
+The matching string will be parsed as XML and then processed by
+`pg-pgip-process-cmd'."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+(defcustom proof-shell-theorem-dependency-list-regexp nil
+ "Regexp matching output telling Proof General what the dependencies are.
+This is so that the dependent theorems can be highlighted somehow.
+Set to nil to disable.
+This is an experimental feature, currently work-in-progress."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+(defcustom proof-shell-trace-output-regexp nil
+ "Regexp matching tracing output which should be displayed in trace buffer.
+Each line which matches this regexp but would otherwise be treated
+as an ordinary response, is sent to the trace buffer instead of the
+response buffer.
+
+This is intended for unusual debugging output from
+the prover, rather than ordinary output from final proofs.
+
+Set to nil to disable.
+
+Suggestion: this can be set a function called by `proof-pre-shell-start-hook'."
+ :type '(choice nil regexp)
+ :group 'proof-shell)
+
+
+;;
+;; 5c. hooks and other miscellaneous customizations
+;;
+
+(defcustom proof-shell-filename-escapes nil
+ "A list of escapes that are applied to %s for filenames.
+A list of cons cells, car of which is string to be replaced
+by the cdr.
+For example, when directories are sent to Isabelle, HOL, and Coq,
+they appear inside ML strings and the backslash character and
+quote characters must be escaped. The setting
+ '((\"\\\\\\\\\" . \"\\\\\\\\\")
+ (\"\\\"\" . \"\\\\\\\"\"))
+achieves this. This does not apply to LEGO, which does not
+need backslash escapes and does not allow filenames with
+quote characters.
+
+This setting is used inside the function `proof-format-filename'."
+ :type '(list (cons string string))
+ :group 'proof-shell)
+
+(defcustom proof-shell-process-connection-type
+ ;; Use ptys unless it seems like we're on Solaris. Only have
+ ;; a good chance to guess if shell-command-to-string and uname
+ ;; available.
+ (if (and
+ (not (fboundp 'win32-long-file-name))
+ (fboundp 'shell-command-to-string))
+ (not (string-match "[sS]un" (shell-command-to-string "uname")))
+ t)
+ "The value of process-connection-type for the proof shell.
+Set non-nil for ptys, nil for pipes.
+The default (and preferred) option is to use pty communication.
+However there is a long-standing backslash/long line problem with
+Solaris which gives a mess of ^G characters when some input is sent
+which has a \ in the 256th position.
+So we select pipes by default if it seems like we're on Solaris.
+We do not force pipes everywhere because this risks loss of data."
+ :type 'boolean
+ :group 'proof-shell)
+
+(defcustom proof-shell-strip-crs-from-input t
+ "If non-nil, replace carriage returns in every input with spaces.
+This is enabled by default: it is appropriate for some systems
+because several CR's can result in several prompts, which may mess
+up the display (or even worse, the synchronization)."
+ :type 'boolean
+ :group 'proof-shell)
+
+(defcustom proof-shell-insert-hook nil
+ "Hooks run by proof-shell-insert before inserting a command.
+Can be used to configure the proof assistant to the interface in
+various ways -- for example, to observe or alter the commands sent to
+the prover, or to sneak in extra commands to configure the prover.
+
+This hook is called inside a save-excursion with the proof-shell-buffer
+current, just before inserting and sending the text in the
+variable `string'. The hook can massage `string' or insert additional
+text directly into the proof-shell-buffer.
+Before sending `string', it will be stripped of carriage returns.
+
+Additionally, the hook can examine the variable `action'. It will be
+a symbol, set to the callback command which is executed in the proof
+shell filter once `string' has been processed. The `action' variable
+suggests what class of command is about to be inserted:
+
+ 'proof-done-invisible A non-scripting command
+ 'proof-done-advancing A \"forward\" scripting command
+ 'proof-done-retracting A \"backward\" scripting command
+
+Caveats: You should be very careful about setting this hook. Proof
+General relies on a careful synchronization with the process between
+inputs and outputs. It expects to see a prompt for each input it
+sends from the queue. If you add extra input here and it causes more
+prompts than expected, things will break! Extending the variable
+`string' may be safer than inserting text directly, since it is
+stripped of carriage returns before being sent.
+
+Example uses:
+LEGO uses this hook for setting the pretty printer width if
+the window width has changed;
+Plastic uses it to remove literate-style markup from `string'.
+The x-symbol support uses this hook to convert special characters
+into tokens for the proof assistant."
+ :type '(repeat function)
+ :group 'proof-shell)
+
+(defcustom proof-pre-shell-start-hook nil
+ "Hooks run before proof shell is started.
+Suggestion: set this to a function which configures just these proof
+shell variables:
+
+ proof-prog-name
+ proof-mode-for-shell
+ proof-mode-for-response
+ proof-mode-for-goals
+ proof-shell-trace-output-regexp
+
+This is the bare minimum needed to get a shell buffer and
+its friends configured in the function proof-shell-start."
+ :type '(repeat function)
+ :group 'proof-shell)
+
+(defcustom proof-shell-handle-delayed-output-hook
+ '(proof-pbp-focus-on-first-goal)
+ "Hooks run after new output has been displayed in goals or response buffer."
+ :type '(repeat function)
+ :group 'proof-shell)
+
+(defcustom proof-shell-handle-error-or-interrupt-hook
+ '(proof-goto-end-of-locked-if-pos-not-visible-in-window)
+ "Run after an error or interrupt has been reported in the response buffer.
+Hook functions may inspect `proof-shell-error-or-interrupt-seen' to
+determine whether the cause was an error or interrupt."
+ :type '(repeat function)
+ :group 'proof-shell)
+
+(defcustom proof-shell-pre-interrupt-hook
+ nil
+ "Run immediately after `comint-interrupt-subjob' is called.
+This hook is added to allow customization for Poly/ML and other
+systems where the system queries the user before returning to
+the top level. For Poly/ML it can be used to send the string \"f\",
+for example."
+ :type '(repeat function)
+ :group 'proof-shell)
+
+(defcustom proof-shell-process-output-system-specific nil
+ "Set this variable to handle system specific output.
+Errors, start of proofs, abortions of proofs and completions of
+proofs are recognised in the function `proof-shell-process-output'.
+All other output from the proof engine is simply reported to the
+user in the RESPONSE buffer.
+
+To catch further special cases, set this variable to a pair of
+functions '(condf . actf). Both are given (cmd string) as arguments.
+`cmd' is a string containing the currently processed command.
+`string' is the response from the proof system. To change the
+behaviour of `proof-shell-process-output', (condf cmd string) must
+return a non-nil value. Then (actf cmd string) is invoked.
+
+See the documentation of `proof-shell-process-output' for the required
+output format."
+ :type '(repeat function)
+ :group 'proof-shell)
+
+(defcustom proof-state-change-hook nil
+ "This hook is called when state change may have occurred.
+Specifically, this hook is called after a region has been
+asserted or retracted, or after a command has been sent
+to the prover with proof-shell-invisible-command.
+
+This hook is used within Proof General to refresh the
+toolbar."
+ :type '(repeat function)
+ :group 'proof-shell)
+
+(defcustom proof-shell-font-lock-keywords nil
+ "Value of font-lock-keywords used to fontify the proof shell.
+This is currently used only by proof-easy-config mechanism,
+to set font-lock-keywords before calling proof-config-done.
+See also proof-{script,resp,goals}-font-lock-keywords."
+ :type 'sexp
+ :group 'proof-script)
+
+
+
+;;
+;; 6. Goals buffer
+;;
+
+(defgroup proof-goals nil
+ "Settings for configuring the goals buffer."
+ :group 'prover-config
+ :prefix "pbp-")
+
+(defcustom proof-analyse-using-stack nil
+ "Choice of syntax tree encoding for terms.
+
+If nil, prover is expected to make no optimisations.
+If non-nil, the pretty printer of the prover only reports local changes.
+For LEGO 1.3.1 use `nil', for Coq 6.2, use `t'."
+ :type 'boolean
+ :group 'proof-goals)
+
+(defcustom pbp-change-goal nil
+ "Command to change to the goal `%s'"
+ :type 'string
+ :group 'proof-goals)
+
+(defcustom pbp-goal-command nil
+ "Command informing the prover that `pbp-button-action' has been
+requested on a goal."
+ :type '(choice nil regexp)
+ :group 'proof-goals)
+
+(defcustom pbp-hyp-command nil
+ "Command informing the prover that `pbp-button-action' has been
+requested on an assumption."
+ :type '(choice nil regexp)
+ :group 'proof-goals)
+
+(defcustom pbp-error-regexp nil
+ "Regexp indicating that the proof process has identified an error."
+ :type '(choice nil regexp)
+ :group 'proof-goals)
+
+(defcustom proof-shell-result-start nil
+ "Regexp matching start of an output from the prover after pbp commands.
+In particular, after a `pbp-goal-command' or a `pbp-hyp-command'."
+ :type '(choice nil regexp)
+ :group 'proof-goals)
+
+(defcustom proof-shell-result-end ""
+ "Regexp matching end of output from the prover after pbp commands.
+In particular, after a `pbp-goal-command' or a `pbp-hyp-command'."
+ :type 'regexp
+ :group 'proof-goals)
+
+(defcustom proof-shell-start-char nil
+ "Starting special for a subterm markup.
+Subsequent characters with values *below* proof-shell-first-special-char
+are assumed to be subterm position indicators. Subterm markups should
+be finished with proof-shell-end-char."
+ :type '(choice character (const nil))
+ :group 'proof-goals)
+
+(defcustom proof-shell-end-char nil
+ "Finishing special for a subterm markup.
+See documentation of proof-shell-start-char."
+ :type '(choice character (const nil))
+ :group 'proof-goals)
+
+(defcustom proof-shell-goal-char nil
+ "Mark for goal.
+
+This setting is also used to see if proof-by-pointing features
+are configured. If it is unset, some of the code
+for parsing the prover output is disabled."
+ :type 'character
+ :group 'proof-goals)
+
+(defcustom proof-shell-field-char nil
+ "Annotated field end"
+ :type 'character
+ :group 'proof-goals)
+
+(defcustom proof-goals-font-lock-keywords nil
+ "Value of font-lock-keywords used to fontify the goals output.
+NB: the goals output is not kept in font-lock-mode because the
+fontification may rely on annotations which are erased before
+displaying. This means internal functions of PG must be used
+to display to the goals buffer to ensure fontification is done!
+This is currently used only by proof-easy-config mechanism,
+to set font-lock-keywords before calling proof-config-done.
+See also proof-{script,shell,resp}-font-lock-keywords."
+ :type 'sexp
+ :group 'proof-goals)
+
+;; FIXME: perhaps we need new customize group here, "goals" is
+;; not quite right for response buffer!
+(defcustom proof-resp-font-lock-keywords nil
+ "Value of font-lock-keywords used to fontify the response output.
+NB: the goals output is not kept in font-lock-mode because the
+fontification may rely on annotations which are erased before
+displaying. This means internal functions of PG must be used
+to display to the goals buffer to ensure fontification is done!
+This is currently used only by proof-easy-config mechanism,
+to set font-lock-keywords before calling proof-config-done.
+See also proof-{script,shell,resp}-font-lock-keywords."
+ :type 'sexp
+ :group 'proof-goals)
+
+
+
+;;
+;; 8. X-Symbol configuration
+;;
+
+(defgroup proof-x-symbol nil
+ "Configuration of X-Symbol for Proof General."
+ :group 'prover-config
+ :prefix "proof-xsym-")
+
+(defcustom proof-xsym-extra-modes nil
+ "List of additional mode names to use X-Symbol with Proof General tokens.
+These modes will have X-Symbol enabled for the proof assistant token language,
+in addition to the four modes for Proof General (script, shell, response, pbp).
+
+Set this variable if you want additional modes to also display
+tokens (for example, editing documentation or source code files)."
+ :type '(repeat symbol)
+ :group 'proof-x-symbol)
+
+;; I don't really know what this setting is good for?
+(defcustom proof-xsym-font-lock-keywords nil
+ "Font lock keywords to use for the proof assistants X-Symbol token language."
+ :type 'sexp
+ :group 'proof-x-symbol)
+
+(defcustom proof-xsym-activate-command nil
+ "Command to activate token input/output for X-Symbol.
+If non-nil, this command is sent to the proof assistant when
+X-Symbol support is activated."
+ :type 'string
+ :group 'proof-x-symbol)
+
+(defcustom proof-xsym-deactivate-command nil
+ "Command to deactivate token input/output for X-Symbol.
+If non-nil, this command is sent to the proof assistant when
+X-Symbol support is deactivated."
+ :type 'string
+ :group 'proof-x-symbol)
+
+(defpgcustom x-symbol-language proof-assistant-symbol
+ "Setting for x-symbol-language for the current proof assistant.
+It defaults to proof-assistant-symbol, which makes X Symbol
+look for files named x-symbol-<PA>.el.")
+
+
+
+
+;;
+;; 9. Prover specific settings
+;;
+;; The settings defined here automatically use the current proof
+;; assistant symbol as a prefix, i.e. isa-favourites, coq-favourites,
+;; or whatever will be defined on evaluation.
+
+(defpgcustom favourites nil
+ "*Favourite commands for this proof assistant.
+A list of lists of the form (COMMAND INSCRIPT MENUNAME KEY),
+arguments for `proof-add-favourite', which see.")
+
+(defpgcustom menu-entries nil
+ "Extra entries for proof assistant specific menu.
+A list of menu items [NAME CALLBACK ENABLER ...]. See the documentation
+of `easy-menu-define' for more details."
+ :type 'sexp
+ :group 'prover-config)
+
+(defpgcustom help-menu-entries nil
+ "Extra entries for help submenu for proof assistant specific help menu.
+A list of menu items [NAME CALLBACK ENABLER ...]. See the documentation
+of `easy-menu-define' for more details."
+ :type 'sexp
+ :group 'prover-config)
+
+(defpgcustom keymap (make-keymap (concat proof-assistant " keymap"))
+ "Proof assistant specific keymap, used under prefix C-c a."
+ :type 'sexp
+ :group 'prover-config)
+
+(defpgcustom completion-table nil
+ "List of identifiers to use for completion for this proof assistant.
+Completion is activated with \\[complete].
+
+If this table is empty or needs adjusting, please make changes using
+`customize-variable' and send suggestions to proofgen@@dcs.ed.ac.uk."
+ :type '(list string)
+ :group 'prover-config)
+
+;; FIXME: not used yet.
+(defpgcustom tags-program nil
+ "Program to run to generate TAGS table for proof assistant."
+ :type 'file
+ :group 'prover-config)
+
+
+
+
+
+;;
+;; 10. Global constants
+
+(defcustom proof-general-name "Proof-General"
+ "Proof General name used internally and in menu titles."
+ :type 'string
+ :group 'proof-general-internals)
+
+(defcustom proof-general-home-page
+ "http://www.proofgeneral.org"
+ "*Web address for Proof General"
+ :type 'string
+ :group 'proof-general-internals)
+
+(defcustom proof-unnamed-theorem-name
+ "Unnamed_thm"
+ "A name for theorems which are unnamed. Used internally by Proof General."
+ :type 'string
+ :group 'proof-general-internals)
+
+;; FIXME: da: could we put these into another keymap shared across the
+;; various PG modes?
+(defcustom proof-universal-keys
+ '(([(control c) (control c)] . proof-interrupt-process)
+ ([(control c) (control v)] . proof-minibuffer-cmd)
+ ([(control c) \`] . proof-next-error))
+"List of key-bindings made for the script, goals and response buffer.
+Elements of the list are tuples `(k . f)'
+where `k' is a key-binding (vector) and `f' the designated function."
+ :type 'sexp
+ :group 'proof-general-internals)
+
+
+
+
+
+
+;; End of proof-config.el
+(provide 'proof-config)
diff --git a/generic/proof-depends.el b/generic/proof-depends.el
new file mode 100644
index 00000000..67a1f586
--- /dev/null
+++ b/generic/proof-depends.el
@@ -0,0 +1,207 @@
+;; proof-depends.el Managing theorem-theorem and theorem-definition dependencies.
+;;
+;; Copyright (C) 2000,1 University of Edinburgh.
+;; Authors: Fiona McNeill, David Aspinall.
+;;
+;; Status: Experimental code
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; Based on Fiona McNeill's MSc project on analysing dependencies within proofs.
+;; Code rewritten by David Aspinall.
+;;
+
+;; Variables
+
+(defvar proof-thm-names-of-files nil
+ "A list of file and theorems contained within.
+A list of lists; the first element of each list is a file-name, the
+second element a list of all the thm names in that file.
+i.e.: ((file-name-1 (thm1 thm2 thm3)) (file-name-2 (thm1 thm2 thm3)))")
+
+(defvar proof-def-names-of-files nil
+ "A list of files and defs contained within.
+A list of lists; the first element of each list is a file-name, the
+second element a list of all the def names in that file.
+i.e.: ((file-name-1 (def1 def2 def3)) (file-name-2 (def1 def2 def3)))")
+
+
+;; Utility functions
+
+(defun proof-depends-module-name-for-buffer ()
+ "Return a module name for the current buffer.
+This is a name that the prover prefixes all item names with.
+For example, in isabelle, a file Stuff.ML contains theorems with
+fully qualified names of the form Stuff.theorem1, etc.
+For other provers, this function may need modifying."
+ (if buffer-file-name
+ (file-name-nondirectory
+ (file-name-sans-extension buffer-file-name)) ""))
+
+(defun proof-depends-module-of (name)
+ "Return a pair of a module name and base name for a given item name.
+Assumes module name is given by dotted prefix."
+ (let ((dot (string-match "\\." name)))
+ (if dot
+ (cons (substring name 0 dot) (substring name (+ dot 1)))
+ (cons "" name))))
+
+(defun proof-depends-names-in-same-file (names)
+ "Return subset of list NAMES which are guessed to occur in same file.
+This is done using `proof-depends-module-name-for-buffer' and
+`proof-depends-module-of'."
+ (let ((filemod (proof-depends-module-name-for-buffer))
+ samefile)
+ (while names
+ (let ((splitname (proof-depends-module-of (car names))))
+ (if (equal filemod (car splitname))
+ (setq samefile (cons (cdr splitname) samefile))))
+ (setq names (cdr names)))
+ ;; NB: reversed order
+ samefile))
+
+
+;;
+;; proof-depends-process-dependencies: the main entry point.
+;;
+;;;###autoload
+(defun proof-depends-process-dependencies (name gspan)
+ "Process dependencies reported by prover, for NAME in span GSPAN.
+Called from `proof-done-advancing' when a save is processed and
+proof-last-theorem-dependencies is set."
+
+ (set-span-property gspan 'dependencies
+ proof-last-theorem-dependencies)
+
+ (let* ((samefilenames (proof-depends-names-in-same-file
+ proof-last-theorem-dependencies))
+
+ ;; Find goalsave spans earlier in this file which this
+ ;; one depends on; update their list of dependents,
+ ;; and return resulting list paired up with names.
+ (depspans
+ (apply 'append
+ (mapcar-spans
+ (lambda (depspan)
+ (let ((dname (span-property depspan 'name)))
+ (if (and
+ (eq (span-property depspan 'type) 'goalsave)
+ (member dname samefilenames))
+ (let ((forwarddeps
+ (span-property depspan 'dependents)))
+ (set-span-property depspan 'dependents
+ (cons
+ (list name gspan) forwarddeps))
+ ;; return list of args for menu fun: name and span
+ (list (list dname depspan))))))
+ (point-min)
+ (span-start gspan)
+ 'type))))
+
+ (set-span-property gspan 'dependencies-within-file depspans)
+ (setq proof-last-theorem-dependencies nil)))
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Menu Functions
+;;
+;; The following functions set up the menus which are the key way in
+;; which the dependency information is used.
+
+
+(defun proof-dependency-in-span-context-menu (span)
+ "Make a portion of a context-sensitive menu showing proof dependencies."
+ (list
+ "-------------"
+ (proof-dep-make-submenu "Local dependency..."
+ (lambda (namespan) (car namespan))
+ 'proof-goto-dependency
+ (span-property span 'dependencies-within-file))
+ (proof-make-highlight-depts-menu "Highlight dependencies"
+ 'proof-highlight-depcs
+ span 'dependencies-within-file)
+ (proof-dep-make-submenu "Local dependents..."
+ (lambda (namepos) (car namepos))
+ 'proof-goto-dependency
+ (span-property span 'dependents))
+ (proof-make-highlight-depts-menu "Highlight dependents"
+ 'proof-highlight-depts
+ span 'dependents)
+ ["Unhighlight all" proof-dep-unhighlight t]
+ "-------------"
+ (proof-dep-make-submenu "All dependencies..."
+ (lambda (name) (car name))
+ 'proof-show-dependency
+ (mapcar 'list (span-property span 'dependencies)))))
+
+
+(defun proof-dep-make-submenu (name namefn appfn list)
+ "Make menu items for a submenu NAME, using appfn applied to each elt in LIST.
+If LIST is empty, return a disabled menu item with NAME."
+ (if list
+ (cons name
+ (mapcar `(lambda (l)
+ (vector (,namefn l)
+ (cons (quote ,appfn) l) t)) list))
+ (vector name nil nil)))
+
+(defun proof-make-highlight-depts-menu (name fn span prop)
+ "Return a menu item that for highlighting dependents/depencies of SPAN."
+ (let ((deps (span-property span prop)))
+ (vector name `(,fn ,(span-property span 'name) (quote ,deps)) (not (not deps)))))
+
+
+;;
+;; Functions triggered by menus
+;;
+
+(defun proof-goto-dependency (name span)
+ ;; FIXME: check buffer is right one. Later we'll allow switching buffer
+ ;; here and jumping to different files.
+ (goto-char (span-start span))
+ (skip-chars-forward " \t\n"))
+
+(defun proof-show-dependency (thm)
+ ;; FIXME: make this prover independent with new regexp for print command!!
+ (proof-shell-invisible-command (format "thm \"%s\";" thm)))
+
+(defun proof-highlight-depcs (name nmspans)
+ (let ((helpmsg (concat "This item is a dependency (ancestor) of " name)))
+ (while nmspans
+ (let ((span (cadar nmspans)))
+ (set-span-property span 'face 'proof-highlight-dependency-face)
+ (set-span-property span 'mouse-highlight nil)
+ (set-span-property span 'help-echo helpmsg))
+ (setq nmspans (cdr nmspans)))))
+
+(defun proof-highlight-depts (name nmspans)
+ (let ((helpmsg (concat "This item depends on (is a child of) " name)))
+ (while nmspans
+ (let ((span (cadar nmspans)))
+ (set-span-property span 'face 'proof-highlight-dependent-face)
+ (set-span-property span 'mouse-highlight nil)
+ (set-span-property span 'help-echo helpmsg)
+ (set-span-property span 'balloon-help helpmsg))
+ (setq nmspans (cdr nmspans)))))
+
+(defun proof-dep-unhighlight ()
+ "Returned all highlighted spans in file to the proof-locked-face highlighting."
+ (interactive)
+ ;; FIXME: not quite right! Will highlight spans in queue as locked too,
+ ;; and covers too many spans.
+ (save-excursion
+ (let ((span (span-at (point-min) 'type)))
+ (while span
+ (pg-set-span-helphighlights span 'nohighlight)
+ (set-span-property span 'face 'proof-locked-face)
+ (setq span (next-span span 'type))))))
+
+
+
+
+(provide 'proof-depends)
+;; proof-depends.el ends here
diff --git a/generic/proof-easy-config.el b/generic/proof-easy-config.el
new file mode 100644
index 00000000..a6a501f6
--- /dev/null
+++ b/generic/proof-easy-config.el
@@ -0,0 +1,84 @@
+;; proof-easy-config.el Easy configuration for Proof General
+;;
+;; Copyright (C) 1999-2001 David Aspinall / LFCS.
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; Future version might copy settings instead; consider how best to
+;; interface with customization mechanism so a new prover can be
+;; configured by editing inside custom buffers.
+;;
+(require 'proof)
+
+(defvar proof-easy-config-derived-modes-table
+ '(("" "script" proof-mode (proof-config-done))
+ ("shell" "shell" proof-shell-mode (proof-shell-config-done))
+ ("response" "response" proof-response-mode (proof-response-config-done))
+ ("goals" "goals" proof-goals-mode (proof-goals-config-done)))
+ "A list of (PREFIXSYM SUFFIXNAME PARENT MODEBODY) for derived modes.")
+
+(defun proof-easy-config-define-derived-modes ()
+ (dolist (modedef proof-easy-config-derived-modes-table)
+ (let* ((prefixsym (nth 0 modedef))
+ (suffixnm (nth 1 modedef))
+ (parent (nth 2 modedef))
+ (body (nthcdr 3 modedef))
+ (modert (concat (symbol-name proof-assistant-symbol)
+ "-" prefixsym))
+ (hyphen (if (string-equal prefixsym "") "" "-"))
+ (mode (intern (concat modert hyphen "mode")))
+ (modename (concat proof-assistant " " suffixnm))
+ (varname (intern (concat "proof-mode-for-" suffixnm)))
+ ;; FIXME: declare these variables in proof-config:
+ ;; proof-script-font-lock-keywords, etc.
+ ;; proof-script-syntax-table-entries, etc.
+ ;; FIXME: in future versions, use these settings in *-config-done
+ ;; to simplify elisp code elsewhere.
+ (fntlcks (intern (concat "proof-" suffixnm "-font-lock-keywords")))
+ (modsyn (intern (concat "proof-" suffixnm "-syntax-table-entries")))
+ (fullbody (append
+ (if (boundp fntlcks)
+ (list `(setq font-lock-keywords ,fntlcks)))
+ (if (boundp modsyn)
+ (list `(let ((syn ,modsyn))
+ (while syn
+ (modify-syntax-entry
+ (car syn) (cadr syn))
+ (setq syn (cddr syn))))))
+ body)))
+ (eval
+ `(define-derived-mode ,mode ,parent ,modename nil ,@fullbody))
+ ;; Set proof-mode-for-script and friends
+ ;; NB: top-level, so we don't need proof-pre-shell-start-hook.
+ (set varname mode))))
+
+(defun proof-easy-config-check-setup (sym name)
+ "A number of simple checks."
+ (cond
+ ((or
+ (and (boundp 'proof-assistant) proof-assistant
+ (not (equal proof-assistant ""))
+ (not (equal proof-assistant name)))
+ (and (boundp 'proof-assistant-symbol) proof-assistant-symbol
+ (not (eq proof-assistant-symbol sym))))
+ (error "proof-easy-config: Proof General is already in use for a different prover!"))
+ (t
+ ;; Setting these here is nice for testing: no need to get
+ ;; proof-assistant-table right first.
+ (customize-set-variable 'proof-assistant name)
+ (customize-set-variable 'proof-assistant-symbol sym))))
+
+;;;###autoload
+(defmacro proof-easy-config (sym name &rest body)
+ "Configure Proof General for proof-assistant using BODY as a setq body."
+ `(progn
+ (proof-easy-config-check-setup ,sym ,name)
+ (setq
+ ,@body)
+ (proof-easy-config-define-derived-modes)))
+
+;;
+(provide 'proof-easy-config)
+
diff --git a/generic/proof-indent.el b/generic/proof-indent.el
new file mode 100644
index 00000000..d7399429
--- /dev/null
+++ b/generic/proof-indent.el
@@ -0,0 +1,98 @@
+;; proof-indent.el Generic Indentation for Proof Assistants
+;; Authors: Markus Wenzel
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+
+(require 'proof) ; loader
+(require 'proof-script) ; indent code is for script editing
+
+
+(defun proof-indent-indent ()
+ "Determine indentation caused by syntax element at current point."
+ (cond
+ ((proof-looking-at-safe proof-indent-open-regexp)
+ proof-indent)
+ ((proof-looking-at-safe proof-indent-close-regexp)
+ (- proof-indent))
+ (t 0)))
+
+(defun proof-indent-offset ()
+ "Determine offset of syntax element at current point"
+ (cond
+ ((proof-looking-at-syntactic-context)
+ proof-indent)
+ ((proof-looking-at-safe proof-indent-inner-regexp)
+ proof-indent)
+ ((proof-looking-at-safe proof-indent-enclose-regexp)
+ proof-indent-enclose-offset)
+ ((proof-looking-at-safe proof-indent-open-regexp)
+ proof-indent-open-offset)
+ ((proof-looking-at-safe proof-indent-close-regexp)
+ proof-indent-close-offset)
+ ((proof-looking-at-safe proof-indent-any-regexp) 0)
+ ((proof-looking-at-safe "\\s-*$") 0)
+ (t proof-indent)))
+
+(defun proof-indent-inner-p ()
+ "Check if current point is between actual indentation elements."
+ (or
+ (proof-looking-at-syntactic-context)
+ (proof-looking-at-safe proof-indent-inner-regexp)
+ (not
+ (or (proof-looking-at-safe proof-indent-any-regexp)
+ (proof-looking-at-safe "\\s-*$")))))
+
+(defun proof-indent-goto-prev () ; Note: may change point, even in case of failure!
+ "Goto to previous syntax element for script indentation, ignoring string/comment contexts."
+ (and
+ (proof-re-search-backward proof-indent-any-regexp nil t)
+ (or (not (proof-looking-at-syntactic-context))
+ (proof-indent-goto-prev))))
+
+(defun proof-indent-calculate (indent inner) ; Note: may change point!
+ "Calculate proper indentation level at current point"
+ (let*
+ ((current (point))
+ (found-prev (proof-indent-goto-prev)))
+ (if (not found-prev) (goto-char current)) ; recover position
+ (cond
+ ((and found-prev (or proof-indent-hang (= (current-indentation) (current-column))))
+ (+ indent
+ (current-column)
+ (if (and inner (not (proof-indent-inner-p))) 0 (proof-indent-indent))
+ (- (proof-indent-offset))))
+ ((not found-prev) 0) ;FIXME mmw: improve this case!?
+ (t
+ (proof-indent-calculate
+ (+ indent (if inner 0 (proof-indent-indent))) inner)))))
+
+
+;;;###autoload
+(defun proof-indent-line ()
+ "Indent current line of proof script, if indentation enabled."
+ (interactive)
+ (unless (not (proof-ass script-indent))
+ (if (< (point) (proof-locked-end))
+ (if (< (current-column) (current-indentation))
+ (skip-chars-forward "\t "))
+ (save-excursion
+ (indent-line-to
+ (max 0 (save-excursion
+ (back-to-indentation)
+ (proof-indent-calculate (proof-indent-offset) (proof-indent-inner-p))))))
+ (if (< (current-column) (current-indentation))
+ (back-to-indentation)))))
+
+
+;;;###autoload
+;FIXME mmw: remove this obsolete function!?
+(defun proof-indent-region (start end)
+ (interactive "r")
+ (if (< (point) (proof-locked-end))
+ (error "can't indent locked region!"))
+ (indent-region start end))
+
+
+(provide 'proof-indent)
diff --git a/generic/proof-menu.el b/generic/proof-menu.el
new file mode 100644
index 00000000..61574b33
--- /dev/null
+++ b/generic/proof-menu.el
@@ -0,0 +1,601 @@
+;; proof-menu.el Menus, keymaps, and misc commands for Proof General
+;;
+;; Copyright (C) 2000,2001 LFCS Edinburgh.
+;; Authors: David Aspinall
+;;
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+
+(require 'proof-toolbar) ; needed for proof-toolbar-scripting-menu
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Miscellaneous commands
+;;;
+
+(defun proof-display-some-buffers ()
+ "Display the reponse or goals buffer, toggling between them.
+Also move point to the end of the response buffer.
+If in three window or multiple frame mode, display both buffers."
+ (interactive)
+ (cond
+ ((or proof-dont-switch-windows proof-multiple-frames-enable)
+ ;; Display both
+ (proof-switch-to-buffer proof-response-buffer 'noselect)
+ (set-window-point (get-buffer-window proof-response-buffer)
+ (point-max))
+ (proof-switch-to-buffer proof-goals-buffer 'noselect))
+ ((and (buffer-live-p proof-response-buffer)
+ (get-buffer-window proof-response-buffer 'visible))
+ ;; Response buffer visible, let's display goals
+ (proof-switch-to-buffer proof-goals-buffer 'noselect))
+ ((buffer-live-p proof-response-buffer)
+ ;; Response buffer invisible, let's display it
+ (proof-switch-to-buffer proof-response-buffer 'noselect)
+ (set-window-point (get-buffer-window proof-response-buffer)
+ (point-max)))
+ (t
+ ;; No buffers existing, do nothing (might crank up process)
+ nil)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Key bindings
+;;;
+
+;;;###autoload
+(defun proof-menu-define-keys (map)
+;; M-a and M-e are usually {forward,backward}-sentence.
+;; Some modes also override these with similar commands
+(define-key map [(meta a)] 'proof-backward-command)
+(define-key map [(meta e)] 'proof-forward-command)
+(define-key map [(meta up)] 'proof-backward-command)
+(define-key map [(meta down)] 'proof-forward-command)
+(define-key map [(control meta a)] 'proof-goto-command-start)
+(define-key map [(control meta e)] 'proof-goto-command-end)
+(define-key map [(control c) (control a)] (proof-ass keymap))
+(define-key map [(control c) (control b)] 'proof-process-buffer)
+;; C-c C-c is proof-interrupt-process in universal-keys
+(define-key map [(control c) (control f)] 'proof-find-theorems)
+(define-key map [(control c) (control h)] 'proof-help)
+(define-key map [(control c) (control l)] 'proof-display-some-buffers)
+(define-key map [(control c) (control n)] 'proof-assert-next-command-interactive)
+(define-key map [(control c) (control p)] 'proof-prf)
+(define-key map [(control c) (control r)] 'proof-retract-buffer)
+(define-key map [(control c) (control s)] 'proof-toggle-active-scripting)
+(define-key map [(control c) (control t)] 'proof-ctxt)
+(define-key map [(control c) (control u)] 'proof-undo-last-successful-command)
+(define-key map [(control c) (control z)] 'proof-frob-locked-end)
+(define-key map [(control c) (control backspace)] 'proof-undo-and-delete-last-successful-command)
+; C-c C-v is proof-minibuffer-cmd in universal-keys
+(define-key map [(control c) (control ?.)] 'proof-goto-end-of-locked)
+(define-key map [(control c) (control return)] 'proof-goto-point)
+(define-key map [(control c) v] 'pg-toggle-visibility);; FIXME: FSF??
+(cond ((string-match "XEmacs" emacs-version)
+(define-key map [(control button3)] 'proof-mouse-goto-point)
+(define-key map [(control button1)] 'proof-mouse-track-insert)) ; no FSF
+ (t
+(define-key map [mouse-3] 'proof-mouse-goto-point))) ; FSF
+;; NB: next binding overwrites comint-find-source-code.
+;; FIXME: not implemented yet
+;; (define-key map [(meta p)] 'proof-previous-matching-command)
+;; (define-key map [(meta n)] 'proof-next-matching-command)
+;; Standard binding for completion
+(define-key map [(control return)] 'proof-script-complete)
+(define-key map [(control c) (control ?\;)] 'pg-insert-last-output-as-comment)
+;;
+;; Experimental: span moving functions
+(if proof-experimental-features (progn
+(define-key map [(control meta up)] 'pg-move-region-up)
+(define-key map [(control meta down)] 'pg-move-region-down)))
+;; Add the universal keys bound in all PG buffers.
+;; C-c ` is next-error in universal-keys
+(proof-define-keys map proof-universal-keys))
+
+
+
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Functions to define the menus
+;;;
+
+;; The main Proof-General generic menu
+
+;;;###autoload
+(defun proof-menu-define-main ()
+ (easy-menu-define
+ proof-mode-menu
+ proof-mode-map
+ "The main Proof General menu"
+ (cons proof-general-name
+ (append
+ proof-toolbar-scripting-menu
+ proof-menu
+ proof-config-menu
+ proof-bug-report-menu))))
+
+
+;; The proof assistant specific menu
+
+;;;###autoload
+(defun proof-menu-define-specific ()
+ (easy-menu-define
+ proof-assistant-menu
+ proof-mode-map
+ (concat "The menu for " proof-assistant)
+ (cons proof-assistant
+ (append
+ (proof-ass menu-entries)
+ '("----")
+ (or proof-menu-favourites
+ (proof-menu-define-favourites-menu))
+ (or proof-menu-settings
+ (proof-menu-define-settings-menu))
+ '("----")
+ (list
+ (vector
+ (concat "Start " proof-assistant)
+ 'proof-shell-start
+ ':active '(not (proof-shell-live-buffer)))
+ (vector
+ (concat "Exit " proof-assistant)
+ 'proof-shell-exit
+ ':active '(proof-shell-live-buffer)))
+ '("----")
+ (list
+ (cons "Help"
+ (append
+ `(;; FIXME: should only put these two on the
+ ;; menu if the settings are non-nil.
+ [,(concat proof-assistant " information")
+ (proof-help) t]
+ [,(concat proof-assistant " web page")
+ (browse-url proof-assistant-home-page) t])
+ (proof-ass help-menu-entries))))))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Contents of the generic menus
+;;;
+
+(defvar proof-help-menu
+ '("Help"
+ ["Proof General home page"
+ (browse-url proof-general-home-page) t]
+ ["Proof General Info"
+ (info "ProofGeneral") t])
+ "Proof General help menu.")
+
+(defvar proof-buffer-menu
+ '("Buffers"
+ ["Display some"
+ proof-display-some-buffers
+ :active (or (buffer-live-p proof-goals-buffer)
+ (buffer-live-p proof-response-buffer))]
+ ["Active scripting"
+ (proof-switch-to-buffer proof-script-buffer)
+ :active (buffer-live-p proof-script-buffer)]
+ ["Goals"
+ (proof-switch-to-buffer proof-goals-buffer t)
+ :active (buffer-live-p proof-goals-buffer)]
+ ["Response"
+ (proof-switch-to-buffer proof-response-buffer t)
+ :active (buffer-live-p proof-response-buffer)]
+ ["Shell"
+ (proof-switch-to-buffer proof-shell-buffer)
+ :active (buffer-live-p proof-shell-buffer)])
+ "Proof General buffer menu.")
+
+;; Make the togglers used in options menu below
+
+(proof-deftoggle proof-dont-switch-windows)
+(proof-deftoggle proof-script-fly-past-comments)
+(proof-deftoggle proof-delete-empty-windows)
+(proof-deftoggle proof-multiple-frames-enable proof-multiple-frames-toggle)
+(proof-deftoggle proof-output-fontify-enable proof-output-fontify-toggle)
+(proof-deftoggle proof-disappearing-proofs)
+(proof-deftoggle-fn (proof-ass-sym x-symbol-enable) 'proof-x-symbol-toggle)
+
+(defvar proof-quick-opts-menu
+ (cons
+ "Options"
+ (append
+ ;; FIXME: remove after 3.2, and promote this setting to proper option
+ (if proof-script-use-new-parser
+ '(["Fly past comments" proof-script-fly-past-comments-toggle
+ :style toggle
+ :selected proof-script-fly-past-comments])
+ nil)
+ '(["Disppearing proofs" proof-disappearing-proofs-toggle
+ :style toggle
+ :selected proof-disappearing-proofs]
+ ["Three window mode" proof-dont-switch-windows-toggle
+ :style toggle
+ :selected proof-dont-switch-windows]
+ ["Delete empty windows" proof-delete-empty-windows-toggle
+ :style toggle
+ :selected proof-delete-empty-windows]
+ ["Multiple frames" proof-multiple-frames-toggle
+ :style toggle
+ :selected proof-multiple-frames-enable]
+ ["Output highlighting" proof-output-fontify-toggle
+ :active t
+ :style toggle
+ :selected proof-output-fontify-enable]
+ ["Toolbar" proof-toolbar-toggle
+ :active (and (or (featurep 'toolbar) (featurep 'tool-bar))
+ (boundp 'proof-buffer-type)
+ ;; only allow toggling of toolbar enable in one
+ ;; buffer to avoid strange effects because we
+ ;; only keep one flag. (Strange effects because
+ ;; we only turn it off in one buffer at a time)
+ (eq proof-buffer-type 'script))
+ :style toggle
+ :selected proof-toolbar-enable]
+ ["X-Symbol" proof-x-symbol-toggle
+ :active (proof-x-symbol-support-maybe-available)
+ :style toggle
+ :selected (proof-ass x-symbol-enable)]
+ ("Follow mode"
+ ["Follow locked region"
+ (customize-set-variable 'proof-follow-mode 'locked)
+ :style radio
+ :selected (eq proof-follow-mode 'locked)]
+ ["Keep locked region displayed"
+ (customize-set-variable 'proof-follow-mode 'follow)
+ :style radio
+ :selected (eq proof-follow-mode 'follow)]
+ ["Never move"
+ (customize-set-variable 'proof-follow-mode 'ignore)
+ :style radio
+ :selected (eq proof-follow-mode 'ignore)]))))
+ "Proof General quick options.")
+
+(defconst proof-shared-menu
+ (append
+ (list "----")
+ (list proof-buffer-menu)
+ (list proof-quick-opts-menu)
+ (list proof-help-menu))
+ "Proof General menu for various modes.")
+
+(defconst proof-config-menu
+ ;; FIXME: customize-menu-create seems to break in Emacs 21.
+ (unless proof-running-on-Emacs21
+ (list "----"
+ (customize-menu-create 'proof-general)
+ (customize-menu-create 'proof-general-internals)))
+ ;;"Internals"))
+ "Proof General configuration menu.")
+
+(defvar proof-bug-report-menu
+ (list "----"
+ ["About Proof General" proof-splash-display-screen t]
+ ["Submit bug report" proof-submit-bug-report t])
+ "Proof General menu for submitting bug report (one item plus separator).")
+
+(defvar proof-menu
+ (append '("----"
+ ["Scripting active" proof-toggle-active-scripting
+ :style toggle
+ :selected (eq proof-script-buffer (current-buffer))]
+ ["Electric terminator" proof-electric-terminator-toggle
+ :style toggle
+ :selected proof-electric-terminator-enable]
+ ["Function menu" function-menu
+ :active (fboundp 'function-menu)]
+ ["Complete identifier" complete t]
+ ["Next error" proof-next-error
+ :active proof-shell-next-error-regexp])
+ proof-shared-menu)
+ "The Proof General generic menu. Functions for scripting buffers.")
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Favourites mechanism for specific menu
+;;;
+
+(defvar proof-menu-favourites nil
+ "The Proof General favourites menu for the current proof assistant.")
+
+(defun proof-menu-define-favourites-menu ()
+ "Return menu generated from `PA-favourites'."
+ (let ((favs (reverse (proof-ass favourites))) ents)
+ (while favs
+ (setq ents (cons (apply 'proof-def-favourite (car favs)) ents))
+ (setq favs (cdr favs)))
+ (setq proof-menu-favourites
+ (list
+ (cons "Favourites"
+ (append ents
+ '(["Add favourite"
+ (call-interactively
+ 'proof-add-favourite) t])))))))
+
+;;; Define stuff from favourites
+
+;;;###autoload
+(defmacro proof-defshortcut (fn string &optional key)
+ "Define shortcut function FN to insert STRING, optional keydef KEY.
+This is intended for defining proof assistant specific functions.
+STRING is inserted using `proof-insert', which see.
+KEY is added onto proof-assistant map."
+ (if key
+ (eval
+ `(define-key (proof-ass keymap) (quote ,key) (quote ,fn))))
+ `(defun ,fn ()
+ (concat "Shortcut command to insert " ,string " into the current buffer.")
+ (interactive)
+ (proof-insert ,string)))
+
+(defmacro proof-definvisible (fn string &optional key)
+ "Define function FN to send STRING to proof assistant, optional keydef KEY.
+This is intended for defining proof assistant specific functions.
+STRING is sent using proof-shell-invisible-command, which see.
+KEY is added onto proof-assistant map."
+ (if key
+ (eval
+ `(define-key (proof-ass keymap) (quote ,key) (quote ,fn))))
+ `(defun ,fn ()
+ ;; FIXME: docstring broken! and above.
+ (concat "Command to send " ,string " to the proof assistant.")
+ (interactive)
+ (proof-shell-invisible-command ,string)))
+
+(defun proof-def-favourite (command inscript menuname &optional key new)
+ "Define and a \"favourite\" proof assisant function.
+See doc of `proof-add-favourite' for first four arguments.
+Extra NEW flag means that this should be a new favourite, so check
+that function defined is not already bound.
+This function defines a function and returns a menu entry
+suitable for adding to the proof assistant menu."
+ (let* ((menunames (split-string (downcase menuname)))
+ (menuname-sym (proof-sym (proof-splice-separator "-" menunames)))
+ (menu-fn menuname-sym) (i 1))
+ (while (and new (fboundp menu-fn))
+ (setq menu-fn (intern (concat (symbol-name menuname-sym)
+ "-" (int-to-string i))))
+ (incf i))
+ (if inscript
+ (eval `(proof-defshortcut ,menu-fn ,command ,key))
+ (eval `(proof-definvisible ,menu-fn ,command ,key)))
+ ;; Return menu entry
+ (vector menuname menu-fn t)))
+
+
+;;; Code for adding "favourites" to the proof-assistant specific menu
+
+(defvar proof-make-favourite-cmd-history nil
+ "History for proof-make-favourite.")
+
+(defun proof-add-favourite (command inscript menuname &optional key)
+ "Define and add a \"favourite\" proof-assisant function to the menu bar.
+The favourite function will issue COMMAND to the proof assistant.
+COMMAND is inserted into script (not sent immediately) if INSCRIPT non-nil.
+MENUNAME is the name of the function for the menu.
+KEY is the optional key binding."
+ (interactive
+ (let*
+ ((cmd (read-string
+ (concat "Command to send to " proof-assistant ": ")
+ (buffer-substring
+ (save-excursion
+ (beginning-of-line-text)
+ (point))
+ (point))
+ proof-make-favourite-cmd-history))
+ (ins (y-or-n-p "Should command be recorded in script? "))
+ (men (read-string "Name of command on menu: " cmd))
+ (key (if (y-or-n-p "Set a keybinding for this command? : ")
+ (events-to-keys
+ (read-key-sequence
+ "Type the key to use (binding will be C-c C-a <key>): " nil t)))))
+ (list cmd ins men key)))
+ (let ((menu-entry (proof-def-favourite command inscript menuname key t)))
+ ;; If definition succeeds, add to customize variable and save immediately.
+ ;; FIXME: should maybe overwrite previous duplicates, use
+ ;; update rather than append.
+ (customize-save-variable (proof-ass-sym favourites)
+ (append (proof-ass favourites)
+ (list
+ (list command inscript menuname key))))
+ (easy-menu-add-item proof-assistant-menu
+ '("Favourites") menu-entry "Add favourite")))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Proof assistant settings mechanism.
+;;;
+
+(defvar proof-assistant-settings nil
+ "A list of default values kept in Proof General for current proof assistant.
+A list of lists (SYMBOL SETTING TYPE) where SETTING is a string value
+to send to the proof assistant using the value of SYMBOL and
+and the function `proof-assistant-format'. The TYPE item determines
+the form of the menu entry for the setting.")
+
+(defvar proof-menu-settings nil
+ "Settings submenu for Proof General.")
+
+(defun proof-menu-define-settings-menu ()
+ "Return menu generated from `proof-assistant-settings'."
+ (let ((setgs proof-assistant-settings) ents)
+ (while setgs
+ (setq ents (cons
+ (apply 'proof-menu-entry-for-setting (car setgs)) ents))
+ (setq setgs (cdr setgs)))
+ (if ents
+ (setq proof-menu-settings
+ (list (cons "Settings" ents))))))
+
+(defun proof-menu-entry-name (symbol)
+ "Return a nice menu entry name for SYMBOL."
+ (upcase-initials
+ (replace-in-string (symbol-name symbol) "-" " ")))
+
+(defun proof-menu-entry-for-setting (symbol setting type)
+ (let ((entry-name (proof-menu-entry-name symbol))
+ (pasym (proof-ass-symv symbol)))
+ (cond
+ ((eq type 'boolean)
+ (vector entry-name
+ (proof-deftoggle-fn pasym)
+ :style 'toggle
+ :selected pasym))
+ ((eq type 'integer)
+ (vector entry-name
+ (proof-defintset-fn pasym)
+ t))
+ ((eq type 'string)
+ (vector entry-name
+ (proof-defstringset-fn pasym)
+ t)))))
+
+;;; autoload for compiled version: used in macro proof-defpacustom
+;;;###autoload
+(defun proof-defpacustom-fn (name val args)
+ "As for macro `defpacustom' but evaluation arguments."
+ (let (newargs setting evalform)
+ (while args
+ (cond
+ ((eq (car args) :setting)
+ (setq setting (cadr args))
+ (setq args (cdr args)))
+ ((eq (car args) :eval)
+ (setq evalform (cadr args))
+ (setq args (cdr args)))
+ ((eq (car args) :type)
+ (setq type (cadr args))
+ (setq newargs (cons (car args) newargs)))
+ (t
+ (setq newargs (cons (car args) newargs))))
+ (setq args (cdr args)))
+ (setq newargs (reverse newargs))
+ (unless (or setting evalform)
+ (error "defpacustom: missing :setting or :eval keyword"))
+ (unless (and type
+ (or (eq (eval type) 'boolean)
+ (eq (eval type) 'integer)
+ (eq (eval type) 'string)))
+ (error "defpacustom: missing :type keyword or wrong :type value"))
+ (if (assoc name proof-assistant-settings)
+ (error "defpacustom: Proof assistanting setting %s already defined!"
+ name))
+ ;; Could consider moving the bulk of the remainder of this
+ ;; function to a function proof-assistant-setup-settings which
+ ;; defines the custom vals *and* menu entries. This would
+ ;; allow proof assistant customization to manipulate
+ ;; proof-assistant-settings directly rather than forcing
+ ;; use of defpacustom. (Probably stay as we are: more abstract)
+ (eval
+ `(defpgcustom ,name ,val
+ ,@newargs
+ :set 'proof-set-value
+ :group 'proof-assistant-setting))
+ (if evalform
+ (eval
+ `(defpgfun ,name ()
+ ,evalform))
+ (eval
+ `(defpgfun ,name ()
+ (proof-assistant-invisible-command-ifposs
+ (proof-assistant-settings-cmd (quote ,name))))))
+ (setq proof-assistant-settings
+ (cons (list name setting (eval type)) proof-assistant-settings))))
+
+;;;###autoload
+(defmacro defpacustom (name val &rest args)
+ "Define a setting NAME for the current proof assitant, default VAL.
+NAME can correspond to some internal setting, flag, etc, for the
+proof assistant, in which case a :setting and :type value should be provided.
+The :type of NAME should be one of 'integer, 'boolean, 'string.
+The customization variable is automatically in group `proof-assistant-setting.
+The function `proof-assistant-format' is used to format VAL.
+If NAME corresponds instead to a PG internal setting, then a form :eval to
+evaluate can be provided instead."
+ `(proof-defpacustom-fn (quote ,name) (quote ,val) (quote ,args)))
+
+(defun proof-assistant-invisible-command-ifposs (cmd)
+ "Send CMD as an \"invisible command\" if the proof process is available."
+ ;; FIXME: better would be to queue the command, or even interrupt a
+ ;; queue in progress. Also must send current settings at start of
+ ;; session somehow. (This might happen automatically if a queue of
+ ;; deffered commands is set, since defcustom calls proof-set-value
+ ;; even to set the default/initial value?)
+ (if (proof-shell-available-p)
+ (progn
+ (proof-shell-invisible-command cmd t)
+ ;; refresh display,
+ ;; FIXME: should only do if goals display is active,
+ ;; messy otherwise.
+ ;; (we need a new flag for "active goals display").
+ (if proof-showproof-command
+ (proof-shell-invisible-command proof-showproof-command))
+ ;; Could also repeat last command if non-state destroying.
+ )))
+
+
+(defun proof-assistant-settings-cmd (&optional setting)
+ "Return string for making setting vals kept in Proof General customizations.
+If SETTING is non-nil, return a string for just that setting.
+Otherwise return a string for configuring all settings."
+ (let
+ ((evalifneeded (lambda (expr)
+ (if (and (cadr expr) ;; setting has PA string?
+ (or (not setting)
+ (eq setting (car expr))))
+ (proof-assistant-format
+ (cadr expr)
+ (eval (proof-ass-symv (car expr))))))))
+ (apply 'concat (mapcar evalifneeded
+ proof-assistant-settings))))
+
+(defun proof-assistant-format (string curvalue)
+ "Replace a format characters %b %i %s in STRING by formatted CURVALUE.
+Formatting suitable for current proof assistant, controlled by
+`proof-assistant-format-table' which see.
+Finally, apply `proof-assistant-setting-format' if non-nil.
+As a special case for boolean settings: the setting STRING
+can be a cons cell of two strings, the first one for true (non-nil
+value) and the second for false."
+ (if (consp string)
+ (if curvalue (car string) (cdr string))
+ ;; Otherwise must use % format characters
+ (let ((setting (proof-format proof-assistant-format-table string)))
+ (if proof-assistant-setting-format
+ (funcall proof-assistant-setting-format setting)
+ setting))))
+
+(defvar proof-assistant-format-table
+ (list
+ (cons "%b" '(proof-assistant-format-bool curvalue))
+ (cons "%i" '(proof-assistant-format-int curvalue))
+ (cons "%s" '(proof-assistant-format-string curvalue)))
+ "Table to use with `proof-format' for formatting CURVALUE for assistant.
+NB: variable curvalue is dynamically scoped (used in proof-assistant-format).")
+
+(defun proof-assistant-format-bool (value)
+ (if value proof-assistant-true-value proof-assistant-false-value))
+
+(defun proof-assistant-format-int (value)
+ (funcall proof-assistant-format-int-fn value))
+
+(defun proof-assistant-format-string (value)
+ (funcall proof-assistant-format-string-fn value))
+
+
+
+
+(provide 'proof-menu)
+;; proof-menu.el ends here.
diff --git a/generic/proof-script.el b/generic/proof-script.el
new file mode 100644
index 00000000..b5f7ca15
--- /dev/null
+++ b/generic/proof-script.el
@@ -0,0 +1,2661 @@
+;; proof-script.el Major mode for proof assistant script files.
+;;
+;; Copyright (C) 1994-2001 LFCS Edinburgh.
+;; Authors: David Aspinall, Yves Bertot, Healfdene Goguen,
+;; Thomas Kleymann and Dilip Sequeira
+;;
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+
+(require 'proof) ; loader
+(require 'proof-syntax) ; utils for manipulating syntax
+(require 'span) ; abstraction of overlays/extents
+(require 'pg-user) ; user-level commands
+(require 'proof-menu) ; menus for script mode
+
+
+
+;; Nuke some byte-compiler warnings
+;; NB: eval-when (compile) is different to eval-when-compile!!
+(eval-when (compile)
+ (proof-try-require 'func-menu)
+ (require 'comint))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Internal variables used by script mode
+;;
+
+(deflocal proof-active-buffer-fake-minor-mode nil
+ "An indication in the modeline that this is the *active* script buffer")
+
+(defvar proof-last-theorem-dependencies nil
+ "Contains the dependencies of the last theorem. A list of strings.
+Set in proof-shell-process-urgent-message.")
+
+(deflocal proof-script-buffer-file-name nil
+ ;; NB: if buffer-file-name is nil for some other reason, this may break.
+ "A copied value of buffer-file-name to cope with `find-alternative-file'.
+The `find-alternative-file' function has a nasty habit of setting the
+buffer file name to nil before running kill buffer, which breaks PG's
+kill buffer hook. This variable is used when buffer-file-name is nil.")
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Configuration of function-menu (aka "fume")
+;;
+;; FIXME: we would like this code only enabled if the user loads
+;; func-menu into Emacs.
+;;
+
+(deflocal proof-script-last-entity nil
+ "Record of last entity found.
+A hack for entities that are named in two places, so that find-next-entity
+doesn't return the same values twice.")
+
+;; FIXME mmw: maybe handle comments/strings by using
+;; proof-looking-at-syntactic-context
+(defun proof-script-find-next-entity (buffer)
+ "Find the next entity for function menu in a proof script.
+A value for fume-find-function-name-method-alist for proof scripts.
+Uses fume-function-name-regexp, which is intialised from
+proof-script-next-entity-regexps, which see."
+ ;; Hopefully this function is fast enough.
+ (set-buffer buffer)
+ ;; could as well use next-entity-regexps directly since this is
+ ;; not really meant to be used as a general function.
+ (let ((anyentity (car fume-function-name-regexp)))
+ (if (proof-re-search-forward anyentity nil t)
+ ;; We've found some interesting entity, but have to find out
+ ;; which one, and where it begins.
+ (let ((entity (buffer-substring (match-beginning 0) (match-end 0)))
+ (start (match-beginning 0))
+ (discriminators (cdr fume-function-name-regexp))
+ (p (point))
+ disc res)
+ (while (and (not res) (setq disc (car-safe discriminators)))
+ (if (proof-string-match (car disc) entity)
+ (let*
+ ((items (nth 1 disc))
+ (items (if (numberp items) (list items) items))
+ (name ""))
+ (dolist (item items)
+ (setq name
+ (concat name
+ (substring entity
+ (match-beginning item)
+ (match-end item))
+ " ")))
+ (cond
+ ((eq (nth 2 disc) 'backward)
+ (setq start
+ (or (proof-re-search-backward (nth 3 disc) nil t)
+ start))
+ (goto-char p))
+ ((eq (nth 2 disc) 'forward)
+ (proof-re-search-forward (nth 3 disc))))
+ (setq res (cons name start)))
+ (setq discriminators (cdr discriminators))))
+ res))))
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Basic code for the locked region and the queue region ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; da FIXME: clean this section
+
+;; Notes on markup in the scripting buffer. (da)
+;;
+;; The locked region is covered by a collection of non-overlaping
+;; spans (our abstraction of extents/overlays).
+;;
+;; For an unfinished proof, there is one extent for each command
+;; or comment outside a command. For a finished proof, there
+;; is one extent for the whole proof.
+;;
+;; Each command span has a 'type property, one of:
+;;
+;; 'goalsave A goal..savegoal region in the buffer, a completed proof.
+;; 'vanilla Initialised in proof-semis-to-vanillas, for
+;; 'comment A comment outside a command.
+;; 'proverproc A region closed by the prover, processed outwith PG
+;; 'pbp A PBP command inserted automatically into the script
+;;
+;; All spans except those of type 'comment have a 'cmd property,
+;; which is set to a string of its command. This is the
+;; text in the buffer stripped of leading whitespace and any comments.
+;;
+;;
+
+
+
+(deflocal proof-locked-span nil
+ "The locked span of the buffer.
+Each script buffer has its own locked span, which may be detached
+from the buffer.
+Proof General allows buffers in other modes also to be locked;
+these also have a non-nil value for this variable.")
+
+;; da: really we only need one queue span rather than one per buffer,
+;; but I've made it local because the initialisation occurs in
+;; proof-init-segmentation, which can happen when a file is visited.
+;; So nasty things might happen if a locked file is visited whilst
+;; another buffer has a non-empty queue region being processed.
+
+(deflocal proof-queue-span nil
+ "The queue span of the buffer. May be detached if inactive or empty.")
+
+;; FIXME da: really the queue region should always be locked strictly.
+
+(defun proof-span-read-only (span)
+ "Make span be read-only, if proof-strict-read-only is non-nil.
+Otherwise make span give a warning message on edits."
+ (if proof-strict-read-only
+ (span-read-only span)
+ (span-write-warning span)))
+
+;; not implemented yet; toggle via restarting scripting
+;; (defun proof-toggle-strict-read-only ()
+;; "Toggle proof-strict-read-only, changing current spans."
+;; (interactive)
+;; map-spans blah
+;; )
+
+(defun proof-init-segmentation ()
+ "Initialise the queue and locked spans in a proof script buffer.
+Allocate spans if need be. The spans are detached from the
+buffer, so the regions are made empty by this function.
+Also clear list of script portions."
+ ;; Initialise queue span, remove it from buffer.
+ (unless proof-queue-span
+ (setq proof-queue-span (make-span 1 1))
+ ;; FIXME: span-raise is an FSF hack to make locked span appear.
+ ;; overlays still don't work as well as they did/should.
+ (span-raise proof-queue-span))
+ (set-span-property proof-queue-span 'start-closed t)
+ (set-span-property proof-queue-span 'end-open t)
+ (proof-span-read-only proof-queue-span)
+ (set-span-property proof-queue-span 'face 'proof-queue-face)
+ (detach-span proof-queue-span)
+ ;; Initialise locked span, remove it from buffer
+ (unless proof-locked-span
+ (setq proof-locked-span (make-span 1 1))
+ (span-raise proof-locked-span))
+ (set-span-property proof-locked-span 'start-closed t)
+ (set-span-property proof-locked-span 'end-open t)
+ (proof-span-read-only proof-locked-span)
+ (set-span-property proof-locked-span 'face 'proof-locked-face)
+ (detach-span proof-locked-span)
+ (setq proof-last-theorem-dependencies nil)
+ (pg-clear-script-portions))
+
+;; These two functions are used in coq.el to edit the locked region
+;; (by lifting local (nested) lemmas out of a proof, to make them global).
+(defsubst proof-unlock-locked ()
+ "Make the locked region writable.
+Used in lisp programs for temporary editing of the locked region.
+See proof-lock-unlocked for the reverse operation."
+ (span-read-write proof-locked-span))
+
+(defsubst proof-lock-unlocked ()
+ "Make the locked region read only (according to proof-strict-read-only).
+Used in lisp programs for temporary editing of the locked region.
+See proof-unlock-locked for the reverse operation."
+ (proof-span-read-only proof-locked-span))
+
+(defsubst proof-set-queue-endpoints (start end)
+ "Set the queue span to be START, END."
+ (set-span-endpoints proof-queue-span start end))
+
+(defsubst proof-set-locked-endpoints (start end)
+ "Set the locked span to be START, END."
+ (set-span-endpoints proof-locked-span start end))
+
+(defsubst proof-detach-queue ()
+ "Remove the span for the queue region."
+ (and proof-queue-span (detach-span proof-queue-span)))
+
+(defsubst proof-detach-locked ()
+ "Remove the span for the locked region."
+ (and proof-locked-span (detach-span proof-locked-span)))
+
+(defsubst proof-set-queue-start (start)
+ "Set the queue span to begin at START."
+ (set-span-start proof-queue-span start))
+
+;; FIXME da: optional arg here was ignored, have fixed.
+;; Do we really need it though?
+(defun proof-detach-segments (&optional buffer)
+ "Remove locked and queue region from BUFFER.
+Defaults to current buffer when BUFFER is nil."
+ (let ((buffer (or buffer (current-buffer))))
+ (with-current-buffer buffer
+ (proof-detach-queue)
+ (proof-detach-locked))))
+
+(defsubst proof-set-locked-end (end)
+ "Set the end of the locked region to be END.
+If END is at or before (point-min), remove the locked region.
+Otherwise set the locked region to be from (point-min) to END."
+ (if (>= (point-min) end)
+ (proof-detach-locked)
+ (set-span-endpoints proof-locked-span (point-min) end)
+ ;; FIXME: the next line doesn't fix the disappearing regions
+ ;; (was span property is lost in latest FSF Emacs, maybe?)
+ ;; (set-span-property proof-locked-span 'face 'proof-locked-face)
+ ))
+
+;; Reimplemented this to mirror above because of remaining
+;; span problen
+(defsubst proof-set-queue-end (end)
+ "Set the queue span to end at END."
+ (if (or (>= (point-min) end)
+ (<= end (span-start proof-queue-span)))
+ (proof-detach-queue)
+ (set-span-end proof-queue-span end)))
+
+
+;; FIXME: get rid of this function. Some places expect this
+;; to return nil if locked region is empty. Moreover,
+;; it confusingly returns the point past the end of the
+;; locked region.
+(defun proof-locked-end ()
+ "Return end of the locked region of the current buffer.
+Only call this from a scripting buffer."
+ (proof-unprocessed-begin))
+
+
+(defsubst proof-end-of-queue ()
+ "Return the end of the queue region, or nil if none."
+ (and proof-queue-span (span-end proof-queue-span)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Buffer position functions
+;;
+;; da:cleaned
+
+(defun proof-unprocessed-begin ()
+ "Return end of locked region in current buffer or (point-min) otherwise.
+The position is actually one beyond the last locked character."
+ (or
+ (and proof-locked-span
+ (span-end proof-locked-span))
+ (point-min)))
+
+(defun proof-script-end ()
+ "Return the character beyond the last non-whitespace character.
+This is the same position proof-locked-end ends up at when asserting
+the script. Works for any kind of buffer."
+ (save-excursion
+ (goto-char (point-max))
+ (skip-chars-backward " \t\n")
+ (point)))
+
+(defun proof-queue-or-locked-end ()
+ "Return the end of the queue region, or locked region, or (point-min).
+This position should be the first writable position in the buffer.
+An appropriate point to move point to (or make sure is displayed)
+when a queue of commands is being processed."
+ (or
+ ;; span-end returns nil if span is detatched
+ (and proof-queue-span (span-end proof-queue-span))
+ (and proof-locked-span (span-end proof-locked-span))
+ (point-min)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Predicates for locked region.
+;;
+;; These work on any buffer, so that non-script buffers can be locked
+;; (as processed files) too.
+;;
+;; da:cleaned
+
+(defun proof-locked-region-full-p ()
+ "Non-nil if the locked region covers all the buffer's non-whitespace.
+Works on any buffer."
+ (save-excursion
+ (goto-char (point-max))
+ (skip-chars-backward " \t\n")
+ (>= (proof-unprocessed-begin) (point))))
+
+(defun proof-locked-region-empty-p ()
+ "Non-nil if the locked region is empty. Works on any buffer."
+ (eq (proof-unprocessed-begin) (point-min)))
+
+(defun proof-only-whitespace-to-locked-region-p ()
+ "Non-nil if only whitespace separates char after point from end of locked region.
+Point should be after the locked region.
+NB: If nil, point is left at first non-whitespace character found.
+If non-nil, point is left where it was."
+ ;; NB: this function doesn't quite do what you'd expect, but fixing it
+ ;; breaks proof-assert-until-point and electric-terminator which
+ ;; rely on the side effect. So careful!
+ ;; (unless (eobp)
+ ;; (forward-char))
+ ;; (save-excursion -- no, side effect is expected!
+ (not (proof-re-search-backward "\\S-" (proof-unprocessed-begin) t)))
+
+(defun proof-in-locked-region-p ()
+ "Non-nil if point is in locked region. Assumes proof script buffer current."
+ (< (point) (proof-unprocessed-begin)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Misc movement functions
+;;
+
+(defun proof-goto-end-of-locked (&optional switch)
+ "Jump to the end of the locked region, maybe switching to script buffer.
+If interactive or SWITCH is non-nil, switch to script buffer first."
+ (interactive)
+ (proof-with-script-buffer
+ (if (and (not (get-buffer-window proof-script-buffer))
+ (or switch (interactive-p)))
+ (switch-to-buffer proof-script-buffer)
+ (goto-char (proof-unprocessed-begin)))))
+
+; NB: think about this because the movement can happen when the user
+; is typing, not very nice!
+(defun proof-goto-end-of-locked-if-pos-not-visible-in-window ()
+ "If the end of the locked region is not visible, jump to the end of it.
+A possible hook function for proof-shell-handle-error-or-interrupt-hook.
+Does nothing if there is no active scripting buffer, or if
+`proof-follow-mode' is set to 'ignore."
+ (interactive)
+ (if (and proof-script-buffer
+ (not (eq proof-follow-mode 'ignore)))
+ (let ((pos (with-current-buffer proof-script-buffer
+ (proof-locked-end)))
+ (win (get-buffer-window proof-script-buffer t)))
+ (unless (and win (pos-visible-in-window-p pos))
+ (proof-goto-end-of-locked t)))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Names of proofs (and other elements) in a script
+;;
+;; New in PG 3.3
+;;
+;; Each kind of part ("idiom") in a proof script has its own name space.
+;; Visibility within a script is then handled with buffer-invisibility-spec
+;; controlling appearance of each idiom.
+;;
+;; TODO:
+;; -- Use fine-scale and large scale control, after all?
+;; -- Deleting spans must remove their entries in pg-script-portions !!
+;; -- Names should be made unique somehow.
+
+;; FIXME: this should be a configuration variable
+(defvar pg-idioms '(proof)
+ "Vector of script element kinds PG is aware of for this prover.")
+
+(deflocal pg-script-portions nil
+ "Table of lists of symbols naming script portions which have been processed so far.")
+
+(defun pg-clear-script-portions ()
+ "Clear record of script portion names and types from internal list.
+Also clear all visibility specifications."
+ (setq pg-script-portions nil)
+ (setq buffer-invisibility-spec nil))
+
+(defun pg-add-script-element (elt)
+ (add-to-list pg-script-portions elt))
+
+(defun pg-remove-script-element (ns id)
+ (let* ((elts (cdr-safe (assq ns pg-script-portions)))
+ (newelts (remq id elts)))
+ (setq pg-script-portions
+ (if newelts
+ (cons (cons ns newelts) (remassq ns pg-script-portions))
+ (remassq ns pg-script-portions)))))
+
+(defsubst pg-visname (namespace name)
+ (intern (concat namespace ":" name)))
+
+(defun pg-add-element (idiom name span)
+ "Add element of type IDIOM named NAME, referred to by SPAN, into cache.
+Names must be unique for a given "
+ (let* ((ns (intern idiom))
+ (id (intern name))
+ (visname (pg-visname idiom name))
+ (delfn `(lambda () (pg-remove-element ,idiom ,name)))
+ (elts (cdr-safe (assq ns pg-script-portions))))
+ (if elts
+ (if (memq id elts)
+ (proof-debug "Element named " name " (type " idiom ") already in buffer.")
+ (nconc elts (list id)))
+ (setq pg-script-portions (cons (cons ns (list id)) pg-script-portions)))
+ (set-span-property span 'span-delete-action delfn)
+ (set-span-property span 'invisible visname)))
+
+(defun pg-remove-element (idiom name)
+ (let ((ns (intern idiom))
+ (id (intern name)))
+ (pg-remove-script-element ns id)
+ ;; We could leave the visibility note, but that may
+ ;; be counterintuitive, so lets remove it.
+ (pg-make-element-visible idiom name)))
+
+(defun pg-make-element-invisible (idiom name)
+ "Make element NAME of type IDIOM invisible, with ellipsis."
+ (add-to-list 'buffer-invisibility-spec
+ (cons (pg-visname idiom name) t)))
+
+(defun pg-make-element-visible (idiom name)
+ (setq buffer-invisibility-spec
+ (remassq (pg-visname idiom name) buffer-invisibility-spec)))
+
+(defun pg-toggle-element-visibility (idiom name)
+ (if (and (listp buffer-invisibility-spec)
+ (assq (pg-visname idiom name) buffer-invisibility-spec))
+ (pg-make-element-visible idiom name)
+ (pg-make-element-invisible idiom name)))
+
+(defun pg-show-all-portions (idiom &optional hide)
+ "Show or hide all portions of kind IDIOM"
+ (interactive
+ (list
+ (completing-read
+ (concat "Make " (if current-prefix-arg "in" "") "visible all regions of: ")
+ (apply 'vector pg-idioms) nil t)
+ current-prefix-arg))
+ (let ((elts (cdr-safe (assq (intern idiom) pg-script-portions)))
+ (alterfn (if hide
+ (lambda (arg) (pg-make-element-invisible idiom
+ (symbol-name arg)))
+ (lambda (arg) (pg-make-element-visible idiom
+ (symbol-name arg))))))
+ (mapcar alterfn elts)))
+
+(defun pg-show-all-proofs ()
+ "Display all completed proofs in the buffer."
+ (interactive)
+ (pg-show-all-portions "proof")
+ (unless proof-running-on-XEmacs
+ ;; FSF Emacs requires redisplay here to see result
+ ;; (sit-for 0) not enough
+ (redraw-frame (selected-frame))))
+
+
+(defun pg-hide-all-proofs ()
+ "Hide all completed proofs in the buffer."
+ (interactive)
+ (pg-show-all-portions "proof" 'hide)
+ (unless proof-running-on-XEmacs
+ ;; FSF Emacs requires redisplay here to see result
+ ;; (sit-for 0) not enough
+ (redraw-frame (selected-frame))))
+
+
+(defun pg-add-proof-element (name span controlspan)
+ "Add a nested span proof element."
+ (pg-add-element "proof" name span)
+ (set-span-property span 'name name)
+ (set-span-property span 'type 'proof)
+ (set-span-property span 'idiom 'proof)
+ ;; Make a navigable link between the two spans.
+ (set-span-property span 'controlspan controlspan)
+ (set-span-property controlspan 'children
+ (cons span (span-property controlspan 'children)))
+ (set-span-property span 'duplicable t)
+ ;; (set-span-property span 'context-menu (pg-proof-element-menu name))
+ (pg-set-span-helphighlights span 'nohighlight)
+ (if proof-disappearing-proofs
+ (pg-make-element-invisible "proof" name)))
+
+(defun pg-span-name (span)
+ "Return a user-level name for SPAN."
+ (let ((type (span-property span 'type))
+ (idiom (span-property span 'idiom))
+ (name (span-property span 'name)))
+ (cond
+ (idiom
+ (concat (upcase-initials (symbol-name idiom))
+ (if name (concat ": " name))))
+ ((or (eq type 'proof) (eq type 'goalsave))
+ (concat "Proof"
+ (let ((name (span-property span 'name)))
+ (if name (concat " of " name)))))
+ ((eq type 'comment) "Comment")
+ ((eq type 'vanilla) "Command")
+ ((eq type 'pbp) "PBP command")
+ ((eq type 'proverproc)
+ "Prover-processed region"))))
+
+(defun pg-set-span-helphighlights (span &optional nohighlight)
+ "Set the help echo message, default highlight, and keymap for SPAN."
+ (let ((helpmsg (pg-span-name span)))
+ (set-span-property span 'balloon-help helpmsg)
+ (set-span-property span 'help-echo helpmsg)
+ (set-span-property span 'keymap pg-span-context-menu-keymap)
+ (unless nohighlight
+ (set-span-property span 'mouse-face 'proof-mouse-highlight-face))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Multiple file handling
+;;
+;;
+;; da:cleaned
+
+(defun proof-complete-buffer-atomic (buffer)
+ "Make sure BUFFER is marked as completely processed, completing with a single step.
+
+If buffer already contains a locked region, only the remainder of the
+buffer is closed off atomically.
+
+This works for buffers which are not in proof scripting mode too,
+to allow other files loaded by proof assistants to be marked read-only."
+;; FIXME: this isn't quite right, because not all of the structure
+;; in the locked region will be preserved when processing across several
+;; files.
+;; In particular, the span for a currently open goal should be removed.
+;; Keeping the structure is an approximation to make up for the fact
+;; that that no structure is created by loading files via the
+;; proof assistant.
+;; Future idea: proof assistant could ask Proof General to do the
+;; loading, to alleviate file handling there?!
+ (save-excursion
+ (set-buffer buffer)
+ (if (< (proof-unprocessed-begin) (proof-script-end))
+ (let ((span (make-span (proof-unprocessed-begin)
+ (proof-script-end)))
+ cmd)
+ (if (eq proof-buffer-type 'script)
+ ;; For a script buffer
+ (progn
+ (goto-char (point-min))
+ (proof-goto-command-end)
+ (let ((cmd-list (member-if
+ (lambda (entry) (equal (car entry) 'cmd))
+ (proof-segment-up-to (point)))))
+ ;; Reset queue and locked regions.
+ (proof-init-segmentation)
+ (if cmd-list
+ (progn
+ ;; FIXME 3.3 da: this can be simplified now,
+ ;; we don't need to set cmd for proverproc
+ (setq cmd (second (car cmd-list)))
+ (set-span-property span 'type 'proverproc)
+ (set-span-property span 'cmd cmd))
+ ;; If there was no command in the buffer, atomic span
+ ;; becomes a comment. This isn't quite right because
+ ;; the first ACS in a buffer could also be a goal-save
+ ;; span. We don't worry about this in the current
+ ;; implementation. This case should not happen in a
+ ;; LEGO module (because we assume that the first
+ ;; command is a module declaration). It should have no
+ ;; impact in Isabelle either (because there is no real
+ ;; retraction).
+ (set-span-property span 'type 'comment))))
+ ;; For a non-script buffer
+ (proof-init-segmentation)
+ (set-span-property span 'type 'comment))
+ ;; End of locked region is always end of buffer
+ (proof-set-locked-end (proof-script-end))))))
+
+
+
+
+
+;; FIXME da: cleanup of odd asymmetry here: we have a nice setting for
+;; proof-register-possibly-new-processed-file but something much more
+;; complicated for retracting, because we allow a hook function
+;; to calculate the new included files list.
+
+(defun proof-register-possibly-new-processed-file (file &optional informprover noquestions)
+ "Register a possibly new FILE as having been processed by the prover.
+
+If INFORMPROVER is non-nil, the proof assistant will be told about this,
+to co-ordinate with its internal file-management. (Otherwise we assume
+that it is a message from the proof assistant which triggers this call).
+In this case, the user will be queried to save some buffers, unless
+NOQUESTIONS is non-nil.
+
+No action is taken if the file is already registered.
+
+A warning message is issued if the register request came from the
+proof assistant and Emacs has a modified buffer visiting the file."
+ (let* ((cfile (file-truename file))
+ (buffer (proof-file-to-buffer cfile)))
+ (proof-debug (concat "Registering file " cfile
+ (if (member cfile proof-included-files-list)
+ " (already registered, no action)." ".")))
+ (unless (member cfile proof-included-files-list)
+ (and buffer
+ (not informprover)
+ (buffer-modified-p buffer)
+ (proof-warning (concat "Changes to "
+ (buffer-name buffer)
+ " have not been saved!")))
+ ;; Add the new file onto the front of the list
+ (setq proof-included-files-list
+ (cons cfile proof-included-files-list))
+ ;; If the file is loaded into a buffer, make sure it is completely locked
+ (if buffer
+ (proof-complete-buffer-atomic buffer))
+ ;; Tell the proof assistant, if we should and if we can
+ (if (and informprover proof-shell-inform-file-processed-cmd)
+ (progn
+ ;; Markus suggests we should ask if the user wants to save
+ ;; the file now (presumably because the proof assistant
+ ;; might examine the file timestamp, or attempt to visit
+ ;; the file later??).
+ ;; Presumably it would be enough to ask about this file,
+ ;; not all files?
+ (if (and
+ proof-query-file-save-when-activating-scripting
+ (not noquestions))
+ (unwind-protect
+ (save-some-buffers)))
+ ;; Tell the prover
+ (proof-shell-invisible-command
+ (proof-format-filename proof-shell-inform-file-processed-cmd
+ cfile)
+ 'wait))))))
+
+(defun proof-inform-prover-file-retracted (rfile)
+ (if proof-shell-inform-file-retracted-cmd
+ (proof-shell-invisible-command
+ (proof-format-filename proof-shell-inform-file-retracted-cmd
+ rfile)
+ 'wait)))
+
+(defun proof-auto-retract-dependencies (cfile &optional informprover)
+ "Perhaps automatically retract the (linear) dependencies of CFILE.
+If proof-auto-multiple-files is nil, no action is taken.
+If CFILE does not appear on proof-included-files-list, no action taken.
+
+Any buffers which are visiting files in proof-included-files-list
+before CFILE are retracted using proof-protected-process-or-retract.
+They are retracted in reverse order.
+
+Since the proof-included-files-list is examined, we expect scripting
+to be turned off before calling here (because turning it off could
+otherwise change proof-included-files-list).
+
+If INFORMPROVER is non-nil, the proof assistant will be told about this,
+using proof-shell-inform-file-retracted-cmd, to co-ordinate with its
+internal file-management.
+
+Files which are not visited by any buffer are not retracted, on the
+basis that we may not have the information necessary to retract them
+-- spans that cover the buffer with definition/declaration
+information. A warning message is given for these cases, since it
+could cause inconsistency problems.
+
+NB! Retraction can cause recursive calls of this function.
+This is a subroutine for proof-unregister-buffer-file-name."
+ (if proof-auto-multiple-files
+ (let ((depfiles (reverse
+ (cdr-safe
+ (member cfile (reverse proof-included-files-list)))))
+ rfile rbuf)
+ (while (setq rfile (car-safe depfiles))
+ ;; If there's a buffer visiting a dependent file, retract it.
+ ;; We test that the file to retract hasn't been retracted
+ ;; already by a recursive call here. (But since we do retraction
+ ;; in reverse order, this shouldn't happen...)
+ (if (and (member rfile proof-included-files-list)
+ (setq rbuf (proof-file-to-buffer rfile)))
+ (progn
+ (proof-debug "Automatically retracting " rfile)
+ (proof-protected-process-or-retract 'retract rbuf)
+ (setq proof-included-files-list
+ (delete rfile proof-included-files-list))
+ ;; Tell the proof assistant, if we should and we can.
+ ;; This may be useful if we synchronise the *prover* with
+ ;; PG's management of multiple files. If the *prover*
+ ;; informs PG (better case), then we hope the prover will
+ ;; retract dependent files and we shouldn't use this
+ ;; degenerate (linear dependency) code.
+ (if informprover
+ (proof-inform-prover-file-retracted rfile)))
+ ;; If no buffer available, issue a warning that nothing was done
+ (proof-warning "Not retracting unvisited file " rfile))
+ (setq depfiles (cdr depfiles))))))
+
+(defun proof-unregister-buffer-file-name (&optional informprover)
+ "Remove current buffer's filename from the list of included files.
+No effect if the current buffer has no file name.
+If INFORMPROVER is non-nil, the proof assistant will be told about this,
+using proof-shell-inform-file-retracted-cmd, to co-ordinate with its
+internal file-management.
+
+If proof-auto-multiple-files is non-nil, any buffers on
+proof-included-files-list before this one will be automatically
+retracted using proof-auto-retract-dependencies."
+ (if buffer-file-name
+ (let ((cfile (file-truename
+ (or buffer-file-name
+ proof-script-buffer-file-name))))
+ (proof-debug (concat "Unregistering file " cfile
+ (if (not (member cfile
+ proof-included-files-list))
+ " (not registered, no action)." ".")))
+ (if (member cfile proof-included-files-list)
+ (progn
+ (proof-auto-retract-dependencies cfile informprover)
+ (setq proof-included-files-list
+ (delete cfile proof-included-files-list))
+ ;; Tell the proof assistant, if we should and we can.
+ ;; This case may be useful if there is a combined
+ ;; management of multiple files between PG and prover.
+ (if informprover
+ (proof-inform-prover-file-retracted cfile)))))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Activating and Deactivating Scripting
+;;
+;;
+;; da: cleaned
+
+(defun proof-protected-process-or-retract (action &optional buffer)
+ "If ACTION='process, process, If ACTION='retract, retract.
+Process or retract the current buffer, which should be the active
+scripting buffer, according to ACTION.
+Retract buffer BUFFER if set, otherwise use the current buffer.
+Gives a message in the minibuffer and busy-waits for the retraction
+or processing to complete. If it fails for some reason,
+an error is signalled here."
+ (let ((fn (cond ((eq action 'process) 'proof-process-buffer)
+ ((eq action 'retract) 'proof-retract-buffer)))
+ (name (cond ((eq action 'process) "Processing")
+ ((eq action 'retract) "Retracting")))
+ (buf (or buffer (current-buffer))))
+ (if fn
+ (unwind-protect
+ (with-current-buffer buf
+ (message "%s buffer %s..." name buf)
+ (funcall fn)
+ (while proof-shell-busy ; busy wait
+ (sit-for 1))
+ (message "%s buffer %s...done." name buf)
+ (sit-for 0))
+ ;; Test to see if action was successful
+ (with-current-buffer buf
+ (or (and (eq action 'retract) (proof-locked-region-empty-p))
+ (and (eq action 'process) (proof-locked-region-full-p))
+ (error "%s of %s failed!" name buf)))))))
+
+
+(defun proof-deactivate-scripting (&optional forcedaction)
+ "Deactivate scripting for the active scripting buffer.
+
+Set proof-script-buffer to nil and turn off the modeline indicator.
+No action if there is no active scripting buffer.
+
+We make sure that the active scripting buffer either has no locked
+region or a full locked region (everything in it has been processed).
+If this is not already the case, we question the user whether to
+retract or assert, or automatically take the action indicated in the
+user option `proof-auto-action-when-deactivating-scripting.'
+
+If the scripting buffer is (or has become) fully processed, and it is
+associated with a file, it is registered on
+`proof-included-files-list'. Conversely, if it is (or has become)
+empty, we make sure that it is *not* registered. This is to be
+certain that the included files list behaves as we might expect with
+respect to the active scripting buffer, in an attempt to harmonize
+mixed scripting and file reading in the prover.
+
+This function either succeeds, fails because the user refused to
+process or retract a partly finished buffer, or gives an error message
+because retraction or processing failed. If this function succeeds,
+then proof-script-buffer is nil afterwards.
+
+The optional argument FORCEDACTION overrides the user option
+`proof-auto-action-when-deactivating-scripting' and prevents
+questioning the user. It is used to make a value for
+the kill-buffer-hook for scripting buffers, so that when
+a scripting buffer is killed it is always retracted."
+ (interactive)
+ (if proof-script-buffer
+ (with-current-buffer proof-script-buffer
+ ;; Examine buffer.
+
+ ;; We must ensure that the locked region is either
+ ;; empty or full, to make sense for multiple-file
+ ;; scripting. (A proof assistant won't be able to
+ ;; process just part of a file typically; moreover
+ ;; switching between buffers during a proof makes
+ ;; no sense.)
+ (if (or (proof-locked-region-empty-p)
+ (proof-locked-region-full-p)
+ ;; Buffer is partly-processed
+ (let*
+ ((action
+ (or
+ forcedaction
+ proof-auto-action-when-deactivating-scripting
+ (progn
+ (save-window-excursion
+ (unless
+ ;; Test to see whether to display the
+ ;; buffer or not.
+ ;; Could have user option here to avoid switching
+ ;; or maybe borrow similar standard setting
+ ;; save-some-buffers-query-display-buffer
+ (or
+ (eq (current-buffer)
+ (window-buffer (selected-window)))
+ (eq (selected-window) (minibuffer-window)))
+ (progn
+ (unless (one-window-p)
+ (delete-other-windows))
+ (switch-to-buffer proof-script-buffer t)))
+ ;; Would be nicer to ask a single question, but
+ ;; a nuisance to define our own dialogue since it
+ ;; doesn't really fit with one of the standard ones.
+ (cond
+ ((y-or-n-p
+ (format
+ "Scripting incomplete in buffer %s, retract? "
+ proof-script-buffer))
+ 'retract)
+ ((y-or-n-p
+ (format
+ "Completely process buffer %s instead? "
+ proof-script-buffer))
+ 'process)))))))
+ ;; Take the required action
+ (if action
+ (proof-protected-process-or-retract action)
+ ;; Give an acknowledgement to user's choice
+ ;; neither to assert or retract.
+ (message "Scripting still active in %s"
+ proof-script-buffer)
+ ;; Delay because this can be followed by an error
+ ;; message in proof-activate-scripting when trying
+ ;; to switch to another scripting buffer.
+ (sit-for 1)
+ nil)))
+
+ ;; If we get here, then the locked region is (now) either
+ ;; completely empty or completely full.
+ (progn
+ ;; We can immediately indicate that there is no active
+ ;; scripting buffer
+ (setq proof-previous-script-buffer proof-script-buffer)
+ (setq proof-script-buffer nil)
+
+ (if (proof-locked-region-full-p)
+ ;; If locked region is full, make sure that this buffer
+ ;; is registered on the included files list, and
+ ;; let the prover know it can consider it processed.
+ (if (or buffer-file-name proof-script-buffer-file-name)
+ (proof-register-possibly-new-processed-file
+ (or buffer-file-name proof-script-buffer-file-name)
+ 'tell-the-prover
+ forcedaction)))
+
+ (if (proof-locked-region-empty-p)
+ ;; If locked region is empty, make sure this buffer is
+ ;; *off* the included files list.
+ ;; FIXME: probably this isn't necessary: the
+ ;; file should be unregistered by the retract
+ ;; action, or in any case since it was only
+ ;; partly processed.
+ ;; FIXME 2: be careful about automatic
+ ;; multiple file handling here, since it calls
+ ;; for activating scripting elsewhere.
+ ;; We move the onus on unregistering now to
+ ;; the activate-scripting action.
+ (proof-unregister-buffer-file-name))
+
+ ;; Turn off Scripting indicator here.
+ (setq proof-active-buffer-fake-minor-mode nil)
+
+ ;; Make status of inactive scripting buffer show up
+ ;; FIXME da:
+ ;; not really necessary when called by kill buffer, at least.
+ (if (fboundp 'redraw-modeline)
+ (redraw-modeline)
+ (force-mode-line-update)))))))
+
+(defun proof-activate-scripting (&optional nosaves queuemode)
+ "Ready prover and activate scripting for the current script buffer.
+
+The current buffer is prepared for scripting. No changes are
+necessary if it is already in Scripting minor mode. Otherwise, it
+will become the new active scripting buffer, provided scripting
+can be switched off in the previous active scripting buffer
+with `proof-deactivate-scripting'.
+
+Activating a new script buffer may be a good time to ask if the
+user wants to save some buffers; this is done if the user
+option `proof-query-file-save-when-activating-scripting' is set
+and provided the optional argument NOSAVES is non-nil.
+
+The optional argument QUEUEMODE relaxes the test for a
+busy proof shell to allow one which has mode QUEUEMODE.
+In all other cases, a proof shell busy error is given.
+
+Finally, the hooks `proof-activate-scripting-hook' are run.
+This can be a useful place to configure the proof assistant for
+scripting in a particular file, for example, loading the
+correct theory, or whatever. If the hooks issue commands
+to the proof assistant (via `proof-shell-invisible-command')
+which result in an error, the activation is considered to
+have failed and an error is given."
+ (interactive)
+ ;; FIXME: the scope of this save-excursion is rather wide.
+ ;; Problems without it however: Use button behaves oddly
+ ;; when process is started already.
+ ;; Where is save-excursion needed?
+ ;; First experiment shows that it's the hooks that cause
+ ;; problem, maybe even the use of proof-cd-sync (can't see why).
+ (save-excursion
+ ;; FIXME: proof-shell-ready-prover here s
+ (proof-shell-ready-prover queuemode)
+ (cond
+ ((not (eq proof-buffer-type 'script))
+ (error "Must be running in a script buffer!"))
+
+ ;; If the current buffer is the active one there's nothing to do.
+ ((equal (current-buffer) proof-script-buffer))
+
+ ;; Otherwise we need to activate a new Scripting buffer.
+ (t
+ ;; If there's another buffer currently active, we need to
+ ;; deactivate it (also fixing up the included files list).
+ (if proof-script-buffer
+ (progn
+ (proof-deactivate-scripting)
+ ;; Test whether deactivation worked
+ (if proof-script-buffer
+ (error
+ "You cannot have more than one active scripting buffer!"))))
+
+ ;; Now make sure that this buffer is off the included files
+ ;; list. In case we re-activate scripting in an already
+ ;; completed buffer, it may be that the proof assistant
+ ;; needs to retract some of this buffer's dependencies.
+ (proof-unregister-buffer-file-name 'tell-the-prover)
+
+ ;; If automatic retraction happened in the above step, we may
+ ;; have inadvertently activated scripting somewhere else.
+ ;; Better turn it off again. This should succeed trivially.
+ ;; NB: it seems that we could move the first test for an already
+ ;; active buffer here, but it is more subtle: the first
+ ;; deactivation can extend the proof-included-files list, which
+ ;; would affect what retraction was done in
+ ;; proof-unregister-buffer-file-name.
+ (if proof-script-buffer
+ (proof-deactivate-scripting))
+ (assert (null proof-script-buffer)
+ "Bug in proof-activate-scripting: deactivate failed.")
+
+ ;; Set the active scripting buffer, and initialise the
+ ;; queue and locked regions if necessary.
+ (setq proof-script-buffer (current-buffer))
+ (if (proof-locked-region-empty-p)
+ ;; This removes any locked region that was there, but
+ ;; sometimes we switch on scripting in "full" buffers,
+ ;; so mustn't do this.
+ (proof-init-segmentation))
+
+ ;; Turn on the minor mode, make it show up.
+ (setq proof-active-buffer-fake-minor-mode t)
+ (if (fboundp 'redraw-modeline)
+ (redraw-modeline)
+ (force-mode-line-update))
+
+ ;; This may be a good time to ask if the user wants to save some
+ ;; buffers. On the other hand, it's jolly annoying to be
+ ;; queried on the active scripting buffer if we've started
+ ;; writing in it. So pretend that one is unmodified, at least
+ ;; (we certainly don't expect the proof assitant to load it)
+ (if (and
+ proof-query-file-save-when-activating-scripting
+ (not nosaves))
+ (let ((modified (buffer-modified-p)))
+ (set-buffer-modified-p nil)
+ (unwind-protect
+ (save-some-buffers)
+ (set-buffer-modified-p modified))))
+
+ ;; Run hooks with a variable which suggests whether or not
+ ;; to block. NB: The hook function may send commands to the
+ ;; process which will re-enter this function, but should exit
+ ;; immediately because scripting has been turned on now.
+ (if proof-activate-scripting-hook
+ (let
+ ((activated-interactively (interactive-p)))
+ ;; Clear flag in case no hooks run shell commands
+ (setq proof-shell-error-or-interrupt-seen nil)
+ (run-hooks 'proof-activate-scripting-hook)
+ ;; In case the activate scripting functions
+ ;; caused an error in the proof assistant, we'll
+ ;; consider activating scripting to have failed,
+ ;; and raise an error here.
+ ;; (Since this behaviour is intimate with the hook functions,
+ ;; it could be removed and left to implementors of
+ ;; specific instances of PG).
+ ;; FIXME: we could consider simply running the hooks
+ ;; as the last step before turning on scripting properly,
+ ;; provided the hooks don't inspect proof-script-buffer.
+ (if proof-shell-error-or-interrupt-seen
+ (progn
+ (proof-deactivate-scripting) ;; turn it off again!
+ ;; Give an error to prevent further actions.
+ (error "Proof General: Scripting not activated because of error or interrupt.")))))))))
+
+
+(defun proof-toggle-active-scripting (&optional arg)
+ "Toggle active scripting mode in the current buffer.
+With ARG, turn on scripting iff ARG is positive."
+ (interactive "P")
+ ;; A little less obvious than it may seem: toggling scripting in the
+ ;; current buffer may involve turning it off in some other buffer
+ ;; first!
+ (if (if (null arg)
+ (not (eq proof-script-buffer (current-buffer)))
+ (> (prefix-numeric-value arg) 0))
+ (progn
+ (if proof-script-buffer
+ (call-interactively 'proof-deactivate-scripting))
+ (call-interactively 'proof-activate-scripting))
+ (call-interactively 'proof-deactivate-scripting)))
+
+;; This function isn't such a wise idea: the buffer will often be fully
+;; locked when writing a script, but we don't want to keep toggling
+;; switching mode!
+;;(defun proof-auto-deactivate-scripting ()
+;; "Turn off scripting if the current scripting buffer is empty or full.
+;;This is a possible value for proof-state-change-hook.
+;;FIXME: this currently doesn't quite work properly as a value for
+;;proof-state-change-hook, in fact: maybe because the
+;;hook is called somewhere where proof-script-buffer
+;;should not be nullified!"
+;; (if proof-script-buffer
+;; (with-current-buffer proof-script-buffer
+;; (if (or (proof-locked-region-empty-p)
+;; (proof-locked-region-full-p))
+;; (proof-deactivate-scripting)))))
+
+;;
+;; End of activating and deactivating scripting section
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;; da: 28.10.98: this is used by toolbar follow mode (which used to
+;; use the function above). [But wouldn't work for
+;; proof-shell-handle-error-or-interrupt-hook?].
+
+(defun proof-goto-end-of-queue-or-locked-if-not-visible ()
+ "Jump to the end of the queue region or locked region if it isn't visible.
+Assumes script buffer is current"
+ (unless (pos-visible-in-window-p
+ (proof-queue-or-locked-end)
+ (get-buffer-window (current-buffer) t))
+ (goto-char (proof-queue-or-locked-end))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; User Commands ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Script management uses two major segments: Locked, which marks text
+; which has been sent to the proof assistant and cannot be altered
+; without being retracted, and Queue, which contains stuff being
+; queued for processing. proof-action-list contains a list of
+; (span,command,action) triples. The loop looks like: Execute the
+; command, and if it's successful, do action on span. If the
+; command's not successful, we bounce the rest of the queue and do
+; some error processing.
+;
+; when a span has been processed, we classify it as follows:
+; 'goalsave - denoting a goal-save pair in the locked region
+; A goalsave may have a nested 'proof region which is the body
+; of the proof and may be hidden.
+; 'goalsave and 'proof regions have a 'name property which
+; is the name of the goal
+; 'comment - denoting a comment
+; 'pbp - denoting a span created by pbp
+; 'vanilla - denoting any other span.
+; 'proverproc -- prover processed region (e.g. when a file is read
+; atomically by the prover)
+; 'pbp & 'vanilla spans have a property 'cmd, which says what
+; command they contain.
+
+
+
+
+; We don't allow commands while the queue has anything in it. So we
+; do configuration by concatenating the config command on the front in
+; proof-shell-insert
+
+;; proof-assert-until-point, and various gunk for its ;;
+;; setup and callback ;;
+
+
+(defun proof-check-atomic-sequents-lists (span cmd end)
+ "Check if CMD is the final command in an ACS.
+
+If CMD is matched by the end regexp in `proof-atomic-sequents-list',
+the ACS is marked in the current buffer. If CMD does not match any,
+`nil' is returned, otherwise non-nil."
+ ;;FIXME tms: needs implementation
+ nil)
+
+
+
+(defun proof-done-advancing (span)
+ "The callback function for assert-until-point."
+ ;; FIXME da: if the buffer dies, this function breaks horribly.
+ ;; Needs robustifying.
+ (if (not (span-live-p span))
+ ;; FIXME da: Sometimes this function is called with a destroyed
+ ;; extent as argument. When? Isn't this a bug?
+ ;; (one case would be if the buffer is killed while
+ ;; a proof is completing)
+ ;; NB: this patch doesn't work! Are spans being destroyed
+ ;; sometime *during* this code??
+ (proof-debug
+ "Proof General idiosyncrasy: proof-done-advancing called with a dead span!")
+ ;;
+ (let ((end (span-end span)) cmd)
+ ;; State of spans after advancing:
+ (proof-set-locked-end end)
+ (proof-set-queue-start end)
+ (setq cmd (span-property span 'cmd))
+ (cond
+ ;; CASE 1: Comments just get highlighted
+ ((eq (span-property span 'type) 'comment)
+ (pg-set-span-helphighlights span))
+
+ ;; CASE 2: Save command seen, now we'll amalgamate spans.
+ ((and proof-save-command-regexp
+ (proof-string-match proof-save-command-regexp cmd)
+ (funcall proof-really-save-command-p span cmd))
+
+ (unless (eq proof-shell-proof-completed 1)
+ ;; We expect saves to succeed only for recently completed proofs.
+ ;; Give a hint to the proof assistant implementor in case something
+ ;; odd is going on.
+ (proof-debug
+ (format
+ "Proof General note: save command with proof-shell-proof-completed=%s"
+ proof-shell-proof-completed)))
+
+ (setq proof-shell-proof-completed nil)
+
+ ;; FIXME: subroutine here:
+ (let ((gspan span)
+ (savestart (span-start span))
+ (saveend (span-end span))
+ goalend nam next ncmd)
+
+ ;; Try to set the name of the theorem from the save
+ (message "%s" cmd)
+
+ (and proof-save-with-hole-regexp
+ (proof-string-match proof-save-with-hole-regexp cmd)
+ (setq nam
+ (if (stringp proof-save-with-hole-result)
+ (replace-match proof-save-with-hole-result nil nil cmd)
+ (match-string proof-save-with-hole-result cmd))))
+ (message "%s" nam)
+
+ ;; Search backwards for first goal command,
+ ;; deleting spans along the way.
+ (while
+ (and gspan
+ (or (eq (span-property gspan 'type) 'comment)
+ (and (setq ncmd (span-property gspan 'cmd))
+ (not (funcall proof-goal-command-p
+ (setq cmd ncmd))))))
+ (setq next (prev-span gspan 'type))
+ (delete-span gspan)
+ (setq gspan next))
+ (if (not gspan)
+ ;; No goal span found! Issue a warning and do nothing more.
+ (proof-warning
+ "Proof General: script management confused, couldn't find goal span for save.")
+
+ ;; If the name isn't set, try to set it from the goal.
+ (unless nam
+ (let ((cmdstr (span-property gspan 'cmd)))
+ (message "%s" cmdstr)
+ (and proof-goal-with-hole-regexp
+ (proof-string-match proof-goal-with-hole-regexp cmdstr)
+ (setq nam
+ (if (stringp proof-goal-with-hole-result)
+ (replace-match proof-goal-with-hole-result nil nil cmdstr)
+ (match-string proof-goal-with-hole-result cmdstr))))))
+
+ ;; As a final desparate attempt, set the name to
+ ;; proof-unnamed-theorem-name (Coq actually uses a default
+ ;; name for unnamed theorems, believe it or not, and issues
+ ;; a name-binding error for two unnamed theorems in a row!).
+ (unless nam
+ (setq nam proof-unnamed-theorem-name))
+
+ ;; FIXME: this needs to be abstracted out into a function
+ ;; pg-add-new-proof-span
+
+ ;; Now make the new goal-save span
+ (setq goalend (span-end gspan))
+ (set-span-end gspan end)
+ (set-span-property gspan 'type 'goalsave)
+ (set-span-property gspan 'idiom 'proof);; links to nested proof element
+ (set-span-property gspan 'name nam)
+ (pg-set-span-helphighlights gspan)
+
+ ;; Make a nested span which contains the purported body of the
+ ;; proof, and add to buffer-local list of elements, maybe
+ ;; making invisible.
+ (let ((proofbodyspan
+ (make-span goalend (if proof-script-integral-proofs
+ saveend savestart))))
+ (pg-add-proof-element nam proofbodyspan gspan))
+
+ ;; *** Theorem dependencies ***
+ (if proof-last-theorem-dependencies
+ (proof-depends-process-dependencies nam gspan))
+
+ ;; In Coq, we have the invariant that if we've done a save and
+ ;; there's a top-level declaration then it must be the
+ ;; associated goal. (Notice that because it's a callback it
+ ;; must have been approved by the theorem prover.)
+ (and proof-lift-global
+ (funcall proof-lift-global gspan)))))
+
+ ;; CASE 3: Proof completed one step or more ago, non-save
+ ;; command seen, no nested goals allowed.
+ ;;
+ ;; We make a fake goal-save from any previous
+ ;; goal to the command before the present one.
+ ;;
+ ;; This is a hack to allow smooth undoing in proofs which have no
+ ;; "qed" statements. If your proof assistant doesn't allow
+ ;; these "unclosed" proofs, then you can safely set
+ ;; proof-completed-proof-behaviour.
+ ;;
+ ;; FIXME: abstract common part of this case and case above,
+ ;; to improve code by making a useful subroutine.
+ ;; FIXME: add proof element here for hiding.
+ ((and
+ proof-shell-proof-completed
+ (or (and (eq proof-completed-proof-behaviour 'extend)
+ (>= proof-shell-proof-completed 0))
+ (and (eq proof-completed-proof-behaviour 'closeany)
+ (> proof-shell-proof-completed 0))
+ (and (eq proof-completed-proof-behaviour 'closegoal)
+ (funcall proof-goal-command-p cmd))))
+
+ (if (eq proof-completed-proof-behaviour 'extend)
+ ;; In the extend case, the context of the proof grows
+ ;; until we hit a save or new goal.
+ (incf proof-shell-proof-completed)
+ (setq proof-shell-proof-completed nil))
+
+ (let* ((swallow (eq proof-completed-proof-behaviour 'extend))
+ (gspan (if swallow span (prev-span span 'type)))
+ (newend (if swallow (span-end span) (span-start span)))
+ nam hitsave dels ncmd)
+ ;; Search backwards to see if we can find a previous goal
+ ;; before a save or the start of the buffer.
+ (while
+ (and
+ gspan
+ (or
+ (eq (span-property gspan 'type) 'comment)
+ (and
+ (setq ncmd (span-property gspan 'cmd))
+ (not (funcall proof-goal-command-p (setq cmd ncmd)))
+ (not
+ (and proof-save-command-regexp
+ (proof-string-match proof-save-command-regexp cmd)
+ (funcall proof-really-save-command-p span cmd)
+ (setq hitsave t))))))
+ (setq dels (cons gspan dels))
+ (setq gspan (prev-span gspan 'type)))
+ (if (or hitsave (null gspan))
+ (proof-debug
+ "Proof General strangeness: unclosed proof completed, but couldn't find its start!")
+ ;; If we haven't hit a save or the start of the buffer,
+ ;; we make a fake goal-save region.
+
+ ;; Delete spans between the previous goal and new command
+ (mapcar 'delete-span dels)
+
+ ;; Try to set a name from the goal
+ ;; (useless for provers like Isabelle)
+ (let ((cmdstr (span-property gspan 'cmd)))
+ (message "%s" cmdstr)
+ (and proof-goal-with-hole-regexp
+ (proof-string-match proof-goal-with-hole-regexp cmdstr)
+ (setq nam
+ (if (stringp proof-goal-with-hole-result)
+ (replace-match proof-goal-with-hole-result nil nil cmdstr)
+ (match-string proof-goal-with-hole-result cmdstr)))))
+
+ ;; As a final desparate attempt, set the name to "Unnamed_thm".
+ (unless nam
+ (setq nam proof-unnamed-theorem-name))
+
+ ;; Now make the new or extended goal-save span
+ ;; Don't bother with Coq's lift global stuff, we assume this
+ ;; case is only good for non-nested goals.
+ (set-span-end gspan newend)
+ (set-span-property gspan 'type 'goalsave)
+ (set-span-property gspan 'name nam)
+ (pg-set-span-helphighlights span))
+ ;; Finally, do the usual thing with highlighting for the span.
+ (unless swallow
+ (pg-set-span-helphighlights span))))
+
+
+ ;; "ACS" for possible future implementation
+ ;; ((proof-check-atomic-sequents-lists span cmd end))
+
+ ;; CASE 4: Some other kind of command (or a nested goal).
+ (t
+ (if proof-shell-proof-completed
+ (incf proof-shell-proof-completed))
+ (pg-set-span-helphighlights span)
+ (and proof-global-p
+ (funcall proof-global-p cmd)
+ proof-lift-global
+ (funcall proof-lift-global span)))))
+
+ ;; State of scripting may have changed now
+ (run-hooks 'proof-state-change-hook)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Yet more NEW parsing functions for 3.3
+;;
+;; We need to be more general and a bit more clear, this
+;; is a much better attempt.
+
+(defun proof-segment-up-to-parser (pos &optional next-command-end)
+ "Parse the script buffer from end of locked to POS.
+Return a list of (type, string, int) tuples (in reverse order).
+
+Each tuple denotes the command and the position of its final character,
+type is one of 'comment, or 'cmd.
+
+The behaviour around comments is set by
+`proof-script-fly-past-comments', which see.
+
+This version is used when `proof-script-parse-function' is set,
+to the function which parses the script segment by segment."
+ (save-excursion
+ (let* ((start (goto-char (proof-queue-or-locked-end)))
+ (cur (1- start))
+ (seg t)
+ prevtype realstart cmdseen segs)
+ ;; Keep parsing until:
+ ;; - we fail to find a segment (seg = nil)
+ ;; - we go beyond the stop point (cur >= end)
+ ;; - unless we're flying past comments, in which case
+ ;; wait for a command (cmdseen<>nil)
+ (while (and seg
+ (or (< cur pos)
+ (and proof-script-fly-past-comments
+ (not cmdseen))))
+ ;; Skip whitespace before this element
+ (skip-chars-forward " \t\n")
+ (setq realstart (point))
+ (let* ((type (funcall proof-script-parse-function)))
+ (setq seg nil)
+ (cond
+ ((eq type 'comment)
+ (setq seg (list 'comment "" (point))))
+ ((eq type 'cmd)
+ (setq cmdseen t)
+ (setq seg (list
+ 'cmd
+ (buffer-substring realstart (point))
+ (point))))
+ ((null type)) ; nothing left in buffer
+ (t
+ (error
+ "proof-segment-up-to-parser: bad TYPE value from proof-script-parse-function.")))
+ ;;
+ (if seg
+ (progn
+ ;; Add the new segment, coalescing comments if
+ ;; the user likes it that way. I first made
+ ;; coalescing a separate configuration option, but
+ ;; it works well used in tandem with the fly-past
+ ;; behaviour.
+ (if (and proof-script-fly-past-comments
+ (eq type 'comment)
+ (eq prevtype 'comment))
+ (setq segs (cons seg (cdr segs)))
+ (setq segs (cons seg segs)))
+ ;; Update state
+ (setq cur (point))
+ (setq prevtype type)))))
+ ;; Return segment list
+ segs)))
+
+(defun proof-script-generic-parse-find-comment-end ()
+ "Find the end of the comment point is at the start of. Nil if not found."
+ (let ((notout t))
+ ;; Find end of comment (NB: doesn't undertand nested comments)
+ (while (and notout (re-search-forward
+ proof-comment-end-regexp nil 'movetolimit))
+ (setq notout (proof-buffer-syntactic-context)))
+ (not (proof-buffer-syntactic-context))))
+
+(defun proof-script-generic-parse-cmdend ()
+ "Used for proof-script-parse-function if proof-script-command-end-regexp is set."
+ (if (looking-at proof-comment-start-regexp)
+ ;; Handle comments
+ (if (proof-script-generic-parse-find-comment-end) 'comment)
+ ;; Handle non-comments: assumed to be commands
+ (let (foundend)
+ ;; Find end of command
+ (while (and (setq foundend
+ (re-search-forward proof-script-command-end-regexp nil t))
+ (proof-buffer-syntactic-context))
+ ;; inside a string or comment before the command end
+ )
+ (if (and foundend
+ (not (proof-buffer-syntactic-context)))
+ ;; Found command end outside string/comment
+ 'cmd
+ ;; Didn't find command end
+ nil))))
+
+(defun proof-script-generic-parse-cmdstart ()
+ "For proof-script-parse-function if proof-script-command-start-regexp is set."
+ ;; This was added for the fine-grained command structure of Isar
+ ;;
+ ;; It's is a lot more involved than the case of just scanning for
+ ;; the command end; we have to find two successive command starts
+ ;; and go backwards from the second. This coalesces comments
+ ;; following commands with commands themselves, and sends them to
+ ;; the prover (only case where it does).
+ ;;
+ ;; To avoid doing that, we would need to scan also for comments but
+ ;; it would be difficult to distinguish between:
+ ;; complete command (* that's it *)
+ ;; and
+ ;; complete (* almost *) command
+ ;;
+ ;; Maybe the second case should be disallowed in command-start regexp case?
+ ;;
+ ;; Another improvement idea might be to take into account both
+ ;; command starts *and* ends, but let's leave that for another day.
+ ;;
+ (if (looking-at proof-comment-start-regexp)
+ ;; Find end of comment
+ (if (proof-script-generic-parse-find-comment-end) 'comment)
+ ;; Handle non-comments: assumed to be commands
+ (if (looking-at proof-script-command-start-regexp)
+ (progn
+ ;; We've got at least the beginnings of a command, skip past it
+ (re-search-forward proof-script-command-start-regexp nil t)
+ (let (foundstart)
+ ;; Find next command start
+ (while (and (setq
+ foundstart
+ (and
+ (re-search-forward proof-script-command-start-regexp
+ nil 'movetolimit)
+ (match-beginning 0)))
+ (proof-buffer-syntactic-context))
+ ;; inside a string or comment before the next command start
+ )
+ (if (not (proof-buffer-syntactic-context)) ; not inside a comment/string
+ (if foundstart ; found a second command start
+ (progn
+ (goto-char foundstart) ; beginning of command start
+ (skip-chars-backward " \t\n") ; end of previous command
+ 'cmd)
+ (if (eq (point) (point-max)) ; At the end of the buffer
+ (progn
+ (skip-chars-backward " \t\n") ; benefit of the doubt, let
+ 'cmd)))) ; the PA moan if it's incomplete
+ ;; Return nil in other cases, no complete command found
+ )))))
+
+
+(defun proof-script-generic-parse-sexp ()
+ "Used for proof-script-parse-function if proof-script-sexp-commands is set."
+ ;; Usual treatment of comments
+ (if (looking-at proof-comment-start-regexp)
+ ;; Find end of comment
+ (if (proof-script-generic-parse-find-comment-end) 'comment)
+ (let* ((parse-sexp-ignore-comments t) ; gobble comments into commands
+ (end (scan-sexps (point) 1)))
+ (if end
+ (progn (goto-char end) 'cmd)))))
+
+
+;; NEW parsing functions for 3.2
+;;
+;; NB: compared with old code,
+;; (1) this doesn't treat comments quite so well, but parsing
+;; should be rather more efficient.
+;; (2) comments are treated less like commands, and are only
+;; coloured blue "in passing" when commands are sent.
+;; However, undo still process comments step-by-step.
+
+(defun proof-segment-up-to-cmdstart (pos &optional next-command-end)
+ "Parse the script buffer from end of locked to POS.
+Return a list of (type, string, int) tuples.
+
+Each tuple denotes the command and the position of its terminator,
+type is one of 'comment, or 'cmd.
+
+If optional NEXT-COMMAND-END is non-nil, we include the command
+which continues past POS, if any. (NOT IMPLEMENTED IN THIS VERSION).
+
+This version is used when `proof-script-command-start-regexp' is set."
+ (save-excursion
+ (let* ((commentre (concat "[ \t\n]*" proof-comment-start-regexp))
+ (commentend (concat proof-comment-end-regexp "[ \t\n]*" ))
+ (add-segment-for-cmd ; local function: advances "prev"
+ (lambda ()
+ (setq tmp (point))
+ ;; Find end of previous command...
+ (goto-char comstart)
+ ;; Special hack: allow terminal char to be included
+ ;; in a command, if it's set.
+ (if (and proof-terminal-char
+ (looking-at
+ (regexp-quote (char-to-string proof-terminal-char))))
+ (goto-char (1+ (point)))
+ (skip-chars-backward " \t\n"))
+ (let* ((prev-no-blanks
+ (save-excursion
+ (goto-char prev)
+ (skip-chars-forward " \t\n")
+ (point)))
+ (comend (point))
+ (bufstr (buffer-substring prev-no-blanks comend))
+ (type (save-excursion
+ ;; The behaviour here is a bit odd: this
+ ;; is a half-hearted attempt to strip comments
+ ;; as we send text to the proof assistant,
+ ;; but it breaks when we have certain bad
+ ;; input: (* foo *) blah (* bar *) cmd
+ ;; We check for the case
+ ;; of a comment spanning the *whole*
+ ;; substring, otherwise send the
+ ;; (defective) text as if it were a
+ ;; proper command anyway.
+ ;; This shouldn't cause problems: the
+ ;; proof assistant is certainly capable
+ ;; of skipping comments itself, and
+ ;; the situation should cause an error.
+ ;; (If it were accepted it could upset the
+ ;; undo behaviour)
+ (goto-char prev-no-blanks)
+ ;; Update: PG 3.4: try to deal with sequences
+ ;; of comments as well, since previous behaviour
+ ;; breaks Isar, in fact, since repeated
+ ;; comments get categorized as commands,
+ ;; breaking sync.
+ (if (and
+ (looking-at commentre)
+ (re-search-forward proof-comment-end-regexp)
+ (progn
+ (while (looking-at commentre)
+ (re-search-forward proof-comment-end-regexp))
+ (>= (point) comend)))
+ 'comment 'cmd)))
+ (string (if (eq type 'comment) "" bufstr)))
+ (setq prev (point))
+ (goto-char tmp)
+ ;; NB: Command string excludes whitespace, span includes it.
+ (setq alist (cons (list type string prev) alist)))))
+ alist prev cmdfnd startpos comstart tmp)
+ (goto-char (proof-queue-or-locked-end))
+ (setq prev (point))
+ (skip-chars-forward " \t\n")
+ (setq startpos (point))
+ (while
+ (and
+ (proof-re-search-forward proof-script-command-start-regexp
+ nil t) ; search for next command
+ (setq comstart (match-beginning 0)); save command start
+ (or (save-excursion
+ (goto-char comstart)
+ ;; continue if inside (or at start of) comment/string
+ (proof-looking-at-syntactic-context))
+ (progn ; or, if found command...
+ (setq cmdfnd
+ (> comstart startpos)); ignore first match
+ (<= prev pos))))
+ (if cmdfnd (progn
+ (funcall add-segment-for-cmd)
+ (setq cmdfnd nil))))
+ ;; End of parse; see if we found some text at the end of the
+ ;; buffer which could be a command. (NB: With a regexp for
+ ;; start of commands only, we can't be sure it is a complete
+ ;; command).
+ (if (and comstart ; previous command was found
+ (<= prev pos) ; last command within range
+ (goto-char (point-max))
+ (setq comstart (point)) ; pretend there's another cmd here
+ (not (proof-buffer-syntactic-context))) ; buffer ends well
+ (funcall add-segment-for-cmd))
+ ; (if (and cmdfnd next-command-end)
+ ; (funcall add-segment-for-cmd))
+ ;; Return resulting list
+ alist)))
+
+
+;; FIXME: this needs fixing to include final comment in buffer
+;; if there is one!!
+
+(defun proof-segment-up-to-cmdend (pos &optional next-command-end)
+ "Parse the script buffer from end of locked to POS.
+Return a list of (type, string, int) tuples.
+
+Each tuple denotes the command and the position of its terminator,
+type is one of 'comment, or 'cmd. 'unclosed-comment may be consed onto
+the start if the segment finishes with an unclosed comment.
+
+If optional NEXT-COMMAND-END is non-nil, we include the command
+which continues past POS, if any.
+
+This version is used when `proof-script-command-end-regexp' is set."
+ (save-excursion
+ (let*
+ ((commentre (concat "[ \t\n]*" proof-comment-start-regexp))
+ (add-segment-for-cmd ; local function: advances "prev"
+ (lambda ()
+ (let ((cmdend (point)) start)
+ (goto-char prev)
+ ;; String may start with comments, let's strip them off
+ (while
+ (and
+ (setq start (point))
+ (proof-re-search-forward commentre cmdend t)
+ (or (eq (match-beginning 0) start)
+ ;; In case a comment inside a command was found, make
+ ;; sure we're at the start of the cmd before exiting
+ (progn (goto-char start) nil)))
+ ;; Look for the end of the comment
+ ;; (FIXME: ignore nested comments here, we should
+ ;; have a consistent policy!)
+ (unless
+ (proof-re-search-forward
+ proof-comment-end-regexp cmdend t)
+ (error
+ "PG error: proof-segment-up-to-cmd-end didn't find comment end."))
+ (setq alist (cons (list 'comment "" (point)) alist)))
+ ;; There should be something left: a command.
+ (skip-chars-forward " \t\n")
+ (setq alist (cons (list 'cmd
+ (buffer-substring
+ (point) cmdend)
+ cmdend) alist))
+ (setq prev cmdend)
+ (goto-char cmdend))))
+ alist prev cmdfnd startpos tmp)
+ (goto-char (proof-queue-or-locked-end))
+ (setq prev (point))
+ (skip-chars-forward " \t\n")
+ (setq startpos (point))
+ (while
+ (and
+ (proof-re-search-forward proof-script-command-end-regexp
+ nil t) ; search for next command
+ (or (proof-buffer-syntactic-context) ; continue if inside comment/string
+ (progn ; or, if found command...
+ (setq cmdfnd t)
+ (<= (point) pos))))
+ (if cmdfnd (progn
+ (funcall add-segment-for-cmd)
+ (setq cmdfnd nil))))
+ ;; End of parse; if we found a command past POS maybe add it.
+ ;; FIXME: also, if we found a *comment* maybe add it!
+ (if cmdfnd ; (and cmdfnd next-command-end)
+ (funcall add-segment-for-cmd))
+ ;; Return resulting list
+ alist)))
+
+(defun proof-semis-to-vanillas (semis &optional callback-fn)
+ "Convert a sequence of terminator positions to a set of vanilla extents.
+Proof terminator positions SEMIS has the form returned by
+the function proof-segment-up-to.
+Set the callback to CALLBACK-FN or 'proof-done-advancing by default."
+ (let ((ct (proof-queue-or-locked-end)) span alist semi)
+ (while (not (null semis))
+ (setq semi (car semis)
+ span (make-span ct (nth 2 semi))
+ ct (nth 2 semi))
+ (if (eq (car (car semis)) 'cmd)
+ (progn
+ (set-span-property span 'type 'vanilla)
+ (set-span-property span 'cmd (nth 1 semi))
+ (setq alist (cons (list span (nth 1 semi)
+ (or callback-fn 'proof-done-advancing))
+ alist)))
+ (set-span-property span 'type 'comment)
+ (setq alist (cons (list span proof-no-command 'proof-done-advancing)
+ alist)))
+ (setq semis (cdr semis)))
+ (nreverse alist)))
+
+;;
+;; Two commands for moving forwards in proof scripts.
+;; Moving forward for a "new" command may insert spaces
+;; or new lines. Moving forward for the "next" command
+;; does not.
+;;
+
+(defun proof-script-new-command-advance ()
+ "Move point to a nice position for a new command.
+Assumes that point is at the end of a command."
+ (interactive)
+; FIXME: pending improvement for 3.2, needs a fix here.
+; (if (eq (proof-locked-end) (point))
+; ;; A hack to fix problem that the locked span
+; ;; is [ ) so sometimes inserting at the end
+; ;; tries to extend it, giving "read only" error.
+; (if (> (point-max) (proof-locked-end))
+; (progn
+; (goto-char (1+ (proof-locked-end)))
+; (backward-char))))
+ (if proof-one-command-per-line
+ ;; One command per line: move to next new line,
+ ;; creating one if at end of buffer or at the
+ ;; start of a blank line. (This has the pleasing
+ ;; effect that blank regions of the buffer are
+ ;; automatically extended when inserting new commands).
+; unfortunately if we're not at the end of a line to start,
+; it skips past stuff to the end of the line! don't want
+; that.
+; (cond
+; ((eq (forward-line) 1)
+; (newline))
+; ((eolp)
+; (newline)
+; (forward-line -1)))
+ (newline)
+ ;; Multiple commands per line: skip spaces at point,
+ ;; and insert the 1/0 number of spaces that were
+ ;; skipped in front of point (at least one).
+ ;; This has the pleasing effect that the spacing
+ ;; policy of the current line is copied: e.g.
+ ;; <command>; <command>;
+ ;; Tab columns don't work properly, however.
+ ;; Instead of proof-one-command-per-line we could
+ ;; introduce a "proof-command-separator" to improve
+ ;; this.
+ (let ((newspace (max (skip-chars-forward " \t") 1))
+ (p (point)))
+ (if proof-script-command-separator
+ (insert proof-script-command-separator)
+ (insert-char ?\ newspace)
+ (goto-char p)))))
+
+(defun proof-script-next-command-advance ()
+ "Move point to the beginning of the next command if it's nearby.
+Assumes that point is at the end of a command."
+ (interactive)
+ ;; skip whitespace on this line
+ (skip-chars-forward " \t")
+ (if (and proof-one-command-per-line (eolp))
+ ;; go to the next line if we have one command per line
+ (forward-line)))
+
+
+;; NB: the "interactive" variant is so that we get a simple docstring.
+(defun proof-assert-until-point-interactive ()
+ "Process the region from the end of the locked-region until point.
+Default action if inside a comment is just process as far as the start of
+the comment."
+ (interactive)
+ (proof-assert-until-point))
+
+
+; Assert until point - We actually use this to implement the
+; assert-until-point, electric terminator keypress, and goto-command-end.
+; In different cases we want different things, but usually the information
+; (i.e. are we inside a comment) isn't available until we've actually run
+; proof-segment-up-to (point), hence all the different options when we've
+; done so.
+
+;; FIXME da: this command doesn't behave as the doc string says when
+;; inside comments. Also is unhelpful at the start of commands, and
+;; in the locked region. I prefer the new version below.
+
+;; FIXME: get rid of duplication between proof-assert-next-command and
+;; proof-assert-until-point. Get rid of ignore process nonsense.
+
+;; FIXME: get rid of unclosed-comment-fun nonsense. It's used
+;; in the electric terminator function, but we should probably
+;; use something else for that!
+
+(defun proof-assert-until-point (&optional unclosed-comment-fun
+ ignore-proof-process-p)
+ "Process the region from the end of the locked-region until point.
+Default action if inside a comment is just process as far as the start of
+the comment.
+
+If you want something different, put it inside
+UNCLOSED-COMMENT-FUN. If IGNORE-PROOF-PROCESS-P is set, no commands
+will be added to the queue and the buffer will not be activated for
+scripting."
+ (unless ignore-proof-process-p
+ (proof-activate-scripting nil 'advancing))
+ (let ((semis))
+ (save-excursion
+ ;; Give error if no non-whitespace between point and end of
+ ;; locked region.
+ (if (proof-only-whitespace-to-locked-region-p)
+ (error "At the end of the locked region already, there's nothing to do to!"))
+ ;; NB: (point) has now been moved backwards to first non-whitespace char.
+ (setq semis (proof-segment-up-to (point))))
+ (if (and unclosed-comment-fun (eq 'unclosed-comment (car semis)))
+ (funcall unclosed-comment-fun)
+ (if (eq 'unclosed-comment (car semis)) (setq semis (cdr semis)))
+ (if (and (not ignore-proof-process-p) (null semis))
+ ;; This is another case that there's nothing to do: maybe
+ ;; because inside a string or something.
+ (if (eq unclosed-comment-fun 'proof-electric-term-incomment-fn)
+ ;; With electric terminator, we shouldn't give an error, but
+ ;; should still insert and pretend it was as if a comment.
+ (proof-electric-term-incomment-fn)
+ (error "I can't find any complete commands to process!"))
+ (goto-char (nth 2 (car semis)))
+ (and (not ignore-proof-process-p)
+ (let ((vanillas (proof-semis-to-vanillas (nreverse semis))))
+ (proof-extend-queue (point) vanillas)))))))
+
+
+;; da: This is my alternative version of the above.
+;; It works from the locked region too.
+;; I find it more convenient to assert up to the current command (command
+;; point is inside), and move to the next command.
+;; This means proofs can be easily replayed with point at the start
+;; of lines. Above function gives stupid "nothing to do error." when
+;; point is on the start of line or in the locked region.
+
+;; FIXME: behaviour inside comments may be odd at the moment. (it
+;; doesn't behave as docstring suggests, same prob as
+;; proof-assert-until-point)
+;; FIXME: polish the undo behaviour and quit behaviour of this
+;; command (should inhibit quit somewhere or other).
+
+
+
+(defun proof-assert-next-command
+ (&optional unclosed-comment-fun ignore-proof-process-p
+ dont-move-forward for-new-command)
+ "Process until the end of the next unprocessed command after point.
+If inside a comment, just process until the start of the comment.
+
+If you want something different, put it inside UNCLOSED-COMMENT-FUN.
+If IGNORE-PROOF-PROCESS-P is set, no commands will be added to the queue.
+Afterwards, move forward to near the next command afterwards, unless
+DONT-MOVE-FORWARD is non-nil. If FOR-NEW-COMMAND is non-nil,
+a space or newline will be inserted automatically."
+ (interactive)
+ (unless ignore-proof-process-p
+ (proof-activate-scripting nil 'advancing))
+ (or ignore-proof-process-p
+ (if (proof-locked-region-full-p)
+ (error "Locked region is full, no more commands to do!")))
+ (let ((semis))
+ (save-excursion
+ ;; CHANGE from old proof-assert-until-point: don't bother check
+ ;; for non-whitespace between locked region and point.
+ ;; CHANGE: ask proof-segment-up-to to scan until command end
+ ;; (which it used to do anyway, except in the case of a comment)
+ (setq semis (proof-segment-up-to (point) t)))
+ ;; old code:
+ ;;(if (not (re-search-backward "\\S-" (proof-unprocessed-begin) t))
+ ;; (progn (goto-char pt)
+ ;; (error "I don't know what I should be doing in this buffer!")))
+ ;; (setq semis (proof-segment-up-to (point))))
+ (if (and unclosed-comment-fun (eq 'unclosed-comment (car-safe semis)))
+ (funcall unclosed-comment-fun)
+ (if (eq 'unclosed-comment (car-safe semis))
+ (setq semis (cdr semis)))
+ (if (and (not ignore-proof-process-p) (null semis))
+ (error "I can't see any complete commands to process!"))
+ (if (nth 2 (car semis))
+ (goto-char (nth 2 (car semis))))
+ (if (not ignore-proof-process-p)
+ (let ((vanillas (proof-semis-to-vanillas (nreverse semis))))
+ (proof-extend-queue (point) vanillas)))
+ ;; This is done after the queuing to be polite: it means the
+ ;; spacing policy enforced here is not put into the locked
+ ;; region so the user can re-edit.
+ (if (not dont-move-forward)
+ (if for-new-command
+ (proof-script-new-command-advance)
+ (proof-script-next-command-advance))))))
+
+(defun proof-goto-point ()
+ "Assert or retract to the command at current position.
+Calls proof-assert-until-point or proof-retract-until-point as
+appropriate."
+ (interactive)
+ (if (<= (proof-queue-or-locked-end) (point))
+ ;; This asserts only until the next command before point and
+ ;; does nothing if whitespace between point and locked region.
+ (proof-assert-until-point)
+ (proof-retract-until-point)))
+
+
+;; insert-pbp-command - an advancing command, for use when ;;
+;; PbpHyp or Pbp has executed in LEGO, and returned a ;;
+;; command for us to run ;;
+
+(defun proof-insert-pbp-command (cmd)
+ (proof-activate-scripting)
+ (let (span)
+ (proof-goto-end-of-locked)
+ (insert cmd)
+ (setq span (make-span (proof-locked-end) (point)))
+ (set-span-property span 'type 'pbp)
+ (set-span-property span 'cmd cmd)
+ (proof-start-queue (proof-unprocessed-begin) (point)
+ (list (list span cmd 'proof-done-advancing)))))
+
+
+;; proof-retract-until-point and associated gunk ;;
+;; most of the hard work (i.e computing the commands to do ;;
+;; the retraction) is implemented in the customisation ;;
+;; module (lego.el or coq.el) which is why this looks so ;;
+;; straightforward ;;
+
+
+(defun proof-done-retracting (span)
+ "Callback for proof-retract-until-point.
+We update display after proof process has reset its state.
+See also the documentation for `proof-retract-until-point'.
+Optionally delete the region corresponding to the proof sequence.
+After an undo, we clear the proof completed flag. The rationale
+is that undoing never leaves prover in a \"proof just completed\"
+state, which is true for some proof assistants (but probably not
+others)."
+ (setq proof-shell-proof-completed nil)
+ (if (span-live-p span)
+ (let ((start (span-start span))
+ (end (span-end span))
+ (kill (span-property span 'delete-me)))
+ ;; FIXME: why is this test for an empty locked region here?
+ ;; seems it could prevent the queue and locked regions
+ ;; from being detached. Not sure where they are supposed
+ ;; to be detached from buffer, but following calls would
+ ;; do the trick if necessary.
+ (unless (proof-locked-region-empty-p)
+ (proof-set-locked-end start)
+ (proof-set-queue-end start))
+ (delete-spans start end 'type)
+ (delete-span span)
+ (if kill (kill-region start end))))
+ ;; State of scripting may have changed now
+ (run-hooks 'proof-state-change-hook))
+
+(defun proof-setup-retract-action (start end proof-command delete-region)
+ (let ((span (make-span start end)))
+ (set-span-property span 'delete-me delete-region)
+ (list (list span proof-command 'proof-done-retracting))))
+
+
+(defun proof-last-goal-or-goalsave ()
+ (save-excursion
+ (let ((span (span-at-before (proof-locked-end) 'type)))
+ (while (and span
+ (not (eq (span-property span 'type) 'goalsave))
+ (or (eq (span-property span 'type) 'proof)
+ (eq (span-property span 'type) 'comment)
+ (not (funcall proof-goal-command-p
+ (span-property span 'cmd)))))
+ (setq span (prev-span span 'type)))
+ span)))
+
+(defun proof-retract-target (target delete-region)
+ "Retract the span TARGET and delete it if DELETE-REGION is non-nil.
+Notice that this necessitates retracting any spans following TARGET,
+up to the end of the locked region."
+ (let ((end (proof-unprocessed-begin))
+ (start (span-start target))
+ (span (proof-last-goal-or-goalsave))
+ actions)
+
+
+ ;; Examine the last span in the locked region.
+
+ ;; If the last goal or save span is not a proof or
+ ;; prover processed file, we examine to see how to remove it
+ (if (and span (not (or
+ (memq (span-property span 'type)
+ '(goalsave proverproc)))))
+ ;; If the goal or goalsave span ends before the target span,
+ ;; then we are retracting within the last unclosed proof,
+ ;; and the retraction just amounts to a number of undo
+ ;; steps.
+ ;; FIXME: really, there shouldn't be more work to do: so
+ ;; why call proof-find-and-forget-fn later?
+ (if (< (span-end span) (span-end target))
+ (progn
+ ;; Skip comment spans at and immediately following target
+ (setq span target)
+ (while (and span (eq (span-property span 'type) 'comment))
+ (setq span (next-span span 'type)))
+ ;; Calculate undos for the current open segment
+ ;; of proof commands
+ (setq actions (proof-setup-retract-action
+ start end
+ (if (null span) proof-no-command
+ (funcall proof-count-undos-fn span))
+ delete-region)
+ end start))
+ ;; Otherwise, start the retraction by killing off the
+ ;; currently active goal.
+ ;; FIXME: and couldn't we move the end upwards?
+ (setq actions
+ (proof-setup-retract-action (span-start span) end
+ proof-kill-goal-command
+ delete-region)
+ end (span-start span))))
+ ;; Check the start of the target span lies before the end
+ ;; of the locked region (should always be true since we don't
+ ;; make spans outside the locked region at the moment)...
+ (if (> end start)
+ (setq actions
+ ;; Append a retract action to clear the entire
+ ;; start-end region. Rely on proof-find-and-forget-fn
+ ;; to calculate a command which "forgets" back to
+ ;; the first definition, declaration, or whatever
+ ;; that comes after the target span.
+ ;; FIXME: originally this assumed a linear context,
+ ;; and that forgetting the first thing forgets all
+ ;; subsequent ones. it might be more general to
+ ;; allow *several* commands, and even queue these
+ ;; separately for each of the spans following target
+ ;; which are concerned.
+ (nconc actions (proof-setup-retract-action
+ start end
+ (funcall proof-find-and-forget-fn target)
+ delete-region))))
+
+ (proof-start-queue (min start end) (proof-locked-end) actions)))
+
+;; FIXME da: I would rather that this function moved point to
+;; the start of the region retracted?
+
+;; FIXME da: Maybe retraction to the start of
+;; a file should remove it from the list of included files?
+;; NB: the "interactive" variant is so that we get a simple docstring.
+(defun proof-retract-until-point-interactive (&optional delete-region)
+ "Tell the proof process to retract until point.
+If invoked outside a locked region, undo the last successfully processed
+command. If called with a prefix argument (DELETE-REGION non-nil), also
+delete the retracted region from the proof-script."
+ (interactive "P")
+ (proof-retract-until-point delete-region))
+
+(defun proof-retract-until-point (&optional delete-region)
+ "Set up the proof process for retracting until point.
+In particular, set a flag for the filter process to call
+`proof-done-retracting' after the proof process has successfully
+reset its state.
+If DELETE-REGION is non-nil, delete the region in the proof script
+corresponding to the proof command sequence.
+If invoked outside a locked region, undo the last successfully processed
+command."
+ ;; Make sure we're ready
+ ;; FIXME: next step in extend regions: (proof-activate-scripting nil 'retracting)
+ (proof-activate-scripting)
+ (let ((span (span-at (point) 'type)))
+ ;; FIXME da: shouldn't this test be earlier??
+ (if (proof-locked-region-empty-p)
+ (error "No locked region"))
+ ;; FIXME da: rationalize this: it retracts the last span
+ ;; in the buffer if there was no span at point, right?
+ ;; why?
+ (and (null span)
+ (progn
+ (proof-goto-end-of-locked)
+ (backward-char)
+ (setq span (span-at (point) 'type))))
+ ;; FIXME mmw: make sure we pass by a proof body overlay (is there a better way?)
+ (and (eq (span-property span 'type) 'proof)
+ (setq span (prev-span span 'type)))
+ (proof-retract-target span delete-region)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Restarting and clearing spans
+;;
+
+(defun proof-restart-buffers (buffers)
+ "Remove all extents in BUFFERS and maybe reset `proof-script-buffer'.
+No effect on a buffer which is nil or killed. If one of the buffers
+is the current scripting buffer, then proof-script-buffer
+will deactivated."
+ (mapcar
+ (lambda (buffer)
+ (save-excursion
+ (if (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (if proof-active-buffer-fake-minor-mode
+ (setq proof-active-buffer-fake-minor-mode nil))
+ (delete-spans (point-min) (point-max) 'type) ;; remove spans
+ (setq pg-script-portions nil) ;; also the record of them
+ (proof-detach-segments buffer) ;; detach queue and locked
+ (proof-init-segmentation)))
+ (if (eq buffer proof-script-buffer)
+ (setq proof-script-buffer nil))))
+ buffers))
+
+(defun proof-script-buffers-with-spans ()
+ "Return a list of all buffers with spans.
+This is calculated by finding all the buffers with a non-nil
+value of proof-locked span."
+ (let ((bufs-left (buffer-list))
+ bufs-got)
+ (dolist (buf bufs-left bufs-got)
+ (if (with-current-buffer buf proof-locked-span)
+ (setq bufs-got (cons buf bufs-got))))))
+
+(defun proof-script-remove-all-spans-and-deactivate ()
+ "Remove all spans from scripting buffers via proof-restart-buffers."
+ (proof-restart-buffers (proof-script-buffers-with-spans)))
+
+(defun proof-script-clear-queue-spans ()
+ "If there is an active scripting buffer, remove the queue span from it.
+This is a subroutine used in proof-shell-handle-{error,interrupt}."
+ (if proof-script-buffer
+ (with-current-buffer proof-script-buffer
+ (proof-detach-queue)
+ ;; FIXME da: point-max seems a bit excessive here,
+ ;; proof-queue-or-locked-end should be enough.
+ (delete-spans (proof-locked-end) (point-max) 'type))))
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Proof General scripting mode definition, part 1.
+;;
+
+(eval-and-compile ; to define vars
+;;; NB: autoload tag below doesn't work for d-d-m, autoload is in proof.el
+;;;###autoload
+(define-derived-mode proof-mode fundamental-mode
+ proof-general-name
+ "Proof General major mode class for proof scripts.
+\\{proof-mode-map}"
+
+ (setq proof-buffer-type 'script)
+
+ ;; During write-file it can happen that we re-set the mode for
+ ;; the currently active scripting buffer. The user might also
+ ;; do this for some reason. We could maybe let
+ ;; this pass through, but it seems safest to treat it as
+ ;; a kill buffer operation (retract and clear spans).
+ ;; (NB: other situations seem to cause double successive calls to
+ ;; proof-mode).
+ (if (eq (current-buffer) proof-script-buffer)
+ (proof-script-kill-buffer-fn))
+
+ ;; We set hook functions here rather than in proof-config-done so
+ ;; that they can be adjusted by prover specific code if need be.
+ (proof-script-set-buffer-hooks)
+
+ (make-local-hook 'after-set-visited-file-name-hooks)
+ (add-hook 'after-set-visited-file-name-hooks 'proof-script-set-visited-file-name))
+
+ (make-local-hook 'proof-activate-scripting-hook)
+ (add-hook 'proof-activate-scripting-hook 'proof-cd-sync nil t))
+
+;; NB: proof-mode-map declared by define-derived-mode above
+(proof-menu-define-keys proof-mode-map)
+
+(defun proof-script-set-visited-file-name ()
+ "Called when visited file name is changed.
+
+This is a hook function for `after-set-visited-file-name-hooks'.
+
+For some provers, the file from which script commands are being
+processed may be important, and if it is changed with C-x C-w, for
+example, we might have to retract the contents or inform the proof
+assistant of the new name. This should be done by adding
+additional functions to `after-set-visited-file-name-hooks'.
+
+At the least, we need to set the buffer local hooks again
+with `proof-script-set-buffer-hooks' which is what this function does,
+as well as setting `proof-script-buffer-file-name' (which see).
+
+This hook also gives a warning in case this is the active scripting buffer."
+ (setq proof-script-buffer-file-true buffer-file-name)
+ (if (eq (current-buffer) proof-script-buffer)
+ (proof-warning
+"Active scripting buffer changed name; synchronization risked if prover tracks filenames!"))
+ (proof-script-set-buffer-hooks))
+
+
+
+(defun proof-script-set-buffer-hooks ()
+ "Set the hooks for a proof script buffer.
+The hooks set here are cleared by write-file, so we use this function
+to restore them using `after-set-visited-file-name-hooks'."
+ (make-local-hook 'kill-buffer-hook)
+ (add-hook 'kill-buffer-hook 'proof-script-kill-buffer-fn t t)
+ ;; Reverting buffer is same as killing it as far as PG is concerned
+ (make-local-hook 'before-revert-hook)
+ (add-hook 'before-revert-hook 'proof-script-kill-buffer-fn t t))
+
+(defun proof-script-kill-buffer-fn ()
+ "Value of kill-buffer-hook for proof script buffers.
+Clean up before a script buffer is killed.
+If killing the active scripting buffer, run proof-deactivate-scripting.
+Otherwise just do proof-restart-buffers to delete some spans from memory."
+ ;; Deactivate scripting in the current buffer if need be, forcing
+ ;; automatic retraction if the buffer is not fully processed.
+ (unwind-protect
+ (if (eq (current-buffer) proof-script-buffer)
+ (proof-deactivate-scripting 'retract))
+ (proof-restart-buffers (list (current-buffer)))
+ ;; Hide away goals, response, and tracing. This is a hack because
+ ;; otherwise we can lead the user to frustration with the
+ ;; dedicated windows nonsense.
+ (proof-map-buffers
+ (list proof-goals-buffer proof-response-buffer proof-trace-buffer)
+ (bury-buffer (current-buffer)))))
+
+
+;; Notes about how to deal with killing/reverting/renaming buffers:
+;; (As of XEmacs 21.1.9, see files.el)
+;;
+;; Killing: easy, set kill-buffer-hook
+;; Reverting: ditto, set before-revert-hook to do same as kill.
+;; Renaming (write-file): much tricker. Code for write-file does
+;; several odd things. It kills off local hook functions, calls
+;; `after-set-visited-file-name-hooks' right at the end to give the
+;; chance to restore them, but then tends to automatically (re-)set
+;; the mode anyway.
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Proof General scripting mode definition - part 2
+;;
+
+;; The functions proof-config-done[-related] are called after the
+;; derived mode has made its settings.
+
+;; The callback *-config-done mechanism is an irritating hack - there
+;; should be some elegant mechanism for computing constants after the
+;; child has configured. Should petition the author of "derived-mode"
+;; about this!
+
+(defun proof-config-done-related ()
+ "Finish setup of Proof General scripting and related modes.
+This is a subroutine of proof-config-done.
+
+This is intended for proof assistant buffers which are similar to
+script buffers, but for which scripting is not enabled. In
+particular, we: lock the buffer if it appears on
+proof-included-files-list; configure font-lock support from
+font-lock-keywords; maybe turn on X-Symbol minor mode.
+
+This is used for Isabelle theory files, which share some scripting
+mode features, but are only ever processed atomically by the proof
+assistant."
+ (setq proof-script-buffer-file-name buffer-file-name)
+
+ ;; Has buffer already been processed?
+ ;; NB: call to file-truename is needed for FSF Emacs which
+ ;; chooses to make buffer-file-truename abbreviate-file-name
+ ;; form of file-truename.
+ (and buffer-file-truename
+ (member (file-truename buffer-file-truename)
+ proof-included-files-list)
+ (proof-complete-buffer-atomic (current-buffer)))
+
+ ;; calculate some strings and regexps for searching
+ (setq proof-terminal-string
+ (if proof-terminal-char
+ (char-to-string proof-terminal-char)
+ ""))
+
+ (make-local-variable 'comment-start)
+ (setq comment-start (concat proof-comment-start " "))
+ (make-local-variable 'comment-end)
+ (setq comment-end (concat " " proof-comment-end))
+
+ (unless proof-comment-start-regexp
+ (setq proof-comment-start-regexp (regexp-quote proof-comment-start)))
+ (unless proof-comment-end-regexp
+ (setq proof-comment-end-regexp (regexp-quote proof-comment-end)))
+
+ (make-local-variable 'comment-start-skip)
+ (setq comment-start-skip
+ (concat proof-comment-start-regexp "+\\s_?"))
+
+ ;;
+ ;; Fontlock support.
+ ;;
+ ;; Assume font-lock case folding follows proof-case-fold-search
+ (proof-font-lock-configure-defaults 'autofontify proof-case-fold-search)
+
+ ;; Hack for unfontifying commas (yuck)
+ (remove-hook 'font-lock-after-fontify-buffer-hook 'proof-zap-commas-buffer t)
+ (remove-hook 'font-lock-mode-hook 'proof-unfontify-separator t)
+ (if proof-font-lock-zap-commas
+ (progn
+ (add-hook 'font-lock-after-fontify-buffer-hook
+ 'proof-zap-commas-buffer nil t)
+ (add-hook 'font-lock-mode-hook 'proof-unfontify-separator
+ nil t)
+ ;; if we don't have the following in XEmacs, zap-commas fails.
+ (if (boundp 'font-lock-always-fontify-immediately)
+ (progn
+ (make-local-variable 'font-lock-always-fontify-immediately)
+ ;; FIXME da: this is pretty nasty. Disables use of
+ ;; lazy/caching font lock for large files, and they
+ ;; can take a long time to fontify.
+ (setq font-lock-always-fontify-immediately t)))))
+
+ ;; Maybe turn on x-symbol mode.
+ (proof-x-symbol-mode))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Generic defaults for hooks, based on regexps.
+;;
+;; NEW November 1999.
+;; Added to PG 3.0 but only used for demoisa so far.
+;;
+
+;;
+;; FIXME: the next step is to use proof-stringfn-match scheme more
+;; widely, to allow settings which are string or fn, so we don't need
+;; both regexp and function hooks, and so that the other hooks can be
+;; functions too.
+;;
+
+(defun proof-generic-goal-command-p (str)
+ "Is STR a goal? Decide by matching with proof-goal-command-regexp."
+ (proof-string-match-safe proof-goal-command-regexp str))
+
+(defun proof-generic-state-preserving-p (cmd)
+ "Is CMD state preserving? Match on proof-non-undoables-regexp."
+ (not (proof-string-match-safe proof-non-undoables-regexp cmd)))
+
+(defun proof-generic-count-undos (span)
+ "Count number of undos in a span, return command needed to undo that far.
+Command is set using `proof-undo-n-times-cmd'.
+
+A default value for `proof-count-undos-fn'.
+
+For this function to work properly, you must configure
+`proof-undo-n-times-cmd' and `proof-ignore-for-undo-count'."
+ (let
+ ((case-fold-search proof-case-fold-search)
+ (ct 0) str i)
+ (while span
+ (setq str (span-property span 'cmd))
+ (cond ((eq (span-property span 'type) 'vanilla)
+ (unless (proof-stringfn-match proof-ignore-for-undo-count str)
+ (incf ct)))
+ ((eq (span-property span 'type) 'pbp)
+ (setq i 0)
+ (while (< i (length str))
+ (if (= (aref str i) proof-terminal-char) (incf ct))
+ (incf i))))
+ (setq span (next-span span 'type)))
+ (if (= ct 0)
+ proof-no-command
+ (cond ((stringp proof-undo-n-times-cmd)
+ (format proof-undo-n-times-cmd ct))
+ ((functionp proof-undo-n-times-cmd)
+ (funcall proof-undo-n-times-cmd ct))))))
+
+(defun proof-generic-find-and-forget (span)
+ "Calculate a forget/undo command to forget back to SPAN.
+This is a long-range forget: we know that there is no
+open goal at the moment, so forgetting involves unbinding
+declarations, etc, rather than undoing proof steps.
+
+Currently this has a trivial implementation: it
+just returns proof-no-command, meaning `do nothing'.
+
+Check the lego-find-and-forget or coq-find-and-forget
+functions for examples of how to write this function."
+ ;; FIXME: implement a useful generic find-and-forget
+ proof-no-command)
+
+;;
+;; End of new generic functions
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;;
+;; Sanity checks on important settings
+;;
+
+(defconst proof-script-important-settings
+ '(proof-comment-start ;
+ proof-comment-end
+ ; proof-goal-command-regexp not needed if proof-goal-command-p is set
+ proof-save-command-regexp
+; proof-goal-with-hole-regexp ; non-essential?
+; proof-save-with-hole-regexp ; non-essential?
+ proof-showproof-command ; non-essential?
+ proof-goal-command ; non-essential
+ proof-save-command ; do
+ proof-kill-goal-command ; do
+ ))
+
+(defun proof-config-done ()
+ "Finish setup of Proof General scripting mode.
+Call this function in the derived mode for the proof assistant to
+finish setup which depends on specific proof assistant configuration."
+
+ (proof-config-done-related)
+
+ ;; Following group of settings only relevant if the current
+ ;; buffer is really a scripting buffer. Isabelle Proof General
+ ;; has theory file buffers which share some aspects, they
+ ;; just use proof-config-done-related.
+
+ ;; Preamble: make this mode class "pg-sticky" so that renaming file
+ ;; to something different doesn't change the mode, no matter what
+ ;; the filename. This is a hack so that write-file will work:
+ ;; otherwise Emacs insists (as of XEmacs 21.1.9 at least) on
+ ;; re-setting the mode, which leads to problems with synchronization
+ ;; and losing extents. (Attempt to catch this in proof-mode by
+ ;; looking for active scripting buffer fails; perhaps because of
+ ;; kill buffer function)
+ (put major-mode 'mode-class 'pg-sticky)
+
+ ;; First, define some values if they aren't defined already.
+ (unless proof-mode-for-script
+ (setq proof-mode-for-script major-mode))
+
+ (if (and proof-non-undoables-regexp
+ (not proof-ignore-for-undo-count))
+ (setq proof-ignore-for-undo-count
+ proof-non-undoables-regexp))
+
+ ;; Give warnings if some crucial settings haven't been made
+ (dolist (sym proof-script-important-settings)
+ (proof-warn-if-unset "proof-config-done" sym))
+
+ ;; Additional key definitions which depend on configuration for
+ ;; specific proof assistant.
+ ;; FIXME da: generalize here. Might have electric terminator for
+ ;; other parsing mechanisms too, using new proof-script-parse-function
+ ;; Could use a default terminal char
+ (if proof-terminal-char
+ (progn
+ (define-key proof-mode-map
+ (vconcat [(control c)] (vector proof-terminal-char))
+ 'proof-electric-terminator-toggle)
+ (define-key proof-mode-map (vector proof-terminal-char)
+ 'proof-electric-terminator)))
+ ;; It's ugly, but every script buffer has a local copy changed in
+ ;; sync by the fn proof-electric-terminator-enable
+ (setq proof-electric-terminator proof-electric-terminator-enable)
+
+ (make-local-variable 'indent-line-function)
+ (setq indent-line-function 'proof-indent-line)
+
+ ;; Toolbar and scripting menu
+ ;; NB: autloads proof-toolbar, which defines proof-toolbar-scripting-menu.
+ (proof-toolbar-setup)
+
+ ;; Menus: the Proof-General and the specific menu
+ (proof-menu-define-main)
+ (proof-menu-define-specific)
+ (easy-menu-add proof-mode-menu proof-mode-map)
+ (easy-menu-add proof-assistant-menu proof-mode-map)
+
+ ;; Choose parsing mechanism according to different kinds of script syntax.
+ ;; Choice of function depends on configuration setting.
+ (unless (fboundp 'proof-segment-up-to)
+ (if (or proof-script-use-new-parser
+ proof-script-sexp-commands)
+ ;; 3.3 mechanism here
+ (progn
+ (defalias 'proof-segment-up-to 'proof-segment-up-to-parser)
+ (cond
+ (proof-script-parse-function
+ ;; already set, nothing to do
+ )
+ (proof-script-sexp-commands
+ (setq proof-script-parse-function 'proof-script-generic-parse-sexp))
+ (proof-script-command-start-regexp
+ (setq proof-script-parse-function 'proof-script-generic-parse-cmdstart))
+ ((or proof-script-command-end-regexp proof-terminal-char)
+ (setq proof-script-parse-function 'proof-script-generic-parse-cmdend)
+ (unless proof-script-command-end-regexp
+ (proof-warn-if-unset "proof-config-done" 'proof-terminal-char)
+ (setq proof-script-command-end-regexp
+ (if proof-terminal-char
+ (regexp-quote (char-to-string proof-terminal-char))
+ "$"))))
+ (t
+ (error "Configuration error: must set `proof-terminal-char' or one of its friends."))))
+ (cond
+ (proof-script-parse-function ;; still allowed to override in 3.2
+ (defalias 'proof-segment-up-to 'proof-segment-up-to-parser))
+ ;; 3.2 mechanism here
+ (proof-script-command-start-regexp
+ (defalias 'proof-segment-up-to 'proof-segment-up-to-cmdstart))
+ (t
+ (defalias 'proof-segment-up-to 'proof-segment-up-to-cmdend)
+ (unless proof-script-command-end-regexp
+ (proof-warn-if-unset "proof-config-done" 'proof-terminal-char)
+ (setq proof-script-command-end-regexp
+ (if proof-terminal-char
+ (regexp-quote (char-to-string proof-terminal-char))
+ "$"))))))) ; default if nothing set is EOL.
+
+ ;; Make sure func menu is configured. (NB: Ideal place for this and
+ ;; similar stuff would be in something evaluated at top level after
+ ;; defining the derived mode: normally we wouldn't repeat this
+ ;; each time the mode function is run, so we wouldn't need "pushnew").
+
+ (cond ((proof-try-require 'func-menu)
+ ;; FIXME: we'd like to let the library load later, but
+ ;; it's a bit tricky: this stuff doesn't seem to work
+ ;; in an eval-after-load body (local vars?).
+ (unless proof-script-next-entity-regexps ; unless already set
+ ;; Try to calculate a useful default value.
+ ;; FIXME: this is rather complicated! The use of the regexp
+ ;; variables needs sorting out.
+ (customize-set-variable
+ 'proof-script-next-entity-regexps
+ (let ((goal-discrim
+ ;; Goal discriminator searches forward for matching
+ ;; save if the regexp is set.
+ (if proof-goal-with-hole-regexp
+ (if proof-save-command-regexp
+ (list
+ proof-goal-with-hole-regexp 2
+ 'forward proof-save-command-regexp)
+ (list proof-goal-with-hole-regexp 2))))
+ ;; Save discriminator searches backward for matching
+ ;; goal if the regexp is set.
+ (save-discrim
+ (if proof-save-with-hole-regexp
+ (if proof-goal-command-regexp
+ (list
+ proof-save-with-hole-regexp 2
+ 'backward proof-goal-command-regexp)
+ (list proof-save-with-hole-regexp 2)))))
+ (cond
+ ((and proof-goal-with-hole-regexp proof-save-with-hole-regexp)
+ (list
+ (proof-regexp-alt
+ proof-goal-with-hole-regexp
+ proof-save-with-hole-regexp) goal-discrim save-discrim))
+
+ (proof-goal-with-hole-regexp
+ (list proof-goal-with-hole-regexp goal-discrim))
+
+ (proof-save-with-hole-regexp
+ (list proof-save-with-hole-regexp save-discrim))))))
+
+ (if proof-script-next-entity-regexps
+ ;; Enable func-menu for this mode if regexps set now
+ (progn
+ (pushnew
+ (cons major-mode 'proof-script-next-entity-regexps)
+ fume-function-name-regexp-alist)
+ (pushnew
+ (cons major-mode proof-script-find-next-entity-fn)
+ fume-find-function-name-method-alist)))))
+
+ ;; Offer to save script mode buffers which have no files,
+ ;; in case Emacs is exited accidently.
+ (or (buffer-file-name)
+ (setq buffer-offer-save t))
+
+ ;; To begin with, make everything visible in the buffer
+ ;; (FIXME: this is done via proof-init-segmentation, now,
+ ;; when is that called?)
+ (setq buffer-invisibility-spec nil)
+
+ ;; Finally, make sure the user has been welcomed!
+ ;; FIXME: this doesn't work well, it gets zapped by loading messages.
+ (proof-splash-message))
+
+
+(provide 'proof-script)
+;; proof-script.el ends here.
+
diff --git a/generic/proof-shell.el b/generic/proof-shell.el
new file mode 100644
index 00000000..4e1948de
--- /dev/null
+++ b/generic/proof-shell.el
@@ -0,0 +1,2255 @@
+;; proof-shell.el Proof General shell mode.
+;;
+;; Copyright (C) 1994-2001 LFCS Edinburgh.
+;; Authors: David Aspinall, Yves Bertot, Healfdene Goguen,
+;; Thomas Kleymann and Dilip Sequeira
+;;
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+
+(require 'proof-menu)
+
+;; Nuke some byte compiler warnings.
+
+(eval-when-compile
+ (require 'comint)
+ (require 'font-lock))
+
+;; Spans are our abstraction of extents/overlays.
+(eval-and-compile
+ (cond ((fboundp 'make-extent) (require 'span-extent))
+ ((fboundp 'make-overlay) (require 'span-overlay))))
+
+;; FIXME:
+;; Autoloads for proof-script (added to nuke warnings,
+;; maybe should be 'official' exported functions in proof.el)
+;; This helps see interface between proof-script / proof-shell.
+;; FIXME 2: We can probably assume that proof-script is always
+;; loaded before proof-shell, so just put a require on
+;; proof-script here.
+(eval-and-compile
+ (mapcar (lambda (f)
+ (autoload f "proof-script"))
+ '(proof-goto-end-of-locked
+ proof-insert-pbp-command
+ proof-detach-queue
+ proof-locked-end
+ proof-set-queue-endpoints
+ proof-script-clear-queue-spans
+ proof-file-to-buffer
+ proof-register-possibly-new-processed-file
+ proof-restart-buffers)))
+
+;; FIXME:
+;; Some variables from proof-shell are also used, in particular,
+;; the menus. These should probably be moved out to proof-menu.
+
+;; ============================================================
+;;
+;; Internal variables used by proof shell
+;;
+
+(defvar proof-marker nil
+ "Marker in proof shell buffer pointing to previous command input.")
+
+(defvar proof-action-list nil
+ "A list of
+
+ (SPAN COMMAND ACTION)
+
+triples, which is a queue of things to do.
+See the functions `proof-start-queue' and `proof-exec-loop'.")
+
+(defvar proof-shell-silent nil
+ "A flag, non-nil if PG thinks the prover is silent.")
+
+
+;;
+;; Implementing the process lock
+;;
+;; da: In fact, there is little need for a lock. Since Emacs Lisp
+;; code is single-threaded, a loop parsing process output cannot get
+;; pre-empted by the user trying to send more input to the process,
+;; or by the process filter trying to deal with more output.
+;; (Moreover, we can tell when the process is busy because the
+;; queue is non-empty).
+;;
+;;
+
+;;
+;; We have two functions:
+;;
+;; proof-shell-ready-prover
+;; starts proof shell, gives error if it's busy.
+;;
+;; proof-activate-scripting (in proof-script.el)
+;; calls proof-shell-ready-prover, and turns on scripting minor
+;; mode for current (scripting) buffer.
+;;
+;; Also, a new enabler predicate:
+;;
+;; proof-shell-available
+;; returns non-nil if a proof shell is active and not locked.
+;;
+;; Maybe proof-shell-ready-prover doesn't need to start the shell?
+;;
+
+;;;###autoload
+(defun proof-shell-ready-prover (&optional queuemode)
+ "Make sure the proof assistant is ready for a command.
+If QUEUEMODE is set, succeed if the proof shell is busy but
+has mode QUEUEMODE.
+Otherwise, if the shell is busy, give an error.
+No change to current buffer or point."
+ (proof-shell-start)
+ (unless (or (not proof-shell-busy) (eq queuemode proof-shell-busy))
+ (error "Proof Process Busy!")))
+
+;;;###autoload
+(defun proof-shell-live-buffer ()
+ "Return buffer of active proof assistant, or nil if none running."
+ (and proof-shell-buffer
+ (buffer-live-p proof-shell-buffer)
+ (comint-check-proc proof-shell-buffer)))
+
+;;;###autoload
+(defun proof-shell-available-p ()
+ "Returns non-nil if there is a proof shell active and available.
+No error messages. Useful as menu or toolbar enabler."
+ (and (proof-shell-live-buffer)
+ (not proof-shell-busy)))
+
+(defun proof-grab-lock (&optional queuemode)
+ "Grab the proof shell lock, starting the proof assistant if need be.
+Runs proof-state-change-hook to notify state change.
+Clears the proof-shell-error-or-interrupt-seen flag.
+If QUEUEMODE is supplied, set the lock to that value."
+ (proof-shell-ready-prover queuemode)
+ (setq proof-shell-error-or-interrupt-seen nil)
+ (setq proof-shell-busy (or queuemode t))
+ (run-hooks 'proof-state-change-hook))
+
+(defun proof-release-lock (&optional err-or-int)
+ "Release the proof shell lock, with error or interrupt flag ERR-OR-INT.
+Clear proof-shell-busy, and set proof-shell-error-or-interrupt-seen
+to err-or-int."
+ (setq proof-shell-error-or-interrupt-seen err-or-int)
+ (setq proof-shell-busy nil))
+
+
+
+;;
+;; Starting and stopping the proof shell
+;;
+
+(defun proof-shell-start ()
+ "Initialise a shell-like buffer for a proof assistant.
+
+Also generates goal and response buffers.
+Does nothing if proof assistant is already running."
+ (interactive)
+ (unless (proof-shell-live-buffer)
+
+ ;; This should configure the mode-setting variables
+ ;; proof-mode-for-<blah> so we can set the modes below.
+ ;; <blah>=shell,goals,response. We also need to set
+ ;; proof-prog-name to start the program!
+ (run-hooks 'proof-pre-shell-start-hook)
+
+ ;; Clear some state [ fixme: should clear more? ]
+ (setq proof-included-files-list nil)
+
+ ;; Added 05/99 by Patrick L.
+ (let ((name (buffer-file-name (current-buffer))))
+ ;; FIXME : we check that the buffer corresponds to a file,
+ ;; but we do not check that it is in coq- or isa-mode
+ (if (and name proof-prog-name-guess proof-guess-command-line)
+ (setq proof-prog-name
+ (apply proof-guess-command-line (list name)))))
+
+ (if proof-prog-name-ask
+ (save-excursion
+ (setq proof-prog-name (read-shell-command "Run process: "
+ proof-prog-name))))
+ (let
+ ;; PG 3.1: Buffer names are now based simply on proof assistant
+ ;; name, not process name which was a bit lowlevel and sometimes
+ ;; ugly (coqtop, hol.unquote).
+ ((proc (downcase proof-assistant)))
+
+ (message "Starting process: %s" proof-prog-name)
+
+ ;; Starting the inferior process (asynchronous)
+ (let ((prog-name-list
+ (proof-string-to-list
+ ;; Cut in proof-rsh-command if it's non-nil and
+ ;; non whitespace. FIXME: whitespace at start
+ ;; of this string is nasty.
+ (if (and proof-rsh-command
+ (not (string-match "^[ \t]*$" proof-rsh-command)))
+ (concat proof-rsh-command " " proof-prog-name)
+ proof-prog-name)
+ ;; Split on spaces: FIXME: maybe should be whitespace.
+ " "))
+
+ (process-connection-type
+ proof-shell-process-connection-type))
+
+ ;; An improvement here might be to catch failure of
+ ;; make-comint and then kill off the buffer. Then we
+ ;; could add back code above for multiple shells <2> <3>, etc.
+ ;; Seems hardly worth it.
+ (apply 'make-comint (append (list proc (car prog-name-list) nil)
+ (cdr prog-name-list))))
+
+ (setq proof-shell-buffer (get-buffer (concat "*" proc "*")))
+
+ (unless (proof-shell-live-buffer)
+ ;; Give error now if shell buffer isn't live
+ ;; Solves problem of make-comint succeeding but process
+ ;; exiting immediately.
+ ;; Might still be problems here if sentinels are set.
+ (setq proof-shell-buffer nil)
+ (error "Starting process: %s..failed" proof-prog-name))
+
+ ;; Create the associated buffers and set buffer variables
+ (let ((goals (concat "*" proc "-goals*"))
+ (resp (concat "*" proc "-response*"))
+ (trace (concat "*" proc "-trace*")))
+
+ (setq proof-goals-buffer (get-buffer-create goals))
+ (setq proof-response-buffer (get-buffer-create resp))
+ ;; Only make a trace buffer if the prover may use it.
+ (if proof-shell-trace-output-regexp
+ (setq proof-trace-buffer (get-buffer-create trace)))
+
+ ;; Set the special-display-regexps now we have the buffer names
+ (setq proof-shell-special-display-regexp
+ (proof-regexp-alt goals resp trace))
+ (proof-multiple-frames-enable))
+
+ (save-excursion
+ (set-buffer proof-shell-buffer)
+
+ ;; PG 3.4: clear output from previous sessions.
+ (erase-buffer)
+
+ ;; Disable multi-byte characters in GNU Emacs.
+ ;; We noticed that for LEGO, it otherwise converts annotations
+ ;; to characters with (non-ASCII) code around 3000 which screws
+ ;; up our conventions that annotations lie between 128 and 256.
+ ;;
+ (and (fboundp 'toggle-enable-multibyte-characters)
+ (toggle-enable-multibyte-characters -1))
+
+ ;; Initialise shell mode
+ ;; Q: should this be done every time the process is started?
+ ;; A: yes, it does the process initialization, which is a bit
+ ;; odd (would expect it to be done here, maybe).
+ (funcall proof-mode-for-shell)
+
+ ;; Check to see that the process is still going.
+ ;; Otherwise the sentinel will have killed off the
+ ;; other buffers and there's no point initialising
+ ;; them.
+ (if (proof-shell-live-buffer)
+ (progn
+ ;; Set mode for response buffer
+ (set-buffer proof-response-buffer)
+ (funcall proof-mode-for-response)
+ ;; Set mode for trace buffer
+ (proof-with-current-buffer-if-exists proof-trace-buffer
+ (funcall proof-mode-for-response))
+ ;; Set mode for goals buffer
+ (set-buffer proof-goals-buffer)
+ (and (fboundp 'toggle-enable-multibyte-characters)
+ (toggle-enable-multibyte-characters -1))
+ (funcall proof-mode-for-goals))
+ ;;
+ ;; If the process died, switch to the buffer to
+ ;; display the error messages to the user.
+ (switch-to-buffer proof-shell-buffer)
+ (error "%s process exited!" proc)))
+
+ (message "Starting %s process... done." proc))))
+
+
+;;
+;; Indicator and fake minor mode for active scripting buffer
+;;
+
+(defcustom proof-shell-active-scripting-indicator
+ (if proof-running-on-XEmacs
+ (cons (make-extent nil nil) " Scripting ")
+ " Scripting")
+ "Modeline indicator for active scripting buffer.
+If first component is extent it will automatically follow the colour
+of the queue region."
+ :type 'sexp
+ :group 'proof-general-internals)
+
+(cond
+ (proof-running-on-XEmacs
+ (if (extentp (car proof-shell-active-scripting-indicator))
+ (set-extent-properties
+ (car proof-shell-active-scripting-indicator)
+ '(face proof-locked-face)))))
+
+(unless
+ (assq 'proof-active-buffer-fake-minor-mode minor-mode-alist)
+ (setq minor-mode-alist
+ (append minor-mode-alist
+ (list
+ (list
+ 'proof-active-buffer-fake-minor-mode
+ proof-shell-active-scripting-indicator)))))
+
+
+;;
+;; Shutting down proof shell and associated buffers
+;;
+
+;; Hooks here are handy for liaising with prover config stuff.
+
+(defvar proof-shell-kill-function-hooks nil
+ "Functions run from proof-shell-kill-function.")
+
+(defun proof-shell-kill-function ()
+ "Function run when a proof-shell buffer is killed.
+Attempt to shut down the proof process nicely and
+clear up all the locked regions and state variables.
+Value for kill-buffer-hook in shell buffer.
+Also called by proof-shell-bail-out if the process is
+exited by hand (or exits by itself)."
+ (let* ((alive (comint-check-proc (current-buffer)))
+ (proc (get-buffer-process (current-buffer)))
+ (bufname (buffer-name)))
+ (message "%s, cleaning up and exiting..." bufname)
+ (let ((inhibit-quit t) ; disable C-g for now
+ timeout-id)
+ (sit-for 0) ; redisplay
+ (if alive ; process still there
+ (progn
+ (catch 'exited
+ (set-process-sentinel proc
+ (lambda (p m) (throw 'exited t)))
+ ;; Try to shut it down politely
+ ;; Do this before deleting other buffers, etc, so that
+ ;; any closing down processing works okay.
+ (if proof-shell-quit-cmd
+ (comint-send-string proc
+ (concat proof-shell-quit-cmd "\n"))
+ (comint-send-eof))
+ ;; Wait a while for it to die before killing
+ ;; it off more rudely. In XEmacs, accept-process-output
+ ;; or sit-for will run process sentinels if a process
+ ;; changes state.
+ ;; In FSF I've no idea how to get the process sentinel
+ ;; to run outside the top-level loop.
+ ;; So put an ugly timeout and busy wait here instead
+ ;; of simply (accept-process-output nil 10).
+ (setq timeout-id
+ (add-timeout
+ proof-shell-quit-timeout
+ (lambda (&rest args)
+ (if (comint-check-proc (current-buffer))
+ (kill-process (get-buffer-process
+ (current-buffer))))
+ (throw 'exited t)) nil))
+ (while (comint-check-proc (current-buffer))
+ ;; Perhaps XEmacs hangs too, lets try both wait forms.
+ (accept-process-output nil 1)
+ (sit-for 1)))
+ ;; Disable timeout and sentinel in case one or
+ ;; other hasn't signalled yet, but we're here anyway.
+ (disable-timeout timeout-id)
+ ;; FIXME: this was added to fix 'No catch for exited tag'
+ ;; problem, but it's done later below anyway?
+ (set-process-sentinel proc nil)))
+ (if (comint-check-proc (current-buffer))
+ (proof-debug
+ "Error in proof-shell-kill-function: process still lives!"))
+ ;; For FSF Emacs, proc may be nil if killed already.
+ (if proc (set-process-sentinel proc nil))
+ ;; Restart all scripting buffers
+ (proof-script-remove-all-spans-and-deactivate)
+ ;; Clear state
+ (proof-shell-clear-state)
+ ;; Run hooks
+ (run-hooks 'proof-shell-kill-function-hooks)
+ ;; Kill buffers associated with shell buffer
+ (dolist
+ (buf '(proof-goals-buffer
+ proof-response-buffer
+ proof-trace-buffer))
+ (if (buffer-live-p (eval buf))
+ (progn
+ (kill-buffer (eval buf))
+ (set buf nil))))
+ (message "%s exited." bufname))))
+
+(defun proof-shell-clear-state ()
+ "Clear internal state of proof shell."
+ (setq proof-action-list nil
+ proof-included-files-list nil
+ proof-shell-busy nil
+ proof-shell-proof-completed nil
+ proof-shell-error-or-interrupt-seen nil
+ proof-shell-silent nil
+ proof-shell-last-output nil
+ proof-shell-last-output-kind nil
+ proof-shell-delayed-output nil
+ proof-shell-delayed-output-kind nil))
+
+(defun proof-shell-exit ()
+ "Query the user and exit the proof process.
+
+This simply kills the proof-shell-buffer relying on the hook function
+proof-shell-kill-function to do the hard work."
+ (interactive)
+ (if (buffer-live-p proof-shell-buffer)
+ (if (yes-or-no-p (format "Exit %s process? " proof-assistant))
+ (progn (kill-buffer proof-shell-buffer)
+ (setq proof-shell-buffer nil))
+ (error "No proof shell buffer to kill!"))))
+
+(defun proof-shell-bail-out (process event)
+ "Value for the process sentinel for the proof assistant process.
+If the proof assistant dies, run proof-shell-kill-function to
+cleanup and remove the associated buffers. The shell buffer is
+left around so the user may discover what killed the process."
+ (message "Process %s %s, shutting down scripting..." process event)
+ (proof-shell-kill-function)
+ (message "Process %s %s, shutting down scripting...done." process event))
+
+(defun proof-shell-restart ()
+ "Clear script buffers and send proof-shell-restart-cmd.
+All locked regions are cleared and the active scripting buffer
+deactivated.
+
+If the proof shell is busy, an interrupt is sent with
+proof-interrupt-process and we wait until the process is ready.
+
+The restart command should re-synchronize Proof General with the proof
+assistant, without actually exiting and restarting the proof assistant
+process.
+
+It is up to the proof assistant how much context is cleared: for
+example, theories already loaded may be \"cached\" in some way,
+so that loading them the next time round only performs a re-linking
+operation, not full re-processing. (One way of caching is via
+object files, used by Lego and Coq)."
+ (interactive)
+ (if proof-shell-busy
+ (progn
+ (proof-interrupt-process)
+ (proof-shell-wait)))
+ (if (not (proof-shell-live-buffer))
+ ;; If shell not running, start one now.
+ ;; (Behaviour suggested by Robert Schneck)
+ (proof-shell-start)
+ ;; Otherwise, clear all context for running prover
+ (proof-script-remove-all-spans-and-deactivate)
+ (proof-shell-clear-state)
+ (if (and (buffer-live-p proof-shell-buffer)
+ proof-shell-restart-cmd)
+ (proof-shell-invisible-command
+ proof-shell-restart-cmd))))
+
+
+
+
+
+;;
+;; PROOF BY POINTING
+;;
+;; Fairly specific to the mechanism implemented in LEGO
+;; To make sense of this code, you should read the
+;; relevant LFCS tech report by tms, yb, and djs
+
+;; New function added for 3.0 -da
+(defun pbp-yank-subterm (event)
+ "Copy the subterm indicated by the mouse-click EVENT.
+This function should be bound to a mouse button in the Proof General
+goals buffer.
+
+The EVENT is used to find the smallest subterm around a point. The
+subterm is copied to the kill-ring, and immediately yanked (copied)
+into the current buffer at the current cursor position.
+
+In case the current buffer is the goals buffer itself, the yank
+is not performed. Then the subterm can be retrieved later by an
+explicit yank."
+ (interactive "e")
+ (let (span)
+ (save-window-excursion
+ (save-excursion
+ (mouse-set-point event)
+ ;; Get either the proof body or whole goalsave
+ (setq span (or
+ (span-at (point) 'proof)
+ (span-at (point) 'goalsave)))
+ (if span (copy-region-as-kill
+ (span-start span)
+ (span-end span)))))
+ (if (and span (not (eq proof-buffer-type 'pbp)))
+ (yank))))
+
+(defun pbp-button-action (event)
+ "Construct a proof-by-pointing command based on the mouse-click EVENT.
+This function should be bound to a mouse button in the Proof General
+goals buffer.
+
+The EVENT is used to find the smallest subterm around a point. A
+position code for the subterm is sent to the proof assistant, to ask
+it to construct an appropriate proof command. The command which is
+constructed will be inserted at the end of the locked region in the
+proof script buffer, and immediately sent back to the proof assistant.
+If it succeeds, the locked region will be extended to cover the
+proof-by-pointing command, just as for any proof command the
+user types by hand."
+ (interactive "e")
+ (mouse-set-point event)
+ (pbp-construct-command))
+
+; Using the spans in a mouse behavior is quite simple: from the
+; mouse position, find the relevant span, then get its annotation
+; and produce a piece of text that will be inserted in the right
+; buffer.
+
+(defun proof-expand-path (string)
+ (let ((a 0) (l (length string)) ls)
+ (while (< a l)
+ (setq ls (cons (int-to-string
+ ;; FIXME: FSF doesn't have char-to-int.
+ (char-to-int (aref string a)))
+ (cons " " ls)))
+ (incf a))
+ (apply 'concat (nreverse ls))))
+
+(defun pbp-construct-command ()
+ (let* ((span (span-at (point) 'goalsave))
+ (top-span (span-at (point) 'proof-top-element))
+ top-info)
+ (if (null top-span) ()
+ (setq top-info (span-property top-span 'proof-top-element))
+ (pop-to-buffer proof-script-buffer)
+ (cond
+ (span
+ (proof-shell-invisible-command
+ (format (if (eq 'hyp (car top-info)) pbp-hyp-command
+ pbp-goal-command)
+ (concat (cdr top-info) (proof-expand-path
+ (span-property span 'goalsave))))))
+ ((eq (car top-info) 'hyp)
+ (proof-shell-invisible-command
+ (format pbp-hyp-command (cdr top-info))))
+ (t
+ (proof-insert-pbp-command
+ (format pbp-change-goal (cdr top-info))))))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Turning annotated output into pbp goal set ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun pbp-make-top-span (start end)
+ (let (span name)
+ (goto-char start)
+ (setq name (funcall proof-goal-hyp-fn))
+ (beginning-of-line)
+ (setq start (point))
+ (goto-char end)
+ (beginning-of-line)
+ (backward-char)
+ (setq span (make-span start (point)))
+ (set-span-property span 'mouse-face 'highlight)
+ (set-span-property span 'proof-top-element name)))
+
+;; Need this for processing error strings and so forth
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Processing output from the prover
+;;
+
+;; We keep a record of the last output from the proof system and a
+;; flag indicating its type, as well as a previous ("delayed") to use
+;; when the end of the queue is reached or an error or interrupt
+;; occurs.
+
+;; A raw record of the last output from the proof system
+(defvar proof-shell-last-output nil
+ "A record of the last string seen from the proof system.")
+
+;; A flag indicating the type of thing proof-shell-last-output
+(defvar proof-shell-last-output-kind nil
+ "A symbol denoting the type of the last output string from the proof system.
+Specifically:
+
+ 'interrupt An interrupt message
+ 'error An error message
+ 'abort A proof abort message
+ 'loopback A command sent from the PA to be inserted into the script
+ 'response A response message
+ 'goals A goals (proof state) display
+ 'systemspecific Something specific to a particular system,
+ -- see `proof-shell-process-output-system-specific'
+
+The output corresponding to this will be in proof-shell-last-output.
+
+See also `proof-shell-proof-completed' for further information about
+the proof process output, when ends of proofs are spotted.
+
+This variable can be used for instance specific functions which want
+to examine proof-shell-last-output.")
+
+(defvar proof-shell-delayed-output nil
+ "A copy of proof-shell-last-output held back for processing at end of queue.")
+
+(defvar proof-shell-delayed-output-kind nil
+ "A copy of proof-shell-last-output-lind held back for processing at end of queue.")
+
+
+;;
+;; Goals buffer processing
+;;
+(defun proof-shell-analyse-structure (string)
+ "Analyse the term structure of STRING and display it in proof-goals-buffer.
+This function converts proof-by-pointing markup into mouse-highlighted
+extents."
+ (save-excursion
+ (let* ((ip 0) (op 0) ap (l (length string))
+ (ann (make-string (length string) ?x))
+ (stack ()) (topl ())
+ (out (make-string l ?x))
+ c span)
+
+ ;; Form output string by removing characters 128 or greater,
+ ;; (ALL annotations), unless proof-shell-leave-annotations-in-output
+ ;; is set.
+
+ ;; FIXME da: this can be removed now that we strip annotations
+ ;; immediately after fontification in proof-fontify-region. We
+ ;; may no longer need the setting
+ ;; proof-shell-leave-annotations-in-ouput, unless it breaks LEGO
+ ;; font lock patterns for example.
+
+ (unless proof-shell-leave-annotations-in-output
+ (while (< ip l)
+ (if (< (setq c (aref string ip)) 128)
+ (progn (aset out op c)
+ (incf op)))
+ (incf ip)))
+
+ ;; Response buffer may be out of date. It may contain (error)
+ ;; messages relating to earlier proof states
+
+ ;; FIXME da: this isn't always the case. In Isabelle
+ ;; we get <WARNING MESSAGE> <CURRENT GOALS> output,
+ ;; or <WARNING MESSAGE> <ORDINARY MESSAGE>. Both times
+ ;; <WARNING MESSAGE> would be relevant.
+ ;; We should only clear the output that was displayed from
+ ;; the *previous* prompt.
+
+ ;; FIXME da: I get a lot of empty response buffers displayed
+ ;; which might be nicer removed. Temporary test for this
+ ;; clean-buffer to see if it behaves well.
+
+ ;; Erase the response buffer if need be, maybe also removing the
+ ;; window. Indicate that it should be erased before the next
+ ;; output.
+ (proof-shell-maybe-erase-response t t)
+
+ (set-buffer proof-goals-buffer)
+
+ (erase-buffer)
+
+ ;; Insert the (possibly cleaned up) string.
+ (let ((dispstring (if proof-shell-leave-annotations-in-output
+ string
+ (substring out 0 op))))
+ (insert dispstring)
+ ;; Override record of last command output
+ (setq proof-shell-last-output dispstring))
+
+ ;; Get fonts and characters right
+ (proof-fontify-region (point-min) (point-max))
+
+ (set-buffer-modified-p nil) ; nicety
+
+ ;; Keep point at the start of the buffer. Might be nicer to
+ ;; keep point at "current" subgoal a la Isamode, but never mind
+ ;; just now.
+ (proof-display-and-keep-buffer proof-goals-buffer (point-min))
+
+ ;; FIXME: This code is broken for Emacs 20.3 (mule?) which has
+ ;; 16 bit character codes. (Despite earlier attempts to make
+ ;; character codes in this buffer 8 bit)
+ ;; But this is a more serious future problem in Proof General
+ ;; which requires re-engineering all this 128 mess.
+ ;; FIXME Mk II: This is also going to be broken for X-Symbol
+ ;; interaction, when tokens (several chars long) are replaced by
+ ;; single characters.
+ (unless
+ (or
+ ;; No point if we haven't set the pbp char vars
+ (not proof-shell-goal-char)
+ ;; Don't do it for Emacs 20.3 or any version which
+ ;; has this suspicious function.
+ (fboundp 'toggle-enable-multibyte-characters))
+ (setq ip 0
+ op 1)
+ (while (< ip l)
+ (setq c (aref string ip))
+ (cond
+ ((= c proof-shell-goal-char)
+ (setq topl (cons op topl))
+ (setq ap 0))
+ ((= c proof-shell-start-char)
+ (if proof-analyse-using-stack
+ (setq ap (- ap (- (aref string (incf ip)) 128)))
+ (setq ap (- (aref string (incf ip)) 128)))
+ (incf ip)
+ (while (not (= (setq c (aref string ip)) proof-shell-end-char))
+ (aset ann ap (- c 128))
+ (incf ap)
+ (incf ip))
+ (setq stack (cons op (cons (substring ann 0 ap) stack))))
+ ((and (consp stack) (= c proof-shell-field-char))
+ ;; (consp stack) has been added to make the code more robust.
+ ;; In fact, this condition is violated when using
+ ;; lego/example.l and FSF GNU Emacs 20.3
+ (setq span (make-span (car stack) op))
+ (set-span-property span 'mouse-face 'highlight)
+ (set-span-property span 'goalsave (car (cdr stack)));; FIXME: really goalsave?
+ ;; Pop annotation off stack
+ (and proof-analyse-using-stack
+ (progn
+ (setq ap 0)
+ (while (< ap (length (cadr stack)))
+ (aset ann ap (aref (cadr stack) ap))
+ (incf ap))))
+ ;; Finish popping annotations
+ (setq stack (cdr (cdr stack))))
+ (t (incf op)))
+ (incf ip))
+ (setq topl (reverse (cons (point-max) topl)))
+ ;; If we want Coq pbp: (setq coq-current-goal 1)
+ (if proof-goal-hyp-fn
+ (while (setq ip (car topl)
+ topl (cdr topl))
+ (pbp-make-top-span ip (car topl))))))))
+
+(defun proof-shell-strip-special-annotations (string)
+ "Strip special annotations from a string, returning cleaned up string.
+*Special* annotations are characters with codes higher than
+'proof-shell-first-special-char'.
+If proof-shell-first-special-char is unset, return STRING unchanged."
+ (if proof-shell-first-special-char
+ (let* ((ip 0) (op 0) (l (length string)) (out (make-string l ?x )))
+ (while (< ip l)
+ (if (>= (aref string ip) proof-shell-first-special-char)
+ (if (char-equal (aref string ip) proof-shell-start-char)
+ (progn (incf ip)
+ (while
+ (< (aref string ip)
+ proof-shell-first-special-char)
+ (incf ip))))
+ (aset out op (aref string ip))
+ (incf op))
+ (incf ip))
+ (substring out 0 op))
+ string))
+
+;;
+;; Response buffer processing
+;;
+(defun proof-shell-handle-output (start-regexp end-regexp append-face)
+ "Displays output from `proof-shell-buffer' in `proof-response-buffer'.
+The region in `proof-shell-buffer begins with the first match
+beyond the prompt for START-REGEXP and is delimited by the
+last match in the buffer for END-REGEXP. The match for END-REGEXP
+is not part of the specified region. This mechanism means if there
+are multiple matches for START-REGEXP and END-REGEXP, we match the
+largest region containing them all.
+This is a subroutine of proof-shell-handle-error."
+;; 3.4: doesn't return the string any more.
+;; Returns the string (with faces) in the specified region."
+ (let (start end string)
+ (save-excursion
+ (set-buffer proof-shell-buffer)
+ (goto-char (point-max))
+ (setq end (search-backward-regexp end-regexp))
+ (goto-char (marker-position proof-marker))
+ (setq start (- (search-forward-regexp start-regexp)
+ (length (match-string 0))))
+ ;; FIXME: if the shell buffer is x-symbol minor mode,
+ ;; this string can contain X-Symbol characters, which
+ ;; is not suitable for processing with proof-fontify-region.
+ (setq string
+ (if proof-shell-leave-annotations-in-output
+ (buffer-substring start end)
+ (proof-shell-strip-special-annotations
+ (buffer-substring start end)))))
+ ;; Erase if need be, and erase next time round too.
+ (proof-shell-maybe-erase-response t nil)
+ (proof-response-buffer-display string append-face)))
+
+
+(defun proof-shell-show-as-response (str)
+ "Show STR as a response in the response buffer."
+ (unless proof-shell-leave-annotations-in-output
+ (setq str (proof-shell-strip-special-annotations str)))
+ (proof-shell-maybe-erase-response t nil)
+ (proof-response-buffer-display str)
+ (proof-display-and-keep-buffer proof-response-buffer))
+
+(defun proof-shell-handle-delayed-output ()
+ "Display delayed output.
+This function handles the cases of proof-shell-delayed-output-kind which
+are not dealt with eagerly during script processing, namely
+'abort, 'response, 'goals outputs."
+ (cond
+ ;; Response buffer output
+ ((eq proof-shell-delayed-output-kind 'abort)
+ (proof-shell-show-as-response "Aborted."))
+ ((eq proof-shell-delayed-output-kind 'response)
+ (proof-shell-show-as-response proof-shell-delayed-output))
+ ;; Goals buffer output
+ ((eq proof-shell-delayed-output-kind 'goals)
+ (proof-shell-analyse-structure proof-shell-delayed-output))
+ ;; Ignore other cases
+ )
+ (run-hooks 'proof-shell-handle-delayed-output-hook))
+
+
+;;
+;; Processing error output
+;;
+
+(defun proof-shell-handle-error (cmd)
+ "React on an error message triggered by the prover.
+We first flush unprocessed goals to the goals buffer.
+The error message is displayed in the responsebuffer.
+Then we call `proof-shell-error-or-interrupt-action', which see."
+ ;; [FIXME: Why not flush goals also for interrupts?]
+ ;; Flush goals or response buffer (from some last successful proof step)
+ (save-excursion
+ (proof-shell-handle-delayed-output))
+ ;; Perhaps we should erase the proof-response-buffer?
+ (proof-shell-handle-output
+ proof-shell-error-regexp proof-shell-annotated-prompt-regexp
+ 'proof-error-face)
+ (proof-display-and-keep-buffer proof-response-buffer)
+ (proof-shell-error-or-interrupt-action 'error))
+
+(defun proof-shell-handle-interrupt ()
+ "React on an interrupt message from the prover.
+ Runs proof-shell-error-or-interrupt-action."
+ (proof-shell-maybe-erase-response t t t) ; force cleaned now & next
+ (proof-shell-handle-output
+ proof-shell-interrupt-regexp proof-shell-annotated-prompt-regexp
+ 'proof-error-face)
+; (proof-display-and-keep-buffer proof-response-buffer)
+ (proof-warning
+ "Interrupt: script management may be in an inconsistent state
+ (but it's probably okay)")
+ (proof-shell-error-or-interrupt-action 'interrupt))
+
+(defun proof-shell-error-or-interrupt-action (&optional err-or-int)
+ "General action when an error or interrupt message appears from prover.
+A subroutine for proof-shell-handle-interrupt and proof-shell-handle-error.
+
+We sound a beep, clear queue spans and proof-action-list, and set the flag
+proof-shell-error-or-interrupt-seen to the ERR-OR-INT argument.
+Then we call `proof-shell-handle-error-or-interrupt-hook'."
+ (save-excursion ;; for safety.
+ (beep)
+ ;; NB: previously for interrupt, clear-queue-spans
+ ;; was only called if shell busy. Any harm calling it always?
+ (proof-script-clear-queue-spans)
+ (setq proof-action-list nil)
+ (proof-release-lock err-or-int)
+ ;; Make sure that prover is outputting data now.
+ ;; FIXME: put something here!
+ ;; New: this is called for interrupts too.
+ (run-hooks 'proof-shell-handle-error-or-interrupt-hook)))
+
+(defun proof-goals-pos (span maparg)
+ "Given a span, return the start of it if corresponds to a goal, nil otherwise."
+ (and (eq 'goal (car (span-property span 'proof-top-element)))
+ (span-start span)))
+
+(defun proof-pbp-focus-on-first-goal ()
+ "If the `proof-goals-buffer' contains goals, bring the first one into view.
+This is a hook function for proof-shell-handle-delayed-output-hook."
+ (and proof-running-on-XEmacs ;; FIXME: map-extents exists on Emacs21
+ (fboundp 'map-extents) ;; but with different typing
+ (let
+ ((pos (map-extents 'proof-goals-pos proof-goals-buffer
+ nil nil nil nil 'proof-top-element)))
+ (and pos (set-window-point
+ (get-buffer-window proof-goals-buffer t) pos)))))
+
+
+(defsubst proof-shell-string-match-safe (regexp string)
+ "Like string-match except returns nil if REGEXP is nil."
+ (and regexp (string-match regexp string)))
+
+
+(defun proof-shell-process-output (cmd string)
+ "Process shell output (resulting from CMD) by matching on STRING.
+CMD is the first part of the proof-action-list that lead to this
+output. The result of this function is a pair (SYMBOL NEWSTRING).
+
+Here is where we recognizes interrupts, abortions of proofs, errors,
+completions of proofs, and proof step hints (proof by pointing results).
+They are checked for in this order, using
+
+ proof-shell-interrupt-regexp
+ proof-shell-error-regexp
+ proof-shell-abort-goal-regexp
+ proof-shell-proof-completed-regexp
+ proof-shell-result-start
+
+All other output from the proof engine will be reported to the user in
+the response buffer by setting proof-shell-delayed-output to a cons
+cell of ('insert . TEXT) where TEXT is the text string to be inserted.
+
+Order of testing is: interrupt, abort, error, completion.
+
+To extend this function, set proof-shell-process-output-system-specific.
+
+The \"aborted\" case is intended for killing off an open proof during
+retraction. Typically it matches the message caused by a
+proof-kill-goal-command. It simply inserts the word \"Aborted\" into
+the response buffer. So it is expected to be the result of a
+retraction, rather than the indication that one should be made.
+
+This function sets `proof-shell-last-output' and `proof-shell-last-output-kind',
+which see."
+ ;; Keep a record of the last message from the prover
+ (setq proof-shell-last-output string)
+ (or
+ ;; First check for error, interrupt, abort, proof completed
+ (cond
+ ((proof-shell-string-match-safe proof-shell-interrupt-regexp string)
+ (setq proof-shell-last-output-kind 'interrupt))
+
+ ((proof-shell-string-match-safe proof-shell-error-regexp string)
+ (setq proof-shell-last-output
+ (proof-shell-strip-special-annotations
+ (substring string (match-beginning 0))))
+ (setq proof-shell-last-output-kind 'error))
+
+ ((proof-shell-string-match-safe proof-shell-abort-goal-regexp string)
+ (proof-clean-buffer proof-goals-buffer)
+ (setq proof-shell-last-output-kind 'abort))
+
+ ((proof-shell-string-match-safe proof-shell-proof-completed-regexp string)
+ ;; In case no goals display
+ (proof-clean-buffer proof-goals-buffer)
+ ;; counter of commands since proof complete.
+ (setq proof-shell-proof-completed 0)
+ ;; But! We carry on matching below for goals output, so that
+ ;; provers may include proof completed message as part of
+ ;; goals message (Isabelle, HOL) or not (LEGO, Coq).
+ nil))
+
+ ;; Check for remaining things
+ (cond
+ ((proof-shell-string-match-safe proof-shell-start-goals-regexp string)
+ (let ((start (match-end 0))
+ end)
+ ;; Find the last goal string in the output
+ (while (string-match proof-shell-start-goals-regexp string start)
+ (setq start (match-end 0)))
+ ;; Convention: provers with special characters appearing in
+ ;; proof-start-goals-regexp don't include the match in their
+ ;; goals output. Others do.
+ ;; (Improvement to examine proof-start-goals-regexp suggested
+ ;; for Coq by Robert Schneck because Coq has specials but
+ ;; doesn't markup goals output specially).
+ (unless (and
+ proof-shell-first-special-char
+ (not (string-equal
+ proof-shell-start-goals-regexp
+ (proof-shell-strip-special-annotations
+ proof-shell-start-goals-regexp))))
+ (setq start (match-beginning 0)))
+ (setq end (if proof-shell-end-goals-regexp
+ (string-match proof-shell-end-goals-regexp string start)
+ (length string)))
+ (setq proof-shell-last-output (substring string start end))
+ (setq proof-shell-last-output-kind 'goals)))
+
+ ;; Test for a proof by pointing command hint
+ ((proof-shell-string-match-safe proof-shell-result-start string)
+ (let (start end)
+ (setq start (+ 1 (match-end 0)))
+ (string-match proof-shell-result-end string)
+ (setq end (- (match-beginning 0) 1))
+ ;; Only record the loopback command in the last output message
+ (setq proof-shell-last-output (substring string start end)))
+ (setq proof-shell-last-output-kind 'loopback))
+
+ ;; Hook to tailor proof-shell-process-output to a specific proof
+ ;; system, in the case that all the above matches fail.
+ ((and proof-shell-process-output-system-specific
+ (funcall (car proof-shell-process-output-system-specific)
+ cmd string))
+ (setq proof-shell-last-output-kind 'systemspecific)
+ (funcall (cdr proof-shell-process-output-system-specific)
+ cmd string))
+
+ ;; Finally, any other output will appear as a response.
+ (t
+ (setq proof-shell-last-output-kind 'response)))))
+
+
+;;
+;; Low-level commands for shell communication
+;;
+
+(defvar proof-shell-insert-space-fudge
+ (cond
+ ((string-match "21.*XEmacs" emacs-version) " ")
+ (proof-running-on-XEmacs "")
+ (t " "))
+ "String to insert after setting proof marker to prevent it moving.
+Allows for a difference between different versions of comint across
+different Emacs versions.")
+
+(defun proof-shell-insert (string action)
+ "Insert STRING at the end of the proof shell, call comint-send-input.
+
+First call proof-shell-insert-hook. The argument ACTION may be
+examined by the hook to determine how to process the STRING variable.
+
+Then strip STRING of carriage returns before inserting it and updating
+proof-marker to point to the end of the newly inserted text.
+
+Do not use this function directly, or output will be lost. It is only
+used in proof-append-alist when we start processing a queue, and in
+proof-shell-exec-loop, to process the next item."
+ (save-excursion
+ (set-buffer proof-shell-buffer)
+ (goto-char (point-max))
+
+ ;; See docstring for this hook: it allows munging of `string'
+ ;; amongst other hacks.
+ (run-hooks 'proof-shell-insert-hook)
+
+ ;; Now we replace CRs from string with spaces. This is done
+ ;; in case CRs in the input strip produce spurious prompts.
+
+ (if proof-shell-strip-crs-from-input
+ (let ((l (length string)) (i 0))
+ (while (< i l)
+ (if (= (aref string i) ?\n) (aset string i ?\ ))
+ (incf i))))
+
+ (insert string)
+
+ ;; Advance the proof-marker, if synchronization has been gained.
+ ;; A null marker position indicates that synchronization is not
+ ;; yet gained. (NB: Any output received before syncrhonization is
+ ;; gained is ignored!)
+ (unless (null (marker-position proof-marker))
+ (set-marker proof-marker (point)))
+
+ ;; FIXME: possible improvement. Make for post 3.0 releases
+ ;; in case of problems.
+ ;; (set-marker proof-shell-urgent-message-marker (point))
+ ;; (set-marker proof-shell-urgent-message-scanner (point))
+
+ ;; FIXME da: this space fudge is actually a visible hack:
+ ;; the response string begins with a space and a newline.
+ ;; It was needed to work around differences in Emacs versions.
+ (insert proof-shell-insert-space-fudge)
+ (comint-send-input)))
+
+;; OLD BUGGY CODE here
+;; Left in as a warning of a race condition.
+;; It seems that comint-send-input can lead to the
+;; output filter running before it returns, so that
+;; the set-marker call below is executed too late.
+;; The result is that the filter deals with
+;; the previous portion of output instead of the
+;; most recent one!
+;;
+;; xemacs and FSF emacs have different semantics for what happens when
+;; shell input is sent next to a marker
+;; the following code accommodates both definitions
+; (let ((inserted (point)))
+; (comint-send-input)
+; (set-marker proof-marker inserted))))
+
+
+;; ============================================================
+;;
+;; Code for manipulating proof queue
+;;
+
+
+(defun proof-shell-command-queue-item (cmd callback)
+ "Return the proof queue entry needed to run CMD with callback CALLBACK."
+ (list nil cmd callback))
+
+
+(defun proof-shell-set-silent (span)
+ "Callback for `proof-shell-start-silent'.
+Very simple function but it's important to give it a name to help
+track what happens in the proof queue."
+ (setq proof-shell-silent t))
+
+(defun proof-shell-start-silent-item ()
+ "Return proof queue entry for starting silent mode."
+ (proof-shell-command-queue-item
+ proof-shell-start-silent-cmd
+ 'proof-shell-set-silent))
+
+(defun proof-shell-clear-silent (span)
+ "Callback for `proof-shell-stop-silent'.
+Very simple function but it's important to give it a name to help
+track what happens in the proof queue."
+ (setq proof-shell-silent nil))
+
+(defun proof-shell-stop-silent-item ()
+ "Return proof queue entry for stopping silent mode."
+ (proof-shell-command-queue-item
+ proof-shell-stop-silent-cmd
+ 'proof-shell-clear-silent))
+
+;; FIXME: could be macro for efficiency improvement in avoiding calculating num
+(defun proof-shell-should-be-silent (num)
+ "Return non-nil if we must switch to silent mode, adding NUM entries to queue."
+ (if proof-shell-start-silent-cmd
+ (or proof-shell-silent ; already
+ ;; NB: there is some question here over counting the
+ ;; proof-action-list, since it could itself contain
+ ;; silent-on/off commands which should be ignored for
+ ;; counting, really... also makes cutting lists for advanced
+ ;; queue processing more tricky.
+ (>= (+ num (length proof-action-list))
+ proof-shell-silent-threshold))))
+
+
+(defun proof-append-alist (alist &optional queuemode)
+ "Chop off the vacuous prefix of the command queue ALIST and queue it.
+For each `proof-no-command' item at the head of the list, invoke its
+callback and remove it from the list.
+
+Append the result onto `proof-action-list', and if the proof
+shell isn't already busy, grab the lock with QUEUEMODE and
+start processing the queue.
+
+If the proof shell is busy when this function is called,
+then QUEUEMODE must match the mode of the queue currently
+being processed."
+ (let (item)
+ ;; FIXME: may be wrong time to invoke callbacks for no-op commands,
+ ;; if the queue is not empty.
+ (while (and alist (string=
+ (nth 1 (setq item (car alist)))
+ proof-no-command))
+ (funcall (nth 2 item) (car item))
+ (setq alist (cdr alist)))
+ (if alist
+ (if proof-action-list
+ (progn
+ ;; internal check: correct queuemode in force if busy
+ ;; (should have proof-action-list<>nil -> busy)
+ (and proof-shell-busy queuemode
+ (unless (eq proof-shell-busy queuemode)
+ (proof-debug "proof-append-alist: wrong queuemode detected for busy shell")
+ (assert (eq proof-shell-busy queuemode))))
+ ;; See if we should make prover quieten down
+ (if (proof-shell-should-be-silent (length alist))
+ ;; Make it ASAP, which is just after the current
+ ;; command (head of queue).
+ (setq proof-action-list
+ (cons (car proof-action-list)
+ (cons (proof-shell-start-silent-item)
+ (cdr proof-action-list)))))
+ ;; append to the current queue
+ (setq proof-action-list
+ (nconc proof-action-list alist)))
+ ;; start processing a new queue
+ (progn
+ (proof-grab-lock queuemode)
+ (setq proof-shell-last-output-kind nil)
+ (if (proof-shell-should-be-silent (length alist))
+ ;;
+ (progn
+ (setq proof-action-list
+ (list (proof-shell-start-silent-item)))
+ (setq item (car proof-action-list))))
+ (setq proof-action-list
+ (nconc proof-action-list alist))
+ ;; Really start things going here
+ (proof-shell-insert (nth 1 item) (nth 2 item)))))))
+
+;;;###autoload
+(defun proof-start-queue (start end alist)
+ "Begin processing a queue of commands in ALIST.
+If START is non-nil, START and END are buffer positions in the
+active scripting buffer for the queue region.
+
+This function calls `proof-append-alist'."
+ (if start
+ (proof-set-queue-endpoints start end))
+ (proof-append-alist alist))
+
+;;;###autoload
+(defun proof-extend-queue (end alist)
+ "Extend the current queue with commands in ALIST, queue end END.
+To make sense, the commands should correspond to processing actions
+for processing a region from (buffer-queue-or-locked-end) to END.
+The queue mode is set to 'advancing"
+ (proof-set-queue-endpoints (proof-unprocessed-begin) end)
+ (proof-append-alist alist 'advancing))
+
+
+
+
+(defun proof-shell-exec-loop ()
+ "Process the proof-action-list.
+
+`proof-action-list' contains a list of (SPAN COMMAND ACTION) triples.
+
+If this function is called with a non-empty proof-action-list, the
+head of the list is the previously executed command which succeeded.
+We execute (ACTION SPAN) on the first item, then (ACTION SPAN) on any
+following items which have proof-no-command as their cmd components.
+If a there is a next command after that, send it to the process. If
+the action list becomes empty, unlock the process and remove the queue
+region.
+
+The return value is non-nil if the action list is now empty."
+ ;; The loop looks like: Execute the
+ ;; command, and if it's successful, do action on span. If the
+ ;; command's not successful, we bounce the rest of the queue and do
+ ;; some error processing.
+
+ (unless (not proof-action-list) ; exit immediately if finished.
+ (save-excursion
+ ;; Switch to active scripting buffer if there is one.
+ (if proof-script-buffer
+ (set-buffer proof-script-buffer))
+ (let ((item (car proof-action-list)))
+ ;; Do (action span) on first item in list
+ (funcall (nth 2 item) (car item))
+ (setq proof-action-list (cdr proof-action-list))
+ ;; Process following items in list with the form
+ ;; ("COMMENT" cmd) by calling (cmd "COMMENT")
+ (while (and proof-action-list
+ (string=
+ (nth 1 (setq item (car proof-action-list)))
+ proof-no-command))
+ ;; Do (action span) on comments
+ (funcall (nth 2 item) (car item))
+ (setq proof-action-list (cdr proof-action-list)))
+ ;; If action list is empty or has a single element,
+ ;; we want to make sure prover is being noisy.
+ (if (and proof-shell-silent
+ (or (null proof-action-list) ; possible?
+ (null (cdr proof-action-list))))
+ (progn
+ ;; Stick the quieten command onto the queue
+ (setq proof-action-list
+ (cons (proof-shell-stop-silent-item)
+ proof-action-list))
+ (setq item (car proof-action-list))))
+ ;; If action list is empty now, release the process lock
+ (if (null proof-action-list)
+ (progn (proof-release-lock)
+ (proof-detach-queue)
+ ;; indicate finished
+ t)
+ ;; Otherwise, send the next command to the process.
+ (proof-shell-insert (nth 1 item) (nth 2 item))
+ ;; indicate not finished
+ nil)))))
+
+;; FIXME da: some places in the code need to be made robust in
+;; case of buffer kills, etc, before callbacks. Is this function
+;; one?
+(defun proof-shell-insert-loopback-cmd (cmd)
+ "Insert command sequence triggered by the proof process
+at the end of locked region (after inserting a newline and indenting).
+Assume proof-script-buffer is active."
+ (unless (string-match "^\\s-*$" cmd) ; FIXME: assumes cmd is single line
+ (save-excursion
+ (set-buffer proof-script-buffer)
+ (let (span)
+ (proof-goto-end-of-locked)
+ ;; Fix 16.11.99. This attempts to indent current line which can
+ ;; be read-only.
+ ;; (newline-and-indent)
+ (let ((proof-one-command-per-line t)) ; because pbp several commands
+ (proof-script-new-command-advance))
+ (insert cmd)
+ ;; Fix 16.11.99. Comment in todo suggested old code below
+ ;; assumed the pbp command would succeed, but it seems fine?
+ ;; But this action belongs in the proof script code.
+ ;; NB: difference between ordinary commands and pbp is that
+ ;; pbp can return *several* commands, that are treated as
+ ;; a unit, i.e. sent to the proof assistant together.
+ ;; FIXME da: this seems very similar to proof-insert-pbp-command
+ ;; in proof-script.el. Should be unified, I suspect.
+ (setq span (make-span (proof-locked-end) (point)))
+ (set-span-property span 'type 'pbp)
+ (set-span-property span 'cmd cmd)
+ (proof-set-queue-endpoints (proof-locked-end) (point))
+ (setq proof-action-list
+ (cons (car proof-action-list)
+ (cons (list span cmd 'proof-done-advancing)
+ (cdr proof-action-list))))))))
+
+;; da: first note of this sentence is false!
+;; ******** NB **********
+;; While we're using pty communication, this code is OK, since all
+;; eager annotations are one line long, and we get input a line at a
+;; time. If we go over to piped communication, it will break.
+
+(defun proof-shell-message (str)
+ "Output STR in minibuffer."
+ ;; %s is used below to escape characters special to
+ ;; 'format' which could appear in STR.
+ (message "%s" (concat "[" proof-assistant "] " str)))
+
+(defun proof-shell-process-urgent-message (message)
+ "Analyse urgent MESSAGE for various cases.
+Cases are: included file, retracted file, cleared response buffer,
+variable setting or dependency list.
+If none of these apply, display MESSAGE.
+
+MESSAGE should be a string annotated with
+proof-shell-eager-annotation-start, proof-shell-eager-annotation-end."
+ (cond
+ ;; CASE processing file: the prover is reading a file directly
+ ;;
+ ;; FIXME da: this interface is quite restrictive: might be
+ ;; useful for one message to name several files, or include
+ ;; an instruction to purge the included files list, rather
+ ;; than erasing everything and re-adding it.
+ ;; Contrast retraction interface: there we compute whole
+ ;; new list.
+ ;; (Come to think of it, maybe we could unify the two
+ ;; cases: automatically find removed files and added files
+ ;; between two versions of proof-included-files-list)
+ ((and proof-shell-process-file
+ (string-match (car proof-shell-process-file) message))
+ (let
+ ((file (funcall (cdr proof-shell-process-file) message)))
+ ;; Special hack: empty string indicates current scripting buffer
+ ;; (not used anywhere presently?)
+ ;; (if (and proof-script-buffer (string= file ""))
+ ;; (setq file (buffer-file-name proof-script-buffer)))
+ ;; YES! It *was* used by LEGO.
+ ;; Now we avoid this in favour of altering the processed
+ ;; files list when the current scripting buffer changes,
+ ;; inside Proof General. Attempt to harmonize behaviour
+ ;; with Isabelle. Seems wrong to add "example.l" to
+ ;; list of processed files if it's only partly processed?
+ ;; (On the other hand, for lego, it may have declared a
+ ;; module heading, which is probably Lego's standard
+ ;; for what a processed file actually is).
+ (if (and file (not (string= file "")))
+ (proof-register-possibly-new-processed-file file))))
+
+ ;; CASE retract: the prover is retracting across files
+ ((and proof-shell-retract-files-regexp
+ (string-match proof-shell-retract-files-regexp message))
+ (let ((current-included proof-included-files-list))
+ (setq proof-included-files-list
+ (funcall proof-shell-compute-new-files-list message))
+ (let
+ ;; Previously active scripting buffer
+ ((scrbuf proof-script-buffer))
+ ;; NB: we assume that no new buffers are *added* by
+ ;; the proof-shell-compute-new-files-list
+ (proof-restart-buffers
+ (proof-files-to-buffers
+ (set-difference current-included
+ proof-included-files-list)))
+ (cond
+ ;; Do nothing if there was no active scripting buffer
+ ((not scrbuf))
+ ;; Do nothing if active scripting buffer hasn't changed
+ ;; (NB: it might have been nuked)
+ ((eq scrbuf proof-script-buffer))
+ ;; FIXME da: I've forgotten the next condition was needed?
+ ;;
+ ;; In fact, it breaks the case that the current scripting
+ ;; buffer should be deactivated if the prover retracts it.
+ ;; When scripting begins again in the buffer, other
+ ;; files may have to be re-read which may not happen unless
+ ;; scripting is properly de-activated.
+ ;;
+ ;; Otherwise, active scripting buffer has been retracted.
+ ;; Add it back!! Why? Presumably because code likes to
+ ;; have an active scripting buffer??
+ (t
+ ;; FIXME da: want to test disabling currently active scripting
+ ;; buffer. Unfortunately this doesn't work with current
+ ;; use of proof-script-buffer-list: always have to have
+ ;; *some* scripting buffer active. ARGHH!
+ ;; FIXME da: test not having this add-back. Then
+ ;; scripting buffer may change wrongly and randomly
+ ;; to some other buffer, without running change functions.
+ ;;
+ ;; FIXME da: test setting this to nil, scary!
+ (setq proof-script-buffer nil)
+ ;;(setq proof-script-buffer-list
+ ;; (cons scrbuf proof-script-buffer-list))
+ ;; (save-excursion
+ ;; (set-buffer scrbuf)
+ ;; (proof-init-segmentation)))))
+ )))
+ ))
+
+ ;; CASE clear response: prover asks PG to clear response buffer
+ ((and proof-shell-clear-response-regexp
+ (string-match proof-shell-clear-response-regexp message)
+ proof-response-buffer)
+ ;; Erase response buffer and possibly its windows.
+ (proof-shell-maybe-erase-response nil t t))
+
+ ;; CASE clear goals: prover asks PG to clear goals buffer
+ ((and proof-shell-clear-goals-regexp
+ (string-match proof-shell-clear-goals-regexp message)
+ proof-goals-buffer)
+ ;; Erase goals buffer but and possibly its windows
+ (proof-clean-buffer proof-goals-buffer))
+
+ ;; CASE variable setting: prover asks PG to set some variable
+ ;; NB: no safety protection whatsoever here, we use blind faith
+ ;; that the prover will not send malicious elisp!!
+ ((and proof-shell-set-elisp-variable-regexp
+ (string-match proof-shell-set-elisp-variable-regexp message))
+ (let
+ ((variable (match-string 1 message))
+ (expr (match-string 2 message)))
+ (condition-case err
+ ;; Easiest way to do this seems to be to dump the lisp
+ ;; string into another buffer -- no direct way to eval
+ ;; from a string?
+ (with-temp-buffer
+ (insert expr)
+ (set (intern variable) (eval-last-sexp t)))
+ (t (proof-debug
+ (concat
+ "lisp error when obeying proof-shell-set-elisp-variable: \n"
+ "setting `" variable "'\n to: \n"
+ expr "\n"))))))
+
+ ;; CASE PGIP message from proof assistant.
+ ((and proof-shell-match-pgip-cmd
+ (string-match proof-shell-match-pgip-cmd message))
+ (require 'pg-xml)
+ (require 'pg-pgip)
+ (let
+ ((parsed-pgip (pg-xml-parse-string message)))
+ (pg-pgip-process-cmd parsed-pgip)))
+
+ ;; CASE theorem dependency: prover lists thms used in last proof
+ ((and proof-shell-theorem-dependency-list-regexp
+ (string-match proof-shell-theorem-dependency-list-regexp message))
+ (setq proof-last-theorem-dependencies
+ (split-string (match-string 1 message))))
+
+ ;; CASE tracing output: output in the tracing buffer instead
+ ;; of the response buffer
+ ((and proof-shell-trace-output-regexp
+ (string-match proof-shell-trace-output-regexp message))
+ (proof-trace-buffer-display
+ (if proof-shell-leave-annotations-in-output
+ message
+ (proof-shell-strip-special-annotations message)))
+ (proof-display-and-keep-buffer proof-trace-buffer)
+ ;; Force redisplay in case in a fast loop which keeps Emacs
+ ;; fully-occupied processing prover output
+ (and (fboundp 'redisplay-frame)
+ ;; XEmacs fn
+ (redisplay-frame))
+ ;; If user quits during tracing output, send an interrupt
+ ;; to the prover. Helps when Emacs is "choking".
+ (if (and quit-flag proof-action-list)
+ (proof-interrupt-process)))
+
+ (t
+ ;; We're about to display a message. Clear the response buffer
+ ;; if necessary, but don't clear it the next time.
+ ;; Don't bother remove the window for the response buffer
+ ;; because we're about to put a message in it.
+ (proof-shell-maybe-erase-response nil nil)
+ (let ((stripped (proof-shell-strip-special-annotations message))
+ firstline)
+ ;; Display first chunk of output in minibuffer.
+ ;; Maybe this should be configurable, it can get noisy.
+ (proof-shell-message
+ (substring stripped 0 (or (string-match "\n" stripped)
+ (min (length stripped) 75))))
+ (proof-response-buffer-display
+ (if proof-shell-leave-annotations-in-output
+ message
+ stripped)
+ 'proof-eager-annotation-face)))))
+
+(defvar proof-shell-urgent-message-marker nil
+ "Marker in proof shell buffer pointing to end of last urgent message.")
+
+(defvar proof-shell-urgent-message-scanner nil
+ "Marker in proof shell buffer pointing to scan start for urgent messages.")
+
+(defun proof-shell-process-urgent-messages ()
+ "Scan the shell buffer for urgent messages.
+Scanning starts from proof-shell-urgent-message-scanner and handles
+strings between regexps eager-annotation-start and eager-annotation-end.
+
+Note that we must search the buffer rather than the chunk of output
+being filtered process because we have no guarantees about where
+chunks are broken: it may be in the middle of an annotation.
+
+This is a subroutine of proof-shell-filter."
+ (let ((pt (point)) (end t) lastend start)
+ (goto-char (marker-position proof-shell-urgent-message-scanner))
+ (while (and end
+ (re-search-forward proof-shell-eager-annotation-start
+ nil 'end))
+ (setq start (match-beginning 0))
+ (if (setq end
+ (re-search-forward proof-shell-eager-annotation-end nil t))
+ ;; Process the text including annotations (stripped if specials)
+ (save-excursion
+ (setq lastend end)
+ (proof-shell-process-urgent-message
+ (buffer-substring start end)))))
+ ;; Set the marker to the (character after) the end of the last
+ ;; message found, if any. Must take care to keep the marker
+ ;; behind the process marker otherwise no output is seen!
+ ;; (insert-before-markers in comint)
+ ;; FIXME: maybe we don't need to be as careful as these three checks?
+ (if lastend
+ (set-marker
+ proof-shell-urgent-message-marker
+ (min lastend
+ (1- (process-mark (get-buffer-process (current-buffer)))))))
+ ;; Now an optimization to avoid searching the same bit of text
+ ;; over and over. But it requires that we know the maximum
+ ;; possible length of an annotation to avoid missing them.
+ (if end
+ ;; If the search for the starting annotation was unsuccessful,
+ ;; set the scanner marker to the limit of the last search for
+ ;; the starting annotation, less the maximal length of the
+ ;; annotation.
+ (set-marker
+ proof-shell-urgent-message-scanner
+ (min
+ ;; NB: possible fix here not included: a test to be sure we
+ ;; don't go back before the start of the command! This
+ ;; fixes a minor problem which is possible duplication
+ ;; of urgent messages which are less than
+ ;; proof-shell-eager-annotation-start-length characters.
+ ;; But if proof-general is configured properly, there
+ ;; should never be any such messages!
+ ;; (max
+ ;; (marker-position proof-marker)
+ (- (point) proof-shell-eager-annotation-start-length)
+ (1- (process-mark (get-buffer-process (current-buffer))))))
+ ;; Otherwise, the search for the ending annotation was
+ ;; unsuccessful, so we set the scanner marker to the start of
+ ;; the annotation found.
+ (set-marker
+ proof-shell-urgent-message-scanner
+ (min
+ start
+ (1- (process-mark (get-buffer-process (current-buffer)))))))
+ (goto-char pt)))
+
+;; NOTE da: proof-shell-filter does *not* update the proof-marker,
+;; that's done in proof-shell-insert. Previous docstring below was
+;; wrong. The one case where this function updates proof-marker is
+;; the first time through the loop to synchronize.
+(defun proof-shell-filter (str)
+ "Filter for the proof assistant shell-process.
+A function for comint-output-filter-functions.
+
+Deal with output and issue new input from the queue.
+
+Handle urgent messages first. As many as possible are processed,
+using the function `proof-shell-process-urgent-messages'.
+
+Otherwise wait until an annotated prompt appears in the input.
+If proof-shell-wakeup-char is set, wait until we see that in the
+output chunk STR. This optimizes the filter a little bit.
+
+If a prompt is seen, run proof-shell-process-output on the output
+between the new prompt and the last input (position of proof-marker)
+or the last urgent message (position of
+proof-shell-urgent-message-marker), whichever is later.
+For example, in this case:
+
+ PROMPT> INPUT
+ OUTPUT-1
+ URGENT-MESSAGE
+ OUTPUT-2
+ PROMPT>
+
+proof-marker is set after INPUT by proof-shell-insert and
+proof-shell-urgent-message-marker is set after URGENT-MESSAGE.
+Only OUTPUT-2 will be processed. For this reason, error
+messages and interrupt messages should *not* be considered
+urgent messages.
+
+Output is processed using proof-shell-filter-process-output.
+
+The first time that a prompt is seen, proof-marker is
+initialised to the end of the prompt. This should
+correspond with initializing the process. The
+ordinary output before the first prompt is ignored (urgent messages,
+however, are always processed; hence their name)."
+ (save-excursion
+ ;; Process urgent messages.
+ (and proof-shell-eager-annotation-start
+ (proof-shell-process-urgent-messages))
+
+ ;; FIXME da: some optimization possible here by customizing
+ ;; filter according to whether proof-shell-wakeup-char, etc,
+ ;; are non-nil. Make proof-shell-filter into a macro to do
+ ;; this.
+
+ (if ;; Some proof systems can be hacked to have annotated prompts;
+ ;; for these we set proof-shell-wakeup-char to the annotation
+ ;; special, and look for it in the output before doing anything.
+ (if proof-shell-wakeup-char
+ ;; FIXME: this match doesn't work in emacs-mule, darn.
+ ;; (string-match (char-to-string proof-shell-wakeup-char) str))
+ ;; FIXME: this match doesn't work in FSF emacs 20.5, darn.
+ ;; (find proof-shell-wakeup-char str)
+ ;; FIXME: 3.1pre: temporarily, use both tests!
+ (or
+ (string-match (char-to-string proof-shell-wakeup-char) str)
+ (find proof-shell-wakeup-char str))
+ ;; Others systems rely on a standard top-level (e.g. SML) whose
+ ;; prompts may be difficult or impossible to hack.
+ ;; For those we must search in the buffer for the prompt.
+ t)
+ (if (null (marker-position proof-marker))
+ ;; Initialisation of proof-marker:
+ ;; Set marker to after the first prompt in the
+ ;; output buffer if one can be found now.
+ ;; FIXME da: we'd rather do this initialization outside
+ ;; of the filter function for better efficiency!
+ (progn
+ (goto-char (point-min))
+ (if (re-search-forward proof-shell-annotated-prompt-regexp nil t)
+ (progn
+ (set-marker proof-marker (point))
+ ;; The first time a prompt is seen we ignore any
+ ;; output that occured before it, assuming that
+ ;; corresponds to uninteresting startup messages.
+ ;; We process the
+ ;; action list to remove the first item if need
+ ;; be (proof-shell-init-cmd sent if
+ ;; proof-shell-config-done).
+ (if proof-action-list
+ (proof-shell-filter-process-output "")))))
+ ;; Now we're looking for the end of the piece of output
+ ;; which will be processed.
+
+ ;; Note that the way this filter works, only one piece of
+ ;; output can be dealt with at a time so we loose sync if
+ ;; there's more than one bit there.
+
+ ;; The blasphemous situation that the proof-action-list
+ ;; is empty is now quietly ignored so that users can
+ ;; type in the shell buffer without being screamed at.
+ ;; Also allows the process to output something for
+ ;; some other reason (perhaps it's just being chatty),
+ ;; although that could break the synchronization.
+ ;; Note that any "unexpected" output like this gets
+ ;; ignored.
+ (if proof-action-list
+ (let ((urgnt (marker-position
+ proof-shell-urgent-message-marker))
+ string startpos)
+ ;; Ignore any urgent messages that have already been
+ ;; dealt with. This loses in the case mentioned above.
+ ;; A more general way of doing this would be
+ ;; to filter out or delete the urgent messages which
+ ;; have been processed already.
+ (setq startpos (goto-char (marker-position proof-marker)))
+ (if (and urgnt
+ (< startpos urgnt))
+ (setq startpos (goto-char urgnt))
+ ;; Otherwise, skip possibly a (fudge) space and new line
+ (if (eq (char-after startpos) ?\ )
+ (setq startpos (goto-char (+ 2 startpos)))
+ (setq startpos (goto-char (1+ startpos)))))
+ ;; Find next prompt.
+ (if (re-search-forward
+ proof-shell-annotated-prompt-regexp nil t)
+ (progn
+ (backward-char (- (match-end 0) (match-beginning 0)))
+ ;; NB: decoding x-symbols here is perhaps a bit
+ ;; expensive; moreover it leads to problems
+ ;; processing special characters as annotations
+ ;; later on. So no fontify or decode.
+ ;; (proof-fontify-region startpos (point))
+ (setq string (buffer-substring startpos (point)))
+ (goto-char (point-max))
+ ;; Process output string.
+ (proof-shell-filter-process-output string))))
+ ;; If proof-action-list is empty, make sure the process lock
+ ;; is not held! This should solve continual "proof shell busy"
+ ;; error messages which sometimes occur during development,
+ ;; at least.
+ (if proof-shell-busy
+ (progn
+ (proof-debug
+ "proof-shell-filter found empty action list yet proof shell busy.")
+ (proof-release-lock))))))))
+
+
+
+(defun proof-shell-filter-process-output (string)
+ "Subroutine of proof-shell-filter to process output STRING.
+
+Appropriate action is taken depending on the what
+proof-shell-process-output returns: maybe handle an interrupt, an
+error, or deal with ordinary output which is a candidate for the goal
+or response buffer. Ordinary output is only displayed when the proof
+action list becomes empty, to avoid a confusing rapidly changing
+output.
+
+After processing the current output, the last step undertaken
+by the filter is to send the next command from the queue."
+ (let
+ ;; Some functions may care which command invoked them
+ ((cmd (nth 1 (car proof-action-list))))
+ (save-excursion
+ ;;
+ (proof-shell-process-output cmd string)
+ ;; da: Added this next line to redisplay, for proof-toolbar
+ ;; FIXME: should do this for all frames displaying the script
+ ;; buffer!
+ ;; ODDITY: has strange effect on highlighting, leave it.
+ ;; (redisplay-frame (window-buffer t)
+ (cond
+ ((eq proof-shell-last-output-kind 'error)
+ (proof-shell-handle-error cmd))
+ ((eq proof-shell-last-output-kind 'interrupt)
+ (proof-shell-handle-interrupt))
+ ((eq proof-shell-last-output-kind 'loopback)
+ (proof-shell-insert-loopback-cmd proof-shell-last-output)
+ (proof-shell-exec-loop))
+ ;; Otherwise, it's something that we should delay
+ ;; handling: we don't act on it unless all the commands
+ ;; in the queue region have been processed.
+ ;; (e.g. goals/response message)
+ (t
+ (setq proof-shell-delayed-output-kind proof-shell-last-output-kind)
+ (setq proof-shell-delayed-output proof-shell-last-output)
+ (if (proof-shell-exec-loop)
+ (proof-shell-handle-delayed-output)))))))
+
+
+
+(defun proof-shell-dont-show-annotations (&optional buffer)
+ "Set display values of annotations in BUFFER to be invisible.
+
+Annotations are characters 128-255."
+ (interactive)
+ (with-current-buffer (or buffer (current-buffer))
+ (let ((disp (make-display-table))
+ (i 128))
+ (while (< i 256)
+ (aset disp i [])
+ (incf i))
+ (cond ((fboundp 'add-spec-to-specifier)
+ (add-spec-to-specifier current-display-table disp (current-buffer)))
+ ((boundp 'buffer-display-table)
+ (setq buffer-display-table disp))))))
+
+(defun proof-shell-show-annotations ()
+ "Remove display table specifier from current buffer.
+This function is for testing purposes only, to reveal 8-bit characters
+in the shell buffer. Use proof-shell-dont-show-annotations to turn
+them off again.
+XEmacs only."
+ (interactive)
+ (remove-specifier current-display-table (current-buffer)))
+
+
+
+
+
+
+
+;;
+;; proof-shell-invisible-command: used to implement user-level commands.
+;;
+
+;;;###autoload
+(defun proof-shell-wait (&optional timeout)
+ "Busy wait for proof-shell-busy to become nil, or for TIMEOUT seconds.
+Needed between sequences of commands to maintain synchronization,
+because Proof General does not allow for the action list to be extended
+in some cases. May be called by proof-shell-invisible-command."
+ (while proof-shell-busy
+ (accept-process-output nil timeout)
+ (sit-for 0)))
+
+
+(defun proof-done-invisible (span)
+ "Callback for proof-shell-invisible-command.
+Calls proof-state-change-hook."
+ (run-hooks 'proof-state-change-hook))
+
+; new code to experiment with after 3.2
+;(defun proof-done-invisible (&optional span)
+; "Callback for proof-shell-invisible-command.
+;Calls proof-state-change-hook."
+; (run-hooks 'proof-state-change-hook)
+; (remove-hook 'proof-shell-handle-error-or-interrupt-hook
+; 'proof-shell-invisible-hook-fn))
+;; Seems to be hard to write this stuff without a temporary variable
+;; (or higher-order functions, sob).
+;(defun proof-shell-invisible-hook-fn ()
+; "Temporary function holding hook for proof-shell-invisible-command.")
+
+;(defmacro proof-shell-invisible-failure-msg (errormsg)
+; "Construct a value for `proof-shell-handle-error-or-interrupt-hook'.
+;Give error message ERRORMSG, then remove self from queue."
+; `(lambda ()
+; (proof-done-invisible)
+; (error ,(eval errormsg))))
+
+;(defmacro proof-shell-invisible-failure-fn (fn)
+; "Construct a value for `proof-shell-handle-error-or-interrupt-hook'.
+;Call function fn, then remove self from queue."
+; `(lambda ()
+; (proof-done-invisible)
+; (,(eval fn))))
+;
+; extra arg ERRORMSGFN to proof-shell-invisible-command:
+;
+;If ERRORMSGFN is non-nil, if the command leads to an error or interrupt
+;in the proof assistant, we will give an error. If ERRORMSGFN
+;is a string, (error ERRORMSGFN) is called; if ERRORMSGFN is a function,
+;it is called directly. If ERRORMSGFN is not a string or function,
+;we will give standard error messages for interrupts and errors."
+;
+; Other (sensible) possibility is to call
+; proof-shell-handle-error-or-interrupt-hook with span as argument.
+
+;;;###autoload
+(defun proof-shell-invisible-command (cmd &optional wait)
+ "Send CMD to the proof process.
+Automatically add proof-terminal-char if necessary, examining
+proof-shell-no-auto-terminate-commands.
+By default, let the command be processed asynchronously.
+But if optional WAIT command is non-nil, wait for processing to finish
+before and after sending the command.
+If WAIT is an integer, wait for that many seconds afterwards."
+ (unless (or (null proof-terminal-char)
+ (not proof-shell-auto-terminate-commands)
+ (string-match (concat
+ (regexp-quote
+ (char-to-string proof-terminal-char))
+ "[ \t]*$") cmd))
+ (setq cmd (concat cmd (char-to-string proof-terminal-char))))
+ (if wait (proof-shell-wait))
+ (proof-shell-ready-prover) ; start proof assistant; set vars.
+ (proof-start-queue nil nil
+ (list (proof-shell-command-queue-item
+ cmd 'proof-done-invisible)))
+ (if wait (proof-shell-wait (if (numberp wait) wait))))
+
+
+
+
+
+
+
+;;
+;; Proof General shell mode definition
+;;
+
+
+(eval-and-compile ; to define vars
+;;; NB: autoload tag below doesn't work for d-d-m, autoload is in proof.el
+;;;###autoload
+(define-derived-mode proof-shell-mode comint-mode
+ "proof-shell" "Proof General shell mode class for proof assistant processes"
+ (setq proof-buffer-type 'shell)
+
+ ;; Clear state
+ (proof-shell-clear-state)
+
+ (make-local-variable 'proof-shell-insert-hook)
+
+ ;; comint customisation. comint-prompt-regexp is used by
+ ;; comint-get-old-input, comint-skip-prompt, comint-bol, backward
+ ;; matching input, etc.
+ (if proof-shell-prompt-pattern
+ (setq comint-prompt-regexp proof-shell-prompt-pattern))
+
+ ;; An article by Helen Lowe in UITP'96 suggests that the user should
+ ;; not see all output produced by the proof process.
+ (remove-hook 'comint-output-filter-functions
+ 'comint-postoutput-scroll-to-bottom 'local)
+
+ (add-hook 'comint-output-filter-functions 'proof-shell-filter nil 'local)
+ (setq comint-get-old-input (function (lambda () "")))
+ (proof-shell-dont-show-annotations)
+
+ ;; Proof marker is initialised in filter to first prompt found
+ (setq proof-marker (make-marker))
+ ;; Urgent message marker records end position of last urgent
+ ;; message seen.
+ (setq proof-shell-urgent-message-marker (make-marker))
+ ;; Urgent message scan marker records starting position to
+ ;; scan for urgent messages from
+ (setq proof-shell-urgent-message-scanner (make-marker))
+ (set-marker proof-shell-urgent-message-scanner (point-min))
+
+ ;; easy-menu-add must be in the mode function for XEmacs.
+ (easy-menu-add proof-shell-mode-menu proof-shell-mode-map)
+
+ ;; [ Should already be in proof-goals-buffer, really.]
+
+ ;; FIXME da: before entering proof assistant specific code,
+ ;; we'd do well to check that process is actually up and
+ ;; running now. If not, call the process sentinel function
+ ;; to display the buffer, and give an error.
+ ;; (Problem to fix is that process can die before sentinel is set:
+ ;; it ought to be set just here, perhaps: but setting hook here
+ ;; had no effect for some odd reason).
+ ;; What actually happens: an obscure infinite loop somewhere
+ ;; that can lead to "lisp nesting exceeded" somewhere, when
+ ;; shell startup fails. Ugly, but low priority to fix.
+ ))
+
+;; watch difference with proof-shell-menu, proof-shell-mode-menu.
+(defvar proof-shell-menu proof-shared-menu
+ "The menu for the Proof-assistant shell.")
+
+(easy-menu-define proof-shell-mode-menu
+ proof-shell-mode-map
+ "Menu used in Proof General shell mode."
+ (cons proof-general-name proof-shell-menu))
+
+
+;;
+;; Sanity checks on important settings
+;;
+
+(defconst proof-shell-important-settings
+ '(proof-shell-annotated-prompt-regexp ; crucial
+ ))
+
+
+(defun proof-shell-config-done ()
+ "Initialise the specific prover after the child has been configured.
+Every derived shell mode should call this function at the end of
+processing."
+ (save-excursion
+ (set-buffer proof-shell-buffer)
+
+ ;; Give warnings if some crucial settings haven't been made
+ (dolist (sym proof-shell-important-settings)
+ (proof-warn-if-unset "proof-shell-config-done" sym))
+
+ ;; We do not use font-lock here, it's a waste of cycles.
+ ;; (proof-font-lock-configure-defaults nil)
+
+ (let ((proc (get-buffer-process proof-shell-buffer)))
+ ;; Add the kill buffer function and process sentinel
+ (make-local-hook 'kill-buffer-hook)
+ (add-hook 'kill-buffer-hook 'proof-shell-kill-function t t)
+ (set-process-sentinel proc 'proof-shell-bail-out)
+
+ ;; Pre-sync initialization command. This is necessary
+ ;; for proof assistants which change their output modes
+ ;; only after some initializations.
+ (if proof-shell-pre-sync-init-cmd
+ (proof-shell-insert proof-shell-pre-sync-init-cmd 'init-cmd))
+
+ ;; Flush pending output from startup (it gets hidden from the user)
+ ;; while waiting for the prompt to appear
+ (while (and (process-live-p proc)
+ (null (marker-position proof-marker)))
+ (accept-process-output proc 1))
+
+ (if (process-live-p proc)
+ (progn
+ ;; Send main intitialization command and wait for it to be
+ ;; processed. Also ensure that proof-action-list is initialised.
+ (setq proof-action-list nil)
+ (if proof-shell-init-cmd
+ (proof-shell-invisible-command proof-shell-init-cmd t))
+
+ ;; Configure for x-symbol
+ (proof-x-symbol-shell-config))))))
+
+
+;;
+;; Response buffer mode
+;;
+
+(eval-and-compile
+(define-derived-mode proof-universal-keys-only-mode fundamental-mode
+ proof-general-name "Universal keymaps only"
+ ;; Doesn't seem to supress TAB, RET
+ (suppress-keymap proof-universal-keys-only-mode-map 'all)
+ (proof-define-keys proof-universal-keys-only-mode-map
+ proof-universal-keys)))
+
+(eval-and-compile
+(define-derived-mode proof-response-mode proof-universal-keys-only-mode
+ "PGResp" "Responses from Proof Assistant"
+ (setq proof-buffer-type 'response)
+ (define-key proof-response-mode-map [q] 'bury-buffer)
+ (easy-menu-add proof-response-mode-menu proof-response-mode-map)
+ (easy-menu-add proof-assistant-menu proof-response-mode-map)
+ (proof-toolbar-setup)
+ (setq proof-shell-next-error nil) ; all error msgs lost!
+ (erase-buffer)))
+
+(easy-menu-define proof-response-mode-menu
+ proof-response-mode-map
+ "Menu for Proof General response buffer."
+ (cons proof-general-name
+ (append
+ proof-toolbar-scripting-menu
+ proof-shared-menu
+ proof-config-menu
+ proof-bug-report-menu)))
+
+
+(defun proof-response-config-done ()
+ "Complete initialisation of a response-mode derived buffer."
+ (proof-font-lock-configure-defaults nil)
+ (proof-x-symbol-configure))
+
+
+;;
+;; Goals buffer mode
+;;
+
+
+(eval-and-compile ; to define proof-goals-mode-map
+(define-derived-mode proof-goals-mode proof-universal-keys-only-mode
+ proof-general-name
+ "Mode for goals display.
+May enable proof-by-pointing or similar features.
+\\{proof-goals-mode-map}"
+ ;; defined-derived-mode proof-goals-mode initialises proof-goals-mode-map
+ (setq proof-buffer-type 'goals)
+ (easy-menu-add proof-goals-mode-menu proof-goals-mode-map)
+ (easy-menu-add proof-assistant-menu proof-goals-mode-map)
+ (proof-toolbar-setup)
+ (erase-buffer)))
+
+;;
+;; Keys for goals buffer
+;;
+(define-key proof-goals-mode-map [q] 'bury-buffer)
+(cond
+(proof-running-on-XEmacs
+(define-key proof-goals-mode-map [(button2)] 'pbp-button-action)
+(define-key proof-goals-mode-map [(control button2)] 'proof-undo-and-delete-last-successful-command)
+;; button 2 is a nuisance on 2 button mice, so we'll do 1 as well.
+;; Actually we better hadn't, people like to use it for cut and paste.
+;; (define-key proof-goals-mode-map [(button1)] 'pbp-button-action)
+;; (define-key proof-goals-mode-map [(control button1)] 'proof-undo-and-delete-last-successful-command)
+(define-key proof-goals-mode-map [(button3)] 'pbp-yank-subterm))
+(t
+(define-key proof-goals-mode-map [mouse-2] 'pbp-button-action)
+(define-key proof-goals-mode-map [C-mouse-2] 'proof-undo-and-delete-last-successful-command)
+;; (define-key proof-goals-mode-map [mouse-1] 'pbp-button-action)
+;; (define-key proof-goals-mode-map [C-mouse-1] 'proof-undo-and-delete-last-successful-command)
+(define-key proof-goals-mode-map [mouse-3] 'pbp-yank-subterm)))
+
+
+;;
+;; Menu for goals buffer (identical to response mode menu currently)
+;;
+(easy-menu-define proof-goals-mode-menu
+ proof-goals-mode-map
+ "Menu for Proof General goals buffer."
+ (cons proof-general-name
+ (append
+ proof-toolbar-scripting-menu
+ proof-shared-menu
+ proof-config-menu
+ proof-bug-report-menu)))
+
+(defun proof-goals-config-done ()
+ "Initialise the goals buffer after the child has been configured."
+ (proof-font-lock-configure-defaults nil)
+ (proof-x-symbol-configure))
+
+
+;;
+;; Multiple frames for goals and response buffers
+;;
+;; -- because who's going to bother do this by hand?
+;;
+
+(defvar proof-shell-special-display-regexp nil
+ "Regexp for special-display-regexps for multiple frame use.
+Internal variable, setting this will have no effect!")
+
+(defun proof-multiple-frames-enable ()
+ (cond
+ (proof-multiple-frames-enable
+ (setq special-display-regexps
+ (union special-display-regexps
+ (list proof-shell-special-display-regexp)))
+ ;; If we're on XEmacs with toolbar, turn off toolbar and
+ ;; menubar for the small frames to save space.
+ ;; FIXME: this could be implemented more smoothly
+ ;; with property lists, and specifiers should perhaps be set
+ ;; for the frame rather than the buffer. Then could disable
+ ;; minibuffer, too.
+ (if (featurep 'toolbar)
+ (progn
+ (proof-with-current-buffer-if-exists
+ proof-response-buffer
+ (set-specifier default-toolbar-visible-p nil (current-buffer))
+ ;; (set-specifier minibuffer (minibuffer-window) (current-buffer))
+ (set-specifier has-modeline-p nil (current-buffer))
+ ;; (and (specifierp 'default-gutter-visible)
+ ;; (set-specifier default-gutter-visibility nil (current-buffer)))
+ (set-specifier menubar-visible-p nil (current-buffer)))
+ (proof-with-current-buffer-if-exists
+ proof-goals-buffer
+ (set-specifier default-toolbar-visible-p nil (current-buffer))
+ ;; (set-specifier minibuffer (minibuffer-window))
+ (set-specifier has-modeline-p nil (current-buffer))
+ (set-specifier menubar-visible-p nil (current-buffer)))
+ (proof-with-current-buffer-if-exists
+ proof-trace-buffer
+ (set-specifier default-toolbar-visible-p nil (current-buffer))
+ ;; (set-specifier minibuffer (minibuffer-window) (current-buffer))
+ (set-specifier has-modeline-p nil (current-buffer))
+ (set-specifier menubar-visible-p nil (current-buffer)))))
+ ;; Try to trigger re-display of goals/response buffers,
+ ;; on next interaction.
+ ;; FIXME: would be nice to do the re-display here, rather
+ ;; than waiting for next re-display
+ (delete-other-windows
+ (if proof-script-buffer
+ (get-buffer-window proof-script-buffer t))))
+ (t
+ ;; FIXME: would be nice to kill off frames automatically,
+ ;; but let's leave it to the user for now.
+ (setq special-display-regexps
+ (delete proof-shell-special-display-regexp
+ special-display-regexps)))))
+
+
+;;
+;; Next error function.
+;; Added in 3.2
+;;
+
+(defvar proof-shell-next-error nil
+ "Error counter in response buffer to count for next error message.")
+
+;;;###autoload
+(defun proof-next-error (&optional argp)
+ "Jump to location of next error reported in the response buffer.
+
+A prefix arg specifies how many error messages to move;
+negative means move back to previous error messages.
+Just C-u as a prefix means reparse the error message buffer
+and start at the first error."
+ (interactive "P")
+ (if (and ;; At least one setting must be configured
+ proof-shell-next-error-regexp
+ ;; Response buffer must be live
+ (or
+ (buffer-live-p proof-response-buffer)
+ (error "proof-next-error: no response buffer to parse!")))
+ (let ((wanted-error (or (and (not (consp argp))
+ (+ (prefix-numeric-value argp)
+ (or proof-shell-next-error 0)))
+ (and (consp arg) 1)
+ (or proof-shell-next-error 1)))
+ line column file errpos)
+ (set-buffer proof-response-buffer)
+ (goto-char (point-min))
+ (if (re-search-forward proof-shell-next-error-regexp
+ nil t wanted-error)
+ (progn
+ (setq errpos (save-excursion
+ (goto-char (match-beginning 0))
+ (beginning-of-line)
+ (point)))
+ (setq line (match-string 2)) ; may be unset
+ (if line (setq line (string-to-int line)))
+ (setq column (match-string 3)) ; may be unset
+ (if column (setq column (string-to-int column)))
+ (setq proof-shell-next-error wanted-error)
+ (if (and
+ proof-shell-next-error-filename-regexp
+ ;; Look for the most recently mentioned filename
+ (re-search-backward
+ proof-shell-next-error-filename-regexp nil t))
+ (setq file
+ (if (file-exists-p (match-string 2))
+ (match-string 2)
+ ;; May need post-processing to extract filename
+ (if proof-shell-next-error-extract-filename
+ (format
+ proof-shell-next-error-extract-filename
+ (match-string 2))))))
+ ;; Now find the other buffer we need to display
+ (let*
+ ((errbuf
+ (if file
+ (find-file-noselect file)
+ (or proof-script-buffer
+ ;; We could make more guesses here,
+ ;; e.g. last script buffer active
+ ;; (keep a record of it?)
+ (error
+ "proof-next-error: can't guess file for error message"))))
+ (pop-up-windows t)
+ (rebufwindow
+ (or (get-buffer-window proof-response-buffer 'visible)
+ ;; Pop up a window.
+ (display-buffer proof-response-buffer))))
+ ;; Make sure the response buffer stays where it is,
+ ;; and make sure source buffer is visible
+ (select-window rebufwindow)
+ (pop-to-buffer errbuf)
+ ;; Display the error message in the response buffer
+ (set-window-point rebufwindow errpos)
+ (set-window-start rebufwindow errpos)
+ ;; Find the error location in the error buffer
+ (set-buffer errbuf)
+ ;; FIXME: no handling of selective display here
+ (goto-line line)
+ (if (and column (> column 1))
+ (move-to-column (1- column)))))
+ (setq proof-shell-next-error nil)
+ (error "proof-next-error: couldn't find next error.")))))
+
+
+
+
+(provide 'proof-shell)
+;; proof-shell.el ends here.
diff --git a/generic/proof-site.el b/generic/proof-site.el
new file mode 100644
index 00000000..8855b327
--- /dev/null
+++ b/generic/proof-site.el
@@ -0,0 +1,378 @@
+;; proof-site.el -- Loading stubs for Proof General.
+;; Configuration for site and choice of provers.
+;;
+;; Copyright (C) 1998-2001 LFCS Edinburgh.
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; NB: Normally you will not need to edit this file.
+;;
+
+(if (featurep 'proof-site)
+ nil ; don't load twice
+
+(if (or (not (boundp 'emacs-major-version))
+ (< emacs-major-version 20))
+ (error "Proof General is not compatible with Emacs %s" emacs-version))
+
+(defgroup proof-general nil
+ "Customization of Proof General."
+ :group 'external
+ :group 'processes
+ :prefix "proof-")
+
+
+;; This customization group gathers together
+;; the internals of Proof General which control
+;; configuration to different proof assistants.
+;; This is for development purposes rather than
+;; user-level customization, so this group does
+;; not belong to 'proof-general (or any other group).
+(defgroup proof-general-internals nil
+ "Customization of Proof General internals."
+ :prefix "proof-")
+
+
+;; Master table of supported assistants.
+(defcustom proof-assistant-table
+ '(;; For demonstration instance of Proof General,
+ ;; export PROOFGENERAL_ASSISTANTS=demoisa.
+ ;;
+ ;; To use Isabelle/Isar instead of classic Isabelle,
+ ;; export PROOFGENERAL_ASSISTANTS=isar
+ ;;
+ (demoisa "Isabelle Demo" "\\.ML$")
+ (isar "Isabelle/Isar" "\\.thy$")
+ (isa "Isabelle" "\\.ML$\\|\\.thy$")
+ ;; Next line for testing only
+ ;; (pgip "PGIP/Isa" "\\.ML$\\|\\.thy$")
+ (lego "LEGO" "\\.l$")
+ (coq "Coq" "\\.v$")
+ (phox "PhoX" "\\.phx$")
+ ;; The following provers are not fully supported,
+ ;; and have only preliminary support written
+ ;; (please volunteer to improve them!)
+ (hol98 "HOL" "\\.sml$")
+ (acl2 "ACL2" "\\.acl2$")
+ ;; The following provers have experimental support
+ (plastic "Plastic" "\\.lf$")
+ (twelf "Twelf" "\\.elf$")
+ )
+ "*Proof General's table of supported proof assistants.
+Extend this table to add a new proof assistant.
+Each entry is a list of the form
+
+ (SYMBOL NAME AUTOMODE-REGEXP)
+
+The NAME is a string, naming the proof assistant.
+The SYMBOL is used to form the name of the mode for the
+assistant, `SYMBOL-mode', run when files with AUTOMODE-REGEXP
+are visited. SYMBOL is also used to form the name of the
+directory and elisp file for the mode, which will be
+
+ PROOF-HOME-DIRECTORY/SYMBOL/SYMBOL.el
+
+where `PROOF-HOME-DIRECTORY' is the value of the
+variable proof-home-directory."
+ :type '(repeat (list symbol string string))
+ :group 'proof-general-internals)
+
+
+
+
+;; Directories
+
+(defun proof-home-directory-fn ()
+ "Used to set proof-home-directory"
+ (let ((s (getenv "PROOFGENERAL_HOME")))
+ (if s
+ (if (string-match "/$" s) s (concat s "/"))
+ (let ((curdir
+ (or
+ (and load-in-progress (file-name-directory load-file-name))
+ (file-name-directory (buffer-file-name)))))
+ (file-name-directory (substring curdir 0 -1))))))
+
+(defcustom proof-home-directory
+ (proof-home-directory-fn)
+ "Directory where Proof General is installed. Ends with slash.
+Default value taken from environment variable `PROOFGENERAL_HOME' if set,
+otherwise based on where the file `proof-site.el' was loaded from.
+You can use customize to set this variable."
+ :type 'directory
+ :group 'proof-general-internals)
+
+(defcustom proof-images-directory
+ (concat proof-home-directory "images/")
+ "Where Proof General image files are installed. Ends with slash."
+ :type 'directory
+ :group 'proof-general-internals)
+
+(defcustom proof-info-directory
+ (concat proof-home-directory "doc/")
+ "Where Proof General Info files are installed. Ends with slash."
+ :type 'directory
+ :group 'proof-general-internals)
+
+;; Add the info directory to the end of Emacs Info path if need be.
+;; It's easier to do this after Info has loaded because of the
+;; complicated way the Info-directory-list is set.
+
+(eval-after-load
+ "info"
+ '(or (member proof-info-directory Info-directory-list)
+ (progn
+ (setq Info-directory-list
+ (cons proof-info-directory
+ Info-directory-list))
+ ;; Clear cache of info dir
+ (setq Info-dir-contents nil))))
+
+
+;; A utility function. Is there an alternative?
+(defun proof-string-to-list (s separator)
+ "Return the list of words in S separated by SEPARATOR.
+If S is nil, return empty list."
+ (if s
+ (let ((end-of-word-occurence (string-match (concat separator "+") s)))
+ (if (not end-of-word-occurence)
+ (if (string= s "")
+ nil
+ (list s))
+ (cons (substring s 0 end-of-word-occurence)
+ (proof-string-to-list
+ (substring s
+ (string-match (concat "[^" separator "]")
+ s end-of-word-occurence))
+ separator))))))
+
+(defcustom proof-assistants nil
+ (concat
+ "*Choice of proof assistants to use with Proof General.
+A list of symbols chosen from:"
+ (apply 'concat (mapcar (lambda (astnt)
+ (concat " '" (symbol-name (car astnt))))
+ proof-assistant-table))
+".\nEach proof assistant defines its own instance of Proof General,
+providing session control, script management, etc. Proof General
+will be started automatically for the assistants chosen here.
+To avoid accidently invoking a proof assistant you don't have,
+only select the proof assistants you (or your site) may need.
+
+You can select which proof assistants you want by setting this
+variable before `proof-site.el' is loaded, or by setting
+the environment variable `PROOFGENERAL_ASSISTANTS' to the
+symbols you want, for example \"lego isa\". Or you can
+edit the file `proof-site.el' itself.
+
+Note: to change proof assistant, you must start a new Emacs session.")
+ :type (cons 'set
+ (mapcar (lambda (astnt)
+ (list 'const ':tag (car (cdr astnt)) (car astnt)))
+ proof-assistant-table))
+ :group 'proof-general)
+
+
+;; Extend load path for the generic files.
+(let ((proof-lisp-path
+ (concat proof-home-directory "generic/")))
+ (or (member proof-lisp-path load-path)
+ (setq load-path
+ (cons proof-lisp-path load-path))))
+
+;; During compilation from the Makefile, generic is on the load path.
+;; Add all of the prover directories.
+;; FIXME: this doesn't work quite right. We want to test
+;; whether we are running during a compilation. How?
+; (eval-when-compile
+; (dolist (assistant proof-assistant-table)
+; (let ((path (concat proof-home-directory
+; (concat (symbol-name (car assistant)) "/"))))
+; (or (member path load-path)
+; (setq load-path
+; (cons path load-path))))))
+
+(defun proof-ready-for-assistant (assistant-name assistantsym)
+ "Configure PG for ASSISTANT-NAME, symbol ASSISTANTSYM."
+ (let*
+ ((sname (symbol-name assistantsym))
+ (cusgrp-rt
+ ;; Normalized a bit to remove spaces and funny characters
+ ;; FIXME UGLY compatibility hack
+ ;; (can use cl macro `substitute' but want to avoid cl here)
+ (if (fboundp 'replace-in-string)
+ ;; XEmacs
+ (replace-in-string (downcase assistant-name) "/\\|[ \t]+" "-")
+ ;; FSF
+ (subst-char-in-string
+ ?/ ?\-
+ (subst-char-in-string ?\ ?\- (downcase assistant-name)))))
+ ;; END compatibility hack
+ (cusgrp (intern cusgrp-rt))
+ (cus-internals (intern (concat cusgrp-rt "-config")))
+ ;; NB: Dir name for each prover is the same as its symbol name!
+ (elisp-dir sname)
+ (loadpath-elt (concat proof-home-directory elisp-dir "/")))
+ (eval `(progn
+ ;; Make a customization group for this assistant
+ (defgroup ,cusgrp nil
+ ,(concat "Customization of user options for " assistant-name
+ " Proof General.")
+ :group 'proof-general)
+ ;; And another one for internals
+ (defgroup ,cus-internals nil
+ ,(concat "Customization of internal settings for "
+ assistant-name " configuration.")
+ :group 'proof-general-internals
+ :prefix ,(concat sname "-"))
+
+ ;; Set the proof-assistant configuration variables
+ ;; NB: tempting to use customize-set-variable: wrong!
+ ;; Here we treat customize as extended docs for these
+ ;; variables.
+ (setq proof-assistant-cusgrp (quote ,cusgrp))
+ (setq proof-assistant-internals-cusgrp (quote ,cus-internals))
+ (setq proof-assistant ,assistant-name)
+ (setq proof-assistant-symbol (quote ,assistantsym))
+ ;; Extend the load path if necessary
+ (if (not (member ,loadpath-elt load-path))
+ (setq load-path (cons ,loadpath-elt load-path)))))))
+
+;; Now add auto-loads and load-path elements to support the
+;; proof assistants selected, and define a stub
+(let ((assistants
+ (or (mapcar 'intern
+ (proof-string-to-list
+ (getenv "PROOFGENERAL_ASSISTANTS") " "))
+ proof-assistants
+ (mapcar (lambda (astnt) (car astnt)) proof-assistant-table))))
+ (while assistants
+ (let*
+ ((assistant (car assistants)) ; compiler bogus warning here
+ (nameregexp
+ (or
+ (cdr-safe
+ (assoc assistant
+ proof-assistant-table))
+ (error "proof-site: symbol " (symbol-name assistant)
+ "is not in proof-assistant-table")))
+ (assistant-name (car nameregexp))
+ (regexp (car (cdr nameregexp)))
+ (sname (symbol-name assistant))
+ ;; NB: File name for each prover is the same as its symbol name!
+ (elisp-file sname)
+ ;; NB: Mode name for each prover is <symbol name>-mode!
+ (proofgen-mode (intern (concat sname "-mode")))
+ ;; NB: Customization group for each prover is its l.c.'d name!
+
+ ;; Stub to do some automatic initialization and load
+ ;; the specific code.
+ (mode-stub
+ `(lambda ()
+ ,(concat
+ "Major mode for editing scripts for proof assistant "
+ assistant-name
+ ".\nThis is a stub which loads the real function.")
+ (interactive)
+ ;; Give a message and stop loading if proof-assistant is
+ ;; already set: things go wrong if proof general is
+ ;; loaded for more than one prover.
+ (cond
+ ((and (boundp 'proof-assistant)
+ (not (string-equal proof-assistant "")))
+ (or (string-equal proof-assistant ,assistant-name)
+ ;; If Proof General was partially loaded last time
+ ;; and mode function wasn't redefined, be silent.
+ (message
+ (concat
+ ,assistant-name
+ " Proof General error: Proof General already in use for "
+ proof-assistant))))
+ (t
+ ;; prepare variables and load path
+ (proof-ready-for-assistant ,assistant-name
+ (quote ,assistant))
+ ;; load the real mode and invoke it.
+ (load-library ,elisp-file)
+ (,proofgen-mode))))))
+
+ (setq auto-mode-alist
+ (cons (cons regexp proofgen-mode) auto-mode-alist))
+
+ (fset proofgen-mode mode-stub)
+
+ (setq assistants (cdr assistants))
+ )))
+
+;; WARNING: do not edit below here
+;; (the next constant is set automatically, also its form is
+;; relied upon in proof-config.el, for proof-splash-contents)
+(defconst proof-general-version "Proof General Version 3.4pre020214. Released by da."
+ "Version string identifying Proof General release.")
+
+;; Now define a few autoloads and basic variables.
+
+;; 1.8.01: add a dummy package-provide command so proof-autoloads
+;; is compatible with FSF Emacs. Needed for next provide
+;; (otherwise would be in proof-compat.el).
+(or (fboundp 'package-provide)
+ (defun package-provide (name &rest attributes)
+ "Dummy version of XEmacs function for FSF compatibility."))
+
+
+(require 'proof-autoloads) ; autoloaded functions
+
+(defcustom proof-assistant-cusgrp nil
+ "Symbol for the customization group of the user options for the proof assistant.
+Do not change this variable! It is set automatically by the mode
+stub defined in proof-site, from the name given in
+proof-assistant-table."
+ :type 'sexp
+ :group 'prover-config)
+
+(defcustom proof-assistant-internals-cusgrp nil
+ "Symbol for the customization group of the PG internal settings proof assistant.
+Do not change this variable! It is set automatically by the mode
+stub defined in proof-site, from the name given in
+proof-assistant-table."
+ :type 'sexp
+ :group 'prover-config)
+
+(defcustom proof-assistant ""
+ "Name of the proof assistant Proof General is using.
+Do not change this variable! It is set automatically by the mode
+stub defined in proof-site, from the name given in
+proof-assistant-table."
+ :type 'string
+ :group 'prover-config)
+
+(defcustom proof-assistant-symbol nil
+ "Symbol for the proof assistant Proof General is using.
+Used for automatic configuration based on standard variable names.
+Settings will be found by looking for names beginning with this
+symbol as a prefix.
+Do not change this variable! It is set automatically by the mode
+stub defined in proof-site, from the symbols given in
+proof-assistant-table."
+ :type 'sexp
+ :group 'prover-config)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Architecture flags
+;;;
+
+(eval-and-compile
+(defvar proof-running-on-XEmacs (string-match "XEmacs" emacs-version)
+ "Non-nil if Proof General is running on XEmacs.")
+(defvar proof-running-on-Emacs21 (and (not proof-running-on-XEmacs)
+ (>= emacs-major-version 21))
+ "Non-nil if Proof General is running on GNU Emacs 21 or later.")
+;; rough test for XEmacs on win32, anyone know about GNU Emacs on win32?
+(defvar proof-running-on-win32 (fboundp 'win32-long-file-name)
+ "Non-nil if Proof General is running on a win32 system."))
+
+(provide 'proof-site))
+;; proof-site.el ends here
diff --git a/generic/proof-splash.el b/generic/proof-splash.el
new file mode 100644
index 00000000..98d17d53
--- /dev/null
+++ b/generic/proof-splash.el
@@ -0,0 +1,264 @@
+;; proof-splash.el -- Splash welcome screen for Proof General
+;;
+;; Copyright (C) 1998-2001 LFCS Edinburgh.
+;; Author: David Aspinall
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Customization of splash screen (was in proof-config)
+
+(defcustom proof-splash-enable t
+ "*If non-nil, display a splash screen when Proof General is loaded."
+ :type 'boolean
+ :group 'proof-user-options)
+
+(defcustom proof-splash-time 2
+ "Minimum number of seconds to display splash screen for.
+The splash screen may be displayed for a couple of seconds longer than
+this, depending on how long it takes the machine to initialise
+Proof General."
+ :type 'number
+ :group 'proof-general-internals)
+
+(defcustom proof-splash-contents
+ '(list
+ nil
+;;; Remove the text for now: XEmacs makes a mess of displaying the
+;;; transparent parts of the gif (at least, on all machines I have seen)
+;;; (proof-splash-display-image "pg-text" t)
+ nil
+ (proof-splash-display-image "ProofGeneral")
+ nil
+ "Welcome to"
+ (concat proof-assistant " Proof General!")
+ nil
+ (substring proof-general-version
+ (string-match "Version [^ ]+ "
+ proof-general-version)
+ (match-end 0))
+ nil
+ "(C) LFCS, University of Edinburgh, 2001."
+ nil
+ nil
+" Please send problems and suggestions to proofgen@dcs.ed.ac.uk,
+ or use the menu command Proof-General -> Submit bug report."
+ nil
+ ;; Don't bother with XEmacs propaganda for GNU Emacs 21.
+ (unless (or proof-running-on-XEmacs proof-running-on-Emacs21)
+ "For a better Proof General experience, please use XEmacs")
+ (unless (or proof-running-on-XEmacs proof-running-on-Emacs21)
+ "(visit http://www.xemacs.org)"))
+ "Evaluated to configure splash screen displayed when entering Proof General.
+A list of the screen contents. If an element is a string or an image
+specifier, it is displayed centred on the window on its own line.
+If it is nil, a new line is inserted."
+ :type 'sexp
+ :group 'proof-general-internals)
+
+(defcustom proof-splash-extensions
+ (if (featurep 'proof-config) nil
+ ;; Display additional hint if we guess we're being loaded
+ ;; by shell script rather than find-file.
+ ;; FIXME (minor): shouldn't be defcustom since evaluated here
+ '(list
+ "To start using Proof General, visit a proof script file"
+ "for your prover, using C-x C-f or the \"File\" menu."))
+ "Prover specific extensions of splash screen.
+These are evaluated and appended to `proof-splash-contents'."
+ :type 'sexp
+ :group 'prover-config)
+
+(defconst proof-splash-welcome "*Proof General Welcome*"
+ "Name of the Proof General splash buffer.")
+
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun proof-splash-display-image (name &optional nojpeg)
+ "Construct an image instantiator for an image, or string failing that.
+Different formats are chosen from according to what can be displayed.
+Unless NOJPEG is set, try jpeg first. Then try gif.
+Gif filename depends on colour depth of display."
+ (let ((jpg (vector 'jpeg :file
+ (concat proof-images-directory name ".jpg")))
+ img)
+ (cond
+ ((and window-system (featurep 'jpeg) (not nojpeg)
+ ;; Actually, jpeg can fail even if it is compiled in.
+ ;; FIXME: this test doesn't work, though: still gives
+ ;; t when visiting the file displays failure message.
+ ;; What's the correct test?
+ (valid-instantiator-p jpg 'image))
+ jpg)
+ ((and window-system (featurep 'gif))
+ (vector 'gif :file
+ (concat proof-images-directory
+ (concat name
+ (or (and
+ (fboundp 'device-pixel-depth)
+ (> (device-pixel-depth) 8)
+ ".gif")
+ ;; Low colour gif for poor displays
+ ".8bit.gif")))))
+ ;; Support GNU Emacs 21
+ ((and
+ proof-running-on-Emacs21
+ (setq img
+ (find-image
+ (list
+ (list :type 'jpeg
+ :file (concat proof-images-directory name ".jpg"))
+ (list :type 'gif
+ :file (concat proof-images-directory name ".gif"))))))
+ img)
+ (t
+ (concat "[ image " name " ]")))))
+
+;; Would be nice to get rid of this variable, but it's tricky
+;; to construct a hook function, with a higher order function,
+;; which can easily remove itself.
+(defvar proof-splash-timeout-conf nil
+ "Holds timeout ID and previous window config for proof splash screen.")
+
+(defun proof-splash-centre-spaces (glyph)
+ "Return number of spaces to insert in order to center given glyph or string.
+Borrowed from startup-center-spaces."
+ (let* ((avg-pixwidth (round (/ (frame-pixel-width) (frame-width))))
+ (fill-area-width (* avg-pixwidth (- fill-column left-margin)))
+ (glyph-pixwidth (cond ((stringp glyph)
+ (* avg-pixwidth (length glyph)))
+ ((and (fboundp 'glyphp)
+ (glyphp glyph))
+ (glyph-width glyph))
+ ((proof-emacs-imagep glyph)
+ (car (image-size glyph 'inpixels)))
+ (t
+ (error
+ "proof-splash-centre-spaces: bad arg")))))
+ (+ left-margin
+ (round (/ (/ (- fill-area-width glyph-pixwidth) 2) avg-pixwidth)))))
+
+;; We take some care to preserve the users window configuration
+;; underneath the splash screen. This is just to be polite.
+;; FIXME: not as polite as it could be: if minibuffer is active,
+;; this may deactivate it.
+(defun proof-splash-remove-screen (conf)
+ "Remove splash screen and restore window config to CONF."
+ (let
+ ((splashbuf (get-buffer proof-splash-welcome)))
+ (if splashbuf
+ (progn
+ (if (get-buffer-window splashbuf)
+ ;; Restore the window config if splash is being displayed
+ (progn
+ (kill-buffer splashbuf)
+ (set-window-configuration conf)
+ (if proof-running-on-XEmacs
+ (redraw-frame nil t)))
+ (kill-buffer splashbuf))))))
+
+(defvar proof-splash-seen nil
+ "Flag indicating the user has been subjected to a welcome message.")
+
+;;;###autoload
+(defun proof-splash-display-screen (&optional timeout)
+ "Save window config and display Proof General splash screen.
+If TIMEOUT is non-nil, time out outside this function, definitely
+by end of configuring proof mode.
+Otherwise, timeout inside this function after 10 seconds or so."
+ (interactive "P")
+ (let
+ ;; Keep win config explicitly instead of pushing/popping because
+ ;; if the user switches windows by hand in some way, we want
+ ;; to ignore the saved value. Unfortunately there seems to
+ ;; be no way currently to remove the top item of the stack.
+ ((winconf (current-window-configuration))
+ (splashbuf (get-buffer-create proof-splash-welcome))
+ (after-change-functions nil) ; no font-lock, thank you
+ (splash-contents (append
+ (eval proof-splash-contents)
+ (eval proof-splash-extensions)))
+ s)
+ (with-current-buffer splashbuf
+ (erase-buffer)
+ ;; [ Don't use do-list to avoid loading cl ]
+ (while splash-contents
+ (setq s (car splash-contents))
+ (cond
+ ((and (vectorp s)
+ (valid-instantiator-p s 'image))
+ (let ((gly (make-glyph s)))
+ (indent-to (proof-splash-centre-spaces gly))
+ (set-extent-begin-glyph (make-extent (point) (point)) gly)))
+ ((proof-emacs-imagep s)
+ (indent-to (proof-splash-centre-spaces s))
+ (insert-image s))
+ ((stringp s)
+ (indent-to (proof-splash-centre-spaces s))
+ (insert s)))
+ (newline)
+ (setq splash-contents (cdr splash-contents)))
+ (goto-char (point-min))
+ (set-buffer-modified-p nil)
+ (delete-other-windows (display-buffer splashbuf))
+ (if (fboundp 'redisplay-frame)
+ (redisplay-frame nil t) ; XEmacs special
+ (sit-for 0))
+ (setq proof-splash-timeout-conf
+ (cons
+ (add-timeout (if timeout proof-splash-time 10)
+ 'proof-splash-remove-screen
+ winconf)
+ winconf)))
+ ;; PROBLEM: when to call proof-splash-display-screen?
+ ;; We'd like to call it during loading/initialising. But it's
+ ;; hard to make the screen persist after loading because of the
+ ;; action of display-buffer invoked after the mode function
+ ;; during find-file.
+ ;; To approximate the best behaviour, we assume that this file is
+ ;; loaded by a call to proof-mode. We display the screen now and add
+ ;; a wait procedure temporarily to proof-mode-hook which prevents
+ ;; redisplay until proof-splash-time has elapsed.
+ (if timeout
+ (add-hook 'proof-mode-hook 'proof-splash-timeout-waiter)
+ ;; Otherwise, this was an "about" type of call, so we wait
+ ;; for a key press or timeout event
+ (proof-splash-timeout-waiter))
+ (setq proof-splash-seen t)))
+
+;;;###autoload
+(defun proof-splash-message ()
+ "Make sure the user gets welcomed one way or another."
+ (interactive)
+ (unless (or proof-splash-seen (noninteractive))
+ (if proof-splash-enable
+ (proof-splash-display-screen (not (interactive-p)))
+ ;; Otherwise, a message
+ (message "Welcome to %s Proof General!" proof-assistant))
+ (setq proof-splash-seen t)))
+
+(defun proof-splash-timeout-waiter ()
+ "Wait for proof-splash-timeout or input, then remove self from hook."
+ (while (and (get-buffer proof-splash-welcome)
+ (not (input-pending-p)))
+ (if proof-running-on-XEmacs
+ (sit-for 0 t) ; XEmacs: wait without redisplay
+ ; (sit-for 1 0 t))) ; FSF: NODISP arg seems broken
+ (sit-for 0)))
+ (if (get-buffer proof-splash-welcome)
+ (proof-splash-remove-screen (cdr proof-splash-timeout-conf)))
+ ;; Make sure timeout is stopped
+ (disable-timeout (car proof-splash-timeout-conf))
+ (if (and (input-pending-p)
+ (fboundp 'next-command-event)) ; 3.3: this function
+ ; disappeared from emacs, sigh
+ (setq unread-command-events
+ (cons (next-command-event) unread-command-events)))
+ (remove-hook 'proof-mode-hook 'proof-splash-timeout-waiter))
+
+(provide 'proof-splash)
+;; End of proof-splash.
diff --git a/generic/proof-syntax.el b/generic/proof-syntax.el
new file mode 100644
index 00000000..1cfea82a
--- /dev/null
+++ b/generic/proof-syntax.el
@@ -0,0 +1,286 @@
+;; proof-syntax.el Functions for dealing with syntax
+;; Copyright (C) 1997-2001 LFCS Edinburgh.
+;;
+;; Authors: David Aspinall, Healfdene Goguen,
+;; Thomas Kleymann, Dilip Sequiera
+;;
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+
+(require 'font-lock)
+(require 'proof-config)
+
+;; FIXME da: would regexp-opt be better here? Or maybe
+;; (concat "\\<" (regexp-opt l) "\\>")
+(defun proof-ids-to-regexp (l)
+ "Maps a non-empty list of tokens `l' to a regexp matching any element"
+ (mapconcat (lambda (s) (concat "\\<" s "\\>")) l "\\|"))
+
+(defun proof-anchor-regexp (e)
+ "Anchor (\\`) and group the regexp E."
+ (concat "\\`\\(" e "\\)"))
+
+(defconst proof-no-regexp
+ "\\'\\`"
+ "A regular expression that never matches anything")
+
+
+(defun proof-regexp-alt (&rest args)
+ "Return the regexp which matches any of the regexps ARGS."
+ ;; Is this not available in some library?
+ (let ((res ""))
+ (dolist (regexp args)
+ (setq res (concat res (if (string-equal res "") "\\(" "\\|\\(")
+ regexp "\\)")))
+ res))
+
+(defun proof-regexp-region (start end)
+ "Return regexp matching START anything over several lines END."
+ ;; FIXME: would like to use shy grouping here \\(?: but it seems
+ ;; buggy or unimplemented in XEmacs.
+ ;; WARNING: this produces nasty regexps that lead to stack
+ ;; overflows. It's better to have a loop that searches over lines,
+ ;; see next function.
+ (concat "\\(" start "\\)\\(\n\\|.\\)*\\(" end "\\)"))
+
+(defun proof-re-search-forward-region (startre endre)
+ "Search for a region delimited by regexps STARTRE and ENDRE.
+Return the start position of the match for STARTRE, or
+nil if a region cannot be found."
+ (if (re-search-forward startre nil t)
+ (let ((start (match-beginning 0)))
+ (if (re-search-forward endre nil t)
+ start))))
+
+;; Functions for string matching and searching that take into account
+;; value of proof-case-fold-search. Last arg to string-match is not
+;; applicable.
+
+(defun proof-re-search-forward (regexp &optional bound noerror count)
+ "Like re-search-forward, but set case-fold-search to proof-case-fold-search."
+ (let
+ ((case-fold-search proof-case-fold-search))
+ (re-search-forward regexp bound noerror count)))
+
+(defun proof-re-search-backward (regexp &optional bound noerror count)
+ "Like re-search-backward, but set case-fold-search to proof-case-fold-search."
+ (let
+ ((case-fold-search proof-case-fold-search))
+ (re-search-backward regexp bound noerror count)))
+
+(defun proof-string-match (regexp string &optional start)
+ "Like string-match, but set case-fold-search to proof-case-fold-search."
+ (let
+ ((case-fold-search proof-case-fold-search))
+ (string-match regexp string start)))
+
+(defun proof-string-match-safe (regexp string &optional start)
+ "Like proof-string-match, but return nil if REGEXP is nil."
+ (if regexp (proof-string-match regexp string start)))
+
+(defun proof-stringfn-match (regexp-or-fn string)
+ "Like proof-string-match if first arg is regexp, otherwise call it."
+ (cond ((stringp regexp-or-fn)
+ (proof-string-match regexp-or-fn string))
+ ((functionp regexp-or-fn)
+ (funcall regexp-or-fn string))))
+
+(defun proof-looking-at (regexp)
+ "Like looking-at, but set case-fold-search to proof-case-fold-search."
+ (let
+ ((case-fold-search proof-case-fold-search))
+ (looking-at regexp)))
+
+(defun proof-looking-at-safe (regexp)
+ "Like proof-looking-at, but return nil if REGEXP is nil."
+ (if regexp (proof-looking-at regexp)))
+
+(defun proof-looking-at-syntactic-context ()
+ "Determine if current point is at beginning or within comment/string context.
+If so, return non-nil."
+ (or
+ (proof-buffer-syntactic-context)
+ (proof-looking-at-safe proof-comment-start-regexp)
+ (proof-looking-at-safe proof-string-start-regexp)))
+
+
+;; Generic font-lock
+
+(defvar proof-id "\\(\\w\\(\\w\\|\\s_\\)*\\)"
+ "A regular expression for parsing identifiers.")
+
+;; For font-lock, we treat ,-separated identifiers as one identifier
+;; and refontify commata using \{proof-unfontify-separator}.
+
+(defun proof-ids (proof-id &optional sepregexp)
+ "Generate a regular expression for separated lists of identifiers.
+Default is comma separated, or SEPREGEXP if set."
+ (concat proof-id "\\(\\s-*" (or sepregexp ",") "\\s-*"
+ proof-id "\\)*"))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; A big hack to unfontify commas in declarations and definitions. ;;
+;; Useful for provers which have declarations of the form x,y,z:Ty ;;
+;; All that can be said for it is that the previous way of doing ;;
+;; this was even more bogus. ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Refontify the whole line, 'cos that's what font-lock-after-change
+;; does.
+
+;;FIXME: Under FSF Emacs 20.2, when initially fontifying the buffer,
+;; commas are not zapped.
+;;
+;; FIXME da: this should be more specific!!
+;;
+(defun proof-zap-commas-region (start end &optional length)
+ "Remove the face of all `,' within the region (START,END).
+The optional argument LENGTH has no effect. It is required so that we
+may assign this function to `after-change-function'."
+ (save-excursion
+ (let
+ ((start (progn (goto-char start) (beginning-of-line) (point)))
+ (end (progn (goto-char end) (end-of-line) (point))))
+ (goto-char start)
+ (while (search-forward "," end t)
+ (if (memq (get-char-property (- (point) 1) 'face)
+ (list 'proof-declaration-name-face
+ 'font-lock-function-name-face))
+ (font-lock-unfontify-region (- (point) 1) (point))
+ )))))
+
+(defun proof-zap-commas-buffer ()
+ "Remove the face of all `,' in the current buffer."
+ (proof-zap-commas-region (point-min) (point-max)))
+
+(defun proof-unfontify-separator ()
+ (make-local-variable 'after-change-functions)
+ (setq after-change-functions
+ (append (delq 'proof-zap-commas-region after-change-functions)
+ '(proof-zap-commas-region))))
+
+;;
+;; Functions for doing something like "format" but with customizable
+;; control characters.
+;;
+;; Added for version 3.1 to help quote funny characters in filenames.
+;;
+
+;;;###autoload
+(defun proof-format (alist string)
+ "Format a string by matching regexps in ALIST against STRING.
+ALIST contains (REGEXP . REPLACEMENT) pairs where REPLACEMENT
+may be a string or sexp evaluated to get a string."
+ (while alist
+ (let ((idx 0))
+ (while (string-match (car (car alist)) string idx)
+ (setq string
+ (concat (substring string 0 (match-beginning 0))
+ (cond
+ ((stringp (cdr (car alist)))
+ (cdr (car alist)))
+ (t
+ (eval (cdr (car alist)))))
+ (substring string (match-end 0))))
+ (setq idx (+ (match-beginning 0) (length (cdr (car alist)))))))
+ (setq alist (cdr alist)))
+ string)
+
+(defun proof-format-filename (string filename)
+ "Format STRING by replacing quoted chars by escaped version of FILENAME.
+
+%e uses the canonicalized expanded version of filename (including
+directory, using default-directory -- see `expand-file-name').
+
+%r uses the unadjusted (possibly relative) version of FILENAME.
+
+%m ('module') uses the basename of the file, without directory
+or extension.
+
+%s means the same as %e.
+
+Using %e can avoid problems with dumb proof assistants who don't
+understand ~, for example.
+
+For all these cases, the escapes in `proof-shell-filename-escapes'
+are processed.
+
+If STRING is in fact a function, instead invoke it on FILENAME and
+return the resulting (string) value."
+ (cond
+ ((functionp string)
+ (funcall string filename))
+ (t
+ (proof-format
+ (list (cons "%s" (proof-format proof-shell-filename-escapes
+ (expand-file-name filename)))
+ (cons "%e" (proof-format proof-shell-filename-escapes
+ (expand-file-name filename)))
+ (cons "%r" (proof-format proof-shell-filename-escapes
+ filename))
+ (cons "%m" (proof-format proof-shell-filename-escapes
+ (file-name-nondirectory
+ (file-name-sans-extension filename)))))
+ string))))
+
+
+;;
+;; Functions for inserting text into buffer.
+;;
+;; Added for version 3.2 to provide more prover specific shortcuts.
+;;
+
+; Taken from Isamode
+;
+; %l - insert the value of isa-logic-name
+; %s - insert the value returned by isa-current-subgoal
+
+(defun proof-insert (text)
+ "Insert TEXT into the current buffer.
+TEXT may include these special characters:
+ %p - place the point here after input
+Any other %-prefixed character inserts itself."
+ ; would be quite nice to have this function:
+ ;(isa-delete-pending-input)
+ (let ((i 0) pos acc)
+ (while (< i (length text))
+ (let ((ch (elt text i)))
+ (if (not (eq ch ?%))
+ (setq acc (concat acc (char-to-string ch)))
+ (setq i (1+ i))
+ (setq ch (elt text i))
+ (cond ;((eq ch ?l)
+ ; (setq acc (concat acc isa-logic-name)))
+ ;((eq ch ?s)
+ ; (setq acc
+ ; (concat acc
+ ; (int-to-string
+ ; (if (boundp 'isa-denoted-subgoal)
+ ; isa-denoted-subgoal
+ ; 1)))))
+ ;((eq ch ?n)
+ ; (if acc (insert acc))
+ ; (setq acc nil)
+ ; (comint-send-input))
+ ((eq ch ?p)
+ (if acc (insert acc))
+ (setq acc nil)
+ (setq pos (point)))
+ (t (setq acc (concat acc (char-to-string ch)))))))
+ (setq i (1+ i)))
+ (if acc (insert acc))
+ (if pos (goto-char pos))))
+
+(defun proof-splice-separator (sep strings)
+ "Splice SEP into list of STRINGS."
+ (let (stringsep)
+ (while strings
+ (setq stringsep (concat stringsep (car strings)))
+ (setq strings (cdr strings))
+ (if strings (setq stringsep
+ (concat stringsep sep))))
+ stringsep))
+
+(provide 'proof-syntax)
diff --git a/generic/proof-system.el b/generic/proof-system.el
new file mode 100644
index 00000000..9a00cdec
--- /dev/null
+++ b/generic/proof-system.el
@@ -0,0 +1,21 @@
+;; proof-system.el Proof General functions for interfacing with proof system.
+;;
+;; Copyright (C) 2000 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; New in 3.2. This file contains code for communicating settings
+;; maintained in Proof General with the underlying proof system,
+;; and code for buiding useful prover specific commands.
+;;
+
+(require 'proof-config)
+
+;; Ooops! Nothing here now. Now in proof-menu.el
+
+
+;; End of proof-system.el
+(provide 'proof-system) \ No newline at end of file
diff --git a/generic/proof-toolbar.el b/generic/proof-toolbar.el
new file mode 100644
index 00000000..c457e49b
--- /dev/null
+++ b/generic/proof-toolbar.el
@@ -0,0 +1,587 @@
+;; proof-toolbar.el Toolbar for Proof General
+;;
+;; Copyright (C) 1998,9 David Aspinall / LFCS.
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; NB: FSF GNU Emacs has no toolbar facility. This file defines
+;; proof-toolbar-menu which holds the same commands and is put on the
+;; menubar by proof-toolbar-setup (perhaps surprisingly).
+;; Could consider moving the generic table stuff to proof-menu now.
+;;
+;; Toolbar is just for the scripting buffer, currently.
+;;
+;;
+;; TODO (minor things):
+;;
+;; 1. edit-toolbar cannot edit proof toolbar (even in a proof mode)
+;; Need a variable containing a specifier or similar.
+;; (defvar proof-toolbar-specifier nil
+;; "Specifier for proof toolbar.")
+;; This doesn't seem worth fixing until XEmacs toolbar implementation
+;; settles a bit. Enablers don't work too well at the moment.
+
+;; 2. It's a little bit tricky to add prover-specific items:
+;; presently it must be done before this file is loaded.
+;; We could improve on that by generating everything on-thy-fly
+;; in proof-toolbar-setup.
+
+;; 3. We could consider automatically disabling buttons which are
+;; not configured for the prover, e.g. if proof-info-command is
+;; not set, then the Info button should not be shown.
+
+
+;;; IMPORT declaration (only to suppress warnings for byte compile)
+;;; NB: can't put require proof-script here: leads to circular
+;;; requirement via proof-menu.
+;; (require 'proof-script)
+;; (autoload 'proof-shell-live-buffer "proof-shell")
+;; (autoload 'proof-shell-restart "proof-shell")
+
+
+(require 'proof-config) ; for <PA>-toolbar-entries
+
+;;
+;; See `proof-toolbar-entries-default' and
+;; `<PA>-toolbar-entries' in proof-config
+;; for the default generic toolbar and
+;; the per-prover toolbar contents variable.
+;;
+
+;;
+;; Function, icon, button names
+;;
+
+(defun proof-toolbar-function (token)
+ (intern (concat "proof-toolbar-" (symbol-name token))))
+
+(defun proof-toolbar-icon (token)
+ (intern (concat "proof-toolbar-" (symbol-name token) "-icon")))
+
+(defun proof-toolbar-enabler (token)
+ (intern (concat "proof-toolbar-" (symbol-name token) "-enable-p")))
+
+(defun proof-toolbar-function-with-enabler (token)
+ (intern (concat "proof-toolbar-" (symbol-name token) "-with-enabler-p")))
+
+;;
+;; Now the toolbar icons and buttons
+;;
+
+(defun proof-toolbar-make-icon (tle)
+ "Make icon variable and icon list entry from a PA-toolbar-entries entry."
+ (let* ((icon (car tle))
+ (tooltip (nth 2 tle))
+ (iconname (symbol-name icon))
+ (iconvar (proof-toolbar-icon icon)))
+ ;; first declare variable
+ ;; (eval
+ ;; `(defvar ,iconvar nil
+ ;; ,(concat
+ ;; "Glyph list for " iconname " button in Proof General toolbar.")))
+ ;; FIXME: above doesn't quite work right. However, we only lose
+ ;; the docstring which is no big deal.
+ ;; now the list entry
+ (if tooltip
+ (list (list iconvar iconname)))))
+
+(defconst proof-toolbar-iconlist
+ (apply 'append
+ (mapcar 'proof-toolbar-make-icon
+ (proof-ass toolbar-entries)))
+ "List of icon variable names and their associated image files.
+A list of lists of the form (VAR IMAGE). IMAGE is the root name
+for an image file in proof-images-directory. The toolbar
+code expects to find files IMAGE.xpm or IMAGE.8bit.xpm
+and chooses the best one for the display properites.")
+
+(defun proof-toolbar-make-toolbar-item (tle)
+ "Make a toolbar button descriptor from a PA-toolbar-entries entry."
+ (let*
+ ((token (car tle))
+ (menuname (cadr tle))
+ (tooltip (nth 2 tle))
+ (existsenabler (nth 3 tle))
+ (enablep (and proof-toolbar-use-button-enablers
+ (>= emacs-major-version 21)
+ existsenabler))
+ (enabler (proof-toolbar-enabler token))
+ (enableritem (if enablep (list enabler) t))
+ (buttonfn (proof-toolbar-function token))
+ (buttonfnwe (proof-toolbar-function-with-enabler token))
+ (icon (proof-toolbar-icon token))
+ (actualfn
+ (if (or enablep (not existsenabler))
+ buttonfn
+ ;; Add the enabler onto the function if necessary.
+ (eval `(defun ,buttonfnwe ()
+ (interactive)
+ (if (,enabler)
+ (call-interactively (quote ,buttonfn))
+ (message ,(concat "Button \"" menuname "\" disabled")))))
+ buttonfnwe)))
+ (if tooltip ;; no tooltip means menu-only item
+ (if proof-running-on-XEmacs
+ (list (vector icon actualfn enableritem tooltip))
+ (list (append (list icon actualfn token
+ :help tooltip)
+ (if enabler (list :enable (list enabler)))))))))
+
+
+(defvar proof-toolbar-button-list
+ (append
+ (apply 'append (mapcar 'proof-toolbar-make-toolbar-item
+ (proof-ass toolbar-entries)))
+ (if proof-running-on-XEmacs
+ (list [:style 3d])))
+ "A toolbar descriptor evaluated in proof-toolbar-setup.
+Specifically, a list of sexps which evaluate to entries in a toolbar
+descriptor. The default value proof-toolbar-default-button-list
+will work for any proof assistant.")
+
+;;
+;; Code for displaying and refreshing toolbar
+;;
+
+(defvar proof-toolbar nil
+ "Proof mode toolbar button list. Set in proof-toolbar-build.
+For GNU Emacs, this holds a keymap.")
+
+(deflocal proof-toolbar-itimer nil
+ "itimer for updating the toolbar in the current buffer")
+
+;;;###autoload
+(defun proof-toolbar-setup ()
+ "Initialize Proof General toolbar and enable it for current buffer.
+If proof-mode-use-toolbar is nil, change the current buffer toolbar
+to the default toolbar."
+ (interactive)
+ (if
+ (and ;; Check support in Emacs
+ (or (and (featurep 'tool-bar) ; GNU Emacs tool-bar library
+ (member 'xpm image-types)) ; and XPM support
+ (and (featurep 'toolbar) ; or XEmacs toolbar library
+ (featurep 'xpm))) ; and XPM support
+ ;; Check support in Window system
+ (memq (if proof-running-on-XEmacs (console-type) window-system)
+ '(x mswindows gtk)))
+
+ ;; Toolbar support is possible.
+ (progn
+ ;; Check the toolbar has been built.
+ (or proof-toolbar (proof-toolbar-build))
+
+ ;; Now see if user wants toolbar
+ ;; or not (this can be changed dyamically).
+ (if proof-toolbar-enable
+
+ ;; Enable the toolbar in this buffer
+ (if proof-running-on-Emacs21
+ ;; For GNU Emacs, we make a local tool-bar-map
+ (set (make-local-variable 'tool-bar-map) proof-toolbar)
+
+ ;; For XEmacs, we set the toolbar specifier for this buffer.
+ (set-specifier default-toolbar proof-toolbar (current-buffer))
+ ;; We also setup refresh hackery
+ (proof-toolbar-setup-refresh))
+
+ ;; Disable the toolbar in this buffer
+ (if proof-running-on-Emacs21
+ ;; For GNU Emacs, we remove local value of tool-bar-map
+ (kill-local-variable 'tool-bar-map)
+ ;; For XEmacs, we remove specifier and disable refresh.
+ (remove-specifier default-toolbar (current-buffer))
+ (proof-toolbar-disable-refresh)))
+
+ ;; Update the display
+ (sit-for 0))))
+
+(defun proof-toolbar-build ()
+ "Build proof-toolbar."
+ (let ((icontype
+ ;; Select 8bit xpm's if we've got a
+ ;; limited colour depth.
+ (if (and (boundp 'device-pixel-depth)
+ (< (device-pixel-depth) 16))
+ ".8bit.xpm" ".xpm")))
+
+ ;; First set the button variables to glyphs.
+ ;; (NB: this is a bit long-winded).
+ (mapcar
+ (lambda (buttons)
+ (let ((var (car buttons))
+ (iconfiles (mapcar (lambda (name)
+ (concat proof-images-directory
+ name
+ icontype)) (cdr buttons))))
+ (set var
+ (if proof-running-on-XEmacs
+ ;; On XEmacs, icon variable holds a list of glyphs
+ (toolbar-make-button-list iconfiles)
+ ;; On GNU emacs, it holds a filename for the icon,
+ ;; without path or extension.
+ (eval (cadr buttons))))))
+ ;; On GNU Emacs, it holds an image descriptor or vector of
+ ;;(if (> 1 (length iconfiles))
+ ;; (apply 'vector (mapcar 'create-image iconfiles))
+ ;; (create-image (car iconfiles)))))))
+ proof-toolbar-iconlist))
+
+ (if proof-running-on-XEmacs
+ ;; For XEmacs, we evaluate the specifier.
+ (setq proof-toolbar (mapcar 'eval proof-toolbar-button-list))
+
+ ;; On GNU emacs, we need to make a new "key"map,
+ ;; and set a local copy of tool-bar-map to it.
+ (setq proof-toolbar (make-sparse-keymap))
+ (let ((tool-bar-map proof-toolbar)
+ (load-path (list proof-images-directory))) ; for finding images
+ (dolist (but proof-toolbar-button-list)
+ (apply
+ 'tool-bar-add-item
+ (eval (nth 0 but)) ; image filename
+ (nth 1 but) ; function symbol
+ (nth 2 but) ; dummy key
+ (nthcdr 3 but))))) ; remaining properties
+ ;; Finished
+ )
+
+
+;; Action to take after altering proof-toolbar-enable
+(defalias 'proof-toolbar-enable 'proof-toolbar-setup)
+(proof-deftoggle proof-toolbar-enable proof-toolbar-toggle)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Toolbar refresh functions (hackery for XEmacs)
+;;
+
+(defun proof-toolbar-setup-refresh ()
+ "Enable the XEmacs hackery to update the toolbar."
+ (if proof-toolbar-use-button-enablers
+ (progn
+ ;; Set the callback for updating the enablers
+ (add-hook 'proof-state-change-hook 'proof-toolbar-refresh)
+ ;; Also call it whenever text changes in this buffer,
+ ;; provided it's a script buffer.
+ (if (eq proof-buffer-type 'script)
+ (add-hook 'after-change-functions
+ 'proof-toolbar-refresh nil t))
+ ;; And the interval timer for really refreshing the toolbar
+ (setq proof-toolbar-itimer
+ (start-itimer "proof toolbar refresh"
+ 'proof-toolbar-really-refresh
+ 0.5 ; seconds of delay
+ 0.5 ; repeated
+ t ; count idle time
+ t ; pass argument
+ (current-buffer))))))
+
+(defun proof-toolbar-disable-refresh ()
+ "Disable the XEmacs hackery to update the toolbar."
+ (remove-hook 'proof-state-change-hook 'proof-toolbar-refresh)
+ (remove-hook 'after-change-functions 'proof-toolbar-refresh)
+ (if proof-toolbar-itimer (delete-itimer proof-toolbar-itimer))
+ (setq proof-toolbar-itimer nil))
+
+(deflocal proof-toolbar-refresh-flag nil
+ "Flag indicating that the toolbar should be refreshed.")
+
+;; &rest args needed for after change function args
+;; FIXME: don't want to do this in every buffer, really;
+;; we'll have proof-toolbar-refresh-flag defined everywhere.
+(defun proof-toolbar-refresh (&rest args)
+ "Set flag to indicate that the toolbar should be refreshed."
+ (setq proof-toolbar-refresh-flag t))
+
+(defvar proof-toolbar-enablers
+ (mapcar (lambda (tle)
+ (list (proof-toolbar-enabler (car tle))))
+ (proof-ass toolbar-entries))
+ "List of all toolbar's enablers")
+
+(defvar proof-toolbar-enablers-last-state
+ nil
+ "Last state of the toolbar's enablers")
+
+(defun proof-toolbar-really-refresh (buf)
+ "Force refresh of toolbar display to re-evaluate enablers.
+This function needs to be called anytime that enablers may have
+changed state."
+ (if ;; Be careful to only add to correct buffer, and if it's live
+ (buffer-live-p buf)
+ (let ((enabler-state (mapcar 'eval proof-toolbar-enablers)))
+ (if
+ (not (equal enabler-state proof-toolbar-enablers-last-state))
+ (progn
+ (setq proof-toolbar-enablers-last-state enabler-state)
+ ;; The official way to do this should be
+ ;; (set-specifier-dirty-flag default-toolbar)
+ ;; but it doesn't work, so we do what VM does instead,
+ ;; removing and re-adding.
+ (remove-specifier default-toolbar buf)
+ (set-specifier default-toolbar proof-toolbar buf)
+ ;; We set the dirty flag as well just in case it helps...
+ (set-specifier-dirty-flag default-toolbar)
+ (setq proof-toolbar-refresh-flag nil))))
+ ;; Kill off this itimer if it's owning buffer has died
+ (delete-itimer current-itimer)))
+
+;;
+;; =================================================================
+;;
+;;
+;; GENERIC PROOF TOOLBAR BUTTON FUNCTIONS
+;;
+;; Defaults functions are provided below for: up, down, restart
+;; Code for specific provers may define the symbols below to use
+;; the other buttons: next, prev, goal, qed (images are provided).
+;;
+;; proof-toolbar-next next function
+;; proof-toolbar-next-enable enable predicate for next (or t)
+;;
+;; etc.
+;;
+;; To add support for more buttons or alter the default
+;; images, <PA>-toolbar-entries should be adjusted.
+;; See proof-config.el for that.
+;;
+;; Note that since the toolbar is displayed for goals and response
+;; buffers too, enablers and command functions must potentially
+;; switch buffer first.
+;;
+;;
+
+
+;;
+;; Undo button
+;;
+
+(defun proof-toolbar-undo-enable-p ()
+ (proof-with-script-buffer
+ (and (proof-shell-available-p)
+ (> (proof-unprocessed-begin) (point-min)))))
+
+(defalias 'proof-toolbar-undo 'proof-undo-last-successful-command)
+
+;;
+;; Delete button (not actually on toolbar)
+;;
+
+(defun proof-toolbar-delete-enable-p ()
+ (proof-with-script-buffer
+ (and (not buffer-read-only)
+ (proof-shell-available-p)
+ (> (proof-unprocessed-begin) (point-min)))))
+
+(defalias 'proof-toolbar-delete 'proof-undo-and-delete-last-successful-command)
+
+
+;;
+;; Lockedend button (not actually on toolbar)
+;;
+
+(defun proof-toolbar-lockedend-enable-p ()
+ t)
+
+(defalias 'proof-toolbar-lockedend 'proof-goto-end-of-locked)
+
+
+
+
+;;
+;; Next button
+;;
+
+(defun proof-toolbar-next-enable-p ()
+ (proof-with-script-buffer
+ (not (proof-locked-region-full-p))))
+
+(defalias 'proof-toolbar-next 'proof-assert-next-command-interactive)
+
+
+;;
+;; Goto button
+;;
+
+(defun proof-toolbar-goto-enable-p ()
+ (eq proof-buffer-type 'script))
+
+(defalias 'proof-toolbar-goto 'proof-goto-point)
+
+
+;;
+;; Retract button
+;;
+
+(defun proof-toolbar-retract-enable-p ()
+ (proof-with-script-buffer
+ (not (proof-locked-region-empty-p))))
+
+(defalias 'proof-toolbar-retract 'proof-retract-buffer)
+
+
+;;
+;; Use button
+;;
+
+(defalias 'proof-toolbar-use-enable-p 'proof-toolbar-next-enable-p)
+(defalias 'proof-toolbar-use 'proof-process-buffer)
+
+;;
+;; Restart button
+;;
+
+(defun proof-toolbar-restart-enable-p ()
+ ;; Could disable this unless there's something running.
+ ;; But it's handy to clearup extents, etc, I suppose.
+ t)
+
+(defalias 'proof-toolbar-restart 'proof-shell-restart)
+
+;;
+;; Goal button
+;;
+
+(defun proof-toolbar-goal-enable-p ()
+ ;; Goals are always allowed: will crank up process if need be.
+ ;; Actually this should only be available when "no subgoals"
+ t)
+
+(defalias 'proof-toolbar-goal 'proof-issue-goal)
+
+
+;;
+;; QED button
+;;
+
+(defun proof-toolbar-qed-enable-p ()
+ (proof-with-script-buffer
+ (and proof-shell-proof-completed
+ (proof-shell-available-p))))
+
+(defalias 'proof-toolbar-qed 'proof-issue-save)
+
+;;
+;; State button
+;;
+
+(defun proof-toolbar-state-enable-p ()
+ (proof-shell-available-p))
+
+(defalias 'proof-toolbar-state 'proof-prf)
+
+;;
+;; Context button
+;;
+
+(defun proof-toolbar-context-enable-p ()
+ (proof-shell-available-p))
+
+(defalias 'proof-toolbar-context 'proof-ctxt)
+
+;;
+;; Info button
+;;
+;; Might as well enable it all the time; convenient trick to
+;; start the proof assistant.
+
+(defun proof-toolbar-info-enable-p ()
+ t)
+
+(defalias 'proof-toolbar-info 'proof-help)
+
+;;
+;; Command button
+;;
+
+(defun proof-toolbar-command-enable-p ()
+ (proof-shell-available-p))
+
+(defalias 'proof-toolbar-command 'proof-minibuffer-cmd)
+
+;;
+;; Help button
+;;
+
+(defun proof-toolbar-help-enable-p ()
+ t)
+
+(defun proof-toolbar-help ()
+ (interactive)
+ (info "ProofGeneral"))
+
+;;
+;; Find button
+;;
+
+(defun proof-toolbar-find-enable-p ()
+ (proof-shell-available-p))
+
+(defalias 'proof-toolbar-find 'proof-find-theorems)
+
+;;
+;; Show and hide buttons (not on toolbar)
+;;
+
+(defun proof-toolbar-show-enable-p () t)
+(defalias 'proof-toolbar-show 'pg-show-all-proofs)
+
+(defun proof-toolbar-hide-enable-p () t)
+(defalias 'proof-toolbar-hide 'pg-hide-all-proofs)
+
+
+
+;;
+;; Interrupt button
+;;
+
+(defun proof-toolbar-interrupt-enable-p ()
+ proof-shell-busy)
+
+(defalias 'proof-toolbar-interrupt 'proof-interrupt-process)
+
+
+;;
+;; =================================================================
+;;
+;; Scripting menu built from toolbar functions
+;;
+
+(defun proof-toolbar-make-menu-item (tle)
+ "Make a menu item from a PA-toolbar-entries entry."
+ (let*
+ ((token (car tle))
+ (menuname (cadr tle))
+ (tooltip (nth 2 tle))
+ (enablep (nth 3 tle))
+ (fnname (proof-toolbar-function token))
+ ;; fnval: remove defalias to get keybinding onto menu;
+ ;; NB: function and alias must both be defined for this
+ ;; to work!!
+ (fnval (if (symbolp (symbol-function fnname))
+ (symbol-function fnname)
+ fnname)))
+ (if menuname
+ (list
+ (apply 'vector
+ (append
+ (list menuname fnval)
+ (if enablep
+ (list ':active (list (proof-toolbar-enabler token))))))))))
+
+(defconst proof-toolbar-scripting-menu
+ ;; Toolbar contains commands to manipulate script and
+ ;; other handy stuff.
+ (apply 'append
+ (mapcar 'proof-toolbar-make-menu-item
+ (proof-ass toolbar-entries)))
+ "Menu made from the Proof General toolbar commands.")
+
+
+;;
+(provide 'proof-toolbar)
+
diff --git a/generic/proof-utils.el b/generic/proof-utils.el
new file mode 100644
index 00000000..44604fe9
--- /dev/null
+++ b/generic/proof-utils.el
@@ -0,0 +1,763 @@
+;; proof-utils.el Proof General utility functions
+;;
+;; Copyright (C) 1998-2001 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk> and others
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;;
+;; Loading note: this file is required immediately from proof.el, so
+;; no autoloads are used here.
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Handy macros
+
+(defmacro deflocal (var value &optional docstring)
+ "Define a buffer local variable VAR with default value VALUE."
+ `(progn
+ (defvar ,var nil ,docstring)
+ (make-variable-buffer-local (quote ,var))
+ (setq-default ,var ,value)))
+
+(defmacro proof-with-current-buffer-if-exists (buf &rest body)
+ "As with-current-buffer if BUF exists and is live, otherwise nothing."
+ `(if (buffer-live-p ,buf)
+ (with-current-buffer ,buf
+ ,@body)))
+
+;; Slightly specialized version of above. This is used in commands
+;; which work from different PG buffers (goals, response), typically
+;; bound to toolbar commands.
+(defmacro proof-with-script-buffer (&rest body)
+ "Execute BODY in some script buffer: current buf or otherwise proof-script-buffer.
+Return nil if not a script buffer or if no active scripting buffer."
+ `(cond
+ ((eq proof-buffer-type 'script)
+ (progn
+ ,@body))
+ ((buffer-live-p proof-script-buffer)
+ (with-current-buffer proof-script-buffer
+ ,@body))))
+
+(defmacro proof-map-buffers (buflist &rest body)
+ "Do BODY on each buffer in BUFLIST, if it exists."
+ `(dolist (buf ,buflist)
+ (proof-with-current-buffer-if-exists buf ,@body)))
+
+(defmacro proof-sym (string)
+ "Return symbol for current proof assistant using STRING."
+ `(intern (concat (symbol-name proof-assistant-symbol) "-" ,string)))
+
+
+(defun proof-try-require (symbol)
+ "Try requiring SYMBOL. No error if the file for SYMBOL isn't found."
+ (condition-case ()
+ (require symbol)
+ (file-error nil))
+ (featurep symbol))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Function for taking action when dynamically adjusting customize values
+;;
+(defun proof-set-value (sym value)
+ "Set a customize variable using set-default and a function.
+We first call `set-default' to set SYM to VALUE.
+Then if there is a function SYM (i.e. with the same name as the
+variable SYM), it is called to take some dynamic action for the new
+setting.
+
+If there is no function SYM, we try stripping
+proof-assistant-symbol and adding \"proof-\" instead to get
+a function name. This extends proof-set-value to work with
+generic individual settings.
+
+The dynamic action call only happens when values *change*: as an
+approximation we test whether proof-config is fully-loaded yet."
+ (set-default sym value)
+ (if (featurep 'proof-config)
+ (if (fboundp sym)
+ (funcall sym)
+ (if (> (length (symbol-name sym))
+ (+ 3 (length (symbol-name proof-assistant-symbol))))
+ (let ((generic
+ (intern
+ (concat "proof"
+ (substring (symbol-name sym)
+ (length (symbol-name
+ proof-assistant-symbol)))))))
+ (if (fboundp generic)
+ (funcall generic)))))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Macros for defining per-assistant customization settings.
+;;
+;; This new mechanism is an improved way to handle per-assistant
+;; settings. Instead of declaring a variable
+;; "proof-assistant-web-page" and duplicating it in the prover
+;; specific code to make the generic setting, we automatically declare
+;; "isabelle-web-page", "coq-web-page", etc, using these macros.
+;;
+;; The advantage of this is that people's save settings will work
+;; properly, and that it will become more possible to use more than
+;; one instance of PG at a time. The disadvantage is that it is
+;; slightly more complicated, and less "object-oriented" than the
+;; previous approach. It is also a big change to move all settings.
+;;
+;; NB: this mechanism is work in progress in 3.2. It will
+;; be expanded, although we may leave most low-level
+;; settings to use the current mechanism.
+;;
+;; Notes:
+;;
+;; Two mechanisms for accessing generic vars:
+;;
+;; (proof-ass name) or (proof-assistant-name)
+;;
+;; Later is more efficient, though defining function
+;; for each setting seems wasteful?
+
+(defun proof-ass-symv (sym)
+ "Return the symbol for SYM for the current prover. SYM is evaluated."
+ (intern (concat (symbol-name proof-assistant-symbol) "-"
+ (symbol-name sym))))
+
+(defmacro proof-ass-sym (sym)
+ "Return the symbol for SYM for the current prover. SYM not evaluated."
+ `(proof-ass-symv (quote ,sym)))
+
+(defun proof-defpgcustom-fn (sym args)
+ "Define a new customization variable <PA>-sym for the current proof assistant.
+Helper for macro `defpgcustom'."
+ (let ((specific-var (proof-ass-symv sym))
+ (generic-var (intern (concat "proof-assistant-" (symbol-name sym)))))
+ (eval
+ `(defcustom ,specific-var
+ ,@args
+ ;; FIXME: would be nicer to grab group from @args here and
+ ;; prefix it automatically. For now, default to internals
+ ;; setting for PA.
+ ;; FIXME 2: would also be nice to grab docstring from args
+ ;; and allow substitution for prover name, etc. A bit too
+ ;; fancy perhaps!
+ :group ,(quote proof-assistant-internals-cusgrp)))
+ ;; For functions, we could simply use defalias. Unfortunately there
+ ;; is nothing similar for values, so we define a new set/get function.
+ (eval
+ `(defun ,generic-var (&optional newval)
+ ,(concat "Set or get value of " (symbol-name sym) " for current proof assistant.
+If NEWVAL is present, set the variable, otherwise return its current value.")
+ (if newval
+ (setq ,specific-var newval)
+ ,specific-var)))))
+
+(defmacro defpgcustom (sym &rest args)
+ "Define a new customization variable <PA>-SYM for the current proof assistant.
+The function proof-assistant-<SYM> is also defined, which can be used in the
+generic portion of Proof General to set and retrieve the value for the current p.a.
+Arguments as for `defcustom', which see.
+
+Usage: (defpgcustom SYM &rest ARGS)."
+ `(proof-defpgcustom-fn (quote ,sym) (quote ,args)))
+
+(defmacro proof-ass (sym)
+ "Return the value for SYM for the current prover."
+ (eval `(proof-ass-sym ,sym)))
+
+(defun proof-defpgdefault-fn (sym value)
+ "Helper for `defpgdefault', which see. SYM and VALUE are evaluated."
+ ;; NB: we need this because nothing in customize library seems to do
+ ;; the right thing.
+ (let ((symbol (proof-ass-symv sym)))
+ (set-default symbol
+ (cond
+ ;; Use saved value if it's set
+ ((get symbol 'saved-value)
+ (car (get symbol 'saved-value)))
+ ;; Otherwise override old default with new one
+ (t
+ value)))))
+
+(defmacro defpgdefault (sym value)
+ "Set default for the proof assistant specific variable <PA>-SYM to VALUE.
+This should be used in prover-specific code to alter the default values
+for prover specific settings.
+
+Usage: (defpgdefault SYM VALUE)"
+ `(proof-defpgdefault-fn (quote ,sym) ,value))
+
+;;
+;; Make a function named for the current proof assistant.
+;;
+(defmacro defpgfun (name arglist &rest args)
+ "Define function <PA>-SYM as for defun."
+ `(defun ,(proof-ass-symv name) ,arglist
+ ,@args))
+
+
+;;
+;; End macros
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Buffers and filenames
+
+(defun proof-file-truename (filename)
+ "Returns the true name of the file FILENAME or nil if file non-existent."
+ (and filename (file-exists-p filename) (file-truename filename)))
+
+(defun proof-file-to-buffer (filename)
+ "Find a buffer visiting file FILENAME, or nil if there isn't one."
+ (let* ((buffers (buffer-list))
+ (pos
+ (position (file-truename filename)
+ (mapcar 'proof-file-truename
+ (mapcar 'buffer-file-name
+ buffers))
+ :test 'equal)))
+ (and pos (nth pos buffers))))
+
+(defun proof-files-to-buffers (filenames)
+ "Converts a list of FILENAMES into a list of BUFFERS."
+ (if (null filenames) nil
+ (let* ((buffer (proof-file-to-buffer (car filenames)))
+ (rest (proof-files-to-buffers (cdr filenames))))
+ (if buffer (cons buffer rest) rest))))
+
+(defun proof-buffers-in-mode (mode &optional buflist)
+ "Return a list of the buffers in the buffer list in major-mode MODE.
+Restrict to BUFLIST if it's set."
+ (let ((bufs-left (or buflist (buffer-list)))
+ bufs-got)
+ (dolist (buf bufs-left bufs-got)
+ (if (with-current-buffer buf (eq mode major-mode))
+ (setq bufs-got (cons buf bufs-got))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Key functions
+
+(defun proof-define-keys (map kbl)
+ "Adds keybindings KBL in MAP.
+The argument KBL is a list of tuples (k . f) where `k' is a keybinding
+(vector) and `f' the designated function."
+ (mapcar
+ (lambda (kbl)
+ (let ((k (car kbl)) (f (cdr kbl)))
+ (define-key map k f)))
+ kbl))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Managing font-lock
+;;
+
+;; Notes:
+;;
+;; * Various mechanisms for setting defaults, different between
+;; Emacsen. Old method(?) was to set "blah-mode-font-lock-keywords"
+;; and copy it into "font-lock-keywords" to engage font-lock.
+;; Present method for XEmacs is to put a 'font-lock-defaults
+;; property on the major-mode symbol, or use font-lock-defaults
+;; buffer local variable. We use the later.
+;;
+;; * Buffers which are output-only are *not* kept in special minor
+;; modes font-lock-mode (or x-symbol-mode). In case the user
+;; doesn't want fontification we have a user option,
+;; proof-output-fontify-enable.
+
+(deflocal proof-font-lock-keywords nil
+ "Value of font-lock-keywords in this buffer.
+We set font-lock-defaults to '(proof-font-lock-keywords t) for
+compatibility with X-Symbol, which may hack proof-font-lock-keywords
+with extra patterns (in non-mule mode).")
+
+(deflocal proof-font-lock-keywords-case-fold-search nil
+ "Value of font-lock-keywords-case-fold-search in this buffer.")
+
+(defun proof-font-lock-configure-defaults (autofontify &optional case-fold)
+ "Set defaults for font-lock based on current font-lock-keywords.
+This is a delicate operation, because we only want to use font-lock-mode
+in some buffers, so we have to tread carefully around the font-lock
+code to avoid it turning itself on in the buffers where that actually
+*breaks* fontification.
+
+AUTOFONTIFY must be nil for buffers where we may want to really use
+font-lock-mode."
+ ;;
+ ;; At the moment, the specific assistant code hacks
+ ;; font-lock-keywords. Here we use that value to hack
+ ;; font-lock-defaults, which is used by font-lock to set
+ ;; font-lock-keywords from again!! Yuk.
+ ;;
+ ;; Previously, 'font-lock-keywords was used directly as a setting
+ ;; for the defaults. This has a bad interaction with x-symbol which
+ ;; edits font-lock-keywords and loses the setting. So we make a
+ ;; copy of it in a new local variable, proof-font-lock-keywords.
+ ;;
+ (make-local-variable 'proof-font-lock-keywords)
+ (make-local-variable 'proof-font-lock-keywords-case-fold-search)
+ (setq proof-font-lock-keywords font-lock-keywords)
+ (setq proof-font-lock-keywords-case-fold-search case-fold)
+ ;; Setting font-lock-defaults explicitly is required by FSF Emacs
+ ;; 20.4's version of font-lock in any case.
+
+ (if autofontify
+ (progn
+ (make-local-variable 'font-lock-defaults) ; needed??
+ (setq font-lock-defaults `(proof-font-lock-keywords nil ,case-fold))
+ ;; 12.1.99: For XEmacs, we must also set the mode property.
+ ;; This is needed for buffers which are put into font-lock-mode
+ ;; (rather than fontified by hand).
+ (put major-mode 'font-lock-defaults font-lock-defaults))
+ ;; 11.12.01: Emacs 21 is very eager about turning on font
+ ;; lock and has hooks all over the place to do it. To make
+ ;; sure it doesn't happen we have to eradicate all sense of
+ ;; having any fontification ability.
+ (proof-font-lock-clear-font-lock-vars)
+ ;; In fact, this still leaves font-lock switched on! But
+ ;; hopefully in a useless way. XEmacs has better control
+ ;; over which modes not to enable it for (although annoying
+ ;; that it's a custom setting)
+ (if proof-running-on-XEmacs
+ (setq font-lock-mode-disable-list
+ (cons major-mode font-lock-mode-disable-list)))))
+
+(defun proof-font-lock-clear-font-lock-vars ()
+ (kill-local-variable 'font-lock-defaults)
+ (kill-local-variable 'font-lock-keywords)
+ (setq font-lock-keywords nil)
+ (put major-mode 'font-lock-defaults nil)
+ ;; Ensure it's switched off, too.
+ ;; NB: this tends to undo the hard work we've done
+ ;; by unfontifying, so don't do that now
+ ;; (font-lock-mode -1))
+ )
+
+(defun proof-font-lock-set-font-lock-vars ()
+ (setq font-lock-defaults
+ `(proof-font-lock-keywords
+ nil
+ ,proof-font-lock-keywords-case-fold-search))
+ (setq font-lock-keywords proof-font-lock-keywords))
+
+(defun proof-fontify-region (start end)
+ "Fontify and decode X-Symbols in region START...END.
+Fontifies according to the buffer's font lock defaults.
+Uses proof-x-symbol-decode to decode tokens if x-symbol is present.
+
+If proof-shell-leave-annotations-in-output is set, remove characters
+with top bit set after fontifying so they don't spoil cut and paste.
+
+Returns new END value."
+ ;; We fontify first because X-sym decoding changes char positions.
+ ;; It's okay because x-symbol-decode works even without font lock.
+ ;; Possible disadvantage is that font lock patterns can't refer
+ ;; to X-Symbol characters. Probably they shouldn't!
+
+ ;; 3.5.01: narrowing causes failure in parse-sexp in XEmacs 21.4.
+ ;; I don't think we need it now we use a function to fontify
+ ;; just the region.
+ ;; (narrow-to-region start end)
+
+ (if proof-output-fontify-enable
+ (progn
+ ;; Temporarily set font-lock defaults
+ (proof-font-lock-set-font-lock-vars)
+ ;; (put major-mode 'font-lock-defaults font-lock-defaults)
+ ;; GNU Emacs hack, yuk.
+ (unless proof-running-on-XEmacs
+ (font-lock-set-defaults))
+ (let ((font-lock-keywords proof-font-lock-keywords))
+ ;; FIXME: should set other bits of font lock defaults,
+ ;; perhaps, such as case fold etc. What happened to
+ ;; the careful buffer local font-lock-defaults??
+ ;; ================================================
+ ;; 3.5.01: call to font-lock-fontify-region breaks
+ ;; in xemacs 21.4. Following hack to fix
+ (if (and (string-match "21\\.4.*XEmacs" emacs-version)
+ (not font-lock-cache-position))
+ (progn
+ (setq font-lock-cache-position (make-marker))
+ (set-marker font-lock-cache-position 0)))
+
+ ;; ================================================
+ (font-lock-default-fontify-region start end nil)
+ (proof-zap-commas-region start end))))
+ (if proof-shell-leave-annotations-in-output
+ ;; Remove special characters that were used for font lock,
+ ;; so that cut and paste works from here.
+ (progn
+ (goto-char start)
+ (while (< (point) end)
+ (forward-char)
+ (unless (< (char-before (point)) 128) ; char-to-int in XEmacs
+ (delete-char -1)
+ (setq end (1- end))))))
+ (prog1
+ ;; Returns new end value
+ (proof-x-symbol-decode-region start end)
+ (proof-font-lock-clear-font-lock-vars)))
+;; old ending:
+;; (prog1 (point-max)
+;; (widen)))
+
+;; FIXME todo: add toggle for fontify region which turns it on/off
+;; (maybe).
+
+(defun proof-fontify-buffer ()
+ "Call proof-fontify-region on whole buffer."
+ (proof-fontify-region (point-min) (point-max)))
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Messaging and display functions
+;;
+
+
+(defun proof-warn-if-unset (tag sym)
+ "Give a warning (with TAG) if symbol SYM is unbound or nil."
+ (unless (and (boundp sym) (symbol-value sym))
+ (warn "Proof General %s: %s is unset." tag (symbol-name sym))))
+
+;; FIXME: this function should be combined with
+;; proof-shell-maybe-erase-response-buffer.
+(defun proof-response-buffer-display (str &optional face)
+ "Display STR with FACE in response buffer."
+ ;; 3.4: no longer return fontified STR, it wasn't used.
+ (if (string-equal str "\n")
+ str ; quick exit, no display.
+ (let (start end)
+ (with-current-buffer proof-response-buffer
+ ;; da: I've moved newline before the string itself, to match
+ ;; the other cases when messages are inserted and to cope
+ ;; with warnings after delayed output (non newline terminated).
+ ; (ugit (format "End is %i" (point-max)))
+ (goto-char (point-max))
+ (newline)
+ (setq start (point))
+ (insert str)
+ (unless (bolp) (newline))
+ (setq end (proof-fontify-region start (point)))
+ ;; This is one reason why we don't keep the buffer in font-lock
+ ;; minor mode: it destroys this hacky property as soon as it's
+ ;; made! (Using the minor mode is much more convenient, tho')
+ (if (and face proof-output-fontify-enable)
+ (font-lock-append-text-property start end 'face face))
+ ;; This returns the decorated string, but it doesn't appear
+ ;; decorated in the minibuffer, unfortunately.
+ ;; 3.4: remove this for efficiency.
+ ;; (buffer-substring start (point-max))
+ ))))
+
+;; An analogue of proof-response-buffer-display
+(defun proof-trace-buffer-display (str)
+ "Display STR in the trace buffer."
+ (let (start end)
+ (with-current-buffer proof-trace-buffer
+ (goto-char (point-max))
+ (newline)
+ (setq start (point))
+ (insert str)
+ (unless (bolp) (newline))
+ (proof-fontify-region start (point)))))
+
+(defun proof-display-and-keep-buffer (buffer &optional pos)
+ "Display BUFFER and mark window according to `proof-dont-switch-windows'.
+If optional POS is present, will set point to POS.
+Otherwise move point to the end of the buffer.
+Ensure that point is visible in window."
+ (let (window)
+ (save-excursion
+ (set-buffer buffer)
+ ;; Here's a hack: if we're asking to display BUFFER from a
+ ;; secondary window and the (next) other one is displaying the
+ ;; script buffer, then we do switch-buffer instead. This means
+ ;; that goals and response buffer are swapped as expected in
+ ;; two-pane mode even if either one is used to "drive" the
+ ;; scripting.
+ ;; FIXME: would be better to deduce here which buffer
+ ;; we're displaying, and use get-buffer-window-list to do
+ ;; something sensible.
+ (if (and
+ (not proof-dont-switch-windows)
+ (not (eq (next-window) (selected-window)))
+ (eq (window-buffer (next-window nil 'ignoreminibuf))
+ proof-script-buffer))
+ (if (eq (selected-window) (minibuffer-window))
+ ;; 17.8.01: avoid switching the minibuffer's contents
+ ;; -- terrrible confusion -- use next-window after
+ ;; script buffer instead.
+ ;; (another hack which is mostly right)
+ (set-window-buffer
+ (next-window
+ (car-safe (get-buffer-window-list proof-script-buffer))
+ 'ignoreminibuf) buffer)
+ (set-window-buffer (selected-window) buffer))
+ (display-buffer buffer))
+ (setq window (get-buffer-window buffer 'visible))
+ (set-window-dedicated-p window proof-dont-switch-windows)
+ (and window
+ (save-selected-window
+ (select-window window)
+ ;; For various reasons, point may get moved
+ ;; around in response buffer.
+ (goto-char (or pos (point-max)))
+ (if pos (beginning-of-line))
+ ;; Ensure point visible
+ (or (pos-visible-in-window-p (point) window)
+ (recenter -1)))))))
+
+(defun proof-clean-buffer (buffer)
+ "Erase buffer and hide from display if proof-delete-empty-windows set.
+Auto deletion only affects selected frame. (We assume that the selected
+frame is the one showing the script buffer.)"
+ (with-current-buffer buffer
+ ;; NB: useful optional arg to erase buffer is XEmacs specific, 8-(.
+ (erase-buffer)
+ (if (eq buffer proof-response-buffer)
+ (setq proof-shell-next-error nil)) ; all error msgs lost!
+ (if proof-delete-empty-windows
+ (delete-windows-on buffer t))))
+
+(defun proof-message (&rest args)
+ "Issue the message ARGS in the response buffer and display it."
+ (proof-response-buffer-display (apply 'concat args))
+ (proof-display-and-keep-buffer proof-response-buffer))
+
+(defun proof-warning (&rest args)
+ "Issue the warning ARGS in the response buffer and display it.
+The warning is coloured with proof-warning-face."
+ (proof-response-buffer-display (apply 'concat args) 'proof-warning-face)
+ (proof-display-and-keep-buffer proof-response-buffer))
+
+;; could be a macro for efficiency in compiled code
+(defun proof-debug (&rest args)
+ "Issue the debugging messages ARGS in the response buffer, display it.
+If proof-show-debug-messages is nil, do nothing."
+ (if proof-show-debug-messages
+ (progn
+ (proof-response-buffer-display (apply 'concat
+ "PG debug: "
+ args)
+ 'proof-debug-message-face)
+ (proof-display-and-keep-buffer proof-response-buffer))))
+
+
+;;; A handy utility function used in the "Buffers" menu.
+(defun proof-switch-to-buffer (buf &optional noselect)
+ "Switch to or display buffer BUF in other window unless already displayed.
+If optional arg NOSELECT is true, don't switch, only display it.
+No action if BUF is nil or killed."
+ ;; Maybe this needs to be more sophisticated, using
+ ;; proof-display-and-keep-buffer ?
+ (and (buffer-live-p buf)
+ (unless (eq buf (window-buffer (selected-window)))
+ (if noselect
+ (display-buffer buf t)
+ (switch-to-buffer-other-window buf)))))
+
+;;
+;; Flag and function to keep response buffer tidy.
+;;
+;; FIXME: rename this now it's moved out of proof-shell.
+;;
+(defvar proof-shell-erase-response-flag nil
+ "Indicates that the response buffer should be cleared before next message.")
+
+(defun proof-shell-maybe-erase-response
+ (&optional erase-next-time clean-windows force)
+ "Erase the response buffer according to proof-shell-erase-response-flag.
+ERASE-NEXT-TIME is the new value for the flag.
+If CLEAN-WINDOWS is set, use proof-clean-buffer to do the erasing.
+If FORCE, override proof-shell-erase-response-flag.
+
+If the user option proof-tidy-response is nil, then
+the buffer is only cleared when FORCE is set.
+
+No effect if there is no response buffer currently.
+Returns non-nil if response buffer was cleared."
+ (when (buffer-live-p proof-response-buffer)
+ (let ((doit (or (and
+ proof-tidy-response
+ (not (eq proof-shell-erase-response-flag 'invisible))
+ proof-shell-erase-response-flag)
+ force)))
+ (if doit
+ (if clean-windows
+ (proof-clean-buffer proof-response-buffer)
+ ;; NB: useful optional arg to erase buffer is XEmacs specific, 8-(.
+ ;; (erase-buffer proof-response-buffer)
+ (with-current-buffer proof-response-buffer
+ (setq proof-shell-next-error nil) ; all error msgs lost!
+ (erase-buffer))))
+ (setq proof-shell-erase-response-flag erase-next-time)
+ doit)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Function for submitting bug reports.
+;;
+
+(defun proof-submit-bug-report ()
+ "Submit an bug report or other report for Proof General."
+ (interactive)
+ (require 'reporter)
+ (let
+ ((reporter-prompt-for-summary-p
+ "(Very) brief summary of problem or suggestion: "))
+ (reporter-submit-bug-report
+ "bugs@proofgeneral.org"
+ "Proof General"
+ (list 'proof-general-version 'proof-assistant)
+ nil nil
+ "[ When reporting a bug, please include a small test case for us to repeat it.
+ Please also check that it is not already covered in the BUGS files that came with
+ the distribution, or the latest versions at
+ http://www.proofgeneral.org/ProofGeneral/BUGS ]")))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Utils for making functions to adjust user settings
+;;;
+
+
+(defun proof-deftoggle-fn (var &optional othername)
+ "Define a function <VAR>-toggle for toggling a boolean customize setting VAR.
+Args as for the macro `proof-deftoggle', except will be evaluated."
+ (eval
+ `(defun ,(if othername othername
+ (intern (concat (symbol-name var) "-toggle"))) (arg)
+ ,(concat "Toggle `" (symbol-name var) "'. With ARG, turn on iff ARG>0.
+This function simply uses customize-set-variable to set the variable.
+It was constructed with `proof-deftoggle-fn'.")
+ (interactive "P")
+ (customize-set-variable
+ (quote ,var)
+ (if (null arg) (not ,var)
+ (> (prefix-numeric-value arg) 0))))))
+
+(defmacro proof-deftoggle (var &optional othername)
+ "Define a function VAR-toggle for toggling a boolean customize setting VAR.
+The toggle function uses customize-set-variable to change the variable.
+OTHERNAME gives an alternative name than the default <VAR>-toggle.
+The name of the defined function is returned."
+ `(proof-deftoggle-fn (quote ,var) (quote ,othername)))
+
+(defun proof-defintset-fn (var &optional othername)
+ "Define a function <VAR>-intset for setting an integer customize setting VAR.
+Args as for the macro `proof-defintset', except will be evaluated."
+ (eval
+ `(defun ,(if othername othername
+ (intern (concat (symbol-name var) "-intset"))) (arg)
+ ,(concat "Set `" (symbol-name var) "' to ARG.
+This function simply uses customize-set-variable to set the variable.
+It was constructed with `proof-defintset-fn'.")
+ (interactive ,(concat "nValue for " (symbol-name var)
+ " (integer): "))
+ (customize-set-variable (quote ,var) arg))))
+
+(defmacro proof-defintset (var &optional othername)
+ "Define a function <VAR>-intset for setting an integer customize setting VAR.
+The setting function uses customize-set-variable to change the variable.
+OTHERNAME gives an alternative name than the default <VAR>-intset.
+The name of the defined function is returned."
+ `(proof-defintset-fn (quote ,var) (quote ,othername)))
+
+(defun proof-defstringset-fn (var &optional othername)
+ "Define a function <VAR>-toggle for setting an integer customize setting VAR.
+Args as for the macro `proof-defstringset', except will be evaluated."
+ (eval
+ `(defun ,(if othername othername
+ (intern (concat (symbol-name var) "-stringset"))) (arg)
+ ,(concat "Set `" (symbol-name var) "' to ARG.
+This function simply uses customize-set-variable to set the variable.
+It was constructed with `proof-defstringset-fn'.")
+ (interactive ,(concat "sValue for " (symbol-name var)
+ " (a string): "))
+ (customize-set-variable (quote ,var) arg))))
+
+(defmacro proof-defstringset (var &optional othername)
+ "The setting function uses customize-set-variable to change the variable.
+OTHERNAME gives an alternative name than the default <VAR>-stringset.
+The name of the defined function is returned."
+ `(proof-defstringset-fn (quote ,var) (quote ,othername)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Finding executables
+;;
+
+(defun proof-locate-executable (progname &optional returnnopath)
+ ;; XEmacs can search the paths for us. Probably FSF Emacs is too
+ ;; daft to provide a useful function to do that, and I don't have
+ ;; the time to waste writing one or trying to find one.
+ "Search for PROGNAME on PATH. Return the full path to PROGNAME, or nil.
+If RETURNNOPATH is non-nil, return PROGNAME even if we can't find a full path."
+ (or (and
+ (fboundp 'locate-file)
+ (locate-file progname
+ (split-path (getenv "PATH"))
+ (if proof-running-on-win32 '(".exe"))
+ 1))
+ (and
+ returnnopath
+ progname)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Stuff for developing PG, not needed for ordinary users really.
+;; [Could consider moving this to a new file `proof-devel.el']
+;;
+
+(put 'proof-if-setting-configured 'lisp-indent-function 1)
+(put 'proof-define-assistant-command 'lisp-indent-function 'defun)
+(put 'proof-define-assistant-command-witharg 'lisp-indent-function 'defun)
+(put 'defpgcustom 'lisp-indent-function 'defun)
+
+(defconst proof-extra-fls
+ (list
+ (list "^(\\(proof-def\\"
+ ;; Variable like things
+ "\\(asscustom)\\|"
+ ;; Function like things
+ "\\([^ \t\n\(\)]+\\)"
+ ;; Any whitespace and declared object.
+ "[ \t'\(]*"
+ "\\([^ \t\n\)]+\\)?")
+ '(1 font-lock-keyword-face)
+ '(8 (cond ((match-beginning 3) 'font-lock-variable-name-face)
+ ;; ((match-beginning 6) 'font-lock-type-face)
+ (t 'font-lock-function-name-face))
+ nil t)))
+
+;; This doesn't work for FSF's font lock, developers should use
+;; XEmacs!
+(if (boundp 'lisp-font-lock-keywords) ; compatibility hack
+ (setq lisp-font-lock-keywords
+ (append proof-extra-fls
+ lisp-font-lock-keywords)))
+
+(setq autoload-package-name "proof")
+(setq generated-autoload-file "proof-autoloads.el")
+
+;; End of proof-utils.el
+(provide 'proof-utils) \ No newline at end of file
diff --git a/generic/proof-x-symbol.el b/generic/proof-x-symbol.el
new file mode 100644
index 00000000..d93da807
--- /dev/null
+++ b/generic/proof-x-symbol.el
@@ -0,0 +1,336 @@
+;; proof-x-symbol.el Support for X-Symbol package
+;;
+;; Copyright (C) 1998,9 LFCS Edinburgh.
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; The X-Symbol package is currently available at
+;; http://www.fmi.uni-passau.de/~wedler/x-symbol
+;;
+;; With thanks to David von Oheimb for providing the original
+;; patches for using X-Symbol with Isabelle Proof General,
+;; and helping to write this file.
+;;
+;; This file is standalone so that the X-Symbol mode for particular
+;; proof assistants may be used elsewhere (e.g. in document modes),
+;; without loading all of Proof General.
+;;
+;; proof-x-symbol.el,v 2.4 1999/08/23 18:38:40 da Exp
+;;
+
+(defvar proof-x-symbol-initialized nil
+ "Non-nil if x-symbol support has been initialized.")
+
+;;; ###autoload
+(defun proof-x-symbol-support-maybe-available ()
+ "A test to see whether x-symbol support may be available."
+ (and window-system ; Not on a tty
+ (condition-case ()
+ (require 'x-symbol-hooks)
+ (t (featurep 'x-symbol-hooks)))))
+
+
+(defun proof-x-symbol-initialize (&optional error)
+ "Initialize x-symbol support for Proof General, if possible.
+If ERROR is non-nil, give error on failure, otherwise a warning."
+ (interactive)
+ ; (unless proof-x-symbol-initialized
+ (let*
+ ((xs-lang (proof-ass x-symbol-language))
+ (xs-lang-name (symbol-name xs-lang))
+ (xs-feature (concat "x-symbol-" xs-lang-name))
+ (xs-feature-sym (intern xs-feature))
+ (error-or-warn
+ (lambda (str) (if error (error str) (warn str)))))
+ ;; Check that support is provided.
+ (cond
+ ;;
+ ;; First, some checks on x-symbol.
+ ;;
+ ((and (not (featurep 'x-symbol))
+ (not (proof-try-require 'x-symbol)))
+ (funcall error-or-warn
+ "Proof General: x-symbol package must be installed for x-symbol-support!
+The package is available at http://www.fmi.uni-passau.de/~wedler/x-symbol"))
+ ((not window-system)
+ (funcall error-or-warn
+ "Proof General: x-symbol package only runs under a window system!"))
+ ((or (not (fboundp 'x-symbol-initialize))
+ (not (fboundp 'x-symbol-register-language)))
+ (funcall error-or-warn
+ "Proof General: x-symbol package installation faulty!"))
+ ;;
+ ;; Now check proof assistant has support provided
+ ;;
+ ;; FIXME: maybe we should let x-symbol load the feature, in
+ ;; case it uses x-symbol stuff inside.
+ ;; Is there an easy way of testing for library exists?
+ ((not (proof-try-require xs-feature-sym))
+ (funcall error-or-warn
+ (format
+ "Proof General: for x-symbol support, you must provide a library %s.el"
+ xs-feature)))
+ (t
+ ;; We've got everything we need! So initialize.
+ (let*
+ ((xs-xtra-modes proof-xsym-extra-modes)
+ (xs-std-modes (list
+ ;; NB: there is a problem with
+ ;; initialization order here, these
+ ;; variables are set in script/shell
+ ;; mode initialization. They ought to
+ ;; be set earlier, and enforced as part
+ ;; of the generic scheme. For the time
+ ;; being, we use default constructed
+ ;; names [which every prover should
+ ;; follow]
+ (or proof-mode-for-shell
+ (intern (concat assistant "-shell-mode")))
+ (or proof-mode-for-response
+ (intern (concat assistant "-response-mode")))
+ (or proof-mode-for-script
+ ;; FIXME: next one only correct for isabelle
+ (intern (concat assistant "-proofscript-mode")))
+ (or proof-mode-for-goals
+ (intern (concat assistant "-goals-mode")))))
+ (all-xs-modes (append xs-std-modes xs-xtra-modes))
+ (am-entry (list proof-xsym-extra-modes t
+ `(quote ,xs-lang)))
+ (symmode-nm (concat xs-lang-name "sym-mode"))
+ (symmode (intern symmode-nm))
+ (symnamevar (intern (concat xs-feature "-name")))
+ (symname (concat (capitalize xs-lang-name) " Symbols"))
+ (symmodelinevar (intern (concat xs-feature "-modeline-name")))
+ (symmodelinenm xs-lang-name)
+ (flks proof-xsym-font-lock-keywords))
+
+
+ (x-symbol-initialize) ;; No harm in doing this multiple times
+ ;; Set default name and modeline indicator for the symbol
+ ;; minor mode
+ (set symnamevar symname)
+ (set symmodelinevar symmodelinenm)
+ (x-symbol-register-language xs-lang xs-feature-sym all-xs-modes)
+ ;; Put the extra modes on the auto-mode-alist
+ ;; 3.0: don't bother: rashly assume that their mode
+ ;; functions invoke proof-x-symbol-mode. That way we can
+ ;; turn on/off cleanly in proof-x-symbol-mode-all-buffers.
+ ;; (if xs-xtra-modes (push am-entry x-symbol-auto-mode-alist))
+ ;; Okay, let's be less rash and put it on a hook list.
+ ;; 12.1.00: Nope, there's a problem here!
+ ;; Results in thy-mode invoking
+ ;; proof-x-symbol-mode twice, first via hook, then
+ ;; from proof-config-done-related, which blasts
+ ;; font-lock-keywords (whilst font-lock is turned on!)
+ ;; . Temporarily disable this,
+ ;; and consider what to do for other extra modes
+ ;; (isa-latex).
+; (dolist (mode proof-xsym-extra-modes)
+; (add-hook
+; (intern (concat (symbol-name mode) "-hook"))
+; 'proof-x-symbol-mode))
+ ;; Font lock support is optional
+ (if flks
+ (put symmode 'font-lock-defaults (list flks)))
+ ;;
+ ;; Finished.
+ (setq proof-x-symbol-initialized t))))))
+
+
+;;;###autoload
+(defun proof-x-symbol-enable ()
+ "Turn on or off support for x-symbol, initializing if necessary.
+Calls proof-x-symbol-toggle-clean-buffers afterwards."
+ (if (and (proof-ass x-symbol-enable) (not proof-x-symbol-initialized))
+ (progn
+ (set (proof-ass-sym x-symbol-enable) nil) ; assume failure!
+ (proof-x-symbol-initialize 'giveerrors)
+ (set (proof-ass-sym x-symbol-enable) t)))
+ (proof-x-symbol-mode-all-buffers)
+ (proof-x-symbol-toggle-clean-buffers))
+
+;; First inclination was to put this function in a hook called by
+;; enable function. But rather than proliferate hooks needlessly, it
+;; seems better to wait to find out whether they're really needed.
+(defun proof-x-symbol-toggle-clean-buffers ()
+ "Clear the response buffer and send proof-showproof-command.
+This function is intended to clean the display after a change
+in the status of X-Symbol display.
+This is a subroutine of proof-x-symbol-enable."
+ (proof-shell-maybe-erase-response nil t t)
+ (if (and proof-showproof-command (proof-shell-available-p))
+ (proof-shell-invisible-command proof-showproof-command)))
+
+;;;###autoload
+(defun proof-x-symbol-decode-region (start end)
+ "Call (x-symbol-decode-region START END), if x-symbol support is enabled.
+This converts tokens in the region into X-Symbol characters.
+Return new END value."
+ (if (proof-ass x-symbol-enable)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region start end)
+ ;; FIXME: for GNU 21, this doesn't work always??
+ ;; (OK for response, but not for goals, why?)
+ (x-symbol-decode-region start end)
+ ;; Decoding may change character positions.
+ ;; Return new end value
+ (point-max)))
+ end))
+
+(defun proof-x-symbol-encode-shell-input ()
+ "Encode shell input in the variable STRING.
+A value for proof-shell-insert-hook."
+ (and x-symbol-language
+ (setq string
+ (save-excursion
+ (let ((language x-symbol-language)
+ (coding x-symbol-coding)
+ (selective selective-display)) ;FIXME: needed?
+ (set-buffer (get-buffer-create "x-symbol comint"))
+ (erase-buffer)
+ (insert string)
+ (setq x-symbol-language language)
+ (setq x-symbol-8bits nil)
+ (setq x-symbol-coding nil)
+ (x-symbol-encode-all nil coding))
+ (prog1
+ (buffer-substring (point-min) (point-max))
+ ;; FIXME da: maybe more efficient just to delete
+ ;; region. Make buffer name start with space
+ ;; to be unselectable.
+ (kill-buffer (current-buffer)))))))
+
+
+
+
+(defun proof-x-symbol-mode-all-buffers ()
+ "Activate/deactivate x-symbols in all Proof General buffers.
+A subroutine of proof-x-symbol-enable."
+ ;; Response and goals buffer are fontified/decoded
+ ;; manually in the code, configuration only sets
+ ;; x-symbol-language.
+ (proof-map-buffers (list proof-goals-buffer
+ proof-response-buffer
+ proof-trace-buffer)
+ (proof-x-symbol-configure))
+ ;; Shell has its own configuration
+ (proof-with-current-buffer-if-exists proof-shell-buffer
+ (proof-x-symbol-shell-config))
+ ;; Script buffers are in X-Symbol's minor mode,
+ ;; And so are any other buffers kept in the same token language
+ (dolist (mode (cons proof-mode-for-script proof-xsym-extra-modes))
+ (proof-map-buffers
+ (proof-buffers-in-mode mode)
+ (proof-x-symbol-mode))))
+
+;;
+;; Three functions for configuring buffers:
+;;
+;; proof-x-symbol-mode: for script buffer (X-Symbol minor mode)
+;; proof-x-symbol-shell-config: for shell buffer (input hook)
+;; proof-x-symbol-configure: for goals/response buffer (font lock)
+;;
+
+(defun proof-x-symbol-set-language ()
+ "Set x-symbol-language for the current proof assistant."
+ (setq x-symbol-language (proof-ass x-symbol-language)))
+
+;;;###autoload
+(defun proof-x-symbol-mode ()
+ "Turn on/off x-symbol mode in current buffer, from proof-x-symbol-enable.
+The X-Symbol minor mode is only useful in buffers where symbol input
+takes place (it isn't used for output-only buffers)."
+ (interactive)
+ (save-excursion ; needed or point moves: why?
+ (if proof-x-symbol-initialized
+ (progn
+ ;; Buffers which have XS minor mode toggled always keep
+ ;; x-symbol-language set.
+ (proof-x-symbol-set-language)
+ (x-symbol-mode (if (proof-ass x-symbol-enable) 1 0))
+ ;; Font lock mode must be engaged for x-symbol to do its job
+ ;; properly, at least when there is no mule around.
+ (if (and x-symbol-mode (not (featurep 'mule)))
+ (if (not font-lock-mode)
+ (font-lock-mode)
+ ;; Even if font-lock was on before we may need to
+ ;; refontify now that the patterns (and buffer
+ ;; contents) have changed. Shouldn't x-symbol do this?
+ (font-lock-fontify-buffer)))))))
+
+;;;####autoload
+(defun proof-x-symbol-shell-config ()
+ "Configure the proof shell for x-symbol, if proof-x-symbol-support<>nil.
+Assumes that the current buffer is the proof shell buffer."
+ ;; The best strategy seems to be *not* to turn on decoding
+ ;; in the shell itself. The reason is that there can be
+ ;; a clash between annotations and X-Symbol characters
+ ;; which leads to funny effects later. Moreover, the
+ ;; user isn't encouraged to interact directly with the
+ ;; shell, so we don't need to be helpful there.
+ ;; So we keep the shell buffer as plain text plus annotations.
+ ;; Even font-lock is problematical, so it should be switched off
+ ;; too.
+ (if proof-x-symbol-initialized
+ (progn
+ (cond
+ ((proof-ass x-symbol-enable)
+ (proof-x-symbol-set-language)
+ (if (and proof-xsym-activate-command
+ (proof-shell-live-buffer))
+ (proof-shell-invisible-command
+ proof-xsym-activate-command 'wait))
+ ;; We do encoding as the first step of input manipulation
+ (add-hook 'proof-shell-insert-hook
+ 'proof-x-symbol-encode-shell-input))
+ ((not (proof-ass x-symbol-enable))
+ (if (and proof-xsym-deactivate-command
+ (proof-shell-live-buffer))
+ (proof-shell-invisible-command
+ proof-xsym-deactivate-command 'wait))
+ (remove-hook 'proof-shell-insert-hook
+ 'proof-x-symbol-encode-shell-input)
+ ;; NB: x-symbol automatically adds an output filter but
+ ;; it doesn't actually get used unless the minor mode is
+ ;; active. Removing it here is just tidying up.
+ (remove-hook 'comint-output-filter-functions
+ 'x-symbol-comint-output-filter))))))
+
+;;;###autoload
+(defun proof-x-symbol-configure ()
+ "Configure the current buffer (goals or response) for X-Symbol."
+ (if (proof-ass x-symbol-enable)
+ (progn
+ (proof-x-symbol-set-language)
+ ;; If we're turning on x-symbol, attempt to convert to
+ ;; characters. (Only works if the buffer already
+ ;; contains tokens!)
+ (x-symbol-decode))))
+ ;; Encoding back to tokens doesn't work too well: needs to
+ ;; do some de-fontification to remove font properties, and
+ ;; is flaky anyway because token -> char not nec injective.
+ ; (if (boundp 'x-symbol-language)
+ ; ;; If we're turning off x-symbol, convert back to tokens.
+ ; (x-symbol-encode))))
+
+
+;; Compatibility with completion package
+
+(put 'completion-separator-self-insert-command 'x-symbol-input t)
+(put 'completion-separator-self-insert-autofilling 'x-symbol-input t)
+
+
+;;
+;; Try to initialize x-symbol-support on load-up if user has asked for it
+;;
+(if (proof-ass x-symbol-enable)
+ (progn
+ (proof-x-symbol-initialize)
+ (unless proof-x-symbol-initialized
+ ;; If initialization failed, turn off
+ ;; x-symbol-enable for the session.
+ (customize-set-variable (proof-ass-sym x-symbol-enable) nil))))
+
+(provide 'proof-x-symbol)
+;; End of proof-x-symbol.el
diff --git a/generic/proof.el b/generic/proof.el
new file mode 100644
index 00000000..40d77733
--- /dev/null
+++ b/generic/proof.el
@@ -0,0 +1,120 @@
+;; proof.el Proof General loader. All files require this one.
+;;
+;; Copyright (C) 1998-2000 LFCS Edinburgh.
+;;
+;; Authors: David Aspinall, Yves Bertot, Healfdene Goguen,
+;; Thomas Kleymann and Dilip Sequeira
+;;
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+
+(require 'proof-site) ; site config
+(require 'proof-compat) ; Emacs and OS compatibility
+(require 'proof-utils) ; utilities
+(require 'proof-config) ; configuration variables
+
+
+(proof-splash-message) ; welcome the user now.
+
+;;;
+;;; Extra autoloads that aren't automatic
+;;; (defined with define-derived-mode)
+;;;
+
+(autoload 'proof-mode "proof-script"
+ "Proof General major mode class for proof scripts.")
+
+(autoload 'proof-shell-mode "proof-shell"
+ "Proof General shell mode class for proof assistant processes")
+
+
+;;;
+;;; Global variables
+;;;
+
+(deflocal proof-buffer-type nil
+ "Symbol indicating the type of this buffer: 'script, 'shell, 'pbp, or 'response.")
+
+(defvar proof-shell-busy nil
+ "A lock indicating that the proof shell is processing.
+When this is non-nil, proof-shell-ready-prover will give
+an error.")
+
+(defvar proof-included-files-list nil
+ "List of files currently included in proof process.
+This list contains files in canonical truename format
+(see `file-truename').
+
+Whenever a new file is being processed, it gets added to this list
+via the proof-shell-process-file configuration settings.
+When the prover retracts a file, this list is resynchronised via the
+proof-shell-retract-files-regexp and proof-shell-compute-new-files-list
+configuration settings.
+
+Only files which have been *fully* processed should be included here.
+Proof General itself will automatically add the filenames of a script
+buffer which has been completely read when scripting is deactivated.
+It will automatically remove the filename of a script buffer which
+is completely unread when scripting is deactivated.
+
+NB: Currently there is no generic provision for removing files which
+are only partly read-in due to an error, so ideally the proof assistant
+should only output a processed message when a file has been successfully
+read.")
+
+
+(defvar proof-script-buffer nil
+ "The currently active scripting buffer or nil if none.")
+
+(defvar proof-previous-script-buffer nil
+ "Previous value of proof-script-buffer, recorded when scripting turned off.
+At the moment, this is only used for Coq's ugly multiple file code,
+to help guess the directory of files Coq says it's reinterning.")
+
+(defvar proof-shell-buffer nil
+ "Process buffer where the proof assistant is run.")
+
+(defvar proof-goals-buffer nil
+ "The goals buffer.")
+
+(defvar proof-response-buffer nil
+ "The response buffer.")
+
+(defvar proof-trace-buffer nil
+ "A tracing buffer for storing tracing output from the proof shell.
+See `proof-shell-trace-output-regexp' for details.")
+
+(defvar proof-shell-error-or-interrupt-seen nil
+ "Flag indicating that an error or interrupt has just occurred.
+Set to 'error or 'interrupt if one was observed from the proof
+assistant during the last group of commands.")
+
+(defvar proof-shell-proof-completed nil
+ "Flag indicating that a completed proof has just been observed.
+If non-nil, the value counts the commands from the last command
+of the proof (starting from 1).")
+
+;; FIXME da: remove proof-terminal-string. At the moment some
+;; commands need to have the terminal string, some don't.
+;; It's used variously in proof-script and proof-shell, which
+;; is another mess. [Shell mode implicitly assumes script mode
+;; has been configured].
+;; We should assume commands are terminated at the specific level.
+
+(defvar proof-terminal-string nil
+ "End-of-line string for proof process.")
+
+
+
+
+;;;
+;;; Load other Proof General libraries
+;;;
+
+(require 'proof-system)
+
+
+(provide 'proof)
+;; proof.el ends here
diff --git a/generic/span-extent.el b/generic/span-extent.el
new file mode 100644
index 00000000..ccbc1a93
--- /dev/null
+++ b/generic/span-extent.el
@@ -0,0 +1,113 @@
+;; This file implements spans in terms of extents, for xemacs.
+;; Copyright (C) 1998 LFCS Edinburgh
+;; Author: Healfdene Goguen
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Bridging the emacs19/xemacs gulf ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Now define "spans" in terms of extents.
+
+(defsubst make-span (start end)
+ "Make a span for the range [START, END) in current buffer."
+ (make-extent start end))
+
+(defsubst detach-span (span)
+ "Remove SPAN from its buffer."
+ (detach-extent span))
+
+(defsubst set-span-endpoints (span start end)
+ "Set the endpoints of SPAN to START, END."
+ (set-extent-endpoints span start end))
+
+(defsubst set-span-start (span value)
+ "Set the start point of SPAN to VALUE."
+ (set-extent-endpoints span value (extent-end-position span)))
+
+(defsubst set-span-end (span value)
+ "Set the end point of SPAN to VALUE."
+ (set-extent-endpoints span (extent-start-position span) value))
+
+(defsubst set-span-property (span name value)
+ "Set SPAN's property NAME to VALUE."
+ (set-extent-property span name value))
+
+(defsubst span-read-only (span)
+ "Set SPAN to be read only."
+ (set-span-property span 'read-only t))
+
+(defsubst span-read-write (span)
+ "Set SPAN to be writeable."
+ (set-span-property span 'read-only nil))
+
+(defun span-give-warning ()
+ "Give a warning message."
+ (message "You should not edit here!"))
+
+(defun span-write-warning (span)
+ "Give a warning message when SPAN is changed."
+ ;; FIXME: implement this in XEmacs, perhaps with after-change-functions
+ ;;
+ (set-span-property span 'read-only nil)
+ )
+
+(defsubst span-property (span name)
+ "Return SPAN's value for property PROPERTY."
+ (extent-property span name))
+
+(defsubst delete-span (span)
+ "Delete SPAN."
+ (let ((predelfn (span-property span 'span-delete-action)))
+ (and predelfn (funcall predelfn)))
+ (delete-extent span))
+
+(defsubst mapcar-spans (fn start end prop &optional val)
+ "Apply function FN to all spans between START and END with property PROP set"
+ (mapcar-extents fn nil (current-buffer) start end nil prop val))
+
+(defsubst delete-spans (start end prop)
+ "Delete all spans between START and END with property PROP set."
+ (mapcar-spans 'delete-span start end prop))
+
+(defsubst span-at (pt prop)
+ "Return the smallest SPAN at point PT with property PROP."
+ (extent-at pt nil prop))
+
+(defsubst span-at-before (pt prop)
+ "Return the smallest SPAN at before PT with property PROP.
+A span is before PT if it covers the character before PT."
+ (extent-at pt nil prop nil 'before))
+
+(defsubst span-start (span)
+ "Return the start position of SPAN, or nil if SPAN is detatched."
+ (extent-start-position span))
+
+(defsubst span-end (span)
+ "Return the end position of SPAN, or nil if SPAN is detatched."
+ (extent-end-position span))
+
+(defsubst prev-span (span prop)
+ "Return span before SPAN with property PROP."
+ (extent-at (extent-start-position span) nil prop nil 'before))
+
+(defsubst next-span (span prop)
+ "Return span after SPAN with property PROP."
+ (extent-at (extent-end-position span) nil prop nil 'after))
+
+(defsubst span-live-p (span)
+ "Return non-nil if SPAN is live and in a live buffer."
+ (and span
+ (extent-live-p span)
+ (buffer-live-p (extent-object span))))
+
+(defun span-raise (span)
+ "Function added for FSF Emacs compatibility. Do nothing here."
+ nil)
+
+(defalias 'span-object 'extent-object)
+
+
+(provide 'span-extent)
diff --git a/generic/span-overlay.el b/generic/span-overlay.el
new file mode 100644
index 00000000..a36d95f7
--- /dev/null
+++ b/generic/span-overlay.el
@@ -0,0 +1,313 @@
+;; This file implements spans in terms of extents, for emacs19.
+;; Copyright (C) 1998 LFCS Edinburgh
+;; Author: Healfdene Goguen
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;;
+;; $Id$
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Bridging the emacs19/xemacs gulf ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; before-list represents a linked list of spans for each buffer.
+;; It has the invariants of:
+;; * being ordered wrt the starting point of the spans in the list,
+;; with detached spans at the end.
+;; * not having overlapping overlays of the same type.
+
+(defvar before-list nil
+ "Start of backwards-linked list of spans")
+
+(make-variable-buffer-local 'before-list)
+
+
+(or (fboundp 'foldr)
+(defun foldr (func a seq)
+ "Return (func (func (func (... (func a Sn) ...) S2) S1) S0)
+when func's argument is 2 and seq is a sequence whose
+elements = S0 S1 S2 ... Sn. [tl-seq.el]"
+ (let ((i (length seq)))
+ (while (> i 0)
+ (setq i (1- i))
+ (setq a (funcall func a (elt seq i)))
+ )
+ a)))
+
+(or (fboundp 'foldl)
+(defun foldl (func a seq)
+ "Return (... (func (func (func a S0) S1) S2) ...)
+when func's argument is 2 and seq is a sequence whose
+elements = S0 S1 S2 .... [tl-seq.el]"
+ (let ((len (length seq))
+ (i 0))
+ (while (< i len)
+ (setq a (funcall func a (elt seq i)))
+ (setq i (1+ i))
+ )
+ a)))
+
+(defsubst span-start (span)
+ "Return the start position of SPAN."
+ (overlay-start span))
+
+(defsubst span-end (span)
+ "Return the end position of SPAN."
+ (overlay-end span))
+
+(defun set-span-property (span name value)
+ "Set SPAN's property NAME to VALUE."
+ (overlay-put span name value))
+
+(defsubst span-property (span name)
+ "Return SPAN's value for property PROPERTY."
+ (overlay-get span name))
+
+;; This function is problematical with font-lock turned on.
+(defun span-read-only-hook (overlay after start end &optional len)
+ (error "Region is read-only"))
+
+;;; FIXME: This is too harsh and breaks font-lock
+;;; If only faces are modified we shouldn't call span-read-only-hook
+(defun span-read-only (span)
+ "Set SPAN to be read only."
+ ;; Unfortunately, this function is called on spans which are
+ ;; detached from a buffer, which gives an error here, since
+ ;; text-properties are associated with text in a particular
+ ;; buffer position.
+ ;(add-text-properties (span-start span) (span-end span) '(read-only t)))
+ (set-span-property span 'modification-hooks '(span-read-only-hook))
+ (set-span-property span 'insert-in-front-hooks '(span-read-only-hook)))
+
+(defun span-read-write (span)
+ "Set SPAN to be writeable."
+ ;; See comment above for text properties problem.
+ (set-span-property span 'modification-hooks nil)
+ (set-span-property span 'insert-in-front-hooks nil))
+
+(defun span-give-warning (&rest args)
+ "Give a warning message."
+ (message "You should not edit here!"))
+
+(defun span-write-warning (span)
+ "Give a warning message when SPAN is changed."
+ (set-span-property span 'modification-hooks '(span-give-warning))
+ (set-span-property span 'insert-in-front-hooks '(span-give-warning)))
+
+(defun int-nil-lt (m n)
+ (cond
+ ((eq m n) nil)
+ ((not n) t)
+ ((not m) nil)
+ (t (< m n))))
+
+;; We use end first because proof-locked-queue is often changed, and
+;; its starting point is always 1
+(defun span-lt (s u)
+ (or (int-nil-lt (span-end s) (span-end u))
+ (and (eq (span-end s) (span-end u))
+ (int-nil-lt (span-start s) (span-start u)))))
+
+(defun span-traverse (span prop)
+ (cond
+ ((not before-list)
+ ;; before-list empty
+ 'empty)
+ ((funcall prop before-list span)
+ ;; property holds for before-list and span
+ 'hd)
+ (t
+ ;; traverse before-list for property
+ (let ((l before-list) (before (span-property before-list 'before)))
+ (while (and before (not (funcall prop before span)))
+ (setq l before)
+ (setq before (span-property before 'before)))
+ l))))
+
+(defun add-span (span)
+ (let ((ans (span-traverse span 'span-lt)))
+ (cond
+ ((eq ans 'empty)
+ (set-span-property span 'before nil)
+ (setq before-list span))
+ ((eq ans 'hd)
+ (set-span-property span 'before before-list)
+ (setq before-list span))
+ (t
+ (set-span-property span 'before
+ (span-property ans 'before))
+ (set-span-property ans 'before span)))))
+
+(defun make-span (start end)
+ "Make a span for the range [START, END) in current buffer."
+ (add-span (make-overlay start end)))
+
+(defun remove-span (span)
+ (let ((ans (span-traverse span 'eq)))
+ (cond
+ ((eq ans 'empty)
+ (error "Bug: empty span list"))
+ ((eq ans 'hd)
+ (setq before-list (span-property before-list 'before)))
+ (ans
+ (set-span-property ans 'before (span-property span 'before)))
+ (t (error "Bug: span does not occur in span list")))))
+
+;; extent-at gives "smallest" extent at pos
+;; we're assuming right now that spans don't overlap
+(defun spans-at-point (pt)
+ (let ((overlays nil) (os nil))
+ (setq os (overlays-at pt))
+ (while os
+ (if (not (memq (car os) overlays))
+ (setq overlays (cons (car os) overlays)))
+ (setq os (cdr os)))
+ overlays))
+
+;; assumes that there are no repetitions in l or m
+(defun append-unique (l m)
+ (foldl (lambda (n a) (if (memq a m) n (cons a n))) m l))
+
+(defun spans-at-region (start end)
+ (let ((overlays nil) (pos start))
+ (while (< pos end)
+ (setq overlays (append-unique (spans-at-point pos) overlays))
+ (setq pos (next-overlay-change pos)))
+ overlays))
+
+(defun spans-at-point-prop (pt prop)
+ (let ((f (cond
+ (prop (lambda (spans span)
+ (if (span-property span prop) (cons span spans)
+ spans)))
+ (t (lambda (spans span) (cons span spans))))))
+ (foldl f nil (spans-at-point pt))))
+
+(defun spans-at-region-prop (start end prop &optional val)
+ (let ((f (cond
+ (prop
+ (lambda (spans span)
+ (if (if val (eq (span-property span prop) val)
+ (span-property span prop))
+ (cons span spans)
+ spans)))
+ (t
+ (lambda (spans span) (cons span spans))))))
+ (foldl f nil (spans-at-region start end))))
+
+(defun span-at (pt prop)
+ "Return the SPAN at point PT with property PROP.
+For XEmacs, span-at gives smallest extent at pos.
+For Emacs, we assume that spans don't overlap."
+ (car (spans-at-point-prop pt prop)))
+
+(defsubst detach-span (span)
+ "Remove SPAN from its buffer."
+ (remove-span span)
+ (delete-overlay span)
+ (add-span span))
+
+(defsubst delete-span (span)
+ "Delete SPAN."
+ (let ((predelfn (span-property span 'span-delete-action)))
+ (and predelfn (funcall predelfn)))
+ (remove-span span)
+ (delete-overlay span))
+
+;; The next two change ordering of list of spans:
+(defsubst set-span-endpoints (span start end)
+ "Set the endpoints of SPAN to START, END.
+Re-attaches SPAN if it was removed from the buffer."
+ (remove-span span)
+ (move-overlay span start end)
+ (add-span span))
+
+(defsubst set-span-start (span value)
+ "Set the start point of SPAN to VALUE."
+ (set-span-endpoints span value (span-end span)))
+
+;; This doesn't affect invariant:
+(defsubst set-span-end (span value)
+ "Set the end point of SPAN to VALUE."
+ (set-span-endpoints span (span-start span) value))
+
+(defsubst mapcar-spans (fn start end prop &optional val)
+ "Apply function FN to all spans between START and END with property PROP set"
+ (mapcar fn (spans-at-region-prop start end prop val)))
+
+(defsubst delete-spans (start end prop)
+ "Delete all spans between START and END with property PROP set."
+ (mapcar-spans 'delete-span start end prop))
+
+(defun map-spans-aux (f l)
+ (cond (l (cons (funcall f l) (map-spans-aux f (span-property l 'before))))
+ (t ())))
+
+(defsubst map-spans (f)
+ (map-spans-aux f before-list))
+
+(defun find-span-aux (prop-p l)
+ (while (and l (not (funcall prop-p l)))
+ (setq l (span-property l 'before)))
+ l)
+
+(defun find-span (prop-p)
+ (find-span-aux prop-p before-list))
+
+(defun span-at-before (pt prop)
+ "Return the smallest SPAN at before PT with property PROP.
+A span is before PT if it covers the character before PT."
+ (let ((prop-pt-p
+ (cond (prop (lambda (span)
+ (let ((start (span-start span)))
+ (and start (> pt start)
+ (span-property span prop)))))
+ (t (lambda (span)
+ (let ((start (span-start span)))
+ (and start (> pt start))))))))
+ (find-span prop-pt-p)))
+
+(defun prev-span (span prop)
+ "Return span before SPAN with property PROP."
+ (let ((prev-prop-p
+ (cond (prop (lambda (span) (span-property span prop)))
+ (t (lambda (span) t)))))
+ (find-span-aux prev-prop-p (span-property span 'before))))
+
+; overlays are [start, end)
+
+; Since Emacs 20.6 or so, next-span started being buggy.
+; Original version:
+;(defun next-span (span prop)
+; "Return span after SPAN with property PROP. If there are two spans overlapping then this won't work."
+; (let ((l (member-if (lambda (span) (span-property span prop))
+; (overlays-at
+; (next-overlay-change (overlay-start span))))))
+; (car-safe l)))
+; Hacked version by Christophe Raffalli:
+(defun next-span (span prop)
+ "Return span after SPAN with property PROP. If there are two spans overlapping then this won't work."
+ (let (spanres (l (member-if (lambda (span) (span-property span prop))
+ (overlays-at
+ (next-overlay-change (overlay-start span))))))
+ (setq spanres (car-safe l))
+ ;; The test is for a dirty bug fix with FSF Emacs with next-span not
+ ;; advancing the span!
+ (if (and spanres (<= (span-start spanres) (span-start span)))
+ nil spanres)))
+
+(defsubst span-live-p (span)
+ "Return non-nil if SPAN is in a live buffer."
+ (and span
+ (overlay-buffer span)
+ (buffer-live-p (overlay-buffer span))))
+
+(defun span-raise (span)
+ "Set priority of span to make it appear above other spans.
+FIXME: new hack added nov 99 because of disappearing overlays.
+Behaviour is still worse than before."
+ (set-span-property span 'priority 100))
+
+(defalias 'span-object 'overlay-object)
+
+(provide 'span-overlay)
diff --git a/generic/span.el b/generic/span.el
new file mode 100644
index 00000000..59710e1f
--- /dev/null
+++ b/generic/span.el
@@ -0,0 +1,20 @@
+;; span.el Datatype of "spans" for Proof General.
+;; Copyright (C) 1998 LFCS Edinburgh
+;; Author: Healfdene Goguen
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+
+
+;; Spans are our abstraction of extents/overlays.
+;;
+(eval-and-compile
+ (cond
+ ((fboundp 'make-extent) (require 'span-extent))
+ ((fboundp 'make-overlay) (require 'span-overlay))
+ (t
+ (error
+ "Your Emacs version is not compatible with Proof General, sorry."))))
+
+(provide 'span)
+;; span.el ends here.
diff --git a/generic/texi-docstring-magic.el b/generic/texi-docstring-magic.el
new file mode 100644
index 00000000..dc16d4ad
--- /dev/null
+++ b/generic/texi-docstring-magic.el
@@ -0,0 +1,381 @@
+;; texi-docstring-magic.el -- munge internal docstrings into texi
+;;
+;; Keywords: lisp, docs, tex
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Copyright (C) 1998 David Aspinall
+;; Maintainer: David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; This file is distributed under the terms of the GNU General Public
+;; License, Version 2. Find a copy of the GPL with your version of
+;; GNU Emacs or Texinfo.
+;;
+;;
+;; This package generates Texinfo source fragments from Emacs
+;; docstrings. This avoids documenting functions and variables
+;; in more than one place, and automatically adds Texinfo markup
+;; to docstrings.
+;;
+;; It relies heavily on you following the Elisp documentation
+;; conventions to produce sensible output, check the Elisp manual
+;; for details. In brief:
+;;
+;; * The first line of a docstring should be a complete sentence.
+;; * Arguments to functions should be written in upper case: ARG1..ARGN
+;; * User options (variables users may want to set) should have docstrings
+;; beginning with an asterisk.
+;;
+;; Usage:
+;;
+;; Write comments of the form:
+;;
+;; @c TEXI DOCSTRING MAGIC: my-package-function-or-variable-name
+;;
+;; In your texi source, mypackage.texi. From within an Emacs session
+;; where my-package is loaded, visit mypackage.texi and run
+;; M-x texi-docstring-magic to update all of the documentation strings.
+;;
+;; This will insert @defopt, @deffn and the like underneath the
+;; magic comment strings.
+;;
+;; The default value for user options will be printed.
+;;
+;; Symbols are recognized if they are defined for faces, functions,
+;; or variables (in that order).
+;;
+;; Automatic markup rules:
+;;
+;; 1. Indented lines are gathered into a @lisp environment.
+;; 2. Pieces of text `stuff' or surrounded in quotes marked up with @samp.
+;; 3. Words *emphasized* are made @strong{emphasized}
+;; 4. Words sym-bol which are symbols become @code{sym-bol}.
+;; 5. Upper cased words ARG corresponding to arguments become @var{arg}.
+;; In fact, you can any word longer than three letters, so that
+;; metavariables can be used easily.
+;; FIXME: to escape this, use `ARG'
+;; 6. Words 'sym which are lisp-quoted are marked with @code{'sym}.
+;;
+;; -----
+;;
+;; Useful key binding when writing Texinfo:
+;;
+;; (define-key TeXinfo-mode-map "C-cC-d" 'texi-docstring-magic-insert-magic)
+;;
+;; -----
+;;
+;; Useful enhancements to do:
+;;
+;; * Tweak replacement: at the moment it skips blank lines
+;; under magic comment.
+;; * Use customize properties (e.g. group, simple types)
+;; * Look for a "texi-docstring" property for symbols
+;; so TeXInfo can be defined directly in case automatic markup
+;; goes badly wrong.
+;; * Add tags to special comments so that user can specify face,
+;; function, or variable binding for a symbol in case more than
+;; one binding exists.
+;;
+;; ------
+
+(defun texi-docstring-magic-find-face (face)
+ ;; Compatibility between FSF Emacs and XEmacs
+ (or (facep face)
+ (and (fboundp 'find-face) (find-face face))))
+
+(defun texi-docstring-magic-splice-sep (strings sep)
+ "Return concatenation of STRINGS spliced together with separator SEP."
+ (let (str)
+ (while strings
+ (setq str (concat str (car strings)))
+ (if (cdr strings)
+ (setq str (concat str sep)))
+ (setq strings (cdr strings)))
+ str))
+
+(defconst texi-docstring-magic-munge-table
+ '(;; 0. FIXME: escape @, { and } characters
+ ;; ("@" t "@@")
+ ;;("{" t "\\{")
+ ;; ("}" t "\\}")
+ ;; 1. Indented lines are gathered into @lisp environment.
+ ("\\(^.*\\S-.*$\\)"
+ t
+ (let
+ ((line (match-string 0 docstring)))
+ (if (eq (char-syntax (string-to-char line)) ?\ )
+ ;; whitespace
+ (if in-quoted-region
+ line
+ (setq in-quoted-region t)
+ (concat "@lisp\n" line))
+ ;; non-white space
+ (if in-quoted-region
+ (progn
+ (setq in-quoted-region nil)
+ (concat "@end lisp\n" line))
+ line))))
+ ;; 2. Pieces of text `stuff' or surrounded in quotes
+ ;; are marked up with @samp. NB: Must be backquote
+ ;; followed by forward quote for this to work.
+ ;; Can't use two forward quotes else problems with
+ ;; symbols.
+ ;; Odd hack: because ' is a word constituent in text/texinfo
+ ;; mode, putting this first enables the recognition of args
+ ;; and symbols put inside quotes.
+ ("\\(`\\([^']+\\)'\\)"
+ t
+ (concat "@samp{" (match-string 2 docstring) "}"))
+ ;; 3. Words *emphasized* are made @strong{emphasized}
+ ("\\(\\*\\(\\w+\\)\\*\\)"
+ t
+ (concat "@strong{" (match-string 2 docstring) "}"))
+ ;; 4. Words sym-bol which are symbols become @code{sym-bol}.
+ ;; Must have at least one hyphen to be recognized,
+ ;; terminated in whitespace, end of line, or punctuation.
+ ;; Only consider symbols made from word constituents
+ ;; and hyphen.
+ ("\\(\\(\\w+\\-\\(\\w\\|\\-\\)+\\)\\)\\(\\s\)\\|\\s-\\|\\s.\\|$\\)"
+ (or (boundp (intern (match-string 2 docstring)))
+ (fboundp (intern (match-string 2 docstring))))
+ (concat "@code{" (match-string 2 docstring) "}"
+ (match-string 4 docstring)))
+ ;; 5. Upper cased words ARG corresponding to arguments become
+ ;; @var{arg}
+ ;; In fact, include any word so long as it is more than 3 characters
+ ;; long. (Comes after symbols to avoid recognizing the
+ ;; lowercased form of an argument as a symbol)
+ ;; FIXME: maybe we don't want to downcase stuff already
+ ;; inside @samp
+ ;; FIXME: should - terminate? should _ be included?
+ ("\\([A-Z0-9_\\-]+\\)\\(/\\|\)\\|}\\|\\s-\\|\\s.\\|$\\)"
+ (or (> (length (match-string 1 docstring)) 3)
+ (member (downcase (match-string 1 docstring)) args))
+ (concat "@var{" (downcase (match-string 1 docstring)) "}"
+ (match-string 2 docstring)))
+
+ ;; 6. Words 'sym which are lisp quoted are
+ ;; marked with @code.
+ ("\\(\\(\\s-\\|^\\)'\\(\\(\\w\\|\\-\\)+\\)\\)\\(\\s\)\\|\\s-\\|\\s.\\|$\\)"
+ t
+ (concat (match-string 2 docstring)
+ "@code{'" (match-string 3 docstring) "}"
+ (match-string 5 docstring)))
+ ;; 7,8. Clean up for @lisp environments left with spurious newlines
+ ;; after 1.
+ ("\\(\\(^\\s-*$\\)\n@lisp\\)" t "@lisp")
+ ("\\(\\(^\\s-*$\\)\n@end lisp\\)" t "@end lisp")
+ ;; 9. Hack to remove @samp{@var{...}} sequences.
+ ;; Changed to just @samp of uppercase.
+ ("\\(@samp{@var{\\([^}]+\\)}}\\)"
+ t
+ (concat "@samp{" (upcase (match-string 2 docstring)) "}")))
+ "Table of regexp matches and replacements used to markup docstrings.
+Format of table is a list of elements of the form
+ (regexp predicate replacement-form)
+If regexp matches and predicate holds, then replacement-form is
+evaluated to get the replacement for the match.
+predicate and replacement-form can use variables arg,
+and forms such as (match-string 1 docstring)
+Match string 1 is assumed to determine the
+length of the matched item, hence where parsing restarts from.
+The replacement must cover the whole match (match string 0),
+including any whitespace included to delimit matches.")
+
+
+(defun texi-docstring-magic-untabify (string)
+ "Convert tabs in STRING into multiple spaces."
+ (save-excursion
+ (set-buffer
+ (get-buffer-create " texi-docstring-magic-untabify"))
+ (insert string)
+ (untabify (point-min) (point-max))
+ (prog1 (buffer-substring)
+ (kill-buffer (current-buffer)))))
+
+(defun texi-docstring-magic-munge-docstring (docstring args)
+ "Markup DOCSTRING for texi according to regexp matches."
+ (let ((case-fold-search nil))
+ (setq docstring (texi-docstring-magic-untabify docstring))
+ (dolist (test texi-docstring-magic-munge-table)
+ (let ((regexp (nth 0 test))
+ (predicate (nth 1 test))
+ (replace (nth 2 test))
+ (i 0)
+ in-quoted-region)
+
+ (while (and
+ (< i (length docstring))
+ (string-match regexp docstring i))
+ (setq i (match-end 1))
+ (if (eval predicate)
+ (let* ((origlength (- (match-end 0) (match-beginning 0)))
+ (replacement (eval replace))
+ (newlength (length replacement)))
+ (setq docstring
+ (replace-match replacement t t docstring))
+ (setq i (+ i (- newlength origlength))))))
+ (if in-quoted-region
+ (setq docstring (concat docstring "\n@end lisp"))))))
+ ;; Force a new line after (what should be) the first sentence,
+ ;; if not already a new paragraph.
+ (let*
+ ((pos (string-match "\n" docstring))
+ (needscr (and pos
+ (not (string= "\n"
+ (substring docstring
+ (1+ pos)
+ (+ pos 2)))))))
+ (if (and pos needscr)
+ (concat (substring docstring 0 pos)
+ "@*\n"
+ (substring docstring (1+ pos)))
+ docstring)))
+
+(defun texi-docstring-magic-texi (env grp name docstring args &optional endtext)
+ "Make a texi def environment ENV for entity NAME with DOCSTRING."
+ (concat "@def" env (if grp (concat " " grp) "") " " name
+ " "
+ (texi-docstring-magic-splice-sep args " ")
+ ;; " "
+ ;; (texi-docstring-magic-splice-sep extras " ")
+ "\n"
+ (texi-docstring-magic-munge-docstring docstring args)
+ "\n"
+ (or endtext "")
+ "@end def" env "\n"))
+
+(defun texi-docstring-magic-format-default (default)
+ "Make a default value string for the value DEFAULT.
+Markup as @code{stuff} or @lisp stuff @end lisp."
+ (let ((text (format "%S" default)))
+ (concat
+ "\nThe default value is "
+ (if (string-match "\n" text)
+ ;; Carriage return will break @code, use @lisp
+ (if (stringp default)
+ (concat "the string: \n@lisp\n" default "\n@end lisp\n")
+ (concat "the value: \n@lisp\n" text "\n@end lisp\n"))
+ (concat "@code{" text "}.\n")))))
+
+
+(defun texi-docstring-magic-texi-for (symbol)
+ (cond
+ ;; Faces
+ ((texi-docstring-magic-find-face symbol)
+ (let*
+ ((face symbol)
+ (name (symbol-name face))
+ (docstring (or (face-doc-string face)
+ "Not documented."))
+ (useropt (eq ?* (string-to-char docstring))))
+ ;; Chop off user option setting
+ (if useropt
+ (setq docstring (substring docstring 1)))
+ (texi-docstring-magic-texi "fn" "Face" name docstring nil)))
+ ((boundp symbol)
+ ;; Variables.
+ (let*
+ ((variable symbol)
+ (name (symbol-name variable))
+ (docstring (or (documentation-property variable
+ 'variable-documentation)
+ "Not documented."))
+ (useropt (eq ?* (string-to-char docstring)))
+ (default (if useropt
+ (texi-docstring-magic-format-default
+ (default-value symbol)))))
+ ;; Chop off user option setting
+ (if useropt
+ (setq docstring (substring docstring 1)))
+ (texi-docstring-magic-texi
+ (if useropt "opt" "var") nil name docstring nil default)))
+ ((fboundp symbol)
+ ;; Functions. Functions with same name as variables are documented
+ ;; as variables.
+ ;; We don't handle macros, aliases, or compiled fns properly.
+ (let*
+ ((function symbol)
+ (name (symbol-name function))
+ (docstring (or (documentation function)
+ "Not documented."))
+ (def (symbol-function function))
+ (macrop (eq 'macro (car-safe def)))
+ (argsyms (cond ((eq (car-safe def) 'lambda)
+ (nth 1 def))))
+ (args (mapcar 'symbol-name argsyms)))
+ (cond
+ ((commandp function)
+ (texi-docstring-magic-texi "fn" "Command" name docstring args))
+ (macrop
+ (texi-docstring-magic-texi "fn" "Macro" name docstring args))
+ (t
+ (texi-docstring-magic-texi "un" nil name docstring args)))))
+ (t
+ (error "Don't know anything about symbol %s" (symbol-name symbol)))))
+
+(defconst texi-docstring-magic-comment
+ "@c TEXI DOCSTRING MAGIC:"
+ "Magic string in a texi buffer expanded into @defopt, or @deffn.")
+
+
+;;;###autoload
+(defun texi-docstring-magic ()
+ "Update all texi docstring magic annotations in buffer."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (let ((magic (concat "^"
+ (regexp-quote texi-docstring-magic-comment)
+ "\\s-*\\(\\(\\w\\|\\-\\)+\\)\\s-*$"))
+ p
+ symbol)
+ (while (re-search-forward magic nil t)
+ (setq symbol (intern (match-string 1)))
+ (forward-line)
+ (setq p (point))
+ ;; If comment already followed by an environment, delete it.
+ (if (and
+ (looking-at "@def\\(\\w+\\)\\s-")
+ (search-forward (concat "@end def" (match-string 1)) nil t))
+ (progn
+ (forward-line)
+ (delete-region p (point))))
+ (insert
+ (texi-docstring-magic-texi-for symbol))))))
+
+(defun texi-docstring-magic-face-at-point ()
+ (ignore-errors
+ (let ((stab (syntax-table)))
+ (unwind-protect
+ (save-excursion
+ (set-syntax-table emacs-lisp-mode-syntax-table)
+ (or (not (zerop (skip-syntax-backward "_w")))
+ (eq (char-syntax (char-after (point))) ?w)
+ (eq (char-syntax (char-after (point))) ?_)
+ (forward-sexp -1))
+ (skip-chars-forward "'")
+ (let ((obj (read (current-buffer))))
+ (and (symbolp obj) (texi-docstring-magic-find-face obj) obj)))
+ (set-syntax-table stab)))))
+
+(defun texi-docstring-magic-insert-magic (symbol)
+ (interactive
+ (let* ((v (or (variable-at-point)
+ (function-at-point)
+ (texi-docstring-magic-face-at-point)))
+ (val (let ((enable-recursive-minibuffers t))
+ (completing-read
+ (if v
+ (format "Magic docstring for symbol (default %s): " v)
+ "Magic docstring for symbol: ")
+ obarray '(lambda (sym)
+ (or (boundp sym)
+ (fboundp sym)
+ (texi-docstring-magic-find-face sym)))
+ t nil 'variable-history))))
+ (list (if (equal val "") v (intern val)))))
+ (insert "\n" texi-docstring-magic-comment " " (symbol-name symbol)))
+
+
+(provide 'texi-docstring-magic)
diff --git a/hol98/README b/hol98/README
new file mode 100644
index 00000000..e6c3b4b3
--- /dev/null
+++ b/hol98/README
@@ -0,0 +1,53 @@
+HOL Proof General, for HOL98.
+
+Written by David Aspinall.
+
+Status: not officially supported yet
+Maintainer: volunteer required
+HOL version: HOL98, tested with Taupo 2
+HOL homepage: http://www.cl.cam.ac.uk/Research/HVG/HOL/HOL.html
+
+========================================
+
+
+This is a "technology demonstration" of Proof General for HOL 98.
+
+It may work with other versions of HOL, but is untested (please let me
+know if you try). Probably just a few settings need changing
+to configure for different output formats.
+
+It has basic script management support, with a little bit of
+decoration of scripts and output.
+
+There is support for X Symbol, but not using a proper token language.
+
+I have written this in the hope that somebody from the HOL community
+will adopt it, maintain and improve it, and thus turn it into a proper
+instantiation of Proof General.
+
+
+------------
+
+Notes:
+
+There are some problems at the moment. HOL proof scripts often use
+batch-oriented single step tactic proofs, but Proof General does not
+offer an easy way to edit these kind of proofs. The "Boomburg-HOL"
+Emacs interface by Koichi Takahashi and Masima Hagiya addressed this,
+and to some extent so perhaps does the Emacs interface supplied with
+HOL. Perhaps one of these could be embedded/reimplemented inside
+Proof General. Implemented in a generic way, managing batch vs
+interactive proofs would also be useful for Isabelle.
+
+Another problem is that HOL scripts sometimes use SML structures,
+which can cause confusion because Proof General does not really parse
+SML, it just looks for semicolons. This could be improved by taking a
+better parser (e.g. from sml mode).
+
+These improvements would be worthwhile contributions to Proof General
+and also provide the HOL community with a nice front end.
+Please have a go!
+
+
+$Id$
+
diff --git a/hol98/example.sml b/hol98/example.sml
new file mode 100644
index 00000000..7e008eb8
--- /dev/null
+++ b/hol98/example.sml
@@ -0,0 +1,30 @@
+(*
+ Example proof script for HOL Proof General.
+
+ $Id$
+*)
+
+g `A /\ B ==> B /\ A`;
+e DISCH_TAC;
+e CONJ_TAC;
+e (IMP_RES_TAC AND_INTRO_THM);
+e (IMP_RES_TAC AND_INTRO_THM);
+val and_comms = pg_top_thm_and_drop();
+
+(* Hints about HOL Proof General:
+
+ Proof General needs to work with top-level declarations throughout,
+ and with "interactive" rather than "batch" versions of proofs.
+
+ For best results, theorems should be saved in the way that they are
+ saved above, with pg_top_thm_and_drop. The function isn't
+ mysterious, it is defined as:
+
+ fun pg_top_thm_and_drop () = let val t = top_thm(); in (drop(); t) end;
+*)
+
+(* this simple proof is not quite like proofs in the other systems,
+ can anyone tell me a more similar proof in HOL? I want to split
+ the IMP_RES_TAC into two steps.
+*)
+
diff --git a/hol98/hol98.el b/hol98/hol98.el
new file mode 100644
index 00000000..937cbb87
--- /dev/null
+++ b/hol98/hol98.el
@@ -0,0 +1,158 @@
+;; hol98.el Basic Proof General instance for HOL 98
+;;
+;; Copyright (C) 2000 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; Needs improvement!
+;;
+;; See the README file in this directory for information.
+
+
+(require 'proof-easy-config) ; easy configure mechanism
+(require 'proof-syntax) ; functions for making regexps
+
+(proof-easy-config 'hol98 "HOL"
+ proof-prog-name "hol.unquote"
+ proof-terminal-char ?\;
+ proof-comment-start "(*"
+ proof-comment-end "*)"
+ ;; These are all approximations, of course.
+ proof-goal-command-regexp "^g[ `]"
+ proof-save-command-regexp "pg_top_thm_and_drop"
+ proof-goal-with-hole-regexp "val \\(\\([^ \t=]*\\)\\)[ \t]*=[ \t]*prove"
+ proof-save-with-hole-regexp "val \\(\\([^ \t=]*\\)\\)[ \t]*=[ \t]*top_thm()"
+ proof-non-undoables-regexp "b()" ; and others..
+ proof-goal-command "g `%s`;"
+ proof-save-command "val %s = pg_top_thm_and_drop();"
+ proof-kill-goal-command "drop();"
+ proof-showproof-command "p()"
+ proof-undo-n-times-cmd "(pg_repeat backup %s; p());"
+ proof-auto-multiple-files t
+ proof-shell-cd-cmd "FileSys.chDir \"%s\""
+ proof-shell-filename-escapes '(("\\\\" . "\\\\") ("\"" . "\\\""))
+ proof-shell-prompt-pattern "^[->] "
+ proof-shell-interrupt-regexp "Interrupted"
+ proof-shell-start-goals-regexp
+ (proof-regexp-alt "Proof manager status"
+ "OK.."
+ "val it =\n")
+ proof-shell-end-goals-regexp
+ (proof-regexp-alt "^[ \t]*: GoalstackPure.goalstack"
+ "^[ \t]*: GoalstackPure.proofs")
+ proof-shell-quit-cmd "quit();"
+ proof-assistant-home-page
+ "http://www.cl.cam.ac.uk/Research/HVG/HOL/HOL.html"
+ proof-shell-annotated-prompt-regexp
+ "^- "
+ ;; This one is nice but less reliable, I think.
+ ;; "\\(> val it = () : unit\n\\)?- "
+ proof-shell-error-regexp "^! "
+ proof-shell-init-cmd
+ "Help.displayLines:=3000;
+ fun pg_repeat f 0 = () | pg_repeat f n = (f(); pg_repeat f (n-1));
+ fun pg_top_thm_and_drop () = let val t = top_thm(); in (drop(); t) end;"
+ ;; FIXME: add optional help topic parameter to help command.
+ ;; Have patch ready for PG 3.2, but PG 3.1 is strictly bug fix.
+ proof-info-command "help \"hol\""
+ proof-shell-proof-completed-regexp "Initial goal proved"
+ ;; FIXME: next one needs setting so that "urgent" messages are displayed
+ ;; eagerly from HOL.
+ ;; proof-shell-eager-annotation-start
+ proof-find-theorems-command "DB.match [] (%s);"
+
+ ;; We must force this to use ptys since mosml doesn't flush its output
+ ;; (on Linux, presumably on Solaris too).
+ proof-shell-process-connection-type t
+
+ ;;
+ ;; Syntax table entries for proof scripts
+ ;;
+ proof-script-syntax-table-entries
+ '(?\` "\""
+ ?\$ "."
+ ?\/ "."
+ ?\\ "."
+ ?+ "."
+ ?- "."
+ ?= "."
+ ?% "."
+ ?< "."
+ ?> "."
+ ?\& "."
+ ?. "w"
+ ?_ "w"
+ ?\' "w"
+ ?\| "."
+ ?\* ". 23"
+ ?\( "()1"
+ ?\) ")(4")
+
+ ;;
+ ;; A few of the vast variety of keywords, tactics, tacticals,
+ ;; for decorating proof scripts.
+ ;;
+ ;; In the future, PG will use a mechanism for passing identifier
+ ;; lists like this from the proof assistant, we don't really
+ ;; want to duplicate the information here!
+ ;;
+ hol98-keywords '("g" "expand" "e" "val" "store_thm" "top_thm" "by"
+ "pg_top_thm_and_drop"
+ "Define" "xDefine" "Hol_defn"
+ "Induct" "Cases" "Cases_on" "Induct_on"
+ "std_ss" "arith_ss" "list_ss"
+ "define_type")
+ hol98-rules '("ASSUME" "REFL" "BETA_CONV" "SUBST"
+ "ABS" "INST_TYPE" "DISCH" "MP"
+ "T_DEF" "FORALL_DEF" "AND_DEF" "OR_DEF" "F_DEF"
+ "NOT_DEF" "EXISTS_UNIQUE_DEF" "BOOL_CASES_AX"
+ "IMP_ANTISYM_AX" "ETA_AX" "SELECT_AX" "ONE_ONE_DEF"
+ "ONTO_DEF" "INFINITY_AX" "LET_DEF" "COND_DEF" "ARB_DEF")
+ hol98-tactics '("ACCEPT_TAC" "ASSUME_TAC" "GEN_TAC"
+ "CONJ_TAC" "DISCH_TAC" "STRIP_TAC"
+ "SUBST_TAC" "ASM_CASES_TAC" "DISJ_CASES_TAC"
+ "REWRITE_TAC" "IMP_RES_TAC" "ALL_TAC" "NO_TAC"
+ "EQ_TAC" "EXISTS_TAC" "INDUCT_TAC"
+ "POP_ASM" "SUBST1_TAC" "ASSUM_LIST"
+ "PROVE" "PROVE_TAC" "DECIDE" "DECIDE_TAC" "RW_TAC"
+ "STP_TAC" "ZAP_TAC"
+ "EXISTS_TAC")
+ hol98-tacticals '("ORELSE" "FIRST" "CHANGED_TAC" "THEN"
+ "THENL" "EVERY" "REPEAT"
+ "MAP_EVERY")
+ proof-script-font-lock-keywords
+ (list
+ (cons (proof-ids-to-regexp hol98-keywords) 'font-lock-keyword-face)
+ (cons (proof-ids-to-regexp hol98-tactics) 'font-lock-keyword-face)
+ ; (cons (proof-ids-to-regexp hol98-rules) 'font-lock-keyword-face)
+ (cons (proof-ids-to-regexp hol98-tacticals) 'proof-tacticals-name-face))
+
+ ;;
+ ;; Some decoration of the goals output
+ ;;
+ proof-goals-font-lock-keywords
+ (list
+ (cons (proof-ids-to-regexp '("Proof manager status"
+ "proof" "Incomplete"
+ "Initial goal proved"
+ "Initial goal"
+ "There are currently no proofs"
+ "OK"))
+ 'font-lock-keyword-face)
+ (cons (regexp-quote "------------------------------------")
+ 'font-lock-comment-face)
+ (cons ": GoalstackPure.goalstack" 'proof-boring-face)
+ (cons ": GoalstackPure.proofs" 'proof-boring-face)
+ (cons ": Thm.thm" 'proof-boring-face)
+ (cons "val it =" 'proof-boring-face))
+
+ ;; End of easy config.
+ )
+
+
+(warn "Hol Proof General is incomplete! Please help improve it!
+Read the manual, make improvements and send them to proofgen@dcs.ed.ac.uk")
+
+(provide 'hol98) \ No newline at end of file
diff --git a/hol98/todo b/hol98/todo
new file mode 100644
index 00000000..d65df204
--- /dev/null
+++ b/hol98/todo
@@ -0,0 +1,25 @@
+-*- mode:outline -*-
+
+* Things to do for HOL
+
+See also ../todo for generic things to do, priority codes.
+
+** A Problem with process filtering.
+
+ Process (sometimes?) doesn't recover after interrupt, and no output
+ is seen. Why?
+
+ Also problem with some input texts: try interactive version of
+ clScript.sml, inductive defn of CL terms breaks things.
+
+** B Improve display to strip ugly val it and spurious >'s.
+
+** B Add special markup to improve robustness
+
+** B Add support for multiple files
+
+** B Add support for proof by pointing.
+
+** B Output highlighting doesn't seem to work properly.
+
+
diff --git a/hol98/x-symbol-hol98.el b/hol98/x-symbol-hol98.el
new file mode 100644
index 00000000..920af03d
--- /dev/null
+++ b/hol98/x-symbol-hol98.el
@@ -0,0 +1,85 @@
+;; x-symbol-hol98.el
+;;
+;; David Aspinall, adapted from file supplied by David von Obheimb
+;;
+;; $Id$
+;;
+
+(defvar x-symbol-hol98-symbol-table
+ '((longarrowright () "->" "\\<longrightarrow>")
+ (longarrowdblright () "==>" "\\<Longrightarrow>")
+ (logicaland () "/\\" "\\<and>")
+ (logicalor () "\\/" "\\<or>")
+ (equivalence () "<->" "\\<equiv>")
+ (existential1 () "EX" "\\<exists>")
+ (universal1 () "ALL" "\\<forall>")
+ ;; some naughty ones, but probably what you'd like
+ ;; (a mess in words like "searching" "philosophy" etc!!)
+ (Gamma () "Gamma" "\\<Gamma>")
+ (Delta () "Delta" "\\<Delta>")
+ (Theta () "Theta" "\\<Theta>")
+ (Lambda () "Lambda" "\\<Lambda>")
+ (Pi () "Pi" "\\<Pi>")
+ (Sigma () "Sigma" "\\<Sigma>")
+ (Phi () "Phi" "\\<Phi>")
+ (Psi () "Psi" "\\<Psi>")
+ (Omega () "Omega" "\\<Omega>")
+ (alpha () "alpha" "\\<alpha>")
+ (beta () "beta" "\\<beta>")
+ (gamma () "gamma" "\\<gamma>")
+ (delta () "delta" "\\<delta>")
+ (epsilon1 () "epsilon" "\\<epsilon>")
+ (zeta () "zeta" "\\<zeta>")
+ (eta () "eta" "\\<eta>")
+ (theta1 () "theta" "\\<theta>")
+ (kappa1 () "kappa" "\\<kappa>")
+ (lambda () "lambda" "\\<lambda>")
+; (mu () "mu" "\\<mu>")
+; (nu () "nu" "\\<nu>")
+; (xi () "xi" "\\<xi>")
+; (pi () "pi" "\\<pi>")
+ (rho () "rho" "\\<rho>")
+ (sigma () "sigma" "\\<sigma>")
+ (tau () "tau" "\\<tau>")
+ (phi1 () "phi" "\\<phi>")
+; (chi () "chi" "\\<chi>")
+ (psi () "psi" "\\<psi>")
+ (omega () "omega" "\\<omega>")))
+
+;; All the stuff X-Symbol complains about
+(defvar x-symbol-hol98-master-directory 'ignore)
+(defvar x-symbol-hol98-image-searchpath '("./"))
+(defvar x-symbol-hol98-image-cached-dirs '("images/" "pictures/"))
+(defvar x-symbol-hol98-image-keywords nil)
+(defvar x-symbol-hol98-font-lock-keywords nil)
+(defvar x-symbol-hol98-header-groups-alist nil)
+(defvar x-symbol-hol98-class-alist
+ '((VALID "Hol98 Symbol" (x-symbol-info-face))
+ (INVALID "no Hol98 Symbol" (red x-symbol-info-face))))
+(defvar x-symbol-hol98-class-face-alist nil)
+(defvar x-symbol-hol98-electric-ignore nil)
+(defvar x-symbol-hol98-required-fonts nil)
+(defvar x-symbol-hol98-case-insensitive nil)
+;; Setting token shape prevents "philosophy" example, but still
+;; problems, e.g. delphi, false1. (Pierre)
+(defvar x-symbol-hol98-token-shape '(?_ "[A-Za-z]+" . "[A-Za-z_]"))
+(defvar x-symbol-hol98-table x-symbol-hol98-symbol-table)
+(defun x-symbol-hol98-default-token-list (tokens) tokens)
+(defvar x-symbol-hol98-token-list 'x-symbol-hol98-default-token-list)
+(defvar x-symbol-hol98-input-token-ignore nil)
+
+;; internal stuff
+(defvar x-symbol-hol98-exec-specs nil)
+(defvar x-symbol-hol98-menu-alist nil)
+(defvar x-symbol-hol98-grid-alist nil)
+(defvar x-symbol-hol98-decode-atree nil)
+(defvar x-symbol-hol98-decode-alist nil)
+(defvar x-symbol-hol98-encode-alist nil)
+(defvar x-symbol-hol98-nomule-decode-exec nil)
+(defvar x-symbol-hol98-nomule-encode-exec nil)
+
+(warn "Hol98 support for X-Symbol is highly incomplete! Please help improve it!
+Send improvements to x-symbol-hol98.el to proofgen@dcs.ed.ac.uk")
+
+
+(provide 'x-symbol-hol98)
diff --git a/html/.cvsignore b/html/.cvsignore
new file mode 100644
index 00000000..d6e10bc1
--- /dev/null
+++ b/html/.cvsignore
@@ -0,0 +1 @@
+ProofGeneral
diff --git a/html/.htaccess b/html/.htaccess
new file mode 100644
index 00000000..45e6575e
--- /dev/null
+++ b/html/.htaccess
@@ -0,0 +1,2 @@
+RemoveHandler .html
+AddType application/x-httpd-php .html
diff --git a/html/Kit/Makefile b/html/Kit/Makefile
new file mode 100644
index 00000000..b35b720b
--- /dev/null
+++ b/html/Kit/Makefile
@@ -0,0 +1,11 @@
+#
+# Update dtds from PG Kit repository.
+#
+
+.PHONY: dtdupdate
+
+DTDTARGS=dtd/pgip.dtd dtd/pgml.dtd
+
+# checkout in temp dir because otherwise CVS complains of repo clash (fixes?)
+dtdupdate:
+ mkdir dtdtmp; cvs -d :ext:da@localssh.dcs.ed.ac.uk:/home/proofgen/src export -kv -D today -d dtdtmp Kit/dtd; mv dtdtmp/* dtd; rmdir dtdtmp; cvs commit -m"Updated from Kit repo" dtd
diff --git a/html/Kit/dtd/pgip.dtd b/html/Kit/dtd/pgip.dtd
new file mode 100644
index 00000000..2861fff2
--- /dev/null
+++ b/html/Kit/dtd/pgip.dtd
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- DTD for PGIP, the Proof General Interface Protocol -->
+<!-- Author: David Aspinall, LFCS, University of Edinburgh -->
+<!-- Version: pgip.dtd,v 1.6 2001/09/10 19:00:42 da Exp -->
+
+<!-- Status: Incomplete. -->
+<!-- For commentary, see the Proof General Kit white paper, -->
+<!-- available from http://www.proofgeneral.org/kit -->
+
+
+<!ELEMENT pgip (%provermsg; | %kitmsg;)*>
+<!ATTLIST pgip
+ version CDATA
+ class CDATA #IMPLIED
+ origin CDATA
+ id CDATA>
+
+
+<!-- STATUS/ERROR MESSAGES -->
+<!-- ===================== -->
+
+<!ELEMENT information (#PCDATA)>
+<!ATTLIST information
+ kind CDATA #IMPLIED
+ location CDATA #IMPLIED>
+
+<!-- kind=message,urgentmessage,display -->
+
+<!ELEMENT error (#PCDATA)>
+<!ATTLIST error
+ kind CDATA #IMPLIED
+ location CDATA #IMPLIED>
+
+<!-- kind=warning,fatal,interrupt -->
+
+<!ENTITY % proverstatus "information | error">
+
+
+
+<!-- CONFIGURATION MESSAGES -->
+<!-- ====================== -->
+
+<!ENTITY % kitconfig "usespgml | haspref | prefval | idtable |
+ addid | delid | menuadd | menudel | guiconfig">
+
+<!-- This is how it should be:
+ <!ENTITY % pgml SYSTEM "pgml.dtd">
+ -->
+
+<!-- Types for config settings -->
+
+<!ELEMENT pgipbool EMPTY>
+<!ELEMENT pgipint (#PCDATA)>
+<!ELEMENT pgipstring (#PCDATA)>
+<!ELEMENT pgipchoice (pgipchoiceitem+)>
+<!ELEMENT pgipchoiceitem (#PCDATA)>
+<!ATTLIST pgipchoiceitem
+ tag CDATA #IMPLIED>
+
+<!ENTITY % pgiptype "pgipbool | pgipint | pgipstring | pgipchoice">
+
+
+<!ELEMENT usespgml EMPTY>
+<!ATTLIST usespgml
+ version CDATA #IMPLIED>
+
+<!ELEMENT haspref pgiptype>
+<!ATTLIST haspref
+ default CDATA #IMPLIED
+ class CDATA #IMPLIED>
+
+<!ELEMENT prefval (#PCDATA)>
+<!ATTLIST prefval
+ name CDATA #IMPLIED>
+
+<!ELEMENT idtable (#PCDATA)>
+<!ATTLIST idtable
+ class CDATA #IMPLIED>
+
+<!ELEMENT addid (#PCDATA)>
+<!ATTLIST addid
+ class CDATA #IMPLIED>
+
+<!ELEMENT delid (#PCDATA)>
+<!ATTLIST delid
+ class CDATA #IMPLIED>
+
+<!ELEMENT menuadd (#PCDATA)>
+<!ATTLIST menuadd
+ path CDATA #IMPLIED
+ name CDATA #IMPLIED>
+
+<!ELEMENT menudel (#PCDATA)>
+<!ATTLIST menudel
+ path CDATA #IMPLIED
+ name CDATA #IMPLIED>
+
+
+<!-- gui configuration -->
+
+<!-- the PCDATA is the icon, base64-encoded -->
+<!ELEMENT objtype (#PCDATA)>
+<!ATTLIST objtype
+ name CDATA #REQUIRED>
+
+<!ELEMENT opn (opsrc, optrg, opcmd)>
+<!ATTLIST opn
+ name CDATA #REQUIRED>
+
+<!-- source types as space-separated list; target type is a single type -->
+<!ELEMENT opsrc (#PCDATA)>
+<!ELEMENT optrg (#PCDATA)>
+<!-- the prover command, with a printf "%1"-style substitution of arguments -->
+<!ELEMENT opcmd (#PCDATA)>
+
+<!-- proof operations (no target sort) -->
+<!ELEMENT proofopn (opsrc, opcmd)>
+<!ATTLIST opn
+ name CDATA #REQUIRED>
+
+<!-- interactive operations-- require some input -->
+<!ELEMENT iopn (inputform, opsrc, optrg, opcmd)>
+<!ATTLIST iopn
+ name CDATA #REQUIRED>
+
+<!-- an input form is a list of fields -->
+<!ELEMENT inputform (field)+>
+<!-- and a field has a type (int, string, bool, choice(c1...cn)) -->
+<!-- and a name; under that name, it will be substituted into the command -->
+<!-- Ex. field name=number opcmd="rtac %1 %number" -->
+<!-- the PCDATA is the prompt for the input field -->
+<!ELEMENT field (pgiptype)>
+<!ATTLIST field
+ type CDATA #REQUIRED
+ name CDATA #REQUIRED>
+
+
+<!ELEMENT guiconfig (objtype*, opn*, iopn*, proofopn*) >
+
+
+
+<!ENTITY % proverconfig "askpgml | askprefs | resetprefs |
+ setpref | getpref">
+
+<!ELEMENT askpgml EMPTY>
+
+<!ELEMENT askprefs EMPTY>
+<!ATTLIST askprefs
+ class CDATA #IMPLIED>
+
+<!ELEMENT resetprefs EMPTY>
+<!ATTLIST resetprefs
+ class CDATA #IMPLIED>
+
+<!ELEMENT setpref EMPTY>
+<!ATTLIST setpref
+ class CDATA #IMPLIED>
+
+<!ELEMENT getpref EMPTY>
+<!ATTLIST getpref
+ class CDATA #IMPLIED>
+
+
+
+<!-- COMMANDS -->
+<!-- ======== -->
+
+<!ELEMENT provercmd (#PCDATA)>
+
+<!ELEMENT goalcmd (#PCDATA)>
+
+<!ELEMENT undocmd EMPTY>
+
+<!ELEMENT abortcmd EMPTY>
+
+<!ELEMENT closecmd (#PCDATA)
+ goalid CDATA #REQUIRED>
+
+<!ELEMENT postponecmd (#PCDATA)
+ goalid CDATA #REQUIRED
+ thmname CDATA #REQUIRED>
+
+<!ELEMENT savecmd EMPTY>
+<!ATTLIST savecmd
+ thmname CDATA #REQUIRED>
+
+<!ELEMENT forgetcmd EMPTY>
+<!ATTLIST forgetcmd
+ thmname CDATA #REQUIRED>
+
+<!ELEMENT restorecmd EMPTY>
+<!ATTLIST restorecmd
+ goalid CDATA #REQUIRED>
+
+<!ELEMENT loadfilecmd (#PCDATA)>
+
+<!ELEMENT retractfilecmd (#PCDATA)>
+
+<!ENTITY % command "provercmd | goalcmd | undocmd | savecmd | forgetcmd |
+ closecmd | quitcmd | postponecmd | restorecmd |
+ loadfilecmd | retractfilecmd">
+
+<!-- savecmd Finishes a proof and saves a new theorem
+ closecmd Temporarily closes a proof and saves state with given id
+ postponecmd As closecmd, but saves a new theorem and
+ generates a proof obligation
+ -->
+
+
+
+
+<!-- Roots of PGIP messages -->
+
+<!-- Messages sent to PG Kit components -->
+
+<!ENTITY % kitmsg "%kitconfig | %proverstatus">
+
+<!-- Messages sent to proof assistant (class "pa") -->
+
+<!ENTITY % provermsg "proverconfig">
+
+
+
+
+<!ELEMENT br EMPTY>
diff --git a/html/Kit/dtd/pgml.dtd b/html/Kit/dtd/pgml.dtd
new file mode 100644
index 00000000..d484c100
--- /dev/null
+++ b/html/Kit/dtd/pgml.dtd
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- DTD for PGML, the Proof General Markup Language -->
+<!-- Author: David Aspinall, LFCS, University of Edinburgh -->
+<!-- Version: pgml.dtd,v 1.6 2001/09/10 16:04:17 da Exp -->
+
+<!-- Status: Complete but experimental version. -->
+<!-- For commentary, see the Proof General Kit white paper, -->
+<!-- available from http://www.proofgeneral.org/kit -->
+
+
+<!ELEMENT pgml (statedisplay | termdisplay | information | warning | error)*>
+<!ATTLIST pgml
+ version CDATA #IMPLIED>
+
+<!ELEMENT statedisplay (statepart)*>
+<!ATTLIST statedisplay
+ systemid CDATA #IMPLIED
+ name CDATA #IMPLIED
+ kind CDATA #IMPLIED>
+
+<!ENTITY % termitem "action | term | type | atom | sym">
+<!ENTITY % nonactionitem "term | type | atom | sym">
+
+<!ELEMENT information (#PCDATA | %termitem;)*>
+<!ATTLIST information
+ name CDATA #IMPLIED
+ kind CDATA #IMPLIED>
+
+<!ELEMENT warning (#PCDATA | %termitem;)*>
+<!ATTLIST warning
+ name CDATA #IMPLIED
+ kind CDATA #IMPLIED>
+
+<!ELEMENT error (#PCDATA | %termitem;)*>
+<!ATTLIST error
+ name CDATA #IMPLIED
+ kind CDATA #IMPLIED>
+
+<!ELEMENT statepart (#PCDATA | %termitem;)*>
+<!ATTLIST statepart
+ name CDATA #IMPLIED
+ kind CDATA #IMPLIED>
+
+<!ELEMENT termdisplay (#PCDATA | %termitem;)*>
+<!ATTLIST termdisplay
+ name CDATA #IMPLIED
+ kind CDATA #IMPLIED>
+
+<!ELEMENT term (#PCDATA | %termitem;)*>
+<!ATTLIST term
+ pos CDATA #IMPLIED
+ kind CDATA #IMPLIED>
+
+<!-- maybe combine this with term and add extra attr to term? -->
+<!ELEMENT type (#PCDATA | %termitem;)*>
+<!ATTLIST type
+ kind CDATA #IMPLIED>
+
+<!ELEMENT action (#PCDATA | %nonactionitem;)*>
+<!ATTLIST action
+ kind CDATA #IMPLIED>
+
+<!ELEMENT atom (#PCDATA)>
+<!ATTLIST atom
+ kind CDATA #IMPLIED
+ fullname CDATA #IMPLIED>
+
+<!ELEMENT sym (#PCDATA)>
+<!ATTLIST sym
+ name CDATA #IMPLIED
+ alt CDATA #IMPLIED>
+
+<!ELEMENT br EMPTY>
+
diff --git a/html/ProofGeneralPortrait.eps.gz b/html/ProofGeneralPortrait.eps.gz
new file mode 100644
index 00000000..97feb1a4
--- /dev/null
+++ b/html/ProofGeneralPortrait.eps.gz
Binary files differ
diff --git a/html/about b/html/about
new file mode 100644
index 00000000..a58717d8
--- /dev/null
+++ b/html/about
@@ -0,0 +1,5 @@
+<?php include('index.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?> \ No newline at end of file
diff --git a/html/about.html b/html/about.html
new file mode 100644
index 00000000..d5be7bc7
--- /dev/null
+++ b/html/about.html
@@ -0,0 +1,56 @@
+<h2>About the Proof General project</h2>
+<p>
+The forefather of Proof General was LEGO mode, begun in 1994 at the <a
+href="http://www.lfcs.informatics.ed.ac.uk">LFCS</a> by Thomas Kleymann. LEGO
+mode was an Emacs-based front end for LEGO similar to David Aspinall's
+<a href="http://www.proofgeneral.org/~isamode">Isamode</a>,
+developed at the LFCS since 1992. After 1994, implementations of
+proof-by-pointing and script management were added to LEGO mode, and
+the code was made generic. The generic basis was developed by
+Thomas Kleymann, Dilip Sequeira, Healfdene Goguen and David Aspinall.
+The current authors and maintainers of the various instantiations of
+Proof General are mentioned on the
+<a href="main">front page</a>.
+</p>
+<p>
+The Proof General project was coordinated until October 1998 by
+Thomas Kleymann, and since then by David Aspinall. The project has
+benefited from funding by
+<!-- this link is broken: <a href="http://www.dcs.ed.ac.uk/lfcs/research/logic_and_proof/attbpa.html"> -->
+EPSRC,
+<!-- (Applications of a Type Theory based Proof Assistant) -->
+<!-- </a>, -->
+the <a
+href="http://www.dcs.ed.ac.uk/lfcs/research/types_bra/index.html">EC</a>,
+and the <a href="http://www.lfcs.informatics.ed.ac.uk">LFCS</a>.
+</p>
+
+<p>
+David Aspinall designed the web pages and graphics for Proof General.
+<br>
+Check the <a href="gallery">gallery</a> for more publicity
+pictures!
+</p>
+<p>
+For more on the history of the development of
+the Proof General program, see the
+<?php htmlshow("ProofGeneral/doc/ProofGeneral_1.html#SEC3","manual preface.","","html") ?>
+</p>
+
+
+<h2>Contact information</h2>
+
+<p>
+Have you any questions, comments, or suggestions about Proof General?
+<br>
+Send us a message using <a href="feedback">this form</a>.
+</p>
+
+<p>
+Discuss Proof General with other users and receive
+announcements by joining our <a href="mailinglist">mailing
+list</a>.
+</p>
+
+
+
diff --git a/html/counter.php3 b/html/counter.php3
new file mode 100644
index 00000000..0ea4593d
--- /dev/null
+++ b/html/counter.php3
@@ -0,0 +1,50 @@
+<?php
+/*
+ * Increment an access counter.
+ * David Aspinall, June 1999.
+ *
+ * $Id$
+ *
+ */
+
+$counterFile = "counter.txt";
+$counterStart = "counterstart.txt";
+$maxlen = 10;
+
+// NB: probably have trouble with permissions
+// if file doesn't exist already, so start with
+// empty files made with touch.
+
+// Here's how to cause it to be initialized:
+//
+// rm -f counter.txt counterstart.txt
+// touch counter.txt counterstart.txt
+// chmod o+w counter.txt counterstart.txt
+//
+
+if (is_readable($counterFile) && is_writeable($counterFile)) {
+ $fp = fopen($counterFile,"r+");
+ if (filesize($counterFile)<1) {
+ // Start counter, write a timestamp.
+ $num = 1;
+ if (is_readable($counterStart) && is_writeable($counterStart)) {
+ $fps = fopen($counterStart,"w");
+ fputs($fps,time());
+ fclose($fps);
+ print "<!-- Hit counter initialized. -->";
+ } else {
+ print "<!-- Hit counter initialized, but timestamp could not be set -->";
+ };
+ } else {
+ $num = fgets($fp,$maxlen);
+ $num += 1;
+ print "<!-- Hit counter: $num -->";
+ };
+ rewind($fp);
+ fputs($fp,$num);
+ fclose($fp);
+} else {
+ print "<!-- Hit counter file $counterFile cannot be accessed. -->";
+};
+?>
+
diff --git a/html/cvsweb.cgi b/html/cvsweb.cgi
new file mode 100644
index 00000000..9aee4f44
--- /dev/null
+++ b/html/cvsweb.cgi
@@ -0,0 +1,2685 @@
+#!/usr/bin/perl -ws
+#
+# cvsweb - a CGI interface to CVS trees.
+#
+# Written in their spare time by
+# Bill Fenner <fenner@freebsd.org> (original work)
+# extended by Henner Zeller <zeller@think.de>,
+# Henrik Nordström <hno@hem.passagen.se>
+# Ken Coar <coar@Apache.Org>
+#
+# Adjustments for Proof General pages by David Aspinall <da@dcs.ed.ac.uk>
+# -- added hr, bighr, widehr, stylesheet. July 2000
+#
+# Based on:
+# * Bill Fenners cvsweb.cgi revision 1.28 available from:
+# http://www.freebsd.org/cgi/cvsweb.cgi/www/en/cgi/cvsweb.cgi
+#
+# Copyright (c) 1996-1998 Bill Fenner
+# (c) 1998-1999 Henner Zeller
+# (c) 1999 Henrik Nordström
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# Original version tag
+# Id: cvsweb.cgi,v 1.79 1999/11/03 08:05:29 hzeller Exp
+#
+# Proof General version tag
+# $Id$
+#
+#
+###
+
+use strict;
+
+use vars qw (
+ $config $allow_version_select $verbose
+ %CVSROOT %CVSROOTdescr %MIRRORS %DEFAULTVALUE %ICONS %MTYPES
+ %alltags @tabcolors %fileinfo %tags @branchnames %nameprinted
+ %symrev %revsym @allrevisions %date %author @revdisplayorder
+ @revisions %state %difflines %log %branchpoint @revorder $prcgi
+ $checkoutMagic $doCheckout $scriptname $scriptwhere
+ $where $Browser $nofilelinks $maycompress @stickyvars
+ %input $query $barequery $sortby $bydate $byrev $byauthor
+ $bylog $byfile $hr_default $logsort $cvstree $cvsroot
+ $mimetype $defaultTextPlain $defaultViewable $allow_compress
+ $GZIPBIN $backicon $diricon $fileicon $fullname $newname
+ $cvstreedefault $body_tag $logo $defaulttitle $footer
+ $backcolor $long_intro $short_instruction $shortLogLen
+ $show_author $dirtable $tablepadding $columnHeaderColorDefault
+ $columnHeaderColorSorted $hr_breakable $hr_funout $hr_ignwhite
+ $hr_ignkeysubst $diffcolorHeading $diffcolorEmpty $diffcolorRemove
+ $diffcolorChange $diffcolorAdd $diffcolorDarkChange $difffontface
+ $difffontsize $inputTextSize $mime_types $allow_annotate
+ $allow_markup $use_java_script $open_extern_window
+ $extern_window_width $extern_window_height $edit_option_form
+ $checkout_magic $show_subdir_lastmod $show_log_in_markup $v
+ $navigationHeaderColor $tableBorderColor $markupLogColor
+ $tabstop $state $annTable $sel $curbranch $HideModules @HideModules
+ $module $moddate $stylesheet $hr $widehr $bighr
+);
+
+##### Start of Configuration Area ########
+# == EDIT this ==
+# User configuration is stored in
+# $config = $ENV{'CVSWEB_CONFIG'} || '/etc/httpd/conf/cvsweb.conf';
+$config = "/home/proofgen/www/cvsweb.conf";
+
+# == Configuration defaults ==
+# Defaults for configuration variables that shouldn't need
+# to be configured..
+$allow_version_select = 1;
+
+##### End of Configuration Area ########
+
+######## Configuration variables #########
+# These are defined to allow checking with perl -cw
+%CVSROOT = %MIRRORS = %DEFAULTVALUE = %ICONS = %MTYPES =
+%tags = %alltags = @tabcolors = ();
+$cvstreedefault = $body_tag = $logo = $defaulttitle = $footer =
+$backcolor = $long_intro = $short_instruction = $shortLogLen =
+$show_author = $dirtable = $tablepadding = $columnHeaderColorDefault =
+$columnHeaderColorSorted = $hr_breakable = $hr_funout = $hr_ignwhite =
+$hr_ignkeysubst = $diffcolorHeading = $diffcolorEmpty = $diffcolorRemove =
+$diffcolorChange = $diffcolorAdd = $diffcolorDarkChange = $difffontface =
+$difffontsize = $inputTextSize = $mime_types = $allow_annotate =
+$allow_markup = $use_java_script = $open_extern_window =
+$extern_window_width = $extern_window_height = $edit_option_form =
+$checkout_magic = $show_subdir_lastmod = $show_log_in_markup = $v =
+$navigationHeaderColor = $tableBorderColor = $markupLogColor =
+$tabstop = $moddate = $stylesheet = undef;
+
+##### End of configuration variables #####
+
+use Time::Local;
+use IPC::Open2;
+
+$verbose = $v;
+$checkoutMagic = "~checkout~";
+$where = defined($ENV{'PATH_INFO'}) ? $ENV{'PATH_INFO'} : "";
+$doCheckout = ($where =~ /^\/$checkoutMagic/);
+$where =~ s|^/($checkoutMagic)?||;
+$where =~ s|/+$||;
+($scriptname = $ENV{'SCRIPT_NAME'}) =~ s|^/?|/|;
+$scriptname =~ s|/+$||;
+if ($where) {
+ $scriptwhere = $scriptname . '/' . urlencode($where);
+}
+else {
+ $scriptwhere = $scriptname;
+}
+$scriptwhere =~ s|/+$||;
+
+# in lynx, it it very annoying to have two links
+# per file, so disable the link at the icon
+# in this case:
+$Browser = defined($ENV{'HTTP_USER_AGENT'}) ? $ENV{'HTTP_USER_AGENT'} : "unknown";
+$nofilelinks = ($Browser =~ m'^Lynx/');
+
+# newer browsers accept gzip content encoding
+# and state this in a header
+# (netscape did always but didn't state it)
+# It has been reported that these
+# braindamaged MS-Internet Exploders claim that they
+# accept gzip .. but don't in fact and
+# display garbage then :-/
+# Turn off gzip if running under mod_perl. piping does
+# not work as expected inside the server. One can probably
+# achieve the same result using Apache::GZIPFilter.
+$maycompress =(( (defined($ENV{'HTTP_ACCEPT_ENCODING'}) ? $ENV{'HTTP_ACCEPT_ENCODING'} =~ m|gzip| : 0 )
+ || $Browser =~ m%^Mozilla/3%)
+ && ($Browser !~ m/MSIE/)
+ && !defined($ENV{'MOD_PERL'}));
+
+# put here the variables we need in order
+# to hold our state - they will be added (with
+# their current value) to any link/query string
+# you construct
+@stickyvars = ('cvsroot','hideattic','sortby','logsort','f','only_with_tag');
+
+if (-f $config) {
+ do "$config";
+ $HideModules = "§" . join("§", @HideModules) . "§";
+}
+else {
+ &fatal("500 Internal Error",
+ 'Configuration not found. Set the variable <code>$config</code> '
+ . 'in cvsweb.cgi, or the environment variable '
+ . '<code>CVSWEB_CONFIG</code>, to your <b>cvsweb.conf</b> '
+ . 'configuration file first.');
+}
+
+undef %input;
+if ($query = $ENV{'QUERY_STRING'}) {
+ foreach (split(/&/, $query)) {
+ s/%(..)/sprintf("%c", hex($1))/ge; # unquote %-quoted
+ if (/(\S+)=(.*)/) {
+ $input{$1} = $2 if ($2 ne "");
+ }
+ else {
+ $input{$_}++;
+ }
+ }
+}
+
+# For backwards compability, set only_with_tag to only_on_branch if set.
+$input{only_with_tag} = $input{only_on_branch}
+ if (defined($input{only_on_branch}));
+
+foreach (keys %DEFAULTVALUE)
+{
+ # replace not given parameters with the default parameters
+ if (!defined($input{$_}) || $input{$_} eq "") {
+ # Empty Checkboxes in forms return -- nothing. So we define a helper
+ # variable in these forms (copt) which indicates that we just set
+ # parameters with a checkbox
+ if (!defined($input{"copt"})) {
+ # 'copt' isn't defined --> empty input is not the result
+ # of empty input checkbox --> set default
+ $input{$_} = $DEFAULTVALUE{$_} if (defined($DEFAULTVALUE{$_}));
+ }
+ else {
+ # 'copt' is defined -> the result of empty input checkbox
+ # -> set to zero (disable) if default is a boolean (0|1).
+ $input{$_} = 0
+ if (defined($DEFAULTVALUE{$_})
+ && ($DEFAULTVALUE{$_} eq "0" || $DEFAULTVALUE{$_} eq "1"));
+ }
+ }
+}
+
+$barequery = "";
+foreach (@stickyvars) {
+ # construct a query string with the sticky non default parameters set
+ if (defined($input{$_}) && $input{$_} ne "" && $input{$_} ne $DEFAULTVALUE{$_}) {
+ if ($barequery) {
+ $barequery = $barequery . "&";
+ }
+ my $thisval = urlencode($_) . "=" . urlencode($input{$_});
+ $barequery .= $thisval;
+ }
+}
+# is there any query ?
+if ($barequery) {
+ $query = "?$barequery";
+ $barequery = "&" . $barequery;
+}
+else {
+ $query = "";
+}
+
+# get actual parameters
+$sortby = $input{"sortby"};
+$bydate = 0;
+$byrev = 0;
+$byauthor = 0;
+$bylog = 0;
+$byfile = 0;
+if ($sortby eq "date") {
+ $bydate = 1;
+}
+elsif ($sortby eq "rev") {
+ $byrev = 1;
+}
+elsif ($sortby eq "author") {
+ $byauthor = 1;
+}
+elsif ($sortby eq "log") {
+ $bylog = 1;
+}
+else {
+ $byfile = 1;
+}
+
+$hr_default = $input{'f'} eq 'h';
+
+$logsort = $input{"logsort"};
+
+
+## Default CVS-Tree
+if (!defined($CVSROOT{$cvstreedefault})) {
+ &fatal("500 Internal Error",
+ "<code>\$cvstreedefault</code> points to a repository "
+ . "not defined in <code>%CVSROOT</code> "
+ . "(edit your configuration file $config)");
+}
+$cvstree = $cvstreedefault;
+$cvsroot = $CVSROOT{"$cvstree"};
+
+# alternate CVS-Tree, configured in cvsweb.conf
+if ($input{'cvsroot'}) {
+ if ($CVSROOT{$input{'cvsroot'}}) {
+ $cvstree = $input{'cvsroot'};
+ $cvsroot = $CVSROOT{"$cvstree"};
+ }
+}
+
+# create icons out of description
+foreach my $k (keys %ICONS) {
+ no strict 'refs';
+ my ($itxt,$ipath,$iwidth,$iheight) = @{$ICONS{$k}};
+ if ($ipath) {
+ $ {"${k}icon"} = "<IMG SRC=\"$ipath\" ALT=\"$itxt\" BORDER=\"0\" WIDTH=\"$iwidth\" HEIGHT=\"$iheight\">";
+ }
+ else {
+ $ {"${k}icon"} = $itxt;
+ }
+}
+
+# Do some special configuration for cvstrees
+do "$config-$cvstree" if (-f "$config-$cvstree");
+
+$fullname = $cvsroot . '/' . $where;
+$mimetype = &getMimeTypeFromSuffix ($fullname);
+$defaultTextPlain = ($mimetype eq "text/plain");
+$defaultViewable = $allow_markup && viewable($mimetype);
+
+# GIF and JPEG images are already compressed.
+# Also, for some reason Netscape does not always likes compressed images.
+#
+if ($mimetype=="image/jpeg" || $mimetype=="image/gif") {$maycompress =0};
+
+# search for GZIP if compression allowed
+# We've to find out if the GZIP-binary exists .. otherwise
+# ge get an Internal Server Error if we try to pipe the
+# output through the nonexistent gzip ..
+# any more elegant ways to prevent this are welcome!
+if ($allow_compress && $maycompress) {
+ foreach (split(/:/, $ENV{PATH})) {
+ if (-x "$_/gzip") {
+ $GZIPBIN = "$_/gzip";
+ last;
+ }
+ }
+}
+
+if (-d $fullname) {
+ #
+ # ensure, that directories always end with (exactly) one '/'
+ # to allow relative URL's. If they're not, make a redirect.
+ ##
+ my $pathinfo = defined($ENV{'PATH_INFO'}) ? $ENV{'PATH_INFO'} : "";
+ if (!($pathinfo =~ m|/$|) || ($pathinfo =~ m |/{2,}$|)) {
+ redirect ($scriptwhere . '/' . $query);
+ }
+ else {
+ $where .= '/';
+ $scriptwhere .= '/';
+ }
+}
+
+if (!-d $cvsroot) {
+ &fatal("500 Internal Error",'$CVSROOT not found!<P>The server on which the CVS tree lives is probably down. Please try again in a few minutes.');
+}
+
+#
+# See if the module is in our forbidden list.
+#
+$where =~ m:([^/]*):;
+$module = $1;
+if ($module && &forbidden_module($module)) {
+ &fatal("403 Forbidden", "Access to $where forbidden.");
+}
+##############################
+# View a directory
+###############################
+elsif (-d $fullname) {
+ my $dh = do {local(*DH);};
+ opendir($dh, $fullname) || &fatal("404 Not Found","$where: $!");
+ my @dir = readdir($dh);
+ closedir($dh);
+ my @subLevelFiles = findLastModifiedSubdirs(@dir)
+ if ($show_subdir_lastmod);
+ getDirLogs($cvsroot,$where,@subLevelFiles);
+
+ if ($where eq '/') {
+ html_header("$defaulttitle");
+ print $long_intro;
+ }
+ else {
+ html_header("$where");
+ print $short_instruction;
+ }
+
+ print "<P><a name=\"dirlist\">\n";
+ # give direct access to dirs
+ if ($where eq '/') {
+ chooseMirror();
+ chooseCVSRoot();
+ }
+ else {
+ print "<p>Current directory: <b>", &clickablePath($where,0), "</b>\n";
+
+ print "<P>Current tag: <B>", $input{only_with_tag}, "</b>\n" if
+ $input{only_with_tag};
+
+ }
+
+
+ print "<P>$hr\n";
+ # Using <MENU> in this manner violates the HTML2.0 spec but
+ # provides the results that I want in most browsers. Another
+ # case of layout spooging up HTML.
+
+ my $infocols = 0;
+ if ($dirtable) {
+ if (defined($tableBorderColor)) {
+ # Can't this be done by defining the border for the inner table?
+ print "<table border=0 cellpadding=0 width=\"100%\"><tr><td bgcolor=\"$tableBorderColor\">";
+ }
+ print "<table width=\"100%\" border=0 cellspacing=1 cellpadding=$tablepadding>\n";
+ $infocols++;
+ print "<tr><th align=left bgcolor=" . (($byfile) ?
+ $columnHeaderColorSorted :
+ $columnHeaderColorDefault) . ">";
+ print "<a href=\"./" . &toggleQuery("sortby","file") .
+ "#dirlist\">" if (!$byfile);
+ print "File";
+ print "</a>" if (!$byfile);
+ print "</th>";
+ # do not display the other column-headers, if we do not have any files
+ # with revision information:
+ if (scalar(%fileinfo)) {
+ $infocols++;
+ print "<th align=left bgcolor=" . (($byrev) ?
+ $columnHeaderColorSorted :
+ $columnHeaderColorDefault) . ">";
+ print "<a href=\"./" . &toggleQuery ("sortby","rev") .
+ "#dirlist\">" if (!$byrev);
+ print "Rev.";
+ print "</a>" if (!$byrev);
+ print "</th>";
+ $infocols++;
+ print "<th align=left bgcolor=" . (($bydate) ?
+ $columnHeaderColorSorted :
+ $columnHeaderColorDefault) . ">";
+ print "<a href=\"./" . &toggleQuery ("sortby","date") .
+ "#dirlist\">" if (!$bydate);
+ print "Age";
+ print "</a>" if (!$bydate);
+ print "</th>";
+ if ($show_author) {
+ $infocols++;
+ print "<th align=left bgcolor=" . (($byauthor) ?
+ $columnHeaderColorSorted :
+ $columnHeaderColorDefault) . ">";
+ print "<a href=\"./" . &toggleQuery ("sortby","author") .
+ "#dirlist\">" if (!$byauthor);
+ print "Author";
+ print "</a>" if (!$byauthor);
+ print "</th>";
+ }
+ $infocols++;
+ print "<th align=left bgcolor=" . (($bylog) ?
+ $columnHeaderColorSorted :
+ $columnHeaderColorDefault) . ">";
+ print "<a href=\"./", toggleQuery("sortby","log"), "#dirlist\">" if (!$bylog);
+ print "Last log entry";
+ print "</a>" if (!$bylog);
+ print "</th>";
+ }
+ print "</tr>\n";
+ }
+ else {
+ print "<menu>\n";
+ }
+ my $dirrow = 0;
+
+ my $i;
+ lookingforattic:
+ for ($i = 0; $i <= $#dir; $i++) {
+ if ($dir[$i] eq "Attic") {
+ last lookingforattic;
+ }
+ }
+ if (!$input{'hideattic'} && ($i <= $#dir) &&
+ opendir($dh, $fullname . "/Attic")) {
+ splice(@dir, $i, 1,
+ grep((s|^|Attic/|,!m|/\.|), readdir($dh)));
+ closedir($dh);
+ }
+
+ my $hideAtticToggleLink = "<a href=\"./" .
+ &toggleQuery ("hideattic") .
+ "#dirlist\">[Hide]</a>" if (!$input{'hideattic'});
+
+ # Sort without the Attic/ pathname.
+ # place directories first
+
+ my $attic;
+ my $url;
+ my $fileurl;
+ my $filesexists;
+ my $filesfound;
+
+ foreach (sort { &fileSortCmp } @dir) {
+ if ($_ eq '.') {
+ next;
+ }
+ # ignore CVS lock and stale NFS files
+ next if (/^#cvs\.|^,|^\.nfs/);
+
+ # Check whether to show the CVSROOT path
+ next if ($input{'hidecvsroot'} && ($_ eq 'CVSROOT'));
+
+ # Check whether the module is in the restricted list
+ next if ($_ && &forbidden_module($_));
+
+ # Ignore non-readable files
+ next if ($input{'hidenonreadable'} && !(-r "$fullname/$_"));
+
+ if (s|^Attic/||) {
+ $attic = " (in the Attic)&nbsp;" . $hideAtticToggleLink;
+ }
+ else {
+ $attic = "";
+ }
+
+ if ($_ eq '..' || -d "$fullname/$_") {
+ next if ($_ eq '..' && $where eq '/');
+ my ($rev,$date,$log,$author,$filename) = @{$fileinfo{$_}}
+ if (defined($fileinfo{$_}));
+ print "<tr bgcolor=\"" . @tabcolors[$dirrow%2] . "\"><td>" if ($dirtable);
+ if ($_ eq '..') {
+ $url = "../" . $query;
+ if ($nofilelinks) {
+ print $backicon;
+ }
+ else {
+ print &link($backicon,$url);
+ }
+ print " ", &link("Previous Directory",$url);
+ }
+ else {
+ $url = urlencode($_) . '/' . $query;
+ print "<A NAME=\"$_\">";
+ if ($nofilelinks) {
+ print $diricon;
+ }
+ else {
+ print &link($diricon,$url);
+ }
+ print " ", &link($_ . "/", $url), $attic;
+ if ($_ eq "Attic") {
+ print "&nbsp; <a href=\"./" .
+ &toggleQuery ("hideattic") .
+ "#dirlist\">[Don't hide]</a>";
+ }
+ }
+ # Show last change in dir
+ if ($filename) {
+ print "</td><td>&nbsp</td><td>&nbsp;" if ($dirtable);
+ if ($date) {
+ print " <i>" . readableTime(time() - $date,0) . "</i>";
+ }
+ if ($show_author) {
+ print "</td><td>&nbsp;" if ($dirtable);
+ print $author;
+ }
+ print "</td><td>&nbsp;" if ($dirtable);
+ $filename =~ s%^[^/]+/%%;
+ print "$filename/$rev";
+ print "<BR>" if ($dirtable);
+ if ($log) {
+ print "&nbsp;<font size=-1>"
+ . &htmlify(substr($log,0,$shortLogLen));
+ if (length $log > 80) {
+ print "...";
+ }
+ print "</font>";
+ }
+ }
+ else {
+ # if there are any files (which require infocols), close the
+ # row with the appropriate number of columns, so that the
+ # vertical seperators are visible
+ if ($dirtable && scalar(%fileinfo)) {
+ print "</td>";
+ my($cols) = $infocols;
+ while ($cols > 1) {
+ print "<td>&nbsp;</td>";
+ $cols--;
+ }
+ }
+ }
+ if ($dirtable) {
+ print "</td></tr>\n";
+ }
+ else {
+ print "<br>\n";
+ }
+ $dirrow++;
+ }
+ elsif (s/,v$//) {
+ $fileurl = ($attic ? "Attic/" : "") . urlencode($_);
+ $url = $fileurl . $query;
+ my $rev = '';
+ my $date = '';
+ my $log = '';
+ my $author = '';
+ $filesexists++;
+ next if (!defined($fileinfo{$_}));
+ ($rev,$date,$log,$author) = @{$fileinfo{$_}};
+ $filesfound++;
+ print "<tr bgcolor=\"" . @tabcolors[$dirrow%2] . "\"><td>" if ($dirtable);
+ print "<A NAME=\"$_\">";
+ if ($nofilelinks) {
+ print $fileicon;
+ }
+ else {
+ print &link($fileicon,$url);
+ }
+ print " ", &link($_, $url), $attic;
+ print "</td><td>&nbsp;" if ($dirtable);
+ download_link($fileurl,
+ $rev, $rev,
+ $defaultViewable ? "text/x-cvsweb-markup" : undef);
+ print "</td><td>&nbsp;" if ($dirtable);
+ if ($date) {
+ print " <i>" . readableTime(time() - $date,0) . "</i>";
+ }
+ if ($show_author) {
+ print "</td><td>&nbsp;" if ($dirtable);
+ print $author;
+ }
+ print "</td><td>&nbsp;" if ($dirtable);
+ if ($log) {
+ print " <font size=-1>" . &htmlify(substr($log,0,$shortLogLen));
+ if (length $log > 80) {
+ print "...";
+ }
+ print "</font>";
+ }
+ print "</td>" if ($dirtable);
+ print (($dirtable) ? "</tr>" : "<br>");
+ $dirrow++;
+ }
+ print "\n";
+ }
+ if ($dirtable && defined($tableBorderColor)) {
+ print "</td></tr></table>";
+ }
+ print "". ($dirtable == 1) ? "</table>" : "</menu>" . "\n";
+
+ if ($filesexists && !$filesfound) {
+ print "<P><B>NOTE:</B> There are $filesexists files, but none matches the current tag ($input{only_with_tag})\n";
+ }
+ if ($input{only_with_tag} && (!%tags || !$tags{$input{only_with_tag}})) {
+ %tags = %alltags
+ }
+ if (scalar %tags
+ || $input{only_with_tag}
+ || $edit_option_form
+ || defined($input{"options"})) {
+ print "$bighr";
+ }
+
+ if (scalar %tags || $input{only_with_tag}) {
+ print "<FORM METHOD=\"GET\" ACTION=\"./\">\n";
+ foreach my $var (@stickyvars) {
+ print "<INPUT TYPE=HIDDEN NAME=\"$var\" VALUE=\"$input{$var}\">\n"
+ if (defined($input{$var})
+ && $input{$var} ne $DEFAULTVALUE{$var}
+ && $input{$var} ne ""
+ && $var ne "only_with_tag");
+ }
+ print "Show only files with tag:\n";
+ print "<SELECT NAME=only_with_tag";
+ print " onchange=\"submit()\"" if ($use_java_script);
+ print ">";
+ print "<OPTION VALUE=\"\">All tags / default branch\n";
+ foreach my $tag (reverse sort { lc $a cmp lc $b } keys %tags) {
+ print "<OPTION",defined($input{only_with_tag}) &&
+ $input{only_with_tag} eq $tag ? " SELECTED":"",
+ ">$tag\n";
+ }
+ print "</SELECT>\n";
+ print "<INPUT TYPE=SUBMIT VALUE=\"Go\">\n";
+ print "</FORM>\n";
+ }
+ my $formwhere = $scriptwhere;
+ $formwhere =~ s|Attic/?$|| if ($input{'hideattic'});
+
+ if ($edit_option_form || defined($input{"options"})) {
+ print "<FORM METHOD=\"GET\" ACTION=\"${formwhere}\">\n";
+ print "<INPUT TYPE=HIDDEN NAME=\"copt\" VALUE=\"1\">\n";
+ if ($cvstree ne $cvstreedefault) {
+ print "<INPUT TYPE=HIDDEN NAME=\"cvsroot\" VALUE=\"$cvstree\">\n";
+ }
+ print "<center><table cellpadding=0 cellspacing=0>";
+ print "<tr bgcolor=\"$columnHeaderColorDefault\"><th colspan=2>Preferences</th></tr>";
+ print "<tr><td>Sort files by <SELECT name=\"sortby\">";
+ print "<OPTION VALUE=\"\">File";
+ print "<OPTION",$bydate ? " SELECTED" : ""," VALUE=date>Age";
+ print "<OPTION",$byauthor ? " SELECTED" : ""," VALUE=author>Author"
+ if ($show_author);
+ print "<OPTION",$byrev ? " SELECTED" : ""," VALUE=rev>Revision";
+ print "<OPTION",$bylog ? " SELECTED" : ""," VALUE=log>Log message";
+ print "</SELECT></td>";
+ print "<td>revisions by: \n";
+ print "<SELECT NAME=logsort>\n";
+ print "<OPTION VALUE=cvs",$logsort eq "cvs" ? " SELECTED" : "", ">Not sorted";
+ print "<OPTION VALUE=date",$logsort eq "date" ? " SELECTED" : "", ">Commit date";
+ print "<OPTION VALUE=rev",$logsort eq "rev" ? " SELECTED" : "", ">Revision";
+ print "</SELECT></td></tr>";
+ print "<tr><td>Diff format: ";
+ printDiffSelect();
+ print "</td>";
+ print "<td>Show Attic files: ";
+ print "<INPUT NAME=hideattic TYPE=CHECKBOX", $input{'hideattic'}?" CHECKED":"",
+ "></td></tr>\n";
+ print "<tr><td align=center colspan=2><input type=submit value=\"Change Options\">";
+ print "</td></tr></table></center></FORM>\n";
+ }
+ print &html_footer;
+ print "</BODY></HTML>\n";
+ }
+
+###############################
+# View Files
+###############################
+ elsif (-f $fullname . ',v') {
+ if (defined($input{'rev'}) || $doCheckout) {
+ &doCheckout($fullname, $input{'rev'});
+ exit;
+ }
+ if (defined($input{'annotate'}) && $allow_annotate) {
+ &doAnnotate($input{'annotate'});
+ exit;
+ }
+ if (defined($input{'r1'}) && defined($input{'r2'})) {
+ &doDiff($fullname, $input{'r1'}, $input{'tr1'},
+ $input{'r2'}, $input{'tr2'}, $input{'f'});
+ exit;
+ }
+ print("going to dolog($fullname)\n") if ($verbose);
+ &doLog($fullname);
+##############################
+# View Diff
+##############################
+ }
+ elsif ($fullname =~ s/\.diff$// && -f $fullname . ",v" &&
+ $input{'r1'} && $input{'r2'}) {
+
+ # $where-diff-removal if 'cvs rdiff' is used
+ # .. but 'cvs rdiff'doesn't support some options
+ # rcsdiff does (-w and -p), so it is disabled
+ # $where =~ s/\.diff$//;
+
+ # Allow diffs using the ".diff" extension
+ # so that browsers that default to the URL
+ # for a save filename don't save diff's as
+ # e.g. foo.c
+ &doDiff($fullname, $input{'r1'}, $input{'tr1'},
+ $input{'r2'}, $input{'tr2'}, $input{'f'});
+ exit;
+ }
+ elsif (($newname = $fullname) =~ s|/([^/]+)$|/Attic/$1| &&
+ -f $newname . ",v") {
+ # The file has been removed and is in the Attic.
+ # Send a redirect pointing to the file in the Attic.
+ (my $newplace = $scriptwhere) =~ s|/([^/]+)$|/Attic/$1|;
+ &redirect($newplace);
+ exit;
+ }
+ elsif (0 && (my @files = &safeglob($fullname . ",v"))) {
+ http_header("text/plain");
+ print "You matched the following files:\n";
+ print join("\n", @files);
+ # Find the tags from each file
+ # Display a form offering diffs between said tags
+ }
+ else {
+ my $fh = do {local(*FH);};
+ my ($xtra, $module);
+ # Assume it's a module name with a potential path following it.
+ $xtra = $& if (($module = $where) =~ s|/.*||);
+ # Is there an indexed version of modules?
+ if (open($fh, "$cvsroot/CVSROOT/modules")) {
+ while (<$fh>) {
+ if (/^(\S+)\s+(\S+)/o && $module eq $1
+ && -d "${cvsroot}/$2" && $module ne $2) {
+ &redirect($scriptname . '/' . $2 . $xtra);
+ }
+ }
+ }
+ &fatal("404 Not Found","$where: no such file or directory");
+ }
+## End MAIN
+
+sub printDiffSelect {
+ my ($use_java_script) = @_;
+ $use_java_script = 0 if (!defined($use_java_script));
+ my ($f) = $input{'f'};
+ print "<SELECT NAME=\"f\"";
+ print " onchange=\"submit()\"" if ($use_java_script);
+ print ">\n";
+ print "<OPTION VALUE=h",$f eq "h" ? " SELECTED" : "", ">Colored Diff";
+ print "<OPTION VALUE=H",$f eq "H" ? " SELECTED" : "", ">Long Colored Diff";
+ print "<OPTION VALUE=u",$f eq "u" ? " SELECTED" : "", ">Unidiff";
+ print "<OPTION VALUE=c",$f eq "c" ? " SELECTED" : "", ">Context Diff";
+ print "<OPTION VALUE=s",$f eq "s" ? " SELECTED" : "", ">Side by Side";
+ print "</SELECT>";
+}
+
+sub findLastModifiedSubdirs {
+ my (@dirs) = @_;
+ my ($dirname, @files);
+
+ foreach $dirname (@dirs) {
+ next if ($dirname eq ".");
+ next if ($dirname eq "..");
+ my ($dir) = "$fullname/$dirname";
+ next if (!-d $dir);
+
+ my ($lastmod) = undef;
+ my ($lastmodtime) = undef;
+ my $dh = do {local(*DH);};
+
+ opendir($dh,$dir) || next;
+ my (@filenames) = readdir($dh);
+ closedir($dh);
+
+ foreach my $filename (@filenames) {
+ $filename = "$dirname/$filename";
+ my ($file) = "$fullname/$filename";
+ next if ($filename !~ /,v$/ || !-f $file);
+ $filename =~ s/,v$//;
+ my $modtime = -M $file;
+ if (!defined($lastmod) || $modtime < $lastmodtime) {
+ $lastmod = $filename;
+ $lastmodtime = $modtime;
+ }
+ }
+ push(@files, $lastmod) if (defined($lastmod));
+ }
+ return @files;
+}
+
+sub htmlify {
+ my($string, $pr) = @_;
+
+ # Special Characters; RFC 1866
+ $string =~ s/&/&amp;/g;
+ $string =~ s/\"/&quot;/g;
+ $string =~ s/</&lt;/g;
+ $string =~ s/>/&gt;/g;
+
+ # get URL's as link ..
+ $string =~ s§(http|ftp)(://[-a-zA-Z0-9%.~:_/]+)([?&]([-a-zA-Z0-9%.~:_]+)=([-a-zA-Z0-9%.~:_])+)*§<A HREF="$1$2$3">$1$2$3</A>§;
+ # get e-mails as link
+ $string =~ s§([-a-zA-Z0-9_.]+@([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})§<A HREF="mailto:$1">$1</A>§;
+
+ # get #PR as link ..
+ if ($pr && defined($prcgi)) {
+ $string =~ s!\b((pr[:#]?\s*#?)|((bin|conf|docs|gnu|i386|kern|misc|ports)\/))(\d+)\b!<A HREF="$prcgi?pr=$5">$&</A>!ig;
+ }
+
+ return $string;
+}
+
+sub spacedHtmlText {
+ my($string, $pr) = @_;
+
+ # Cut trailing spaces
+ s/\s+$//;
+
+ # Expand tabs
+ $string =~ s/\t+/' ' x (length($&) * $tabstop - length($`) % $tabstop)/e
+ if (defined($tabstop));
+
+ # replace <tab> and <space> (§ is to protect us from htmlify)
+ # gzip can make excellent use of this repeating pattern :-)
+ $string =~ s/§/§%/g; #protect our & substitute
+ if ($hr_breakable) {
+ # make every other space 'breakable'
+ $string =~ s/ / §nbsp; §nbsp; §nbsp; §nbsp;/g; # <tab>
+ $string =~ s/ / §nbsp;/g; # 2 * <space>
+ # leave single space as it is
+ }
+ else {
+ $string =~ s/ /§nbsp;§nbsp;§nbsp;§nbsp;§nbsp;§nbsp;§nbsp;§nbsp;/g;
+ $string =~ s/ /§nbsp;/g;
+ }
+
+ $string = htmlify($string);
+
+ # unescape
+ $string =~ s/§([^%])/&$1/g;
+ $string =~ s/§%/§/g;
+
+ return $string;
+}
+
+sub link {
+ my($name, $where) = @_;
+
+ return "<A HREF=\"$where\">$name</A>\n";
+}
+
+sub revcmp {
+ my($rev1, $rev2) = @_;
+ my(@r1) = split(/\./, $rev1);
+ my(@r2) = split(/\./, $rev2);
+ my($a,$b);
+
+ while (($a = shift(@r1)) && ($b = shift(@r2))) {
+ if ($a != $b) {
+ return $a <=> $b;
+ }
+ }
+ if (@r1) { return 1; }
+ if (@r2) { return -1; }
+ return 0;
+}
+
+sub fatal {
+ my($errcode, $errmsg) = @_;
+ if (defined($ENV{'MOD_PERL'})) {
+ Apache->request->status((split(/ /, $errcode))[0]);
+ }
+ else {
+ print "Status: $errcode\n";
+ }
+ html_header("Error");
+ print "Error: $errmsg\n";
+ print &html_footer;
+ exit(1);
+}
+
+sub redirect {
+ my($url) = @_;
+ if (defined($ENV{'MOD_PERL'})) {
+ Apache->request->status(301);
+ Apache->request->header_out(Location => $url);
+ }
+ else {
+ print "Status: 301 Moved\n";
+ print "Location: $url\n";
+ }
+ html_header("Moved");
+ print "This document is located <A HREF=$url>here</A>.\n";
+ print &html_footer;
+ exit(1);
+}
+
+sub safeglob {
+ my ($filename) = @_;
+ my ($dirname);
+ my (@results);
+ my $dh = do {local(*DH);};
+
+ ($dirname = $filename) =~ s|/[^/]+$||;
+ $filename =~ s|.*/||;
+
+ if (opendir($dh, $dirname)) {
+ my $glob = $filename;
+ my $t;
+ # transform filename from glob to regex. Deal with:
+ # [, {, ?, * as glob chars
+ # make sure to escape all other regex chars
+ $glob =~ s/([\.\(\)\|\+])/\\$1/g;
+ $glob =~ s/\*/.*/g;
+ $glob =~ s/\?/./g;
+ $glob =~ s/{([^}]+)}/($t = $1) =~ s-,-|-g; "($t)"/eg;
+ foreach (readdir($dh)) {
+ if (/^${glob}$/) {
+ push(@results, $dirname . "/" .$_);
+ }
+ }
+ }
+
+ @results;
+}
+
+sub getMimeTypeFromSuffix {
+ my ($fullname) = @_;
+ my ($mimetype, $suffix);
+ my $fh = do {local(*FH);};
+
+ ($suffix = $fullname) =~ s/^.*\.([^.]*)$/$1/;
+ $mimetype = $MTYPES{$suffix};
+ $mimetype = $MTYPES{'*'} if (!$mimetype);
+
+ if (!$mimetype && -f $mime_types) {
+ # okey, this is something special - search the
+ # mime.types database
+ open ($fh, "<$mime_types");
+ while (<$fh>) {
+ if ($_ =~ /^\s*(\S+\/\S+).*\b$suffix\b/) {
+ $mimetype = $1;
+ last;
+ }
+ }
+ close ($fh);
+ }
+
+# okey, didn't find anything useful ..
+ if (!($mimetype =~ /\S\/\S/)) {
+ $mimetype = "text/plain";
+ }
+ return $mimetype;
+}
+
+###############################
+# show Annotation
+###############################
+sub doAnnotate ($$) {
+ my ($rev) = @_;
+ my ($pid);
+ my ($pathname, $filename);
+ my $reader = do {local(*FH);};
+ my $writer = do {local(*FH);};
+
+ # make sure the revisions a wellformed, for security
+ # reasons ..
+ if (!($rev =~ /^[\d\.]+$/)) {
+ &fatal("404 Not Found",
+ "Malformed query \"$ENV{'QUERY_STRING'}\"");
+ }
+
+ ($pathname = $where) =~ s/(Attic\/)?[^\/]*$//;
+ ($filename = $where) =~ s/^.*\///;
+
+ http_header();
+
+ navigateHeader ($scriptwhere,$pathname,$filename,$rev, "annotate");
+ print "<h3 align=center>Annotation of $pathname$filename, Revision $rev</h3>\n";
+
+ # this seems to be necessary
+ $| = 1; $| = 0; # Flush
+
+ # this annotate version is based on the
+ # cvs annotate-demo Perl script by Cyclic Software
+ # It was written by Cyclic Software, http://www.cyclic.com/, and is in
+ # the public domain.
+ # we could abandon the use of rlog, rcsdiff and co using
+ # the cvsserver in a similiar way one day (..after rewrite)
+ $pid = open2($reader, $writer, "cvs server") || fatal ("500 Internal Error",
+ "Fatal Error - unable to open cvs for annotation");
+
+ # OK, first send the request to the server. A simplified example is:
+ # Root /home/kingdon/zwork/cvsroot
+ # Argument foo/xx
+ # Directory foo
+ # /home/kingdon/zwork/cvsroot/foo
+ # Directory .
+ # /home/kingdon/zwork/cvsroot
+ # annotate
+ # although as you can see there are a few more details.
+
+ print $writer "Root $cvsroot\n";
+ print $writer "Valid-responses ok error Valid-requests Checked-in Updated Merged Removed M E\n";
+ # Don't worry about sending valid-requests, the server just needs to
+ # support "annotate" and if it doesn't, there isn't anything to be done.
+ print $writer "UseUnchanged\n";
+ print $writer "Argument -r\n";
+ print $writer "Argument $rev\n";
+ print $writer "Argument $where\n";
+
+ # The protocol requires us to fully fake a working directory (at
+ # least to the point of including the directories down to the one
+ # containing the file in question).
+ # So if $where is "dir/sdir/file", then @dirs will be ("dir","sdir","file")
+ my @dirs = split (/\//, $where);
+ my $path = "";
+ foreach (@dirs) {
+ if ($path eq "") {
+ # In our example, $_ is "dir".
+ $path = $_;
+ }
+ else {
+ print $writer "Directory " . $path . "\n";
+ print $writer "$cvsroot/" . $path ."\n";
+ # In our example, $_ is "sdir" and $path becomes "dir/sdir"
+ # And the next time, "file" and "dir/sdir/file" (which then gets
+ # ignored, because we don't need to send Directory for the file).
+ $path = $path . "/" . $_;
+ }
+ }
+ # And the last "Directory" before "annotate" is the top level.
+ print $writer "Directory .\n";
+ print $writer "$cvsroot\n";
+
+ print $writer "annotate\n";
+ # OK, we've sent our command to the server. Thing to do is to
+ # close the writer side and get all the responses. If "cvs server"
+ # were nicer about buffering, then we could just leave it open, I think.
+ close ($writer) || die "cannot close: $!";
+
+ # Ready to get the responses from the server.
+ # For example:
+ # E Annotations for foo/xx
+ # E ***************
+ # M 1.3 (kingdon 06-Sep-97): hello
+ # ok
+ my ($lineNr) = 0;
+ my ($oldLrev, $oldLusr) = ("", "");
+ my ($revprint, $usrprint);
+ if ($annTable) {
+ print "<table border=0 cellspacing=0 cellpadding=0>\n";
+ }
+ else {
+ print "<pre>";
+ }
+ while (<$reader>) {
+ my @words = split;
+ # Adding one is for the (single) space which follows $words[0].
+ my $rest = substr ($_, length ($words[0]) + 1);
+ if ($words[0] eq "E") {
+ next;
+ }
+ elsif ($words[0] eq "M") {
+ $lineNr++;
+ my $lrev = substr ($_, 2, 13);
+ my $lusr = substr ($_, 16, 9);
+ my $line = substr ($_, 36);
+ # we should parse the date here ..
+ if ($lrev eq $oldLrev) {
+ $revprint = " ";
+ }
+ else {
+ $revprint = $lrev; $oldLusr = "";
+ }
+ if ($lusr eq $oldLusr) {
+ $usrprint = " ";
+ }
+ else {
+ $usrprint = $lusr;
+ }
+ $oldLrev = $lrev;
+ $oldLusr = $lusr;
+ # is there a less timeconsuming way to strip spaces ?
+ ($lrev = $lrev) =~ s/\s+//g;
+ my $isCurrentRev = ("$rev" eq "$lrev");
+
+ print "<b>" if ($isCurrentRev);
+ printf ("%8s%s%8s %4d:", $revprint, ($isCurrentRev ? "|" : " "), $usrprint, $lineNr);
+ print spacedHtmlText($line);
+ print "</b>" if ($isCurrentRev);
+ }
+ elsif ($words[0] eq "ok") {
+ # We could complain about any text received after this, like the
+ # CVS command line client. But for simplicity, we don't.
+ }
+ elsif ($words[0] eq "error") {
+ fatal ("500 Internal Error", "Error occured during annotate: <b>$_</b>");
+ }
+ }
+ if ($annTable) {
+ print "</table>";
+ }
+ else {
+ print "</pre>";
+ }
+ close ($reader) || warn "cannot close: $!";
+ wait;
+}
+
+###############################
+# make Checkout
+###############################
+sub doCheckout {
+ my ($fullname, $rev) = @_;
+ my ($mimetype,$revopt);
+ my $fh = do {local(*FH);};
+
+ # make sure the revisions a wellformed, for security
+ # reasons ..
+ if (defined($rev) && !($rev =~ /^[\d\.]+$/)) {
+ &fatal("404 Not Found",
+ "Malformed query \"$ENV{'QUERY_STRING'}\"");
+ }
+
+ # get mimetype
+ if (defined($input{"content-type"}) && ($input{"content-type"} =~ /\S\/\S/)) {
+ $mimetype = $input{"content-type"}
+ }
+ else {
+ $mimetype = &getMimeTypeFromSuffix($fullname);
+ }
+
+ if (defined($rev)) {
+ $revopt = "-r'$rev'";
+ readLog($fullname,$rev);
+ $moddate=$date{$rev};
+ }
+ else {
+ $revopt = "";
+ readLog($fullname);
+ $moddate=$date{$symrev{HEAD}};
+ }
+
+ # this may not be quoted with single quotes
+ # in windows .. but should in U*nx. there
+ # is a function which allows for quoting `evil`
+ # characters somewhere, I know (buried in the Perl-manpage)
+ ##
+ ### just for the record:
+ ### 'cvs co' seems to have a bug regarding single checkout of
+ ### directories/files having spaces in it;
+ ### this is an issue that should be resolved on cvs's side
+ open($fh, "cvs -d'$cvsroot' co -p $revopt '$where' 2>&1 |") ||
+ &fatal("500 Internal Error", "Couldn't co: $!");
+#===================================================================
+#Checking out squid/src/ftp.c
+#RCS: /usr/src/CVS/squid/src/ftp.c,v
+#VERS: 1.1.1.28.6.2
+#***************
+
+ # Parse CVS header
+ my ($revision, $filename, $cvsheader);
+ while(<$fh>) {
+ last if (/^\*\*\*\*/);
+ $revision = $1 if (/^VERS: (.*)$/);
+ $filename = $1 if (/^Checking out (.*)$/);
+ $cvsheader .= $_;
+ }
+ if ($filename ne $where) {
+ &fatal("500 Internal Error",
+ "Unexpected output from cvs co: $cvsheader"
+ . "<p><b>Check whether the directory $cvsroot/CVSROOT exists "
+ . "and the script has write-access to the CVSROOT/history "
+ . "file if it exists."
+ . "<br>The script needs to place lock files in the "
+ . "directory the file is in as well.</b>");
+ }
+ $| = 1;
+
+ if ($mimetype eq "text/x-cvsweb-markup") {
+ &cvswebMarkup($fh,$fullname,$revision);
+ }
+ else {
+ http_header($mimetype);
+ print <$fh>;
+ }
+ close($fh);
+}
+
+sub cvswebMarkup {
+ my ($filehandle,$fullname,$revision) = @_;
+ my ($pathname, $filename);
+
+ ($pathname = $where) =~ s/(Attic\/)?[^\/]*$//;
+ ($filename = $where) =~ s/^.*\///;
+ my ($fileurl) = urlencode($filename);
+
+ http_header();
+
+ navigateHeader ($scriptwhere, $pathname, $filename, $revision, "view");
+ print "$hr";
+ print "<table width=\"100%\"><tr><td bgcolor=\"$markupLogColor\">";
+ print "File: ", &clickablePath($where, 1), "</b>";
+ print "&nbsp;";
+ &download_link(urlencode($fileurl), $revision, "(download)");
+ if (!$defaultTextPlain) {
+ print "&nbsp;";
+ &download_link(urlencode($fileurl), $revision, "(as text)",
+ "text/plain");
+ }
+ print "<BR>\n";
+ if ($show_log_in_markup) {
+ readLog($fullname); #,$revision);
+ printLog($revision,0);
+ }
+ else {
+ print "Version: <B>$revision</B><BR>\n";
+ print "Tag: <B>", $input{only_with_tag}, "</b><br>\n" if
+ $input{only_with_tag};
+ }
+ print "</td></tr></table>";
+ my @content = <$filehandle>;
+ my $url = download_url($fileurl, $revision, $mimetype);
+ print "$hr";
+ if ($mimetype =~ /^image/) {
+ print "<IMG SRC=\"$url$barequery\"><BR>";
+ }
+ else {
+ print "<PRE>";
+ foreach (@content) {
+ print htmlify($_);
+ }
+ print "</PRE>";
+ }
+}
+
+sub viewable($) {
+ my ($mimetype) = @_;
+
+ $mimetype =~ m%^text/% ||
+ $mimetype =~ m%^image/% ||
+ 0;
+}
+
+###############################
+# Show Colored Diff
+###############################
+sub doDiff {
+ my($fullname, $r1, $tr1, $r2, $tr2, $f) = @_;
+ my $fh = do {local(*FH);};
+ my ($rev1, $rev2, $sym1, $sym2, $difftype, $diffname, $f1, $f2);
+
+ if ($r1 =~ /([^:]+)(:(.+))?/) {
+ $rev1 = $1;
+ $sym1 = $3;
+ }
+ if ($r1 eq 'text') {
+ $rev1 = $tr1;
+ $sym1 = "";
+ }
+ if ($r2 =~ /([^:]+)(:(.+))?/) {
+ $rev2 = $1;
+ $sym2 = $3;
+ }
+ if ($r2 eq 'text') {
+ $rev2 = $tr2;
+ $sym2 = "";
+ }
+ # make sure the revisions a wellformed, for security
+ # reasons ..
+ if (!($rev1 =~ /^[\d\.]+$/) || !($rev2 =~ /^[\d\.]+$/)) {
+ &fatal("404 Not Found",
+ "Malformed query \"$ENV{'QUERY_STRING'}\"");
+ }
+#
+# rev1 and rev2 are now both numeric revisions.
+# Thus we do a DWIM here and swap them if rev1 is after rev2.
+# XXX should we warn about the fact that we do this?
+ if (&revcmp($rev1,$rev2) > 0) {
+ my ($tmp1, $tmp2) = ($rev1, $sym1);
+ ($rev1, $sym1) = ($rev2, $sym2);
+ ($rev2, $sym2) = ($tmp1, $tmp2);
+ }
+ my $human_readable = 0;
+ if ($f eq 'c') {
+ $difftype = '-c';
+ $diffname = "Context diff";
+ }
+ elsif ($f eq 's') {
+ $difftype = '--side-by-side --width=164';
+ $diffname = "Side by Side";
+ }
+ elsif ($f eq 'H') {
+ $human_readable = 1;
+ $difftype = '--unified=15';
+ $diffname = "Long Human readable";
+ }
+ elsif ($f eq 'h') {
+ $difftype = '-u';
+ $human_readable = 1;
+ $diffname = "Human readable";
+ }
+ elsif ($f eq 'u') {
+ $difftype = '-u';
+ $diffname = "Unidiff";
+ }
+ else {
+ fatal ("400 Bad arguments", "Diff format $f not understood");
+ }
+
+ # apply special options
+ if ($human_readable) {
+ if ($hr_funout) {
+ $difftype = $difftype . ' -p';
+ }
+ if ($hr_ignwhite) {
+ $difftype = $difftype . ' -w';
+ }
+ if ($hr_ignkeysubst) {
+ $difftype = $difftype . ' -kk';
+ }
+ }
+## cvs rdiff doesn't support '-p' and '-w' option .. sad
+# open($fh, "cvs -d $cvsroot rdiff $difftype " .
+# "-r$rev1 -r$rev2 '$where' 2>&1 |")
+# || &fatal("500 Internal Error", "Couldn't cvs rdiff: $!");
+###
+ open($fh, "rcsdiff $difftype -r$rev1 -r$rev2 '$fullname' 2>&1 |")
+ || &fatal("500 Internal Error", "Couldn't GNU rcsdiff: $!");
+ if ($human_readable) {
+ http_header();
+ &human_readable_diff($fh, $rev2);
+ exit;
+ }
+ else {
+ http_header("text/plain");
+ }
+#
+#===================================================================
+#RCS file: /home/ncvs/src/sys/netinet/tcp_output.c,v
+#retrieving revision 1.16
+#retrieving revision 1.17
+#diff -c -r1.16 -r1.17
+#*** /home/ncvs/src/sys/netinet/tcp_output.c 1995/11/03 22:08:08 1.16
+#--- /home/ncvs/src/sys/netinet/tcp_output.c 1995/12/05 17:46:35 1.17
+#
+# Ideas:
+# - nuke the stderr output if it's what we expect it to be
+# - Add "no differences found" if the diff command supplied no output.
+#
+#*** src/sys/netinet/tcp_output.c 1995/11/03 22:08:08 1.16
+#--- src/sys/netinet/tcp_output.c 1995/12/05 17:46:35 1.17 RELENG_2_1_0
+# (bogus example, but...)
+#
+ if ($difftype eq '-u') {
+ $f1 = '---';
+ $f2 = '\+\+\+';
+ }
+ else {
+ $f1 = '\*\*\*';
+ $f2 = '---';
+ }
+ while (<$fh>) {
+ if (m|^$f1 $cvsroot|o) {
+ s|$cvsroot/||o;
+ if ($sym1) {
+ chop;
+ $_ .= " " . $sym1 . "\n";
+ }
+ }
+ elsif (m|^$f2 $cvsroot|o) {
+ s|$cvsroot/||o;
+ if ($sym2) {
+ chop;
+ $_ .= " " . $sym2 . "\n";
+ }
+ }
+ print $_;
+ }
+ close($fh);
+}
+
+###############################
+# Show Logs ..
+###############################
+sub getDirLogs {
+ my ($cvsroot,$dirname,@otherFiles) = @_;
+ my ($state,$otherFiles,$tag, $file, $date, $branchpoint, $branch, $log);
+ my ($rev, $revision, $revwanted, $filename, $head, $author);
+
+ $tag = $input{only_with_tag};
+
+ my ($DirName) = "$cvsroot/$where";
+ my (@files, @filetags);
+ my $fh = do {local(*FH);};
+
+ push(@files, &safeglob("$DirName/*,v"));
+ push(@files, &safeglob("$DirName/Attic/*,v")) if (!$input{'hideattic'});
+ foreach $file (@otherFiles) {
+ push(@files, "$DirName/$file");
+ }
+
+ # just execute rlog if there are any files
+ if ($#files < 0) {
+ return;
+ }
+
+ my ($filenames) = join("' '",@files);
+ if ($tag) {
+ #can't use -r<tag> as - is allowed in tagnames, but misinterpreated by rlog..
+ open($fh, "rlog '$filenames' 2>/dev/null |")
+ || &fatal("500 Internal Error", "Failed to spawn GNU rlog");
+ }
+ else {
+ open($fh, "rlog -r '$filenames' 2>/dev/null |")
+ || &fatal("500 Internal Error", "Failed to spawn GNU rlog");
+ }
+ $state = "start";
+ while (<$fh>) {
+ if ($state eq "start") {
+ #Next file. Initialize file variables
+ $rev = undef;
+ $revwanted = undef;
+ $branch = undef;
+ $branchpoint = undef;
+ $filename = undef;
+ $log = undef;
+ $revision = undef;
+ $branch = undef;
+ %symrev = ();
+ @filetags = ();
+ #jump to head state
+ $state = "head";
+ }
+ print "$state:$_" if ($verbose);
+again:
+ if ($state eq "head") {
+ #$rcsfile = $1 if (/^RCS file: (.+)$/); #not used (yet)
+ $filename = $1 if (/^Working file: (.+)$/);
+ $head = $1 if (/^head: (.+)$/);
+ $branch = $1 if (/^branch: (.+)$/);
+ }
+ if ($state eq "head" && /^symbolic names/) {
+ $state = "tags";
+ ($branch = $head) =~ s/\.\d+$// if (!defined($branch));
+ $branch =~ s/(\.?)(\d+)$/${1}0.$2/;
+ $symrev{MAIN} = $branch;
+ $symrev{HEAD} = $branch;
+ $alltags{MAIN} = 1;
+ $alltags{HEAD} = 1;
+ push (@filetags, "MAIN", "HEAD");
+ next;
+ }
+ if ($state eq "tags" &&
+ /^\s+(.+):\s+([\d\.]+)\s+$/) {
+ push (@filetags, $1);
+ $symrev{$1} = $2;
+ $alltags{$1} = 1;
+ next;
+ }
+ if ($state eq "tags" && /^\S/) {
+ if (defined($tag) && (defined($symrev{$tag}) || $tag eq "HEAD")) {
+ $revwanted = $tag eq "HEAD" ? $symrev{"MAIN"} : $symrev{$tag};
+ ($branch = $revwanted) =~ s/\b0\.//;
+ ($branchpoint = $branch) =~ s/\.?\d+$//;
+ $revwanted = undef if ($revwanted ne $branch);
+ }
+ elsif (defined($tag) && $tag ne "HEAD") {
+ print "Tag not found, skip this file" if ($verbose);
+ $state = "skip";
+ next;
+ }
+ foreach my $tagfound (@filetags) {
+ $tags{$tagfound} = 1;
+ }
+ $state = "head";
+ goto again;
+ }
+ if ($state eq "head" && /^----------------------------$/) {
+ $state = "log";
+ $rev = undef;
+ $date = undef;
+ $log = "";
+ # Try to reconstruct the relative filename if RCS spits out a full path
+ $filename =~ s%^$DirName/%%;
+ next;
+ }
+ if ($state eq "log") {
+ if (/^----------------------------$/
+ || /^=============================/) {
+ # End of a log entry.
+ my $revbranch;
+ ($revbranch = $rev) =~ s/\.\d+$//;
+ print "$filename $rev Wanted: $revwanted "
+ . "Revbranch: $revbranch Branch: $branch "
+ . "Branchpoint: $branchpoint\n" if ($verbose);
+ if (!defined($revwanted) && defined($branch)
+ && $branch eq $revbranch || !defined($tag)) {
+ print "File revision $rev found for branch $branch\n"
+ if ($verbose);
+ $revwanted = $rev;
+ }
+ if (defined($revwanted) ? $rev eq $revwanted :
+ defined($branchpoint) ? $rev eq $branchpoint :
+ 0 && ($rev eq $head)) { # Don't think head is needed here..
+ print "File info $rev found for $filename\n" if ($verbose);
+ my @finfo = ($rev,$date,$log,$author,$filename);
+ my ($name);
+ ($name = $filename) =~ s%/.*%%;
+ $fileinfo{$name} = [ @finfo ];
+ $state = "done" if ($rev eq $revwanted);
+ }
+ $rev = undef;
+ $date = undef;
+ $log = "";
+ }
+ elsif (!defined($date) && m|^date:\s+(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+);|) {
+ my $yr = $1;
+ # damn 2-digit year routines :-)
+ if ($yr > 100) {
+ $yr -= 1900;
+ }
+ $date = &Time::Local::timegm($6,$5,$4,$3,$2 - 1,$yr);
+ ($author) = /author: ([^;]+)/;
+ $state = "log";
+ $log = '';
+ next;
+ }
+ elsif (!defined($rev) && m/^revision (.*)$/) {
+ $rev = $1;
+ next;
+ }
+ else {
+ $log = $log . $_;
+ }
+ }
+ if (/^===============/) {
+ $state = "start";
+ next;
+ }
+ }
+ if ($. == 0) {
+ fatal("500 Internal Error",
+ "Failed to spawn GNU rlog on <em>'$filenames'</em><p>did you set the <b>\$ENV{PATH}</b> in your configuration file correctly ?");
+ }
+ close($fh);
+}
+
+sub readLog {
+ my($fullname,$revision) = @_;
+ my ($symnames, $head, $rev, $br, $brp, $branch, $branchrev);
+ my $fh = do {local(*FH);};
+
+ if (defined($revision)) {
+ $revision = "-r$revision";
+ }
+ else {
+ $revision = "";
+ }
+
+ undef %symrev;
+ undef %revsym;
+ undef @allrevisions;
+ undef %date;
+ undef %author;
+ undef %state;
+ undef %difflines;
+ undef %log;
+
+ print("Going to rlog '$fullname'\n") if ($verbose);
+ open($fh, "rlog $revision '$fullname'|")
+ || &fatal("500 Internal Error", "Failed to spawn rlog");
+
+ while (<$fh>) {
+ print if ($verbose);
+ if ($symnames) {
+ if (/^\s+([^:]+):\s+([\d\.]+)/) {
+ $symrev{$1} = $2;
+ }
+ else {
+ $symnames = 0;
+ }
+ }
+ elsif (/^head:\s+([\d\.]+)/) {
+ $head = $1;
+ }
+ elsif (/^branch:\s+([\d\.]+)/) {
+ $curbranch = $1;
+ }
+ elsif (/^symbolic names/) {
+ $symnames = 1;
+ }
+ elsif (/^-----/) {
+ last;
+ }
+ }
+ ($curbranch = $head) =~ s/\.\d+$// if (!defined($curbranch));
+
+# each log entry is of the form:
+# ----------------------------
+# revision 3.7.1.1
+# date: 1995/11/29 22:15:52; author: fenner; state: Exp; lines: +5 -3
+# log info
+# ----------------------------
+ logentry:
+ while (!/^=========/) {
+ $_ = <$fh>;
+ last logentry if (!defined($_)); # EOF
+ print "R:", $_ if ($verbose);
+ if (/^revision ([\d\.]+)/) {
+ $rev = $1;
+ unshift(@allrevisions,$rev);
+ }
+ elsif (/^========/ || /^----------------------------$/) {
+ next logentry;
+ }
+ else {
+ # The rlog output is syntactically ambiguous. We must
+ # have guessed wrong about where the end of the last log
+ # message was.
+ # Since this is likely to happen when people put rlog output
+ # in their commit messages, don't even bother keeping
+ # these lines since we don't know what revision they go with
+ # any more.
+ next logentry;
+# &fatal("500 Internal Error","Error parsing RCS output: $_");
+ }
+ $_ = <$fh>;
+ print "D:", $_ if ($verbose);
+ if (m|^date:\s+(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+);\s+author:\s+(\S+);\s+state:\s+(\S+);\s+(lines:\s+([0-9\s+-]+))?|) {
+ my $yr = $1;
+ # damn 2-digit year routines :-)
+ if ($yr > 100) {
+ $yr -= 1900;
+ }
+ $date{$rev} = &Time::Local::timegm($6,$5,$4,$3,$2 - 1,$yr);
+ $author{$rev} = $7;
+ $state{$rev} = $8;
+ $difflines{$rev} = $10;
+ }
+ else {
+ &fatal("500 Internal Error", "Error parsing RCS output: $_");
+ }
+ line:
+ while (<$fh>) {
+ print "L:", $_ if ($verbose);
+ next line if (/^branches:\s/);
+ last line if (/^----------------------------$/ || /^=========/);
+ $log{$rev} .= $_;
+ }
+ print "E:", $_ if ($verbose);
+ }
+ close($fh);
+ print "Done reading RCS file\n" if ($verbose);
+
+ @revorder = reverse sort {revcmp($a,$b)} @allrevisions;
+ print "Done sorting revisions",join(" ",@revorder),"\n" if ($verbose);
+
+#
+# HEAD is an artificial tag which is simply the highest tag number on the main
+# branch, unless there is a branch tag in the RCS file in which case it's the
+# highest revision on that branch. Find it by looking through @revorder; it
+# is the first commit listed on the appropriate branch.
+# This is not neccesary the same revision as marked as head in the RCS file.
+ my $headrev = $curbranch || "1";
+ ($symrev{"MAIN"} = $headrev) =~ s/(\.?)(\d+)$/${1}0.$2/;
+ revision:
+ foreach $rev (@revorder) {
+ if ($rev =~ /^(\S*)\.\d+$/ && $headrev eq $1) {
+ $symrev{"HEAD"} = $rev;
+ last revision;
+ }
+ }
+ ($symrev{"HEAD"} = $headrev) =~ s/\.\d+$//
+ if (!defined($symrev{"HEAD"}));
+ print "Done finding HEAD\n" if ($verbose);
+#
+# Now that we know all of the revision numbers, we can associate
+# absolute revision numbers with all of the symbolic names, and
+# pass them to the form so that the same association doesn't have
+# to be built then.
+#
+ undef @branchnames;
+ undef %branchpoint;
+ undef $sel;
+
+ foreach (reverse sort keys %symrev) {
+ $rev = $symrev{$_};
+ if ($rev =~ /^((.*)\.)?\b0\.(\d+)$/) {
+ push(@branchnames, $_);
+ #
+ # A revision number of A.B.0.D really translates into
+ # "the highest current revision on branch A.B.D".
+ #
+ # If there is no branch A.B.D, then it translates into
+ # the head A.B .
+ #
+ # This reasoning also applies to the main branch A.B,
+ # with the branch number 0.A, with the exception that
+ # it has no head to translate to if there is nothing on
+ # the branch, but I guess this can never happen?
+ # (the code below gracefully forgets about the branch
+ # if it should happen)
+ #
+ $head = defined($2) ? $2 : "";
+ $branch = $3;
+ $branchrev = $head . ($head ne "" ? "." : "") . $branch;
+ my $regex;
+ ($regex = $branchrev) =~ s/\./\\./g;
+ $rev = $head;
+
+ revision:
+ foreach my $r (@revorder) {
+ if ($r =~ /^${regex}\b/) {
+ $rev = $branchrev;
+ last revision;
+ }
+ }
+ next if ($rev eq "");
+ if ($rev ne $head && $head ne "") {
+ $branchpoint{$head} .= ", " if ($branchpoint{$head});
+ $branchpoint{$head} .= $_;
+ }
+ }
+ $revsym{$rev} .= ", " if ($revsym{$rev});
+ $revsym{$rev} .= $_;
+ $sel .= "<OPTION VALUE=\"${rev}:${_}\">$_\n";
+ }
+ print "Done associating revisions with branches\n" if ($verbose);
+
+ my ($onlyonbranch, $onlybranchpoint);
+ if ($onlyonbranch = $input{'only_with_tag'}) {
+ $onlyonbranch = $symrev{$onlyonbranch};
+ if ($onlyonbranch =~ s/\b0\.//) {
+ ($onlybranchpoint = $onlyonbranch) =~ s/\.\d+$//;
+ }
+ else {
+ $onlybranchpoint = $onlyonbranch;
+ }
+ if (!defined($onlyonbranch) || $onlybranchpoint eq "") {
+ fatal("404 Tag not found","Tag $input{'only_with_tag'} not defined");
+ }
+ }
+
+ undef @revisions;
+
+ foreach (@allrevisions) {
+ ($br = $_) =~ s/\.\d+$//;
+ ($brp = $br) =~ s/\.\d+$//;
+ next if ($onlyonbranch && $br ne $onlyonbranch &&
+ $_ ne $onlybranchpoint);
+ unshift(@revisions,$_);
+ }
+
+ if ($logsort eq "date") {
+ # Sort the revisions in commit order an secondary sort on revision
+ # (secondary sort needed for imported sources, or the first main
+ # revision gets before the same revision on the 1.1.1 branch)
+ @revdisplayorder = sort {$date{$b} <=> $date{$a} || -revcmp($a, $b)} @revisions;
+ }
+ elsif ($logsort eq "rev") {
+ # Sort the revisions in revision order, highest first
+ @revdisplayorder = reverse sort {revcmp($a,$b)} @revisions;
+ }
+ else {
+ # No sorting. Present in the same order as rlog / cvs log
+ @revdisplayorder = @revisions;
+ }
+
+}
+
+sub printLog($;$) {
+ my ($link, $br, $brp);
+ ($_,$link) = @_;
+ ($br = $_) =~ s/\.\d+$//;
+ ($brp = $br) =~ s/\.?\d+$//;
+ my ($isDead, $prev);
+
+ $link = 1 if (!defined($link));
+ $isDead = ($state{$_} eq "dead");
+
+ if ($link && !$isDead) {
+ my ($filename);
+ ($filename = $where) =~ s/^.*\///;
+ my ($fileurl) = urlencode($filename);
+ print "<a NAME=\"rev$_\"></a>";
+ if (defined($revsym{$_})) {
+ foreach my $sym (split(", ", $revsym{$_})) {
+ print "<a NAME=\"$sym\"></a>";
+ }
+ }
+ if (defined($revsym{$br}) && $revsym{$br} && !defined($nameprinted{$br})) {
+ foreach my $sym (split(", ", $revsym{$br})) {
+ print "<a NAME=\"$sym\"></a>";
+ }
+ $nameprinted{$br} = 1;
+ }
+ print "\n Revision ";
+ &download_link($fileurl, $_, $_,
+ $defaultViewable ? "text/x-cvsweb-markup" : undef);
+ if ($defaultViewable) {
+ print " / ";
+ &download_link($fileurl, $_, "(download)", $mimetype);
+ }
+ if (not $defaultTextPlain) {
+ print " / ";
+ &download_link($fileurl, $_, "(as text)",
+ "text/plain");
+ }
+ if (!$defaultViewable) {
+ print " / ";
+ &download_link($fileurl, $_, "(view)", "text/x-cvsweb-markup");
+ }
+ if ($allow_annotate) {
+ print " - <a href=\"" . $scriptname . "/" . urlencode($where) . "?annotate=$_$barequery\">";
+ print "annotate</a>";
+ }
+ # Plus a select link if enabled, and this version isn't selected
+ if ($allow_version_select) {
+ if ((!defined($input{"r1"}) || $input{"r1"} ne $_)) {
+ print " - <A HREF=\"${scriptwhere}?r1=$_$barequery" .
+ "\">[select for diffs]</A>\n";
+ }
+ else {
+ print " - <b>[selected]</b>";
+ }
+ }
+ }
+ else {
+ print "Revision <B>$_</B>";
+ }
+ if (/^1\.1\.1\.\d+$/) {
+ print " <i>(vendor branch)</i>";
+ }
+ print ", <i>" . scalar gmtime($date{$_}) . " UTC</i> (";
+ print readableTime(time() - $date{$_},1) . " ago)";
+ print " by ";
+ print "<i>" . $author{$_} . "</i>\n";
+ print "<BR>Branch: <b>",$link?link_tags($revsym{$br}):$revsym{$br},"</b>\n"
+ if ($revsym{$br});
+ print "<BR>CVS Tags: <b>",$link?link_tags($revsym{$_}):$revsym{$_},"</b>"
+ if ($revsym{$_});
+ print "<BR>Branch point for: <b>",$link?link_tags($branchpoint{$_}):$branchpoint{$_},"</b>\n"
+ if ($branchpoint{$_});
+ # Find the previous revision
+ my @prevrev = split(/\./, $_);
+ do {
+ if (--$prevrev[$#prevrev] <= 0) {
+ # If it was X.Y.Z.1, just make it X.Y
+ pop(@prevrev);
+ pop(@prevrev);
+ }
+ $prev = join(".", @prevrev);
+ } until (defined($date{$prev}) || $prev eq "");
+ if ($prev ne "") {
+ if ($difflines{$_}) {
+ print "<BR>Changes since <b>$prev: $difflines{$_} lines</b>";
+ }
+ }
+ if ($isDead) {
+ print "<BR><B><I>FILE REMOVED</I></B>\n";
+ }
+ elsif ($link) {
+ my %diffrev = ();
+ $diffrev{$_} = 1;
+ $diffrev{""} = 1;
+ print "<BR>Diff";
+ #
+ # Offer diff to previous revision
+ if ($prev) {
+ $diffrev{$prev} = 1;
+ print " to previous <A HREF=\"${scriptwhere}.diff?r1=$prev";
+ print "&r2=$_" . $barequery . "\">$prev</A>\n";
+ if (!$hr_default) { # offer a human readable version if not default
+ print "(<A HREF=\"${scriptwhere}.diff?r1=$prev";
+ print "&r2=$_" . $barequery . "&f=h\">colored</A>)\n";
+ }
+ }
+ #
+ # Plus, if it's on a branch, and it's not a vendor branch,
+ # offer a diff with the branch point.
+ if ($revsym{$brp} && !/^1\.1\.1\.\d+$/ && !defined($diffrev{$brp})) {
+ print " to branchpoint <A HREF=\"${scriptwhere}.diff?r1=$brp";
+ print "&r2=$_" . $barequery . "\">$brp</A>\n";
+ if (!$hr_default) { # offer a human readable version if not default
+ print "(<A HREF=\"${scriptwhere}.diff?r1=$brp";
+ print "&r2=$_" . $barequery . "&f=h\">colored</A>)\n";
+ }
+ }
+ #
+ # Plus, if it's on a branch, and it's not a vendor branch,
+ # offer to diff with the next revision of the higher branch.
+ # (e.g. change gets committed and then brought
+ # over to -stable)
+ if (/^\d+\.\d+\.\d+/ && !/^1\.1\.1\.\d+$/) {
+ my ($i,$nextmain);
+ for ($i = 0; $i < $#revorder && $revorder[$i] ne $_; $i++){}
+ my (@tmp2) = split(/\./, $_);
+ for ($nextmain = ""; $i > 0; $i--) {
+ my ($next) = $revorder[$i-1];
+ my (@tmp1) = split(/\./, $next);
+ if ($#tmp1 < $#tmp2) {
+ $nextmain = $next;
+ last;
+ }
+ # Only the highest version on a branch should have
+ # a diff for the "next main".
+ last if (join(".",@tmp1[0..$#tmp1-1])
+ eq join(".",@tmp2[0..$#tmp1-1]));
+ }
+ if (!defined($diffrev{$nextmain})) {
+ $diffrev{$nextmain} = 1;
+ print " next main <A HREF=\"${scriptwhere}.diff?r1=$nextmain";
+ print "&r2=$_" . $barequery .
+ "\">$nextmain</A>\n";
+ if (!$hr_default) { # offer a human readable version if not default
+ print "(<A HREF=\"${scriptwhere}.diff?r1=$nextmain";
+ print "&r2=$_" . $barequery .
+ "&f=h\">colored</A>)\n";
+ }
+ }
+ }
+ # Plus if user has selected only r1, then present a link
+ # to make a diff to that revision
+ if (defined($input{"r1"}) && !defined($diffrev{$input{"r1"}})) {
+ $diffrev{$input{"r1"}} = 1;
+ print " to selected <A HREF=\"${scriptwhere}.diff?"
+ . "r1=$input{'r1'}&r2=$_" . $barequery
+ . "\">$input{'r1'}</A>\n";
+ if (!$hr_default) { # offer a human readable version if not default
+ print "(<A HREF=\"${scriptwhere}.diff?r1=$input{'r1'}";
+ print "&r2=$_" . $barequery .
+ "&f=h\">colored</A>)\n";
+
+ }
+ }
+ }
+ print "<PRE>\n";
+ print &htmlify($log{$_}, 1);
+ print "</PRE>\n";
+}
+
+sub doLog {
+ my($fullname) = @_;
+ my ($diffrev, $upwhere, $filename, $backurl);
+
+ readLog($fullname);
+
+ html_header("CVS log for $where");
+ ($upwhere = $where) =~ s|(Attic/)?[^/]+$||;
+ ($filename = $where) =~ s|^.*/||;
+ $backurl = $scriptname . "/" . urlencode($upwhere) . $query;
+ print &link($backicon, "$backurl#$filename"),
+ " <b>Up to ", &clickablePath($upwhere, 1), "</b><p>\n";
+ print "<A HREF=\"#diff\">Request diff between arbitrary revisions</A>\n";
+ print "$hr\n";
+ if ($curbranch) {
+ print "Default branch: ";
+ print ($revsym{$curbranch} || $curbranch);
+ }
+ else {
+ print "No default branch";
+ }
+ print "<BR>\n";
+ if ($input{only_with_tag}) {
+ print "Current tag: $input{only_with_tag}<BR>\n";
+ }
+
+ undef %nameprinted;
+
+ for (my $i = 0; $i <= $#revdisplayorder; $i++) {
+ print "$bighr";
+ printLog($revdisplayorder[$i]);
+ }
+
+ print "<A NAME=diff>\n";
+ print "$hr";
+ print "This form allows you to request diff's between any two\n";
+ print "revisions of a file. You may select a symbolic revision\n";
+ print "name using the selection box or you may type in a numeric\n";
+ print "name using the type-in text box.\n";
+ print "</A><P>\n";
+ print "<FORM METHOD=\"GET\" ACTION=\"${scriptwhere}.diff\" NAME=\"diff_select\">\n";
+ foreach (@stickyvars) {
+ print "<INPUT TYPE=HIDDEN NAME=\"$_\" VALUE=\"$input{$_}\">\n"
+ if (defined($input{$_})
+ && ($input{$_} ne $DEFAULTVALUE{$_} && $input{$_} ne ""));
+ }
+ print "Diffs between \n";
+ print "<SELECT NAME=\"r1\">\n";
+ print "<OPTION VALUE=\"text\" SELECTED>Use Text Field\n";
+ print $sel;
+ print "</SELECT>\n";
+ $diffrev = $revdisplayorder[$#revdisplayorder];
+ $diffrev = $input{"r1"} if (defined($input{"r1"}));
+ print "<INPUT TYPE=\"TEXT\" SIZE=\"$inputTextSize\" NAME=\"tr1\" VALUE=\"$diffrev\" onChange='document.diff_select.r1.selectedIndex=0'>\n";
+ print " and \n";
+ print "<SELECT NAME=\"r2\">\n";
+ print "<OPTION VALUE=\"text\" SELECTED>Use Text Field\n";
+ print $sel;
+ print "</SELECT>\n";
+ $diffrev = $revdisplayorder[0];
+ $diffrev = $input{"r2"} if (defined($input{"r2"}));
+ print "<INPUT TYPE=\"TEXT\" SIZE=\"$inputTextSize\" NAME=\"tr2\" VALUE=\"$diffrev\" onChange='docuement.diff_select.r2.selectedIndex=0'>\n";
+ print "<BR>Type of Diff should be a&nbsp;";
+ printDiffSelect();
+ print "<INPUT TYPE=SUBMIT VALUE=\" Get Diffs \">\n";
+ print "</FORM>\n";
+ print "$hr\n";
+ if (@branchnames) {
+ print "<A name=branch>\n";
+ print "<FORM METHOD=\"GET\" ACTION=\"$scriptwhere\">\n";
+ foreach (@stickyvars) {
+ next if ($_ eq "only_with_tag");
+ next if ($_ eq "logsort");
+ print "<INPUT TYPE=HIDDEN NAME=\"$_\" VALUE=\"$input{$_}\">\n"
+ if (defined($input{$_}) && $input{$_} ne $DEFAULTVALUE{$_}
+ && $input{$_} ne "");
+ }
+ print "View only Branch: \n";
+ print "<SELECT NAME=\"only_with_tag\"";
+ print " onchange=\"submit()\"" if ($use_java_script);
+ print ">\n";
+ print "<OPTION VALUE=\"\"";
+ print " SELECTED" if (defined($input{"only_with_tag"}) &&
+ $input{"only_with_tag"} eq "");
+ print ">Show all branches\n";
+ foreach (reverse sort @branchnames) {
+ print "<OPTION";
+ print " SELECTED" if (defined($input{"only_with_tag"})
+ && $input{"only_with_tag"} eq $_);
+ print ">${_}\n";
+ }
+ print "</SELECT>\n";
+ print "<INPUT TYPE=SUBMIT VALUE=\" View Branch \">\n";
+ print "</FORM>\n";
+ print "</A>\n";
+ }
+ print "<A name=logsort>\n";
+ print "<FORM METHOD=\"GET\" ACTION=\"$scriptwhere\">\n";
+ foreach (@stickyvars) {
+ next if ($_ eq "only_with_tag");
+ next if ($_ eq "logsort");
+ print "<INPUT TYPE=HIDDEN NAME=\"$_\" VALUE=\"$input{$_}\">\n"
+ if (defined($input{$_}) && $input{$_} ne $DEFAULTVALUE{$_}
+ && $input{$_} ne "");
+ }
+ print "Sort log by: \n";
+ print "<SELECT NAME=\"logsort\"";
+ print " onchange=\"submit()\"" if ($use_java_script);
+ print ">\n";
+ print "<OPTION VALUE=cvs",$logsort eq "cvs" ? " SELECTED" : "", ">Not sorted";
+ print "<OPTION VALUE=date",$logsort eq "date" ? " SELECTED" : "", ">Commit date";
+ print "<OPTION VALUE=rev",$logsort eq "rev" ? " SELECTED" : "", ">Revision";
+ print "</SELECT>\n";
+ print "<INPUT TYPE=SUBMIT VALUE=\" Sort \">\n";
+ print "</FORM>\n";
+ print "</A>";
+ print &html_footer;
+ print "</BODY></HTML>\n";
+}
+
+sub flush_diff_rows ($$$$)
+{
+ my $j;
+ my ($leftColRef,$rightColRef,$leftRow,$rightRow) = @_;
+ if ($state eq "PreChangeRemove") { # we just got remove-lines before
+ for ($j = 0 ; $j < $leftRow; $j++) {
+ print "<tr><td bgcolor=\"$diffcolorRemove\">@$leftColRef[$j]</td>";
+ print "<td bgcolor=\"$diffcolorEmpty\">&nbsp;</td></tr>\n";
+ }
+ }
+ elsif ($state eq "PreChange") { # state eq "PreChange"
+ # we got removes with subsequent adds
+ for ($j = 0; $j < $leftRow || $j < $rightRow ; $j++) { # dump out both cols
+ print "<tr>";
+ if ($j < $leftRow) {
+ print "<td bgcolor=\"$diffcolorChange\">@$leftColRef[$j]</td>";
+ }
+ else {
+ print "<td bgcolor=\"$diffcolorDarkChange\">&nbsp;</td>";
+ }
+ if ($j < $rightRow) {
+ print "<td bgcolor=\"$diffcolorChange\">@$rightColRef[$j]</td>";
+ }
+ else {
+ print "<td bgcolor=\"$diffcolorDarkChange\">&nbsp;</td>";
+ }
+ print "</tr>\n";
+ }
+ }
+}
+
+##
+# Function to generate Human readable diff-files
+# human_readable_diff(String revision_to_return_to);
+##
+sub human_readable_diff($){
+ my ($i,$difftxt, $where_nd, $filename, $pathname, $scriptwhere_nd);
+ my ($fh, $rev) = @_;
+ my ($date1, $date2, $r1d, $r2d, $r1r, $r2r, $rev1, $rev2, $sym1, $sym2);
+ my (@rightCol, @leftCol);
+
+ ($where_nd = $where) =~ s/.diff$//;
+ ($filename = $where_nd) =~ s/^.*\///;
+ ($pathname = $where_nd) =~ s/(Attic\/)?[^\/]*$//;
+ ($scriptwhere_nd = $scriptwhere) =~ s/.diff$//;
+
+ navigateHeader ($scriptwhere_nd, $pathname, $filename, $rev, "diff");
+
+ # Read header to pick up read revision and date, if possible
+ while (<$fh>) {
+ ($r1d,$r1r) = /\t(.*)\t(.*)$/ if (/^--- /);
+ ($r2d,$r2r) = /\t(.*)\t(.*)$/ if (/^\+\+\+ /);
+ last if (/^\+\+\+ /);
+ }
+ if (defined($r1r) && $r1r =~ /^(\d+\.)+\d+$/) {
+ $rev1 = $r1r;
+ $date1 = $r1d;
+ }
+ if (defined($r2r) && $r2r =~ /^(\d+\.)+\d+$/) {
+ $rev2 = $r2r;
+ $date2 = $r2d;
+ }
+
+ print "<h3 align=center>Diff for /$where_nd between version $rev1 and $rev2</h3>\n";
+
+ print "<table border=0 cellspacing=0 cellpadding=0 width=100%>\n";
+ print "<tr bgcolor=#ffffff>\n";
+ print "<th width=\"50%\" valign=TOP>";
+ print "version $rev1";
+ print ", $date1" if (defined($date1));
+ print "<br>Tag: $sym1\n" if ($sym1);
+ print "</th>\n";
+ print "<th width=\"50%\" valign=TOP>";
+ print "version $rev2";
+ print ", $date2" if (defined($date2));
+ print "<br>Tag: $sym2\n" if ($sym1);
+ print "</th>\n";
+
+ my $fs = "<font face=\"$difffontface\" size=\"$difffontsize\">";
+ my $fe = "</font>";
+
+ my $leftRow = 0;
+ my $rightRow = 0;
+ my ($oldline, $newline, $funname, $diffcode, $rest);
+
+ # Process diff text
+ # The diffrows are could make excellent use of
+ # cascading style sheets because we've to set the
+ # font and color for each row. anyone ...?
+ ####
+ while (<$fh>) {
+ $difftxt = $_;
+
+ if ($difftxt =~ /^@@/) {
+ ($oldline,$newline,$funname) = $difftxt =~ /@@ \-([0-9]+).*\+([0-9]+).*@@(.*)/;
+ print "<tr bgcolor=\"$diffcolorHeading\"><td width=\"50%\">";
+ print "<table width=100% border=1 cellpadding=5><tr><td><b>Line $oldline</b>";
+ print "&nbsp;<font size=-1>$funname</font></td></tr></table>";
+ print "</td><td width=\"50%\">";
+ print "<table width=100% border=1 cellpadding=5><tr><td><b>Line $newline</b>";
+ print "&nbsp;<font size=-1>$funname</font></td></tr></table>";
+ print "</td><tr>\n";
+ $state = "dump";
+ $leftRow = 0;
+ $rightRow = 0;
+ }
+ else {
+ ($diffcode,$rest) = $difftxt =~ /^([-+ ])(.*)/;
+ $_ = spacedHtmlText ($rest);
+
+ # Add fontface, size
+ $_ = "$fs&nbsp;$_$fe";
+
+ #########
+ # little state machine to parse unified-diff output (Hen, zeller@think.de)
+ # in order to get some nice 'ediff'-mode output
+ # states:
+ # "dump" - just dump the value
+ # "PreChangeRemove" - we began with '-' .. so this could be the start of a 'change' area or just remove
+ # "PreChange" - okey, we got several '-' lines and moved to '+' lines -> this is a change block
+ ##########
+
+ if ($diffcode eq '+') {
+ if ($state eq "dump") { # 'change' never begins with '+': just dump out value
+ print "<tr><td bgcolor=\"$diffcolorEmpty\">&nbsp;</td><td bgcolor=\"$diffcolorAdd\">$_</td></tr>\n";
+ }
+ else { # we got minus before
+ $state = "PreChange";
+ $rightCol[$rightRow++] = $_;
+ }
+ }
+ elsif ($diffcode eq '-') {
+ $state = "PreChangeRemove";
+ $leftCol[$leftRow++] = $_;
+ }
+ else { # empty diffcode
+ flush_diff_rows \@leftCol, \@rightCol, $leftRow, $rightRow;
+ print "<tr><td>$_</td><td>$_</td></tr>\n";
+ $state = "dump";
+ $leftRow = 0;
+ $rightRow = 0;
+ }
+ }
+ }
+ flush_diff_rows \@leftCol, \@rightCol, $leftRow, $rightRow;
+
+ # state is empty if we didn't have any change
+ if (!$state) {
+ print "<tr><td colspan=2>&nbsp;</td></tr>";
+ print "<tr bgcolor=\"$diffcolorEmpty\" >";
+ print "<td colspan=2 align=center><b>- No viewable Change -</b></td></tr>";
+ }
+ print "</table>";
+ close($fh);
+
+ print "<br>$widehr\n";
+
+ print "<table border=0>";
+
+ print "<tr><td>";
+ # print legend
+ print "<table border=1><tr><td>";
+ print "Legend:<br><table border=0 cellspacing=0 cellpadding=1>\n";
+ print "<tr><td align=center bgcolor=\"$diffcolorRemove\">Removed from v.$rev1</td><td bgcolor=\"$diffcolorEmpty\">&nbsp;</td></tr>";
+ print "<tr bgcolor=\"$diffcolorChange\"><td align=center colspan=2>changed lines</td></tr>";
+ print "<tr><td bgcolor=\"$diffcolorEmpty\">&nbsp;</td><td align=center bgcolor=\"$diffcolorAdd\">Added in v.$rev2</td></tr>";
+ print "</table></td></tr></table>\n";
+ print "</body>\n</html>\n";
+
+ print "<td>";
+ # Print format selector
+ print "<FORM METHOD=\"GET\" ACTION=\"${scriptwhere}\">\n";
+ foreach my $var (keys %input) {
+ next if ($var eq "f");
+ next if (defined($DEFAULTVALUE{$var})
+ && $DEFAULTVALUE{$var} eq $input{$var});
+ print "<INPUT TYPE=HIDDEN NAME=\"",urlencode($var),"\" VALUE=\"",
+ urlencode($input{$var}),"\">\n";
+ }
+ printDiffSelect($use_java_script);
+ print "<INPUT TYPE=SUBMIT VALUE=\"Show\">\n";
+ print "</FORM>\n";
+ print "</td>";
+
+ print "</tr></table>";
+}
+
+sub navigateHeader ($$$$$) {
+ my ($swhere,$path,$filename,$rev,$title) = @_;
+ $swhere = "" if ($swhere eq $scriptwhere);
+ $swhere = urlencode($filename) if ($swhere eq "");
+ print "<HTML>\n<HEAD>\n";
+ print '<!-- hennerik CVSweb $Revision$ -->';
+ print "\n<TITLE>$path$filename - $title - $rev</TITLE>";
+ print $stylesheet if ($stylesheet);
+ print "</HEAD>\n";
+ print "<BODY BGCOLOR=\"$backcolor\">\n";
+ print "<table width=\"100%\" border=0 cellspacing=0 cellpadding=1 bgcolor=\"$navigationHeaderColor\">";
+ print "<tr valign=bottom><td>";
+ print "<a href=\"$swhere$query#rev$rev\">$backicon";
+ print "</a> <b>Return to ", &link("$filename","$swhere$query#rev$rev")," CVS log";
+ print "</b> $fileicon</td>";
+
+ print "<td align=right>$diricon <b>Up to ", &clickablePath($path, 1), "</b></td>";
+ print "</tr></table>";
+}
+
+sub plural_write ($$)
+{
+ my ($num,$text) = @_;
+ if ($num != 1) {
+ $text = $text . "s";
+ }
+ if ($num > 0) {
+ return $num . " " . $text;
+ }
+ else {
+ return "";
+ }
+}
+
+##
+# print readable timestamp in terms of
+# '..time ago'
+# H. Zeller <zeller@think.de>
+##
+sub readableTime ($$)
+{
+ my ($i, $break, $retval);
+ my ($secs,$long) = @_;
+
+ # this function works correct for time >= 2 seconds
+ if ($secs < 2) {
+ return "very little time";
+ }
+
+ my %desc = (1 , 'second',
+ 60, 'minute',
+ 3600, 'hour',
+ 86400, 'day',
+ 604800, 'week',
+ 2628000, 'month',
+ 31536000, 'year');
+ my @breaks = sort {$a <=> $b} keys %desc;
+ $i = 0;
+ while ($i <= $#breaks && $secs >= 2 * $breaks[$i]) {
+ $i++;
+ }
+ $i--;
+ $break = $breaks[$i];
+ $retval = plural_write(int ($secs / $break), $desc{"$break"});
+
+ if ($long == 1 && $i > 0) {
+ my $rest = $secs % $break;
+ $i--;
+ $break = $breaks[$i];
+ my $resttime = plural_write(int ($rest / $break),
+ $desc{"$break"});
+ if ($resttime) {
+ $retval = $retval . ", " . $resttime;
+ }
+ }
+
+ return $retval;
+}
+
+##
+# clickablePath(String pathname, boolean last_item_clickable)
+#
+# returns a html-ified path whereas each directory is a link for
+# faster navigation. last_item_clickable controls whether the
+# basename (last directory/file) is a link as well
+##
+sub clickablePath($$) {
+ my ($pathname,$clickLast) = @_;
+ my $retval = '';
+
+ if ($pathname eq '/') {
+ # this should never happen - chooseCVSRoot() is
+ # intended to do this
+ $retval = "[$cvstree]";
+ }
+ else {
+ $retval = $retval . " <a href=\"${scriptname}/${query}#dirlist\">[$cvstree]</a>";
+ my $wherepath = '';
+ my ($lastslash) = $pathname =~ m|/$|;
+ foreach (split(/\//, $pathname)) {
+ $retval = $retval . " / ";
+ $wherepath = $wherepath . '/' . $_;
+ my ($last) = "$wherepath/" eq "/$pathname"
+ || "$wherepath" eq "/$pathname";
+ if ($clickLast || !$last) {
+ $retval = $retval . "<a href=\"${scriptname}"
+ . urlencode($wherepath)
+ . (!$last || $lastslash ? '/' : '')
+ . ${query}
+ . (!$last || $lastslash ? "#dirlist" : "")
+ . "\">$_</a>";
+ }
+ else { # do not make a link to the current dir
+ $retval = $retval . $_;
+ }
+ }
+ }
+ return $retval;
+}
+
+sub chooseCVSRoot() {
+ my @foo;
+ foreach (sort keys %CVSROOT) {
+ if (-d $CVSROOT{$_}) {
+ push(@foo, $_);
+ }
+ }
+ if (@foo > 1) {
+ my ($k);
+ print "<form method=\"GET\" action=\"${scriptwhere}\">\n";
+ foreach $k (keys %input) {
+ print "<input type=hidden NAME=$k VALUE=$input{$k}>\n"
+ if ($input{$k}) && ($k ne "cvsroot");
+ }
+ # Form-Elements look wierd in Netscape if the background
+ # isn't gray and the form elements are not placed
+ # within a table ...
+ print "<table><tr>";
+ print "<td>CVS Root:</td>";
+ print "<td>\n<select name=\"cvsroot\"";
+ print " onchange=\"submit()\"" if ($use_java_script);
+ print ">\n";
+ foreach $k (@foo) {
+ print "<option value=\"$k\"";
+ print " selected" if ("$k" eq "$cvstree");
+ print ">" . ($CVSROOTdescr{"$k"} ? $CVSROOTdescr{"$k"} :
+ $k). "</option>\n";
+ }
+ print "</select>\n</td>";
+ print "<td><input type=submit value=\"Go\"></td>";
+ print "</tr></table></form>";
+ }
+ else {
+ # no choice ..
+ print "CVS Root: <b>[$cvstree]</b>";
+ }
+}
+
+sub chooseMirror() {
+ my ($mirror,$moremirrors);
+ $moremirrors = 0;
+ # This code comes from the original BSD-cvsweb
+ # and may not be useful for your site; If you don't
+ # set %MIRRORS this won't show up, anyway
+ #
+ # Should perhaps exlude the current site somehow..
+ if (keys %MIRRORS) {
+ print "\nThis cvsweb is mirrored in:\n";
+ foreach $mirror (keys %MIRRORS) {
+ print ", " if ($moremirrors);
+ print qq(<a href="$MIRRORS{$mirror}">$mirror</A>\n);
+ $moremirrors = 1;
+ }
+ print "<p>\n";
+ }
+}
+
+sub fileSortCmp {
+ my ($comp) = 0;
+ my ($c,$d,$af,$bf);
+
+ ($af = $a) =~ s/,v$//;
+ ($bf = $b) =~ s/,v$//;
+ my ($rev1,$date1,$log1,$author1,$filename1) = @{$fileinfo{$af}}
+ if (defined($fileinfo{$af}));
+ my ($rev2,$date2,$log2,$author2,$filename2) = @{$fileinfo{$bf}}
+ if (defined($fileinfo{$bf}));
+
+ if (defined($filename1) && defined($filename2) && $af eq $filename1 && $bf eq $filename2) {
+ # Two files
+ $comp = -revcmp($rev1, $rev2) if ($byrev && $rev1 && $rev2);
+ $comp = ($date2 <=> $date1) if ($bydate && $date1 && $date2);
+ $comp = ($log1 cmp $log2) if ($bylog && $log1 && $log2);
+ $comp = ($author1 cmp $author2) if ($byauthor && $author1 && $author2);
+ }
+ if ($comp == 0) {
+ # Directories first, then sorted on name if no other sort critera
+ # available.
+ my $ad = ((-d "$fullname/$a")?"D":"F");
+ my $bd = ((-d "$fullname/$b")?"D":"F");
+ ($c=$a) =~ s|.*/||;
+ ($d=$b) =~ s|.*/||;
+ $comp = ("$ad$c" cmp "$bd$d");
+ }
+ return $comp;
+}
+
+# make A url for downloading
+sub download_url {
+ my ($url,$revision,$mimetype) = @_;
+
+ $revision =~ s/\b0\.//;
+
+ if (defined($checkout_magic)
+ && (!defined($mimetype) || $mimetype ne "text/x-cvsweb-markup")) {
+ my ($path);
+ ($path = $where) =~ s|/[^/]*$|/|;
+ $url = "$scriptname/$checkoutMagic/${path}$url";
+ }
+ $url .= "?rev=$revision";
+ $url .= "&content-type=$mimetype" if (defined($mimetype));
+
+ return $url;
+}
+
+# Presents a link to download the
+# selected revision
+sub download_link {
+ my ($url,$revision,$textlink,$mimetype) = @_;
+ my ($fullurl) = download_url($url,$revision,$mimetype);
+ my ($paren) = $textlink =~ /^\(/;
+ $textlink =~ s/^\(// if ($paren);
+ $textlink =~ s/\)$// if ($paren);
+ print "(" if ($paren);
+ print "<A HREF=\"$fullurl";
+ print $barequery;
+ print "\"";
+ if ($open_extern_window && (!defined($mimetype) || $mimetype ne "text/x-cvsweb-markup")) {
+ print " target=\"cvs_checkout\"";
+ # we should have
+ # 'if (document.cvswin==null) document.cvswin=window.open(...'
+ # in order to allow the user to resize the window; otherwise
+ # the user may resize the window, but on next checkout - zap -
+ # its original (configured s. cvsweb.conf) size is back again
+ # .. annoying (if $extern_window_(width|height) is defined)
+ # but this if (..) solution is far from perfect
+ # what we need to do as well is
+ # 1) save cvswin in an invisible frame that always exists
+ # (document.cvswin will be void on next load)
+ # 2) on close of the cvs_checkout - window set the cvswin
+ # variable to 'null' again - so that it will be
+ # reopenend with the configured size
+ # anyone a JavaScript programmer ?
+ # .. so here without if (..):
+ # currently, the best way is to comment out the size parameters
+ # ($extern_window...) in cvsweb.conf.
+ if ($use_java_script) {
+ print " onClick=\"window.open('$fullurl','cvs_checkout',";
+ print "'resizeable,scrollbars";
+ print ",status,toolbar" if (defined($mimetype)
+ && $mimetype eq "text/html");
+ print ",width=$extern_window_width" if (defined($extern_window_width));
+ print ",height=$extern_window_height" if (defined($extern_window_height));
+ print"');\"";
+ }
+ }
+ print "><b>$textlink</b></A>";
+ print ")" if ($paren);
+}
+
+# Returns a Query string with the
+# specified parameter toggled
+sub toggleQuery($$) {
+ my ($toggle,$value) = @_;
+ my ($newquery,$var);
+ my (%vars);
+ %vars = %input;
+ if (defined($value)) {
+ $vars{$toggle} = $value;
+ }
+ else {
+ $vars{$toggle} = $vars{$toggle} ? 0 : 1;
+ }
+ # Build a new query of non-default paramenters
+ $newquery = "";
+ foreach $var (@stickyvars) {
+ my ($value) = defined($vars{$var}) ? $vars{$var} : "";
+ my ($default) = defined($DEFAULTVALUE{$var}) ? $DEFAULTVALUE{$var} : "";
+ if ($value ne $default) {
+ $newquery .= "&" if ($newquery ne "");
+ $newquery .= urlencode($var) . "=" . urlencode($value);
+ }
+ }
+ if ($newquery) {
+ return '?' . $newquery;
+ }
+ return "";
+}
+
+sub urlencode {
+ my ($in) = @_;
+ my ($out);
+ ($out = $in) =~ s/([\000-+{-\377])/sprintf("%%%02x", ord($1))/ge;
+ return $out;
+}
+
+sub http_header {
+ my $content_type = shift || "text/html";
+ my $is_mod_perl = defined($ENV{'MOD_PERL'});
+ if (defined($moddate)) {
+ if ($is_mod_perl) {
+ Apache->request->header_out(Last_modified => scalar gmtime($moddate) . " GMT");
+ }
+ else {
+ print "Last-Modified: " . scalar gmtime($moddate) . " GMT\n";
+ }
+ }
+ if ($is_mod_perl) {
+ Apache->request->content_type($content_type);
+ }
+ else {
+ print "Content-type: $content_type\n";
+ }
+ if ($allow_compress && $maycompress) {
+ my $fh = do {local(*FH);};
+ if (defined($GZIPBIN) && open($fh, "|$GZIPBIN -1 -c")) {
+ if ($is_mod_perl) {
+ Apache->request->content_encoding("x-gzip");
+ Apache->request->header_out(Vary => "Accept-Encoding");
+ Apache->request->send_http_header;
+ }
+ else {
+ print "Content-encoding: x-gzip\n";
+ print "Vary: Accept-Encoding\n"; #RFC 2068, 14.43
+ print "\n"; # Close headers
+ }
+ $| = 1; $| = 0; # Flush header output
+ select ($fh);
+# print "<!-- gzipped -->" if ($content_type eq "text/html");
+ }
+ else {
+ if ($is_mod_perl) {
+ Apache->request->send_http_header;
+ }
+ else {
+ print "\n"; # Close headers
+ }
+ print "<font size=-1>Unable to find gzip binary in the \$PATH to compress output</font><br>";
+ }
+ }
+ else {
+ if ($is_mod_perl) {
+ Apache->request->send_http_header;
+ }
+ else {
+ print "\n"; # Close headers
+ }
+ }
+}
+
+sub html_header($) {
+ my ($title) = @_;
+ http_header();
+ print <<EOH;
+<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN"
+ "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+<title>$title</title>
+<!-- hennerik CVSweb \$Revision$ \-->
+EOH
+print $stylesheet if ($stylesheet);
+print <<EOH;
+</head>
+$body_tag
+$logo <h1 align="center">$title</h1>
+EOH
+}
+
+sub html_footer {
+ return "$hr$footer\n";
+}
+
+sub link_tags
+{
+ my ($tags) = @_;
+ my ($ret) = "";
+ my ($fileurl,$filename);
+
+ ($filename = $where) =~ s/^.*\///;
+ $fileurl = urlencode($filename);
+
+ foreach my $sym (split(", ", $tags)) {
+ $ret .= ",\n" if ($ret ne "");
+ $ret .= "<A HREF=\"$fileurl"
+ . toggleQuery('only_with_tag',$sym) . "\">$sym</A>";
+ }
+ return $ret."\n";
+}
+
+#
+# See if a module is listed in the config file's @HideModule list.
+#
+sub forbidden_module {
+ my($module) = @_;
+
+ return ($HideModules =~ /§$module§/);
+}
diff --git a/html/cvsweb.conf b/html/cvsweb.conf
new file mode 100644
index 00000000..73de6277
--- /dev/null
+++ b/html/cvsweb.conf
@@ -0,0 +1,350 @@
+# -*-perl-*-
+# Configuration of cvsweb.cgi, the
+# CGI interface to CVS Repositories.
+#
+# (c) 1998-1999 H. Zeller <zeller@think.de>
+# 1999 H. Nordström <hno@hem.passagen.se>
+# based on work by Bill Fenner <fenner@freebsd.org>
+# $Id$
+#
+###
+
+##############
+# CVS Root
+##############
+# CVSweb can handle several CVS-Repositories
+# at once. Enter a short symbolic names and the
+# full path of these repositories here.
+# NOTE that the symbolic names may not contain
+# whitespaces.
+# Note, that cvsweb.cgi currently needs to have physical access
+# to the CVS repository so :pserver:someone@xyz.com:/data/cvsroot
+# won't work!
+
+# 'symbolic_name' 'path_to_the_actual_repository'
+%CVSROOT = (
+ 'ProofGeneral' => '/home/proofgen/cvsmirror/src'
+ );
+
+# This tree is enabled by default when
+# you enter the page
+$cvstreedefault = 'ProofGeneral';
+
+##############
+# Defaults for UserSettings
+##############
+%DEFAULTVALUE = (
+ # sortby: File sort order
+ # file Sort by filename
+ # rev Sort by revision number
+ # date Sort by commit date
+ # author Sort by author
+ # log Sort by log message
+
+ "sortby" => "file",
+
+ # hideattic: Hide or show files in Attic
+ # 1 Hide files in Attic
+ # 0 Show files in Attic
+
+ "hideattic" => "1",
+
+ # logsort: Sort order for CVS logs
+ # date Sort revisions by date
+ # rev Sort revision by revision number
+ # cvs Don't sort them. Same order as CVS/RCS shows them.
+
+ "logsort" => "date",
+
+ # f: Default diff format
+ # h Human readable
+ # u Unified diff
+ # c Context diff
+ # s Side by side
+ "f" => "h",
+
+ # hidecvsroot: Don't show the CVSROOT directory
+ # 1 Hide CVSROOT directory
+ # 0 Show CVSROOT directory
+ "hidecvsroot" => "0",
+
+ # hidenonreadable: Don't show entries which cannot be read
+ # 1 Hide non-readable entries
+ # 0 Show non-readble entries
+ "hidenonreadable" => "1",
+);
+
+##############
+# some layout stuff
+##############
+
+$stylesheet = '<link rel="stylesheet"
+ href="http://www.proofgeneral.org/proofgen.css"
+ type="text/css">';
+
+
+# color settings in the body-tag
+# $body_tag = '<body text="#000000" bgcolor="#ffffff">';
+$body_tag = '<body>';
+
+# Wanna have a logo on the page ?
+$logo = '<a href="http://www.proofgeneral.org">
+ <img src="http://www.proofgeneral.org/images/ProofGeneral.jpg" alt="Proof General" align=top
+ width=65 height=76 border=0 ></a>';
+
+
+# The title of the Page on startup
+$defaulttitle = "Proof General CVS Repository";
+
+# This message is shown on the footer
+$footer = '<small>
+<i>Contact <a href="http://www.proofgeneral.org/~da/">David Aspinall</a>
+for information about Proof General development.
+<br>
+This page was generated by
+<a href="http://linux.fh-heilbronn.de/~zeller/cgi/cvsweb.cgi">CVSweb</a>.
+</i>
+</small>';
+
+# Default page background color for the diffs
+# and annotations
+$backcolor = "#222222";
+
+# color of navigation Header for
+# diffs and annotations
+$navigationHeaderColor = '#AAAA66';
+
+$long_intro = <<EOT;
+<p>
+This is a WWW interface to the Proof General CVS Repository.
+You can browse the file hierarchy by picking directories
+(which have slashes after them, <i>e.g.</i>, <b>src/</b>).
+If you pick a file, you will see the revision history
+for that file.
+Selecting a revision number will download that revision of
+the file. There is a link at each revision to display
+diffs between that revision and the previous one, and
+a form at the bottom of the page that allows you to
+display diffs between arbitrary revisions.
+</p>
+EOT
+
+$short_instruction = <<EOT;
+<p>
+Click on a directory to enter that directory. Click on a file to display
+its revision history and to get a chance to display diffs between revisions.
+</p>
+EOT
+
+# used icons; if icon-url is empty, the text representation is used; if
+# you do not want to have an ugly tooltip for the icon, remove the
+# text-representation.
+# The width and height of the icon allow the browser to correcly display
+# the table while still loading the icons.
+# These default icons are coming with apache.
+# If these icons are too large, check out the miniicons in the
+# icons/ directory; they have a width/height of 16/16
+# format: TEXT ICON-URL width height
+%ICONS = (
+ back => [ ("[BACK]", "/icons/back.gif", 20, 22) ],
+ dir => [ ("[DIR]", "/icons/dir.gif", 20, 22) ],
+ file => [ ("[TXT]", "/icons/text.gif", 20, 22) ],
+ );
+
+# the length to which the last logentry should
+# be truncated when shown in the directory view
+$shortLogLen = 80;
+
+# Show author of last change
+$show_author = 1;
+
+##############
+# table view for directories
+##############
+
+# Show directory as table
+# this is much more readable but has one
+# drawback: the whole table has to be loaded
+# before common browsers display it which may
+# be annoying if you have a slow link - and a
+# large directory ..
+$dirtable = 1;
+
+# show different colors for even/odd rows
+@tabcolors = ('#664433', '#663344');
+$tablepadding = 2;
+
+# Color of Header
+$columnHeaderColorDefault = '#333333';
+$columnHeaderColorSorted = '#880088';
+
+#
+# If you want to have colored borders
+# around each row, uncomment this
+$tableBorderColor = '#999999';
+
+#
+# Modules in the repository that should not be displayed, either by default
+# nor by explicit path specification.
+#
+@HideModules = (
+ );
+
+##############
+# Human Readable Diff
+##############
+
+# (c) 1998 H. Zeller <zeller@think.de>
+#
+# Generates two columns of color encoded
+# diff; much like xdiff or emacs-ediff mode.
+#
+# The diff-stuff is a piece of code I once made for
+# cvs2html which is under GPL,
+# see http://www.sslug.dk/cvs2html
+# (c) 1997/98 Peter Toft <pto@sslug.imm.dtu.dk>
+#
+# some parameters to screw:
+##
+
+# make lines breakable so that the columns do not
+# exceed the width of the browser
+$hr_breakable = 1;
+
+# give out function names in human readable diffs
+# this just makes sense if we have C-files, otherwise
+# diff's heuristic doesn't work well ..
+# ( '-p' option to diff)
+$hr_funout = 0;
+
+# ignore whitespaces for human readable diffs
+# (indendation and stuff ..)
+# ( '-w' option to diff)
+$hr_ignwhite = 1;
+
+# ignore diffs which are caused by
+# keyword-substitution like $Id - Stuff
+# ( '-kk' option to rcsdiff)
+$hr_ignkeysubst = 1;
+
+# Colors and font to show the diff type of code changes
+$diffcolorHeading = '#99cccc'; # color of 'Line'-head of each diffed file
+$diffcolorEmpty = '#cccccc'; # color of 'empty' lines
+$diffcolorRemove = '#ff9999'; # Removed line(s) (left) ( - )
+$diffcolorChange = '#99ff99'; # Changed line(s) ( both )
+$diffcolorAdd = '#ccccff'; # Added line(s) ( - ) (right)
+$diffcolorDarkChange = '#99cc99'; # lines, which are empty in change
+$difffontface = "Helvetica,Arial";
+$difffontsize = "-1";
+
+# the width of the textinput of the
+# request-diff-form
+$inputTextSize = 12;
+
+##############
+# Mime Types
+##############
+
+# mapping to mimetypes to help
+# cvsweb to guess the correct mime-type on
+# checkout; you can use the mime.types from
+# apache here:
+$mime_types = '/etc/httpd/conf/mime.types';
+
+# quick mime-type lookup; maps file-suffices to
+# mime-types for displaying checkouts in the browser.
+# Further MimeTypes will be found in the
+# file $mime_types (apache style mime.types - file)
+# - add common mappings here for faster lookup
+%MTYPES = (
+ "html" => "text/html",
+ "shtml" => "text/html",
+ "gif" => "image/gif",
+ "jpeg" => "image/jpeg",
+ "jpg" => "image/jpeg",
+ "*" => "text/plain",
+ );
+
+##############
+# Misc
+##############
+# allow annotation of files
+# this requires rw-access to the
+# CVSROOT/history - file and rw-access
+# to the subdirectory to place the lock
+# so you maybe don't want it
+$allow_annotate = 1;
+
+# allow pretty-printed version of files
+$allow_markup = 1;
+
+# allow compression with gzip
+# of output if the Browser accepts
+# it (HTTP_ACCEPT_ENCODING=gzip)
+# [make sure to have gzip in the path]
+$allow_compress = 1;
+
+# Make use of javascript functions.
+# This way you can select one of your CVSroot
+# without pressing 'Go' (.. if you do have more
+# than one CVSROOT defined)
+$use_java_script = 1;
+
+# open Download-Links in another window
+$open_extern_window = 1;
+
+# The size of this extern window; this size option
+# needs use_java_script to be defined
+# just comment them if you don't want to have a fixed
+# size
+#$extern_window_width = 600;
+#$extern_window_height = 440;
+
+# Edit Options
+# Enable form to edit your options (hideattic,sortbydate)
+# this isn't necessary if you've $dirtable defined 'cause
+# this allows editing of all your options more intuitive
+$edit_option_form = (not $dirtable);
+
+# remember to set the path to your
+# rcsutils: rlog, rcsdiff (gzip if you use compression)
+#$ENV{'PATH'} = '/usr/local/bin';
+
+# If you have files which automatically refers to other files
+# (such as HTML) then this allows you to browse the checked
+# out files as if outside CVS.
+$checkout_magic = 1;
+
+# Show last changelog message for sub directories
+# The current implementation makes many assumptions and may show the
+# incorrect file at some times. The main assumption is that the last
+# modified file has the newest filedate. But some CVS operations
+# touches the file without even when a new version is't checked in,
+# and TAG based browsing essientially puts this out of order, unless
+# the last checkin was on the same tag as you are viewing.
+# Enable this if you like the feature, but don't rely on correct results.
+$show_subdir_lastmod = 0;
+
+# Background color of logentry in markup
+$markupLogColor = "#ffffff";
+
+# Show CVS log when viewing file contents
+$show_log_in_markup = 1;
+
+# Tabstop used to expand tabs in colored diffs. If undefined then
+# tabs are always expanded to 8 spaces.
+$tabstop = 8;
+
+# Horizontal rules (added by da@dcs.ed.ac.uk)
+
+# defaults:
+# $hr="<hr noshade>";
+# $bighr="<hr noshade size=1>";
+# $widehr="<hr noshade width=100%>";
+
+$hr = '<img border=0 src="http://www.proofgeneral.org/images/silverrule.gif" height=4 width=100%>';
+$bighr = '<img border=0 src="http://www.proofgeneral.org/images/silverrule.gif" height=8 width=100%>';
+$widehr = '<img border=0 src="http://www.proofgeneral.org/images/silverrule.gif" height=4 width=100%>';
+
+
+#EOF
diff --git a/html/devel b/html/devel
new file mode 100644
index 00000000..a58717d8
--- /dev/null
+++ b/html/devel
@@ -0,0 +1,5 @@
+<?php include('index.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?> \ No newline at end of file
diff --git a/html/devel.html b/html/devel.html
new file mode 100644
index 00000000..a008a96d
--- /dev/null
+++ b/html/devel.html
@@ -0,0 +1,109 @@
+<h2>Development Information</h2>
+<p>
+Proof General follows an open development method.
+<br>
+We welcome code contributions, suggestions, and bug reports, from all
+users and hackers!
+</p>
+
+<ul>
+<li>
+Read about ideas for the <a href="kit">Proof General Kit</a>
+here.
+</li>
+</ul>
+<ul>
+<li>
+Download the latest <a href="develdownload.html">development release:
+<!-- WARNING! Line below automatically edited by makefile. -->
+ <b>ProofGeneral-3.4pre020214</b></a>
+<!-- end WARNING -->
+<br>
+or <a href="ProofGeneral">browse</a> the development distribution.
+ <br>
+Check the
+<!-- WARNING! Line below automatically edited by makefile. -->
+<?php fileshow("ProofGeneral-3.4pre020214/CHANGES","CHANGES"); ?> file
+<!-- End Warning. -->
+for a summary of changes since the last stable version.
+</li>
+</ul>
+<ul>
+<li>
+Browse a mirror of the <a href="http://www.proofgeneral.org/cgi-bin/cvsweb.cgi">Proof General CVS repository</a>. <br>
+<i>Note:</i> this mirror is updated nightly, so it may be
+slightly out of date.<br>
+</li>
+<li>
+If you want to be an "official" developer and
+access the real CVS repository,
+<a href="feedback.html">ask here</a>.
+</li>
+</ul>
+<ul>
+<li>
+Get involved!
+Take a look at the Proof General <a href="projects.html">project proposals</a>.
+</li>
+</ul>
+<ul>
+<li>
+Read the
+developer's
+<?php fileshow("ProofGeneral-3.4pre020214/README.devel","README file"); ?>,
+with development hints and tips.
+</li>
+</ul>
+<ul>
+<li>
+Read the brief list of planned
+<?php fileshow("ProofGeneral-3.4pre020214/TODO","things to do "); ?>
+for Proof General.
+</ul>
+<ul>
+<li>
+<a name="lowleveltodo">See our current low-level lists of things to do</a>,
+for the
+<!-- WARNING! Lines below automatically edited by makefile. -->
+ <?php fileshow("ProofGeneral-3.4pre020214/todo","generic base"); ?>,
+ <br>
+ and for each prover:
+ <?php fileshow("ProofGeneral-3.4pre020214/lego/todo","lego to do"); ?>,
+ <?php fileshow("ProofGeneral-3.4pre020214/coq/todo","coq to do"); ?>,
+ <?php fileshow("ProofGeneral-3.4pre020214/isa/todo","isa to do"); ?>,
+ <?php fileshow("ProofGeneral-3.4pre020214/isar/todo","isar to do"); ?>,
+ <?php fileshow("ProofGeneral-3.4pre020214/hol98/todo","hol to do"); ?>.
+<!-- end WARNING -->
+</li>
+</ul>
+<!-- <ul> -->
+<!-- <li> -->
+<!-- Browse source files from the current pre-release: -->
+<!-- <?php fileshow("ProofGeneral-3.4pre020214/generic/proof.el") ?>, -->
+<!-- <?php fileshow("ProofGeneral-3.4pre020214/generic/proof-site.el") ?>, -->
+<!-- <?php fileshow("ProofGeneral-3.4pre020214/generic/proof-config.el") ?>, -->
+<!-- <?php fileshow("ProofGeneral-3.4pre020214/generic/proof-script.el") ?>, -->
+<!-- <?php fileshow("ProofGeneral-3.4pre020214/generic/proof-shell.el") ?>, -->
+<!-- <?php fileshow("ProofGeneral-3.4pre020214/generic/proof-toolbar.el") ?>, -->
+<!-- <?php fileshow("ProofGeneral-3.4pre020214/generic/proof-syntax.el") ?>, -->
+<!-- <?php fileshow("ProofGeneral-3.4pre020214/generic/proof-splash.el") ?>, -->
+<!-- <?php fileshow("ProofGeneral-3.4pre020214/generic/proof-easy-config.el") ?>. -->
+<!-- </ul> -->
+<ul>
+<li>
+<?php hlink("feedback.html","Send us a message ","Feedback form")?>
+about any development issues.
+</li>
+</ul>
+
+<h2><a name="develmail">Developers Mailing List</a></h2>
+
+<p>
+We have a mailing list for developers, at
+<a href="mailto:proofgeneral-devel@informatics.ed.ac.uk">
+<tt>proofgeneral-devel@informatics.ed.ac.uk</tt></a>.
+<br>
+To subscribe (or unsubscribe),
+visit <a href="http://lists.informatics.ed.ac.uk/listinfo/proofgeneral-devel">this web page</a>.
+</p>
+
diff --git a/html/develdownload b/html/develdownload
new file mode 100644
index 00000000..4c9b3b01
--- /dev/null
+++ b/html/develdownload
@@ -0,0 +1,5 @@
+<?php include('develdownload.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?>
diff --git a/html/develdownload.html b/html/develdownload.html
new file mode 100644
index 00000000..4c9b3b01
--- /dev/null
+++ b/html/develdownload.html
@@ -0,0 +1,5 @@
+<?php include('develdownload.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?>
diff --git a/html/develdownload.php b/html/develdownload.php
new file mode 100644
index 00000000..81f64c70
--- /dev/null
+++ b/html/develdownload.php
@@ -0,0 +1,141 @@
+<?php
+ require('functions.php3');
+ small_header("Proof General Development Release");
+ ?>
+
+<p>
+<a href="#prerel">Below</a> is the latest pre-release of Proof General,
+made available for those who wish to test the latest features or bug
+fixes. For developers, this release is also available as a
+<a href="#devel">complete CVS snapshot (further below)</a>.
+</p>
+<p>
+Pre-releases of Proof General may be buggy as we add new features and
+experiment with them. Nonetheless, we welcome bug reports. But
+please make sure you are using the latest pre-release before
+reporting problems.
+</p>
+<p>
+Please <a href="register">register</a> if you haven't done so already.
+</p>
+
+
+<!-- WARNING! Line below automatically edited by makefile. -->
+<h2><a name="doc">Manual for ProofGeneral-3.4pre020214</a></h2>
+<!-- End Warning. -->
+<p>
+The manual included with the pre-release may be
+updated from that of the
+<a href="doc">last stable release</a>.
+</p>
+<p>
+Here is the pre-release documentation: the user manual in
+<?php htmlshow("ProofGeneral/doc/ProofGeneral_toc.html","HTML","Proof General manual") ?>,
+<?php download_link("ProofGeneral/doc/ProofGeneral.ps.gz", "ps") ?>
+or
+<?php download_link("ProofGeneral/doc/ProofGeneral.pdf", "pdf") ?>,
+and the new separate "adapting" manual, in
+<?php htmlshow("ProofGeneral/doc/PG-adapting_toc.html","HTML","Adapting Proof General manual") ?>,
+<?php download_link("ProofGeneral/doc/PG-adapting.ps.gz", "ps") ?>
+or
+<?php download_link("ProofGeneral/doc/PG-adapting.pdf", "pdf") ?>.
+</p>
+
+
+<!-- WARNING! Line below automatically edited by makefile. -->
+<h2><a name="prerel">Pre-release: ProofGeneral-3.4pre020214</a></h2>
+
+<p>
+This version has been tested with XEmacs version 21.4 and
+(minimally) with GNU Emacs 21.1.
+We recommend the use of XEmacs; use under GNU Emacs
+is not well supported.
+</p>
+<p>
+Check the
+<!-- WARNING! Line below automatically edited by makefile. -->
+<?php fileshow("ProofGeneral-3.4pre020214/CHANGES","CHANGES"); ?> file
+<!-- End Warning. -->
+for a summary of changes since the last stable version, and
+notes about work-in-progress.
+</p>
+<table width="80%" cellspacing=8>
+<tr>
+<td width=150>gzip'ed tar file</td>
+<!-- WARNING! Lines below automatically edited by makefile. -->
+<td><?php download_link("ProofGeneral-3.4pre020214.tar.gz") ?></td>
+</tr>
+<tr>
+<td>zip file</td>
+<td><?php download_link("ProofGeneral-3.4pre020214.zip") ?></td>
+</tr>
+<tr>
+<td>RPM package </td>
+<td><?php download_link("ProofGeneral-3.4pre020214-1.noarch.rpm") ?></td>
+</tr>
+<tr>
+<td>individual files</td>
+<td><a href="ProofGeneral">http access to files in development release</a>
+</tr>
+</table>
+<!-- End Warning. -->
+<p>
+NB: we no longer distribute the source RPM, since you can build
+both source and "binary" RPMs direct from the tarball using
+"rpm -ta".
+</p>
+<p>
+For install instructions, see
+the <a href="download#install">stable version download</a>.
+</p>
+
+<p>
+</p>
+<p>
+</p>
+
+
+<!-- WARNING! Line below automatically edited by makefile. -->
+<h2><a name="devel">Complete Archive of ProofGeneral-3.4pre020214 for Developers</a></h2>
+<!-- End Warning. -->
+
+<p>
+This archive is a snapshot from our CVS repository.
+</p>
+<ul>
+ <li> gzip'ed tar file:
+<!-- WARNING! Line below automatically edited by makefile. -->
+ <?php download_link("ProofGeneral-3.4pre020214-devel.tar.gz") ?>
+<!-- End Warning. -->
+ </li>
+</ul>
+<p>
+What's the difference from the user's pre-release above?
+The complete archive also includes:
+</p>
+<ul>
+ <li> the low-level developer's todo files
+ (see <a href="devel#lowleveltodo">the developers page</a>)
+ and the detailed
+ <!-- WARNING! Line below automatically edited by makefile. -->
+ <?php fileshow("ProofGeneral-3.4pre020214/ChangeLog","ChangeLog"); ?>,
+ <!-- End Warning. -->
+ </li>
+ <li> developer's Makefile used to generate documentation files
+ and the release itself,</li>
+ <li> test files, </li>
+ <li> image source files, </li>
+ <li> the web pages, </li>
+ <li> working instantiations of Proof General for new provers </li>
+</ul>
+<p>
+You probably <em>don't</em> need to download this if you're only
+interested in hacking the Emacs lisp part of the program for a prover
+that is currently supported. Note that there are no pre-built
+documentation files in the developer's release.
+</p>
+
+<?php
+ click_to_go_back();
+ footer();
+?>
diff --git a/html/doc b/html/doc
new file mode 100644
index 00000000..a58717d8
--- /dev/null
+++ b/html/doc
@@ -0,0 +1,5 @@
+<?php include('index.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?> \ No newline at end of file
diff --git a/html/doc.html b/html/doc.html
new file mode 100644
index 00000000..3f092ade
--- /dev/null
+++ b/html/doc.html
@@ -0,0 +1,107 @@
+<h2>Manual</h2>
+
+<p>
+There are two manuals for Proof General:
+</p>
+<ul>
+<li> the
+<?php htmlshow("ProofGeneral-3.3/doc/ProofGeneral_toc.html","Proof General user manual ","Proof General Manual") ?>
+</li>
+<li> the
+<?php htmlshow("ProofGeneral/doc/PG-adapting_toc.html","Adapting Proof General manual","Adapting Proof General manual") ?>
+</li>
+</ul>
+<p>
+The second manual gives instructions on how to adapt Proof General to new
+proof systems, it's not needed for ordinary use.
+</p>
+<p>
+For printing you can download:
+<ul>
+<li>
+<?php download_link("ProofGeneral-3.3/doc/ProofGeneral.ps.gz", "User manual [ps]") ?> and
+<?php download_link("ProofGeneral-3.3/doc/PG-adapting.ps.gz", "Adapting manual [ps]") ?>, or
+</li>
+<li>
+<?php download_link("ProofGeneral-3.3/doc/ProofGeneral.pdf", "User manual [pdf]") ?>,
+<?php download_link("ProofGeneral-3.3/doc/PG-adapting.pdf", "Adapting manual [pdf]") ?>
+</li>
+</ul>
+<p>
+The PostScript files are recommended over the PDF.
+</p>
+<p>
+Note that both manuals (in HTML and Info formats) are included in the
+<a href="download">download</a>. When running Proof General the manual
+is available from the "Proof General" menu. It should also appear in
+the system Info pages.
+</p>
+
+
+<p>
+You can discuss Proof General with other users and receive
+announcements by joining our <a href="mailinglist.html">mailing
+list</a>.
+</p>
+
+<h2>References</h2>
+
+<p> Ideas for the future of Proof General are given here:
+</p>
+<ul>
+<li><a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+ <b><i>Protocols for Interactive e-Proof</i></b>.
+ Draft version, see
+ <a href="http://zermelo.dcs.ed.ac.uk/~da/drafts/#eproof">here</a>.
+</li>
+<li><a href="http://www.dcs.ed.ac.uk/home/da">David Aspinall</a>.
+ <b><i>Proof General Kit (white paper)</i></b>.
+ Draft version, see
+ <a href="http://zermelo.dcs.ed.ac.uk/home/da/drafts/#white">here</a>.
+</li>
+</ul>
+<p> A technology overview of Proof General is given here:
+</p>
+<ul>
+<li> <a href="http://www.dcs.ed.ac.uk/home/da">David Aspinall</a>.
+ <a href="papers/pgoutline.ps.gz">Proof General: A Generic Tool for
+ Proof Development</a>.
+ <i>Tools and Algorithms for the Construction and
+ Analysis of Systems, Proc TACAS 2000</i>, LNCS 1785.
+ <br>
+ Here are some <a href="papers/pgtalk.pdf">slides</a>
+ used for this talk and some other presentations of Proof General.
+</li>
+</ul>
+<p> Proof General supports Script Management as documented in:
+</p>
+<ul>
+ <li> <a
+ href="http://www.inria.fr/croap/personnel/Yves.Bertot/me.html">Yves
+ Bertot</a> and <a
+ href="http://www.inria.fr/croap/personnel/Laurent.Thery/me.html">Laurent
+ Th&eacute;ry</a>. <a
+ href="ftp://babar.inria.fr/pub/croap/bertot/jsymcomp.ps">A
+ generic approach to building user interfaces for theorem
+ provers</a>.
+ <i>Journal of Symbolic Computation</i>, 25(7), pp. 161-194, February 1998.
+ </li>
+ </ul>
+ <p>
+ It has support for Proof by Pointing, as documented in:
+ </p>
+ <ul>
+ <li> <A
+ HREF="http://www.inria.fr/croap/personnel/Yves.Bertot/me.html">Yves
+ Bertot</A>, <A HREF="http://www.dcs.ed.ac.uk/home/tms">
+ Thomas Kleymann-Schreiber</A> and <A
+ HREF="http://www.dcs.ed.ac.uk/home/djs">Dilip Sequeira</a>.
+ <I>Implementing Proof by Pointing without a Structure Editor</I>.
+ LFCS Technical Report <A
+ HREF="http://www.lfcs.informatics.ed.ac.uk/reports/97/ECS-LFCS-97-368/index.html">ECS-LFCS-97-368</a>.
+ Also published as Rapport de recherche de l'INRIA
+ <A HREF="http://www.inria.fr/Unites/SOPHIA-eng.html"> Sophia
+ Antipolis</a> <A
+ HREF="http://www.inria.fr/RRRT/RR-3286.html">RR-3286</a>
+ </li>
+</ul>
diff --git a/html/download b/html/download
new file mode 100644
index 00000000..a58717d8
--- /dev/null
+++ b/html/download
@@ -0,0 +1,5 @@
+<?php include('index.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?> \ No newline at end of file
diff --git a/html/download.html b/html/download.html
new file mode 100644
index 00000000..6ebdfdf2
--- /dev/null
+++ b/html/download.html
@@ -0,0 +1,224 @@
+<h2>Please register</h2>
+<p>
+Before downloading Proof General, <i>please</i>
+<a href="register">register</a>.
+It's free, it only takes a moment.
+If you have already registered you do not need to do so again.
+The statistics collected from registrations are used to help
+make a case for support for Proof General, and nothing else.
+It is likely that development of Proof General will <i>finish soon</i>
+unless we find new resources. As a courtesy, we do not make
+registration compulsory and I can tell from the server logs that the
+majority of people downloading do not register. But if you don't
+register now, please consider returning to register later if you find
+Proof General interesting or useful. If you don't want to fill the
+form, please <a href="mailto:proofgen@dcs.ed.ac.uk">send an email</a>
+directly or even a paper letter to the <a
+href="http://www.lfcs.informatics.ed.ac.uk/">LFCS</a>. And if you
+can offer to help resource the development of Proof General
+in some way, please
+<a href="feedback">contact us</a> (quickly!).
+</p>
+
+<p>
+You may like to join the
+Proof General
+<a href="mailinglist">mailing list</a>.
+Developers and beta-testers may like to download
+a <a href="develdownload.html">development release</a>
+of Proof General.
+If you use an old version of a proof assistant,
+you may need to download one of the
+<a href="oldrel.php">previous releases</a>.
+</p>
+<p>
+Please check the
+<?php fileshow("ProofGeneral/COPYING","license conditions "); ?>
+for using Proof General.
+<br>
+See <a href="#prereq">below</a> for software pre-requisites for running Proof General.
+</p>
+
+<h2><a name="stable">
+ Proof General Version 3.3, released 10th September 2001
+ </a>
+</h2>
+
+<p>
+Proof General is available as an archive and an RPM package.
+</p>
+<table width="80%" cellspacing=8>
+<tr>
+<td width=150>gzip'ed tar file</td>
+<!-- WARNING! Lines below automatically edited by makefile. -->
+<td><?php download_link("ProofGeneral-3.3.tar.gz") ?></td>
+</tr>
+<tr>
+<td>zip file</td>
+<td><?php download_link("ProofGeneral-3.3.zip") ?></td>
+</tr>
+<tr>
+<td>RPM package </td>
+<td><?php download_link("ProofGeneral-3.3-1.noarch.rpm") ?></td>
+</tr>
+<tr>
+<td>individual files</td>
+<td><a href="ProofGeneral-3.3">browse individual files</a>
+</tr>
+</table>
+<p>
+Both the tarball and the RPM package include the generic elisp
+code,
+code for the supported provers, installation instructions
+and documentation in Info and HTML formats.
+Documentation is available in other formats
+here <a href="doc">here</a>.
+If you want to format the documentation yourself,
+you may like to download the
+<?php download_link("ProofGeneralPortrait.eps.gz",
+"front page image") ?>.
+Note that we don't ship an SRPM now, since you can build the RPM directly
+from the source tarball using <tt>rpm -ta</tt>.
+</p>
+<p>
+This version of Proof General has been tested
+with XEmacs 21.4 and (briefly with) GNU Emacs 20.7.
+It supports earlier versions of both Emacsen, but
+we recommend using the latest versions available
+</p>
+<p>
+Check the <?php fileshow("ProofGeneral-3.3/CHANGES","CHANGES"); ?> file
+for >a summary of changes since version 3.2.
+</p>
+<p>
+Check the latest <?php fileshow("ProofGeneral/BUGS","BUGS"); ?> file
+(also
+<?php fileshow("ProofGeneral/lego/BUGS","lego/BUGS, "); ?>
+<?php fileshow("ProofGeneral/coq/BUGS","coq/BUGS, "); ?>
+<?php fileshow("ProofGeneral/isa/BUGS","isa/BUGS, "); ?>
+<?php fileshow("ProofGeneral/isar/BUGS","isar/BUGS," ); ?>)
+<!-- <?php fileshow("ProofGeneral/hol98/BUGS","hol98/BUGS"); ?>) -->
+before reporting problems. If you find a problem not already mentioned,
+please
+<?php hlink("feedback.html","send us a note","Feedback form")?>.
+</p>
+<br>
+<br>
+
+<h2><a name="prereq">
+ What you need to run Proof General
+ </a>
+</h2>
+<p>
+To run Proof General, you <strong>must</strong> have:
+</p>
+<ul>
+<li>
+Version 21.1 or later
+of <a href="http://www.xemacs.org">XEmacs</a>
+(this UK
+<a href="http://sunsite.doc.ic.ac.uk/Mirrors/ftp.xemacs.org/pub/xemacs/">
+ftp mirror</a> may help).
+<br>
+<b>or</b> version 20.7 of the much poorer
+<a href="http://www.gnu.org/software/emacs/">GNU GNU Emacs</a>.
+<br>
+Both Emacsen are available for a variety of platforms, including
+Unix variants and Windows 95/98/NT/2k.
+</li>
+<li>
+One or more of the supported proof assistants. Or write your own
+support for a new assistant.
+<br>
+See the
+<a href="main">front page</a> for links to supported
+assistants.
+</li>
+</ul>
+<p>
+
+There are also some <strong>optional</strong> components for using
+Proof General:
+<ul>
+<li>
+For displaying logical and mathematical symbols, the excellent
+<a href="http://www.fmi.uni-passau.de/~wedler/x-symbol/">X-Symbol</a>
+package.
+<br>It's very easy to install. See <a href="#xsyminstall">here</a>
+for installation notes.
+<br>X-Symbol presently only works with XEmacs on systems running X.
+</li>
+<!-- <li> -->
+<!-- For GNU Emacs, a version of <tt>func-menu.el</tt> to get -->
+<!-- <a href="features#funcmenu">function menus</a>. -->
+<!-- <br>Unfortunately I can't find a version of this that -->
+<!-- works with current GNU Emacs releases. I'd be grateful -->
+<!-- for a pointer to one. -->
+<!-- <br> -->
+<!-- (The package -->
+<!-- <tt>imenu.el</tt> may be a suitable replacement, -->
+<!-- and it ships with both Emacsen. Perhaps -->
+<!-- somebody could contribute patches to use that -->
+<!-- instead of <tt>func-menu</tt>). -->
+</ul>
+<p>
+All components mentioned above are distributed under the GPL license.
+</p>
+<br>
+<br>
+
+<h3><a name="install">Easy installation of Proof General</a></h3>
+<p>
+To use Proof General, simply unpack the sources with
+</p>
+ <blockquote>
+ <tt>tar xpzf ProofGeneral-3.3.tar.gz</tt>
+ </blockquote>
+<p>
+(use <tt>gunzip</tt> first in place of <tt>z</tt> if you don't have
+GNU tar),<br> and then add this one line to your .emacs file:
+</p>
+ <blockquote>
+ <tt> (load-file "<var>directory</var>/generic/proof-site.el")</tt>
+ </blockquote>
+<p>
+Where <var>directory</var> is the directory in which you unpacked
+the sources.
+<br>
+If you use the RPM package, <var>directory</var> is
+<tt>/usr/share/emacs/ProofGeneral</tt>
+</p>
+<p>
+If you're using Windows, then download the zip file.
+<br>
+Use a zip file utility to unpack it somewhere, for example
+<tt>c:\\ProofGeneral</tt>
+</p>
+<p>
+Further customization is possible via the Customize menus in
+Emacs.
+<br>
+See the <?php fileshow("ProofGeneral-3.3/INSTALL","INSTALL")?>
+file in the distribution for more details.
+</p>
+
+<h3><a name="xsyminstall">Easy installation of X-Symbol</a></h3>
+
+<p>
+X-Symbol is easy to install and configures itself automatically.
+</p>
+<p>
+Simply download the binary package file, and do something
+like this to install in your home directory:
+</p>
+<blockquote><tt>
+ mkdir -p ~/.xemacs<br>
+ cd ~/.xemacs<br>
+ tar xpzf ../x-symbol-pkg.tar.gz<br>
+</tt></blockquote>
+<p>
+NB: if you have version 21.x of XEmacs, you may need to install
+x-symbol inside a subdirectory
+<tt>~/.xemacs/xemacs-packages</tt> instead of
+<tt>~/.xemacs</tt>.
+
diff --git a/html/elispmarkup.php3 b/html/elispmarkup.php3
new file mode 100644
index 00000000..2e21180c
--- /dev/null
+++ b/html/elispmarkup.php3
@@ -0,0 +1,135 @@
+<?php
+//
+// Markup Emacs Lisp and Outline files
+//
+// David Aspinall, March 2000
+//
+// $Id$
+//
+//
+
+function isexpanded($headingno,$expanded) {
+ // print "testing $headingno";
+ $all = ereg("all",$expanded);
+ $thisone = ereg("," . $headingno,$expanded);
+ return ($all ? ! $thisone : $thisone);
+}
+
+function addexpanded($headingno,$expanded) {
+ $all = ereg("all",$expanded);
+ return ($all ? str_replace("," . $headingno,"",$expanded) :
+ $expanded . "," . $headingno);
+}
+
+function removeexpanded($headingno,$expanded) {
+ $all = ereg("all",$expanded);
+ return ($all ? $expanded . "," . $headingno :
+ str_replace("," . $headingno,"",$expanded));
+}
+
+function link_toggle($headingno,$text,$thispage,$filename,$expanded) {
+ if (isexpanded($headingno,$expanded)) {
+ $newexpanded=removeexpanded($headingno,$expanded);
+ } else {
+ $newexpanded=addexpanded($headingno,$expanded);
+ }
+ print "<a name=\"$headingno\"><a href=\"$thispage";
+ print "?file=" . urlencode($filename);
+ print "&expanded=" . urlencode($newexpanded) . "#" . $headingno . "\">" . $text . "</a></a>\n";
+}
+
+// FIXME: this is a nonsense really. Might be okay if it
+// used dynamic HTML but it's too much of a faff at the moment.
+// Also, we should use the tree structure properly and keep a stack!
+
+function outline_markup($filename,$thispage,$expanded) {
+ if ($title=="") { $title=$filename; };
+ $outline = false;
+ $file = file($filename);
+ $i = 0;
+ $level=0;
+ $headingno=0;
+ /* Now parse file, watching for outline headers */
+ for (;$i < count($file);$i++) {
+ $line = $file[$i];
+ // HTML escapes
+ $line = htmlentities($line);
+ // Anchors for URLs
+ $line = ereg_replace("((http://|mailto:)[-a-zA-Z0-9\.~/_@]+)","<a href=\"\\1\">\\1</a>",$line);
+ // Assume a heading
+ $multipar=false;
+ if (ereg("-\*- (mode:)?outline -\*-",$line)) {
+ // Found line with outline mode header, set flag
+ // and print message
+ $outline = true;
+ print "<p><i>";
+ print "This is a flattened outline file: click on a title to hide/reveal the leaf underneath it.";
+ print "<br>Click ";
+ print "<a href=\"$thispage?file=" . urlencode($filename);
+ print "&expanded=all\">here</a> to show whole body, or ";
+ print "<a href=\"$thispage?file=" . urlencode($filename);
+ print "\">here</a> to hide whole body.";
+ print "</i></p>\n";
+ } elseif ($outline) {
+ if (ereg("^ *\n",$line)) {
+ // if (!newpara) { print "</p><p>\n"; };
+ $newpara = true;
+ } elseif (ereg("^([\*]+) (.*)\n",$line,$heading)) {
+ $newlevel = strlen($heading[1])+1;
+ // if ($newlevel < $level) {
+ // Up a level
+ // $p = strpos($path,"-");
+ // $path = substr($path,0,$p-1);
+ if ($newpara &&
+ $level<=$newlevel &&
+ isexpanded($headingno,$expanded)) { print "<p>\n"; }
+ $headingno++;
+ $level=$newlevel;
+ $text="<h$level>$heading[2]</h$level>";
+ link_toggle($headingno,$text,$thispage,$filename,$expanded);
+ } elseif (isexpanded($headingno,$expanded)) {
+ if ($newpara && $level==0) { print "<p>\n"; }
+ print $line;
+ $newpara=false;
+ $level=0;
+ }
+ } else {
+ print $line;
+ }
+ }
+}
+
+//
+// For browsing source. Unfinished.
+//
+
+function elisp_markup($filename,$thispage,$title="") {
+ if ($title=="") { $title=$filename; };
+ $file = file($filename);
+ $i = 0;
+ $level=0;
+ $headingno=0;
+ /* Now parse file, watching for outline headers */
+ for (;$i < count($file);$i++) {
+ $line = $file[$i];
+ // HTML escapes
+ $line = htmlentities($line);
+ // Anchors for URLs
+ $line = ereg_replace("((http://|mailto:)[-a-zA-Z0-9\.~/_@]+)","<a href=\"\\1\">\\1</a>",$line);
+ // Font-lock equivalents...
+ // 1. comments. Strings roughly done: ignore if quote appears after ;
+// seems buggy.
+// $line = ereg_replace("^([^;]*)(\;+[^\"]+)$",
+// "\\1<div style=\"color: #8080E0\">\\2</div>",
+// $line);
+ // 2. keywords
+ // FIXME: this inserts CR's.
+// $line = ereg_replace("^\(def(macro|un|var|custom|const|group)",
+// "(<div style=\"color: #C0B0B0\">def\\1</div>",
+// $line);
+ // FIXME: add hrefs for keywords, looking up in TAGS file.
+ // FIXME: add line numbers
+ // FIXME: parse strings
+ print $line;
+ }
+}
diff --git a/html/features b/html/features
new file mode 100644
index 00000000..a58717d8
--- /dev/null
+++ b/html/features
@@ -0,0 +1,5 @@
+<?php include('index.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?> \ No newline at end of file
diff --git a/html/features.html b/html/features.html
new file mode 100644
index 00000000..3fde03c4
--- /dev/null
+++ b/html/features.html
@@ -0,0 +1,194 @@
+<h2>Features of Proof General</h2>
+<p>
+It doesn't matter if you're an Emacs militant or a pacifist!
+</p>
+
+<p>
+Proof General is designed to be useful for novices and expert users alike.
+<br>
+It will be useful to you if you use a proof assistant, and
+you'd like an interface with the following features...
+</p>
+<dl>
+ <?php dt("Script management","script") ?>
+ <dd>
+ A <em>proof script</em> is a sequence of commands sent to
+ a proof assistant to construct a proof, usually stored in
+ a file. <em>Script management</em> connects the editing of a
+ proof script directly to an interactive proof process,
+ maintaining consistency between the edit buffer
+ and the state of the proof assistant.
+ <p>
+ Proof General colours a proof script to show the state in the proof
+ assistant. Parts of a proof script that have been processed are
+ displayed in blue and are "locked" -- they cannot be edited. Parts
+ of the script currently being processed by the proof assistant are
+ shown in red. Bodies of completed proofs in the locked region
+ can be hidden from view to help browsing.
+ Proof General has commands for processing new parts
+ of the buffer, or undoing already processed parts.
+ </p>
+ <p>
+ Take a look at these
+ <a href="screenshot">screenshots</a>
+ of Proof General to see script management in action.
+ </p>
+ </dd>
+</dl><dl>
+ <?php dt("Simplified interaction","simple") ?>
+ <dd>
+ Proof General is designed for proof assistants which have a
+ command-line shell interpreter. When using Proof General, the proof
+ assistant's shell is hidden from the user. Communication takes
+ place via three buffers (Emacs text widgets). The <i>script
+ buffer</i> holds input, the commands to construct a proof. The
+ <i>goals buffer</i> displays the current list of subgoals to be
+ solved. The <i>response buffer</i> displays other output from the
+ proof assistant. By default, only two of these three buffers are
+ displayed at once. This means that the user only sees the output
+ from the most recent interaction, rather than a screen full of
+ output from the proof assistant.
+ <p>
+ Despite this more friendly communication model, Proof General does not
+ commandeer the proof assistant shell: the user still has complete
+ access to it if necessary.
+ </p>
+ </dd>
+</dl><dl>
+ <?php dt("Multiple files","multiple") ?>
+ <dd>
+ Script management in Proof General can work across many script
+ files, integrating with the file handling of
+ the proof assistant. When a script is visited in the editor, it
+ is locked (coloured) to reflect whether the proof assistant has
+ loaded it in this session. When a file is unlocked, all of the
+ files which depend on it are automatically unlocked too.
+ <p>
+ Dependencies between script files are either communicated from the
+ proof assistant to Proof General, or maintained automatically by
+ Proof General (based on the order in which files were processed).
+ </p>
+ </dd>
+</dl><dl>
+ <?php dt("Proof by Pointing","pbp") ?>
+ <dd>
+ <em>Proof by pointing</em> allows you to click on a subterm of
+ a goal to be proved, and apply an appropriate rule or
+ tactic automatically.
+ <p>
+ Proof by pointing uses the interface to highlight subterms under the
+ mouse, and sends messages asking the prover for hints to proceed.
+ Proof General also uses the subterm structure to make it easy to cut
+ and paste from complicated terms.
+ </p>
+ <?php footnote("Proof by pointing for Proof General is only supported by LEGO (experimentally) at the moment. For others, we need help from each proof assistant implementor to add support for their system. Please canvas the implementor of your favourite
+proof assistant to add PBP support.") ?>
+ </dd>
+</dl><dl>
+ <?php dt("Toolbar and menus","toolbar") ?>
+ <dd>
+ Proof General has a toolbar with buttons for examining
+ the proof state, starting a proof, manoeuvring in the proof script,
+ restarting the prover, saving a proof, searching for a theorem,
+ issuing a command, interrupting the assistant, and getting help.
+ <p>
+ Using the toolbar, you can replay proofs without knowing any
+ low-level commands of the proof assistant or any Emacs hot-keys!
+ <p>
+ Additionally, the toolbar commands and many more besides are
+ available on menus; you don't need to know magical key presses for
+ any features.
+ </p>
+ <?php footnote("Toolbar is available not available on GNU Emacs < 21") ?>
+ </dd>
+</dl><dl>
+ <?php dt("Syntax highlighting","fontlock") ?>
+ <dd>
+ Syntax highlighting is an editing feature which decorates a file
+ with different colours or fonts according to the syntax of some
+ language (usually a programming language).
+ <p>
+ Proof General decorates proof scripts: proof commands are
+ highlighted and different fonts may be used for definitions and
+ assumptions, for example.
+ </p>
+ </dd>
+</dl><dl>
+ <?php dt("Real symbols","xsymbol") ?>
+ <dd>
+ Proof General has a close integration with the
+ powerful
+ <a href="http://www.fmi.uni-passau.de/~wedler/x-symbol">X-Symbol</a>
+ package, which makes it easy to transparently use real symbols and
+ Greek letters in your proofs.
+ <br>
+ Instead of seeing "not P", you see "&not; P", instead
+ of "a * b", you see "a &times; b", etc.
+ <br>
+ (Those examples are simple so they will work on most browsers
+ without needing images, see the
+ <a href="screenshot">screenshots</a> for more examples.)
+ <p>
+ <?php footnote("X-Symbol currently works in XEmacs only") ?>
+ </dd>
+</dl><dl>
+ <?php dt("Functions Menu","funcmenu") ?>
+ <dd>
+ A pull-down menu gives easy
+ navigations to theorems, definitions, and declarations
+ proved in the current buffer.
+<!-- it is in FSF Emacs if you download func-menu.el from somewhere -->
+<!-- <?php footnote("Definitions menu is available in XEmacs only") ?> -->
+ <p>
+ </dd>
+</dl><dl>
+ <?php dt("Remote proof assistant.") ?>
+ <dd>
+ Sometimes you may want to run a proof assistant on a powerful remote
+ machine. Proof General can communicate with a proof assistant running
+ remotely, while your files and editor reside on your local machine.
+ <p></p>
+ </dd>
+</dl><dl>
+ <?php dt("Tags","tags") ?>
+ <dd>
+ Tags are an editing feature which allow you to quickly locate the
+ definition or declaration of a particular identifier. Proof General
+ is supplied with utilities to make tag indexes for Emacs.
+ This makes it easy to quickly access
+ definitions from a standard library, for example, and in large proof
+ developments split across multiple files.
+<!-- <?php footnote("Tags programs are provided for LEGO and Coq") ?> -->
+ <p></p>
+ </dd>
+</dl><dl>
+ <?php dt("Adaptability","generic") ?>
+ <dd>
+ Proof General is designed to be adaptable. Many aspects
+ of its behaviour can be easily customized (using dialogue boxes and
+ buttons, no text file editing!).
+ <p>
+ Most importantly, Proof General is generic, so you can adapt it to
+ a new proof assistant with surprisingly little effort.
+ <p>
+ Adapting for a new proof assistant is mainly a matter of setting
+ some variables with regular expressions to help parse output from
+ the prover, and setting other variables with commands to send to the
+ prover. See this basic
+ <?php fileshow("ProofGeneral/demoisa/demoisa-easy.el",
+ "example instance"); ?>.
+ To get the most from Proof General (proof by pointing, for
+ example), it may be necessary to put some hooks in
+ the output routines of the proof assistant.
+ </p>
+ Please feel free to download Proof General to customize it for a new
+ system, and
+ <?php hlink("feedback.html","tell us ","Feedback form")?>
+ how you get on.
+ </dd>
+</dl>
+<p>
+For (even) more details of Proof General's features, see the manuals and
+papers on the <a href="doc">documentation page</a>.
+</p>
+
diff --git a/html/feedback b/html/feedback
new file mode 100644
index 00000000..94066bcf
--- /dev/null
+++ b/html/feedback
@@ -0,0 +1,6 @@
+<?php include('feedback.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?>
+
diff --git a/html/feedback.php b/html/feedback.php
new file mode 100644
index 00000000..4b01ce80
--- /dev/null
+++ b/html/feedback.php
@@ -0,0 +1,87 @@
+<?php
+##
+## Proof General feedback form.
+##
+## David Aspinall, June 1999.
+##
+## $Id$
+##
+ require('functions.php3');
+
+ if ($argv[0] !="submit"):
+###
+### Feedback form
+###
+ small_header("Proof General Feedback Form");
+?>
+
+<p>
+Please use the form below to send us comments, suggestions,
+or offers to help with Proof Generl development.
+<br>
+Or send email directly to
+the <?php mlinktxt($project_feedback, "Proof General maintainer &lt;$project_feedback&gt."); ?>
+</p>
+<p>
+You can also report a bug using this form, although it would
+be more helpful to do this from within Emacs, using the
+"<kbd>Proof General -> Submit bug report</kbd>" menu command.
+</p>
+
+<form method=post action="<?php print $PHP_SELF . "?submit"; ?>">
+<table width="300" border="0" cellspacing="2" cellpadding="0">
+<tr>
+ <td width="20%">From:</td>
+ <td width="80%"><input type=text name="from" size="40"></td>
+</tr>
+<tr>
+ <td>Subject:</td>
+ <td><input type=text name="subject" size="40"></td>
+</tr>
+<tr><td colspan="2">
+<textarea rows="12" cols="60" wrap="physical" name="feedback">
+Dear Proof General developers,
+
+
+</textarea>
+</td></tr>
+</table>
+<br>
+<input type=submit value="Send feedback">
+<input type=reset value="Clear">
+</form>
+
+<?php
+ click_to_go_back();
+ footer();
+ else:
+##
+## Process feedback
+##
+ small_header("Thank-you!");
+
+ /* NB: No validation of address! */
+
+ /* FIXME: could append extra info to feedback. */
+
+ $message = "From:\t\t" . $from . "\nSubject:\t" . $subject
+ . "\n\n" . "Message:\n" . $feedback;
+
+ if ($from != "") { print "<p>Dear " . $from . ",</p>\n"; };
+ print "<p>";
+ print "Thank-you for sending us feedback";
+ if ($subject != "") { print " about " . $subject; };
+ print ".</p>\n<p>";
+ print "If you provided a valid return email address, somebody from the Proof General team will acknowledge your message after it has been read.";
+ print "</p>";
+
+ mail($project_feedback,
+ "[Web Feedback Form]: " . $subject,
+ $message,
+ "Reply-To: " . $from . "\n");
+
+ click_to_go_back();
+
+ footer();
+endif;
+?>
diff --git a/html/fileshow.php b/html/fileshow.php
new file mode 100644
index 00000000..09747fda
--- /dev/null
+++ b/html/fileshow.php
@@ -0,0 +1,24 @@
+<?php
+ require('functions.php3');
+ require('elispmarkup.php3');
+ $filename=$HTTP_GET_VARS["file"];
+ $title=$HTTP_GET_VARS["title"];
+ $expanded=$HTTP_GET_VARS["expanded"];
+ if ($title=="") { $title = $filename; };
+ small_header($title);
+ print "<pre>\n";
+ /* I hope this is enough to prevent access outside cwd */
+ if (substr($filename,0,1)=="." or
+ substr($filename,0,1)=="/" or
+ substr($filename,0,1)=="~") {
+ print "Sorry, can't show you that file!\n";
+ } elseif (substr($filename,-3)==".el") {
+ elisp_markup($filename,"fileshow.php");
+ } else {
+ outline_markup($filename,"fileshow.php",$expanded);
+ }
+ print "</pre>\n";
+ print "<hr>";
+ click_to_go_back();
+ footer();
+?>
diff --git a/html/footer.html b/html/footer.html
new file mode 100644
index 00000000..de01ece5
--- /dev/null
+++ b/html/footer.html
@@ -0,0 +1,10 @@
+<!-- This is the footer -->
+<hr>
+<address>
+Web pages by
+<a href="http://www.dcs.ed.ac.uk/~da">David Aspinall</a>.
+<br>
+Contact
+<?php mlinktxt($project_feedback, "Proof General maintainer."); ?>
+<br>
+
diff --git a/html/functions.php3 b/html/functions.php3
new file mode 100644
index 00000000..90b94f3e
--- /dev/null
+++ b/html/functions.php3
@@ -0,0 +1,294 @@
+<?php
+//
+// Dave's PHP3 Header
+//
+// Included in every page.
+// Prints DTD and defines some useful functions.
+//
+// David Aspinall, June 1999.
+//
+// $Id$
+//
+//
+
+
+// Project configuration
+
+// $project_email = "feedback@proofgeneral.org";
+// $project_list = "users@proofgeneral.org";
+// $project_feedback = "feedback@proofgeneral.org":
+
+// Disable because free parking forwarding is broken
+$proofgenatdcs = "proofgen@dcs.ed.ac.uk";
+$project_email = $proofgenatdcs;
+$project_list = $proofgenatdcs;
+$project_feedback = $proofgenatdcs;
+
+$project_title = "Proof General";
+
+$project_subtitle = "Organize your Proofs!";
+$project_full_title = $project_title . " --- " . $project_subtitle;
+
+if ($title == "") { $title = $project_title; } // default page title.
+
+// DTD
+
+$dtd_strict = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n";
+$dtd_loose = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n";
+
+print $dtd_loose;
+
+// Validator address
+
+// $validator = "http://validator.dcs.ed.ac.uk/";
+// It's a private link which won't work elsewhere, but never mind.
+ $validator = "http://localhost/validator/";
+
+function mlink($addr) {
+ print "<a href=\"mailto:" . $addr . "\">" . $addr . "</a>";
+}
+
+function mlinktxt($addr,$txt) {
+ print "<a href=\"mailto:" . $addr . "\">" . $txt . "</a>";
+}
+
+
+// FIXME: doesn't seem to work. Why not?
+function project_email() {
+ mlink($project_email);
+}
+
+
+/* Style sheet element for dt doesnt work in Netscape 4, so hack it here.
+ NB! This violates HTML 4 DTD.
+*/
+function dt($string,$name="") {
+ print "<dt>";
+ if ($name != "") { print "<a name =\"$name\">"; }
+ print "<div style=\"font-style:italic; font-weight: bold\">";
+ print $string;
+ print "</div>";
+ if ($name != "") { print "</a>"; }
+ print "</dt>";
+}
+
+/* Automatic footnotes? */
+/* FIXME: for now, just inline them. */
+
+function footnote ($text) {
+ print "<p><i><small>[" . $text . "]</small></i></p>";
+}
+
+/* A hyper-link with optional mouse over text.
+ Could be made more sophisticated to do roll-overs,
+ or whatever.
+*/
+
+function hlink ($url,$text,$mouseover="") {
+ print "<a href=\"" . $url . "\"";
+ if ($mouseover != "") {
+ print " onMouseOver=\"window.status='" . $mouseover . "'; return true;\"";
+ };
+ print ">" . $text . "</a>";
+}
+
+/* Determining download sizes (print broken message if file not found) */
+
+function download_size($filename) {
+ if (file_exists($filename)) {
+ $size = filesize($filename);
+ $sizek = (int) ($size/1024);
+ print " (";
+ if ($sizek == 0) {
+ print $size . " bytes)";
+ } else {
+ print $sizek . "k)";
+ }
+ } else {
+ print " (link broken)";
+ }
+}
+
+function download_link($filename,$linkname = "") {
+ print "<a href=\"" . $filename . "\">";
+ if ($linkname == "") {
+ print $filename;
+ } else {
+ print $linkname;
+ };
+ print "</a>";
+ print download_size($filename);
+}
+
+function date_modified($filename) {
+ $time = filemtime($filename);
+ if ($time) {
+ print "Last modified " . strftime("%d %B %Y",$time) . ".\n";
+ }
+}
+
+function small_header($title) {
+ print $dtd;
+ print "<html>";
+ include('head.html');
+ include('smallheader.html');
+ print "<h1>" . $title . "</h1>\n</td>\n</table>\n";
+}
+
+function small_header_body($title) {
+ include('smallheader.html');
+ print "<h1>" . $title . "</h1>\n</td>\n</table>\n";
+/* print "<p>"; FIXME: hack to get CSS to work with bad HTML from texi2html */
+}
+
+/* FIXME: remove this function: maybe just set a global variable,
+ or use SCRIPT_NAME, and then include footer.html. */
+
+function footer($filemodified=".") {
+ global $project_feedback;
+ include('footer.html');
+ date_modified($filemodified);
+ print "</address>\n";
+// print "</font>\n"; /* Naughty stuff for older browsers, shouldn't do if V4 */
+ print "</body>\n";
+ print "</html>\n";
+}
+
+function click_to_go_back() {
+ print "<p>\nClick <a href=\"\">here</a> to go back to the ";
+ print $project_title; // FIXME: doesn't work.
+ print " front page.</p>\n";
+}
+
+/* Link to a marked up file */
+/* NB: could determine type automatically! */
+
+function fileshow($filename,$text="",$title="") {
+ if ( $text == "") { $text=$filename; };
+ $message=$title;
+ if ( $message == "") { $message=$filename; };
+ $titlecode = ($title == "" ? "" : "&title=" . urlencode($title));
+ hlink("fileshow.php?file=" . urlencode($filename) . $titlecode,
+ $text, $message);
+}
+
+
+/* Similar for html file (NB: could pick automatically) */
+
+function htmlshow($filename,$text="",$title="") {
+ if ( $text == "") { $text=$filename; };
+ $message=$title;
+ if ( $message == "") { $message=$filename; };
+ $urlbits = parse_url($filename);
+ hlink("htmlshow.php"
+ . "?title=" . urlencode($title)
+ . "&file=" . urlencode($urlbits["path"])
+ . ($urlbits["fragment"]=="" ? "" : "#" . $urlbits["fragment"]),
+ $text, $message);
+}
+
+
+
+
+/* Markup plain text file, by escaping < and > */
+
+function markup_plain_text($filename) {
+ $file = file($filename);
+ for($i = 0;$i < count($file);$i++) {
+ $line = $file[$i];
+ $line = ereg_replace("<","&lt;",$line);
+ $line = ereg_replace(">","&gt;",$line);
+ print $line;
+ };
+}
+
+/* Hack an html file to be shown with our style sheet
+ and hack relative links to go via htmlshow.php.
+ This isn't particularly robust, but seems to work for
+ the output of texi2html.
+*/
+
+function hack_html($filename,$title="") {
+ if ($title=="") { $title=$filename; };
+ $file = file($filename);
+ /* Paste style sheet in head */
+ for($i = 0;$i < count($file);$i++) {
+ $line = $file[$i];
+ if (eregi("</HEAD>",$line)) {
+ /* Paste in style sheet */
+ print "<style type=\"text/css\">\n<!--";
+ include("proofgen.css");
+ print "-->\n</style>\n";
+ /* End style sheet paste in */
+ print $line;
+ $i++;
+ break;
+ } else { print $line; };
+ }
+ /* Now parse rest of document, hacking relative links. */
+ /* Matching here is not great, will get confused by html tags inside strings, etc. */
+ for (;$i < count($file);$i++) {
+ $line = $file[$i];
+ /* PHP has no way to get the match position, so we have to
+ match a suffix of the line, add extra parenthesis, and calculate it. */
+ while (eregi("(<A([^>]*)(HREF=\"([^\"]+)\")(.*))",$line,$linebits)) {
+ /* found URL in a particularly simple form */
+ $matchpos = strlen($line) - strlen($linebits[1]);
+ print substr($line,0,$matchpos); /* start of line */
+ $line = $linebits[5]; /* rest of line after link */
+ $urlbits = parse_url($linebits[4]);
+ if ($urlbits["host"]=="") {
+ /* Assume a relative link, let's hack it. */
+ /* Use same title */
+ $newurl = "htmlshow.php?title=" . urlencode($title);
+ if ($urlbits["path"]=="") {
+ /* A fragment in same file */
+ $newurl = $newurl . "&file="
+ . urlencode($filename) . "#" . $urlbits["fragment"];
+ } else {
+ /* Another file */
+ $newurl = $newurl . "&file="
+ . urlencode(dirname($filename) . "/" . $urlbits["path"])
+ . ($urlbits["fragment"]=="" ? "" : "#" . $urlbits["fragment"]);
+ };
+ print "<A " . $linebits[2] . " HREF=\"" . $newurl . "\"";
+ } else { print "<A " . $linebits[2] . $linebits[3]; }
+ };
+ /* Hack on a header and footer */
+ if (eregi("<BODY.*>",$line)) {
+ /* Assume there's nothing else interesting on the line, whoops. */
+ print $line;
+ small_header_body($title);
+ } elseif (eregi("</BODY>",$line)) {
+ /* Assume there's nothing else interesting on the line, whoops. */
+ click_to_go_back();
+ print $line;
+ } else {
+ print $line;
+ };
+ }
+}
+
+
+
+/* Display a small page with standard header, footer added on.
+ Much like htmlshow. */
+
+function smallpage($filename,$text="",$title="",$message="") {
+ if ( $text == "") { $text=$filename; };
+ if ( $message == "") { $message=$title; };
+ if ( $message == "") { $message=$filename; };
+ $urlbits = parse_url($filename);
+ hlink("smallpage.php"
+ . "?title=" . urlencode($title)
+ . "&file=" . urlencode($urlbits["path"])
+ . ($urlbits["fragment"]=="" ? "" : "#" . $urlbits["fragment"]),
+ $text, $message);
+}
+
+/* Specialised version for projects */
+
+function pgproject($filename,$title) {
+ smallpage("projects/$filename.html",$title,"Proof General Project",$title);
+}
+
diff --git a/html/gallery b/html/gallery
new file mode 100644
index 00000000..7342616d
--- /dev/null
+++ b/html/gallery
@@ -0,0 +1,6 @@
+<?php include('gallery.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?>
+
diff --git a/html/gallery.php b/html/gallery.php
new file mode 100644
index 00000000..035136f1
--- /dev/null
+++ b/html/gallery.php
@@ -0,0 +1,84 @@
+<?php
+ require('functions.php3');
+ small_header("Proof General Gallery");
+ ?>
+
+<blockquote>
+<p>
+Here are some publicity pictures for Proof General. They were created
+by David Aspinall in his spare time, using the excellent freeware
+programs <a href="http://www.gimp.org">GIMP</a> and <a
+href="http://www.blender.nl">Blender</a>. The General himself is
+based on a commercial mesh given away by
+<a href="http://www.viewpoint.com">Viewpoint</a>.
+</p>
+<p>
+Click on a thumbnail to see a full-size images. All full-size images
+are 720x990 pixel JPGs (a nice size to print at 180dpi on A5 paper).
+Please download and print for your own use!
+<p>
+Copyright for the images is held by
+<a href="http://www.dcs.ed.ac.uk/home/da">David Aspinall</a>.
+Please do not publish the images or incorporate them into other
+work without his permission. If you have comments or suggestions,
+or if you would like a copy of one of the images
+in another size or format,
+please <a href="feedback">contact us</a>.
+</p>
+
+</p>
+<p>
+For pictures of what Proof General looks like in use,
+see the <a href="screenshot">screenshots</a> page.
+</p>
+</blockquote>
+
+<!-- todo: php3 this -->
+<table width="80%">
+<tr>
+<td width="200">
+<a href="images/portrait.jpg">
+<img src="images/portrait-thumb.jpg" alt="Portrait" width=150 height=206 border=0>
+</a>
+</td>
+<td>
+<p>
+Proof General portrait <br>
+This is the Proof General logo,
+with the home page URL at the bottom. <br>
+A nice poster for your wall or door. <br>
+</p>
+</tr>
+<tr>
+<td>
+<a href="images/whip.jpg">
+<img src="images/whip-thumb.jpg" alt="New recruit" width=150 height=206 border=0>
+</a>
+</td>
+<td>
+<p>
+New Recruits Wanted <br>
+This is a request for help with the Proof General
+project. <br>
+Please <a href="feedback">sign up here</a>!
+</p>
+</tr>
+<tr>
+<td>
+<a href="images/whole-man.jpg">
+<img src="images/whole-man-thumb.jpg" alt="Whole man" width=150 height=206 border=0>
+</a>
+</td>
+<td>
+<p>
+Scary boots! <br>
+This is a full-length shot of Proof General,
+again with the home page at the bottom.
+</p>
+</tr>
+</table>
+
+<?php
+ click_to_go_back();
+ footer();
+?>
diff --git a/html/head.html b/html/head.html
new file mode 100644
index 00000000..c40263e7
--- /dev/null
+++ b/html/head.html
@@ -0,0 +1,30 @@
+<head>
+ <title><?php print $title ?></title>
+ <meta name="author" content="David Aspinall <da@dcs.ed.ac.uk>">
+ <meta name="keywords" content="Isabelle, LEGO, Coq, Emacs, XEmacs,
+ Interface, Theorem Prover, GUI, David Aspinall">
+ <meta name="description" content="Proof General is an Emacs based
+ generic interface for theorem provers">
+<?php
+/* Did have linked style sheet, with:
+ * <link rel="stylesheet" href="proofgen.css" type="text/css">
+ * Instead, its embedded it to save another server access.
+ */
+ print "<style type=\"text/css\">\n<!--";
+ include("proofgen.css");
+ print "-->\n</style>\n";
+?>
+</head>
+<body
+ bgcolor="#2D1D03"
+ background="images/canvaswallpaper.jpg"
+ text="#FFFFFF"
+ link="#FFD820"
+ vlink="#FFD820"
+ alink="#FFF030"
+ >
+ <!-- Duplicate some style entries in body elt to support Version 3 browsers.
+ FIXME: Shouldn't serve this mess up to V4s and later. -->
+<!-- <font face="Verdana, Arial, LucidaSans, sans-serif;">-->
+
+
diff --git a/html/header.html b/html/header.html
new file mode 100644
index 00000000..c9c59e86
--- /dev/null
+++ b/html/header.html
@@ -0,0 +1,62 @@
+<!-- This is the header -->
+<table width="550">
+<tr>
+<td width="190">
+<a href="">
+<img src="images/ProofGeneral.jpg" alt="Proof General" align=top
+ width=180 height=238 border=0 >
+</a>
+</td>
+<td>
+ <center>
+ <img src="images/pg-text.gif" alt="Proof General" width=175 height=76>
+ <h1>Organize your proofs!</h1>
+<?php
+ /* Header link generator. David Aspinall, June 1999.
+ * Based orginially on navbar.php3 by Douglas Campbell
+ * Look for $WANTED in array. If not found, use default of "Home"
+ * and fix $WANTED. Hrefs are given by page parameter to current doc.
+ */
+ $separator='<td><img src="images/bullethole.gif" width=15 height=15 align="top" alt=".">';
+ $urlbits = parse_url($REQUEST_URI);
+ $file = ereg_replace("^(.*/)+","",$urlbits["path"]);
+ $WANTED = ereg_replace(".html","",$file);
+ print "<table class=\"menubar\"><tr>\n";
+ $links_arr = array(
+ "Home" => "main",
+ "Features" => "features",
+ "Download" => "download",
+ "News" => "news",
+ "Screenshots" => "screenshot",
+ "Documentation" => "doc",
+ "Development" => "devel",
+ "About" => "about",
+ "Links" => "links"
+ );
+ $DEFAULT = $links_arr["Home"];
+ $wanted_okay = 0;
+ for (reset($links_arr); $name = key($links_arr); next($links_arr)) {
+ if ($WANTED == $links_arr[$name]) {
+ $wanted_okay = 1;
+ }
+ };
+ if (! $wanted_okay) {
+ $WANTED = "main";
+ };
+ for (reset($links_arr); $name = key($links_arr); next($links_arr)) {
+ print $separator;
+ if ($WANTED == $links_arr[$name]) {
+ print "<b>" . $name . "</b>";
+ }
+ else {
+ print "<a href=\"$links_arr[$name]\">$name</a>";
+ }
+ print " </td>\n";
+ if ($name=="Download" || $name=="Documentation") print "</tr>\n<tr>";
+ }
+ print "</tr></table>\n";
+?>
+</center>
+</td></tr>
+</table>
+<!-- End of header --> \ No newline at end of file
diff --git a/html/hits b/html/hits
new file mode 100644
index 00000000..6d5c2be6
--- /dev/null
+++ b/html/hits
@@ -0,0 +1,26 @@
+<?php
+ $counterFile = "counter.txt";
+ $counterStart = "counterstart.txt";
+ $maxlen=10;
+ require('functions.php3');
+ small_header("Hit counter");
+ print "<p>";
+ if (is_readable($counterFile)) {
+ print "These pages have been accessed ";
+ readfile($counterFile);
+ print " times ";
+ if (is_readable($counterStart)) {
+ $fp=fopen($counterStart,"r");
+ $start=fgets($fp,20);
+ print "since ";
+ print strftime("%d %B %Y",$start);
+ print ".\n";
+ } else {
+ print "<br>\n(could not access time stamp file $counterStart)\n";
+ };
+ } else {
+ echo "Could not access hit counter file $counterFile\n";
+ };
+ print "</p>";
+ footer();
+?>
diff --git a/html/htmlshow.html b/html/htmlshow.html
new file mode 100644
index 00000000..d9cb8b46
--- /dev/null
+++ b/html/htmlshow.html
@@ -0,0 +1,5 @@
+<?php
+ require('functions.php3');
+ hack_html($file,$title);
+ footer();
+?>
diff --git a/html/htmlshow.php b/html/htmlshow.php
new file mode 100644
index 00000000..915aac6f
--- /dev/null
+++ b/html/htmlshow.php
@@ -0,0 +1,11 @@
+<?php
+ require('functions.php3');
+ if (substr($file,0,1)=="." or
+ substr($file,0,1)=="/" or
+ substr($file,0,1)=="~") {
+ print "Sorry, can't show you that file!\n";
+ } else {
+ hack_html($file,$title);
+ }
+ footer();
+?>
diff --git a/html/images/.cvsignore b/html/images/.cvsignore
new file mode 100644
index 00000000..5c165d91
--- /dev/null
+++ b/html/images/.cvsignore
@@ -0,0 +1 @@
+.xvpics
diff --git a/html/images/IsaPGscreen.jpg b/html/images/IsaPGscreen.jpg
new file mode 100644
index 00000000..5e2dda74
--- /dev/null
+++ b/html/images/IsaPGscreen.jpg
Binary files differ
diff --git a/html/images/PG-small.jpg b/html/images/PG-small.jpg
new file mode 100644
index 00000000..50bb9cf6
--- /dev/null
+++ b/html/images/PG-small.jpg
Binary files differ
diff --git a/html/images/ProofGeneral.jpg b/html/images/ProofGeneral.jpg
new file mode 100644
index 00000000..d2c430cd
--- /dev/null
+++ b/html/images/ProofGeneral.jpg
Binary files differ
diff --git a/html/images/bullethole.gif b/html/images/bullethole.gif
new file mode 100644
index 00000000..1eb03072
--- /dev/null
+++ b/html/images/bullethole.gif
Binary files differ
diff --git a/html/images/canvaswallpaper.jpg b/html/images/canvaswallpaper.jpg
new file mode 100644
index 00000000..8062bd4e
--- /dev/null
+++ b/html/images/canvaswallpaper.jpg
Binary files differ
diff --git a/html/images/coq-badge.gif b/html/images/coq-badge.gif
new file mode 100644
index 00000000..901e7645
--- /dev/null
+++ b/html/images/coq-badge.gif
Binary files differ
diff --git a/html/images/coqlogo4.gif b/html/images/coqlogo4.gif
new file mode 100644
index 00000000..5899de81
--- /dev/null
+++ b/html/images/coqlogo4.gif
Binary files differ
diff --git a/html/images/coqlogo4.xcf b/html/images/coqlogo4.xcf
new file mode 100644
index 00000000..21cd46cb
--- /dev/null
+++ b/html/images/coqlogo4.xcf
Binary files differ
diff --git a/html/images/isabelle-badge.gif b/html/images/isabelle-badge.gif
new file mode 100644
index 00000000..8da95453
--- /dev/null
+++ b/html/images/isabelle-badge.gif
Binary files differ
diff --git a/html/images/isabelle.gif b/html/images/isabelle.gif
new file mode 100644
index 00000000..171b2101
--- /dev/null
+++ b/html/images/isabelle.gif
Binary files differ
diff --git a/html/images/lego-badge.gif b/html/images/lego-badge.gif
new file mode 100644
index 00000000..182ad85f
--- /dev/null
+++ b/html/images/lego-badge.gif
Binary files differ
diff --git a/html/images/pg-coq-screenshot.png b/html/images/pg-coq-screenshot.png
new file mode 100644
index 00000000..eb071514
--- /dev/null
+++ b/html/images/pg-coq-screenshot.png
Binary files differ
diff --git a/html/images/pg-coq-thumb.png b/html/images/pg-coq-thumb.png
new file mode 100644
index 00000000..1510b502
--- /dev/null
+++ b/html/images/pg-coq-thumb.png
Binary files differ
diff --git a/html/images/pg-isa-screenshot.png b/html/images/pg-isa-screenshot.png
new file mode 100644
index 00000000..e903e4e3
--- /dev/null
+++ b/html/images/pg-isa-screenshot.png
Binary files differ
diff --git a/html/images/pg-isa-thumb.png b/html/images/pg-isa-thumb.png
new file mode 100644
index 00000000..d0db67cc
--- /dev/null
+++ b/html/images/pg-isa-thumb.png
Binary files differ
diff --git a/html/images/pg-isar-screenshot.png b/html/images/pg-isar-screenshot.png
new file mode 100644
index 00000000..6ea369de
--- /dev/null
+++ b/html/images/pg-isar-screenshot.png
Binary files differ
diff --git a/html/images/pg-isar-thumb.png b/html/images/pg-isar-thumb.png
new file mode 100644
index 00000000..bc558d56
--- /dev/null
+++ b/html/images/pg-isar-thumb.png
Binary files differ
diff --git a/html/images/pg-lego-console-thumb.png b/html/images/pg-lego-console-thumb.png
new file mode 100644
index 00000000..0a44450a
--- /dev/null
+++ b/html/images/pg-lego-console-thumb.png
Binary files differ
diff --git a/html/images/pg-lego-console.png b/html/images/pg-lego-console.png
new file mode 100644
index 00000000..0e7c22a3
--- /dev/null
+++ b/html/images/pg-lego-console.png
Binary files differ
diff --git a/html/images/pg-lego-screenshot.png b/html/images/pg-lego-screenshot.png
new file mode 100644
index 00000000..e8c6b749
--- /dev/null
+++ b/html/images/pg-lego-screenshot.png
Binary files differ
diff --git a/html/images/pg-lego-thumb.png b/html/images/pg-lego-thumb.png
new file mode 100644
index 00000000..6f650baa
--- /dev/null
+++ b/html/images/pg-lego-thumb.png
Binary files differ
diff --git a/html/images/pg-text.gif b/html/images/pg-text.gif
new file mode 100644
index 00000000..acab510e
--- /dev/null
+++ b/html/images/pg-text.gif
Binary files differ
diff --git a/html/images/portrait-thumb.jpg b/html/images/portrait-thumb.jpg
new file mode 100644
index 00000000..d84d27b4
--- /dev/null
+++ b/html/images/portrait-thumb.jpg
Binary files differ
diff --git a/html/images/portrait.jpg b/html/images/portrait.jpg
new file mode 100644
index 00000000..a23f0f16
--- /dev/null
+++ b/html/images/portrait.jpg
Binary files differ
diff --git a/html/images/silverrule.gif b/html/images/silverrule.gif
new file mode 100644
index 00000000..3ad7fbda
--- /dev/null
+++ b/html/images/silverrule.gif
Binary files differ
diff --git a/html/images/vh40.gif b/html/images/vh40.gif
new file mode 100644
index 00000000..c5e9402e
--- /dev/null
+++ b/html/images/vh40.gif
Binary files differ
diff --git a/html/images/whip-thumb.jpg b/html/images/whip-thumb.jpg
new file mode 100644
index 00000000..16aac5b4
--- /dev/null
+++ b/html/images/whip-thumb.jpg
Binary files differ
diff --git a/html/images/whip.jpg b/html/images/whip.jpg
new file mode 100644
index 00000000..1a6341b6
--- /dev/null
+++ b/html/images/whip.jpg
Binary files differ
diff --git a/html/images/whole-man-thumb.jpg b/html/images/whole-man-thumb.jpg
new file mode 100644
index 00000000..32175a27
--- /dev/null
+++ b/html/images/whole-man-thumb.jpg
Binary files differ
diff --git a/html/images/whole-man.jpg b/html/images/whole-man.jpg
new file mode 100644
index 00000000..f3fff341
--- /dev/null
+++ b/html/images/whole-man.jpg
Binary files differ
diff --git a/html/index.php b/html/index.php
new file mode 100644
index 00000000..5d90977c
--- /dev/null
+++ b/html/index.php
@@ -0,0 +1,9 @@
+<?php require('functions.php3'); ?>
+<html>
+<?php include('head.html'); ?>
+<?php
+ include('header.html');
+ include($WANTED . '.html' . $WANTEDFRAG);
+ footer();
+?>
+
diff --git a/html/index.shtml b/html/index.shtml
new file mode 100644
index 00000000..d4bdff95
--- /dev/null
+++ b/html/index.shtml
@@ -0,0 +1,3 @@
+<!-- This is the entry point to the Proof General web pages -->
+<!--#include file="counter.php3"-->
+<!--#include file="index.php"-->
diff --git a/html/kit b/html/kit
new file mode 100644
index 00000000..d7ba8cb2
--- /dev/null
+++ b/html/kit
@@ -0,0 +1,5 @@
+<?php include('kit.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?>
diff --git a/html/kit.html b/html/kit.html
new file mode 100644
index 00000000..d7ba8cb2
--- /dev/null
+++ b/html/kit.html
@@ -0,0 +1,5 @@
+<?php include('kit.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?>
diff --git a/html/kit.php b/html/kit.php
new file mode 100644
index 00000000..4612071e
--- /dev/null
+++ b/html/kit.php
@@ -0,0 +1,49 @@
+<?php
+ require('functions.php3');
+ small_header("Proof General Kit");
+ ?>
+
+<p>
+The Proof General Kit project is in an early pre-experimental stage at
+the moment. If you are interested in collaborating, or have ideas
+or suggestions to contribute, please send a note to
+<a href="mailto:kit@proofgeneral.org"><tt>kit@proofgeneral.org</tt></a>
+</p>
+
+<h3>Planning</h3>
+<p>
+Ideas for the future of Proof General are described in these papers:
+</p>
+<ul>
+<li><a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+ <b><i>Protocols for Interactive e-Proof</i></b>.
+ Draft version, see
+ <a href="http://zermelo.dcs.ed.ac.uk/~da/drafts/#eproof">here</a>.
+</li>
+<li><a href="http://www.dcs.ed.ac.uk/home/da">David Aspinall</a>.
+ <b><i>Proof General Kit (white paper)</i></b>.
+ Draft version, see
+ <a href="http://zermelo.dcs.ed.ac.uk/home/da/drafts/#white">here</a>.
+</li>
+</ul>
+
+<h3>Development</h3>
+<p>
+Not much has been started yet.
+<br>
+But you can download the DTDs for PGIP and PGML, here:
+</p>
+<ul>
+<li><?php download_link("Kit/dtd/pgip.dtd") ?>
+</li>
+<li><?php download_link("Kit/dtd/pgml.dtd") ?>
+</li>
+</ul>
+<p>
+Comments and contributions welcomed!
+</p>
+
+<?php
+ click_to_go_back();
+ footer();
+?>
diff --git a/html/links b/html/links
new file mode 100644
index 00000000..a58717d8
--- /dev/null
+++ b/html/links
@@ -0,0 +1,5 @@
+<?php include('index.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?> \ No newline at end of file
diff --git a/html/links.html b/html/links.html
new file mode 100644
index 00000000..d3ca2b61
--- /dev/null
+++ b/html/links.html
@@ -0,0 +1,71 @@
+<h2>Related projects</h2>
+<p>
+Here are some links to related things.
+If you have any suggestions
+for links to include here, please
+<?php hlink("feedback","contact us","Feedback form")?>.
+</p>
+
+<ul>
+<li><a href="http://zermelo.dcs.ed.ac.uk/~isamode">Isamode</a>
+ is an XEmacs front-end for Isabelle. It has a different
+ feature collection compared with Proof General:
+ script management is not supported, but there are extensive
+ menus and shortcuts provided for common Isabelle
+ commands.
+</li>
+</ul>
+<ul>
+<li><a href="http://www-sop.inria.fr/croap/ctcoq/ctcoq-eng.html">CtCoq</a>
+ is an interface for the Coq theorem prover, developed
+ at INRIA, Sophia Antipolis, as part of
+ <a href="http://www-sop.inria.fr/croap/">Projet CROAP</a>.
+ Like Proof General, CtCoq is based on a general approach for
+ building user-interfaces for theorem provers, although no other
+ current theorem provers are supported. Unlike Proof General, CtCoq
+ is based on a graphical environment with structure editing,
+ created with the <a
+ href="http://www-sop.inria.fr/croap/centaur/centaur.html">Centaur</a>
+ system.
+</li>
+</ul>
+<ul>
+<li>
+ <a href="http://www.ags.uni-sb.de/~omega/">OMEGA</a> is
+ a collection of web-based distributed tools for supporting
+ theorem proving.
+</li>
+</ul>
+<ul>
+<li>
+ <a href="http://www.dcs.gla.ac.uk/prosper/">Prosper</a> is a project
+ to develop an extensible, open proof tool architecture for
+ incorporating formal verification into industrial CAD/CASE tool
+ flows and design methodologies. The tools include novel
+ user-friendly interfaces.
+</li>
+</ul>
+<ul>
+<li>
+ As a possible foundation for generic proof environments,
+ <a href="http://www.nag.co.uk/projects/openmath/omsoc/">OpenMath</a>
+ is a standard representation form for mathematical objects, which
+ links in with the <a href="http://www.w3.org/Math/">MathML</a>
+ markup language.
+</li>
+</ul>
+<ul>
+<li>
+ <a href="http://www.mrg.dist.unige.it/omrs/index.html">Open Mechanized Reasoning System (OMRS)</a>
+</li>
+</ul>
+<ul>
+<li>
+ <a href="http://www.cs.unibo.it/~asperti/HELM/home.html">Hypertextual Electronic Library of Mathematics (HELM)</a>
+</li>
+</ul>
+<ul>
+<li>
+ <a href="http://eti.cs.uni-dortmund.de:8080/servlet/ETI">ETI</a>
+</li>
+</ul>
diff --git a/html/mailinglist b/html/mailinglist
new file mode 100644
index 00000000..b4cfc176
--- /dev/null
+++ b/html/mailinglist
@@ -0,0 +1,99 @@
+<?php
+/*
+ * Proof General mailing list subscription and unsubscription.
+ *
+ * David Aspinall, June 1999.
+ *
+ * $Id$
+ *
+ */
+
+ require('functions.php3');
+ if ($subscribe == ""):
+##
+## Subscription form
+##
+ small_header("Proof General Mailing List");
+ ?>
+<p>
+The mailing list address is
+<a href="mailto:users@proofgeneral.org">
+<tt>users@proofgeneral.org</tt>.
+</a>
+</p>
+
+<p>
+To subscribe or unsubscribe, you can fill in the form below.
+<br>
+Or send a message to
+<a href="mailto:majordomo@proofgeneral.org">
+ <tt>majordomo@proofgeneral.org</tt>
+</a>
+with the words "<tt>subscribe proofgeneral</tt>"
+(or "<tt>unsubscribe proofgeneral"</tt>) in the message body.
+</p>
+
+<p>
+Since its beginning, the mailing list has been a low-volume list (one
+message every few months). If the volume increases significantly due
+to user interaction, we will introduce a separate mailing list for
+announcements.
+</p>
+
+<h2>Mailing list subscription</h2>
+
+<form method=post action="<?php echo $PHP_SELF; ?>">
+<table width="300" border="0" cellspacing="2" cellpadding="0">
+<tr>
+ <td width="30%">Your name:</td>
+ <td width="70%"><input type=text name="name" size="40"></td>
+</tr>
+<tr>
+ <td width="30%">Email address:</td>
+ <td width="70%"><input type=text name="email" size="40"></td>
+</tr>
+<tr>
+ <td width="30%"><input type=radio name="subscribe" value="yes" checked></td>
+ <td width="70%">Please add me to the mailing list.</td>
+</tr>
+<tr>
+ <td width="30%"><input type=radio name="subscribe" value="no"></td>
+ <td width="70%">Please remove me from the mailing list.</td>
+</tr>
+</table>
+<input type=submit value="Send request">
+</form>
+<p>
+</p>
+<?php
+ click_to_go_back();
+ footer();
+
+ else:
+##
+## Process subscription
+##
+ $title = ($subscribe == "yes" ? "Subscription" : "Unsubscription") . " Request";
+ small_header($title);
+
+ $request = ($subscribe == "yes" ? "join" : "be removed");
+
+ $message = ($subscribe == "yes" ? "subscribe " : "unsubscribe ")
+ . "proofgeneral";
+ mail("majordomo@dcs.ed.ac.uk",
+ "[Web form from ~proofgen]",
+ $message,
+ "Reply-To: " . $email . "\nFrom: " . $email);
+
+ if ($from != "") { print "<p>Dear " . $from . ",</p>\n"; };
+ print "<p>";
+ print "Your request to " . $request . " the proof general mailing list has been submitted.<br>";
+ print "Thank-you!";
+ print "</p>\n<p>";
+
+ click_to_go_back();
+
+ footer();
+ endif;
+?>
+
diff --git a/html/mailinglist.html b/html/mailinglist.html
new file mode 100644
index 00000000..59a74d27
--- /dev/null
+++ b/html/mailinglist.html
@@ -0,0 +1,6 @@
+<?php include('mailinglist'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?>
+
diff --git a/html/main b/html/main
new file mode 100644
index 00000000..a58717d8
--- /dev/null
+++ b/html/main
@@ -0,0 +1,5 @@
+<?php include('index.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?> \ No newline at end of file
diff --git a/html/main.html b/html/main.html
new file mode 100644
index 00000000..3d6e8ea6
--- /dev/null
+++ b/html/main.html
@@ -0,0 +1,154 @@
+<h2>What is Proof General?</h2>
+<p>
+<b>Proof General</b> is a generic interface for proof assistants,
+currently based on Emacs.
+It has been developed at the
+<a href="http://www.lfcs.informatics.ed.ac.uk/">LFCS</a>
+in the <a href="http://www.ed.ac.uk/">University of Edinburgh</a>.
+Proof General
+works best under
+<a href="http://www.xemacs.org/">XEmacs</a>, but can also be used with
+<a href="http://www.gnu.org/software/emacs/">GNU Emacs</a>.
+You need a recent version in either case.
+</p>
+<p>
+The aim of the Proof General project is to provide powerful and
+configurable interfaces which help user-interaction with interactive
+proof assistants. The strategy of Proof General is to target power
+users rather than novices, building an environment for <i>proof
+engineering</i>. But we include modern user interface features, such
+as toolbar and menus, which make use easier for all. Proof General is
+currently used by many people for organizing large proof developments,
+and also for teaching interactive proof.
+<p>
+To read more about what Proof General
+provides,
+<a href="features">check the features list</a>.
+To see what Proof General looks like in use, have a look at these
+<a href="screenshot">screenshots</a>.
+To download Proof General, visit the
+<a href="download">download page</a>.
+To contact the developers, click
+<?php hlink("feedback","here","Feedback form")?>.
+</p>
+
+
+
+<h2>What systems does Proof General work with?</h2>
+<p>
+Proof General comes ready-customized for these proof assistants:
+</p>
+
+<table width="90%">
+ <tr>
+ <td align="center">
+ <?php hlink("http://pauillac.inria.fr/coq/",
+ "<img src=\"images/coqlogo4.gif\" width=66 height=61 border=0 alt=\"Coq badge\">","The Coq Home Page") ?>
+ </td>
+ <td>
+ <b><?php fileshow("ProofGeneral/coq/README","Coq Proof General "); ?></b> for
+ <?php hlink("http://pauillac.inria.fr/coq/",
+ "Coq","The Coq Home Page") ?>
+ <br>
+ <div style="font-size: smaller">
+ First crafted by
+ <a href="http://www.dcs.ed.ac.uk/~hhg">Healfdene Goguen</a>.
+ <br>
+ Contributions by Patrick Loiseleur.
+ <br>
+ Maintained by
+ <a href="mailto:courtieu@lri.fr">Pierre Courtieu</a>.
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">
+ <?php hlink("http://www.cl.cam.ac.uk/Research/HVG/Isabelle/",
+ "<img src=\"images/isabelle.gif\" width=74 height=64 border=0 alt=\"Isabelle badge\">",
+ "The Isabelle Home Page"); ?>
+ </td>
+ <td><b><?php fileshow("ProofGeneral/isa/README","Isabelle Proof General "); ?></b> for
+ <?php hlink("http://www.cl.cam.ac.uk/Research/HVG/Isabelle/",
+ "Isabelle", "The Isabelle Home Page"); ?>
+ <br>
+ <div style="font-size: smaller">
+ Crafted and maintained by
+ <a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+ <br>
+ Additional maintainance, support for
+ <a href="http://isabelle.in.tum.de/Isar">Isabelle/Isar</a>
+ by
+ <a href="http://www.in.tum.de/~wenzelm/">Markus Wenzel</a>.
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">
+ <?php hlink("http://www.dcs.ed.ac.uk/home/lego",
+ "<img src=\"images/lego-badge.gif\" width=123 height=33 border=0 alt=\"LEGO badge\">",
+ "The LEGO Home Page") ?>
+ </td>
+ <td><b><?php fileshow("ProofGeneral/lego/README","LEGO Proof General "); ?></b> for
+ <?php hlink("http://www.dcs.ed.ac.uk/home/lego",
+ "LEGO","The LEGO Home Page") ?>
+ <br>
+ <div style="font-size: smaller">
+ First crafted by <a href="http://www.dcs.ed.ac.uk/~tms">Thomas Kleymann</a>
+ and
+ <a href="http://www.dcs.ed.ac.uk/~djs/welcome.html">Dilip Sequeira</a>.
+ <br>
+ Maintained by
+ <a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>
+ and
+ <a href="http://www.dur.ac.uk/p.c.callaghan/">Paul Callaghan</a>.
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">
+ <?php hlink("http://www.lama.univ-savoie.fr/~RAFFALLI/af2.html",
+ "PhoX",
+ "The PhoX Home Page") ?>
+ </td>
+ <td><b><?php fileshow("ProofGeneral/phox/README","PhoX Proof General "); ?></b> for
+ <?php hlink("http://www.lama.univ-savoie.fr/~RAFFALLI/af2.html",
+ "PhoX","The PhoX Home Page") ?>
+ <br>
+ <div style="font-size: smaller">
+ Crafted and maintained by
+ <a href="http://www.lama.univ-savoie.fr/~RAFFALLI">Christophe Raffalli</a>
+ and
+ <a href="mailto:roziere@logique.jussieu.fr">Paul Roziere</a>.
+ </div>
+ </td>
+ </tr>
+</table>
+<p>
+There are also <i>experimental</i> instances of Proof General:
+<ul>
+<li><b><?php fileshow("ProofGeneral/hol98/README","HOL Proof General"); ?></b>,
+for <a href="http://www.cl.cam.ac.uk/Research/HVG/HOL/HOL.html">HOL98</a>.
+</li>
+<li><b><?php fileshow("ProofGeneral/twelf/README","Twelf Proof General"); ?></b>,
+for <a href="http://www.twelf.org">Twelf</a>.
+</li>
+<li><b><?php fileshow("ProofGeneral/acl2/README","ACL2 Proof General"); ?></b>,
+for <a href="http://www.cs.utexas.edu/users/moore/acl2">ACL2</a>.
+</li>
+</ul>
+<p>
+These instances of Proof General are functional, but only show a bare
+fraction of what is possible. We are
+seeking volunteers to support and improve each of these
+(please <a href="feedback">send a note to
+ <tt><?php print $project_feedback; ?></tt></a> if you're interested).
+</p>
+<p>
+Proof General is ready to be customized to new proof assistants.
+It can be <?php fileshow("ProofGeneral/demoisa/demoisa-easy.el",
+"very easy"); ?> to get basic support working.
+Full <a href="ProofGeneral/doc/PG-adapting.pdf">documentation on
+configuration</a> is provided.
+</p>
+
+
diff --git a/html/mission.html b/html/mission.html
new file mode 100644
index 00000000..a0203092
--- /dev/null
+++ b/html/mission.html
@@ -0,0 +1,136 @@
+<?php
+ require('functions.php3');
+ small_header("Proof General Mission (draft)");
+ ?>
+
+<center>
+<h2>Mission Statement</h2>
+<h2>Proof General Developers</h2>
+<h2>March 2000</h2>
+</center>
+
+<p>
+We seek to provide an interface suite for helping users interact with
+<a href="#pas"><i>proof assistants</i></a>.
+</p>
+
+<p>
+Our approach is based on these principles:
+<ul>
+<li>
+Be useful to both <a href="#experts"><i>experts and novices</i></a>.
+</li>
+<li>
+Be <a href="scalable"><i>scalable</i></a> to large proof developments.
+</li>
+<li>
+Be <a href="#learn"><i>easy to learn</i></a>,
+yet still provide advanced features.
+</li>
+<li>
+Be <a href="#generic"><i>generic</i></a>
+to support many proof assistants with
+a uniform interaction mechanism.
+</li>
+<li>
+Be a <a href="#quality"><i>high-quality</i></a> research prototype.
+</li>
+</ul>
+</p>
+<p>
+Above all, we take a <i>pragmatic</i> approach to constructing
+interfaces. Our primary aim is to provide a tool which is
+immediately useful for proof engineering.
+</p>
+<p>
+This aim means that we harness a range of
+<a href="#proven">proven techniques</a>
+reimplemented in our generic system.
+Nevertheless, by the act of constructing Proof General, we do invent
+and incorporate some <a href="#novel">novel advances</a> which
+contribute to research in the field.
+</p>
+
+<hr>
+<p>
+</p>
+<h2>Footnotes and elaboration</h2>
+
+<dl>
+<?php dt("Proof assistants.","pas") ?>
+<dd>
+Computer programs for constructing formal machine proofs. Terminology
+varies; we include all kinds of theorem proving systems
+which involve user interaction while a proof is constructed.
+We currently focus on systems based on a notion of <i>proof
+script</i>, which is a file containing a user-level representation
+of the proof or how it was constructed.
+</dd>
+<?php dt("Experts and novices.","experts") ?>
+<dd>
+Many interfaces for proof assistants are aimed at novice or beginner
+users (and often used for teaching). Instead, we want to provide an
+interface which is useful for expert users in the first place.
+But we believe such a system can also be helpful for beginner users.
+</dd>
+<?php dt("Scalability.","scalable") ?>
+<dd>
+Some interfaces fail to scale to large proof developments;
+we want Proof General to be useful for real-life, large
+projects, consisting of many theorems and theories.
+</dd>
+<?php dt("Easy to learn.","learn") ?>
+<dd>
+It is difficult enough to learn how to use the logic and language
+of a proof assistant, without an extra effort for learning its
+interface. We want to provide a friendly interface with
+intuitive features, hence a shallow learning curve.
+</dd>
+<?php dt("Genericity.","generic") ?>
+<dd>
+Proof General is intended to be used with a variety of underlying
+proof assistants. We appreciate that different proof assistants are
+based on different logical principles, and implement different proof
+languages. Yet interaction between different systems often has a
+similar behaviour. We exploit this to provide a good user interface
+for many systems at once, saving repeated development effort by proof
+assistant implementors. It has the added benefit of providing a
+uniform interaction mechanism between different systems, making it
+easier for users to experiment with several proof assistants.
+</dd>
+<?php dt("High-quality.","quality") ?>
+<dd>
+The developers are working on Proof General in the academic sector,
+and engineering work itself is not directly funded. Despite this, we
+strive to follow good engineering practices to build a robust and
+maintainable system, which users can easily install (or test on the
+web). To this end, we employ open-source development with frequent
+test releases before stable releases, and high-priority attention to
+user suggestions and bug reports. We use CVS for source control,
+a strategy of bottom-up successive improvement, and provide support
+for each proof assistant by an experienced user/developer.
+</dd>
+<?php dt("Proven techniques.","proven") ?>
+<dd>
+Amongst other features, Proof General currently includes
+<a href="features#script">script management</a>
+and
+<a href="features#pbp">proof-by-pointing</a>
+both championed in
+<a href="http://www-sop.inria.fr/croap/">Projet CROAP</a>.
+</dd>
+<?php dt("Novel advances.","novel") ?>
+<dd>
+Proof General also advances the state-of-the-art.
+For example, we introduced proof-by-pointing in
+an free-form environment,
+and extended script management to handle
+<a href="features#multiple">multiple files</a>.
+</dd>
+</dl>
+
+
+<?php
+ click_to_go_back();
+ footer();
+?>
diff --git a/html/news b/html/news
new file mode 100644
index 00000000..a58717d8
--- /dev/null
+++ b/html/news
@@ -0,0 +1,5 @@
+<?php include('index.php'); ?>
+<?php
+ /* This file needs some extra characters in it for apache to work its magic.
+ Things work fine as link to index.html, but it's tricky to include links
+ in cvs. */ ?> \ No newline at end of file
diff --git a/html/news.html b/html/news.html
new file mode 100644
index 00000000..e7f80cb6
--- /dev/null
+++ b/html/news.html
@@ -0,0 +1,28 @@
+<h2>News about Proof General</h2>
+
+<ul>
+<li><b>11th December 2001</b>
+<p>
+The current <a href="develdownload.html">development release</a> takes
+advantage of the new fancy features available in GNU Emacs 21, to add
+toolbar support and other features there. As usual, maintaining the
+code to work with both Emacs versions is quite troublesome, so bug
+reports and patches from users are very welcome.
+</p>
+</li>
+
+<li><b>10th September 2001</b>
+<p>
+<a href="download">Proof General 3.3</a> is released, with
+<?php fileshow("ProofGeneral-3.3/CHANGES","new features"); ?> to
+increase your proof script editing efficiency. Happy proving!
+</p>
+</li>
+</ul>
+<!-- da: Put this line in instead if you're not me -->
+<!-- <i>(News items entered by <a href="http://www.dcs.ed.ac.uk/~da">David Aspinall</a> -->
+<!-- unless noted.)</i> -->
+<i>News items by <a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.</i>
+<br>
+<i>Click <a href="oldnews.html">here</a> for old news.</i>
+</p>
diff --git a/html/notes.txt b/html/notes.txt
new file mode 100644
index 00000000..7d73ce30
--- /dev/null
+++ b/html/notes.txt
@@ -0,0 +1,56 @@
+Developers' Notes about Web Pages
+---------------------------------
+
+NEW: server hacks needed to serve these pages, giving nice urls
+
+ PHP3 module included
+ .html treated as application
+
+ Mime magic configured:
+
+LoadModule mime_magic_module modules/mod_mime_magic.so
+AddModule mod_mime_magic.c
+MimeMagicFile /etc/httpd/conf/magic
+
+to recognize files beginning <?php, by
+ adding this to /etc/httpd/conf/magic:
+
+0 string <?php application/x-httpd-php3
+
+Then add these links:
+
+ news -> index.html
+ doc -> index.html
+
+etc.
+
+***************
+
+Notes about php:
+
+Some functions I've written
+
+ <?php hlink("html file","text","status message")?>
+
+NB: no space after text so you must write
+
+ <?php ... ?> blah
+
+to get a space. Don't put "blah" onto a new line, space will
+be lost!
+
+
+*************
+
+Tell Thomas (& other folk?) to update his home page links to Proof General.
+[Probably okay: Thomas links to image in home directory, but we'll
+ keep that as a copy of images/ProofGeneral.jpg]
+
+*************
+
+Suggestions for improving web pages after Rod reading them:
+
+ - slideshow rather than single screen shot
+ - separate feature list
+ - explain what a proof script is and what script management buys you
+
diff --git a/html/oldnews.html b/html/oldnews.html
new file mode 100644
index 00000000..2cc3c42b
--- /dev/null
+++ b/html/oldnews.html
@@ -0,0 +1,383 @@
+<?php
+ require('functions.php3');
+ small_header("Proof General Old News");
+ ?>
+<ul>
+
+
+<li><b>1st August 2001</b>
+<p>
+The past few months have seen a few more improvements and
+bug fixes to Proof General: many thanks to those who have
+sent us <a href="feedback">useful feedback</a>.
+It's time that we made a proper release, so please try
+out the <a href="develdownload.html">development release</a>
+and help us iron out as many more problems as we can.
+<br>
+Emacs Lisp and the Emacsen libraries has to be one of the
+worst moving target platforms to develop an application on,
+so please help us! Once things are looking good, we'll
+release PG 3.3.
+</p>
+<li><b>8th May 2001</b>
+<p>
+Proof General has had a few quiet improvements since October, which
+appear in the current
+<a href="develdownload.html">development release</a>.
+This version also has some compatibility fixes
+for the recent releases of Emacs (20.7) and XEmacs (21.4).
+</p>
+
+<li><b>2nd October 2000</b>
+<p>
+Proof General 3.2 is released today. Happy proving!
+</p>
+
+<li><b>25th Sep 2000</b>
+<p>
+Final week of testing for Proof General 3.2.
+The last chance to report bugs or request (minor) improvements for this release.
+Please help us by trying out the
+<a href="develdownload.html">pre-release</a>, especially if you are
+relying on an older or non-standard Emacs version.
+Also check to see if the new
+manuals are useful: now split into
+the user manual in
+<?php htmlshow("ProofGeneral/doc/ProofGeneral_toc.html","HTML","Proof General manual") ?>,
+<?php download_link("ProofGeneral/doc/ProofGeneral.ps.gz", "ps") ?>
+or
+<?php download_link("ProofGeneral/doc/ProofGeneral.pdf", "pdf") ?>,
+and the separate "adapting" manual, in
+<?php htmlshow("ProofGeneral/doc/PG-adapting_toc.html","HTML","Adapting Proof General manual") ?>,
+<?php download_link("ProofGeneral/doc/PG-adapting.ps.gz", "ps") ?>
+or
+<?php download_link("ProofGeneral/doc/PG-adapting.pdf", "pdf") ?>.
+(Info files are included in the distribution).
+</p>
+<li><b>14th Sep 2000</b>
+<p>
+Improvements to web pages. Graphics made smaller, text more concise.
+Please <?php hlink("feedback","send me suggestions ","Feedback form")?>
+for further improvements.
+(I know some pages display poorly in Netscape 4.7x because
+of patchy stylesheet support; they appear much better in IE5
+or the rather impressive recent versions of KDE's Konqueror).
+</p>
+<li><b>28th Aug 2000</b>
+<p>
+We're starting the testing phase for Proof General 3.2.
+It has several new features and improvements.
+Please try out the <a href="develdownload.html">pre-release</a>
+version, and report any problems to us. Your
+feedback is very important because we have no resources available for
+serious compatibility testing ourselves.
+</p>
+<p>
+We hope to release 3.2 by the end of September.
+</p>
+</li>
+<li><b>25th May 2000</b>
+<p>
+Minor patch 3.1.6 released today. This turns off toolbar enablers if
+you're running XEmacs on Solaris; because of strange Solaris problems,
+buttons are disabled too often there. (You can live without
+this part of the patch by customizing the variable
+<tt>proof-toolbar-use-button-enablers</tt>).
+The patch also removes
+the use of an "interval timer" when
+<tt>proof-toolbar-use-button-enablers</tt> is off, since a user
+reported being unable to start itimers unless
+running as root (likely an operating system configuration problem).
+Thanks to Markus Wenzel and Pierre Lescanne for reporting problems.
+</p>
+</li>
+<li><b>9th May 2000</b>
+<p>
+New! For developers, a web-browsable
+mirror of the Proof General cvs is available
+<a href="http://www.proofgeneral.org/cgi-bin/cvsweb.cgi">here</a>.
+</p>
+<li><b>5th May 2000</b>
+<p>
+New!
+Proof General <?php fileshow("ProofGeneral/FAQ", "FAQ");?>.
+Please send questions or suggestions for inclusion to
+<a href="mailto:proofgen@dcs.ed.ac.uk">proofgen@dcs.ed.ac.uk</a>,
+thanks.
+</p>
+<li><b>28th April 2000</b>
+<p>
+A minor patch to Proof General 3.1 is released today. To check what
+version you have, look at the variable <tt>proof-general-version</tt>
+set in <tt>proof-site.el</tt>. (It is not recorded in the tar file
+name or package version). The current patch, to 3.1.4, was made to
+fix a problem with Isabelle and theory file retraction, accidently
+introduced in 3.1. See <?php
+fileshow("ProofGeneral-3.1-devel/etc/release-log.txt","the developer's
+release log"); ?> for details.
+NB: This patch was first made on 4th April, but didn't quite solve the
+problem. Thanks to Mike Squire for sending a patch to fix the fix.
+</p>
+<p>
+Further improvements are being introduced in the new 3.2 pre-releases,
+see the
+<a href="develdownload.html">development download</a> page, as usual.
+</p>
+<li><b>23rd March 2000</b>
+<p>
+Proof General 3.1 is now available from the
+<a href="download">download page</a>. Enjoy!
+</p>
+</li>
+<li><b>14th March 2000</b>
+<p>
+Release candidate for Proof General 3.1 available.
+Pre-releases from now on are release candidates for version 3.1.
+Please test and report any problems you find
+(check the CHANGES and BUGS lists for issues known about
+and/or resolved). Version 3.1 should be released next week.
+</p>
+</li>
+<li><b>10th March 2000</b>
+<p>
+New: <b>HOL Proof General</b>!
+It took me only a couple of hours to add a basic instantiation of
+ProofGeneral for
+<a href="http://www.cl.cam.ac.uk/Researc/HVG/HOL/HOL.html">HOL98</a>.
+Most of this time was in trying to find out how to do things in HOL,
+I could have done with a HOL user to hand. But I thought it was high time
+HOL got a look-in.
+</p>
+<p>
+HOL Proof General provides script management support, automatic
+multiple files, decoration of proof scripts and output.
+Character-sequence X Symbols as in Coq and LEGO. Although this is a
+basic feature set for Proof General, the result is still an enormous
+improvement over shell interaction.
+</p>
+<p>
+My hope is to entice HOL users so that one of them may improve HOL
+Proof General. I don't plan to maintain or seriously improve this
+instantiation myself.
+</p>
+<p>
+The HOL support is shipping in the
+current <a href="develdownload.html">development release</a>.
+</p>
+</li>
+<li><b>15th February 2000</b>
+<p>
+There is now a new
+<a href="devel">page for developers</a>.
+I plan to apply for funding to continue managing the evolution
+and development of Proof General, once my own job position
+is more secure.
+Now is the time to flesh out ideas
+for the future!
+Check the development page for the
+latest proposals. These include some desirable contributions
+which could be undertaken as self-contained projects.
+</p>
+<li><b>9th February 2000</b>
+<p>
+Countdown to Proof General 3.1 begins. This will be a bug fix releaase.
+A few bugs have been fixed in
+recent Proof General development releases, one important one is fixing
+support for non-mule versions of GNU Emacs (thanks to Pierre Courtieu
+for raising it to my attention). I would like to release PG 3.1 next
+month so that everyone can benefit.
+</p>
+<p>
+In the meantime, please
+<?php
+ hlink("feedback","report any important problems ","Feedback form")?>
+that you would like to see fixed, and consider trying out
+the current <a href="devel">development release</a>.
+</p>
+<li><b>14th December 1999</b>
+<p>
+I'm pleased to say that Proof General will be demonstrated at
+<a href="http://iks.cs.tu-berlin.de/etaps2000/etaps.html">ETAPS 2000</a>.
+Here are some draft <a href="papers/pgtalk.pdf">slides</a> for
+the presentation
+(any <a href="mailto:da@dcs.ed.ac.uk">comments</a> would be welcome).
+A presentation of Proof General based on these slides was given at
+<a href="http://www.clrc.ac.uk/">Rutherford Appleton Laboratory</a> last week.
+</p>
+<li><b>26th November 1999</b>
+<p>
+Proof General 3.0 is released!
+</p>
+<li><b>17th November 1999</b><br>
+<p>
+Proof General 3.0 is currently in final testing, and will be released
+in a small number of days. Please help me with this by testing the
+current <a href="devel">pre-release</a>, so I can iron out as
+many bugs as possible before making the release. It's very easy to
+install or upgrade Proof General, so it shouldn't be much effort to
+test it quickly. Particularly if you're already running an earlier
+version.
+</p>
+<li><b>16th November 1999</b><br>
+<p>
+New! With Proof General 3.0, adapting to a new prover is easier
+than ever before!
+It includes an
+ <?php fileshow("ProofGeneral/demoisa/demoisa-easy.el", "example instance ");?>
+of Proof General for Isabelle, which
+configures the main core of the interface with less than 30 lines of
+code. Not bad for getting about 4000 lines worth of code in benefit!
+</p>
+<li><b>9th November 1999</b><br>
+<p>
+Isabelle 99 was released last week, and Proof General 3.0 should
+be ready for release in the next week or so. In
+the meantime, please use the current
+<a href="develdownload.html">pre-release</a>
+for Isabelle 99.
+</p>
+<p>
+Some recent changes have been made to the support for
+<a href="http://www.fmi.uni-passau.de/~wedler/x-symbol/">X-Symbol</a>,
+so that it is easier to turn on and off, and support is now
+properly generic. At the moment only Isabelle has
+support implemented.
+</p>
+<li><b>21st October 1999</b><br>
+ <p>
+ See what Proof General 3.0 will look like!
+ The <a href="screenshot.html">screenshot</a> has been updated.
+ </p>
+<li><b>14th October 1999</b><br>
+ <p>
+ The next version of Proof General will be 3.0.
+ </p>
+ <p>
+ There have been significant changes to the core of
+ Proof General and many improvements in the code.
+ Extra features have been added, and the ones already
+ there improved upon. Usability has been a particular
+ focus. Adding new provers has been made easier.
+ Installation will be made even easier.
+ All of these changes warrant moving to a major release!
+ </p>
+ <p>
+ Version 3.0 is planned for release in November.
+ Please test a Version 3.0 pre-release if you can
+ and report any problems.
+ </p>
+<li><b>12th October 1999</b><br>
+ <p>
+ I'm very grateful to
+ <a href="mailto:courtieu@lri.fr">Pierre Courtieu &lt;courtieu@lri.fr&gt;</a>
+ for offering to help work on Coq Proof General.
+ <br>
+ If anyone else in the Coq community would like to assist, please
+ offer still,
+ there is plenty to do to add: better recognition of proof scripts,
+ multiple file management, proof by pointing, etc...
+ </p>
+<li><b>1st October 1999</b><br>
+ <p>
+ Recently there has been a flurry of work on the next version of Proof
+ General. It has quite a number of improvements (see the <?php
+ fileshow("ProofGeneral/CHANGES","CHANGES"); ?> file), made by myself
+ and Markus Wenzel. <br> The next version is aimed to coincide
+ roughly with the release of Isabelle 99.
+ </p>
+ <p>
+ At the moment we <b>urgently need</b> somebody from the Coq world to
+ maintain and improve Coq Proof General, since Patrick Loiseleur
+ can no longer work on it.
+ Support from the Coq community is vital for Proof General to
+ be a useful tool there. <a href="feedback">Please offer to help</a>,
+ it needn't be a heavy commitment.
+ </p>
+<li><b>13th September 1999</b><br>
+ <p>
+ I've just returned from the
+ <a href="http://www-sop.inria.fr/types-project/types-sum-school.html">Types Summer School, Giens, France</a>
+ where Proof General was used for a class of
+ about 50 students who were learning
+ Coq, Isabelle, and LEGO. I received
+ many useful comments and feedback,
+ which will be
+ used to improve the next version.
+ Thanks to everyone who gave suggestions and bug reports
+ to me, including:
+ Michael Abbott,
+ Bernd Grobauer,
+ Sebastian Skalberg,
+ Thierry Massart,
+ Darmalingum Muthiayen.
+ <br>
+ </p>
+<li><b>27th August 1999</b><br>
+ <p>
+ Print pictures from the new
+ <a href="gallery">gallery</a>
+ of publicity shots of Proof General!
+ </p>
+<li><b>24th August 1999</b><br>
+ <p>
+ Proof General version 2.1 is released.
+ <br>
+ Check the <?php fileshow("ProofGeneral-2.1/CHANGES","CHANGES"); ?> file
+ for a summary of changes since Proof General 2.0.
+ </p>
+ <p>
+ It is recommended that all users upgrade except
+ those still using Isabelle 98-1.
+ <br>
+ Proof General 2.1 supports only the 99 version of Isabelle.
+ </p>
+</li>
+
+<li><b>24th June 1999</b><br>
+ <p>
+ New Proof General web pages go live!
+ </p>
+ <p>
+ The general is now more serious looking.
+ Appropriate, because there are some serious improvements
+ in the pipeline...
+ Before that, we will release Proof General 2.1,
+ mainly a bug-fix improvement of 2.0.
+ </p>
+ <p>
+ Please explore the new web pages and report any problems
+ or suggestions to <?php mlink($project_email); ?>.
+ Please also try out the latest pre-release of Proof General,
+ this is the final chance to get fixes and tweaks
+ sorted before 2.1.
+ </p>
+</li>
+
+<li><b>11th May 1999</b><br>
+ <p>A new instantiation of Proof General has been added by
+ <a href="http://www.dur.ac.uk/~dcs1pcc/">Paul Callaghan</a>
+ for
+ <a href="http://www.dur.ac.uk/CARG/plastic.html">Plastic</a>,
+ a new proof assistant based on
+ Luo's Typed Logical Framework and
+ implemented in Haskell.
+ </p>
+</li>
+
+<li><b>16th April 1999</b><br>
+ <p>A new instantiation of Proof General has been added by
+ <a href="http://www.in.tum.de/~wenzelm/">Markus Wenzel</a>
+ for <a href="http://isabelle.in.tum.de/Isar/">Isabelle/Isar</a>,
+ a new proof language for Isabelle to be included with Isabelle 99.
+ </p>
+</li>
+</ul>
+<p>
+<i>News items by <a href="http://www.dcs.ed.ac.uk/~da">David Aspinall</a>.</i>
+</p>
+
+
+<?php
+ click_to_go_back();
+ footer();
+?>
diff --git a/html/oldrel.php b/html/oldrel.php
new file mode 100644
index 00000000..6d45372c
--- /dev/null
+++ b/html/oldrel.php
@@ -0,0 +1,141 @@
+<?php
+ require('functions.php3');
+ small_header("Previous Releases of Proof General");
+ ?>
+
+<p>
+Please note that we do not support these old releases in any way.
+</p>
+
+<h2>Proof General Version 3.2, released 2nd October 2000</h2>
+<p>
+This version of Proof General has been tested
+with XEmacs 21.1 and (briefly with) FSF Emacs 20.7.
+It supports Coq version 6.3, LEGO version 1.3.1 and
+Isabelle99-1.
+</p>
+
+<ul>
+ <li> gzip'ed tar file:
+ <?php download_link("ProofGeneral-3.2.tar.gz") ?>,
+ <br>
+ or the same thing in a zip file:
+ <?php download_link("ProofGeneral-3.2.zip") ?>,
+ </li>
+ <li> Linux RPM package:
+ <?php download_link("ProofGeneral-3.2-1.noarch.rpm") ?>
+ <br>
+ You probably don't need the
+ <?php download_link("ProofGeneral-3.2-1.src.rpm",
+ "source RPM") ?>.
+ </li>
+</ul>
+
+<p>
+Check the <?php fileshow("ProofGeneral-3.2/CHANGES","CHANGES"); ?> file
+for a summary of changes since version 3.1.
+</p>
+
+<h2>Proof General Version 3.1, released 23rd March 2000</h2>
+
+<p>
+This version of Proof General has been tested
+with XEmacs 21.1 and FSF Emacs 20.4.
+It supports Coq version 6.3, LEGO version 1.3.1 and
+Isabelle99.
+</p>
+
+<ul>
+ <li> gzip'ed tar file:
+ <?php download_link("ProofGeneral-3.1.tar.gz") ?>
+ <br>or zip file:
+ <?php download_link("ProofGeneral-3.1.zip") ?>,
+ </li>
+ <li> RPM package:
+ <?php download_link("ProofGeneral-3.1-1.noarch.rpm") ?>
+ <br>
+ The
+ <?php download_link("ProofGeneral-3.1-1.src.rpm",
+ "source RPM") ?>.
+ </li>
+</ul>
+<p>
+Check the <?php fileshow("ProofGeneral-3.1/CHANGES","CHANGES"); ?> file
+for a summary of changes since version 3.0.
+</p>
+
+
+
+<h2>Proof General Version 3.0, released 26th November 1999</h2>
+
+<p>
+This version of Proof General has been tested
+with XEmacs 20.4, XEmacs 21.1.8 and FSF Emacs 20.5.<br>
+It supports Coq version 6.3, LEGO version 1.3.1 and Isabelle99.
+</p>
+<ul>
+ <li> gzip'ed tar file:
+ <?php download_link("ProofGeneral-3.0.tar.gz") ?>
+ </li>
+ <li> Linux RPM package:
+ <?php download_link("ProofGeneral-3.0-1.noarch.rpm") ?>
+ <br>
+ The source RPM is
+ <?php download_link("ProofGeneral-3.0-1.noarch.rpm","here") ?>.
+ </li>
+</ul>
+<p>
+Check the <?php fileshow("ProofGeneral-3.0/CHANGES","CHANGES"); ?> file
+for a summary of changes since version 2.1.
+</p>
+
+
+
+<h2>Proof General Version 2.1, released 24th August 1999</h2>
+
+<p>
+This version of Proof General has been tested
+with XEmacs 20.4, XEmacs 21 and FSF Emacs 20.3.<br>
+It supports Coq version 6.3, LEGO version 1.3.1 and
+some pre-release versions of Isabelle version 99.
+<ul>
+ <li> gzip'ed tar file:
+ <?php download_link("ProofGeneral-2.1.tar.gz") ?>
+ </li>
+ <li> Linux RPM package:
+ <?php download_link("ProofGeneral-2.1-1.noarch.rpm") ?>
+ <br>
+ The source RPM is
+ <?php download_link("ProofGeneral-2.1-1.noarch.rpm","here") ?>.
+ </li>
+</ul>
+<p>
+Check the <?php fileshow("ProofGeneral-2.1/CHANGES","CHANGES"); ?> file
+for a summary of changes since version 2.0.
+</p>
+
+
+<h2>Proof General Version 2.0, released 16th December 1998</h2>
+
+<p>
+This version of Proof General has been tested
+with XEmacs 20.4 and FSF Emacs 20.2, 20.3.<br>
+It supports Coq version 6.2, LEGO version 1.3.1, and
+Isabelle version 98-1.<br>
+</p>
+<ul>
+ <li> gzip'ed tar file:
+ <?php download_link("ProofGeneral-2.0.tar.gz") ?>
+ </li>
+ <li> Linux RPM package:
+ <?php download_link("ProofGeneral-2.0-1.noarch.rpm") ?>
+ <br>
+ The source RPM is
+ <?php download_link("ProofGeneral-2.0-1.noarch.rpm","here") ?>.
+ </li>
+</ul>
+
+<?php
+ click_to_go_back();
+ footer();
+?>
diff --git a/html/papers/pgoutline.pdf b/html/papers/pgoutline.pdf
new file mode 100644
index 00000000..e712bade
--- /dev/null
+++ b/html/papers/pgoutline.pdf
Binary files differ
diff --git a/html/papers/pgoutline.ps.gz b/html/papers/pgoutline.ps.gz
new file mode 100644
index 00000000..632f431a
--- /dev/null
+++ b/html/papers/pgoutline.ps.gz
Binary files differ
diff --git a/html/papers/pgtalk.pdf b/html/papers/pgtalk.pdf
new file mode 100644
index 00000000..18989c20
--- /dev/null
+++ b/html/papers/pgtalk.pdf
Binary files differ
diff --git a/html/projects.html b/html/projects.html
new file mode 100644
index 00000000..a1a6ba8a
--- /dev/null
+++ b/html/projects.html
@@ -0,0 +1,96 @@
+<?php
+ require('functions.php3');
+ small_header("Proof General Projects");
+ ?>
+
+<p>
+Here are some proposals for projects connected to Proof General.
+</p>
+<p>
+The projects are designed as fairly self-contained contributions,
+involving code development and possibly a portion of supporting
+research. They would be ideal projects for interested students
+or researchers.
+</p>
+<p>
+The projects are divided into those which are specific to Proof
+General, and those which would be useful more widely and do not depend
+on Proof General. For more information on a project, click on its
+title.
+</p>
+
+<h2>A. Projects involving Proof General</h2>
+<ol>
+<li><?php pgproject("coqpbp","Proof-by-pointing support for Coq") ?></li>
+<li><?php pgproject("coqfile","Multiple file handling support for Coq") ?></li>
+<li><?php pgproject("isapbp","Proof-by-pointing support for Isabelle") ?></li>
+<li><?php pgproject("outline","Integrating block-structured development and outline mode") ?></li>
+<li><?php pgproject("thybrowse","A Generic Theory Browser") ?></li>
+<li><?php pgproject("pgml","Specification and tools for PGML") ?></li>
+<li><?php pgproject("pgip","A New Protocol for Interactive Proof in Proof General") ?></li>
+<li><?php pgproject("webreplay","A Web-based Proof Replayer for Proof General") ?></li>
+<li><?php pgproject("test","A Test Harness and Test Suite for Proof General") ?></li>
+<li><?php pgproject("hol","Proof General for HOL") ?></li>
+<li><?php pgproject("acs","Implementing Atomic Command Sequences") ?></li>
+</ol>
+
+<h2>B. Projects not directly involving Proof General</h2>
+<ol>
+<li><?php pgproject("mm","Multiplexed Modes for Emacs") ?></li>
+<li><?php pgproject("scrgen","Script General") ?></li>
+<li><?php pgproject("corba","An Experimental CORBA binding for ML") ?></li>
+<li><?php pgproject("reelcase","A ClearCase-like Configuration Management tool for Linux") ?></li>
+</ol>
+
+<p>
+Some projects involve Emacs Lisp. This is the embedded programming
+language inside Emacs. It is very easy to learn, since it is small,
+has a good manual, and has an interactive interpreter. It is easy to
+use, not least because of its <i>self-documenting</i> nature: each
+variable or function is compiled together with documentation of its
+purpose. (Other languages would do well to follow this). It also
+has a powerful source-level debugger, <i>edebug</i>.
+</p>
+
+<!-- template for project pages -->
+<!-- <h2> </h2> -->
+<!-- <p> -->
+<!-- </p> -->
+<!-- <p> -->
+<!-- <b>Skills:</b> -->
+<!-- </p><p> -->
+<!-- <b>Proposer:</b> -->
+<!-- <a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>. -->
+<!-- </p> -->
+
+<p>
+If you are interested in working on any of these projects,
+feel free to discuss with the project proposer or on the
+<a href="devel#develmail">developer's mailing list</a>.
+</p>
+
+<p>
+If you would like to use any of these ideas as a formal project
+proposal for students at your institution, please feel free
+but do <?php hlink("feedback","let us know ","Feedback form")?>
+if some work is begun, to help coordinate efforts.
+NB: the proposer of the project does not guarantee to be available for
+formal supervision or intensive help with the project (but it may be
+possible to find somebody else to do that).
+</p>
+
+<p>
+If you would like to submit a project proposal
+for an improvement or extension of Proof General,
+please send an email or write a description on the
+<?php hlink("feedback","web feedback form","Feedback form")?>.
+Projects should be significant contributions rather than
+incremental improvements (although we welcome the suggestion of those
+too).
+</p>
+
+
+<?php
+ click_to_go_back();
+ footer();
+?>
diff --git a/html/projects/acs.html b/html/projects/acs.html
new file mode 100644
index 00000000..d3768c17
--- /dev/null
+++ b/html/projects/acs.html
@@ -0,0 +1,36 @@
+<h2>Implementing Atomic Command Sequences</h2>
+<p>
+In Proof General, the blue region of a script buffer contains the
+initial segment of the proof script which has been processed
+successfully. It consists of atomic sequences of commands
+(ACS). Retraction is supported to the beginning of every ACS. By
+default, every command is an ACS. But the granularity of atomicity
+should be able to be adjusted.
+</p>
+<p>
+This adjustment is essential when arbitrary retraction is not
+supported in the prover. Usually, after a theorem has been proved, one
+may only retract to the start of the goal. One needs to mark the proof
+of the theorem as an ACS. At present, support for these goal-save
+sequences has been hard wired. No other ACS are currently
+supported. We need a generalisation to overcome this deficiency.
+</p>
+<p>
+This improvement should allow support for Coq's <i>Section</i> command,
+LEGO's <i>Discharge</i> and simplified support for Isabelle/Isar,
+by removing some of the prover-specific code.
+</p>
+<p>
+<b>References:</b>
+Proof General manual
+(<?php htmlshow("ProofGeneral/doc/ProofGeneral_17.html#SEC119","this section","Proof General Manual") ?>), and proof assistant manuals.</p>
+<p>
+<b>Skills:</b>
+Good Emacs Lisp, understanding of "granularity" problem
+for proof assistant history mechanisms.</p>
+<p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>
+(based on an original idea by Thomas Kleymann).
+</p>
+
diff --git a/html/projects/coqfile.html b/html/projects/coqfile.html
new file mode 100644
index 00000000..35d48eb1
--- /dev/null
+++ b/html/projects/coqfile.html
@@ -0,0 +1,22 @@
+<h2>Multiple file handling support for Coq</h2>
+<p>
+Coq Proof General does not yet handle script management across file
+boundaries, as do the LEGO and Isabelle versions. Script management
+for multiple files means that whenever a file is viewed in the editor,
+it is locked if it has been loaded into the current Coq session. It
+may mean that Proof General can make use of the file-level primitives
+of Coq, so that the user doesn't have to escape the interface,
+or carefully load each file and its dependencies. This also means that
+complete proof scripts will not so often need to be interpreted by
+Proof General, solving one of the present bottlenecks with using
+Coq Proof General.
+</p>
+<p>
+<b>Skills:</b>
+ Some understanding of Coq implementation, co-operation with
+ the Coq developers to get any Coq modifications (if any) incorporated.
+ Some Emacs Lisp knowledge.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
diff --git a/html/projects/coqpbp.html b/html/projects/coqpbp.html
new file mode 100644
index 00000000..366feb7c
--- /dev/null
+++ b/html/projects/coqpbp.html
@@ -0,0 +1,17 @@
+<h2>Proof-by-pointing support for Coq</h2>
+<p>
+Coq already has sophisticated notions of proof-by-pointing,
+and old work on support for Proof General may be helpful.
+We want to integrate with the latest version of Coq's
+proof-by-pointing, possibly improving Proof General's
+support along the way.
+</p>
+<p>
+<b>Skills:</b>
+ Some understanding of Coq implementation, co-operation with
+ the Coq developers to get any Coq modifications (if any) incorporated.
+ Minimal Emacs Lisp knowledge.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
diff --git a/html/projects/corba.html b/html/projects/corba.html
new file mode 100644
index 00000000..35faa73f
--- /dev/null
+++ b/html/projects/corba.html
@@ -0,0 +1,37 @@
+<h2>An Experimental CORBA binding and IDL mapping for ML</h2>
+<p>
+The future version of Proof General may use CORBA as a communication
+mechanism between different components. CORBA is also used by the
+Unix/Linux desktops KDE and GNOME, which use the free implementations
+MICO and ORBIT respectively. We would like to be able to use ML to
+write to interface with other CORBA components on the desktop and
+network. For this a binding for ORB functions in ML is needed, as well
+as perhaps a mapping from the CORBA IDL into Standard ML, so that
+we can write CORBA enabled applications in SML.
+</p>
+<p>
+This project involves the design and implementation of an experimental
+version (subset of features) of such a system, using one of the
+open-source ML compilers such as Moscow ML, Poly/ML or OCaml (in fact,
+there is already some handling of COM in OCaml which can be used to
+access an ORB). Essentially, we want to analyse the feasibility
+and performance of using a CORBA architecture for Proof General.
+</p>
+<p>
+An CORBA binding for Haskell would also be an interesting project.
+</p>
+<p>
+See
+<a href="http://www.cl.cam.ac.uk/~cvr21/projects.html">Claudio Russo's</a>
+project suggestion for a similar proposal, including useful links.
+</p>
+<p>
+<b>Skills:</b>
+Good ML, C, C++, programming skills and understanding of abstraction
+mechanisms, basic understanding of CORBA and willing to get to
+grasps with some of MICO or ORBIT.
+</p><p>
+<b>Proposers:</b>
+<a href="http://www.in.tum.de/~wenzelm/">Markus Wenzel</a> and
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
diff --git a/html/projects/hol.html b/html/projects/hol.html
new file mode 100644
index 00000000..6828899a
--- /dev/null
+++ b/html/projects/hol.html
@@ -0,0 +1,40 @@
+<h2>Proof General for HOL</h2>
+<p>
+It is fairly easy to get basic support for Proof General for
+<a href="http://www.cl.cam.ac.uk/Research/HVG/HOL/HOL.html">HOL</a>, and
+this has recently been tried for HOL 98. However, it would be a bigger
+and more interesting project to get proper and complete support for
+HOL working. There are a couple of problems unique to HOL.
+</p>
+<p>
+Much more than Isabelle, HOL relies on its meta language, ML. HOL
+proof scripts often use batch-oriented single step tactic proofs
+constructed in ML, but Proof General does not offer an easy way to
+edit these kind of proofs (as opposed to multi-step interactive
+proofs). The <a
+href="http://hagi.is.s.u-tokyo.ac.jp/boomborg/">Boomburg-HOL</a> Emacs
+interface by Koichi Takahashi and Masima Hagiya addressed this
+problem, as well as providing support for proof-by-pointing to HOL.
+Their interface could perhaps be reinterpreted or reimplemented inside
+Proof General. Implemented in a generic way, batch script editing
+would also be useful for Isabelle.
+</p>
+<p>
+Another problem is that HOL scripts sometimes use SML structures,
+which can cause confusion because Proof General does not really parse
+SML, it just looks for semicolons. This could be improved by taking a
+better parser (e.g. from sml mode).
+</p>
+<p>
+Finally, to fully support the current Proof General feature set,
+it would be useful to extend HOL with support for communicating
+file-dependency information to Proof General, and term-structure
+markup for proof by pointing.
+<p>
+<b>Skills:</b>
+Some Standard ML, some Emacs Lisp. Basic understanding of
+proof assistant behaviour, interest in HOL.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
diff --git a/html/projects/isapbp.html b/html/projects/isapbp.html
new file mode 100644
index 00000000..c08ea85e
--- /dev/null
+++ b/html/projects/isapbp.html
@@ -0,0 +1,25 @@
+<h2>Proof-by-pointing support for Isabelle</h2>
+<p>
+Isabelle has a sophisticated concrete syntax mechanism which makes it
+difficult to add annotations to connect the displayed output back to
+the internal abstract syntax. This issue needs to be solved to
+support proof-by-pointing (and other features) in Isabelle.
+A
+<a href="http://www.informatik.uni-bremen.de/~bu/isa_contrib/isabelle.html">
+patch by Burkhart Wolff</a>
+providing term structure annotations for a previous release of
+Isabelle may be useful here. To implement proof-by-pointing itself,
+tactics using the gesture information must be written.
+</p>
+<p>
+<b>Skills:</b>
+ Some understanding of Isabelle implementation,
+ co-operation with the Isabelle developers to get
+ Isabelle modifications incorporated.
+ Skill in writing Isabelle tactics.
+ Minimal Emacs Lisp knowledge.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
+
diff --git a/html/projects/mm.html b/html/projects/mm.html
new file mode 100644
index 00000000..d7bf6954
--- /dev/null
+++ b/html/projects/mm.html
@@ -0,0 +1,23 @@
+<h2>Multiplexed Modes for Emacs</h2>
+<p>
+Emacs has a mechanism for customizing the editing behaviour of buffers
+based on their <i>major mode</i>. A buffer can only have one major
+mode, but in literate styles of programming and proving we want to mix
+program text with documentation in a single file. A way of
+multiplexing major modes is needed, so that different regions of a
+buffer can be edited in different modes. One approach may be to use
+"views" onto untangled buffers, although it isn't clear how search and
+replace, etc, should behave in this case.
+</p><p>
+Emacs hackers may already have worked on this problem and solved it
+sufficiently well (does anybody know?), in which case this project
+might degenerate into applying the work for Coq and Isabelle/Isar, as
+a feasibility demonstration.
+</p><p>
+<b>Skills:</b>
+A passion for Emacs and Emacs Lisp.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
+
diff --git a/html/projects/outline.html b/html/projects/outline.html
new file mode 100644
index 00000000..67680b8f
--- /dev/null
+++ b/html/projects/outline.html
@@ -0,0 +1,26 @@
+<h2>Integrating block-structured development and outline mode</h2>
+<p>
+Emacs already provides powerful outline facilities (cf. the
+outl-minor-mode setup for the well-known auc-tex package).
+Similarly, proof systems such as Isabelle/Isar are inherently based on
+block-structured proof texts, with compositional proof checking.
+</p><p>
+But Proof General currently offers a mostly linear model of
+incremental script management. The aim of this project is to extend that
+model to a hierarchic one: e.g. sub-proofs could be suppressed in the
+presentation, or even temporarily suspended (to achieve top-down
+development).
+</p><p>
+Outline support would be useful for the large scale structure of formal
+developments as well, e.g. support the basic arrangement into logical
+section (cf. Coq), or even just traditional layout-based ones (cf. LaTeX).
+</p>
+<p>
+<b>Skills:</b>
+Some understanding of the workings of Emacs outline mode and Proof
+General script management. Good portion of Emacs lisp knowledge.
+</p><p>
+<b>Proposer:</b>
+<a href="http://www.in.tum.de/~wenzelm/">Markus Wenzel</a>.
+</p>
+
diff --git a/html/projects/pgip.html b/html/projects/pgip.html
new file mode 100644
index 00000000..073edd06
--- /dev/null
+++ b/html/projects/pgip.html
@@ -0,0 +1,22 @@
+<h2>A New Protocol for Interactive Proof in Proof General</h2>
+<p>
+PGIP is a protocol for interactive proof to be used in the next
+version of Proof General. It is based around the present protocol,
+but implemented with a standard collection of messages rather than
+different messages for different proof assistants. An outline of PGIP
+and an experimental DTD
+is given in the <a href="/home/da/drafts/#white">white paper</a>. A
+first implementation of PGIP will consist of (1) a filter (or
+modification of the output routines) for an existing proof assistant,
+which could be implemented in perl or some other language; and (2) a
+new backend for Proof General in Emacs, which configures it for PGIP.
+</p>
+<p>
+<b>Skills:</b>
+Interest in interactive proof and basic understanding
+of interaction mechanisms with at least one of
+LEGO, Coq, Isabelle. Programmming in Emacs Lisp.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
diff --git a/html/projects/pgml.html b/html/projects/pgml.html
new file mode 100644
index 00000000..46cdd960
--- /dev/null
+++ b/html/projects/pgml.html
@@ -0,0 +1,26 @@
+<h2>Specification and tools for PGML</h2>
+<p>
+PGML is the proposed logical markup language for future versions of
+Proof General. The basic version legitimizes the present markup
+scheme which is used by Proof General (based on 8-bit characters).
+The ideas for PGML are described in the white paper
+<a href="/home/da/drafts/#white">here</a>, and an experimental
+DTD is given there. This project is to refine the specification
+of PGML, and develop some tools for using it. Various tools are desirable,
+including: (1) translation tools which convert PGML to various other
+formats, such as HTML and LaTeX. (2) a display tool which displays PGML
+inside Emacs, or converts it to HTML for display by a web browser;
+(3) a filter or revised version of LEGO which converts its 8-bit markup
+into PGML, for testing purposes. We need the last tool for other
+proof assistants too.
+</p>
+<p>
+<b>Skills:</b>
+Understanding of markup languages and tools for using and specifying them.
+Interest in representation of mathematical content.
+Necessary programming skills.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
+
diff --git a/html/projects/reelcase.html b/html/projects/reelcase.html
new file mode 100644
index 00000000..f5fa2f04
--- /dev/null
+++ b/html/projects/reelcase.html
@@ -0,0 +1,34 @@
+<h2>A ClearCase-like Configuration Management tool for Linux</h2>
+<p>
+Managing large libraries of theories and proofs, good software
+engineering practices of configuration management become important
+when using proof assistants. One powerful and popular configuration
+management tool is the commercial <a
+href="http://www.rational.com/products/clearcase/index.jtmpl">Rational
+ClearCase</a>.
+</p>
+<p>
+The crucial way that ClearCase goes beyond CVS is in providing a view
+of a configuration directly through a special mountpoint on
+the filesystem.
+</p>
+<p>
+This is a project to implement a kernel-level filesystem driver for
+Linux using the Linux VFS to create a ClearCase-like view of a
+configuration, through a mountable filesystem. The underlying
+configuration management could be done through RCS or CVS, perhaps
+invoked via a companion user-level process.
+Particular revisions of files should be accessible through names
+interpreted specially by the filesystem driver, and some
+user-level commands will be needed for other operations.
+</p>
+<p>
+<b>Skills:</b>
+Expert C programmer, with ability to understand and work on Linux
+kernel code. Understanding of configuration management principles.
+</p><p>
+<b>Proposers:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>
+from an idea by
+<a href="http://www.dcs.ed.ac.uk/home/cxl">Christoph L&uuml;th</a>
+</p>
diff --git a/html/projects/scrgen.html b/html/projects/scrgen.html
new file mode 100644
index 00000000..d65b477f
--- /dev/null
+++ b/html/projects/scrgen.html
@@ -0,0 +1,26 @@
+<h2>Script General</h2>
+<p>
+Proof General is based around a core system of script management
+for proof scripts. But the idea of script management is not
+restricted to proof assistants, it makes sense for many interactive
+scripting languages. It deserves to be better known and used.
+A worthwhile project would be to rewrite the core script management
+features of Proof General so that they could work for arbitrary
+interactive scripting languages, and instantiate to Proof General as
+well as languages such as ML, Haskell, LISP, Scheme, Python, and
+even Emacs Lisp itself.
+</p>
+<p>
+An alternative version of this project is to implement a
+generic basis for script management which does <i>not</i> depend on
+Emacs, but uses a similar protocol to communicate with other
+text editors or display widgets. This could be implemented in
+SML, OCaml, Java, C++, or any other suitable language.
+<p>
+<b>Skills:</b>
+Proficient Emacs Lisp (or other programming language),
+knowledge of scripting languages desirable.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
diff --git a/html/projects/test.html b/html/projects/test.html
new file mode 100644
index 00000000..f9d5ecf0
--- /dev/null
+++ b/html/projects/test.html
@@ -0,0 +1,24 @@
+<h2>A Test Harness and Test Suite for Proof General</h2>
+<p>
+As Proof General becomes a more complex system, we badly need some way
+of performing automatic functional testing, to ensure that changes and
+extensions preserve functional correctness. Although classical
+testing of interfaces involves manually following a checklist of
+actions and observations, it should be straightforward to automate
+this using Emacs Lisp. Interactive actions can be simulated by
+certain function calls, and their results can be determined by
+examining the contents of the edit buffers. This project proposes the
+design and implementation of a test harness and accompanying test
+suite to test some of the core functions of Proof General.
+Ultimately, the tests should be run as part of the build process
+before each development release is allowed to go ahead.
+</p>
+<p>
+<b>Skills:</b>
+An interesting in testing user interfaces.
+Basic knowledge of Emacs Lisp.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
+
diff --git a/html/projects/thybrowse.html b/html/projects/thybrowse.html
new file mode 100644
index 00000000..8993d942
--- /dev/null
+++ b/html/projects/thybrowse.html
@@ -0,0 +1,34 @@
+<h2>A Generic Theory Browser</h2>
+<p>
+Proof General has very limited mechanisms for helping the user find
+theorems and definitions during a proof. It has notion of displaying
+a "current context" for a proof, and configuration with a proof
+engine command for searching for theorems. It would be useful to
+extend these facilities with a <i>theory browser</i> for investigating
+the theories currently defined in (or available from) a running proof
+assistant. This involves designing a small protocol to communicate
+with the proof assistant and a generic way of displaying theories
+which have different aspects from system to system. A way which would
+fit in well with Emacs would be to use a <tt>dired</tt>-like buffer.
+</p>
+<p>
+An alternative version of this project would be to write a standalone
+theory browser which uses an extension of the forthcoming Proof
+General standardized protocol for interaction (see white paper <a
+href="/home/da/drafts/#white">here</a>). This could be implemented in
+Java, or in a functional language, Perl, C or C++, so long as a nice
+toolkit is chosen (Qt or GTK).
+</p>
+<p>
+(For a related idea, see the browser integrated with OCaml).
+</p>
+<p>
+<b>Skills:</b>
+Interface programming skills.
+Basic understanding of what theories are for several different proof
+assistants.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
+
diff --git a/html/projects/webreplay.html b/html/projects/webreplay.html
new file mode 100644
index 00000000..1754e2df
--- /dev/null
+++ b/html/projects/webreplay.html
@@ -0,0 +1,24 @@
+<h2>A Web-based Proof Replayer for Proof General</h2>
+<p>
+One of the nice features of Proof General is that it is very easy to
+replay existing proofs, by mouse clicks alone. No low-level
+understanding of a proof assistant is needed to step through proofs.
+We would like to have a web-based version of Proof General which
+allowed for this proof replay (at least), perhaps running a proof
+assistant remotely. The main aspect is to implement an engine for
+script management (colouring of lines of files), displaying in a web
+browser, sending lines to a proof assistant process, and displaying the
+results. Ideally, the ideas for new standard protocols for Proof
+General in the <a href="/home/da/drafts/#white">white paper</a> would
+be followed.
+</p>
+<p>
+<b>Skills:</b>
+Strong web programming skills using scripting languages,
+dynamic HTML, etc.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
+
+
diff --git a/html/projects/xmlpgip.html b/html/projects/xmlpgip.html
new file mode 100644
index 00000000..30828a97
--- /dev/null
+++ b/html/projects/xmlpgip.html
@@ -0,0 +1,40 @@
+<h2>A New Protocol for Interactive Proof in Proof General</h2>
+<p>
+PGIP is a protocol for interactive proof to be used in the next
+version of Proof General. It is based around the present protocol,
+but implemented with a standard collection of messages rather than
+different messages for different proof assistants. An outline of PGIP
+is given in the <a href="/home/da/drafts/#white">white paper</a>. A
+first implementation of PGIP will consist of (1) a filter (or
+modification of the output routines) for an existing proof assistant,
+which could be implemented in perl or some other language; and (2) a
+new backend for Proof General in Emacs, which configures it for PGIP.
+</p>
+<p>
+<b>Skills:</b>
+Interest in interactive proof and basic understanding
+of interaction mechanisms with at least one of
+LEGO, Coq, Isabelle. Programmming in Emacs Lisp.
+</p><p>
+<b>Proposer:</b>
+<a href="http://zermelo.dcs.ed.ac.uk/~da">David Aspinall</a>.
+</p>
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <title></title>
+ </head>
+
+ <body>
+ <h1></h1>
+
+
+
+ <hr>
+ <address><a href="mailto:da@dcs.ed.ac.uk">David Aspinall</a></address>
+<!-- Created: Tue Apr 25 18:11:06 BST 2000 -->
+<!-- hhmts start -->
+Last modified: Tue Apr 25 18:22:01 BST 2000
+<!-- hhmts end -->
+ </body>
+</html>
diff --git a/html/proofgen.css b/html/proofgen.css
new file mode 100644
index 00000000..e29db5a5
--- /dev/null
+++ b/html/proofgen.css
@@ -0,0 +1,136 @@
+/* Style sheet for the Proof General web pages.
+ * David Aspinall, June 1999.
+ * proofgen.css,v 4.0 2000/03/13 07:36:57 da Exp
+ */
+
+body{
+ font-family: Verdana, Arial, sans-serif; /* font for the doc body */
+ background: #2D1D03; /* background brown */
+ background-image:
+ url(images/canvaswallpaper.jpg);
+ background-attachment: fixed; /* background shouldn't scroll */
+ color: #FFFFFF; /* text colour is white */
+}
+
+p{
+ font-family: Verdana, Arial, sans-serif; /* Netscape is picky, */
+ color: #FFFFFF; /* so we must set every tag */
+}
+
+pre{
+ font-family: LucidaTypewriter, mono;
+ color: #FFFFFF;
+}
+
+h1{
+ font-family: Verdana, Arial, sans-serif;
+ color: #FFFFFF;
+ font-size: large;
+ font-series: bold;
+}
+
+h2{
+ font-family: Verdana, Arial, sans-serif;
+ font-size: medium;
+ font-weight: bold;
+ color: #FFFFD0;
+ padding: 2px 4px 4px 4px;
+ background: #7D4D33;
+}
+
+h3{
+ font-family: Verdana, Arial, sans-serif;
+ font-size: medium;
+ padding: 2px 2px 2px 2px;
+ margin-right: 10%;
+ background: #6D3D43;
+ color: #FFFFD0;
+}
+
+h4{
+ font-family: Verdana, Arial, sans-serif;
+ font-size: medium;
+ color: #FFD0D0;
+}
+
+h5{
+ font-family: Verdana, Arial, sans-serif;
+ font-size: medium;
+ color: #E0C0C0;
+}
+
+blockquote,form,input,select{
+ font-family: Verdana, Arial, sans-serif;
+ color: #FFFFFF;
+}
+
+address{
+ font-family: Verdana, Arial, sans-serif;
+ font-size: small; /* "smaller" is better on IE */
+ color: #FFFFFF; /* but varies randomly in NN */
+}
+
+input,select,textarea {
+ background: #2D1D03;
+ color: #FFFFFF;
+}
+
+/* Lists */
+
+dl,ul,dir,li{
+ font-family: Verdana, Arial, sans-serif;
+ color: #FFFFFF;
+}
+dt{ font-style: italic;
+ padding: 2px 2px 2px 2px;
+ margin-left: 20px;
+ margin-right: 20px;
+ background: #6D3D43;
+}
+
+/* Table Elements */
+table{
+ font-family: Verdana, Arial, sans-serif;
+/* background: #2D1D03; */
+ color: #FFFFFF;
+}
+
+table.menubar{
+ font-family: Verdana, Arial, sans-serif;
+ font-size: smaller;
+/* background: #2D1D03; */
+ color: #FFFFFF;
+}
+
+td,tr{
+ font-family: Verdana, Arial, sans-serif;
+/* background-color: #2D1D03; */
+ color: #FFFFFF;
+}
+
+/* Link Elements */
+a:link,a:visited{ /* visited appears same */
+ font-family: Verdana, Arial, sans-serif;
+ text-decoration: none; /* Remove the underline */
+ color: #FFD820;
+}
+
+/* hover is IE specific nasty but nice */
+a:active,a:hover{
+ font-family: Verdana, Arial, sans-serif;
+ text-decoration: underline; /* Underline on mouse over */
+ color: #FFF030; /* Brighter colour too */
+}
+
+
+pre{
+ background: #2D1D03;
+}
+
+/* Specifics */
+
+p.nb{
+ font-size: smaller;
+ font-style: italic;
+}
+
diff --git a/html/register b/html/register
new file mode 100644
index 00000000..097d8441
--- /dev/null
+++ b/html/register
@@ -0,0 +1,110 @@
+<?php
+##
+## Proof General registration form.
+##
+## David Aspinall, June 1999.
+##
+## $Id$
+##
+ require('functions.php3');
+
+ $failure= ($argv[0]=="submit" && ($name=="" || $email=="" || $site==""));
+
+ if ($argv[0] !="submit" || $failure):
+###
+### Registration form
+###
+ small_header("Proof General Registration");
+
+ if ($failure):
+?>
+<p>
+ Your registration form was incomplete. Please fill in all
+ the fields, thank-you!
+</p>
+<?php else:
+ $mailinglist=true
+?>
+<p>
+Please register your download using the short form below.
+<br>
+The information provided will only be used to help
+provide a case for support for Proof General in the future.
+</p>
+<p>
+If you have already registered you do not need to fill in the form
+again, so return to <a href="download#prereq">the download page</a>.
+</p>
+<?php endif; ?>
+<h2>Registration Form</h2>
+<form method=post action="<?php print $PHP_SELF . "?submit"; ?>">
+<table width="300" border="0" cellspacing="2" cellpadding="0">
+<tr>
+ <td width="30%">Your name:</td>
+ <td width="70%"><input type=text name="name" size="40"
+ value="<?php echo $name;?>"></td>
+</tr>
+<tr>
+ <td width="30%">Email address:</td>
+ <td width="70%"><input type=text name="email" size="40"
+ value="<?php echo $email;?>"></td>
+</tr>
+<tr>
+ <td width="30%">Site name:</td>
+ <td width="70%"><input type=text name="site" size="40"
+ value="<?php echo $site;?>"></td>
+</tr>
+<tr>
+ <td width="30%"><input type=checkbox name="mailinglist"
+ <?php if ($mailinglist) print "checked"; ?>></td>
+ <td width="70%">Please add me to the mailing list.</td>
+</table>
+<input type=submit value="Send form">
+</form>
+<p>
+</p>
+<?php
+ click_to_go_back();
+ footer();
+ else:
+##
+## Process registration
+##
+ small_header("Registration Form Sent");
+
+
+ $message = "Registration form for using Proof General"
+ . "\nName:\t\t " . $name
+ . "\nEmail:\t\t " . $email
+ . "\nSite:\t\t " . $site
+ . "\nSubmitted:\t" . date("h:ia D jS F Y");
+ mail("proofgen@dcs.ed.ac.uk",
+ "[Registration form from ~proofgen]",
+ $message);
+
+ print "<p>Dear " . $name . ",</p>\n";
+ print "<p>";
+ print "Thank you for filling in the form. Your registration has been sent.<br>";
+
+ /* Next bit duplicated in mailinglist.html.
+ Could be a function in functions.php3 */
+
+ if ($mailinglist) {
+ $message = "subscribe proofgeneral";
+ mail("majordomo@dcs.ed.ac.uk",
+ "[Web form from ~proofgen]",
+ $message,
+ "Reply-To: " . $email . "\nFrom: " . $email);
+ print "Your name has been added to the Proof General mailing list.<br>";
+ }
+ print "</p>\n<p>";
+
+ print "<p>\nClick ";
+ print "<a href=\"download#prereq\">here</a>";
+ print " to return to the download page.<br></p>\n";
+ click_to_go_back();
+
+ footer();
+ endif;
+?>
+
diff --git a/html/register.html b/html/register.html
new file mode 100644
index 00000000..097d8441
--- /dev/null
+++ b/html/register.html
@@ -0,0 +1,110 @@
+<?php
+##
+## Proof General registration form.
+##
+## David Aspinall, June 1999.
+##
+## $Id$
+##
+ require('functions.php3');
+
+ $failure= ($argv[0]=="submit" && ($name=="" || $email=="" || $site==""));
+
+ if ($argv[0] !="submit" || $failure):
+###
+### Registration form
+###
+ small_header("Proof General Registration");
+
+ if ($failure):
+?>
+<p>
+ Your registration form was incomplete. Please fill in all
+ the fields, thank-you!
+</p>
+<?php else:
+ $mailinglist=true
+?>
+<p>
+Please register your download using the short form below.
+<br>
+The information provided will only be used to help
+provide a case for support for Proof General in the future.
+</p>
+<p>
+If you have already registered you do not need to fill in the form
+again, so return to <a href="download#prereq">the download page</a>.
+</p>
+<?php endif; ?>
+<h2>Registration Form</h2>
+<form method=post action="<?php print $PHP_SELF . "?submit"; ?>">
+<table width="300" border="0" cellspacing="2" cellpadding="0">
+<tr>
+ <td width="30%">Your name:</td>
+ <td width="70%"><input type=text name="name" size="40"
+ value="<?php echo $name;?>"></td>
+</tr>
+<tr>
+ <td width="30%">Email address:</td>
+ <td width="70%"><input type=text name="email" size="40"
+ value="<?php echo $email;?>"></td>
+</tr>
+<tr>
+ <td width="30%">Site name:</td>
+ <td width="70%"><input type=text name="site" size="40"
+ value="<?php echo $site;?>"></td>
+</tr>
+<tr>
+ <td width="30%"><input type=checkbox name="mailinglist"
+ <?php if ($mailinglist) print "checked"; ?>></td>
+ <td width="70%">Please add me to the mailing list.</td>
+</table>
+<input type=submit value="Send form">
+</form>
+<p>
+</p>
+<?php
+ click_to_go_back();
+ footer();
+ else:
+##
+## Process registration
+##
+ small_header("Registration Form Sent");
+
+
+ $message = "Registration form for using Proof General"
+ . "\nName:\t\t " . $name
+ . "\nEmail:\t\t " . $email
+ . "\nSite:\t\t " . $site
+ . "\nSubmitted:\t" . date("h:ia D jS F Y");
+ mail("proofgen@dcs.ed.ac.uk",
+ "[Registration form from ~proofgen]",
+ $message);
+
+ print "<p>Dear " . $name . ",</p>\n";
+ print "<p>";
+ print "Thank you for filling in the form. Your registration has been sent.<br>";
+
+ /* Next bit duplicated in mailinglist.html.
+ Could be a function in functions.php3 */
+
+ if ($mailinglist) {
+ $message = "subscribe proofgeneral";
+ mail("majordomo@dcs.ed.ac.uk",
+ "[Web form from ~proofgen]",
+ $message,
+ "Reply-To: " . $email . "\nFrom: " . $email);
+ print "Your name has been added to the Proof General mailing list.<br>";
+ }
+ print "</p>\n<p>";
+
+ print "<p>\nClick ";
+ print "<a href=\"download#prereq\">here</a>";
+ print " to return to the download page.<br></p>\n";
+ click_to_go_back();
+
+ footer();
+ endif;
+?>
+
diff --git a/html/screenshot b/html/screenshot
new file mode 100644
index 00000000..f0cbe7a1
--- /dev/null
+++ b/html/screenshot
@@ -0,0 +1,9 @@
+<?php require('functions.php3'); ?>
+<html>
+<?php include('head.html'); ?>
+<?php
+ include('header.html');
+ include($WANTED . '.html');
+ footer();
+?>
+
diff --git a/html/screenshot.html b/html/screenshot.html
new file mode 100644
index 00000000..0567b83b
--- /dev/null
+++ b/html/screenshot.html
@@ -0,0 +1,108 @@
+<p>
+Here are some screenshots of Proof General 3.0 running with
+different theorem provers. To see the full-size version
+of a picture, click on its thumbnail.
+</p>
+<p>
+<i>NB: Your browser needs PNG support to view these pictures.
+</i>
+</p>
+
+<!-- todo: php3 this, add space between rows! -->
+<table width="80%">
+<tr>
+<td width="200">
+<a href="images/pg-lego-screenshot.png">
+<img src="images/pg-lego-thumb.png" alt="LEGO Proof General" width=128 height=109 border=0>
+</a>
+</td>
+<td>
+<p>
+Building a simple proof in LEGO with proof-by-pointing.
+<br>
+The top half of the window displays the proof script.
+The bottom displays the output from LEGO at each
+stage of the proof. Here, it shows
+the current subgoals to be solved.
+The part of the proof already processed by LEGO
+has a blue background.
+<br>
+Clicking on terms in the subgoals list generates
+commands which are added to the proof script.
+</p>
+</tr>
+<tr>
+<td width="200">
+<a href="images/pg-coq-screenshot.png">
+<img src="images/pg-coq-thumb.png" alt="Coq Proof General" width=153 height=115 border=0>
+</a>
+</td>
+<td>
+<p>
+Coq Proof General running in multiple frame mode,
+full screen shot (1024x768).
+<br>
+There are separate windows on the screen
+for the script, goals, and response buffers.
+In this picture, you can see Proof General's
+indication that Coq is processing the
+induction step, because the background of
+the proof step is pink. It will become
+blue when Coq finishes that step.
+</p>
+</tr>
+<tr>
+<td width="200">
+<a href="images/pg-isa-screenshot.png">
+<img src="images/pg-isa-thumb.png" alt="Isabelle Proof General" width=150 height=142 border=0>
+</a>
+</td>
+<td>
+<p>
+Replaying a domain theory proof in Isabelle's HOLCF logic.
+<br>
+In Isabelle, theory files as well as ML files are coloured.
+Proof General has some functions for processing and
+undoing theory files, but most operations it provides
+are for writing proof scripts in ML files.
+<br>
+Isabelle supports input and output in tokens which
+display as symbols using the
+<a href="http://www.fmi.uni-passau.de/~wedler/x-symbol">X-Symbol</a>
+package in conjunction with Proof General.
+Here you can see some symbols in Isabelle's output.
+</p>
+</tr>
+<tr>
+<td width="200">
+<a href="images/pg-isar-screenshot.png">
+<img src="images/pg-isar-thumb.png" alt="Isabelle/Isar Proof General" width=150 height=142 border=0>
+</a>
+</td>
+<td>
+<p>
+Replaying a proof in Isar, Isabelle's new proof language
+developed by Markus Wenzel.
+</p>
+</tr>
+<tr>
+<td width="200">
+<a href="images/pg-lego-console.png">
+<img src="images/pg-lego-console-thumb.png" alt="LEGO Proof General (console)" width=174 height=65 border=0>
+</a>
+</td>
+<td>
+<p>
+LEGO Proof General running in plain console mode.
+<br>
+This shows that you can run Proof General even if sometimes
+you need to use a plain tty or xterminal. Of course, the
+graphical features are reduced!
+</p>
+</tr>
+</table>
+
+<p>
+For more pictures, see the Proof General <a href="gallery">gallery</a>.
+</p>
+
diff --git a/html/smallheader.html b/html/smallheader.html
new file mode 100644
index 00000000..55cb7a4c
--- /dev/null
+++ b/html/smallheader.html
@@ -0,0 +1,8 @@
+<table width="80%">
+<tr>
+<td width="30%">
+<a href="">
+<img src="images/PG-small.jpg" align=top width=75 height=99 border=0 alt="Proof General Home">
+</a>
+</td>
+<td width="70%">
diff --git a/html/smallpage.html b/html/smallpage.html
new file mode 100644
index 00000000..64f538a3
--- /dev/null
+++ b/html/smallpage.html
@@ -0,0 +1,6 @@
+<?php
+ require('functions.php3');
+ small_header($title);
+ include($file);
+ footer();
+?>
diff --git a/html/smallpage.php b/html/smallpage.php
new file mode 100644
index 00000000..ef165c6d
--- /dev/null
+++ b/html/smallpage.php
@@ -0,0 +1,12 @@
+<?php
+ require('functions.php3');
+ small_header($title);
+ if (substr($file,0,1)=="." or
+ substr($file,0,1)=="/" or
+ substr($file,0,1)=="~") {
+ print "Sorry, can't show you that file!\n";
+ } else {
+ include($file);
+ }
+ footer();
+?>
diff --git a/images/.cvsignore b/images/.cvsignore
new file mode 100644
index 00000000..46b71d73
--- /dev/null
+++ b/images/.cvsignore
@@ -0,0 +1,4 @@
+buttons
+webpix
+.xvpics
+
diff --git a/images/Makefile b/images/Makefile
new file mode 100644
index 00000000..5b00818f
--- /dev/null
+++ b/images/Makefile
@@ -0,0 +1,100 @@
+##
+## Makefile for Proof General images directory.
+##
+## Author: David Aspinall <da@dcs.ed.ac.uk>
+##
+## Developer use only, not part of distribution.
+##
+## $Id$
+##
+## make buttons make *.xpm from gimp xcf files
+## make webpix make *.jpg from gimp xcf files
+## make install copy *.jpg to ../html directory
+## make clean remove dummy targets
+## make cvsclean remove non-cvs files
+##
+## make dist ready for distribution
+## (make buttons, move jpegs to html)
+##
+###########################################################################
+
+# Sources
+BUTTONS=goal.xcf next.xcf qed.xcf restart.xcf retract.xcf undo.xcf use.xcf state.xcf context.xcf info.xcf command.xcf help.xcf find.xcf interrupt.xcf goto.xcf abort.xcf
+WEBPIX=isabelle_transparent.xcf ProofGeneral.xcf pg-text.xcf
+
+# Targets for html directory
+WEBPIX_ONLY=
+WEBPIX_TARGETS=$(WEBPIX_ONLY) ProofGeneral.jpg pg-text.gif
+# Targets for doc directory
+DOCPIX_TARGETS=ProofGeneral.jpg
+
+# Junk not wanted
+UNWANTED=text_general.jpg text_proof.jpg
+
+CWD=$(shell pwd)
+GIMP_DIRECTORY=$(CWD)/gimp
+
+# Command to run gimp in batch mode.
+GIMP=export GIMP_DIRECTORY=$(GIMP_DIRECTORY); gimp --no-interface --no-data --console-messages --batch
+
+default: all
+
+images: all
+
+all: buttons backgroundize-xpm webpix
+
+dist: all install distclean
+
+# Edit xpm files to add a substitution background colour for
+# the XEmacs toolbar background -- a hack that almost works
+# (only almost because the images have anti-aliasing with
+# a different background colour, and xpm files only allow
+# one-bit alpha).
+backgroundize-xpm: $(BUTTONS)
+ for f in *.xpm; do sed 's/#BCBCBC"/#BCBCBC s backgroundToolBarColor"/g' $$f > $$f.new; mv $$f.new $$f; done
+
+# NB: gimp sometimes fails with this argument, in case it is built
+# without support for one of the image formats.
+# (Happens with gimp from Mandrake 6.0, for example)
+buttons: $(BUTTONS)
+ $(GIMP) '(script-fu-proofgeneral-make-all-buttons 1)' '(gimp-quit 0)'
+ $(MAKE) backgroundize-xpm
+ touch buttons
+
+webpix: $(WEBPIX)
+ $(GIMP) '(script-fu-proofgeneral-save-all-pix 1)' '(gimp-quit 0)'
+ touch webpix
+
+cvsclean: clean
+# For the time being we keep all this junk under CVS too, for convenience.
+# rm -f *.xpm *.jpg gimp/pluginrc
+# rm -f *.jpg gimp/pluginrc
+
+# Remove all the generated targets and other junk.
+wellclean: clean
+ rm -f *.xpm *.jpg *.gif
+
+distclean: clean
+
+clean:
+ rm -f buttons webpix gimp/pluginrc
+ rm -f $(WEBPIX_ONLY) $(UNWANTED)
+
+install: webpix
+ cp -pf $(WEBPIX_TARGETS) ../html/images
+ cp -pf $(DOCPIX_TARGETS) ../doc
+
+##
+## Batch mode is a bit broken on The Gimp at the moment (v 1.0)
+## For script fu, at least, it seems tricky to pass arguments to
+## scripts.
+## With '1' as first argument to indicate "non-interactive", things
+## don't work. With '0', we get popup menus and args are ignored!
+
+%.xpm: %.xcf
+ $(GIMP) '(script-fu-proofgeneral-make-buttons "$(CWD)/$*")' '(gimp-quit 0)'
+
+#%.jpg: %.xcf
+# $(GIMP) '(script-fu-proofgeneral-save-jpg 0 "$(CWD)/$*")' '(gimp-quit 0)'
+# cp -pf $*.jpg ../html
+
diff --git a/images/ProofGeneral.8bit.gif b/images/ProofGeneral.8bit.gif
new file mode 100644
index 00000000..dfb182be
--- /dev/null
+++ b/images/ProofGeneral.8bit.gif
Binary files differ
diff --git a/images/ProofGeneral.gif b/images/ProofGeneral.gif
new file mode 100644
index 00000000..4f83fb95
--- /dev/null
+++ b/images/ProofGeneral.gif
Binary files differ
diff --git a/images/ProofGeneral.jpg b/images/ProofGeneral.jpg
new file mode 100644
index 00000000..d2c430cd
--- /dev/null
+++ b/images/ProofGeneral.jpg
Binary files differ
diff --git a/images/ProofGeneral.xcf b/images/ProofGeneral.xcf
new file mode 100644
index 00000000..709b346c
--- /dev/null
+++ b/images/ProofGeneral.xcf
Binary files differ
diff --git a/images/README b/images/README
new file mode 100644
index 00000000..e9bc5489
--- /dev/null
+++ b/images/README
@@ -0,0 +1,16 @@
+$Id$
+
+Icons for Proof General.
+
+David Aspinall <da@dcs.ed.ac.uk>
+
+Contact: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+
+The images in this directory were made with The Gimp
+(check www.gimp.org).
+
+
+
+
+
+
diff --git a/images/abort.8bit.xpm b/images/abort.8bit.xpm
new file mode 100644
index 00000000..01a9afc8
--- /dev/null
+++ b/images/abort.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * abort_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #020202",
+"+ c #860E0E",
+"@ c #8D1F1F",
+"# c #9A4646",
+"$ c #A05D5D",
+"% c #AA8282",
+"& c #AE9292",
+"* c #BEBDBD",
+"********************************",
+"*****&%%%%%%%%%%%%%%%%%%%%%*****",
+"*****#+++++++++++++++++++++*****",
+"*****#+##################@+*****",
+"*****#+******************#+*****",
+"*****#+**++**********&+**#+*****",
+"*****#+**++*********$++**#+*****",
+"*****#+**++********$++***#+*****",
+"*****#+**++*******$++****#+*****",
+"*****#+**++******$++*****#+*****",
+"*****#+**++*****%++******#+*****",
+"*****#+**++++++++++++++**#+*****",
+"*****#+**++++++++++++++**#+*****",
+"*****#+**++**%++*********#+*****",
+"*****#+**++*%++**********#+*****",
+"*****#+**++$++******&****#+*****",
+"*****#+**++++************#+*****",
+"*****#+**+++********&****#+*****",
+"*****#+*$++***&**********#+*****",
+"*&***#+*@+***************#+*****",
+"*****#+****************&*#+*****",
+"*****$+%%%%%%%%%%%%%%%%%%@+*****",
+"*****$@++++++++++++++++++++*****",
+"*****%#####################*****",
+"********************************",
+"*******..***..************.*****",
+"******.*.***.*************.*****",
+"******.*.***....*...*.......****",
+"*****....***..*...*.**..*..*****",
+"*****.**.**..*.*.**.*..**.******",
+"****..**..*...**...**.***..*****",
+"********************************"};
diff --git a/images/abort.xcf b/images/abort.xcf
new file mode 100644
index 00000000..b69d6b15
--- /dev/null
+++ b/images/abort.xcf
Binary files differ
diff --git a/images/abort.xpm b/images/abort.xpm
new file mode 100644
index 00000000..37e86f75
--- /dev/null
+++ b/images/abort.xpm
@@ -0,0 +1,71 @@
+/* XPM */
+static char * abort_xpm[] = {
+"32 32 36 1",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #8D2121",
+"& c #BBBABA",
+"* c #AE9090",
+"= c #860C0C",
+"- c #BBB9B9",
+"; c #BCBBBB",
+"> c #A46F6F",
+", c #A16464",
+"' c #BAB6B6",
+") c #994848",
+"! c #BBB8B8",
+"~ c #9A4A4A",
+"{ c #870E0E",
+"] c #9A4C4C",
+"^ c #902C2C",
+"/ c #9B5050",
+"( c #891212",
+"_ c #9C5454",
+": c #8A1616",
+"< c #AB8282",
+"[ c #933434",
+"} c #9E5858",
+"| c #8B1A1A",
+"1 c #881212",
+"2 c #A87B7B",
+"3 c #9C5252",
+"4 c #9A4B4B",
+"5 c #994949",
+"6 c #BBBBBB",
+"7 c #000000",
+"................................",
+".....+@@@@@@@@@@@@@@@@@@@@@.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....#$##################%$.....",
+".....#$..................#$.....",
+".....#$..$$........&&*=..#$.....",
+".....#$..$$.......-;>==..#$.....",
+".....#$..$$......&;,==...#$.....",
+".....#$..$$....;'&,==....#$.....",
+".....#$..$$...;;.>==.....#$.....",
+".....#$..=$...;.*==......#$.....",
+".....#$..$$$$$$===$$$$$..#$.....",
+".....#$..$$$$$==$$$$$$$..#$.....",
+".....#$..$$.;*==.;.;;....#$.....",
+".....#$..$$-*==.&;;;;....#$.....",
+".....#$..$=>==..;;;.&....#$.....",
+".....#$..$===;;;.;&;;;...#$.....",
+".....)$..$$=!;;;;;;;!....#$.....",
+".....~{.>==;.;..;;;;;;;..#$.....",
+".....]{.^=...............#$.....",
+"...../(..................#$.....",
+"....._:<@@@@@@@@@@@@@@@@@[$.....",
+".....}|1$$$$$$$$$$$$$$$$$$$.....",
+".....2345##################.....",
+"................................",
+".66666.77...77............7...6.",
+".6..667.7...7...6666.66..67666..",
+"......7.766.777767776777777766..",
+"...6677776..776777.7.677677.6...",
+".....76676.77.7.7..7.77667...6..",
+"6...776677.77766777..76.677...6.",
+"................................"};
diff --git a/images/blank.xcf b/images/blank.xcf
new file mode 100644
index 00000000..950652e5
--- /dev/null
+++ b/images/blank.xcf
Binary files differ
diff --git a/images/command.8bit.xpm b/images/command.8bit.xpm
new file mode 100644
index 00000000..a5dbc8aa
--- /dev/null
+++ b/images/command.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * command_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #211D1A",
+"+ c #735D55",
+"@ c #A4857C",
+"# c #C89870",
+"$ c #860E0C",
+"% c #BDBDBB",
+"& c #3E3936",
+"* c #86433D",
+"%#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%",
+"%*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%",
+"%*$**************************$$%",
+"%*$%%%%%%%%%%%%%%%%%%%%%%%%%%*$%",
+"%*$%%%%%%%%%%%%%%%%%%%%%%%%%%*$%",
+"%*$%%%%%%%#@@@+#@#@#@@#@@####**%",
+"%**@%%%##@#####################+",
+"%@@#%+@###########@*.*$.&**&**&+",
+"%@@@%##############@@@*@@@@%#*$%",
+"%@@%%*######*****@####+%%%%%%*$%",
+"%@+%%&*###@**@##*#@##*%%%%%%%*$%",
+"%@+%%...$...$#@######*%%%%%%%*$%",
+"%@+%%@&....*##$$.$$..&%%%%%%%*$%",
+"%@+@%+##&...*##@++*.#%%%%%%%%*$%",
+"%@@&%@###*.@+.**+*&.%%%%%%%%%*$%",
+"%@@&%*@###.**@&...&@%%%%%%%%%*$%",
+"%++.&@%#@++++.&*&@%%%%%%%%%%%*$%",
+"%...#%%%%%%%%%@+@%%%%%%%%%%%%*$%",
+"%*$%%%%%%%%%%%%%%%%%%%%%%%%%%*$%",
+"%*$%%%%%%%%%%%%%%%%%%%%%%%%%%*$%",
+"%*$@@@@@@@@@@@@@@@@@@@@@@@@@@*$%",
+"%*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%",
+"%+*****************************%",
+"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@",
+"%#.&*%%%%%%%%%%%%%%%%%%%%%%%%%#&",
+"%&@%@#++@&@+#+@&@+#+%@*&#+@+%@&&",
+"%&%%%&%&@.+.&&%.+.&&%&@&#&+.@.@+",
+"+&%%@&%+@.+.%&%.+.%&++++@&%&+@++",
+"%.%%@.%&+&@+%&+&@&@+&&&+@+@&&+&@",
+"%+&+%+&@%+@+@+@+@@@+++++@@@++&@+",
+"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%",
+"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"};
diff --git a/images/command.xcf b/images/command.xcf
new file mode 100644
index 00000000..40548654
--- /dev/null
+++ b/images/command.xcf
Binary files differ
diff --git a/images/command.xpm b/images/command.xpm
new file mode 100644
index 00000000..f9e2e4ce
--- /dev/null
+++ b/images/command.xpm
@@ -0,0 +1,336 @@
+/* XPM */
+static char * command_xpm[] = {
+"32 32 301 2",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #994848",
+"& c #8D2121",
+"* c #B1B1B1",
+"= c #A0948A",
+"- c #AE8C70",
+"; c #9F724E",
+"> c #8D6342",
+", c #976D4C",
+"' c #B18460",
+") c #AC8361",
+"! c #B88C69",
+"~ c #AA8566",
+"{ c #AA8568",
+"] c #A28166",
+"^ c #A8886E",
+"/ c #A98D75",
+"( c #B2957F",
+"_ c #B39781",
+": c #AE9784",
+"< c #9E5A4A",
+"[ c #9C3728",
+"} c #BBB7B4",
+"| c #43353E",
+"1 c #624D5E",
+"2 c #777783",
+"3 c #B4B4B4",
+"4 c #BBBBBB",
+"5 c #ABA49E",
+"6 c #AC8E76",
+"7 c #BB865C",
+"8 c #D99966",
+"9 c #C78C5D",
+"0 c #C78B5D",
+"a c #CF905F",
+"b c #C98A5B",
+"c c #CC905F",
+"d c #D89764",
+"e c #D89865",
+"f c #D99865",
+"g c #916546",
+"h c #8989A8",
+"i c #8B8B93",
+"j c #FFFFFF",
+"k c #75665A",
+"l c #B98963",
+"m c #D79865",
+"n c #D39563",
+"o c #C2895B",
+"p c #63452E",
+"q c #322115",
+"r c #523621",
+"s c #4F321F",
+"t c #25170E",
+"u c #392517",
+"v c #6F4A2F",
+"w c #6B472D",
+"x c #3E2818",
+"y c #5E3C25",
+"z c #5D3C25",
+"A c #4F301E",
+"B c #504C49",
+"C c #8A86A3",
+"D c #8888A7",
+"E c #8C8C8E",
+"F c #936E51",
+"G c #D89663",
+"H c #B58055",
+"I c #B98357",
+"J c #AA7850",
+"K c #6D4B31",
+"L c #828282",
+"M c #969696",
+"N c #B5B5B5",
+"O c #ADADAD",
+"P c #833D3D",
+"Q c #810C0C",
+"R c #8A85A2",
+"S c #777792",
+"T c #959595",
+"U c #865B3C",
+"V c #CB8A5A",
+"W c #925C38",
+"X c #865534",
+"Y c #674228",
+"Z c #8E5C3A",
+"` c #96643F",
+" . c #C18152",
+".. c #D48F5C",
+"+. c #D6925F",
+"@. c #D69360",
+"#. c #D08D5B",
+"$. c #91725C",
+"%. c #66667E",
+"&. c #9A9A9A",
+"*. c #171412",
+"=. c #7A4F30",
+"-. c #CF8A58",
+";. c #D5915E",
+">. c #CF8C5A",
+",. c #C27D4D",
+"'. c #72482B",
+"). c #4F3522",
+"!. c #A4734D",
+"~. c #B88256",
+"{. c #956946",
+"]. c #A2724C",
+"^. c #B78055",
+"/. c #D69562",
+"(. c #CC8553",
+"_. c #7E695B",
+":. c #696981",
+"<. c #1C1C1C",
+"[. c #000000",
+"}. c #150D08",
+"|. c #372315",
+"1. c #0C0704",
+"2. c #060403",
+"3. c #5A3B25",
+"4. c #D79663",
+"5. c #B97B4E",
+"6. c #D69461",
+"7. c #CE8451",
+"8. c #67422A",
+"9. c #BABABA",
+"0. c #8B819C",
+"a. c #6F6F88",
+"b. c #8A8A8A",
+"c. c #6A513F",
+"d. c #5E3C24",
+"e. c #20140C",
+"f. c #7F5A3C",
+"g. c #D09362",
+"h. c #C18659",
+"i. c #362518",
+"j. c #4A2E1C",
+"k. c #382315",
+"l. c #432A19",
+"m. c #352114",
+"n. c #140D08",
+"o. c #424242",
+"p. c #74748E",
+"q. c #676767",
+"r. c #DADADA",
+"s. c #A27C5F",
+"t. c #D28D5B",
+"u. c #845433",
+"v. c #0A0604",
+"w. c #302217",
+"x. c #795235",
+"y. c #CE8B59",
+"z. c #AC7A51",
+"A. c #996C48",
+"B. c #825C3D",
+"C. c #66452C",
+"D. c #342C27",
+"E. c #A6A6A6",
+"F. c #81819E",
+"G. c #4F4F4F",
+"H. c #97765B",
+"I. c #99603A",
+"J. c #18110B",
+"K. c #C68C5D",
+"L. c #885F3F",
+"M. c #2C1D12",
+"N. c #6F452A",
+"O. c #835332",
+"P. c #744A2E",
+"Q. c #71482C",
+"R. c #654027",
+"S. c #231F1C",
+"T. c #8B809B",
+"U. c #383839",
+"V. c #6B5A4F",
+"W. c #BA8863",
+"X. c #D18D5B",
+"Y. c #D5925F",
+"Z. c #CE8350",
+"`. c #362214",
+" + c #5F3D26",
+".+ c #805435",
+"++ c #C08456",
+"@+ c #513926",
+"#+ c #030201",
+"$+ c #0C0805",
+"%+ c #1B1B1B",
+"&+ c #484848",
+"*+ c #888888",
+"=+ c #6C6072",
+"-+ c #57576B",
+";+ c #1C1C1F",
+">+ c #363636",
+",+ c #777777",
+"'+ c #A4A09E",
+")+ c #99887C",
+"!+ c #947B6A",
+"~+ c #685F58",
+"{+ c #555555",
+"]+ c #211D19",
+"^+ c #4E3421",
+"/+ c #794D2F",
+"(+ c #6F462A",
+"_+ c #808080",
+":+ c #1C0E0E",
+"<+ c #030304",
+"[+ c #19191C",
+"}+ c #AFAFAF",
+"|+ c #919191",
+"1+ c #747474",
+"2+ c #858585",
+"3+ c #AB8383",
+"4+ c #AB8484",
+"5+ c #933434",
+"6+ c #A56E6E",
+"7+ c #999999",
+"8+ c #292929",
+"9+ c #3E3E3E",
+"0+ c #494949",
+"a+ c #AAAAAA",
+"b+ c #A2A2A2",
+"c+ c #323232",
+"d+ c #373737",
+"e+ c #8E8E8E",
+"f+ c #A7A7A7",
+"g+ c #535353",
+"h+ c #616161",
+"i+ c #939393",
+"j+ c #474747",
+"k+ c #585858",
+"l+ c #9D9D9D",
+"m+ c #8F8F8F",
+"n+ c #4C4C4C",
+"o+ c #7E7E7E",
+"p+ c #575757",
+"q+ c #989898",
+"r+ c #6A6A6A",
+"s+ c #3F3F3F",
+"t+ c #909090",
+"u+ c #5C5C5C",
+"v+ c #949494",
+"w+ c #383838",
+"x+ c #A4A4A4",
+"y+ c #8D8D8D",
+"z+ c #1D1D1D",
+"A+ c #606060",
+"B+ c #121212",
+"C+ c #343434",
+"D+ c #232323",
+"E+ c #5E5E5E",
+"F+ c #0D0D0D",
+"G+ c #353535",
+"H+ c #454545",
+"I+ c #666666",
+"J+ c #8B8B8B",
+"K+ c #2D2D2D",
+"L+ c #686868",
+"M+ c #7D7D7D",
+"N+ c #414141",
+"O+ c #B8B8B8",
+"P+ c #0C0C0C",
+"Q+ c #282828",
+"R+ c #464646",
+"S+ c #B0B0B0",
+"T+ c #141414",
+"U+ c #737373",
+"V+ c #4D4D4D",
+"W+ c #6B6B6B",
+"X+ c #5A5A5A",
+"Y+ c #4E4E4E",
+"Z+ c #979797",
+"`+ c #A1A1A1",
+" @ c #6E6E6E",
+".@ c #7B7B7B",
+"+@ c #656565",
+"@@ c #2B2B2B",
+"#@ c #A8A8A8",
+"$@ c #303030",
+"%@ c #9F9F9F",
+"&@ c #505050",
+"*@ c #818181",
+"=@ c #333333",
+"-@ c #3C3C3C",
+";@ c #757575",
+">@ c #646464",
+",@ c #515151",
+"'@ c #3A3A3A",
+")@ c #767676",
+"!@ c #444444",
+"~@ c #717171",
+"{@ c #7A7A7A",
+"]@ c #898989",
+"^@ c #838383",
+"/@ c #565656",
+"(@ c #6C6C6C",
+"_@ c #545454",
+":@ c #787878",
+". + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". # $ # # % % % % % % % # # # # % % % % # # # # # # # # # & $ . ",
+". # $ . . . . . . . . . . . . . . . . . . . . . . . . . . # $ . ",
+". # $ . . . . . . . . . . . . . . . . . . . . . . . . . . # $ . ",
+". % $ . . . . . . * = - ; > , ' ) ! ~ { { { { ] ^ / ( _ : < [ } ",
+". | 1 2 . 3 4 5 6 7 8 8 8 8 8 9 0 a b c 8 8 8 d e 8 8 8 8 8 f g ",
+". h h i j k l m 8 8 8 8 8 8 8 8 8 n o p q r s t u v w x y z A B ",
+". C D E j F 8 8 8 8 8 G 8 d f 8 8 8 8 H I J K L M M M N O P Q . ",
+". R S T j U e 8 8 8 8 V W X Y Z ` ...+.@.#.$.4 . . . . . # $ . ",
+". R %.&.j *.=.-.;.>.,.'.).!.n ~.{.].^./.(._.. . . . . . . # $ . ",
+". R :.&.j <.[.}.|.1.[.2.3.4.5.+.d d 6...7.8.9.. . . . . . # $ . ",
+". 0.a.b.j c.d.e.[.[.[.f.g.h.i.j.|.k.l.m.n.o.. . . . . . . # $ . ",
+". 0.p.q.r.s.e t.u.v.[.w.x.y.a z.A.B.C.D.E.. . . . . . . . # $ . ",
+". 0.F.G.N H.8 8 6.I.J.K.L.M.N.O.P.Q.R.S.. . . . . . . . . # $ . ",
+". T.h U.3 V.W.X.Y.Z.`. +.+++@+#+$+%+&+*+. . . . . . . . . # $ . ",
+". =+-+;+>+,+4 '+)+!+~+G.{+]+^+/+(+_+. . . . . . . . . . . # $ . ",
+". :+<+[+}+. . . . . . . . 4 |+1+2+. . . . . . . . . . . . # $ . ",
+". # $ . . . . . . . . . . . . . . . . . . . . . . . . . . # $ . ",
+". # $ . . . . . . . . . . . . . . . . . . . . . . . . . . # $ . ",
+". # $ @ @ @ @ 3+4+4+4+4+4+@ @ @ 4+4+4+4+4+@ @ @ @ @ @ @ @ 5+$ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". 6+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . }+2+",
+". 7+8+9+0+a+. . . . . . . . . . . . . . . . . . . . . . . . b+c+",
+". d+e+4 f+f+g+h+i+j+_+k+l+q.m+n+o+p+q+r+3 T &+s+l+k+t+u+N v+w+d+",
+"f+c+}+. 3 s+x+9+y+z+A+B+G.C+x+D+E+F+n+G+O G+t+H+l+s+I+D+J+K+T L+",
+"M+N+. . T H+O+g+i+P+1+Q+f+R+S+T+U+D+l+V+W+X+E+Y+Z+d+`+G+ @.@+@h+",
+"f+@@#@4 _+$@%@s+M+w+2+&@x+H+*@N+M+&@7+Y+0+=@-@;@y+>@_+H+j+,@'@.@",
+". )@s+W+f+u+!@x+y+~@e+2+*+g+{@)@*+]@^@{+.@/@(@+@y+]@*@/@(@_@:@)@",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};
diff --git a/images/context.8bit.xpm b/images/context.8bit.xpm
new file mode 100644
index 00000000..dc67bc64
--- /dev/null
+++ b/images/context.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * context_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #09090A",
+"+ c #856F70",
+"@ c #958987",
+"# c #2E2E2F",
+"$ c #FEFEFC",
+"% c #860E0C",
+"& c #BCBCBA",
+"* c #7B403E",
+"&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&",
+"&*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&",
+"&*%**************************%%&",
+"&*%&&&&&&&&&&&&&&&&&&&&&&&&&&*%&",
+"&*%&&&&&&@@@&&&&&&&@@@&&&&&&&*%&",
+"&*%&&&&++@@@+&&&&@+@@@@&&&&&&*%&",
+"&*%&&&+@+*....@&+@+#...*@&&&&*%&",
+"&+%&&@++.#+@@+.#@*.*+@@*.@&&&*%&",
+"&*%&&@@.+&$$$&&#..&$$$&&&.@&&*%&",
+"&+%&&@*#&$$$#.&@.#$$$&##&**&&*%&",
+"&*%&&@##$$$&#.+$.@$$$@..&@.&&*%&",
+"&+%&&@##$$$$&+$$.@$$$$@&$&.&&*%&",
+"&*%&&+##$$$$$$$$.@$$$$$$$@.&&*%&",
+"&+%&&@##$$$$$$$$.@$$$$$$$@.&&*%&",
+"&*%&&&*#$$$$$$$&.+$$$$$$$+.&&+%&",
+"&+%&&&&.+$$$$$$#..&$$$$$&.@&&*%&",
+"&*%&&&&+##&$&&##@##@$$&@#*&&&*%&",
+"&*%&&&&&@#....*@&&*....#*&&&&*%&",
+"&*%&&&&&&&@@@@&&&&&&+@@@&&&&&*%&",
+"&*%&&&&&&&&&&&&&&&&&&&&&&&&&&*%&",
+"&*%@@@@@@@@@@@@@@@@@@@@@@@@@@*%&",
+"&*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&",
+"&@*****************************&",
+"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
+"&&+.*#@&&&&&&&&&&&@&&&&&&&&&&&@&",
+"&*#&&&@&+*&@*&+*&##+&@*+&*@+++.#",
+"@.@&&&&.@+.&.*+.&#*&@*@.&+##++.&",
+"@.&&&&+#&@.@.++#&#@&.#*@&@.+&+#&",
+"@.+&&@##&.@@#&#+&.+&.+&+@#++&#*&",
+"&@##+&&##@&++&*#&+#&+#+@++&#@@#@",
+"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"};
diff --git a/images/context.xcf b/images/context.xcf
new file mode 100644
index 00000000..fc9ad9d9
--- /dev/null
+++ b/images/context.xcf
Binary files differ
diff --git a/images/context.xpm b/images/context.xpm
new file mode 100644
index 00000000..f39fc805
--- /dev/null
+++ b/images/context.xpm
@@ -0,0 +1,180 @@
+/* XPM */
+static char * context_xpm[] = {
+"32 32 145 2",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #994848",
+"& c #8D2121",
+"* c #A2A2A2",
+"= c #919191",
+"- c #959595",
+"; c #AFAFAF",
+"> c #B3B3B3",
+", c #7A7A7A",
+"' c #787878",
+") c #7F7F7F",
+"! c #7C7C7C",
+"~ c #797979",
+"{ c #A3A3A3",
+"] c #878787",
+"^ c #777777",
+"/ c #808080",
+"( c #870F0F",
+"_ c #6D6D6D",
+": c #4F4F4F",
+"< c #0A0A0A",
+"[ c #141414",
+"} c #8E8E8E",
+"| c #AEAEAE",
+"1 c #818181",
+"2 c #7E7E7E",
+"3 c #616161",
+"4 c #2F2F2F",
+"5 c #090909",
+"6 c #454545",
+"7 c #994949",
+"8 c #891313",
+"9 c #181818",
+"0 c #7D7D7D",
+"a c #8D8D8D",
+"b c #888888",
+"c c #757575",
+"d c #010101",
+"e c #383838",
+"f c #525252",
+"g c #030303",
+"h c #464646",
+"i c #050505",
+"j c #994A4A",
+"k c #8A1818",
+"l c #7B7B7B",
+"m c #121212",
+"n c #6E6E6E",
+"o c #D3D3D3",
+"p c #FBFBFB",
+"q c #FDFDFD",
+"r c #E1E1E1",
+"s c #C4C4C4",
+"t c #3D3D3D",
+"u c #0D0D0D",
+"v c #BABABA",
+"w c #E6E6E6",
+"x c #CECECE",
+"y c #B8B8B8",
+"z c #080808",
+"A c #9A4C4C",
+"B c #8B1C1C",
+"C c #555555",
+"D c #222222",
+"E c #B9B9B9",
+"F c #FCFCFC",
+"G c #FEFEFE",
+"H c #EBEBEB",
+"I c #3A3A3A",
+"J c #070707",
+"K c #999999",
+"L c #9B9B9B",
+"M c #000000",
+"N c #494949",
+"O c #FFFFFF",
+"P c #B2B2B2",
+"Q c #131313",
+"R c #2D2D2D",
+"S c #C5C5C5",
+"T c #3C3C3C",
+"U c #9B4E4E",
+"V c #303030",
+"W c #393939",
+"X c #F2F2F2",
+"Y c #E4E4E4",
+"Z c #171717",
+"` c #939393",
+" . c #C7C7C7",
+".. c #8C1E1E",
+"+. c #3F3F3F",
+"@. c #BDBDBD",
+"#. c #868686",
+"$. c #F4F4F4",
+"%. c #9F9F9F",
+"&. c #F6F6F6",
+"*. c #949494",
+"=. c #FAFAFA",
+"-. c #994B4B",
+";. c #8B1B1B",
+">. c #F7F7F7",
+",. c #F3F3F3",
+"'. c #891414",
+"). c #B0B0B0",
+"!. c #4B4B4B",
+"~. c #323232",
+"{. c #E3E3E3",
+"]. c #D5D5D5",
+"^. c #F8F8F8",
+"/. c #0E0E0E",
+"(. c #881010",
+"_. c #0C0C0C",
+":. c #F0F0F0",
+"<. c #E8E8E8",
+"[. c #444444",
+"}. c #828282",
+"|. c #707070",
+"1. c #232323",
+"2. c #545454",
+"3. c #E2E2E2",
+"4. c #CBCBCB",
+"5. c #373737",
+"6. c #1A1A1A",
+"7. c #3E3E3E",
+"8. c #343434",
+"9. c #8F8F8F",
+"0. c #D9D9D9",
+"a. c #ECECEC",
+"b. c #870E0E",
+"c. c #4A4A4A",
+"d. c #515151",
+"e. c #202020",
+"f. c #8A8A8A",
+"g. c #AB8383",
+"h. c #AB8484",
+"i. c #933434",
+"j. c #A56E6E",
+"k. c #151515",
+"l. c #2A2A2A",
+"m. c #A7A7A7",
+"n. c #696969",
+". + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". # $ # # % % % % % % % # # # # % % % % # # # # # # # # # & $ . ",
+". # $ . . . . . . . . . . . . . . . . . . . . . . . . . . # $ . ",
+". # $ . . . . . * = = - . . . . . . ; = = = > . . . . . . # $ . ",
+". % $ . . . . , ' ) ) ! ~ { . . . ] ^ / / / ~ . . . . . . # $ . ",
+". % ( . . ; ' ) _ : < < < [ } | 1 2 3 4 5 5 5 6 = . . . . # $ . ",
+". 7 8 . . } ) _ 9 9 0 a b c d e / f g h 1 = 1 h i ~ . . . # $ . ",
+". j k . . l ) m n o p q r s s t u i v w p p x s y z b . . # $ . ",
+". A B . . ) C D E F G H I J K L M N H O O P Q R S N T . . # $ . ",
+". U B . . ) V W X G G Y Z g ' H M a q O O ` J m .a M . . # $ . ",
+". U ... . ) V +.G G G F @.#.$.O M %.O O O &.*.; =.%.d . . # $ . ",
+". -.... . , V +.G G G G G G G O M %.O O O O O G G %.M . . # $ . ",
+". -.;.. . } V T >.G G G G G G ,.M - q O O O O G q - d . . # $ . ",
+". 7 '.. . ).!.~.{.G G G G G q ].M , ^.O O O O G ^., /.. . # $ . ",
+". 7 (.. . . . _.l :.G G G G <.[.M M o ^.O O O ^.o d }.. . # $ . ",
+". % ( . . . . |.1.2.].<.3.4.5.6.} 7.8.9.0.a.0.9.8.7.| . . # $ . ",
+". % b.. . . . . ! T d d d i c.K . . d.e.M M M e.d.. . . . # $ . ",
+". # $ . . . . . . P ] ] ] f.. . . . . %.] ] ] %.. . . . . # $ . ",
+". # $ . . . . . . . . . . . . . . . . . . . . . . . . . . # $ . ",
+". # $ @ @ @ @ g.h.h.h.h.h.@ @ @ h.h.h.h.h.@ @ @ @ @ @ @ @ i.$ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". j.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . 2.k.+.l.0 . . . . . . . . . . m.0 . . . . . . . . . . . 0 m.",
+". +.l.. . m.m.m.2.+.` ` +.` n.2.. l.k.n.. ` +.n.. 2.0 n.n.n.M +.",
+"m.M ` . . . m.k.m.n.M . M 2.2.M . +.2.. 0 +.0 k.. n.l.l.0 0 k.. ",
+"0 M . . . . 2.+.. 0 k.m.M 0 n.+.. l.0 . k.l.+.` . m.M n.. n.+.. ",
+"m.M 0 . . m.+.l.m.k.0 0 l.. +.2.. M 0 . M n.. n.` +.n.n.. +.+.. ",
+". ` +.+.n.m.m.+.+.` . 0 n.. 2.+.. 2.+.. 0 +.2.` n.n.. +.` 0 +.` ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};
diff --git a/images/coq-badge.xcf b/images/coq-badge.xcf
new file mode 100644
index 00000000..98ba6ded
--- /dev/null
+++ b/images/coq-badge.xcf
Binary files differ
diff --git a/images/find.8bit.xpm b/images/find.8bit.xpm
new file mode 100644
index 00000000..5e4ce58e
--- /dev/null
+++ b/images/find.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * find_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #1B1C1D",
+"+ c #8A4948",
+"@ c #8C7E81",
+"# c #BABEBD",
+"$ c #EBFEFC",
+"% c #373132",
+"& c #D4F4FA",
+"* c #761917",
+"#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#",
+"#+*****************************#",
+"#+*+++++++++++++++*+%#@#@++++**#",
+"#+*###############@##&#&&@+##+*#",
+"#+*################&#&&#&$###+*#",
+"#+*############%#&&&&&&&&$&##+*#",
+"#+*###########@%#&#&&&&&$$$#++*#",
+"#+*###########%@&&&&&$$$$$&$#+*#",
+"#+*###########.&&&&&&$$$$$$&@+*#",
+"#+*###########@&&&&$$$$$$$$@++*#",
+"#+*###########%&&&&$$$$$$$$%%+*#",
+"#+*########@@#@&&$$$$$$$$&&@.+*#",
+"#+*######+..@#&@@&&$$$$$&##%@+*#",
+"#+*###@+%.%.@&&#@#&$$&#@.#&.@+*#",
+"#+*###*%...%.%###@@@&%@@@@#@#+*#",
+"#+*#@+..%%%%%@###@.%@@%@%%@##+*#",
+"#+*%%%%%%%%@##########@######+*#",
+"#+*%%%@#@@###################+*#",
+"#+*%@#&######################+*#",
+"#+*##########################+*#",
+"#+*@@@@@@@@@@@@@@@@@@@@@@@@@@**#",
+"#+*****************************#",
+"#++++++++++++++++++++++++++++++#",
+"################################",
+"#############@@########@@@######",
+"########+.+%++@#########*@######",
+"########@.##@+@@%@+@##+%.#######",
+"########+.%+#.#@.@%*#.@@*#######",
+"########%+##@.#+.@%@@%#.+#######",
+"########.@##+%#%@#.@%%+.@#######",
+"#######+%%##@%#+@#%@@%#%@#######",
+"################################"};
diff --git a/images/find.xcf b/images/find.xcf
new file mode 100644
index 00000000..1c5fbe92
--- /dev/null
+++ b/images/find.xcf
Binary files differ
diff --git a/images/find.xpm b/images/find.xpm
new file mode 100644
index 00000000..814864fc
--- /dev/null
+++ b/images/find.xpm
@@ -0,0 +1,259 @@
+/* XPM */
+static char * find_xpm[] = {
+"32 32 224 2",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #7B0C0C",
+"& c #6A0D0E",
+"* c #850D0D",
+"= c #470707",
+"- c #812125",
+"; c #994848",
+"> c #4A2323",
+", c #3F414B",
+"' c #375F74",
+") c #8BAABF",
+"! c #647F8C",
+"~ c #68B3D9",
+"{ c #7592AD",
+"] c #846571",
+"^ c #8D2121",
+"/ c #B8BCBD",
+"( c #ABBAC2",
+"_ c #5994B2",
+": c #92C5D9",
+"< c #6EB7DB",
+"[ c #C4E8F3",
+"} c #A2D5E9",
+"| c #B3E0F0",
+"1 c #B7E3F1",
+"2 c #668A99",
+"3 c #565656",
+"4 c #B1C5CF",
+"5 c #75BADC",
+"6 c #82C4E1",
+"7 c #CAF1F8",
+"8 c #B2E5F2",
+"9 c #C2EDF6",
+"0 c #B3E5F2",
+"a c #B5E7F3",
+"b c #C8F0F8",
+"c c #E3FEFF",
+"d c #86BCD4",
+"e c #B0BBC0",
+"f c #3B3B3B",
+"g c #A4C4D3",
+"h c #E2FAFC",
+"i c #B6E6F2",
+"j c #BCEAF5",
+"k c #CCF2F9",
+"l c #D0F4FA",
+"m c #CDF3F9",
+"n c #DEFBFD",
+"o c #D2F5FA",
+"p c #E5FFFF",
+"q c #CBEEF5",
+"r c #C7D1D1",
+"s c #B5B5B5",
+"t c #870F0F",
+"u c #818181",
+"v c #2F393C",
+"w c #97D1E8",
+"x c #B4E6F3",
+"y c #E4FEFF",
+"z c #E4FFFF",
+"A c #E8FFFF",
+"B c #F3FFFF",
+"C c #F0FFFF",
+"D c #E6FFFF",
+"E c #A5B8B8",
+"F c #464646",
+"G c #994949",
+"H c #891313",
+"I c #3C3C3C",
+"J c #8C9C9C",
+"K c #C9F1F8",
+"L c #D7F8FB",
+"M c #EBFFFF",
+"N c #F4FFFF",
+"O c #FFFFFF",
+"P c #E7FFFF",
+"Q c #C1C8C8",
+"R c #994A4A",
+"S c #8A1818",
+"T c #ADADAD",
+"U c #0A0B0B",
+"V c #DFF9F9",
+"W c #C0ECF6",
+"X c #DDFBFD",
+"Y c #F5FFFF",
+"Z c #F6FFFF",
+"` c #CFEBEE",
+" . c #7AA1B4",
+".. c #9A4C4C",
+"+. c #8B1C1C",
+"@. c #91ADBB",
+"#. c #BBE5F2",
+"$. c #ECFFFF",
+"%. c #6F7C7C",
+"&. c #61686B",
+"*. c #9B4E4E",
+"=. c #3B474D",
+"-. c #B2D1D8",
+";. c #EFFFFF",
+">. c #F9FFFF",
+",. c #FAFFFF",
+"'. c #212728",
+"). c #2E2E2E",
+"!. c #8C4141",
+"~. c #8C1E1E",
+"{. c #878787",
+"]. c #7D7D7D",
+"^. c #BABCBD",
+"/. c #909698",
+"(. c #CEF0F4",
+"_. c #C3E5EC",
+":. c #4C7385",
+"<. c #212121",
+"[. c #994B4B",
+"}. c #6F6F6F",
+"|. c #2A2A2A",
+"1. c #282828",
+"2. c #6A7D87",
+"3. c #8CB7CD",
+"4. c #B5D6E5",
+"5. c #8A9EA4",
+"6. c #5D6868",
+"7. c #E2FCFC",
+"8. c #A7CDDA",
+"9. c #BADDE9",
+"0. c #3A4E56",
+"a. c #666666",
+"b. c #8B1B1B",
+"c. c #949494",
+"d. c #6C6C6C",
+"e. c #292929",
+"f. c #171717",
+"g. c #141617",
+"h. c #5A8DA7",
+"i. c #EFF7FB",
+"j. c #D4D8DB",
+"k. c #C7C7C7",
+"l. c #7396A6",
+"m. c #99BFCC",
+"n. c #D1EEF1",
+"o. c #E1FBFB",
+"p. c #B4C8C8",
+"q. c #7E9092",
+"r. c #1C262B",
+"s. c #70A1B8",
+"t. c #E1ECF0",
+"u. c #070707",
+"v. c #AAAAAA",
+"w. c #891414",
+"x. c #3A3A3A",
+"y. c #232323",
+"z. c #161616",
+"A. c #1B1B1B",
+"B. c #202020",
+"C. c #313131",
+"D. c #4C4C4C",
+"E. c #A5AFB5",
+"F. c #7A97A6",
+"G. c #47778F",
+"H. c #7AA5B8",
+"I. c #B2D4DD",
+"J. c #3E4545",
+"K. c #475F6A",
+"L. c #486C7E",
+"M. c #6091A8",
+"N. c #597F91",
+"O. c #99B3BD",
+"P. c #A1A1A1",
+"Q. c #881010",
+"R. c #A6A6A6",
+"S. c #8C8C8C",
+"T. c #4F4F4F",
+"U. c #2F2F2F",
+"V. c #050505",
+"W. c #3E3E3E",
+"X. c #272727",
+"Y. c #8E8E8E",
+"Z. c #000001",
+"`. c #394D56",
+" + c #6E93A6",
+".+ c #537C90",
+"++ c #334B56",
+"@+ c #749EB3",
+"#+ c #1B292F",
+"$+ c #4F5456",
+"%+ c #370606",
+"&+ c #454545",
+"*+ c #333333",
+"=+ c #383838",
+"-+ c #3D3D3D",
+";+ c #323232",
+">+ c #2C2C2C",
+",+ c #6A6A6A",
+"'+ c #AEAEAE",
+")+ c #9C9C9C",
+"!+ c #A6AAAC",
+"~+ c #999999",
+"{+ c #520B0B",
+"]+ c #252525",
+"^+ c #3F3F3F",
+"/+ c #C5C5C5",
+"(+ c #707070",
+"_+ c #868686",
+":+ c #ABABAB",
+"<+ c #6D0A0A",
+"[+ c #7F7F7F",
+"}+ c #E7E7E7",
+"|+ c #BFBFBF",
+"1+ c #C8C8C8",
+"2+ c #AB8383",
+"3+ c #AB8484",
+"4+ c #933434",
+"5+ c #A56E6E",
+"6+ c #939393",
+"7+ c #A7A7A7",
+"8+ c #696969",
+"9+ c #000000",
+"0+ c #545454",
+"a+ c #151515",
+". + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % & * = - $ $ $ $ $ $ $ . ",
+". # $ # # ; ; ; ; ; ; ; # # # # ; ; > , ' ) ! ~ { ] # # # ^ $ . ",
+". # $ . . . . . . . . . . . . . / ( _ : < [ } | 1 2 3 . . # $ . ",
+". # $ . . . . . . . . . . . . . 4 5 6 7 8 9 0 a b c d e . # $ . ",
+". ; $ . . . . . . . . . . . . f g h i j k l m n o p q r s # $ . ",
+". ; t . . . . . . . . . . . u v w 0 x y z p A B C D p E F # $ . ",
+". G H . . . . . . . . . . . I J K b L p M N O O O P p p Q # $ . ",
+". R S . . . . . . . . . . T U V W X p p Y O O O Z p p ` .# $ . ",
+". ..+.. . . . . . . . . . . @.#.p p p P O O O O $.p p %.&.# $ . ",
+". *.+.. . . . . . . . . . . =.-.p p p p ;.>.,.C p p p '.).!.$ . ",
+". *.~.. . . . . . . T {.].^./.(.p p p p p p P p p p _.:.<.# $ . ",
+". [.~.. . . . . . }.|.1.2.3.4.5.6.p p p p p p p 7.8.9.0.a.# $ . ",
+". [.b.. . . c.d.e.f.|.g.h.i.j.k.l.m.n.p p o.p.q.r.s.t.u.v.# $ . ",
+". G w.. . . x.y.z.A.B.C.1.D.. . E.F.G.H.I.J.K.L.M.N.O.P.. # $ . ",
+". G Q.R.S.T.U.V.e.I W.y.X.].. . . Y.Z.`. +.+++@+#+$+c.. . # $ . ",
+". ; %+&+*+=+f -+;+).>+,+. . . . . . '+)+. !+u . ~+. . . . # $ . ",
+". ; {+]+^+^+a./+(+_+:+. . . . . . . . . . . . . . . . . . # $ . ",
+". # <+&+[+s }+k.. . . . . . . . . . . . . . . . . . . . . # $ . ",
+". # $ . |+1+. . . . . . . . . . . . . . . . . . . . . . . # $ . ",
+". # $ @ @ @ @ 2+3+3+3+3+3+@ @ @ 3+3+3+3+3+@ @ @ @ @ @ @ @ 4+$ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". 5+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . 6+6+. . . . . . . . 7+].7+. . . . . . ",
+". . . . . . . . 8+9+^+^+0+8+].. . . . . . . . 7+9+6+. . . . . . ",
+". . . . . . . . 6+9+. . 6+^+6+8+^+7+0+].. 7+0+^+9+. . . . . . . ",
+". . . . . . . . 8+a+^+0+. 9+. ].a+8+|.^+. a+7+].^+. . . . . . . ",
+". . . . . . . . ^+0+7+7+].a+. 8+a+7+|.].].^+. a+0+. . . . . . . ",
+". . . . . . . . a+].. . 8+^+. ^+8+. 9+6+^+|.0+|.].. . . . . . . ",
+". . . . . . . 8+^+0+. . 8+^+. 0+6+7+^+8+].^+7+^+8+. . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};
diff --git a/images/fireworks.xcf b/images/fireworks.xcf
new file mode 100644
index 00000000..81a40470
--- /dev/null
+++ b/images/fireworks.xcf
Binary files differ
diff --git a/images/gimp/.cvsignore b/images/gimp/.cvsignore
new file mode 100644
index 00000000..10b93a39
--- /dev/null
+++ b/images/gimp/.cvsignore
@@ -0,0 +1,5 @@
+menurc
+pluginrc
+unitrc
+parasiterc
+
diff --git a/images/gimp/scripts/proofgeneral.scm b/images/gimp/scripts/proofgeneral.scm
new file mode 100644
index 00000000..68c3921b
--- /dev/null
+++ b/images/gimp/scripts/proofgeneral.scm
@@ -0,0 +1,98 @@
+;;
+;; Gimp script fu to make buttons from a source .xcf file.
+;;
+;; David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+
+
+;; TODO: make greyed out, pressed, unpressed versions.
+;; e.g. : Add bevel for "up" position:
+;; (script-fu-add-bevel 0 image
+;; (car (gimp-image-active-drawable image)) "10" 0 0)
+
+(define (script-fu-proofgeneral-make-button buttonname)
+ (let* ((filename (string-append buttonname ".xcf"))
+ (image (car (gimp-file-load 1 filename filename)))
+ (xpmname (string-append buttonname ".xpm"))
+ (poor-xpm (string-append buttonname ".8bit.xpm")))
+ (gimp-image-flatten image)
+ ;; Full xpm
+ (gimp-file-save 1 image (car (gimp-image-active-drawable image))
+ xpmname xpmname)
+ ;; Impoverised xpm
+ (gimp-convert-indexed image 1 0 8 1 1 "blah")
+ (gimp-file-save 1 image (car (gimp-image-active-drawable image))
+ poor-xpm poor-xpm)
+ ;; Finish
+ (gimp-image-delete image)
+ ))
+
+(script-fu-register "script-fu-proofgeneral-make-button"
+ "<Toolbox>/Xtns/Script-Fu/Proof General/Make Button"
+ "Save buttons in various formats"
+ "da@dcs.ed.ac.uk" "da@dcs.ed.ac.uk"
+ "1998/10/04"
+ ""
+ SF-VALUE "Button/file name" "\"goal\"")
+
+(define (script-fu-proofgeneral-make-all-buttons)
+ (mapcar script-fu-proofgeneral-make-button
+ '("goal" "next" "qed" "restart" "retract" "undo" "use" "state" "context" "info" "command" "find" "help" "interrupt" "goto" "abort")))
+
+(script-fu-register "script-fu-proofgeneral-make-all-buttons"
+ "<Toolbox>/Xtns/Script-Fu/Proof General/Make All Buttons"
+ "Save Proof General buttons in the various formats"
+ "da@dcs.ed.ac.uk" "da@dcs.ed.ac.uk"
+ "1998/10/04"
+ "")
+
+(define (script-fu-proofgeneral-save-pic imgname)
+ (let* ((filename (string-append imgname ".xcf"))
+ (image (car (gimp-file-load 1 filename filename)))
+ (jpgname (string-append imgname ".jpg"))
+ (gifname (string-append imgname ".gif"))
+ (poorgifname (string-append imgname ".8bit.gif")))
+ ;; Flatten and save as jpg
+ ;;(gimp-image-flatten image)
+ ;; Flattening forces a white background. Let's use merge.
+ (if (> (car (gimp-image-get-layers image)) 1)
+ (gimp-image-merge-visible-layers image 0))
+ (file-jpeg-save 1 image (car (gimp-image-active-drawable image))
+ jpgname jpgname
+ 0.75 0 1)
+ ;; gif with full palette
+ (gimp-convert-indexed image TRUE 255)
+ (file-gif-save 1 image (car (gimp-image-active-drawable image))
+ gifname gifname
+ FALSE FALSE 0 0)
+ ;; gif with impoverished palette for display in XEmacs
+ (gimp-convert-rgb image)
+ (gimp-convert-indexed image 1 15)
+ (file-gif-save 1 image (car (gimp-image-active-drawable image))
+ poorgifname poorgifname
+ FALSE FALSE 0 0)
+ ;; Finish
+ (gimp-image-delete image)
+ ))
+
+(script-fu-register "script-fu-proofgeneral-save-jpg"
+ "<Toolbox>/Xtns/Script-Fu/Proof General/Save Jpeg"
+ "Save image as jpeg"
+ "da@dcs.ed.ac.uk" "da@dcs.ed.ac.uk"
+ "1998/10/04"
+ ""
+ SF-VALUE "Basename" "\"test\"")
+
+
+(define (script-fu-proofgeneral-save-all-pix)
+ (mapcar script-fu-proofgeneral-save-pic
+ '("ProofGeneral" "pg-text")))
+
+(script-fu-register "script-fu-proofgeneral-save-all-jpegs"
+ "<Toolbox>/Xtns/Script-Fu/Proof General/Save all Jpegs"
+ "Save Proof General images as jpegs"
+ "da@dcs.ed.ac.uk" "da@dcs.ed.ac.uk"
+ "1998/10/04"
+ "") \ No newline at end of file
diff --git a/images/goal.8bit.xpm b/images/goal.8bit.xpm
new file mode 100644
index 00000000..1d64db49
--- /dev/null
+++ b/images/goal.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * goal_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #10170F",
+"+ c #656545",
+"@ c #8A9175",
+"# c #79CE62",
+"$ c #BCC5B7",
+"% c #E1ECDD",
+"& c #383C35",
+"* c #8B2826",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@$",
+"$******************************$",
+"$******************************$",
+"$$%%%%%$$%#%%#%#%#%##%##%######$",
+"$#%##@@++@&@###########+###@###$",
+"$%%@@++@@&+.+&+&+@&&+&&&&++#&##$",
+"$%@@@$$+#+@@++++++&&&&+@#@&@&##$",
+"$%@$@$%+%@#@@###+##+##@##@&+&+#$",
+"$%+$@#%@##&++#@#@##++#&#+#+++&#$",
+"$%@$$@#@.@+#&#@++&@###+@&#+#+&#$",
+"$%@$@&@%#$@%#&%@#@##@#@#@#+#&&@$",
+"$%+$%@%$&++$@+++@@#%#@@###+++++#",
+"$%*$%++$@$&@#%%#%#+@+##+@@+&&.+$",
+"$%+$%&%%$+$%%%%%%#%%#%#%##++++#$",
+"$%+%$+%@@%%%%%%%%%%%%%#%%#+@+#%$",
+"$%+%%$&$%%%%%%%%%%%%#%%%%%+++#%$",
+"$%+%@+$%%%%%%%%%%%%%%%%%#%+##%#$",
+"$$+$$%%%%%%%%%%%%%%%%%%%%%@$%%%$",
+"$%+%%%%%%%%%%%%%%%%%%%%%%%$$#%%$",
+"$%$%%%%%%%%%%%%%%%%%%%%%%%%%%%%$",
+"$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$",
+"$***************************.**$",
+"$+*****************************$",
+"$$$$$$$$$$$$$$$$$$$$$$$$+$$$$$$$",
+"$$$$$$$$+.&&@$$$$$$$$$$@.@$$$$$$",
+"$$$$$$$*&$$@$$+&+$$+&&@$.$$$$$$$",
+"$$$$$$@.@$$$$&+@.@&+$.@+&$$$$@$$",
+"$@$$@$@.$$..+.$$.+.$&.$+&$$@$$$$",
+"$$$$$$@.+$&++.@&&+.+&&$*+$$$$$$$",
+"$$$$$$$@*&&$$&&+$$&@+&$&+$$$@$$$",
+"$@$$@$$$$$$$$$$$$$$$$$$$$$$$$$$$"};
diff --git a/images/goal.xcf b/images/goal.xcf
new file mode 100644
index 00000000..9613c52f
--- /dev/null
+++ b/images/goal.xcf
Binary files differ
diff --git a/images/goal.xpm b/images/goal.xpm
new file mode 100644
index 00000000..ede117f9
--- /dev/null
+++ b/images/goal.xpm
@@ -0,0 +1,586 @@
+/* XPM */
+static char * goal_xpm[] = {
+"32 32 551 2",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #994848",
+"& c #8D2121",
+"* c #A8E1A3",
+"= c #A8E29F",
+"- c #A8E498",
+"; c #A1DF96",
+"> c #A3E098",
+", c #A2DB8D",
+"' c #A1CD74",
+") c #96CA6C",
+"! c #92D674",
+"~ c #8FDF77",
+"{ c #8FE176",
+"] c #8ADE73",
+"^ c #8BD974",
+"/ c #83DB71",
+"( c #7EDE68",
+"_ c #85DD67",
+": c #7BDF62",
+"< c #7CDD5C",
+"[ c #76DF60",
+"} c #6FDA52",
+"| c #75D857",
+"1 c #74DF59",
+"2 c #6DD552",
+"3 c #6EDD53",
+"4 c #6DDF53",
+"5 c #6ADA5B",
+"6 c #72D751",
+"7 c #6FDA4E",
+"8 c #6DE152",
+"9 c #72DA51",
+"0 c #B7E7A6",
+"a c #B3E9A6",
+"b c #B4E6A2",
+"c c #A4D694",
+"d c #6F8958",
+"e c #8C7F31",
+"f c #6E6D2E",
+"g c #6E7636",
+"h c #65793F",
+"i c #344A2D",
+"j c #6CA65C",
+"k c #7ABD6A",
+"l c #92DF7C",
+"m c #88D976",
+"n c #72B759",
+"o c #72BC5D",
+"p c #6EB656",
+"q c #69B94F",
+"r c #6FCC5B",
+"s c #71D15F",
+"t c #71D759",
+"u c #68CC4D",
+"v c #417C31",
+"w c #58B145",
+"x c #60CC4D",
+"y c #60A33A",
+"z c #579833",
+"A c #5DBA45",
+"B c #6EDD54",
+"C c #72DC58",
+"D c #BFECB1",
+"E c #BBE7AE",
+"F c #899C70",
+"G c #957829",
+"H c #A5781B",
+"I c #806720",
+"J c #958F43",
+"K c #807F38",
+"L c #4A4A20",
+"M c #41512F",
+"N c #1D2819",
+"O c #395533",
+"P c #243620",
+"Q c #406239",
+"R c #263A20",
+"S c #548246",
+"T c #5B8E4C",
+"U c #2F4F28",
+"V c #284024",
+"W c #375E2F",
+"X c #2A4922",
+"Y c #142610",
+"Z c #243E16",
+"` c #2F3D11",
+" . c #516318",
+".. c #5A862F",
+"+. c #69A938",
+"@. c #326026",
+"#. c #70DC57",
+"$. c #6BD953",
+"%. c #C9E9BD",
+"&. c #9AAE83",
+"*. c #9D7E2F",
+"=. c #9D975C",
+"-. c #AECA8E",
+";. c #AFD592",
+">. c #65764D",
+",. c #9AB173",
+"'. c #6B6833",
+"). c #A1A14E",
+"!. c #958D3B",
+"~. c #71631D",
+"{. c #72621E",
+"]. c #74621E",
+"^. c #70621E",
+"/. c #685817",
+"(. c #645717",
+"_. c #4F430F",
+":. c #42390D",
+"<. c #3F390D",
+"[. c #433D0E",
+"}. c #6D7020",
+"|. c #799D39",
+"1. c #7BBA48",
+"2. c #718A2A",
+"3. c #284519",
+"4. c #4A933D",
+"5. c #285022",
+"6. c #4E9C38",
+"7. c #6DDE50",
+"8. c #CCE6CA",
+"9. c #8E9972",
+"0. c #ACA260",
+"a. c #8EA98A",
+"b. c #A6C69E",
+"c. c #BEE2B1",
+"d. c #63795A",
+"e. c #B8E6AC",
+"f. c #81A174",
+"g. c #81A47A",
+"h. c #7BA172",
+"i. c #66895D",
+"j. c #A2E895",
+"k. c #7AB078",
+"l. c #90C77B",
+"m. c #537848",
+"n. c #A3E086",
+"o. c #94D278",
+"p. c #57763E",
+"q. c #90D16F",
+"r. c #88C96A",
+"s. c #558E4F",
+"t. c #86DF70",
+"u. c #5EA450",
+"v. c #80B247",
+"w. c #3D5220",
+"x. c #36622E",
+"y. c #1F3916",
+"z. c #39722D",
+"A. c #6CDF54",
+"B. c #D5EAD2",
+"C. c #7A7B66",
+"D. c #BDAE6C",
+"E. c #98A690",
+"F. c #A9C2A4",
+"G. c #C8E3BD",
+"H. c #7C9174",
+"I. c #9DB48A",
+"J. c #A6C79A",
+"K. c #354031",
+"L. c #455841",
+"M. c #4D6645",
+"N. c #AFE2A3",
+"O. c #87B177",
+"P. c #87B377",
+"Q. c #6D8F60",
+"R. c #97D084",
+"S. c #9AD283",
+"T. c #334E31",
+"U. c #5C8A4F",
+"V. c #5E9153",
+"W. c #345130",
+"X. c #93E176",
+"Y. c #538447",
+"Z. c #8FD26F",
+"`. c #595E1D",
+" + c #385D2C",
+".+ c #467B39",
+"++ c #1D3618",
+"@+ c #7DDB5C",
+"#+ c #DCE6D1",
+"$+ c #7F7E67",
+"%+ c #BEAE6D",
+"&+ c #C7DEBD",
+"*+ c #809580",
+"=+ c #9EB797",
+"-+ c #768A70",
+";+ c #222721",
+">+ c #839A82",
+",+ c #6D816B",
+"'+ c #ACD1A2",
+")+ c #2A3529",
+"!+ c #92B48B",
+"~+ c #819E75",
+"{+ c #495B42",
+"]+ c #627955",
+"^+ c #2B3A27",
+"/+ c #5E8050",
+"(+ c #71A567",
+"_+ c #7FB370",
+":+ c #95D77F",
+"<+ c #4A6841",
+"[+ c #537D4A",
+"}+ c #2F4B2C",
+"|+ c #8ED77B",
+"1+ c #5D5D1C",
+"2+ c #72B861",
+"3+ c #4A8042",
+"4+ c #0F1A0E",
+"5+ c #76C967",
+"6+ c #E4EAE2",
+"7+ c #908A71",
+"8+ c #C4B87F",
+"9+ c #9AA290",
+"0+ c #3F443E",
+"a+ c #A1AD9B",
+"b+ c #CFE4C4",
+"c+ c #95A58E",
+"d+ c #B3CCAE",
+"e+ c #788570",
+"f+ c #C4E9BA",
+"g+ c #96BA95",
+"h+ c #3E4B3B",
+"i+ c #BCE4B5",
+"j+ c #708A69",
+"k+ c #BBE4AE",
+"l+ c #6C8864",
+"m+ c #B3E2A3",
+"n+ c #8EBC85",
+"o+ c #719B66",
+"p+ c #A3E591",
+"q+ c #62845A",
+"r+ c #98DE87",
+"s+ c #5C8658",
+"t+ c #8FD478",
+"u+ c #747023",
+"v+ c #88D078",
+"w+ c #233920",
+"x+ c #3C6636",
+"y+ c #598F47",
+"z+ c #E5EBE7",
+"A+ c #7B7258",
+"B+ c #CBBE92",
+"C+ c #D0D4C5",
+"D+ c #878E83",
+"E+ c #DDE9D8",
+"F+ c #A5B39F",
+"G+ c #545B54",
+"H+ c #6A736A",
+"I+ c #4A5448",
+"J+ c #C7DFC4",
+"K+ c #829781",
+"L+ c #4E604C",
+"M+ c #5C715A",
+"N+ c #5B6D55",
+"O+ c #748C6D",
+"P+ c #7B9873",
+"Q+ c #B9E6AA",
+"R+ c #ADE5A6",
+"S+ c #87AE83",
+"T+ c #779669",
+"U+ c #6C9062",
+"V+ c #96CF86",
+"W+ c #6F9D67",
+"X+ c #96D080",
+"Y+ c #786720",
+"Z+ c #557A4B",
+"`+ c #4C6F42",
+" @ c #486F3B",
+".@ c #528047",
+"+@ c #EAE7E9",
+"@@ c #564525",
+"#@ c #CFC1A1",
+"$@ c #E7E9DE",
+"%@ c #787D74",
+"&@ c #6C716C",
+"*@ c #A1A89B",
+"=@ c #A1AA9B",
+"-@ c #9CA698",
+";@ c #4E544C",
+">@ c #6F7A6D",
+",@ c #B4CCB1",
+"'@ c #C9ECCA",
+")@ c #CFEDC2",
+"!@ c #CBEABC",
+"~@ c #C2E8B6",
+"{@ c #7E987B",
+"]@ c #73886F",
+"^@ c #718C6C",
+"/@ c #6D8366",
+"(@ c #A1C594",
+"_@ c #8FBE88",
+":@ c #698D5F",
+"<@ c #688E62",
+"[@ c #688B5B",
+"}@ c #6F5A19",
+"|@ c #3B5135",
+"1@ c #10160E",
+"2@ c #131C10",
+"3@ c #4A6E40",
+"4@ c #ECEBED",
+"5@ c #654D1E",
+"6@ c #DFD5C4",
+"7@ c #CFCDC7",
+"8@ c #464745",
+"9@ c #DFDFDA",
+"0@ c #E8EDE3",
+"a@ c #B8C4B8",
+"b@ c #63685F",
+"c@ c #CAD2C9",
+"d@ c #D9EAD7",
+"e@ c #D7E9D6",
+"f@ c #D7ECD2",
+"g@ c #D2EBCE",
+"h@ c #D3E8C7",
+"i@ c #CCEBC0",
+"j@ c #C7E8C5",
+"k@ c #C6E7C1",
+"l@ c #CBEBBA",
+"m@ c #C4E8B9",
+"n@ c #BDE9AD",
+"o@ c #B4E4B2",
+"p@ c #B5E8AA",
+"q@ c #B1E7A6",
+"r@ c #B1E0A2",
+"s@ c #79601E",
+"t@ c #3B5036",
+"u@ c #425D3C",
+"v@ c #4E6946",
+"w@ c #9EE390",
+"x@ c #EDECEE",
+"y@ c #7D5E22",
+"z@ c #E7E4E2",
+"A@ c #D2D3D3",
+"B@ c #6B6A68",
+"C@ c #E7E5E5",
+"D@ c #909290",
+"E@ c #848685",
+"F@ c #E0E5DF",
+"G@ c #E5EEE7",
+"H@ c #E3ECD9",
+"I@ c #DDECDB",
+"J@ c #DDE9D6",
+"K@ c #D9EAD5",
+"L@ c #D6E6D2",
+"M@ c #D3E9CC",
+"N@ c #CEE5CA",
+"O@ c #D3E7CD",
+"P@ c #D0EDC4",
+"Q@ c #CAE9B7",
+"R@ c #C9E7B9",
+"S@ c #C1E5B4",
+"T@ c #C0E6B4",
+"U@ c #B9E6A8",
+"V@ c #B8E4A8",
+"W@ c #7A5F1E",
+"X@ c #80A47B",
+"Y@ c #384833",
+"Z@ c #A4E496",
+"`@ c #A8E69B",
+" # c #EEEAEA",
+".# c #826222",
+"+# c #EBEDEC",
+"@# c #EFEAEA",
+"## c #BFB9BE",
+"$# c #484746",
+"%# c #A7A9A8",
+"&# c #E7EFE9",
+"*# c #EDEEED",
+"=# c #EDEFEB",
+"-# c #EBEDE8",
+";# c #E3EBE6",
+"># c #DFECDD",
+",# c #DBEDDD",
+"'# c #D9EBDD",
+")# c #DCEAD9",
+"!# c #D9E9D2",
+"~# c #D9E9D1",
+"{# c #D7EDCE",
+"]# c #C8ECC4",
+"^# c #D4E6C9",
+"/# c #C5E6BB",
+"(# c #C8EAC5",
+"_# c #C5E9B9",
+":# c #BFE8B4",
+"<# c #7C601F",
+"[# c #4F6148",
+"}# c #4B6044",
+"|# c #B1EAA0",
+"1# c #ADE7A0",
+"2# c #E1DFDF",
+"3# c #896A2B",
+"4# c #EBEFEA",
+"5# c #A4A2A4",
+"6# c #747575",
+"7# c #D2D0D2",
+"8# c #F0E6ED",
+"9# c #EDEEEB",
+"0# c #EDEAF0",
+"a# c #EBEEE7",
+"b# c #EBF1EB",
+"c# c #E9EDE5",
+"d# c #E8EDE7",
+"e# c #E6ECE8",
+"f# c #E0EBE1",
+"g# c #E5EAE4",
+"h# c #E0EDDA",
+"i# c #DCECD9",
+"j# c #DBEBD4",
+"k# c #D4E8D0",
+"l# c #D3EAD0",
+"m# c #D0E9CB",
+"n# c #CFE9C9",
+"o# c #C9E6C5",
+"p# c #C5E8BD",
+"q# c #866924",
+"r# c #A6C79E",
+"s# c #B3D6A4",
+"t# c #B6E5B3",
+"u# c #B3E9AD",
+"v# c #DEE1E4",
+"w# c #856627",
+"x# c #C5C7C6",
+"y# c #9B9A9C",
+"z# c #ECEBF0",
+"A# c #EEEAEB",
+"B# c #F0ECEA",
+"C# c #E8EEEE",
+"D# c #EFEBEE",
+"E# c #EEEEEC",
+"F# c #F0F1ED",
+"G# c #F2F0EF",
+"H# c #EBEBED",
+"I# c #EFEAEC",
+"J# c #E7ECE5",
+"K# c #E6EDE4",
+"L# c #E2EEE3",
+"M# c #DFEAE2",
+"N# c #DDE6E0",
+"O# c #DCEDD5",
+"P# c #DCEFD4",
+"Q# c #DCEBD5",
+"R# c #D4E9D0",
+"S# c #D4EBC8",
+"T# c #D4EBCB",
+"U# c #A68B45",
+"V# c #A9B297",
+"W# c #C5E5BB",
+"X# c #C5E2B8",
+"Y# c #BDE9B2",
+"Z# c #EAEBED",
+"`# c #846425",
+" $ c #EAECF0",
+".$ c #EBEBF1",
+"+$ c #EDEDED",
+"@$ c #ECEDEC",
+"#$ c #EBEAEE",
+"$$ c #EAEEEF",
+"%$ c #F1EDEE",
+"&$ c #EAECED",
+"*$ c #EDEEF1",
+"=$ c #EFECEC",
+"-$ c #EBEBEE",
+";$ c #EDEEE6",
+">$ c #E7ECE7",
+",$ c #E5EDE1",
+"'$ c #E6E9E2",
+")$ c #E3EDE2",
+"!$ c #E6EADC",
+"~$ c #DBEADE",
+"{$ c #E0EBD8",
+"]$ c #D9F1D3",
+"^$ c #D8E9D0",
+"/$ c #BAB985",
+"($ c #C5C89A",
+"_$ c #CCE5C0",
+":$ c #CDEBC6",
+"<$ c #C5EAC4",
+"[$ c #EEEDEB",
+"}$ c #D9CCB1",
+"|$ c #EDEAEC",
+"1$ c #EEEEED",
+"2$ c #E7ECEB",
+"3$ c #EEECEC",
+"4$ c #EEECEF",
+"5$ c #EEEFF0",
+"6$ c #F0ECED",
+"7$ c #EBEEEC",
+"8$ c #ECEBEC",
+"9$ c #ECEDE9",
+"0$ c #F0EEEB",
+"a$ c #EBECEE",
+"b$ c #EDEDEB",
+"c$ c #EBEFE8",
+"d$ c #EBEEE8",
+"e$ c #EAEDE5",
+"f$ c #EDEBE1",
+"g$ c #E4E8E5",
+"h$ c #E6EDE0",
+"i$ c #DDEFDE",
+"j$ c #DEE7D8",
+"k$ c #DCEAD2",
+"l$ c #D8EAD0",
+"m$ c #DAE9CD",
+"n$ c #D0EDC8",
+"o$ c #D3E8C8",
+"p$ c #EEE9ED",
+"q$ c #ECE9EC",
+"r$ c #EDEBE8",
+"s$ c #EFEFEE",
+"t$ c #F0F1EC",
+"u$ c #EAECEC",
+"v$ c #EEEEEA",
+"w$ c #ECECEF",
+"x$ c #EEEEEE",
+"y$ c #EDEDEA",
+"z$ c #ECECEC",
+"A$ c #EFF0EC",
+"B$ c #EBEDEF",
+"C$ c #F0EDED",
+"D$ c #EAEBEE",
+"E$ c #EDF0EA",
+"F$ c #E9EDEB",
+"G$ c #EFECEB",
+"H$ c #EBECEB",
+"I$ c #EBE9E8",
+"J$ c #EAEAE2",
+"K$ c #E3EDE6",
+"L$ c #E6ECE5",
+"M$ c #DFECDA",
+"N$ c #DBEBDA",
+"O$ c #DCEADA",
+"P$ c #E5F0E0",
+"Q$ c #A56E6E",
+"R$ c #A7A7A7",
+"S$ c #7D7D7D",
+"T$ c #545454",
+"U$ c #151515",
+"V$ c #3F3F3F",
+"W$ c #2A2A2A",
+"X$ c #939393",
+"Y$ c #000000",
+"Z$ c #696969",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". # $ # # % % % % % % % # # # # % % % % # # # # # # # # # & $ . ",
+". * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 . ",
+". 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C . ",
+". D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.#.$.. ",
+". %.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.. ",
+". 8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.. ",
+". B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+. ",
+". #+$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+^+/+(+_+:+<+[+}+|+1+2+3+4+5+. ",
+". 6+7+8+9+0+a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+. ",
+". z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@. ",
+". +@@@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@[@}@|@1@2@3@. ",
+". 4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@j@k@l@m@n@o@p@q@r@s@t@u@v@w@. ",
+". x@y@z@A@B@C@D@E@F@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@. ",
+". #.#+#@###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]#^#/#(#_#:#<#[#}#|#1#. ",
+". 2#3#4#5#6#7#8#9#0#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#. ",
+". v#w#x#y#z#A#B#C#D#E#F#G#H#I#J#K#L#M#N#O#P#Q#R#S#T#U#V#W#X#Y#. ",
+". Z#`# $.$+$@$#$$$%$&$*$x@=$-$;$*#>$,$'$)$!$~${$]$^$/$($_$:$<$. ",
+". [$}$|$1$4@2$3$4$5$6$7$8$9$0$a$b$$$c$d$e$f$g$h$i$j$k$l$m$n$o$. ",
+". p$q$r$s$t$u$v$w$x$E#H#y$z$A$B$C$D$E$F$G$H$I$J$K$L$M$N$O$Q#P$. ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". Q$# # # # # # # # # # # # # # # # # # # # # # # # # # # # # . ",
+". . . . . . . . . . . . . . . . . . . . . . . R$S$R$. . . . . . ",
+". . . . . . . . T$U$V$W$X$. . . . . . . . . . R$Y$R$. . . . . . ",
+". . . . . . . V$W$. . R$R$. Z$V$Z$. . Z$V$V$X$R$Y$. . . . . . . ",
+". . . . . . R$Y$X$. . . . V$Z$R$Y$S$T$Z$. Y$R$S$V$. . . . . . . ",
+". . . . . . S$Y$. . U$U$Z$Y$. . Y$S$Y$. T$U$. T$T$. . . . . . . ",
+". . . . . . R$Y$S$. V$T$S$Y$R$V$V$S$Y$Z$V$V$. W$S$. . . . . . . ",
+". . . . . . . X$V$V$T$R$. T$V$Z$. R$V$S$Z$V$. V$Z$. . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};
diff --git a/images/goal_large.xcf b/images/goal_large.xcf
new file mode 100644
index 00000000..95146fa2
--- /dev/null
+++ b/images/goal_large.xcf
Binary files differ
diff --git a/images/goto.8bit.xpm b/images/goto.8bit.xpm
new file mode 100644
index 00000000..fa2cc0ba
--- /dev/null
+++ b/images/goto.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * goto_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #020202",
+"+ c #5C2525",
+"@ c #9A4646",
+"# c #7D5F5F",
+"$ c #877D7D",
+"% c #AA8282",
+"& c #BDBCBC",
+"* c #860E0E",
+"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&%%%%%%%%%%%%%%%%%%%%%%&&&&&",
+"&&&&&@*********************&&&&&",
+"&&&&&@*@@@@@@@@@@@@@@@@@@**&&&&&",
+"&&&&&@*&&&&&&&&&&&&&&&&&&@*&&&&&",
+"&&&&&@*&&&&&&&&&&&&&&&&&&@*&&&&&",
+"&&&&&@*&@&&&&&&&&&&&&&&*&@*&&&&&",
+"&&&&&@*&*%&&&&&&&&&&&&#*&@*&&&&&",
+"&&&&&@*&**#&&&&&&&&&&%**&@*&&&&&",
+"&&&&&@*&***#&&&&&&&&@***&@*&&&&&",
+"&&&&&@*&****@&&%%&&%****&@*&&&&&",
+"&&&&&@*&*****@&@@%%*****&@*&&&&&",
+"&&&&&@*&******%**&@*****&@*&&&&&",
+"&&&&&@*&*****&%@$&%*****&@*&&&&&",
+"&&&&&@*&****%&&&&&&%****&@*&&&&&",
+"&&&&&@*&***%&&&&&&&&&***&@*&&&&&",
+"&&&&&@*&**%&&&&&&&&&&&**&@*&&&&&",
+"&&&&&@*&*%&&&&&&&&&&&&@*&@*&&&&&",
+"&&&&&@*&%&&&&&&&&&&&&&&%&@*&&&&&",
+"&&&&&@*&&&&&&&&&&&&&&&&&&@*&&&&&",
+"&&&&&@*&&&&&&&&&&&&&&&&&&@*&&&&&",
+"&&&&&@*%%%%%%%%%%%%%%%%%$@*&&&&&",
+"&&&&&@*********************&&&&&",
+"&&&&&%@@@@@@@@@@@@@@@@@@@@@&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
+"&&&&&&&&#.++$&&&&&&$&&&&&&&&&&&&",
+"&&&&&&&++&&&&&#+#&..$&$+#&&&&&&&",
+"&&&&&&&.$&&&&+#&.$+#&$+&.+&&&&&&",
+"&&&&&&$.&&..$.&&.$+$&.$&##&&&&&&",
+"&&&&&&&.$&+#$.&+#&.$&.#$.&&&&&&&",
+"&&&&&&&$#+#&&#+$&&#+&$##$&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"};
diff --git a/images/goto.xcf b/images/goto.xcf
new file mode 100644
index 00000000..413bc9a3
--- /dev/null
+++ b/images/goto.xcf
Binary files differ
diff --git a/images/goto.xpm b/images/goto.xpm
new file mode 100644
index 00000000..7725cf8b
--- /dev/null
+++ b/images/goto.xpm
@@ -0,0 +1,106 @@
+/* XPM */
+static char * goto_xpm[] = {
+"32 32 71 1",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #8D2121",
+"& c #BCBBBB",
+"* c #BBBABA",
+"= c #BBB9B9",
+"- c #BAB7B7",
+"; c #BAB6B6",
+"> c #BBBBBB",
+", c #9A4B4B",
+"' c #8B1919",
+") c #881212",
+"! c #A87A7A",
+"~ c #9E5858",
+"{ c #891313",
+"] c #A06161",
+"^ c #A26868",
+"/ c #891414",
+"( c #A16565",
+"_ c #B8AFAF",
+": c #9F5C5C",
+"< c #891515",
+"[ c #860C0C",
+"} c #9C5454",
+"| c #B19797",
+"1 c #B29A9A",
+"2 c #A77777",
+"3 c #BAB8B8",
+"4 c #8A1616",
+"5 c #984949",
+"6 c #B5A5A5",
+"7 c #8F2D2D",
+"8 c #8E2828",
+"9 c #B3A0A0",
+"0 c #A67575",
+"a c #881515",
+"b c #B29C9C",
+"c c #850D0D",
+"d c #B4A2A2",
+"e c #9E5A5A",
+"f c #B39E9E",
+"g c #9C5757",
+"h c #A87B7B",
+"i c #B7ACAC",
+"j c #891212",
+"k c #870E0E",
+"l c #B6A7A7",
+"m c #AD8C8C",
+"n c #881111",
+"o c #AA8181",
+"p c #B5A4A4",
+"q c #AA7F7F",
+"r c #B4A1A1",
+"s c #AB8585",
+"t c #AE8F8F",
+"u c #AC8888",
+"v c #933434",
+"w c #A56E6E",
+"x c #545454",
+"y c #151515",
+"z c #3E3E3E",
+"A c #2A2A2A",
+"B c #929292",
+"C c #A7A7A7",
+"D c #7D7D7D",
+"E c #686868",
+"F c #000000",
+"................................",
+".....+@@@@@@@@@@@@@@@@@@@@@.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....#$##################%$.....",
+".....#$....&*&.=-;-=*>...#$.....",
+".....#$..................#$.....",
+".....#$.,&&...........&'>#$.....",
+".....#$.)!=...........~)>#$.....",
+".....#$&{$]&.........^${*#$.....",
+".....#$*/$$(_......*:$$/=#$.....",
+".....#$*<$$[}&.|1.-2[$$<3#$.....",
+".....#$*4$$$$567890$$$$43#$.....",
+".....#$*<$$$[abccde[$$$<3#$.....",
+".....#$&/$$$[1fghi|[$$$/=#$.....",
+".....#$&j$$kb..li..m{$$j*#$.....",
+".....#$.n$ko=.......p$$n>#$.....",
+".....#$.k$q&.........r$k>#$.....",
+".....#$.{s..&......&..,$.#$.....",
+".....#$.t..............u.#$.....",
+".....#$..................#$.....",
+".....#$..................#$.....",
+".....#$@@@@@@@@@@@@@@@@@@v$.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....w#####################.....",
+"................................",
+"........xyzAB.....CD............",
+".......zA..CC.EzE.AyE.BzxC......",
+"......CFB....zECFDzx.DA.Az......",
+"......DF..yyEF..FBAD.yD.zx......",
+"......CFD.zxDFCzz.FD.FEDyC......",
+".......BzzxC.xzE..xz.DzxC.......",
+"................................"};
diff --git a/images/help.8bit.xpm b/images/help.8bit.xpm
new file mode 100644
index 00000000..b50057e9
--- /dev/null
+++ b/images/help.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * help_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #22210A",
+"+ c #C0BEBB",
+"@ c #B4998B",
+"# c #8D2321",
+"$ c #717264",
+"% c #A27A73",
+"& c #4F5537",
+"* c #434133",
+"+@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+",
+"+##############################+",
+"+............*$*....*..........+",
+"+............&@&&..*&..........+",
+"+...........*$@$&&*.*&.........+",
+"@.......**...&&&*&&*.&.........+",
+"+.......**.*...**$$&***........+",
+"@.......*.*....*.*&$*.*........+",
+"+........*...****.**&*.........+",
+"@..........&*%$@@@$.*..........+",
+"+.........&..&%*.*@@...........+",
+"+.........*...*...@+$..........+",
+"+.........$..&%*..@++..........@",
+"@.........%.#%+&*#@+%..........+",
+"+.........%.*#@@%@@@%..........+",
+"+.........%&&*#%#@@@...........+",
+"+.........%##*..#*#%...........+",
+"@.........%*$#&$%&#$...........+",
+"+.........@%#*%%@++@...........+",
+"@.........%%&#%++++%...........+",
+"+..........#$%@++%&&...........+",
+"+##############################+",
+"+%#############################+",
+"++++++++++++++++++++++++++++++++",
+"++++++++++++++++++@@++++++++++++",
+"+++++++$.$+..@++++$.++++++++++++",
+"+++++++@.++*$+@*$+$*@*@$*+++++++",
+"+++++++&.**.$$*$.+*$+..&.$++++++",
+"+++++++**+@.+..*@+.@+.$@.@++++++",
+"+++++++.$+$.+.$+&@.+$.+*&+++++++",
+"++++++&*$+**$$*&@$*$$..@++++++++",
+"++++++++++++++++++++*$++++++++++"};
diff --git a/images/help.xcf b/images/help.xcf
new file mode 100644
index 00000000..f165f10b
--- /dev/null
+++ b/images/help.xcf
Binary files differ
diff --git a/images/help.xpm b/images/help.xpm
new file mode 100644
index 00000000..c9866007
--- /dev/null
+++ b/images/help.xpm
@@ -0,0 +1,368 @@
+/* XPM */
+static char * help_xpm[] = {
+"32 32 333 2",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #232006",
+"& c #1F1D04",
+"* c #1D1D04",
+"= c #191A03",
+"- c #141802",
+"; c #161903",
+"> c #1D1C04",
+", c #252005",
+"' c #152C0E",
+") c #0E270E",
+"! c #0E280E",
+"~ c #0D220C",
+"{ c #4A4F23",
+"] c #7E7E46",
+"^ c #4B5524",
+"/ c #143714",
+"( c #0F2B10",
+"_ c #112F11",
+": c #1A491B",
+"< c #224D1B",
+"[ c #242106",
+"} c #262106",
+"| c #242006",
+"1 c #221F06",
+"2 c #1F1E05",
+"3 c #1B1B04",
+"4 c #181A04",
+"5 c #1B1C04",
+"6 c #2C2407",
+"7 c #231F05",
+"8 c #242005",
+"9 c #1E1D04",
+"0 c #202709",
+"a c #102E11",
+"b c #0C250D",
+"c c #243114",
+"d c #62622C",
+"e c #9B9A5C",
+"f c #65652D",
+"g c #2A4D1D",
+"h c #113212",
+"i c #153B15",
+"j c #225A23",
+"k c #233E13",
+"l c #252106",
+"m c #211F05",
+"n c #201E05",
+"o c #211E05",
+"p c #302608",
+"q c #2E2508",
+"r c #121703",
+"s c #151903",
+"t c #2A2306",
+"u c #201E04",
+"v c #1B3612",
+"w c #133413",
+"x c #0F2C0F",
+"y c #0C230D",
+"z c #1F3014",
+"A c #808045",
+"B c #8D8D54",
+"C c #737537",
+"D c #244D1C",
+"E c #1B4C1C",
+"F c #143815",
+"G c #113312",
+"H c #1A461B",
+"I c #276025",
+"J c #292508",
+"K c #292307",
+"L c #292207",
+"M c #2D2508",
+"N c #312708",
+"O c #2D2407",
+"P c #191B04",
+"Q c #1C1C04",
+"R c #221F05",
+"S c #1E1E05",
+"T c #1D461B",
+"U c #163A16",
+"V c #172E11",
+"W c #142D10",
+"X c #394621",
+"Y c #5F6533",
+"Z c #395024",
+"` c #254619",
+" . c #3D5E24",
+".. c #32632A",
+"+. c #123312",
+"@. c #235E24",
+"#. c #253A12",
+"$. c #272207",
+"%. c #282207",
+"&. c #272106",
+"*. c #2B2407",
+"=. c #2A2307",
+"-. c #1D2408",
+";. c #1F4D1F",
+">. c #123212",
+",. c #1A2710",
+"'. c #313C1E",
+"). c #242817",
+"!. c #27261A",
+"~. c #2A281A",
+"{. c #32311C",
+"]. c #454422",
+"^. c #67692E",
+"/. c #5F712E",
+"(. c #2D4B20",
+"_. c #19471A",
+":. c #224918",
+"<. c #1F1E04",
+"[. c #1A1B03",
+"}. c #201F05",
+"|. c #1A4519",
+"1. c #172B16",
+"2. c #45423B",
+"3. c #161311",
+"4. c #121212",
+"5. c #1D1F1F",
+"6. c #292B2A",
+"7. c #2C302E",
+"8. c #2C2F2E",
+"9. c #373533",
+"0. c #6C6A4D",
+"a. c #6D7231",
+"b. c #20431A",
+"c. c #123412",
+"d. c #204B19",
+"e. c #1E1D05",
+"f. c #292206",
+"g. c #1B3510",
+"h. c #31382A",
+"i. c #0F0E0D",
+"j. c #20211B",
+"k. c #312820",
+"l. c #513A31",
+"m. c #433028",
+"n. c #513B32",
+"o. c #44342A",
+"p. c #34332B",
+"q. c #2F342F",
+"r. c #423F2F",
+"s. c #3F5722",
+"t. c #103011",
+"u. c #1F3711",
+"v. c #1A1B04",
+"w. c #2B2307",
+"x. c #2E2507",
+"y. c #191B03",
+"z. c #1C1E05",
+"A. c #13170C",
+"B. c #343024",
+"C. c #704F40",
+"D. c #5E4336",
+"E. c #A97C67",
+"F. c #8B6354",
+"G. c #CF967C",
+"H. c #C18C71",
+"I. c #BD8870",
+"J. c #8E6957",
+"K. c #1D1F16",
+"L. c #1E3216",
+"M. c #122F10",
+"N. c #222307",
+"O. c #1C1C05",
+"P. c #131803",
+"Q. c #252006",
+"R. c #2A2206",
+"S. c #171A03",
+"T. c #1B1B03",
+"U. c #1B1E06",
+"V. c #695741",
+"W. c #2C2118",
+"X. c #372820",
+"Y. c #695247",
+"Z. c #916C61",
+"`. c #564238",
+" + c #443428",
+".+ c #4A392A",
+"++ c #BD9178",
+"@+ c #CDA386",
+"#+ c #193916",
+"$+ c #1E2208",
+"%+ c #1D1D05",
+"&+ c #171A04",
+"*+ c #22210A",
+"=+ c #393022",
+"-+ c #1A150D",
+";+ c #211C16",
+">+ c #3C332A",
+",+ c #543E36",
+"'+ c #252119",
+")+ c #1E1910",
+"!+ c #2E2416",
+"~+ c #9F8873",
+"{+ c #FACBAB",
+"]+ c #866C50",
+"^+ c #43341F",
+"/+ c #726050",
+"(+ c #231C13",
+"_+ c #27231D",
+":+ c #5B463D",
+"<+ c #B8836E",
+"[+ c #342E27",
+"}+ c #221C11",
+"|+ c #322718",
+"1+ c #B09C85",
+"2+ c #F3C5A6",
+"3+ c #F4BB9F",
+"4+ c #252107",
+"5+ c #272206",
+"6+ c #2E2710",
+"7+ c #826758",
+"8+ c #2E271E",
+"9+ c #43352E",
+"0+ c #855F50",
+"a+ c #EDB59A",
+"b+ c #795E51",
+"c+ c #3E3228",
+"d+ c #433628",
+"e+ c #B99785",
+"f+ c #DEB49D",
+"g+ c #BF8775",
+"h+ c #1F1D05",
+"i+ c #262107",
+"j+ c #9A705E",
+"k+ c #4D3832",
+"l+ c #5E443C",
+"m+ c #7A574B",
+"n+ c #BC8B77",
+"o+ c #C3937D",
+"p+ c #8D6455",
+"q+ c #D5907D",
+"r+ c #C29D90",
+"s+ c #C8A492",
+"t+ c #98765F",
+"u+ c #2B2306",
+"v+ c #99705C",
+"w+ c #574039",
+"x+ c #694B40",
+"y+ c #5D3E35",
+"z+ c #66463B",
+"A+ c #966555",
+"B+ c #79584A",
+"C+ c #C48C78",
+"D+ c #B0958B",
+"E+ c #AC9284",
+"F+ c #443B24",
+"G+ c #231F06",
+"H+ c #282206",
+"I+ c #A87A63",
+"J+ c #4C372F",
+"K+ c #65352F",
+"L+ c #592A27",
+"M+ c #291616",
+"N+ c #442916",
+"O+ c #482F1B",
+"P+ c #40291A",
+"Q+ c #805850",
+"R+ c #87746B",
+"S+ c #1D1D08",
+"T+ c #141803",
+"U+ c #BE836D",
+"V+ c #5A4036",
+"W+ c #825C4D",
+"X+ c #5D4037",
+"Y+ c #79564C",
+"Z+ c #9A6254",
+"`+ c #835C47",
+" @ c #664431",
+".@ c #8F473C",
+"+@ c #946C5F",
+"@@ c #211F07",
+"#@ c #111703",
+"$@ c #1D1C05",
+"%@ c #252105",
+"&@ c #2D2509",
+"*@ c #D28C78",
+"=@ c #895D4F",
+"-@ c #624539",
+";@ c #533C34",
+">@ c #876256",
+",@ c #C7917F",
+"'@ c #E1A591",
+")@ c #FDCDAD",
+"!@ c #F6C4A7",
+"~@ c #C29C80",
+"{@ c #342809",
+"]@ c #221E05",
+"^@ c #232005",
+"/@ c #252007",
+"(@ c #8F6353",
+"_@ c #AA7362",
+":@ c #60453B",
+"<@ c #75554A",
+"[@ c #8F685D",
+"}@ c #EBAF97",
+"|@ c #FACAB0",
+"1@ c #FED4B2",
+"2@ c #F1BC9E",
+"3@ c #8E7663",
+"4@ c #1F200A",
+"5@ c #292306",
+"6@ c #0D1208",
+"7@ c #262727",
+"8@ c #654D46",
+"9@ c #715247",
+"0@ c #9C7265",
+"a@ c #BA8878",
+"b@ c #F3BBA2",
+"c@ c #DAAD96",
+"d@ c #8E6A5D",
+"e@ c #544948",
+"f@ c #595B5A",
+"g@ c #132312",
+"h@ c #242409",
+"i@ c #A56E6E",
+"j@ c #939393",
+"k@ c #7D7D7D",
+"l@ c #696969",
+"m@ c #000000",
+"n@ c #151515",
+"o@ c #2A2A2A",
+"p@ c #3F3F3F",
+"q@ c #A7A7A7",
+"r@ c #545454",
+". + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 } 6 . ",
+". 4 4 7 8 9 9 9 0 a ! b c d e f g h a i j k | l m n | o } p q . ",
+". r s o t 7 u 9 v w x y z A B C D E F G H I J K | l L K M N O . ",
+". P * Q R & = S T U ! V W X Y Z ` ...+.G @.#.L $.%.$.&.*.6 =.. ",
+". | m 3 > = s -.;.>.,.'.).!.~.{.].^./.(.h _.:.% % | 1 m %.l % . ",
+". L } <.& 9 [.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.1 % % e.2 | e.Q . ",
+". L f.} , o Q & g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.n n R Q v.Q ; s . ",
+". &.w.x.t R 3 y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.v.O.O.4 Q 4 P.; . ",
+". Q.&.t R.R [.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+%+P O.P &+v.s ; v.. ",
+". 1 R , 8 R > T.9 *+=+-+;+>+,+'+)+!+~+{+]+1 e.5 e.%+P 4 ; ; Q . ",
+". | 8 , o 5 > & & ^+/+(+_+:+<+[+}+|+1+2+3+4+o %+1 % Q P %+O.O.. ",
+". 5+5+R > T.9 R R 6+7+8+9+0+a+b+c+d+e+f+g+h+2 1 % l Q.Q.w.l l . ",
+". | 8 7 5 > 8 } , i+j+k+l+m+n+o+p+q+r+s+t+v.2 o $.&.Q.=.N 6 l . ",
+". h+m } 9 [.<.} u+t v+w+x+y+z+A+B+C+D+E+F+O.l 1 e.2 5 G+L Q.% . ",
+". Q 7 H+R ; = o t w.I+J+K+L+M+N+O+P+Q+R+S+2 6 %.%+&+T+Q 1 | m . ",
+". e.n 8 o S.[.9 7 =.U+V+W+X+Y+Z+`+ @.@+@@@m O O o P.#@$@1 l 1 . ",
+". m n 9 Q * 9 n %@&@*@=@-@;@>@,@'@)@!@~@} =.{@p % s r %+o m O.. ",
+". % 7 ]@u ^@o o &./@(@_@:@<@[@}@|@1@2@3@4@=.p 6 H+e.5 m %+%+5 . ",
+". &., R 9 R R m 5@6@7@8@9@0@a@b@c@d@e@f@g@h@Q.% % Q.Q.Q.%+Q n . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". i@# # # # # # # # # # # # # # # # # # # # # # # # # # # # # . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . j@k@. . . . . . . . . . . . ",
+". . . . . . . l@m@l@. n@n@j@. . . . l@o@. . . . . . . . . . . . ",
+". . . . . . . j@m@. . p@l@. j@p@l@. l@p@j@p@j@l@p@q@. . . . . . ",
+". . . . . . . l@n@p@p@m@k@k@p@k@n@. p@k@. n@o@l@m@k@. . . . . . ",
+". . . . . . . p@r@. q@m@. n@o@p@j@. n@j@. m@k@j@m@q@. . . . . . ",
+". . . . . . . n@k@. k@o@. m@l@. l@q@m@. k@n@. p@l@. . . . . . . ",
+". . . . . . l@p@l@. p@p@j@k@p@r@j@j@p@j@l@n@p@j@. . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . p@l@. . . . . . . . . . "};
diff --git a/images/info.8bit.xpm b/images/info.8bit.xpm
new file mode 100644
index 00000000..b93c3a5c
--- /dev/null
+++ b/images/info.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * info_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #0504AC",
+"+ c #763E50",
+"@ c #7B586E",
+"# c #7B7B9E",
+"$ c #860F0D",
+"% c #AA8284",
+"& c #BCBCBD",
+"* c #FEFEFC",
+"&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&",
+"&@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$&",
+"&+$+@++@++@++++$+++++@++@++@+$$&",
+"&@$&&&&&&&&#+......+%&&&&&&&&@$&",
+"&+$&&&&&&&@....@##...@&&&&&&&+$&",
+"&+$&&&&&&......%*&.....&&&&&&@$&",
+"&+$&&&&&@......&**.....@&&&&&+$&",
+"&@$&&&&#................%&&&&+$&",
+"&@$&&&&+.....&&&&&......+&&&&+$&",
+"&@$&&&%......****&.......%&&&@$&",
+"&@$&&&#........&**.......#&&&+$&",
+"&@$&&&#........%*&.......%&&&+$&",
+"&@$&&&#........&**.......#&&&@$&",
+"&@$&&&#........%*&.......%&&&+$&",
+"&@$&&&%........&**.......%&&&+$&",
+"&@$&&&&+.......%*&......+&&&&+$&",
+"&+$&&&&#.......&**......#&&&&@$&",
+"&@$&&&&&@....@@&**@+...@&&&&&+$&",
+"&+$&&&&&&....******&...&&&&&&+$&",
+"&@$&&&&&&&#..######@.@&&&&&&&@$&",
+"&+$%%%%#%#%@+......+@#%%%%%%%$$&",
+"&+$$$$$$$$$$$$$$$$$$$$$$$$$$$$$&",
+"&%++++++++++@+@+@++++++++@+@+@+&",
+"&&&&&&&&&&&&&&&&&&%%&&&&&&&&&&&&",
+"&&&&&&&&%.+&&&&&&%@#&&&&&&&&&&&&",
+"&&&&&&&&%.&+@%+&#..%&@+%&&&&&&&&",
+"&&&&&&&&@.&++#.#&.&&.&@.&&&&&&&&",
+"&&&&&&&&++&.+%.&%.&++&#$&&&&&&&&",
+"&&&&&&&&.#&.&#.&#+&+.&.#&&&&&&&&",
+"&&&&&&&#++&+&#+#+@&&++%&&&&&&&&&",
+"&&&&&&&&&&&&&&&&.#&&&&&&&&&&&&&&",
+"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"};
diff --git a/images/info.xcf b/images/info.xcf
new file mode 100644
index 00000000..ff7a632c
--- /dev/null
+++ b/images/info.xcf
Binary files differ
diff --git a/images/info.xpm b/images/info.xpm
new file mode 100644
index 00000000..1ceef4fc
--- /dev/null
+++ b/images/info.xpm
@@ -0,0 +1,113 @@
+/* XPM */
+static char * info_xpm[] = {
+"32 32 78 1",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #994848",
+"& c #8D3C3E",
+"* c #813039",
+"= c #813139",
+"- c #8D3C3F",
+"; c #8D2121",
+"> c #797991",
+", c #2F2F9A",
+"' c #1818A9",
+") c #0101BD",
+"! c #A5A5A8",
+"~ c #5E5E8D",
+"{ c #4F4FD2",
+"] c #7F7FDE",
+"^ c #6F6FDA",
+"/ c #0000BE",
+"( c #2020A2",
+"_ c #9F9FE6",
+": c #FEFEFE",
+"< c #DFDFF6",
+"[ c #870F0F",
+"} c #5E5E8E",
+"| c #994949",
+"1 c #891313",
+"2 c #994A4A",
+"3 c #8A1818",
+"4 c #0101BE",
+"5 c #1818C4",
+"6 c #BFBFEE",
+"7 c #A7A7E8",
+"8 c #9A4C4C",
+"9 c #8B1C1C",
+"0 c #9999A0",
+"a c #2020C6",
+"b c #9B4E4E",
+"c c #767690",
+"d c #0404BF",
+"e c #ABABE9",
+"f c #8C1E1E",
+"g c #994B4B",
+"h c #8B1B1B",
+"i c #0000BD",
+"j c #891414",
+"k c #881010",
+"l c #870E0E",
+"m c #0C0CC1",
+"n c #5F5FD6",
+"o c #C3C3EF",
+"p c #EBEBF9",
+"q c #4747D0",
+"r c #FFFFFF",
+"s c #1010C2",
+"t c #AB8383",
+"u c #AB8484",
+"v c #7E5767",
+"w c #4D266D",
+"x c #3D1576",
+"y c #2E0683",
+"z c #2E0582",
+"A c #2E0885",
+"B c #3D1677",
+"C c #933434",
+"D c #A56E6E",
+"E c #939393",
+"F c #7D7D7D",
+"G c #696969",
+"H c #000000",
+"I c #2A2A2A",
+"J c #545454",
+"K c #A7A7A7",
+"L c #3F3F3F",
+"M c #151515",
+".+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.",
+".#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.",
+".#$##%%%%%%%#&**==-%#########;$.",
+".#$........>,'))))',>........#$.",
+".#$......!~)))){]^///~!......#$.",
+".%$.....!()))))_:<////(!.....#$.",
+".%[.....}/)))))_:</////~.....#$.",
+".|1....>)/))))))))//////>....#$.",
+".23....,4/))566667//////,....#$.",
+".89...0')/))a::::<//////'0...#$.",
+".b9...c44/))daae:<///////c...#$.",
+".bf...c/)/)))))_:<///////c...#$.",
+".gf...c))/)))))_:<///////c...#$.",
+".gh...c)i/)))))_:<///////c...#$.",
+".|j...0')/)))))_:<//////'0...#$.",
+".|k....,)/)))))_:<//////,....#$.",
+".%[....>4/)))))_:<//////>....#$.",
+".%l.....~/))mnno:pnq///~.....#$.",
+".#$.....!())a:::::r6//(!.....#$.",
+".#$......!~)s]]]]]]n/~!......#$.",
+".#$@@@@tuuuvwxyzAABwv@@@@@@@@C$.",
+".#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.",
+".D#############################.",
+"..................EF............",
+"........GHI......GJGK...........",
+"........EHKLGELKFMIEKJLE........",
+"........GH.LLGHF.H.KMKGH........",
+"........LL.ILKH.FM.JL.FM........",
+"........MG.HKFM.GL.LIKMF........",
+".......GLLKL.FLELJ.KLLE.........",
+"................MF..............",
+"................................"};
diff --git a/images/interrupt.8bit.xpm b/images/interrupt.8bit.xpm
new file mode 100644
index 00000000..9438fa6f
--- /dev/null
+++ b/images/interrupt.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * interrupt_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #373130",
+"+ c #9A4746",
+"@ c #957979",
+"# c #860E0C",
+"$ c #BDBDBB",
+"% c #8A1819",
+"& c #FEFEFC",
+"* c #F80405",
+"$@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@$",
+"$+%%%%%%%%%%%%%%%%%%%%%%%%%%%%#$",
+"$+%++++++++@*#*#*#*#*%+++++++%%$",
+"$+#$$$$$$&*************&$$$$$+#$",
+"$+#$$$$$&***************&$$$$+#$",
+"$+#$$$$&*****************&$$$+#$",
+"$+#$$$&*******************&$$+#$",
+"$+#$$$********************&$$+#$",
+"$+%$$$*********************$$+#$",
+"$+%$$$**&&&&&&&&&&&&&&&&&**$$+#$",
+"$+%$$$*&&&&&&&&&&&&&&&&&&&*$$+#$",
+"$+%$$$*&&&&&&&&&&&&&&&&&&&*$$+#$",
+"$+%$$$**&&&&&&&&&&&&&&&&&**$$+#$",
+"$+%$$$*********************$$+#$",
+"$+%$$$@*******************&$$+#$",
+"$+#$$$@*******************&$$+#$",
+"$+#$$$&******************&&$$+#$",
+"$+#$$$&&****************&&$$$+#$",
+"$+#$$$$&&**************&&$$$$+#$",
+"$+#$$$$$&*************&&$$$$$+#$",
+"$+#@@@@@@$$**********$@@@@@@@+#$",
+"$+#%#%%%%##############%#%#####$",
+"$@+++++++++++++.#++++++++++++++$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$@...$@@$$$$$$$$$$$$$$$$$$$",
+"$$$$$$..$$$...$@..$@.@.@$$$$$$$$",
+"$$$$$$$..@$@.$@.$.@$.@@.@$$$$$$$",
+"$$$$$$$$@.$@.$.@$@.$.@$.@$$$$$$$",
+"$$$$$$.$@.$@.$@.$.@$.@$.@$$$$$$$",
+"$$$$$$@..@$$.@$@..$$...@$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$..$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"};
diff --git a/images/interrupt.xcf b/images/interrupt.xcf
new file mode 100644
index 00000000..eeb7a61e
--- /dev/null
+++ b/images/interrupt.xcf
Binary files differ
diff --git a/images/interrupt.xpm b/images/interrupt.xpm
new file mode 100644
index 00000000..da49b0c4
--- /dev/null
+++ b/images/interrupt.xpm
@@ -0,0 +1,87 @@
+/* XPM */
+static char * interrupt_xpm[] = {
+"32 32 52 1",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #994848",
+"& c #AF5E5E",
+"* c #AF0909",
+"= c #AF1C1C",
+"- c #AF1919",
+"; c #8D2121",
+"> c #FFFFFF",
+", c #FF0000",
+"' c #FF3131",
+") c #870F0F",
+"! c #994949",
+"~ c #891313",
+"{ c #994A4A",
+"] c #8A1818",
+"^ c #9A4C4C",
+"/ c #8B1C1C",
+"( c #9B4E4E",
+"_ c #8C1E1E",
+": c #994B4B",
+"< c #8B1B1B",
+"[ c #891414",
+"} c #FF7B7B",
+"| c #881010",
+"1 c #870E0E",
+"2 c #AB8383",
+"3 c #AB8484",
+"4 c #D8B1B1",
+"5 c #D7B0B0",
+"6 c #D70606",
+"7 c #D70505",
+"8 c #D70404",
+"9 c #D80707",
+"0 c #D7AFAF",
+"a c #933434",
+"b c #A56E6E",
+"c c #5A0909",
+"d c #830909",
+"e c #7D7D7D",
+"f c #3F3F3F",
+"g c #2A2A2A",
+"h c #A7A7A7",
+"i c #151515",
+"j c #696969",
+"k c #545454",
+"l c #939393",
+"m c #000000",
+".+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.",
+".#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.",
+".#$##%%%%%&&********=-#######;$.",
+".#$......>,,,,,,,,,,,,,>.....#$.",
+".#$.....>,,,,,,,,,,,,,,'>....#$.",
+".%$....>,,,,,,,,,,,,,,,,,>...#$.",
+".%)...>,,,,,,,,,,,,,,,,,,,>..#$.",
+".!~...,,,,,,,,,,,,,,,,,,,,>..#$.",
+".{]...,,,,,,,,,,,,,,,,,,,,,..#$.",
+".^/...,,>>>>>>>>>>>>>>>>>,,..#$.",
+".(/...,>>>>>>>>>>>>>>>>>>>,..#$.",
+".(_...,>>>>>>>>>>>>>>>>>>>,..#$.",
+".:_...,,>>>>>>>>>>>>>>>>>,,..#$.",
+".:<...,,,,,,,,,,,,,,,,,,,,,..#$.",
+".![...},,,,,,,,,,,,,,,,,,,>..#$.",
+".!|...},,,,,,,,,,,,,,,,,,,>..#$.",
+".%)...>,,,,,,,,,,,,,,,,,,>>..#$.",
+".%1...>>,,,,,,,,,,,,,,,,>>...#$.",
+".#$....>>,,,,,,,,,,,,,,>>....#$.",
+".#$.....>',,,,,,,,,,,,>>.....#$.",
+".#$@@@@234566778996660@@@@@@@a$.",
+".#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.",
+".b#############cd##############.",
+"................................",
+"......effg.he...................",
+"......ff...gij.jfk.lfefj........",
+"......hiih.ef.jf.fj.fkhil.......",
+"........ji.ef.fe.ef.fe.fe.......",
+"......j.hm.ef.jf.fk.fjhil.......",
+"......effl..kj.jfk..fkfe........",
+"...................hgk..........",
+"................................"};
diff --git a/images/isabelle-badge.xcf b/images/isabelle-badge.xcf
new file mode 100644
index 00000000..ad5de7bd
--- /dev/null
+++ b/images/isabelle-badge.xcf
Binary files differ
diff --git a/images/isabelle_transparent.8bit.gif b/images/isabelle_transparent.8bit.gif
new file mode 100644
index 00000000..8c07669e
--- /dev/null
+++ b/images/isabelle_transparent.8bit.gif
Binary files differ
diff --git a/images/isabelle_transparent.gif b/images/isabelle_transparent.gif
new file mode 100644
index 00000000..f541024f
--- /dev/null
+++ b/images/isabelle_transparent.gif
Binary files differ
diff --git a/images/isabelle_transparent.xcf b/images/isabelle_transparent.xcf
new file mode 100644
index 00000000..9c44a694
--- /dev/null
+++ b/images/isabelle_transparent.xcf
Binary files differ
diff --git a/images/lego-badge.xcf b/images/lego-badge.xcf
new file mode 100644
index 00000000..c0a2985d
--- /dev/null
+++ b/images/lego-badge.xcf
Binary files differ
diff --git a/images/next.8bit.xpm b/images/next.8bit.xpm
new file mode 100644
index 00000000..96ba38c8
--- /dev/null
+++ b/images/next.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * next_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #020204",
+"+ c #860E0C",
+"@ c #3B2C2A",
+"# c #9A4644",
+"$ c #6E6768",
+"% c #7E7E7C",
+"& c #AA8284",
+"* c #BDBDBB",
+"********************************",
+"*****&&&&&&&&&&&&&&&&&&&&&&*****",
+"*****#+++++++++++++++++++++*****",
+"*****#+##################++*****",
+"*****#+******************#+*****",
+"*****#+******************#+*****",
+"*****#+**+***************#+*****",
+"*****#+**+++*************#+*****",
+"*****#+**++++++**********#+*****",
+"*****#+**++++++++********#+*****",
+"*****#+**+++++++++++*****#+*****",
+"*****#+**+++++++++++++***#+*****",
+"*****#+**+++++++++++++***#+*****",
+"*****#+**+++++++++++++***#+*****",
+"*****#+**++++++++++******#+*****",
+"*****#+**+++++++#********#+*****",
+"*****#+**+++++&**********#+*****",
+"*****#+**++$*************#+*****",
+"*****#+**&***************#+*****",
+"*****#+******************#+*****",
+"*****#+******************#+*****",
+"*****#+&&&&&&&&&&&&&&%&&&++*****",
+"*****#+++++++++++++++++++++*****",
+"*****&#####################*****",
+"********************************",
+"*******$.%*$.%*********%&*******",
+"*******&.@*%$*&@$*$$$$$.@*******",
+"*******$%.$@%%@%.*$@@%%@********",
+"*******@*$.@*.@@**&.$*$@********",
+"*******@**.@*.$*$*@$$*@@********",
+"******$@%*%$*%@$%$$*@*%@%*******",
+"********************************"};
diff --git a/images/next.xcf b/images/next.xcf
new file mode 100644
index 00000000..55fa1782
--- /dev/null
+++ b/images/next.xcf
Binary files differ
diff --git a/images/next.xpm b/images/next.xpm
new file mode 100644
index 00000000..61db9a70
--- /dev/null
+++ b/images/next.xpm
@@ -0,0 +1,59 @@
+/* XPM */
+static char * next_xpm[] = {
+"32 32 24 1",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #8D2121",
+"& c #902D2D",
+"* c #9E5959",
+"= c #B09595",
+"- c #8A1616",
+"; c #A06262",
+"> c #AC8888",
+", c #933434",
+"' c #A56E6E",
+") c #696969",
+"! c #000000",
+"~ c #7D7D7D",
+"{ c #545454",
+"] c #151515",
+"^ c #939393",
+"/ c #A7A7A7",
+"( c #3F3F3F",
+"_ c #2A2A2A",
+"................................",
+".....+@@@@@@@@@@@@@@@@@@@@@.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....#$##################%$.....",
+".....#$..................#$.....",
+".....#$..................#$.....",
+".....#$..$...............#$.....",
+".....#$..$$$.............#$.....",
+".....#$..$$$$$$..........#$.....",
+".....#$..$$$$$$$$........#$.....",
+".....#$..$$$$$$$$$$$.....#$.....",
+".....#$..$$$$$$$$$$$$$...#$.....",
+".....#$..$$$$$$$$$$$$$...#$.....",
+".....#$..$$$$$$$$$$$$&...#$.....",
+".....#$..$$$$$$$$$$......#$.....",
+".....#$..$$$$$$$*........#$.....",
+".....#$..$$$$&=..........#$.....",
+".....#$..$-;.............#$.....",
+".....#$..>...............#$.....",
+".....#$..................#$.....",
+".....#$..................#$.....",
+".....#$@@@@@@@@@@@@@@@@@@,$.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....'#####################.....",
+"................................",
+".......)!~.{]^.........~/.......",
+".......^]].~).^().{~)))!(.......",
+".......)~])(~~(~].)__~~]........",
+".......(/)]].]_(^./!).)(........",
+"......._..]].!).)^()).((........",
+"......)(^.~).~({^)).(^~(^.......",
+"................................"};
diff --git a/images/notes.txt b/images/notes.txt
new file mode 100644
index 00000000..645ee0de
--- /dev/null
+++ b/images/notes.txt
@@ -0,0 +1,100 @@
+$Id$
+
+Notes about how I made the icons and logos here (not in core distribution).
+============================================================================
+
+ David Aspinall <da@dcs.ed.ac.uk>
+
+ICONS
+=====
+
+Made with the Gimp.
+
+Icons to fit on the (default size) Emacs toolbars are 32x32. The ones
+with pictures were made at 256x256, then shrunk to have text added.
+
+Background grey is V74.
+Red for buttons is 135,13,13.
+
+Red background for web is 80,0,48
+
+CD player buttons based on font wptypographicsymbols, point size 28,
+placed at 5,2.
+
+Text is lucidafax demibold italic at point size 8.
+
+blank.xcf -- blank with correct background colour.
+
+Some icons I drew, some I stole from free sources.
+
+
+
+LOGOS
+=====
+
+Original text logo:
+
+script fu -> logos -> comic book
+
+ StencilBT font
+ Browns gradient
+ 40pt Text size
+ 4pt outline (NB: size of both black and shaded portion)
+
+Then I filled background with web page colour, and shaded portion
+with green colour.
+
+New text logo: same font, but made in blender file.
+
+
+Proof general logos
+===================
+
+Web page: scene with canvas backdrop. Render in blender at full size,
+then use gimp to scale to web size (250pix wide). This gives much
+nicer result than low-resolution render: textures are smoothed out
+more prettily.
+
+EPS (doc/ProofGeneral.eps): For texi documentation. Used another,
+wider image with alpha channel to (attempt to) leave background white
+on printed page. Post processing with gimp to add fuzzy border and
+white background since eps (gimp?) can't handle alpha channel.
+
+ Width 5.00 "
+ Height 7.87 (wrong, obviously: 3.48 is right by scaling)
+
+ But: this is *page* size! The image size itself
+ was square, I think.
+ Size of tiff image is 904x903.
+
+ X-offset 2.8 "
+ Y-offset 1.0 "
+ Rotation: 0
+
+Actually, Y-offset seems to have no effect on page position: what
+happens is that TeX compensates for the offset when it inserts the
+image! Changing the offset and retexing puts the image back where TeX
+wants it. Probably same true for X offset.
+
+Solving the size problem: original .eps is 8.4M. (Original xcf file
+is missing/not saved).
+
+Test procedure:
+
+ 1. render at 239dpi (original file seems to have 1200x1200 image in
+ it, this is closest I can get, makes 1199x1199 image).
+ 2. save as pnm (gives 4.1M file)
+ 3. Run pnmtoeps with -rle argument to get run length encoding. (4.1M)
+ 4. gzip -9 -> gives 1.6M file.
+
+Just using gzip directly gives 1.6M file anyway.
+tiff is 1.5M. png is 1.2M. bz2 is 1.3M.
+
+Okay, so we'll distribute the original .eps file, gzipped.
+(It gets compressed inside the tar file anyway, of course, but
+leaving it zipped is less polluting).
+
+Badges
+======
+
+These were cut out from a close-up view of Proof General's chest.
diff --git a/images/pg-text.8bit.gif b/images/pg-text.8bit.gif
new file mode 100644
index 00000000..faf44286
--- /dev/null
+++ b/images/pg-text.8bit.gif
Binary files differ
diff --git a/images/pg-text.gif b/images/pg-text.gif
new file mode 100644
index 00000000..acab510e
--- /dev/null
+++ b/images/pg-text.gif
Binary files differ
diff --git a/images/pg-text.jpg b/images/pg-text.jpg
new file mode 100644
index 00000000..e2f1d5e3
--- /dev/null
+++ b/images/pg-text.jpg
Binary files differ
diff --git a/images/pg-text.xcf b/images/pg-text.xcf
new file mode 100644
index 00000000..1b542378
--- /dev/null
+++ b/images/pg-text.xcf
Binary files differ
diff --git a/images/pgicon.png b/images/pgicon.png
new file mode 100644
index 00000000..233b15d2
--- /dev/null
+++ b/images/pgicon.png
Binary files differ
diff --git a/images/pgmini.xpm b/images/pgmini.xpm
new file mode 100644
index 00000000..a7153212
--- /dev/null
+++ b/images/pgmini.xpm
@@ -0,0 +1,241 @@
+/* XPM */
+static char * pgmini_xpm[] = {
+"16 16 222 2",
+" c None",
+". c #291D00",
+"+ c #231B00",
+"@ c #1A0F00",
+"# c #0F0000",
+"$ c #0A0000",
+"% c #000000",
+"& c #004512",
+"* c #00430F",
+"= c #0D5C13",
+"- c #003C0B",
+"; c #120000",
+"> c #241600",
+", c #281D00",
+"' c #221B00",
+") c #312200",
+"! c #251B00",
+"~ c #1D1300",
+"{ c #100000",
+"] c #0E0000",
+"^ c #001C00",
+"/ c #026424",
+"( c #00510A",
+"_ c #044D09",
+": c #FFFF97",
+"< c #1A6A21",
+"[ c #050000",
+"} c #1A0E00",
+"| c #2A2200",
+"1 c #292200",
+"2 c #2D2200",
+"3 c #1D1600",
+"4 c #150C00",
+"5 c #061200",
+"6 c #005915",
+"7 c #1B5F09",
+"8 c #759E32",
+"9 c #707B37",
+"0 c #7E8640",
+"a c #125322",
+"b c #020F00",
+"c c #0B0200",
+"d c #201700",
+"e c #272100",
+"f c #2F2301",
+"g c #181000",
+"h c #030000",
+"i c #011700",
+"j c #004C09",
+"k c #445E26",
+"l c #936D4A",
+"m c #7E4B46",
+"n c #6C3E45",
+"o c #1F2316",
+"p c #1C1400",
+"q c #272000",
+"r c #150F00",
+"s c #070100",
+"t c #3D602F",
+"u c #FFCDB1",
+"v c #FFBFB7",
+"w c #F9B5B5",
+"x c #3F3130",
+"y c #010000",
+"z c #010100",
+"A c #181200",
+"B c #221900",
+"C c #0E0700",
+"D c #100A00",
+"E c #080000",
+"F c #956F54",
+"G c #FFDDC0",
+"H c #FFBFAB",
+"I c #825A45",
+"J c #CD8D80",
+"K c #4A4130",
+"L c #060A00",
+"M c #020500",
+"N c #0B0700",
+"O c #160F00",
+"P c #0E0400",
+"Q c #150E00",
+"R c #0F0900",
+"S c #FFD5AF",
+"T c #FFF3CE",
+"U c #FFB093",
+"V c #C66658",
+"W c #60402A",
+"X c #0B0100",
+"Y c #373228",
+"Z c #1E2019",
+"` c #0A0600",
+" . c #161000",
+".. c #090100",
+"+. c #150A00",
+"@. c #070000",
+"#. c #FFD7B6",
+"$. c #FFEBC6",
+"%. c #FFAD92",
+"&. c #D3856F",
+"*. c #482B16",
+"=. c #2F2014",
+"-. c #171508",
+";. c #181100",
+">. c #060000",
+",. c #140100",
+"'. c #140300",
+"). c #000700",
+"!. c #AA7D7E",
+"~. c #F59D87",
+"{. c #FFA684",
+"]. c #FFC8AF",
+"^. c #433321",
+"/. c #050400",
+"(. c #080500",
+"_. c #1D1700",
+":. c #020000",
+"<. c #182210",
+"[. c #162711",
+"}. c #0F230C",
+"|. c #081C04",
+"1. c #001904",
+"2. c #001E12",
+"3. c #919A9F",
+"4. c #A88DBD",
+"5. c #9FA5AF",
+"6. c #0A0300",
+"7. c #060300",
+"8. c #080200",
+"9. c #130D00",
+"0. c #131B0C",
+"a. c #193426",
+"b. c #1A2E1E",
+"c. c #122719",
+"d. c #092012",
+"e. c #001606",
+"f. c #093418",
+"g. c #063218",
+"h. c #654B74",
+"i. c #D8C4F9",
+"j. c #001401",
+"k. c #0E0500",
+"l. c #110400",
+"m. c #0E0300",
+"n. c #0A0400",
+"o. c #2B4A2B",
+"p. c #264628",
+"q. c #2E462B",
+"r. c #223B21",
+"s. c #162E14",
+"t. c #122B14",
+"u. c #153716",
+"v. c #0B320D",
+"w. c #182420",
+"x. c #5B3C70",
+"y. c #0E2D1B",
+"z. c #7C8D76",
+"A. c #372913",
+"B. c #120600",
+"C. c #0B0300",
+"D. c #0D0600",
+"E. c #2D4C2C",
+"F. c #294226",
+"G. c #314D2F",
+"H. c #304C2E",
+"I. c #2B4728",
+"J. c #233C22",
+"K. c #10270F",
+"L. c #19341A",
+"M. c #133A16",
+"N. c #0B2915",
+"O. c #15421F",
+"P. c #92A190",
+"Q. c #B1A09C",
+"R. c #0E0600",
+"S. c #2C462A",
+"T. c #243D22",
+"U. c #3C563A",
+"V. c #2C472A",
+"W. c #203D1C",
+"X. c #192F18",
+"Y. c #010903",
+"Z. c #000F00",
+"`. c #193219",
+" + c #173319",
+".+ c #0D2912",
+"++ c #51534C",
+"@+ c #B7ABAE",
+"#+ c #161A06",
+"$+ c #0B0000",
+"%+ c #180800",
+"&+ c #253F24",
+"*+ c #263F25",
+"=+ c #3B533A",
+"-+ c #233D21",
+";+ c #21391F",
+">+ c #263222",
+",+ c #2F371F",
+"'+ c #2F3E1D",
+")+ c #1E361D",
+"!+ c #0F2B0F",
+"~+ c #354833",
+"{+ c #FFFFFF",
+"]+ c #385139",
+"^+ c #0F0E00",
+"/+ c #270E00",
+"(+ c #2A391E",
+"_+ c #2A4323",
+":+ c #2F3819",
+"<+ c #1F321A",
+"[+ c #2D4825",
+"}+ c #314928",
+"|+ c #1B3419",
+"1+ c #223E25",
+"2+ c #233625",
+"3+ c #123214",
+"4+ c #152C0E",
+"5+ c #19311E",
+"6+ c #1A3F1B",
+"7+ c #072716",
+"8+ c #233314",
+"9+ c #1A0C00",
+". + @ # # $ % & * = - ; $ > , ' ",
+") ! ~ { ] ^ / ( _ : < % [ } | 1 ",
+"2 3 4 # 5 6 7 8 9 0 a b % c d e ",
+"f g [ h i j k l m n % o % [ p q ",
+"3 r s % % t u v % w x y y z A B ",
+"C D E % % F G H I J K % L M N O ",
+"P Q R % % h S T U V W X Y Z ` .",
+"..D +.@.% % #.$.%.&.*.c =.-.` ;.",
+">.,.'.$ h ).!.~.{.].^.% % /.(._.",
+":.<.[.}.|.1.2.3.4.5.% y 6.7.8.9.",
+"0.a.b.c.d.e.f.g.h.i.j.% k.l.m.n.",
+"o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.",
+"E.F.G.H.I.J.K.L.M.N.O.P.Q.[ ] R.",
+"S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+%+",
+"&+*+=+-+;+>+,+'+)+`.!+~+{+]+^+/+",
+"(+_+:+<+[+}+|+1+2+3+4+5+6+7+8+9+"};
diff --git a/images/qed.8bit.xpm b/images/qed.8bit.xpm
new file mode 100644
index 00000000..eede5c5b
--- /dev/null
+++ b/images/qed.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * qed_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #161210",
+"+ c #C2C0BD",
+"@ c #A38B85",
+"# c #860E0C",
+"$ c #615047",
+"% c #954F4D",
+"& c #372D2A",
+"* c #563938",
+"++++++++++++++++++++++++++++++++",
+"+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+",
+"+%#############################+",
+"+%#%%%%%%%%%%%%%%%%%%%%%%%%%%##+",
+"+.........#.&..................+",
+"+....#.#.&**$#&#&.&....&&*&....+",
+"+..**&&&&#$%%%*&&&&&&.&&&+@&...+",
+"+.&%@%*&&%@++%****&*&&&&$+@*...+",
+"+.&%+@**#*@++@%$$@$*&&&&$$$&...+",
+"+.&*%%***%@++%*$@+@$&&$$$&&&&..+",
+"+.#&&*%**%%%%%$*$@$$&$$&&&$&...+",
+"+..&&&&%$%%%%***$$&$$$&&&$$*&..+",
+"+&&&&&&***$$%****$$$$&$&$$+@...+",
+"+.&&*******$%$&$&$$$$&&&$$+$&..+",
+"+&****$*$%%%%$*&$$@@$$$&$$$$&..+",
+"+**%%%$**%++%$&&$$@++@$&&&&&...+",
+"+&$++@$**$%%$$**$$++++&&&......+",
+"+*%++@$******$&$$$+@@$$&&&.....+",
+"+&*@@%$*&&&&*$$&&&+@*&&.&......+",
+"+&&**@%&&&&&&$$$$+&&&&.........+",
+"+.&&&&$%&..&&@$$++$..&.........+",
+"+.&.&&&%.....**$*&.............+",
+"+%#############################+",
+"+%%%%%%%%%%%%%%%%%%%%%%%*%%%%%%+",
+"++++++++++++++++++++++++++@+++++",
+"++++$&*.$+++@.&&.+++$.*&&@++@+++",
+"+++@.++$.++++.@+++++@.++*$++++++",
+"+++.$++@.+++@.&.++++$&++&&++++++",
+"+++.@++.$+++@.+@++++&$++.@++++++",
+"@++.$+$.+$$+$&+@@$@+.@+&&+*@@+++",
+"+++@&&$++$@@&$&&+&+$$&&@++&+++++",
+"++++++$$&+++++++++++++++++++++++"};
diff --git a/images/qed.xcf b/images/qed.xcf
new file mode 100644
index 00000000..48dc1d43
--- /dev/null
+++ b/images/qed.xcf
Binary files differ
diff --git a/images/qed.xpm b/images/qed.xpm
new file mode 100644
index 00000000..f88586e7
--- /dev/null
+++ b/images/qed.xpm
@@ -0,0 +1,573 @@
+/* XPM */
+static char * qed_xpm[] = {
+"32 32 538 2",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #994848",
+"& c #8D2121",
+"* c #140B0D",
+"= c #1A0F10",
+"- c #1E1112",
+"; c #231414",
+"> c #241514",
+", c #241513",
+"' c #2B1916",
+") c #321D18",
+"! c #36201A",
+"~ c #422922",
+"{ c #432B24",
+"] c #38251F",
+"^ c #2A1A16",
+"/ c #2A1D17",
+"( c #281D18",
+"_ c #221916",
+": c #1F1815",
+"< c #1A1512",
+"[ c #191513",
+"} c #1C1A14",
+"| c #1C1B16",
+"1 c #1B1B15",
+"2 c #1F2219",
+"3 c #1B1F15",
+"4 c #161A12",
+"5 c #12140F",
+"6 c #090A07",
+"7 c #040503",
+"8 c #010101",
+"9 c #1B1112",
+"0 c #221515",
+"a c #2B1A19",
+"b c #2F1C1B",
+"c c #321E1B",
+"d c #331E1C",
+"e c #351F1C",
+"f c #3E231D",
+"g c #502E25",
+"h c #663F33",
+"i c #653F34",
+"j c #462A21",
+"k c #3E2821",
+"l c #37251F",
+"m c #30231E",
+"n c #2D221F",
+"o c #29211D",
+"p c #201B17",
+"q c #1E1A15",
+"r c #1D1A15",
+"s c #1C1C15",
+"t c #212219",
+"u c #2B3223",
+"v c #394932",
+"w c #2B3826",
+"x c #171D13",
+"y c #0E100B",
+"z c #080907",
+"A c #050604",
+"B c #1F1315",
+"C c #301F1E",
+"D c #422926",
+"E c #50302C",
+"F c #4A2C28",
+"G c #412723",
+"H c #3D2420",
+"I c #462923",
+"J c #502C22",
+"K c #784333",
+"L c #B36A50",
+"M c #A15E47",
+"N c #6D4030",
+"O c #57372D",
+"P c #442F27",
+"Q c #3A2B25",
+"R c #352A25",
+"S c #2F2622",
+"T c #2A241F",
+"U c #2A241E",
+"V c #24211A",
+"W c #22211A",
+"X c #25281D",
+"Y c #394831",
+"Z c #A4C096",
+"` c #6D8D64",
+" . c #263221",
+".. c #171B13",
+"+. c #0D0F0A",
+"@. c #231617",
+"#. c #362221",
+"$. c #704540",
+"%. c #CF988B",
+"&. c #945D53",
+"*. c #512F2B",
+"=. c #452823",
+"-. c #4B2A23",
+";. c #693A2D",
+">. c #B86547",
+",. c #FDD0A5",
+"'. c #F2B385",
+"). c #AD6248",
+"!. c #6A4334",
+"~. c #50382F",
+"{. c #473731",
+"]. c #4B3F39",
+"^. c #413833",
+"/. c #3F3731",
+"(. c #363029",
+"_. c #302C24",
+":. c #2C2B22",
+"<. c #303225",
+"[. c #49573C",
+"}. c #9FB990",
+"|. c #7C9B71",
+"1. c #384330",
+"2. c #23271D",
+"3. c #161712",
+"4. c #0E0F0B",
+"5. c #27191A",
+"6. c #402929",
+"7. c #80504A",
+"8. c #F0BEB2",
+"9. c #BC8175",
+"0. c #5D3934",
+"a. c #50302B",
+"b. c #56312A",
+"c. c #7A4536",
+"d. c #DB8059",
+"e. c #FEFBED",
+"f. c #FEE8CA",
+"g. c #D27D5B",
+"h. c #835544",
+"i. c #6A4F44",
+"j. c #685852",
+"k. c #7A7472",
+"l. c #635C57",
+"m. c #474039",
+"n. c #3A332C",
+"o. c #322D26",
+"p. c #2E2C23",
+"q. c #414635",
+"r. c #59654C",
+"s. c #546349",
+"t. c #3F4934",
+"u. c #2B3023",
+"v. c #1C1E16",
+"w. c #181812",
+"x. c #141410",
+"y. c #27191B",
+"z. c #392526",
+"A. c #523433",
+"B. c #774C48",
+"C. c #7F534D",
+"D. c #613E39",
+"E. c #50312D",
+"F. c #56332D",
+"G. c #7A493D",
+"H. c #CD7E60",
+"I. c #F2AE81",
+"J. c #E79064",
+"K. c #9A5942",
+"L. c #6D4639",
+"M. c #634A41",
+"N. c #867E7A",
+"O. c #F0E4CB",
+"P. c #7E7D78",
+"Q. c #4C453D",
+"R. c #3E3730",
+"S. c #38322A",
+"T. c #4D5140",
+"U. c #555C48",
+"V. c #333326",
+"W. c #38392A",
+"X. c #36372A",
+"Y. c #2A2B20",
+"Z. c #201F18",
+"`. c #191813",
+" + c #100E0B",
+".+ c #27191D",
+"++ c #312023",
+"@+ c #402A2C",
+"#+ c #493031",
+"$+ c #533635",
+"%+ c #6A4642",
+"&+ c #5C3B38",
+"*+ c #623F3B",
+"=+ c #784D44",
+"-+ c #8C5547",
+";+ c #945643",
+">+ c #9D5E47",
+",+ c #764A3A",
+"'+ c #604035",
+")+ c #594239",
+"!+ c #655751",
+"~+ c #8B8680",
+"{+ c #645E57",
+"]+ c #4E453C",
+"^+ c #413A30",
+"/+ c #555845",
+"(+ c #4E503F",
+"_+ c #342F26",
+":+ c #353025",
+"<+ c #3E392C",
+"[+ c #3F392E",
+"}+ c #312D23",
+"|+ c #27241D",
+"1+ c #181611",
+"2+ c #0F0E0A",
+"3+ c #26191F",
+"4+ c #2F1F24",
+"5+ c #3A272B",
+"6+ c #3D292D",
+"7+ c #3F292C",
+"8+ c #503536",
+"9+ c #6A4845",
+"0+ c #6B4946",
+"a+ c #67433E",
+"b+ c #6D463E",
+"c+ c #7B4D41",
+"d+ c #915C47",
+"e+ c #5D3B32",
+"f+ c #573C34",
+"g+ c #533D35",
+"h+ c #56453D",
+"i+ c #5C4F46",
+"j+ c #4C4138",
+"k+ c #4B4136",
+"l+ c #5A5846",
+"m+ c #51513F",
+"n+ c #342D23",
+"o+ c #342E24",
+"p+ c #40382B",
+"q+ c #534638",
+"r+ c #665544",
+"s+ c #4D4034",
+"t+ c #2B251D",
+"u+ c #191611",
+"v+ c #11100C",
+"w+ c #2B1D23",
+"x+ c #322229",
+"y+ c #3C2A31",
+"z+ c #3E2A31",
+"A+ c #402B30",
+"B+ c #472F33",
+"C+ c #654748",
+"D+ c #5F4040",
+"E+ c #614140",
+"F+ c #62403E",
+"G+ c #6C453F",
+"H+ c #825344",
+"I+ c #583931",
+"J+ c #523A33",
+"K+ c #533E36",
+"L+ c #544238",
+"M+ c #544539",
+"N+ c #504637",
+"O+ c #595342",
+"P+ c #575340",
+"Q+ c #3D3427",
+"R+ c #3B3227",
+"S+ c #3F3529",
+"T+ c #483C2F",
+"U+ c #886F5B",
+"V+ c #E1CFB9",
+"W+ c #7C6250",
+"X+ c #332A22",
+"Y+ c #1F1A14",
+"Z+ c #15110E",
+"`+ c #31222A",
+" @ c #3B2A33",
+".@ c #46323C",
+"+@ c #48333C",
+"@@ c #483139",
+"#@ c #50393F",
+"$@ c #523A3F",
+"%@ c #5A3E41",
+"&@ c #614144",
+"*@ c #5F3D3F",
+"=@ c #674341",
+"-@ c #8A5847",
+";@ c #774F41",
+">@ c #503A34",
+",@ c #513C35",
+"'@ c #544237",
+")@ c #594B3B",
+"!@ c #5E533F",
+"~@ c #686047",
+"{@ c #514430",
+"]@ c #423727",
+"^@ c #403627",
+"/@ c #3B3125",
+"(@ c #473B2D",
+"_@ c #7B6452",
+":@ c #C6AC95",
+"<@ c #7B6352",
+"[@ c #3B3128",
+"}@ c #231E18",
+"|@ c #17130F",
+"1@ c #33222C",
+"2@ c #493441",
+"3@ c #58414E",
+"4@ c #5B4250",
+"5@ c #573F4A",
+"6@ c #5D444E",
+"7@ c #573E46",
+"8@ c #5B3E44",
+"9@ c #67434A",
+"0@ c #905C67",
+"a@ c #8D5C64",
+"b@ c #87594F",
+"c@ c #724C41",
+"d@ c #4A3531",
+"e@ c #4C3931",
+"f@ c #544236",
+"g@ c #696048",
+"h@ c #796D4E",
+"i@ c #958154",
+"j@ c #77653F",
+"k@ c #5C4E34",
+"l@ c #463B2A",
+"m@ c #473C2D",
+"n@ c #4F4335",
+"o@ c #56483A",
+"p@ c #635244",
+"q@ c #493C31",
+"r@ c #302821",
+"s@ c #1E1914",
+"t@ c #110D0B",
+"u@ c #463340",
+"v@ c #543C4C",
+"w@ c #7A5C71",
+"x@ c #805F76",
+"y@ c #795C6E",
+"z@ c #634956",
+"A@ c #583E48",
+"B@ c #5F4249",
+"C@ c #845963",
+"D@ c #ECBCC1",
+"E@ c #DAA5AC",
+"F@ c #7B504F",
+"G@ c #734C41",
+"H@ c #48332E",
+"I@ c #43322B",
+"J@ c #544839",
+"K@ c #6B6247",
+"L@ c #A28C59",
+"M@ c #F8EBCB",
+"N@ c #E9DAAC",
+"O@ c #99885E",
+"P@ c #665940",
+"Q@ c #493F2F",
+"R@ c #372E23",
+"S@ c #342B22",
+"T@ c #312720",
+"U@ c #272019",
+"V@ c #1B1511",
+"W@ c #13100C",
+"X@ c #0E0A08",
+"Y@ c #43303E",
+"Z@ c #6D5168",
+"`@ c #BF98B9",
+" # c #E5C7E1",
+".# c #9B7693",
+"+# c #624758",
+"@# c #543B47",
+"## c #553B44",
+"$# c #67454E",
+"%# c #895665",
+"&# c #90606C",
+"*# c #5F3E3F",
+"=# c #744C3F",
+"-# c #4B352E",
+";# c #45372F",
+"># c #5B5341",
+",# c #66553E",
+"'# c #AB9561",
+")# c #FDF1DB",
+"!# c #F8EAC7",
+"~# c #938155",
+"{# c #4D412D",
+"]# c #362D20",
+"^# c #2C241B",
+"/# c #29221B",
+"(# c #251E18",
+"_# c #1E1813",
+":# c #0F0C09",
+"<# c #0A0707",
+"[# c #4A3746",
+"}# c #73566E",
+"|# c #D9B5D5",
+"1# c #FDF3FC",
+"2# c #B48BAC",
+"3# c #705567",
+"4# c #59424E",
+"5# c #4E3841",
+"6# c #4C353D",
+"7# c #4D333A",
+"8# c #563C40",
+"9# c #4C3536",
+"0# c #7B5140",
+"a# c #4A362F",
+"b# c #504B3E",
+"c# c #473B2F",
+"d# c #514231",
+"e# c #A28D5B",
+"f# c #9C895B",
+"g# c #615338",
+"h# c #4A402E",
+"i# c #332B1F",
+"j# c #272018",
+"k# c #211B15",
+"l# c #1C1814",
+"m# c #181411",
+"n# c #100F0B",
+"o# c #0C0A08",
+"p# c #080605",
+"q# c #3D2C3A",
+"r# c #5A4255",
+"s# c #886682",
+"t# c #A881A1",
+"u# c #806279",
+"v# c #5D4655",
+"w# c #493540",
+"x# c #402E36",
+"y# c #3E2B32",
+"z# c #3D2A30",
+"A# c #433034",
+"B# c #453232",
+"C# c #764E3E",
+"D# c #51453A",
+"E# c #443B32",
+"F# c #3D332A",
+"G# c #43382C",
+"H# c #5C4F3A",
+"I# c #534632",
+"J# c #3F3526",
+"K# c #2E271C",
+"L# c #29231A",
+"M# c #28221B",
+"N# c #201B15",
+"O# c #191512",
+"P# c #12100D",
+"Q# c #080706",
+"R# c #050404",
+"S# c #332430",
+"T# c #3E2C3A",
+"U# c #553F50",
+"V# c #5C4557",
+"W# c #3C2C36",
+"X# c #37272F",
+"Y# c #302228",
+"Z# c #2D1F24",
+"`# c #322427",
+" $ c #3E2F2E",
+".$ c #825A47",
+"+$ c #615443",
+"@$ c #594638",
+"#$ c #423B30",
+"$$ c #F5E8C5",
+"%$ c #4A4034",
+"&$ c #332A20",
+"*$ c #2F271D",
+"=$ c #352C22",
+"-$ c #221C15",
+";$ c #1D1713",
+">$ c #1B1612",
+",$ c #191511",
+"'$ c #181412",
+")$ c #12110E",
+"!$ c #0C0B09",
+"~$ c #070605",
+"{$ c #040303",
+"]$ c #251923",
+"^$ c #31232E",
+"/$ c #382935",
+"($ c #3F2F3B",
+"_$ c #3C2D38",
+":$ c #2C1F26",
+"<$ c #291E23",
+"[$ c #281D22",
+"}$ c #291D20",
+"|$ c #332B29",
+"1$ c #7D6A52",
+"2$ c #645442",
+"3$ c #755540",
+"4$ c #F3D9B5",
+"5$ c #322B23",
+"6$ c #241D17",
+"7$ c #201914",
+"8$ c #261F19",
+"9$ c #1C1713",
+"0$ c #16120F",
+"a$ c #130F0D",
+"b$ c #100D0A",
+"c$ c #100C0B",
+"d$ c #0E0C0A",
+"e$ c #070606",
+"f$ c #030302",
+"g$ c #1C131B",
+"h$ c #281D26",
+"i$ c #261A23",
+"j$ c #2E222B",
+"k$ c #2B2029",
+"l$ c #2E222A",
+"m$ c #23191F",
+"n$ c #21171C",
+"o$ c #1F161A",
+"p$ c #22181C",
+"q$ c #261E1F",
+"r$ c #573C30",
+"s$ c #50372C",
+"t$ c #3D2921",
+"u$ c #33221C",
+"v$ c #28201D",
+"w$ c #1A1412",
+"x$ c #181311",
+"y$ c #16110F",
+"z$ c #171210",
+"A$ c #0D0909",
+"B$ c #0B0807",
+"C$ c #020202",
+"D$ c #A56E6E",
+"E$ c #7D7D7D",
+"F$ c #2A2A2A",
+"G$ c #3F3F3F",
+"H$ c #151515",
+"I$ c #939393",
+"J$ c #696969",
+"K$ c #000000",
+"L$ c #A7A7A7",
+"M$ c #545454",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". # $ # # % % % % % % % # # # # % % % % # # # # # # # # # & $ . ",
+". * = - ; > > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 . ",
+". 9 0 a b c d e ) f g h i j k l m n o p q r s t u v w x y z A . ",
+". B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.z . ",
+". @.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.. ",
+". 5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.. ",
+". y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +. ",
+". .+++@+#+$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+^+/+(+_+:+<+[+}+|+1+2+. ",
+". 3+4+5+6+7+8+9+0+a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+. ",
+". w+x+y+z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+. ",
+". `+ @.@+@@@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@[@}@|@. ",
+". 1@2@3@4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@j@k@l@m@n@o@p@q@r@s@t@. ",
+". u@v@w@x@y@z@A@B@C@D@E@F@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@. ",
+". Y@Z@`@ #.#+#@###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]#^#/#(#_#Z+:#<#. ",
+". [#}#|#1#2#3#4#5#6#7#8#9#0#a#b#c#d#!#e#f#g#h#i#j#k#l#m#n#o#p#. ",
+". q#r#s#t#u#v#w#x#y#z#A#B#C#D#E#F#G#!#H#I#J#K#L#M#N#O#P#o#Q#R#. ",
+". S#T#U#V#u#u#W#X#Y#Z#`# $.$+$@$#$$$%$&$*$=$-$;$>$,$'$)$!$~${$. ",
+". ]$^$/$($_$u#u#:$<$[$}$|$1$2$3$4$!#5$6$7$8$9$0$a$b$c$d$o#e$f$. ",
+". g$h$i$j$k$l$u#m$n$o$p$q$r$s$t$u$v$w$x$y$z$< t@A$B$<#Q#~${$C$. ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". D$# # # # # # # # # # # # # # # # # # # # # # # # # # # # # . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . E$F$G$H$E$. . . I$H$F$G$F$. . . J$K$G$G$F$L$. . . . . . ",
+". . . E$H$L$. J$K$. . . . H$E$. . . . . I$H$. . G$G$. . . . . . ",
+". . . H$J$. . E$K$. . . L$K$G$F$. . . . J$G$. . G$G$. . . . . . ",
+". . . K$E$. . F$M$. . . E$H$. I$. . . . G$M$. . H$E$. . . . . . ",
+". . . H$J$. J$F$L$E$J$. M$G$. I$I$M$I$. H$E$. G$G$. M$I$. . . . ",
+". . . I$G$F$G$. . J$E$I$G$G$G$G$. G$L$J$G$G$G$J$. . G$L$. . . . ",
+". . . . . . J$M$G$L$. . . . . . . . . . . . . . . . . . . . . . "};
diff --git a/images/restart.8bit.xpm b/images/restart.8bit.xpm
new file mode 100644
index 00000000..82f3d255
--- /dev/null
+++ b/images/restart.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * restart_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #020204",
+"+ c #860E0C",
+"@ c #353230",
+"# c #9A4644",
+"$ c #7D5E5C",
+"% c #797574",
+"& c #AA8284",
+"* c #BDBDBB",
+"********************************",
+"*****&&&&&&&&&&&&&&&&&&&&&&*****",
+"*****#+++++++++++++++++++++*****",
+"*****#+##################++*****",
+"*****#+******************#+*****",
+"*****#+*******$+++$******#+*****",
+"*****#+*****$+++++++*****#+*****",
+"*****#+****&+++++++++****#+*****",
+"*****#+****+++$****$+****#+*****",
+"*****#+***+++&******+****#+*****",
+"*****#+*+++++++****+++***#+*****",
+"*****#+*&++++++***+++++**#+*****",
+"*****#+**+++++***++++++&*#+*****",
+"*****#+***+++****+++++++*#+*****",
+"*****#+****+******$+++***#+*****",
+"*****#+****+#****#+++****#+*****",
+"*****#+****+++++++++$****#+*****",
+"*****#+*****+++++++$*****#+*****",
+"*****#+******$+++&*******#+*****",
+"*****#+******************#+*****",
+"*****#+******************#+*****",
+"*****#+&&&&&&&&&&&&&&&&&&++*****",
+"*****#+++++++++++++++++++++*****",
+"*****$#####################*****",
+"********************************",
+"**$.@.%**********%&***********%*",
+"**%.*$$*&$@*&$@%%.@**@@@*@$%%@.%",
+"**$@%.&*@*.&@@&*&.**.*%@*@@%&@$*",
+"**@$.%*$.@%**.@*%@*%@*.$*.$**@%*",
+"**.&%.*@@*&&%*.%@@*@@$@%*.***.%*",
+"*%@%*@%*@@%*@@%*%$&%@*@%%@***$@*",
+"********************************"};
diff --git a/images/restart.xcf b/images/restart.xcf
new file mode 100644
index 00000000..8b10079e
--- /dev/null
+++ b/images/restart.xcf
Binary files differ
diff --git a/images/restart.xpm b/images/restart.xpm
new file mode 100644
index 00000000..92724495
--- /dev/null
+++ b/images/restart.xpm
@@ -0,0 +1,55 @@
+/* XPM */
+static char * restart_xpm[] = {
+"32 32 20 1",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #8D2121",
+"& c #A26767",
+"* c #A97E7E",
+"= c #933434",
+"- c #A56E6E",
+"; c #696969",
+"> c #000000",
+", c #3F3F3F",
+"' c #151515",
+") c #7D7D7D",
+"! c #A7A7A7",
+"~ c #545454",
+"{ c #2A2A2A",
+"] c #939393",
+"................................",
+".....+@@@@@@@@@@@@@@@@@@@@@.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....#$##################%$.....",
+".....#$..................#$.....",
+".....#$.......&$$$&......#$.....",
+".....#$.....&$$$$$$$.....#$.....",
+".....#$....&$$$$$$$$$....#$.....",
+".....#$....$$$&....&$....#$.....",
+".....#$...$$$&......$....#$.....",
+".....#$.$$$$$$$....$$$...#$.....",
+".....#$.*$$$$$$...$$$$$..#$.....",
+".....#$..$$$$$...$$$$$$*.#$.....",
+".....#$...$$$....$$$$$$$.#$.....",
+".....#$....$......&$$$...#$.....",
+".....#$....$&....&$$$....#$.....",
+".....#$....$$$$$$$$$&....#$.....",
+".....#$.....$$$$$$$&.....#$.....",
+".....#$......&$$$&.......#$.....",
+".....#$..................#$.....",
+".....#$..................#$.....",
+".....#$@@@@@@@@@@@@@@@@@@=$.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....-#####################.....",
+"................................",
+"..;>,')..........)!..........!).",
+"..)'.,~.!~~!!~,);>,.!~,,.,;)){';",
+"..~{;'!!{!>],{!!)'..'!){.,,;],~.",
+"..,~').~',;.!',.;,.;,.'~.>~..{).",
+"..>];'!,{.]];!>),,.,{~{)!>...>).",
+".;,;.,;!,,).,,;.),]),!,;],...~,.",
+"................................"};
diff --git a/images/retract.8bit.xpm b/images/retract.8bit.xpm
new file mode 100644
index 00000000..6cfac9da
--- /dev/null
+++ b/images/retract.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * retract_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #020204",
+"+ c #860E0C",
+"@ c #3A3231",
+"# c #9A4644",
+"$ c #686263",
+"% c #807D7B",
+"& c #AA8284",
+"* c #BDBCBA",
+"********************************",
+"*****&&&&&&&&&&&&&&&&&&&&&&*****",
+"*****#+++++++++++++++++++++*****",
+"*****#+##################++*****",
+"*****#+******************#+*****",
+"*****#+******************#+*****",
+"*****#+**&+++++++++++++**#+*****",
+"*****#+**&+++++++++++++**#+*****",
+"*****#+********+++*******#+*****",
+"*****#+*******+++++******#+*****",
+"*****#+*******+++++******#+*****",
+"*****#+******++++++#*****#+*****",
+"*****#+******+++++++*****#+*****",
+"*****#+*****++++++++&****#+*****",
+"*****#+*****++++++++#****#+*****",
+"*****#+****#+++++++++****#+*****",
+"*****#+****++++++++++$***#+*****",
+"*****#+****+++++++++++***#+*****",
+"*****#+**&++++++++++++&**#+*****",
+"*****#+******************#+*****",
+"*****#+******************#+*****",
+"*****#+&&&&&&&&&&&&&&&&&&#+*****",
+"*****#+++++++++++++++++++++*****",
+"*****&#####################*****",
+"********************************",
+"*$.@.%******%****************%**",
+"*%.*@$*&$$&$.@&@&$*&$@@**$@$$.@*",
+"*$@$@&*@*.&%.**.$%*.*%@*@@*$%.**",
+"*@$.%*$.@$*%@*%.%*$@*.$%.***%@**",
+"*.%$.*@@*%%$@*%@**@@$@%%.***@@**",
+"$@%*@$*@$%*%@%%$**%@*@$*$@$*%$%*",
+"********************************"};
diff --git a/images/retract.xcf b/images/retract.xcf
new file mode 100644
index 00000000..e0a81c8c
--- /dev/null
+++ b/images/retract.xcf
Binary files differ
diff --git a/images/retract.xpm b/images/retract.xpm
new file mode 100644
index 00000000..8ffdfdd4
--- /dev/null
+++ b/images/retract.xpm
@@ -0,0 +1,62 @@
+/* XPM */
+static char * retract_xpm[] = {
+"32 32 27 1",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #8D2121",
+"& c #860C0C",
+"* c #9E5959",
+"= c #B09595",
+"- c #902D2D",
+"; c #A16363",
+"> c #A06262",
+", c #B29A9A",
+"' c #8A1616",
+") c #AC8888",
+"! c #933434",
+"~ c #A56E6E",
+"{ c #696969",
+"] c #000000",
+"^ c #3F3F3F",
+"/ c #151515",
+"( c #7D7D7D",
+"_ c #A7A7A7",
+": c #545454",
+"< c #939393",
+"[ c #2A2A2A",
+"................................",
+".....+@@@@@@@@@@@@@@@@@@@@@.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....#$##################%$.....",
+".....#$..................#$.....",
+".....#$..................#$.....",
+".....#$..@$$$$$$$&$$$$$..#$.....",
+".....#$..@$$$$$$$$$$$$$..#$.....",
+".....#$........$$$.......#$.....",
+".....#$.......$$$$$......#$.....",
+".....#$.......$$$$$......#$.....",
+".....#$......$$$$$$*.....#$.....",
+".....#$......$$$$$$$.....#$.....",
+".....#$.....$$$$$$$$=....#$.....",
+".....#$.....$$$$$$$$-....#$.....",
+".....#$....;$$$$$$$$$....#$.....",
+".....#$....$$$$$$$$$$>...#$.....",
+".....#$...,$$$$$$$$$$'...#$.....",
+".....#$..,$$$$$$$$$$$$)..#$.....",
+".....#$..................#$.....",
+".....#$..................#$.....",
+".....#$@@@@@@@@@@@@@@@@@@!$.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....~#####################.....",
+"................................",
+".{]^/(......(_...............(_.",
+".(/.^:._::_{]^<^<:__:^^..{^{{]^.",
+".:[{/__[_]<(/..]:(_/_([.^^.{(/..",
+".^:/(.:/^{.{^.(]<.{^./:<]...{^..",
+".]<{/_^[.<<^^.{^..^[:[((]__.^^..",
+"{^{.^{_^^(.(^<{{..(^_^{.:^{.(^<.",
+"................................"};
diff --git a/images/state.8bit.xpm b/images/state.8bit.xpm
new file mode 100644
index 00000000..40fbc6f7
--- /dev/null
+++ b/images/state.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * state_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #050507",
+"+ c #7F4644",
+"@ c #8D7D7D",
+"# c #BABAB9",
+"$ c #FEFEFC",
+"% c #1A1A1A",
+"& c #EFEFF0",
+"* c #781514",
+"#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#",
+"#+*****************************#",
+"#+*++++++++++++++++++++++++++**#",
+"#+*##########################+*#",
+"#+*######@@@######@@@@#######+*#",
+"#+*####+*...%+###+%%..+@#####+*#",
+"#+*###+%@&&&@++@%%&&&#+%@####+*#",
+"#+*##@.&$&$$$#..+&&$$$$@%####+*#",
+"#+*##%@&$$$$$$@.#$$$$$$&%+###+*#",
+"#+*##.@$$$$$$$@.&$$$$$$&++@##+*#",
+"#++##.#&$$$$$$#.$$$$$$$$%%@##+*#",
+"#+*##.#$#@&$$$@.$&@#$$$$++@##+*#",
+"#+*##.@#%.@$$$@.&@.%&$$&%%@##+*#",
+"&+*##++#%%#$$&+.#@.%&$$#%@@##+*#",
+"#+*##@%##&&$&#..%&#&$$#@%@@##+*#",
+"#+*###@.+@@@+.+@%.@@@@%%@@@##+*#",
+"#+*####@+%.%%@@@#@%%.%+@@@###+*#",
+"#+*######@@@@@@####@@@@@@####+*#",
+"#+*#######@@@#######@@@@#####+*#",
+"#+*##########################+*#",
+"#+*@#@@@@#@@@@@@@@@@#@@@@@@@@+*#",
+"#+*****************************#",
+"#@+++++++++++++++++++++++++++++#",
+"#############&##################",
+"#######*+%&@@#######@###########",
+"######+%##@%%##@++@@.+##++######",
+"######@%+##%@#+@#.#@%##%#.@#####",
+"########%+#.##.#+%#++#+.+@######",
+"#####@@#%@@.#@.@%+#%+#%%#@######",
+"######+%+##%+#%@@+#@%##%+@######",
+"################################",
+"################################"};
diff --git a/images/state.xcf b/images/state.xcf
new file mode 100644
index 00000000..1b62f712
--- /dev/null
+++ b/images/state.xcf
Binary files differ
diff --git a/images/state.xpm b/images/state.xpm
new file mode 100644
index 00000000..2a3102fa
--- /dev/null
+++ b/images/state.xpm
@@ -0,0 +1,180 @@
+/* XPM */
+static char * state_xpm[] = {
+"32 32 145 2",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #994848",
+"& c #8D2121",
+"* c #9F9F9F",
+"= c #878787",
+"- c #8A8A8A",
+"; c #B2B2B2",
+"> c #515151",
+", c #202020",
+"' c #000000",
+") c #999999",
+"! c #4A4A4A",
+"~ c #050505",
+"{ c #010101",
+"] c #3C3C3C",
+"^ c #7C7C7C",
+"/ c #870F0F",
+"( c #AEAEAE",
+"_ c #3E3E3E",
+": c #343434",
+"< c #8F8F8F",
+"[ c #D9D9D9",
+"} c #ECECEC",
+"| c #8E8E8E",
+"1 c #1A1A1A",
+"2 c #373737",
+"3 c #CBCBCB",
+"4 c #E2E2E2",
+"5 c #E8E8E8",
+"6 c #D5D5D5",
+"7 c #545454",
+"8 c #232323",
+"9 c #707070",
+"0 c #994949",
+"a c #891313",
+"b c #828282",
+"c c #D3D3D3",
+"d c #F8F8F8",
+"e c #FFFFFF",
+"f c #444444",
+"g c #FEFEFE",
+"h c #F0F0F0",
+"i c #7B7B7B",
+"j c #0C0C0C",
+"k c #994A4A",
+"l c #8A1818",
+"m c #0E0E0E",
+"n c #7A7A7A",
+"o c #FDFDFD",
+"p c #E3E3E3",
+"q c #323232",
+"r c #4B4B4B",
+"s c #B0B0B0",
+"t c #9A4C4C",
+"u c #8B1C1C",
+"v c #959595",
+"w c #F3F3F3",
+"x c #F7F7F7",
+"y c #303030",
+"z c #9B4E4E",
+"A c #3F3F3F",
+"B c #8C1E1E",
+"C c #FAFAFA",
+"D c #AFAFAF",
+"E c #949494",
+"F c #F6F6F6",
+"G c #F4F4F4",
+"H c #868686",
+"I c #BDBDBD",
+"J c #FCFCFC",
+"K c #7F7F7F",
+"L c #994B4B",
+"M c #8D8D8D",
+"N c #C7C7C7",
+"O c #121212",
+"P c #070707",
+"Q c #939393",
+"R c #EBEBEB",
+"S c #787878",
+"T c #030303",
+"U c #171717",
+"V c #E4E4E4",
+"W c #F2F2F2",
+"X c #393939",
+"Y c #8B1B1B",
+"Z c #494949",
+"` c #C5C5C5",
+" . c #2D2D2D",
+".. c #131313",
+"+. c #9B9B9B",
+"@. c #3A3A3A",
+"#. c #B9B9B9",
+"$. c #222222",
+"%. c #555555",
+"&. c #891414",
+"*. c #888888",
+"=. c #080808",
+"-. c #B8B8B8",
+";. c #C4C4C4",
+">. c #CECECE",
+",. c #FBFBFB",
+"'. c #E6E6E6",
+"). c #BABABA",
+"!. c #0D0D0D",
+"~. c #3D3D3D",
+"{. c #E1E1E1",
+"]. c #6E6E6E",
+"^. c #881010",
+"/. c #797979",
+"(. c #464646",
+"_. c #818181",
+":. c #919191",
+"<. c #525252",
+"[. c #808080",
+"}. c #383838",
+"|. c #757575",
+"1. c #7D7D7D",
+"2. c #181818",
+"3. c #6D6D6D",
+"4. c #454545",
+"5. c #090909",
+"6. c #2F2F2F",
+"7. c #616161",
+"8. c #7E7E7E",
+"9. c #141414",
+"0. c #0A0A0A",
+"a. c #4F4F4F",
+"b. c #870E0E",
+"c. c #777777",
+"d. c #A3A3A3",
+"e. c #B3B3B3",
+"f. c #A2A2A2",
+"g. c #AB8383",
+"h. c #AB8484",
+"i. c #933434",
+"j. c #A56E6E",
+"k. c #2A2A2A",
+"l. c #A7A7A7",
+"m. c #151515",
+"n. c #696969",
+". + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". # $ # # % % % % % % % # # # # % % % % # # # # # # # # # & $ . ",
+". # $ . . . . . . . . . . . . . . . . . . . . . . . . . . # $ . ",
+". # $ . . . . . * = = = * . . . . . - = = = ; . . . . . . # $ . ",
+". % $ . . . . > , ' ' ' , > . . ) ! ~ { { { ] ^ . . . . . # $ . ",
+". % / . . ( _ : < [ } [ < : _ | 1 2 3 4 5 6 7 8 9 . . . . # $ . ",
+". 0 a . . b { c d e e e d c ' ' f 5 g g g g h i j . . . . # $ . ",
+". k l . . m n d g e e e e d n ' 6 o g g g g g p q r s . . # $ . ",
+". t u . . { v o g e e e e o v ' w g g g g g g x ] y | . . # $ . ",
+". z u . . ' * g g e e e e e * ' e g g g g g g g A y n . . # $ . ",
+". z B . . { * C D E F e e e * ' e G H I J g g g A y K . . # $ . ",
+". L B . . ' M N O P Q e e o M ' R S T U V g g W X y K . . # $ . ",
+". L Y . . ] Z ` ...; e e R Z ' +.) P @.R g J #.$.%.K . . # $ . ",
+". 0 &.. . *.=.-.;.>.,.,.'.).~ !.~.;.;.{.o ,.c ].O K i . . # $ . ",
+". 0 ^.. . . /.~ (._.:._.(.T <.[.}.{ |.*.M 1.2.2.3.K | . . # $ . ",
+". % / . . . . :.4.5.5.5.6.7.8._.( | 9.0.0.0.a.3.K S D . . # $ . ",
+". % b.. . . . . . /.[.[.[.c.= . . . d./.^ K K S n . . . . # $ . ",
+". # $ . . . . . . e.:.:.:.D . . . . . . v :.:.f.. . . . . # $ . ",
+". # $ . . . . . . . . . . . . . . . . . . . . . . . . . . # $ . ",
+". # $ @ @ @ @ g.h.h.h.h.h.@ @ @ h.h.h.h.h.@ @ @ @ @ @ @ @ i.$ . ",
+". # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ . ",
+". j.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . Q k.A k.. Q Q . . . . . . . 1.l.. . . . . . . . . . ",
+". . . . . . A k.. . Q m.k.Q . n.A A Q n.' A . l.7 7 l.. . . . . ",
+". . . . . . Q ' A . . ' Q . 7 n.. ' . 1.m.. l.k.l.' Q . . . . . ",
+". . . . . . . l.m.7 l.' . l.' . 7 m.. n.A . 7 m.A n.. . . . . . ",
+". . . . . Q 1.. k.n.1.' . 1.' n.A A . A A . A k.. Q Q . . . . . ",
+". . . . . l.A A n.. l.A n.l.A 1.n.A . 1.A Q l.A A 1.. . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};
diff --git a/images/undo.8bit.xpm b/images/undo.8bit.xpm
new file mode 100644
index 00000000..4444863c
--- /dev/null
+++ b/images/undo.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * undo_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #020204",
+"+ c #860E0C",
+"@ c #3E3230",
+"# c #9A4644",
+"$ c #736C6C",
+"% c #AA8284",
+"& c #AE8A8C",
+"* c #BDBDBB",
+"********************************",
+"*****&%%%%%%%%%%%%%%%%%%%%%*****",
+"*****#+++++++++++++++++++++*****",
+"*****#+##################++*****",
+"*****#+******************#+*****",
+"*****#+******************#+*****",
+"*****#+**************+***#+*****",
+"*****#+************+++***#+*****",
+"*****#+*********++++++***#+*****",
+"*****#+*******++++++++***#+*****",
+"*****#+****+++++++++++***#+*****",
+"*****#+**+++++++++++++***#+*****",
+"*****#+**+++++++++++++***#+*****",
+"*****#+**+++++++++++++***#+*****",
+"*****#+*****++++++++++***#+*****",
+"*****#+*******#+++++++***#+*****",
+"*****#+*********&+++++***#+*****",
+"*****#+************#++***#+*****",
+"*****#+**************%***#+*****",
+"*****#+******************#+*****",
+"*****#+******************#+*****",
+"*****#+%%%%%%%%%%%%%%%%%%++*****",
+"*****#+++++++++++++++++++++*****",
+"*****$#####################*****",
+"********************&$**********",
+"******@.$*.@********$.**********",
+"******$.**@*@$&@**%@@@**@@&*****",
+"******@@**.*@@$.$&@*@$*.*$.*****",
+"******.&**@*@@*.*@$&.&@@*$.*****",
+"******.$*$$*.*$@*.$@.*@@*@$*****",
+"******&@@$**@*$@&$@*@**@@&******",
+"********************************"};
diff --git a/images/undo.xcf b/images/undo.xcf
new file mode 100644
index 00000000..07b7da28
--- /dev/null
+++ b/images/undo.xcf
Binary files differ
diff --git a/images/undo.xpm b/images/undo.xpm
new file mode 100644
index 00000000..6ae21467
--- /dev/null
+++ b/images/undo.xpm
@@ -0,0 +1,59 @@
+/* XPM */
+static char * undo_xpm[] = {
+"32 32 24 1",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #B09696",
+"@ c #AA8282",
+"# c #994747",
+"$ c #870D0D",
+"% c #8D2121",
+"& c #902D2D",
+"* c #9E5959",
+"= c #B09595",
+"- c #A06262",
+"; c #8A1616",
+"> c #AC8888",
+", c #933434",
+"' c #A56E6E",
+") c #939393",
+"! c #7D7D7D",
+"~ c #3F3F3F",
+"{ c #000000",
+"] c #696969",
+"^ c #151515",
+"/ c #2A2A2A",
+"( c #A7A7A7",
+"_ c #545454",
+"................................",
+".....+@@@@@@@@@@@@@@@@@@@@@.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....#$##################%$.....",
+".....#$..................#$.....",
+".....#$..................#$.....",
+".....#$..............$...#$.....",
+".....#$............$$$...#$.....",
+".....#$.........$$$$$$...#$.....",
+".....#$.......$$$$$$$$...#$.....",
+".....#$....$$$$$$$$$$$...#$.....",
+".....#$..$$$$$$$$$$$$$...#$.....",
+".....#$..$$$$$$$$$$$$$...#$.....",
+".....#$..&$$$$$$$$$$$$...#$.....",
+".....#$.....$$$$$$$$$$...#$.....",
+".....#$.......*$$$$$$$...#$.....",
+".....#$.........=&$$$$...#$.....",
+".....#$............-;$...#$.....",
+".....#$..............>...#$.....",
+".....#$..................#$.....",
+".....#$..................#$.....",
+".....#$@@@@@@@@@@@@@@@@@@,$.....",
+".....#$$$$$$$$$$$$$$$$$$$$$.....",
+".....'#####################.....",
+"....................)!..........",
+"......~{].^/........]^..........",
+"......!^..~(~])~(.)~/~.(_~).....",
+"......~~..{.~~]{!)/.~](^(]{.....",
+"......{!.(~./~({.~!){)_~.!^.....",
+"......^].]].{(!^.{_~{.~/(^!.....",
+"......)~~].(~.!~)__)~)(~~)......",
+"................................"};
diff --git a/images/use.8bit.xpm b/images/use.8bit.xpm
new file mode 100644
index 00000000..82f9e484
--- /dev/null
+++ b/images/use.8bit.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * use_8bit_xpm[] = {
+"32 32 9 1",
+" c None",
+". c #020204",
+"+ c #860E0C",
+"@ c #463433",
+"# c #9A4644",
+"$ c #776C6C",
+"% c #AA8284",
+"& c #AE8A8C",
+"* c #BDBDBB",
+"********************************",
+"*****#####################%*****",
+"*****+++++++++++++++++++++#*****",
+"*****+#%%%%%%%%%%%%%%%%%%+#*****",
+"*****+#******************+#*****",
+"*****+#******************+#*****",
+"*****+#**&++++++++++++%**+#*****",
+"*****+#***&+++++++++++***+#*****",
+"*****+#****++++++++++$***+#*****",
+"*****+#****#+++++++++****+#*****",
+"*****+#*****+++++++++****+#*****",
+"*****+#*****++++++++&****+#*****",
+"*****+#******+++++++*****+#*****",
+"*****+#******++++++#*****+#*****",
+"*****+#*******+++++******+#*****",
+"*****+#*******+++++******+#*****",
+"*****+#********+++*******+#*****",
+"*****+#**%+++++++++++++**+#*****",
+"*****+#**%+++++++++++++**+#*****",
+"*****+#******************+#*****",
+"*****+#******************+#*****",
+"*****++##################+#*****",
+"*****+++++++++++++++++++++#*****",
+"*****%%%%%%%%%%%%%%%%%%%%%&*****",
+"********************************",
+"*********@.$*.@*****************",
+"*********$.**@&&@@&*$@%*********",
+"*********@@**.*.$&*@$@@*********",
+"*********.%**@*$.$&.@$**********",
+"*********.$*$$&*$.&.&*$*********",
+"*********&@@$*&@@&*$@$&*********",
+"********************************"};
diff --git a/images/use.xcf b/images/use.xcf
new file mode 100644
index 00000000..c4d68aac
--- /dev/null
+++ b/images/use.xcf
Binary files differ
diff --git a/images/use.xpm b/images/use.xpm
new file mode 100644
index 00000000..37e22111
--- /dev/null
+++ b/images/use.xpm
@@ -0,0 +1,62 @@
+/* XPM */
+static char * use_xpm[] = {
+"32 32 27 1",
+" c None",
+". c #BCBCBC s backgroundToolBarColor",
+"+ c #994747",
+"@ c #A56E6E",
+"# c #870D0D",
+"$ c #933434",
+"% c #AA8282",
+"& c #B29A9A",
+"* c #AC8888",
+"= c #8A1616",
+"- c #A06262",
+"; c #A16363",
+"> c #902D2D",
+", c #B09595",
+"' c #9E5959",
+") c #860C0C",
+"! c #8D2121",
+"~ c #B09696",
+"{ c #3F3F3F",
+"] c #000000",
+"^ c #696969",
+"/ c #151515",
+"( c #2A2A2A",
+"_ c #7D7D7D",
+": c #A7A7A7",
+"< c #939393",
+"[ c #545454",
+"................................",
+".....+++++++++++++++++++++@.....",
+".....#####################+.....",
+".....#$%%%%%%%%%%%%%%%%%%#+.....",
+".....#+..................#+.....",
+".....#+..................#+.....",
+".....#+..&############*..#+.....",
+".....#+...&##########=...#+.....",
+".....#+....##########-...#+.....",
+".....#+....;#########....#+.....",
+".....#+.....########>....#+.....",
+".....#+.....########,....#+.....",
+".....#+......#######.....#+.....",
+".....#+......######'.....#+.....",
+".....#+.......#####......#+.....",
+".....#+.......#####......#+.....",
+".....#+........###.......#+.....",
+".....#+..%#############..#+.....",
+".....#+..%#######)#####..#+.....",
+".....#+..................#+.....",
+".....#+..................#+.....",
+".....#!++++++++++++++++++#+.....",
+".....#####################+.....",
+".....%%%%%%%%%%%%%%%%%%%%%~.....",
+"................................",
+".........{]^./(.................",
+"........._/..{:<{{:.^{<.........",
+".........{{..].]^<.{_{[.........",
+".........]_.:{._]_<]{[:.........",
+"........./^.^^<<^]_]::_.........",
+".........<{{^.<{{<.[{^:.........",
+"................................"};
diff --git a/isa/BUGS b/isa/BUGS
new file mode 100644
index 00000000..068e7fa9
--- /dev/null
+++ b/isa/BUGS
@@ -0,0 +1,50 @@
+-*- mode:outline -*-
+
+* Isabelle Proof General Bugs
+
+See also ../BUGS for generic bugs.
+
+
+** set proof_timing is problematic
+
+It will make the goals display disappear during proof. This is
+because Proof General only displays goals output that appears *after*
+Isabelle messages, but Isabelle prints the timing message after the
+goals are displayed.
+
+** General difficulty with proof scripts containing ML structures, etc.
+
+Proof General does not understand full ML syntax(!), so it will be
+confused by structures which contain semi-colons after declarations,
+for example. Also, it cannot undo function declarations. See the
+section on ML files in the manual for more details.
+
+** Blocking when processing multiple files, beginning from a .ML file.
+
+Proof General will block the Emacs process when it is waiting for a
+theory file (and it's ancestors) to be read as scripting is turned on.
+To avoid this, assert the theory file rather than the ML file.
+
+** Subsection Interaction with theory database
+
+Isabelle Proof General uses some support from Isabelle to remove and
+reload theories from the theory database. To maintain consistency,
+Isabelle is rather conservative. So re-asserting a retracted file will
+often re-load it, even if it has not changed. (This is because the
+file may have implicit dependencies on things in the global ML
+environment not made apparent by the theory structure).
+This may lead to seemingly unnecessary repetition of time-consuming
+proofs, so be careful not to retract more than you need!
+
+As of Isabelle 99-1 and Proof General 3.2, there should be much
+less unncessary re-loading of theories; be careful to use Isabelle's
+mechanisms of declaring dependencies in theory file headers.
+
+** Clash with SML mode
+
+Since Isabelle proof scripts are not differentiated from `.ML' files,
+Proof General may compete with `sml-mode' (if you use it) for
+controlling these buffers. To ensure Proof General wins, load it last.
+
+Workaround: use another extension for real ML files, e.g. `.sml',
+and disable `.ML' from entering `sml-mode'.
diff --git a/isa/Example-Xsym.ML b/isa/Example-Xsym.ML
new file mode 100644
index 00000000..d566a850
--- /dev/null
+++ b/isa/Example-Xsym.ML
@@ -0,0 +1,15 @@
+(*
+ Example proof script for Isabelle Proof General.
+
+ $Id$
+
+ Just a version of Example.ML using XSymbol
+*)
+
+Goal "A \\<and> B \\<longrightarrow> B \\<and> A";
+by (rtac impI 1);
+by (etac conjE 1);
+by (rtac conjI 1);
+by (assume_tac 1);
+by (assume_tac 1);
+qed "and_comms";
diff --git a/isa/Example.ML b/isa/Example.ML
new file mode 100644
index 00000000..720e3a47
--- /dev/null
+++ b/isa/Example.ML
@@ -0,0 +1,13 @@
+(*
+ Example proof script for Isabelle Proof General.
+
+ $Id$
+*)
+
+Goal "A & B --> B & A";
+ by (rtac impI 1);
+ by (etac conjE 1);
+ by (rtac conjI 1);
+ by (assume_tac 1);
+ by (assume_tac 1);
+qed "and_comms";
diff --git a/isa/Example.thy b/isa/Example.thy
new file mode 100644
index 00000000..252a5a4c
--- /dev/null
+++ b/isa/Example.thy
@@ -0,0 +1,10 @@
+(*
+ Example theory file for Isabelle
+
+ David Aspinall <da@dcs.ed.ac.uk>
+
+ $Id$
+
+*)
+
+Example = Main
diff --git a/isa/Example2.ML b/isa/Example2.ML
new file mode 100644
index 00000000..ab2fef03
--- /dev/null
+++ b/isa/Example2.ML
@@ -0,0 +1,15 @@
+(*
+ Example proof script for Isabelle Proof General.
+
+ $Id$
+
+ Same as Example.ML, except using X-Symbol input tokens.
+*)
+
+Goal "A \\<and> B \\<longrightarrow> B \\<and> A";
+ by (rtac impI 1);
+ by (etac conjE 1);
+ by (rtac conjI 1);
+ by (assume_tac 1);
+ by (assume_tac 1);
+qed "and_comms";
diff --git a/isa/README b/isa/README
new file mode 100644
index 00000000..8207071a
--- /dev/null
+++ b/isa/README
@@ -0,0 +1,33 @@
+Isabelle Proof General
+
+Written by David Aspinall, later with assistance from
+Markus Wenzel and David von Oheimb.
+
+Status: supported
+Maintainer: David Aspinall
+Isabelle versions: Isabelle99-1, Isabelle99-2, Isabelle2002
+Isabelle homepage: http://www.cl.cam.ac.uk/Research/HVG/Isabelle/
+
+========================================
+
+Isabelle Proof General has full support for multiple file scripting,
+with dependencies between theories communicated between Isabelle and
+Proof General. It has a mode for editing theory files taken from
+Isamode.
+
+There is proper support for X Symbol, using the Isabelle print mode
+for X Symbol tokens. Many Isabelle theories have X Symbol syntax
+already defined and it's easy to add to your own theories.
+
+There is no support for proof by pointing yet, and no tags program.
+
+The script `interface' and file 'interface-setup.el' are used to start
+Isabelle Proof General via the 'Isabelle' shell command. These files
+were provided by Markus Wenzel.
+
+Check the value of isabelle-prog-name.
+
+========================================
+
+$Id$
+
diff --git a/isa/depends.ML b/isa/depends.ML
new file mode 100644
index 00000000..65e2b91f
--- /dev/null
+++ b/isa/depends.ML
@@ -0,0 +1,100 @@
+(* depends.ML
+
+ Experimental code for communicating theorem dependencies from Isabelle
+ to Proof General.
+
+ This code is taken from thm_deps.ML in Isabelle 99-2. It's incompatible
+ with other Isabelle versions.
+
+ It is duplicated almost verbatim because what we need is
+ hardwired to a call on the browser tool.
+*)
+
+
+fun depends_enable () = Thm.keep_derivs := ThmDeriv;
+fun depends_disable () = Thm.keep_derivs := MinDeriv;
+
+
+
+fun is_internal (name, tags) = name = "" orelse Drule.has_internal tags;
+
+fun is_thm_axm (Theorem x) = not (is_internal x)
+ | is_thm_axm (Axiom x) = not (is_internal x)
+ | is_thm_axm _ = false;
+
+fun get_name (Theorem (s, _)) = s
+ | get_name (Axiom (s, _)) = s
+ | get_name _ = "";
+
+fun make_deps_graph ((gra, parents), Join (ta, ders)) =
+ let
+ val name = get_name ta;
+ in
+ if is_thm_axm ta then
+ if is_none (Symtab.lookup (gra, name)) then
+ let
+ val (gra', parents') = foldl make_deps_graph ((gra, []), ders);
+ val prefx = #1 (Library.split_last (NameSpace.unpack name));
+ val session =
+ (case prefx of
+ (x :: _) =>
+ (case ThyInfo.lookup_theory x of
+ Some thy =>
+ let val name = #name (Present.get_info thy)
+ in if name = "" then [] else [name] end
+ | None => [])
+ | _ => ["global"]);
+ in
+ (Symtab.update ((name,
+ {name = Sign.base_name name, ID = name,
+ dir = space_implode "/" (session @ prefx),
+ unfold = false, path = "", parents = parents'}), gra'), name ins parents)
+ end
+ else (gra, name ins parents)
+ else
+ foldl make_deps_graph ((gra, parents), ders)
+ end;
+
+fun thm_deps thms =
+ let
+ val _ = writeln "Generating graph ...";
+ val gra = map snd (Symtab.dest (fst (foldl make_deps_graph ((Symtab.empty, []),
+ map (#2 o #der o Thm.rep_thm) thms))));
+ val path = File.tmp_path (Path.unpack "theorems.graph");
+ val _ = Present.write_graph gra path;
+ val _ = system ("$ISATOOL browser -d " ^ Path.pack (Path.expand path) ^ " &");
+ in () end;
+
+fun new_thm_deps thms =
+ let
+ val header = "Proof General, the theorem dependencies are: \"";
+ val gra = map snd (Symtab.dest (fst (foldl make_deps_graph ((Symtab.empty, []),
+ map (#2 o #der o Thm.rep_thm) thms))));
+ val deps = sort_strings (foldl (op union) ([],(map #parents gra)))
+ val msg = header ^ (space_implode " " deps) ^ "\""
+ in priority msg end;
+
+val old_qed = qed;
+fun qed name =
+ let val _ = old_qed name
+ val proved_thm = thm name
+ in new_thm_deps [proved_thm] end;
+
+val old_qed_goal = qed_goal;
+fun qed_goal name thy goal tacsf =
+ let val _ = old_qed_goal name thy goal tacsf
+ val proved_thm = thm name
+ in new_thm_deps [proved_thm] end;
+
+val old_qed_goalw = qed_goalw;
+fun qed_goalw name thy rews goal tacsf =
+ let val _ = old_qed_goalw name thy rews goal tacsf
+ val proved_thm = thm name
+ in new_thm_deps [proved_thm] end;
+
+(* FIXME: this one only in HOL?? *)
+val old_qed_spec_mp = qed_spec_mp;
+fun qed_spec_mp name =
+ let val _ = old_qed_spec_mp name
+ val proved_thm = thm name
+ in new_thm_deps [proved_thm] end;
diff --git a/isa/interface b/isa/interface
new file mode 100644
index 00000000..46c78a58
--- /dev/null
+++ b/isa/interface
@@ -0,0 +1,236 @@
+#!/usr/bin/env bash
+#
+# $Id$
+#
+# Proof General interface wrapper for Isabelle.
+
+
+## self references
+
+THIS=$(cd "$(dirname "$0")"; pwd)
+SUPER=$(cd "$THIS/.."; pwd)
+KIND=$(basename "$(dirname "$0")")
+
+if [ "$KIND" = isar ]; then
+ ISAR=true
+else
+ ISAR=false
+fi
+
+
+## diagnostics
+
+usage()
+{
+ echo
+ echo "Usage: Isabelle [OPTIONS] [FILES ...]"
+ echo
+ echo " Options are:"
+ echo " -I BOOL use Isabelle/Isar instead of classic Isabelle (default $ISAR)"
+ echo " -P BOOL actually start Proof General (default true), otherwise"
+ echo " run plain tty session"
+ echo " -X BOOL configure the X-Symbol package on startup (default true)"
+ echo " -g GEOMETRY specify Emacs geometry"
+ echo " -k NAME use specific isar-keywords for named logic"
+ echo " -l NAME logic image name (default \$ISABELLE_LOGIC=$ISABELLE_LOGIC)"
+ echo " -m MODE add print mode for output"
+ echo " -p NAME Emacs program name (default xemacs)"
+ echo " -u BOOL use personal .emacs file (default true)"
+ echo " -w BOOL use window system (default true)"
+ echo " -x BOOL enable the X-Symbol package on startup (default false)"
+ echo
+ echo "Starts Proof General for Isabelle with theory and proof FILES"
+ echo "(default Scratch.thy)."
+ echo
+ echo " PROOFGENERAL_OPTIONS=$PROOFGENERAL_OPTIONS"
+ echo
+ exit 1
+}
+
+fail()
+{
+ echo "$1" >&2
+ exit 2
+}
+
+
+## process command line
+
+# options
+
+ISABELLE_OPTIONS=""
+START_PG="true"
+GEOMETRY=""
+KEYWORDS=""
+LOGIC="$ISABELLE_LOGIC"
+PROGNAME="xemacs"
+INITFILE="true"
+WINDOWSYSTEM="true"
+XSYMBOL=""
+XSYMBOLSETUP=true
+
+getoptions()
+{
+ OPTIND=1
+ while getopts "I:P:X:g:k:l:m:p:u:w:x:" OPT
+ do
+ case "$OPT" in
+ I)
+ ISAR="$OPTARG"
+ ;;
+ P)
+ START_PG="$OPTARG"
+ ;;
+ X)
+ XSYMBOLSETUP="$OPTARG"
+ ;;
+ g)
+ GEOMETRY="$OPTARG"
+ ;;
+ k)
+ KEYWORDS="$OPTARG"
+ ;;
+ l)
+ LOGIC="$OPTARG"
+ ;;
+ m)
+ if [ -z "$ISABELLE_OPTIONS" ]; then
+ ISABELLE_OPTIONS="-m $OPTARG"
+ else
+ ISABELLE_OPTIONS="$ISABELLE_OPTIONS -m $OPTARG"
+ fi
+ ;;
+ p)
+ PROGNAME="$OPTARG"
+ ;;
+ u)
+ INITFILE="$OPTARG"
+ ;;
+ w)
+ WINDOWSYSTEM="$OPTARG"
+ ;;
+ x)
+ XSYMBOL="$OPTARG"
+ ;;
+ \?)
+ usage
+ ;;
+ esac
+ done
+}
+
+getoptions $PROOFGENERAL_OPTIONS
+
+getoptions "$@"
+shift $(($OPTIND - 1))
+
+if [ "$ISAR" = true ]; then
+ KIND=isar
+ DEFAULT_FILES="Scratch.thy"
+else
+ KIND=isa
+ DEFAULT_FILES="Scratch.thy Scratch.ML"
+fi
+
+
+# args
+
+if [ "$#" -eq 0 ]; then
+ FILES="$DEFAULT_FILES"
+else
+ FILES=""
+ while [ "$#" -gt 0 ]; do
+ FILES="$FILES '$1'"
+ shift
+ done
+fi
+
+
+## smart X11 font installation
+
+function checkfonts ()
+{
+ XLSFONTS=$(xlsfonts -fn "-xsymb-xsymb0-*" 2>&1) || return 1
+
+ case "$XLSFONTS" in
+ xlsfonts:*)
+ return 1
+ ;;
+ esac
+
+ return 0
+}
+
+function installfonts ()
+{
+ checkfonts "$XSYMBOL_PATTERN" || eval $XSYMBOL_INSTALLFONTS
+}
+
+
+## main
+
+if [ "$START_PG" = false ]; then
+
+ [ "$ISAR" = true ] && ISABELLE_OPTIONS="$ISABELLE_OPTIONS -I"
+ exec "$ISABELLE" $ISABELLE_OPTIONS "$LOGIC"
+
+else
+
+ ARGS=""
+
+ [ -n "$GEOMETRY" ] && ARGS="$ARGS -geometry '$GEOMETRY'"
+
+ [ "$INITFILE" = false ] && ARGS="$ARGS -q"
+
+ if [ "$WINDOWSYSTEM" = true -a -n "$DISPLAY" ]; then
+ ARGS="$ARGS -T Isabelle"
+ [ -n "$XSYMBOL_INSTALLFONTS" -a "$XSYMBOLSETUP" = true ] && installfonts
+ else
+ ARGS="$ARGS -nw"
+ XSYMBOL=false
+ fi
+
+ [ ! "$XSYMBOLSETUP" = true ] && XSYMBOL_HOME=""
+
+
+ ARGS="$ARGS -l '$SUPER/isa/interface-setup.el'"
+
+ if [ -n "$KEYWORDS" ]; then
+ if [ -f "$ISABELLE_HOME_USER/etc/isar-keywords-$KEYWORDS.el" ]; then
+ ARGS="$ARGS -l '$ISABELLE_HOME_USER/etc/isar-keywords-$KEYWORDS.el'"
+ elif [ -f "$ISABELLE_HOME/etc/isar-keywords-$KEYWORDS.el" ]; then
+ ARGS="$ARGS -l '$ISABELLE_HOME/etc/isar-keywords-$KEYWORDS.el'"
+ else
+ fail "No isar-keywords file for '$KEYWORDS'"
+ fi
+ elif [ -f "$ISABELLE_HOME_USER/etc/isar-keywords.el" ]; then
+ ARGS="$ARGS -l '$ISABELLE_HOME_USER/etc/isar-keywords.el'"
+ elif [ -f "$ISABELLE_HOME/etc/isar-keywords.el" ]; then
+ ARGS="$ARGS -l '$ISABELLE_HOME/etc/isar-keywords.el'"
+ fi
+
+ for FILE in "$ISABELLE_HOME/etc/proofgeneral-settings.el" \
+ "$ISABELLE_HOME_USER/etc/proofgeneral-settings.el"
+ do
+ [ -f "$FILE" ] && ARGS="$ARGS -l '$FILE'"
+ done
+
+ case "$LOGIC" in
+ /*)
+ ;;
+ */*)
+ LOGIC="$PWD/$LOGIC"
+ ;;
+ esac
+
+ PROOFGENERAL_HOME="$SUPER"
+ PROOFGENERAL_ASSISTANTS="$KIND"
+ PROOFGENERAL_LOGIC="$LOGIC"
+ PROOFGENERAL_XSYMBOL="$XSYMBOL"
+
+ export PROOFGENERAL_HOME PROOFGENERAL_ASSISTANTS PROOFGENERAL_LOGIC PROOFGENERAL_XSYMBOL
+ export ISABELLE_OPTIONS
+
+ eval exec "$PROGNAME" "$ARGS" "$FILES"
+
+fi
diff --git a/isa/interface-setup.el b/isa/interface-setup.el
new file mode 100644
index 00000000..2ed504cb
--- /dev/null
+++ b/isa/interface-setup.el
@@ -0,0 +1,48 @@
+;; interface-setup.el Interface wrapper for Isabelle Proof General
+;;
+;; This file 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, or (at your option)
+;; any later version.
+;;
+;; Author: Markus Wenzel <wenzelm@in.tum.de>
+;;
+;; $Id$
+;;
+
+;;;
+;;; X-Symbol
+;;;
+
+(if (string-match "XEmacs" emacs-version) ;current X-Symbol works with XEmacs only!
+ (let ((xsymbol-home (getenv "XSYMBOL_HOME"))
+ (xsymbol (getenv "PROOFGENERAL_XSYMBOL"))
+ (enable-var
+ (if (equal (getenv "PROOFGENERAL_ASSISTANTS") "isa")
+ 'isa-x-symbol-enable 'isar-x-symbol-enable)))
+ ;; setup the x-symbol package, if not already present
+ (if (and xsymbol-home
+ (not (equal xsymbol-home ""))
+ (not (fboundp 'x-symbol-initialize))
+ (not (get 'x-symbol 'x-symbol-initialized)))
+ (progn
+ (load (expand-file-name "lisp/x-symbol/auto-autoloads" xsymbol-home))
+ (push (expand-file-name "lisp/x-symbol" xsymbol-home) load-path)
+ (if (boundp 'data-directory-list)
+ (push (expand-file-name "etc/" xsymbol-home) data-directory-list))
+ (if (boundp 'Info-directory-list)
+ (push (expand-file-name "info/" xsymbol-home) Info-directory-list))
+ (if (not (boundp 'x-symbol-image-converter)) ;avoid confusing warning message
+ (customize-set-variable 'x-symbol-image-converter nil))
+ (x-symbol-initialize)))
+ ;; tell Proof General about -x option
+ (if (and xsymbol (not (equal xsymbol "")))
+ (customize-set-variable enable-var (equal xsymbol "true")))))
+
+
+;;
+;; Proof General
+;;
+
+(if (not (featurep 'proof-site))
+ (load (concat (getenv "PROOFGENERAL_HOME") "/generic/proof-site.el")))
diff --git a/isa/isa-syntax.el b/isa/isa-syntax.el
new file mode 100644
index 00000000..d8697cb8
--- /dev/null
+++ b/isa/isa-syntax.el
@@ -0,0 +1,304 @@
+;; isa-syntax.el Syntax expressions for Isabelle
+;; Copyright (C) 1994-1998 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;;
+(require 'proof-syntax)
+
+;; character syntax
+
+(defun isa-init-syntax-table ()
+ "Set appropriate values for syntax table in current buffer."
+ (modify-syntax-entry ?\$ ".")
+ (modify-syntax-entry ?\/ ".")
+ (modify-syntax-entry ?\\ ".")
+ (modify-syntax-entry ?+ ".")
+ (modify-syntax-entry ?- ".")
+ (modify-syntax-entry ?= ".")
+ (modify-syntax-entry ?% ".")
+ (modify-syntax-entry ?< ".")
+ (modify-syntax-entry ?> ".")
+ (modify-syntax-entry ?\& ".")
+ (modify-syntax-entry ?. "w")
+ (modify-syntax-entry ?_ "w")
+ (modify-syntax-entry ?\' "w")
+ (modify-syntax-entry ?\| ".")
+ (modify-syntax-entry ?\* ". 23")
+ (modify-syntax-entry ?\( "()1")
+ (modify-syntax-entry ?\) ")(4"))
+
+(defun isa-init-output-syntax-table ()
+ "Set appropriate values for syntax table for Isabelle output."
+ (isa-init-syntax-table)
+ ;; ignore strings so font-locking works
+ ;; inside them
+ (modify-syntax-entry ?\" " ")
+ (modify-syntax-entry ?\* ".")
+ (modify-syntax-entry ?\( "()")
+ (modify-syntax-entry ?\) ")(")
+ (modify-syntax-entry ?\{ "(}")
+ (modify-syntax-entry ?\} "){"))
+
+;;
+;; Syntax for font-lock and other features
+;;
+
+;; Note: this command-keyword recognition of the proof script isn't
+;; good enough for Isabelle, since we can have arbitrary ML code
+;; around.
+;; Alternatives:
+;; 1) propose a restricted language consisting of the interactive
+;; commands. Or try Markus Wenzel's Isar proof language!
+;; 2) add hooks from Isabelle to say "I've just seen a goal command"
+;; or "I've just seen a tactic". This would allow more accurate
+;; counting of undos. We could even approximate this without hooks,
+;; by examining the proof state output carefully.
+;;
+
+;; FIXME da: here are some examples of input failures I've
+;; found in real proofs:
+;;
+;; val lemma = result() RS spec RS mp;
+;;
+;; Not recognized as a qed command, and therefore assumed
+;; to be an undoable tactic command.
+;;
+
+(defgroup isa-syntax nil
+ "Customization of Isabelle syntax for proof mode"
+ :group 'isa-settings)
+
+(defcustom isa-keywords-decl
+ '("val" "fun" "datatype" "signature" "structure")
+ "Isabelle keywords for declarations. Includes ML keywords to fontify ML files."
+ :group 'isa-syntax
+ :type '(repeat string))
+
+(defcustom isa-keywords-defn
+ '("bind_thm" "bind_thms")
+ "Isabelle keywords for definitions"
+ :group 'isa-syntax
+ :type '(repeat string))
+
+;; isa-keywords-goal is used to manage undo actions
+(defcustom isa-keywords-goal
+ '("Goal" "Goalw" "goal" "goalw" "goalw_cterm" "atomic_goal" "atomic_goalw")
+ "Isabelle commands to begin an interactive proof"
+ :group 'isa-syntax
+ :type '(repeat string))
+
+(defcustom isa-keywords-save
+ '("qed" "qed_spec_mp" "no_qed")
+ ;; Related commands, but having different types, so PG
+ ;; won't bother support them:
+ ;; "uresult" "bind_thm" "store_thm"
+ "Isabelle commands to extract the proved theorem"
+ :group 'isa-syntax
+ :type '(repeat string))
+
+(defcustom isa-keywords-commands
+ '("by" "byev"
+ "ba" "br" "be" "bd" "brs" "bes" "bds"
+ "chop" "choplev" "back" "undo" "ProofGeneral.repeat_undo"
+ "fa" "fr" "fe" "fd" "frs" "fes" "fds"
+ "bw" "bws" "ren"
+ ;; batch proofs
+ "prove_goal" "qed_goal" "prove_goalw" "qed_goalw" "prove_goalw_cterm")
+ "Isabelle command keywords"
+ :group 'isa-syntax
+ :type '(repeat string))
+
+;; NB: this means that any adjustments above by customize will
+;; only have effect in next session.
+(defconst isa-keywords
+ (append isa-keywords-goal isa-keywords-save isa-keywords-decl
+ isa-keywords-defn isa-keywords-commands)
+ "All keywords in a Isabelle script")
+
+(defconst isa-keywords-proof-commands
+ (append isa-keywords-goal isa-keywords-save isa-keywords-commands)
+ "Actual Isabelle proof script commands")
+
+;; The most common Isabelle/Pure tacticals
+(defconst isa-tacticals
+ '("ALLGOALS" "DETERM" "EVERY" "EVERY'" "FIRST" "FIRST'" "FIRSTGOAL"
+ "ORELSE" "ORELSE'" "REPEAT" "REPEAT" "REPEAT1" "REPEAT_FIRST"
+ "REPEAT_SOME" "SELECT_GOAL" "SOMEGOAL" "THEN" "THEN'" "TRY" "TRYALL"))
+
+
+;; ----- regular expressions
+
+(defconst isa-id "\\([A-Za-z][A-Za-z0-9'_]*\\)")
+(defconst isa-idx (concat isa-id "\\(\\.[0-9]+\\)?"))
+
+(defconst isa-ids (proof-ids isa-id "[ \t]*")
+ "Matches a sequence of identifiers separated by whitespace.")
+
+(defconst isa-string "\"\\(\\([^\\\"]\\|\\\\\"\\)*\\)\"")
+
+(defcustom isa-save-command-regexp
+ (proof-regexp-alt
+ (proof-anchor-regexp (proof-ids-to-regexp isa-keywords-save))
+ ;; match val ... = result blah
+ (proof-anchor-regexp
+ (concat
+ (proof-ids-to-regexp '("val")) ".+=\\s-*"
+ "\\(" (proof-ids-to-regexp isa-keywords-save) "\\)")))
+ "Regular expression used to match a qed/result."
+ :type 'regexp
+ :group 'isabelle-config)
+
+
+;; CHECKED
+(defconst isa-save-with-hole-regexp
+ (concat "\\(" (proof-ids-to-regexp isa-keywords-save)
+ "\\)\\s-+\"\\(" isa-id "\\)\"\\s-*;"))
+
+(defcustom isa-goal-command-regexp
+ (proof-regexp-alt
+ (proof-anchor-regexp (proof-ids-to-regexp isa-keywords-goal))
+ ;; match val ... = goal blah
+ (proof-anchor-regexp
+ (concat
+ (proof-ids-to-regexp '("val")) ".+=\\s-*"
+ "\\(" (proof-ids-to-regexp isa-keywords-goal) "\\)")))
+ "Regular expression used to match a goal."
+ :type 'regexp
+ :group 'isabelle-config)
+
+(defconst isa-string-regexp
+ (concat "\\s-*\"\\(" isa-id "\\)\"\\s-*")
+ "Regexp matching ML strings, with contents bracketed.")
+
+(defconst isa-goal-with-hole-regexp
+ (concat "\\("
+ ;; Don't bother with "val xxx = prove_goal blah".
+ (proof-ids-to-regexp '("qed_goal"))
+ "\\)" isa-string-regexp)
+ "Regexp matching goal commands in Isabelle which name a theorem")
+
+
+(defconst isa-proof-command-regexp
+ (proof-ids-to-regexp isa-keywords-proof-commands)
+ "Regexp to match proof commands, with no extra output (apart from proof state)")
+
+
+;; ----- Isabelle inner syntax hilite
+
+(defface isabelle-class-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "red"))
+ (((type x) (class color) (background dark))
+ (:foreground "red3"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defface isabelle-tfree-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "purple"))
+ (((type x) (class color) (background dark))
+ (:foreground "purple3"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defface isabelle-tvar-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "purple"))
+ (((type x) (class color) (background dark))
+ (:foreground "purple3"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defface isabelle-free-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "blue"))
+ (((type x) (class color) (background dark))
+ (:foreground "blue3"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defface isabelle-bound-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "green4"))
+ (((type x) (class color) (background dark))
+ (:foreground "green"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defface isabelle-var-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "darkblue"))
+ (((type x) (class color) (background dark))
+ (:foreground "blue3"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defconst isabelle-class-name-face 'isabelle-class-name-face)
+(defconst isabelle-tfree-name-face 'isabelle-tfree-name-face)
+(defconst isabelle-tvar-name-face 'isabelle-tvar-name-face)
+(defconst isabelle-free-name-face 'isabelle-free-name-face)
+(defconst isabelle-bound-name-face 'isabelle-bound-name-face)
+(defconst isabelle-var-name-face 'isabelle-var-name-face)
+
+
+(defvar isa-font-lock-keywords-1
+ (list
+ (cons (proof-ids-to-regexp isa-keywords) 'font-lock-keyword-face)
+ (cons (proof-ids-to-regexp isa-tacticals) 'proof-tacticals-name-face)
+ (list isa-goal-with-hole-regexp 2 'font-lock-function-name-face)
+ (list isa-save-with-hole-regexp 2 'font-lock-function-name-face)))
+
+(defvar isa-output-font-lock-keywords-1
+ (list
+ (cons (concat "\351" isa-id "\350") 'isabelle-class-name-face)
+ (cons (concat "\352'" isa-id "\350") 'isabelle-tfree-name-face)
+ (cons (concat "\353\\?'" isa-idx "\350") 'isabelle-tvar-name-face)
+ (cons (concat "\354" isa-id "\350") 'isabelle-free-name-face)
+ (cons (concat "\355" isa-id "\350") 'isabelle-bound-name-face)
+ (cons (concat "\356\\?" isa-idx "\350") 'isabelle-var-name-face)
+ (cons (concat "\357\\?" isa-idx "\350") 'proof-declaration-name-face)
+ )
+ "*Font-lock table for Isabelle terms.")
+
+(defvar isa-goals-font-lock-keywords
+ (append
+ (list
+ "^Level [0-9].*"
+ "^No subgoals!$"
+ "^Variables:$"
+ "^Constants:$"
+ "\\s-*[0-9][0-9]?\\. ")
+ isa-output-font-lock-keywords-1)
+ "*Font-lock table for Isabelle goals output.")
+
+
+;; ----- indentation
+
+(defconst isa-indent-any-regexp
+ (proof-regexp-alt (proof-ids-to-regexp isa-keywords) "\\s(" "\\s)"))
+(defconst isa-indent-inner-regexp
+ (proof-regexp-alt "\\s(" "\\s)"))
+(defconst isa-indent-enclose-regexp
+ (proof-ids-to-regexp isa-keywords-save))
+(defconst isa-indent-open-regexp
+ (proof-regexp-alt (proof-ids-to-regexp isa-keywords-goal) "\\s("))
+(defconst isa-indent-close-regexp
+ (proof-regexp-alt (proof-ids-to-regexp isa-keywords-save) "\\s)"))
+
+(provide 'isa-syntax)
diff --git a/isa/isa.el b/isa/isa.el
new file mode 100644
index 00000000..245c17d0
--- /dev/null
+++ b/isa/isa.el
@@ -0,0 +1,765 @@
+;; isa-mode.el Emacs support for Isabelle proof assistant
+;; Copyright (C) 1993-2000 LFCS Edinburgh, David Aspinall.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Contact: isa@proofgeneral.org
+;;
+;; $Id$
+;;
+;; -----------------------------------------------------------------
+;;
+;; This file and the rest of Isabelle Proof General contain code taken
+;; from David Aspinall's Isamode system, a personal project undertaken
+;; 1993-1999 as a contribution to the Isabelle community.
+;;
+;; -----------------------------------------------------------------
+
+
+;; Add Isabelle image onto splash screen
+;;
+;; (don't use customize-set-variable since it will be saved with options!)
+(setq proof-splash-extensions
+ '(list
+ nil
+ (proof-splash-display-image "isabelle_transparent" t)))
+
+;; In case Isa mode was invoked directly or by -*- isa -*- at
+;; the start of the file, ensure that Isa mode is used from now
+;; on for .thy and .ML files.
+;; FIXME: be less messy with auto-mode-alist here (remove dups)
+(setq auto-mode-alist
+ (cons '("\\.ML$\\|\\.thy$" . isa-mode) auto-mode-alist))
+
+(require 'proof)
+(require 'isa-syntax)
+(require 'isabelle-system)
+
+;;;
+;;; ======== User settings for Isabelle ========
+;;;
+
+;;; proof-site provides us with the cusomization groups
+;;;
+;;; 'isabelle - User options for Isabelle Proof General
+;;; 'isabelle-config - Configuration of Isabelle Proof General
+;;; (constants, but may be nice to tweak)
+
+
+;;;
+;;; ======== Configuration of generic modes ========
+;;;
+
+(defcustom isa-outline-regexp
+ (proof-ids-to-regexp '("goal" "Goal" "prove_goal"))
+ "Outline regexp for Isabelle ML files"
+ :type 'regexp
+ :group 'isabelle-config)
+
+;;; End of a command needs parsing to find, so this is approximate.
+(defcustom isa-outline-heading-end-regexp ";[ \t\n]*"
+ "Outline heading end regexp for Isabelle ML files."
+ :type 'regexp
+ :group 'isabelle-config)
+
+(defvar isa-shell-outline-regexp "\370[ \t]*\\([0-9]+\\)\\.")
+(defvar isa-shell-outline-heading-end-regexp "$")
+
+
+
+
+(defun isa-mode-config-set-variables ()
+ "Configure generic proof scripting/thy mode variables for Isabelle.
+Settings here are the ones which are needed for both shell mode
+and script mode."
+ (setq
+ proof-assistant-home-page isabelle-web-page
+ proof-mode-for-script 'isa-proofscript-mode
+ ;; proof script syntax
+ proof-terminal-char ?\; ; ends a proof
+ proof-comment-start "(*" ; comment in a proof
+ proof-comment-end "*)" ;
+ ;; Next few used for func-menu and recognizing goal..save regions in
+ ;; script buffer.
+ proof-save-command-regexp isa-save-command-regexp
+ proof-goal-command-regexp isa-goal-command-regexp
+ proof-goal-with-hole-regexp isa-goal-with-hole-regexp
+ proof-save-with-hole-regexp isa-save-with-hole-regexp
+ ;; Unfortunately the default value of proof-script-next-entity-regexps
+ ;; is no good, because goals with holes in Isabelle are batch
+ ;; commands, and not terminated by saves. So we omit the forward
+ ;; search from the default value.
+ proof-script-next-entity-regexps
+ (list (proof-regexp-alt
+ isa-goal-with-hole-regexp
+ isa-save-with-hole-regexp)
+ (list isa-goal-with-hole-regexp 2)
+ (list isa-save-with-hole-regexp 2
+ 'backward isa-goal-command-regexp))
+
+ proof-indent-enclose-offset (- proof-indent)
+ proof-indent-open-offset 0
+ proof-indent-close-offset 0
+ proof-indent-any-regexp isa-indent-any-regexp
+ proof-indent-inner-regexp isa-indent-inner-regexp
+ proof-indent-enclose-regexp isa-indent-enclose-regexp
+ proof-indent-open-regexp isa-indent-open-regexp
+ proof-indent-close-regexp isa-indent-close-regexp
+
+ ;; proof engine commands
+ proof-showproof-command "pr();"
+ proof-goal-command "Goal \"%s\";"
+ proof-save-command "qed \"%s\";"
+ proof-context-command "ProofGeneral.show_context();"
+ proof-info-command "ProofGeneral.help();"
+ proof-kill-goal-command "ProofGeneral.kill_goal();"
+ proof-find-theorems-command "ProofGeneral.thms_containing (space_explode \",\" \"%s\");"
+ proof-shell-start-silent-cmd "Goals.disable_pr();"
+ proof-shell-stop-silent-cmd "Goals.enable_pr();"
+ ;; command hooks
+ proof-goal-command-p 'isa-goal-command-p
+ proof-count-undos-fn 'isa-count-undos
+ proof-find-and-forget-fn 'isa-find-and-forget
+ proof-state-preserving-p 'isa-state-preserving-p
+
+ ;; close goal..save regions eagerly
+ proof-completed-proof-behaviour 'closeany
+
+ proof-shell-compute-new-files-list 'isa-shell-compute-new-files-list
+ proof-shell-inform-file-processed-cmd
+ "ProofGeneral.inform_file_processed \"%s\";"
+ proof-shell-inform-file-retracted-cmd
+ "ProofGeneral.inform_file_retracted \"%s\";"
+
+ ;; Parsing error messages. Bit tricky to allow for
+ ;; multitude of possible error formats Isabelle spits out.
+ ;; Ideally we shouldn't bother parsing errors that appear
+ ;; in the temporary ML files generated while reading
+ ;; theories, but unfortunately the user sometimes needs to
+ ;; examine them to understand a strange problem...
+ proof-shell-next-error-regexp
+ "\\(error on \\|Error: in '[^']+', \\)line \\([0-9]+\\)\\|The error(s) above occurred"
+ proof-shell-next-error-filename-regexp
+ "\\(Loading theory \"\\|Error: in '\\)\\([^\"']+\\)[\"']"
+ proof-shell-next-error-extract-filename
+ "%s.thy"))
+
+
+
+(defun isa-shell-mode-config-set-variables ()
+ "Configure generic proof shell mode variables for Isabelle."
+ (setq
+ proof-shell-first-special-char ?\350
+
+ proof-shell-wakeup-char ?\372
+ proof-shell-annotated-prompt-regexp "\\(val it = () : unit\n\\)?> \372"
+
+ ;; This pattern is just for comint
+ proof-shell-prompt-pattern "^2?[ML-=#>]>? \372?"
+
+ ;; for issuing command, not used to track cwd in any way.
+ proof-shell-cd-cmd "ThyLoad.add_path \"%s\";"
+
+ ;; Escapes for filenames inside ML strings.
+ ;; We also make a hack for Isabelle, by switching from backslashes
+ ;; to forward slashes if it looks like we're running on Windows.
+ proof-shell-filename-escapes
+ (if (fboundp 'win32-long-file-name) ; rough test for XEmacs on win32
+ ;; Patterns to unixfy names. Avoids a deliberate bomb in Isabelle which
+ ;; barfs at paths with these characters in them.
+ '(("\\\\" . "/") ("\"" . "\\\"") ("^[a-zA-Z]:" . ""))
+ ;; Normal case: quotation for backslash, quote mark.
+ '(("\\\\" . "\\\\") ("\"" . "\\\"")))
+
+ proof-shell-interrupt-regexp "Interrupt"
+ proof-shell-error-regexp "^\364\\*\\*\\*\\|^.*Error:\\|^uncaught exception \\|^Exception-\\( \\|$\\)"
+
+ ;; matches names of assumptions
+ proof-shell-assumption-regexp isa-id
+ ;; matches subgoal name
+ ;; FIXME: not used yet. In future will be used for
+ ;; proof-by-pointing like features.
+ ;; proof-shell-goal-regexp "\370[ \t]*\\([0-9]+\\)\\."
+
+ proof-shell-start-goals-regexp "\366"
+ proof-shell-end-goals-regexp "\367"
+ proof-shell-goal-char ?\370
+
+ proof-shell-proof-completed-regexp "^No subgoals!"
+
+ ;; initial command configures Isabelle by hacking print functions,
+ ;; restoring settings saved by Proof General, etc.
+
+ ;; FIXME: temporary hack for almost enabling/disabling printing.
+ ;; Also for setting default values.
+ proof-shell-pre-sync-init-cmd "ProofGeneral.init false;"
+ proof-shell-init-cmd (proof-assistant-settings-cmd)
+
+ proof-shell-restart-cmd "ProofGeneral.isa_restart();"
+ proof-shell-quit-cmd "quit();"
+
+ ;; NB: the settings below will only recognize tracing output in
+ ;; Isabelle 2001.
+ proof-shell-eager-annotation-start "\360\\|\362"
+ proof-shell-eager-annotation-start-length 1
+ proof-shell-eager-annotation-end "\361\\|\363"
+ ;; see isa-pre-shell-start for proof-shell-trace-output-regexp
+
+ ;; Some messages delimited by eager annotations
+ proof-shell-clear-response-regexp "Proof General, please clear the response buffer."
+ proof-shell-clear-goals-regexp "Proof General, please clear the goals buffer."
+ proof-shell-set-elisp-variable-regexp "Proof General, please set the variable \\([^ ]+\\) to: #\\([^#]+\\)#\\."
+ proof-shell-theorem-dependency-list-regexp "Proof General, the theorem dependencies are: \"\\([^\"]*\\)\""
+
+ ;; Dirty hack to allow font-locking for output based on hidden
+ ;; annotations, see isa-output-font-lock-keywords-1
+ proof-shell-leave-annotations-in-output t
+
+ ;; === ANNOTATIONS === ones here are broken
+ proof-shell-result-start "\372 Pbp result \373"
+ proof-shell-result-end "\372 End Pbp result \373"
+ proof-analyse-using-stack t
+ proof-shell-start-char ?\372
+ proof-shell-end-char ?\373
+ proof-shell-field-char ?\374
+
+ ;; === MULTIPLE FILE HANDLING ===
+ proof-shell-process-file
+ (cons
+ ;; Theory loader output and verbose update() output.
+ "Proof General, this file is loaded: \"\\(.*\\)\""
+ (lambda (str)
+ (match-string 1 str)))
+ ;; This is the output returned by a special command to
+ ;; query Isabelle for outdated files.
+ ;; proof-shell-clear-included-files-regexp
+ ;; "Proof General, please clear your record of loaded files."
+ proof-shell-retract-files-regexp
+ "Proof General, you can unlock the file \"\\(.*\\)\""
+ proof-shell-compute-new-files-list 'isa-shell-compute-new-files-list
+ )
+ (add-hook 'proof-activate-scripting-hook 'isa-shell-update-thy 'append)
+ )
+
+
+;;;
+;;; Theory loader operations
+;;;
+
+;; Experiments for background non-blocking loading of theory: this is
+;; quite difficult, actually: we need to set a callback from
+;; proof-done-invisible to take the final step in switching on
+;; scripting. We may be able to pass the hook argument into the
+;; action list using the "span" argument which means nothing for
+;; invisible command usually.
+
+; attempt to trap C-g. Needs more work so revert to previous
+;(defun isa-update-thy-only (file try wait)
+; "Tell Isabelle to update current buffer's theory, and all ancestors."
+; ;; Trap interrupts from C-g during the update
+; (condition-case err
+; (proof-shell-invisible-command
+; (format "ProofGeneral.%supdate_thy_only \"%s\";"
+; (if try "try_" "") (file-name-sans-extension file))
+; wait)
+; (t (message "Isabelle Proof General: error or interrupt during update theory...")
+; (if proof-shell-busy
+; (proof-interrupt-process))
+; (sit-for 1)
+; (proof-deactivate-scripting)
+; (if (cdr err) ;; quit is just (quit).
+; (error (cdr err))))))
+
+(defun isa-update-thy-only (file try wait)
+ "Tell Isabelle to update current buffer's theory, and all ancestors."
+ ;; First make sure we're in the right directory to take care of
+ ;; relative "files" paths inside theory file.
+ (proof-cd-sync)
+ (proof-shell-invisible-command
+ (proof-format-filename
+ ;; %r parameter means relative (don't expand) path
+ (format "ProofGeneral.%supdate_thy_only \"%%r\";" (if try "try_" ""))
+ (file-name-nondirectory (file-name-sans-extension file)))
+ wait))
+
+(defun isa-shell-update-thy ()
+ "Possibly issue update_thy_only command to Isabelle.
+If the current buffer has an empty locked region, the interface is
+about to send commands from it to Isabelle. This function sends
+a command to read any theory file corresponding to the current ML file.
+This is a hook function for proof-activate-scripting-hook."
+ (if (proof-locked-region-empty-p)
+ ;; If we switch to this buffer and it *does* have a locked
+ ;; region, we could check that no updates are needed and
+ ;; unlock the whole buffer in case they were. But that's
+ ;; a bit messy. Instead we assume that things must be
+ ;; up to date, after all, the user wasn't allowed to edit
+ ;; anything that this file depends on, was she?
+ (progn
+ ;; Wait after sending, so that queue is cleared for further
+ ;; commands without giving "proof process busy" error.
+ (isa-update-thy-only buffer-file-name t
+ ;; whether to block or not
+ (if (and (boundp 'activated-interactively)
+ activated-interactively)
+ t ; was nil, but falsely leaves Scripting on!
+ t))
+ ;; Leave the messages from the update around.
+ (setq proof-shell-erase-response-flag nil))))
+
+(defun isa-remove-file (name files cmp-base)
+ (if (not files) nil
+ (let*
+ ((file (car files))
+ (rest (cdr files))
+ (same (if cmp-base (string= name (file-name-nondirectory file))
+ (string= name file))))
+ (if same (isa-remove-file name rest cmp-base)
+ (cons file (isa-remove-file name rest cmp-base))))))
+
+(defun isa-shell-compute-new-files-list (str)
+ "Compute the new list of files read by the proof assistant.
+This is called when Proof General spots output matching
+proof-shell-retract-files-regexp."
+ (let*
+ ((name (match-string 1 str))
+ (base-name (file-name-nondirectory name)))
+ (if (string= name base-name)
+ (isa-remove-file name proof-included-files-list t)
+ (isa-remove-file (file-truename name) proof-included-files-list nil))))
+
+
+;;
+;; Define the derived modes
+;;
+(eval-and-compile
+(define-derived-mode isa-shell-mode proof-shell-mode
+ "Isabelle shell" nil
+ (isa-shell-mode-config)))
+
+(eval-and-compile
+(define-derived-mode isa-response-mode proof-response-mode
+ "Isabelle response" nil
+ (isa-response-mode-config)))
+
+(eval-and-compile ; to define vars for byte comp.
+(define-derived-mode isa-goals-mode proof-goals-mode
+ "Isabelle goals" nil
+ (isa-goals-mode-config)))
+
+(eval-and-compile ; to define vars for byte comp.
+(define-derived-mode isa-proofscript-mode proof-mode
+ "Isabelle script" nil
+ (isa-mode-config)))
+
+
+;;
+;; Automatically selecting theory mode or Proof General script mode.
+;;
+
+(defun isa-mode ()
+ "Mode for Isabelle buffers: either isa-proofscript-mode or thy-mode.
+Files with extension .thy will be in thy-mode, otherwise we choose
+isa-proofscript-mode."
+ (interactive)
+ (cond
+ (;; Theory files only if they have the right extension
+ (and (buffer-file-name)
+ (proof-string-match "\\.thy$" (buffer-file-name)))
+
+ ;; Enter theory mode, but first configure settings for proof
+ ;; script if they haven't been done already. This is a hack,
+ ;; needed because Proof General assumes that the script mode must
+ ;; have been configured before shell mode can be triggered, which
+ ;; isn't true for Isabelle.
+ ;; (proof-config-done-related and proof-shell-mode refer to
+ ;; the troublesome settings in question)
+ ;; 3.3 fix: add require proof-script since context menus are
+ ;; now added for response/goals buffer, which requires proof mode.
+ (unless proof-terminal-char
+ (require 'proof-script)
+ (proof-menu-define-specific)
+ (isa-mode-config-set-variables))
+
+ (thy-mode)
+
+ ;; related mode configuration including locking buffer,
+ ;; fontification, etc.
+ (proof-config-done-related)
+
+ ;; Hack for splash screen
+ (if (and (boundp 'proof-mode-hook)
+ (memq 'proof-splash-timeout-waiter proof-mode-hook))
+ (proof-splash-timeout-waiter)
+ ;; Otherwise, user may need welcoming.
+ (proof-splash-message)))
+ (t
+ (isa-proofscript-mode))))
+
+(eval-after-load
+ "thy-mode"
+ ;; Extend theory mode keymap
+ '(let ((map thy-mode-map))
+(define-key map "\C-c\C-b" 'isa-process-thy-file)
+(define-key map "\C-c\C-r" 'isa-retract-thy-file)
+(proof-define-keys map proof-universal-keys)))
+
+;; FIXME: could test that the buffer isn't already locked.
+(defun isa-process-thy-file (file)
+ "Process the theory file FILE. If interactive, use buffer-file-name."
+ (interactive (list buffer-file-name))
+ (save-some-buffers)
+ (isa-update-thy-only file nil nil))
+
+(defcustom isa-retract-thy-file-command "ThyInfo.remove_thy \"%r\";"
+ "Sent to Isabelle to forget theory file and descendants.
+Resulting output from Isabelle will be parsed by Proof General."
+ :type 'string
+ :group 'isabelle-config)
+
+(defun isa-retract-thy-file (file)
+ "Retract the theory file FILE. If interactive, use buffer-file-name.
+To prevent inconsistencies, scripting is deactivated before doing this.
+So if scripting is active in an ML file which is not completely processed,
+you will be asked to retract the file or process the remainder of it."
+ (interactive (list buffer-file-name))
+ (proof-deactivate-scripting)
+ (proof-shell-invisible-command
+ (proof-format-filename isa-retract-thy-file-command
+ (file-name-nondirectory
+ (file-name-sans-extension file)))))
+
+
+;; Next bits taken from isa-load.el
+;; isa-load.el,v 3.8 1998/09/01
+
+(defgroup thy nil
+ "Customization of Isamode's theory editing mode"
+ ;; :link '(info-link "(Isamode)Theory Files")
+ :load 'thy-mode
+ :group 'isabelle)
+
+(autoload 'thy-mode "thy-mode"
+ "Major mode for Isabelle theory files" t nil)
+
+(autoload 'thy-find-other-file "thy-mode"
+ "Find associated .ML or .thy file." t nil)
+
+(defun isa-splice-separator (sep strings)
+ (let (stringsep)
+ (while strings
+ (setq stringsep (concat stringsep (car strings)))
+ (setq strings (cdr strings))
+ (if strings (setq stringsep
+ (concat stringsep sep))))
+ stringsep))
+
+(defun isa-file-name-cons-extension (name)
+ "Return cons cell of NAME without final extension and extension"
+ (if (string-match "\\.[^\\.]+$" name)
+ (cons (substring name 0 (match-beginning 0))
+ (substring name (match-beginning 0)))
+ (cons name "")))
+
+(defun isa-format (alist string)
+ "Format a string by matching regexps in ALIST against STRING"
+ (while alist
+ (while (string-match (car (car alist)) string)
+ (setq string
+ (concat (substring string 0 (match-beginning 0))
+ (cdr (car alist))
+ (substring string (match-end 0)))))
+ (setq alist (cdr alist)))
+ string)
+
+;; Key to switch to theory mode
+(define-key isa-proofscript-mode-map
+ [(control c) (control o)] 'thy-find-other-file)
+
+
+
+
+;;
+;; Code that's Isabelle specific
+;;
+
+(defcustom isa-not-undoable-commands-regexp
+ (proof-ids-to-regexp '("undo"))
+ "Regular expression matching commands which are *not* undoable."
+ :type 'regexp
+ :group 'isabelle-config)
+
+;; This next function is the important one for undo operations.
+(defun isa-count-undos (span)
+ "Count number of undos in a span, return the command needed to undo that far."
+ (let
+ ((case-fold-search nil)
+ (ct 0) str i)
+ (if (and span (prev-span span 'type)
+ (not (eq (span-property (prev-span span 'type) 'type) 'comment))
+ (isa-goal-command-p
+ (span-property (prev-span span 'type) 'cmd)))
+ (concat "choplev 0" proof-terminal-string)
+ (while span
+ (setq str (span-property span 'cmd))
+ (cond ((eq (span-property span 'type) 'vanilla)
+ (or (proof-string-match isa-not-undoable-commands-regexp str)
+ (setq ct (+ 1 ct))))
+ ((eq (span-property span 'type) 'pbp)
+ ;; this case probably redundant for Isabelle, unless we
+ ;; think of some nice ways of matching non-undoable cmds.
+ (cond ((not (proof-string-match
+ isa-not-undoable-commands-regexp str))
+ (setq i 0)
+ (while (< i (length str))
+ (if (= (aref str i) proof-terminal-char)
+ (setq ct (+ 1 ct)))
+ (setq i (+ 1 i))))
+ (t nil))))
+ (setq span (next-span span 'type)))
+ (concat "ProofGeneral.repeat_undo "
+ (int-to-string ct) proof-terminal-string))))
+
+(defun isa-goal-command-p (str)
+ "Decide whether argument is a goal or not"
+ (proof-string-match isa-goal-command-regexp str)) ; this regexp defined in isa-syntax.el
+
+;; Isabelle has no concept of a Linear context, so forgetting back
+;; to the declaration of a particular something makes no real
+;; sense. Perhaps in the future there will be functions to remove
+;; theorems from theories, but even then all we could do is
+;; forget particular theorems one by one. So we ought to search
+;; backwards in isa-find-and-forget, rather than forwards as
+;; the code from the type theory provers does.
+
+;; MMW: this version even does nothing at all
+(defun isa-find-and-forget (span)
+ proof-no-command)
+
+(defun isa-state-preserving-p (cmd)
+ "Non-nil if command preserves the proofstate."
+ (not (proof-string-match isa-not-undoable-commands-regexp cmd)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Isa shell startup and exit hooks ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun isa-pre-shell-start ()
+ (setq proof-prog-name (isabelle-command-line))
+ (setq proof-mode-for-shell 'isa-shell-mode)
+ (setq proof-mode-for-goals 'isa-goals-mode)
+ (setq proof-mode-for-response 'isa-response-mode)
+ (setq proof-shell-trace-output-regexp "\375"))
+
+(defun isa-mode-config ()
+ (isa-mode-config-set-variables)
+ (isa-init-syntax-table)
+ (setq font-lock-keywords isa-font-lock-keywords-1)
+ (proof-config-done)
+ ;; outline
+ ;; FIXME: do we need to call make-local-variable here?
+ (make-local-variable 'outline-regexp)
+ (setq outline-regexp isa-outline-regexp)
+ (make-local-variable 'outline-heading-end-regexp)
+ (setq outline-heading-end-regexp isa-outline-heading-end-regexp)
+ ;; tags
+ ; (and (boundp 'tag-table-alist)
+ ; (setq tag-table-alist
+ ; (append '(("\\.ML$" . isa-ML-file-tags-table)
+ ; ("\\.thy$" . thy-file-tags-table))
+ ; tag-table-alist)))
+ (setq blink-matching-paren-dont-ignore-comments t))
+
+
+;; These hooks are added on load because proof shells can
+;; be started from .thy (not in scripting mode) or .ML files.
+(add-hook 'proof-pre-shell-start-hook 'isa-pre-shell-start nil t)
+(add-hook 'proof-shell-insert-hook 'isa-preprocessing)
+
+(defun isa-shell-mode-config ()
+ "Configure Proof General proof shell for Isabelle."
+ (isa-init-output-syntax-table)
+ (setq font-lock-keywords isa-output-font-lock-keywords-1)
+ (isa-shell-mode-config-set-variables)
+ (proof-shell-config-done))
+
+(defun isa-response-mode-config ()
+ (setq font-lock-keywords isa-output-font-lock-keywords-1)
+ (isa-init-output-syntax-table)
+ (proof-response-config-done))
+
+(defun isa-goals-mode-config ()
+ ;; FIXME: next two broken, of course, as is PBP everywhere except LEGO.
+ (setq pbp-change-goal "Show %s.")
+ (setq pbp-error-regexp proof-shell-error-regexp)
+ (isa-init-output-syntax-table)
+ (setq font-lock-keywords isa-goals-font-lock-keywords)
+ (proof-goals-config-done))
+
+(defun isa-preprocessing () ;dynamic scoping of `string'
+ "Handle ^VERBATIM marker -- acts on variable STRING by dynamic scoping"
+ (if (proof-string-match isabelle-verbatim-regexp string)
+ (setq string (match-string 1 string))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; x-symbol support for Isabelle PG, provided by David von Oheimb.
+;;
+;; The following settings configure the generic PG package.
+;; The token language "Isabelle Symbols" is in file x-symbol-isa.el
+;;
+
+(setq proof-xsym-extra-modes '(thy-mode)
+ proof-xsym-activate-command
+ "print_mode := ([\"xsymbols\",\"symbols\"] @ ! print_mode);"
+ proof-xsym-deactivate-command
+ "print_mode := (! print_mode \\\\ [\"xsymbols\",\"symbols\"]);")
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Completion table for Isabelle identifiers
+;;
+;; Ideally this could be set automatically from the running process,
+;; and maybe a default value could be dumped by Isabelle when it is
+;; built.
+
+(defpgdefault completion-table
+ '("quit"
+ "cd" "use" "use_thy" "time_use" "time_use_thy"
+ "Pretty.setdepth" "Pretty.setmargin" "print_depth"
+ "show_hyps" "show_types" "show_sorts"
+ "print_exn"
+ "goal" "goalw" "goalw_cterm" "premises"
+ "by" "byev"
+ "result" "uresult"
+ "chop" "choplev" "back" "undo"
+ "pr" "prlev" "goals_limit"
+ "proof_timing"
+ "prove_goal" "prove_goalw" "prove_goalw_cterm"
+ "push_proof" "pop_proof" "rotate_proof"
+ "save_proof" "restore_proof"
+ "read" "prin" "printyp"
+ "topthm" "getgoal" "gethyps"
+ "filter_goal" "compat_goal"
+
+ ;; short cuts - should these be included?
+ "ba" "br" "be" "bd" "brs" "bes" "bds"
+ "fs" "fr" "fe" "fd" "frs" "fes" "fds"
+ "bw" "bws" "ren"
+
+ "resolve_tac" "eresolve_tac" "dresolve_tac" "forward_tac"
+ "assume_tac" "eq_assume_tac"
+ "match_tac" "ematch_tac" "dmatch_tac"
+ "res_inst_tac" "eres_inst_tac" "dres_inst_tac" "forw_inst_tac"
+ "rewrite_goals_tac" "rewrite_tac" "fold_goals_tac"
+ "fold_goals_tac" "fold_tac"
+ "cut_facts_tac" "subgoal_tac"
+
+ ;; short cuts - should these be included?
+ "rtac" "etac" "dtac" "atac" "ares_tac" "rewtac"
+
+ ;; In general, I think rules should appear in rule tables, not here.
+ "asm_rl" "cut_rl"
+
+ "flexflex_tac" "rename_tac" "rename_last_tac"
+ "Logic.set_rename_prefix" "Logic.auto_rename"
+
+ "compose_tac"
+
+ "biresolve_tac" "bimatch_tac" "subgoals_of_brl" "lessb"
+ "head_string" "insert_thm" "delete_thm" "compat_resolve_tac"
+
+ "could_unify" "filter_thms" "filt_resolve_tac"
+
+ ;; probably shouldn't be included:
+ "tapply" "Tactic" "PRIMITIVE" "STATE" "SUBGOAL"
+
+ "pause_tac" "print_tac"
+
+ "THEN" "ORELSE" "APPEND" "INTLEAVE"
+ "EVERY" "FIRST" "TRY" "REPEAT_DETERM" "REPEAT" "REPEAT1"
+ "trace_REPEAT"
+ "all_tac" "no_tac"
+ "FILTER" "CHANGED" "DEPTH_FIRST" "DEPTH_SOLVE"
+ "DEPTH_SOLVE_1" "trace_DEPTH_FIRST"
+ "BREADTH_FIRST" "BEST_FIRST" "THEN_BEST_FIRST"
+ "trace_BEST_FIRST"
+ "COND" "IF_UNSOLVED" "DETERM"
+
+ "SELECT_GOAL" "METAHYPS"
+
+ "ALLGOALS" "TRYALL" "SOMEGOAL" "FIRSTGOAL"
+ "REPEAT_SOME" "REPEAT_FIRST" "trace_goalno_tac"
+
+ ;; include primed versions of tacticals?
+
+ "EVERY1" "FIRST1"
+
+ "prth" "prths" "prthq"
+ "RSN" "RLN" "RL"
+
+ ;; simplifier
+
+ "addsimps" "addeqcongs" "delsimps"
+ "setsolver" "setloop" "setmksimps" "setsubgoaler"
+ "empty_ss" "merge_ss" "prems_of_ss" "rep_ss"
+ "simp_tac" "asm_full_simp_tac" "asm_simp_tac"
+
+ ;; classical prover
+
+ "empty_cs"
+ "addDs" "addEs" "addIs" "addSDs" "addSEs" "addSIs"
+ "print_cs"
+ "rep_claset" "best_tac" "chain_tac" "contr_tac" "eq_mp_tac"
+ "fast_tac" "joinrules" "mp_tac" "safe_tac" "safe_step_tac"
+ "slow_best_tac" "slow_tac" "step_tac" "swapify"
+ "swap_res_tac" "inst_step_tac"
+
+ ;; that's it for now!
+ ))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Theorem dependencies (experimental)
+;;
+
+(defpacustom theorem-dependencies nil
+ "Whether to track theorem dependencies within Proof General."
+ :type 'boolean
+ ;; when this is built-in (or with a ":=%b" setting).
+ ;; :setting ("depends_enable()" . "depends_disable()")
+ :eval (isa-theorem-dependencies-switch))
+
+(defvar isa-dependsml-file-loaded nil)
+
+(add-hook 'proof-shell-kill-function-hooks
+ (lambda () (setq isa-dependsml-file-loaded nil)))
+
+(defun isa-load-dependsml-file ()
+ ;; NB: maybe doesn't work if enabled before Isabelle starts.
+ (if (proof-shell-available-p)
+ (progn
+ (proof-shell-invisible-command
+ (proof-format-filename
+ "use \"%r\";"
+ (concat (file-name-directory
+ (locate-library "isa"))
+ "depends.ML")))
+ (setq isa-dependsml-file-loaded t))))
+
+(defun isa-theorem-dependencies-switch ()
+ "Switch on/off theorem dependency tracking. (Experimental feature)."
+ (if (and isa-theorem-dependencies (not isa-dependsml-file-loaded))
+ (isa-load-dependsml-file))
+ (proof-shell-invisible-command (if isa-theorem-dependencies
+ "depends_enable()"
+ "depends_disable()")))
+
+
+
+
+
+(provide 'isa)
diff --git a/isa/isabelle-system.el b/isa/isabelle-system.el
new file mode 100644
index 00000000..01d98767
--- /dev/null
+++ b/isa/isabelle-system.el
@@ -0,0 +1,382 @@
+;; isabelle-system.el Interface with Isabelle system
+;;
+;; Copyright (C) 2000 LFCS Edinburgh, David Aspinall.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Maintainer: Proof General maintainer <proofgen@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;; Most of this code is taken from the final version of Isamode.
+;; --------------------------------------------------------------
+;;
+
+(require 'proof)
+
+(defconst isa-running-isar (eq proof-assistant-symbol 'isar))
+
+;; If we're using Isabelle/Isar then the isabelle custom
+;; group won't have been defined yet.
+(if isa-running-isar
+(defgroup isabelle nil
+ "Customization of user options for Isabelle and Isabelle/Isar Proof General"
+ :group 'proof-general))
+
+(defcustom isabelle-web-page
+ "http://www.cl.cam.ac.uk/Research/HVG/Isabelle/"
+ ;; "http://isabelle.in.tum.de"
+ ;; "http://www.dcs.ed.ac.uk/home/isabelle"
+ "URL of web page for Isabelle."
+ :type 'string
+ :group 'isabelle)
+
+
+;;; ================ Extract Isabelle settings ================
+
+(defcustom isa-isatool-command
+ (or (getenv "ISATOOL")
+ (proof-locate-executable "isatool")
+ (let ((possibilities
+ '("/usr/bin/isatool"
+ "/usr/share/Isabelle/bin/isatool"
+ "/usr/local/bin/isatool"
+ "/usr/local/Isabelle/bin/isatool"
+ "/opt/bin/isatool"
+ "/opt/Isabelle/bin/isatool")))
+ (while (and possibilities
+ (not (file-executable-p
+ (car possibilities))))
+ (setq possibilities (cdr possibilities)))
+ (car-safe possibilities))
+ "path_to_isatool_is_unknown")
+ "Command to invoke Isabelle tool 'isatool'.
+XEmacs should be able to find `isatool' if it is on the PATH when
+started. Then several standard locations are attempted.
+Otherwise you should set this, using a full path name here for reliable
+working."
+ :type 'file
+ :group 'isabelle)
+
+(defun isa-set-isatool-command ()
+ "Make sure isa-isatool-command points to a valid executable.
+If it does not, prompt the user for the proper setting.
+If it appears we're running on win32 or FSF Emacs, we allow this to
+remain unverified.
+Returns non-nil if isa-isatool-command is surely an executable
+with full path."
+ (interactive)
+ (while (unless proof-running-on-win32
+ (not (file-executable-p isa-isatool-command)))
+ (beep)
+ (setq isa-isatool-command
+ (read-file-name
+ "Please type in the full path to the `isatool' program: "
+ nil nil t)))
+ (if (and proof-running-on-win32
+ (not (file-executable-p isa-isatool-command)))
+ (warning "Proof General: isatool command not found; ignored because Win32 system detected."))
+ (file-executable-p isa-isatool-command))
+
+(defun isa-shell-command-to-string (command)
+ "Like shell-command-to-string except the last character is stripped."
+ ;; FIXME: sometimes the command may fail. This will usually cause PG
+ ;; to break. Bit of an effort to trap errors here, we would need
+ ;; to provide some advice to shell-command-to-string to retain result
+ ;; of call to call-process, and raise and error in case it failed.
+ (substring (shell-command-to-string command) 0 -1))
+
+(defun isa-getenv (envvar &optional default)
+ "Extract an environment variable setting using the `isatool' program.
+If the isatool command is not available, try using elisp's getenv
+to extract the value from Emacs' environment.
+If there is no setting for the variable, DEFAULT will be returned"
+ (isa-set-isatool-command)
+ (if (file-executable-p isa-isatool-command)
+ (let ((setting (isa-shell-command-to-string
+ (concat isa-isatool-command
+ " getenv -b " envvar))))
+ (if (string-equal setting "")
+ default
+ setting))
+ (or (getenv envvar) default)))
+
+;;;
+;;; ======= Interaction with System using Isabelle tools =======
+;;;
+
+(defcustom isabelle-program-name
+ (if (fboundp 'proof-running-on-win32)
+ "C:\\sml\\bin\\.run\\run.x86-win32.exe @SMLload=C:\\Isabelle\\"
+ (proof-locate-executable "isabelle" t))
+ "*Default name of program to run Isabelle.
+
+The default value except when running under Windows is \"isabelle\",
+which will get expanded using PATH if possible.
+
+The default value when running under Windows is:
+
+ C:\\sml\\bin\\.run\\run.x86-win32.exe @SMLload=C:\\Isabelle\\
+
+This expects SML/NJ in C:\\sml and Isabelle images in C:\Isabelle.
+The logic image name is tagged onto the end.
+
+NB: The Isabelle settings mechanism or the environment variable
+ISABELLE will always override this setting."
+ :type 'file
+ :group 'isabelle)
+
+(defvar isabelle-prog-name isabelle-program-name
+ "Set from `isabelle-program-name', has name of logic appended sometimes.")
+
+(defun isabelle-command-line ()
+ "Make proper command line for running Isabelle"
+ (let*
+ ;; The ISABELLE and PROOFGENERAL_LOGIC values (as set when run
+ ;; under the interface wrapper script) indicate that we should
+ ;; determine the proper command line from the current Isabelle
+ ;; settings environment.
+ ((isabelle (or
+ (getenv "ISABELLE") ; overrides default, may be updated
+ isabelle-program-name ; calculated earlier
+ "isabelle")) ; to be really sure
+ (isabelle-opts (getenv "ISABELLE_OPTIONS"))
+ (opts (concat
+ (if isa-running-isar " -PI" "")
+ (if (and isabelle-opts (not (equal isabelle-opts "")))
+ (concat " " isabelle-opts) "")))
+ (logic (or isabelle-chosen-logic
+ (getenv "PROOFGENERAL_LOGIC")))
+ (logicarg (if (and logic (not (equal logic "")))
+ (concat " " logic) "")))
+ (concat isabelle opts logicarg)))
+
+(defun isabelle-choose-logic (logic)
+ "Adjust isabelle-prog-name and proof-prog-name for running LOGIC."
+ ;; a little bit obnoxious maybe (but what naive user would expect)
+ ;; (customize-save-variable 'isabelle-chosen-logic logic)
+ (customize-set-variable 'isabelle-chosen-logic logic)
+ (setq isabelle-prog-name (isabelle-command-line))
+ (setq proof-prog-name isabelle-prog-name))
+
+(defun isa-tool-list-logics ()
+ "Generate a list of available object logics."
+ (if (isa-set-isatool-command)
+ (split-string (isa-shell-command-to-string
+ (concat isa-isatool-command " findlogics")) "[ \t]")))
+
+(defun isa-view-doc (docname)
+ "View Isabelle document DOCNAME, using Isabelle tools."
+ (if (isa-set-isatool-command)
+ (apply 'start-process
+ "isa-view-doc" nil
+ (list isa-isatool-command "doc" docname))))
+
+(defun isa-tool-list-docs ()
+ "Generate a list of documentation files available, with descriptions.
+This function returns a list of lists of the form
+ ((DOCNAME DESCRIPTION) ....)
+of Isabelle document names and descriptions. When DOCNAME is
+passed to isa-tool-doc-command, DOCNAME will be viewed."
+ (if (isa-set-isatool-command)
+ (let ((docs (isa-shell-command-to-string
+ (concat isa-isatool-command " doc"))))
+ (unless (string-equal docs "")
+ (mapcar
+ (function (lambda (docdes)
+ (list
+ (substring docdes
+ (proof-string-match "\\(\\S-+\\)[ \t]+" docdes)
+ (match-end 1))
+ (substring docdes (match-end 0)))))
+ (split-string docs "\n"))))))
+
+(defun isa-quit (save)
+ "Quit / save the Isabelle session.
+Called with one argument: t to save database, nil otherwise."
+ (if (not save)
+ (isa-insert-ret "quit();"))
+ (comint-send-eof))
+
+(defconst isabelle-verbatim-regexp "\\`\^VERBATIM: \\(\\(.\\|\n\\)*\\)\\'"
+ "Regexp matching internal marker for verbatim command output")
+
+(defun isabelle-verbatim (str)
+ "Mark internal command for verbatim output"
+ (concat "\^VERBATIM: " str))
+
+;;; Set proof-shell-pre-interrupt-hook for PolyML 3.
+(if (and
+ (not proof-shell-pre-interrupt-hook)
+ ;; (Older versions of Isabelle reported PolyML for PolyML 3).
+ (proof-string-match "\\`polyml" (isa-getenv "ML_SYSTEM"))
+ (not (proof-string-match "\\`polyml-4" (isa-getenv "ML_SYSTEM"))))
+ (add-hook
+ 'proof-shell-pre-interrupt-hook
+ (lambda () (proof-shell-insert (isabelle-verbatim "f") nil))))
+
+;;; ========== Utility functions ==========
+
+(defcustom isabelle-logics-available (isa-tool-list-logics)
+ "*List of logics available to use with Isabelle.
+If the `isatool' program is available, this is automatically
+generated with the lisp form `(isa-tool-list-logics)'."
+ :type (list 'string)
+ :group 'isabelle)
+
+;; FIXME: document this one
+(defcustom isabelle-chosen-logic nil
+ "*Choice of logic to use with Isabelle.
+If non-nil, will be added into isabelle-prog-name as default value.
+
+NB: you have saved a new logic image, it may not appear in the choices
+until Proof General is restarted."
+ :type (append
+ (list 'choice)
+ (mapcar (lambda (str) (list 'const str)) isabelle-logics-available)
+ (list '(string :tag "Choose another")
+ '(const :tag "Unset (use default)" nil)))
+ :group 'isabelle)
+
+(defconst isabelle-docs-menu
+ (let ((vc '(lambda (docdes)
+ (vector (car (cdr docdes))
+ (list 'isa-view-doc (car docdes)) t))))
+ (list (cons "Isabelle documentation" (mapcar vc (isa-tool-list-docs)))))
+ "Isabelle documentation menu. Constructed when PG is loaded.")
+
+
+;; It's a hassle to bother trying to reconstruct this
+;; dynamically like it was in Isamode, so we don't bother.
+
+(defconst isabelle-logics-menu
+ (cons "Logics"
+ (cons
+ ["Default"
+ (isabelle-choose-logic nil)
+ :active (not (proof-shell-live-buffer))
+ :style radio
+ :selected (not isabelle-chosen-logic)]
+ (mapcar (lambda (l)
+ (vector l (list 'isabelle-choose-logic l)
+ :active '(not (proof-shell-live-buffer))
+ :style 'radio
+ :selected (list 'equal 'isabelle-chosen-logic l)))
+ (isa-tool-list-logics))))
+ "Isabelle logics menu. Constructed when PG is loaded.")
+
+
+
+;;; ========== Mirroring Proof General options in Isabelle process ========
+
+;; NB: use of defpacustom here gives separate customizable
+;; options for Isabelle and Isabelle/Isar.
+
+(defpacustom show-types nil
+ "Whether to show types in Isabelle."
+ :type 'boolean
+ :setting "show_types:=%b;")
+
+(defpacustom show-sorts nil
+ "Whether to show sorts in Isabelle."
+ :type 'boolean
+ :setting "show_sorts:=%b;")
+
+(defpacustom show-consts nil
+ "Whether to show types of consts in Isabelle goals."
+ :type 'boolean
+ :setting "show_consts:=%b;")
+
+(defpacustom long-names nil
+ "Whether to show fully qualified names in Isabelle."
+ :type 'boolean
+ :setting "long_names:=%b;")
+
+(defpacustom eta-contract t
+ "Whether to print terms eta-contracted in Isabelle."
+ :type 'boolean
+ :setting "Syntax.eta_contract:=%b;")
+
+(defpacustom trace-simplifier nil
+ "Whether to trace the Simplifier in Isabelle."
+ :type 'boolean
+ :setting "trace_simp:=%b;")
+
+(defpacustom trace-rules nil
+ "Whether to trace the standard rules in Isabelle."
+ :type 'boolean
+ :setting "trace_rules:=%b;")
+
+(defpacustom quick-and-dirty t
+ "Whether to take a few short cuts occasionally."
+ :type 'boolean
+ :setting "quick_and_dirty:=%b;")
+
+(defpacustom full-proofs nil
+ "Whether to record full proof objects internally."
+ :type 'boolean
+ :setting "Library.error_fn := (fn _ => ()); Library.try (fn () => Context.use_mltext \"ProofGeneral.full_proofs %b;\" false None) ();")
+;FIXME should become "ProofGeneral.full_proofs %b;" next time
+
+(defpacustom global-timing nil
+ "Whether to enable timing in Isabelle."
+ :type 'boolean
+ :setting "Library.timing:=%b;")
+
+(defpacustom goals-limit 10
+ "Setting for maximum number of goals printed in Isabelle."
+ :type 'integer
+ :setting "goals_limit:=%i;")
+
+(defpacustom prems-limit 10
+ "Setting for maximum number of premises printed in Isabelle/Isar."
+ :type 'integer
+ :setting "ProofContext.prems_limit:=%i;")
+
+(defpacustom print-depth 10
+ "Setting for the ML print depth in Isabelle."
+ :type 'integer
+ :setting "print_depth %i;")
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Generic Isabelle menu for Isabelle and Isabelle/Isar
+;;
+
+(defpgdefault menu-entries
+ (append
+ (if isa-running-isar
+ nil
+ (list ["Switch to theory" thy-find-other-file t]))
+ (list isabelle-logics-menu)))
+
+(defpgdefault help-menu-entries isabelle-docs-menu)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; X-Symbol language configuration, and adding to completion table
+;;
+
+(defpgdefault x-symbol-language 'isabelle)
+
+(setq proof-xsym-font-lock-keywords
+ ;; fontification for tokens themselves (FIXME: broken)
+ '(("\\\\<[A-Za-z][A-Za-z0-9_']*>" (0 font-lock-type-face))))
+
+(eval-after-load "x-symbol-isabelle"
+ ;; Add x-symbol tokens to isa-completion-table and rebuild
+ ;; internal completion table if completion is already active
+'(progn
+ (defpgdefault completion-table
+ (append (proof-ass completion-table)
+ (mapcar (lambda (xsym) (nth 2 xsym))
+ x-symbol-isabelle-table)))
+ (if (featurep 'completion)
+ (proof-add-completions))))
+
+
+
+
+(provide 'isabelle-system)
+;; End of isabelle-system.el
diff --git a/isa/thy-mode.el b/isa/thy-mode.el
new file mode 100644
index 00000000..07e0ca54
--- /dev/null
+++ b/isa/thy-mode.el
@@ -0,0 +1,1047 @@
+;; thy-mode.el - Mode for Isabelle theory files.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Maintainer: Isabelle maintainer <isabelle@dcs.ed.ac.uk>
+;;
+;; Taken from Isamode, version: 3.6 1998/09/02 11:40:45
+;;
+;; $Id$
+;;
+;; NAMESPACE management: all functions and variables declared
+;; in this file begin with isa-thy-
+
+(require 'proof-site)
+(require 'proof-syntax)
+(require 'isa)
+
+;;; ========== Theory File Mode User Options ==========
+
+(defcustom thy-heading-indent 0
+ "Indentation for section headings."
+ :type 'integer
+ :group 'thy)
+
+(defcustom thy-indent-level 2
+ "*Indentation level for Isabelle theory files. An integer."
+ :type 'integer
+ :group 'thy)
+
+(defcustom thy-indent-strings t
+ "If non-nil, indent inside strings.
+You may wish to disable indenting inside strings if your logic uses
+any of the usual bracket characters in unusual ways."
+ :type 'boolean
+ :group 'thy)
+
+(defcustom thy-use-sml-mode nil
+ "*If non-nil, invoke sml-mode inside \"ML\" section of theory files.
+This option is left-over from Isamode. Really, it would be more
+useful if the script editing mode of Proof General itself could be based
+on sml-mode, but at the moment there is no way to do this."
+ :type 'boolean
+ :group 'thy)
+
+
+;;; ====== Theory and ML file templates =========================
+
+(defcustom thy-sections
+ ;; NB: preceding white space in templates deleted by indentation alg.
+ ;; top must come first.
+ '(("top" . thy-insert-header)
+ ("classes" . thy-insert-class)
+ ("default" . thy-insert-default-sort) ; is "default" obsolete?
+ ("defaultsort" . thy-insert-default-sort)
+ ("types" . thy-insert-type)
+ ("typedecl")
+ ("arities" . thy-insert-arity)
+ ;; =================================
+ ;; These only make sense for HOL.
+ ;; Ideally we should parameterise these parts on the theory.
+ ("datatype") ("typedef")
+ ("inductive") ("coninductive")
+ ("intrs") ("monos")
+ ("primrec") ("recdef")
+ ("rep_datatype") ("distinct") ("induct")
+ ;; ==============================
+ ("consts" . thy-insert-const)
+ ("translations" . "\"\"\t==\t\"\"")
+ ("axclass")
+ ("syntax")
+ ("instance")
+ ("rules" . thy-insert-rule)
+ ("defs" . thy-insert-rule)
+ ("axioms" . thy-insert-rule)
+ ("use")
+ ("theory")
+ ("files")
+ ("constdefs")
+ ("oracle")
+ ("local")
+ ("locale")
+ ("nonterminals")
+ ("setup")
+ ("global")
+ ("end")
+ ("ML"))
+ "Names of theory file sections and their templates.
+Each item in the list is a pair of a section name and a template.
+A template is either a string to insert or a function. Useful functions are:
+ thy-insert-header, thy-insert-class, thy-insert-default-sort,
+ thy-insert-const, thy-insert-rule.
+The nil template does nothing.
+You can add extra sections to theory files by extending this variable."
+ :type '(repeat
+ (cons string
+ (choice function
+ string
+ (const :tag "no template" nil))))
+ :group 'thy)
+
+(defcustom thy-id-header
+ "(*
+ File: %f
+ Theory Name: %t
+ Logic Image: %l
+*)\n\n"
+ "*Identification header for .thy and .ML files.
+Format characters: %f replaced by filename, %t by theory name,
+and %l by the logic image name this file should be read in."
+ :group 'thy
+ :type 'string)
+
+(defcustom thy-template
+"%t = %p +\n
+classes\n
+default\n
+types\n
+arities\n
+consts\n
+translations\n
+rules\n
+end\n
+ML\n"
+"Template for theory files.
+Contains a default selection of sections in a traditional order.
+You can use the following format characters:
+
+`%t' --- replaced by theory name.
+
+`%p' --- replaced by names of parents, separated by `+' characters."
+ :group 'thy
+ :type 'string)
+
+
+
+;;; ========== Code ==========
+
+(defvar thy-mode-map nil)
+
+(defvar thy-mode-syntax-table nil) ; Shared below.
+
+(if thy-mode-syntax-table
+ nil
+ ;; This is like sml-mode, except:
+ ;; . is a word constituent (not punctuation). (bad for comments?)
+ ;; " is a paired delimiter
+ (setq thy-mode-syntax-table (make-syntax-table))
+ (modify-syntax-entry ?\( "()1 " thy-mode-syntax-table)
+ (modify-syntax-entry ?\) ")(4 " thy-mode-syntax-table)
+ (modify-syntax-entry ?\\ "\\ " thy-mode-syntax-table)
+ (modify-syntax-entry ?* ". 23" thy-mode-syntax-table)
+ (modify-syntax-entry ?_ "w " thy-mode-syntax-table)
+ (modify-syntax-entry ?\' "w " thy-mode-syntax-table)
+; it's annoying to match with quotes from previous strings,
+; so this has been removed.
+; (modify-syntax-entry ?\" "$ " thy-mode-syntax-table)
+ (modify-syntax-entry ?. "w " thy-mode-syntax-table))
+
+(or thy-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [(control up)] 'thy-goto-prev-section)
+ (define-key map [(control down)] 'thy-goto-next-section)
+ (define-key map "\C-c\C-n" 'thy-goto-next-section)
+ (define-key map "\C-c\C-p" 'thy-goto-prev-section)
+ (define-key map "\C-c\C-m" 'thy-minor-sml-mode)
+ (define-key map "\C-c\C-t" 'thy-insert-template)
+ ;; Disabled for Proof General
+ ;;(define-key map "\C-c\C-u" 'thy-use-file)
+ ;;(define-key map "\C-c\C-l" 'thy-raise-windows)
+ (define-key map "\C-c\C-o" 'thy-find-other-file)
+ (define-key map "\C-M" 'newline-and-indent)
+ (define-key map "\C-k" 'thy-kill-line)
+ (setq thy-mode-map map)))
+
+(defun thy-add-menus (&optional file)
+ "Add Proof General and Isabelle menu to current menu bar."
+ (require 'proof-script) ; Later: proof-menu, autoloaded
+ (easy-menu-define thy-mode-pg-menu
+ thy-mode-map
+ "PG Menu for Isabelle Proof General"
+ (cons proof-general-name
+ (append
+ (list
+ ;; A couple from the toolbar that make sense here
+ ;; (also in proof-universal-keys)
+ ["Issue command" proof-minibuffer-cmd t]
+ ["Interrupt prover" proof-interrupt-process t])
+ proof-shared-menu
+ ;; begin UGLY COMPATIBILTY HACK
+ ;; older/non-existent customize doesn't have
+ ;; this function.
+ (if (fboundp 'customize-menu-create)
+ (list (customize-menu-create 'proof-general)
+ (customize-menu-create
+ 'proof-general-internals
+ "Internals"))
+ nil)
+ ;; end UGLY COMPATIBILTY HACK
+ )))
+ (easy-menu-define thy-mode-isa-menu
+ thy-mode-map
+ "Menu for Isabelle Proof General, theory file mode."
+ (cons "Theory"
+ (list
+ ["Next section" thy-goto-next-section t]
+ ["Prev section" thy-goto-prev-section t]
+ ["Insert template" thy-insert-template t]
+ ["Process theory" isa-process-thy-file
+ :active (proof-locked-region-empty-p)]
+ ["Retract theory" isa-retract-thy-file
+ :active (proof-locked-region-full-p)]
+ ["Next error" proof-next-error t]
+ ["Switch to script" thy-find-other-file t])))
+ (easy-menu-add thy-mode-pg-menu thy-mode-map)
+ (easy-menu-add thy-mode-isa-menu thy-mode-map)
+
+ (if file
+ (progn (easy-menu-remove thy-mode-deps-menu)
+ (proof-thy-menu-define-deps file)
+ (easy-menu-add thy-mode-deps-menu thy-mode-map))))
+
+
+(defun thy-mode (&optional nomessage)
+ "Major mode for editing Isabelle theory files.
+\\<thy-mode-map>
+\\[thy-goto-next-section]\t Skips to the next section.
+\\[thy-goto-prev-section]\t Skips to the previous section.
+
+\\[indent-for-tab-command]\t Indents the current line.
+
+\\[thy-insert-template]\t Inserts a template for the file or current section.
+
+If thy-use-sml-mode is non-nil, \\<thy-mode-map>\\[thy-minor-sml-mode] \
+invokes sml-mode as a minor mode
+in the ML section. This is done automatically by \
+\\[indent-for-tab-command].
+
+The style of indentation for theory files is controlled by these variables:
+ thy-heading-indent
+ thy-indent-level
+ thy-indent-strings
+- see individual variable documentation for details.
+
+Here is the full list of theory mode key bindings:
+\\{thy-mode-map}"
+ (interactive)
+ (kill-all-local-variables)
+ (setq major-mode 'thy-mode)
+ (setq mode-name "Theory")
+ (use-local-map thy-mode-map)
+ (thy-add-menus)
+
+ (set-syntax-table thy-mode-syntax-table)
+ (make-local-variable 'indent-line-function)
+ (setq indent-line-function 'thy-indent-line)
+ (make-local-variable 'comment-start) ; Following lines as in sml-mode
+ (setq comment-start "(* ") ; .
+ (make-local-variable 'comment-end) ; .
+ (setq comment-end " *)") ; .
+ (setq comment-start-skip "(\\*+[ \t]?") ; .
+ (setq font-lock-keywords
+ thy-mode-font-lock-keywords)
+
+ ;; Toolbar: needs alteration for non-scripting mode!
+ ;; (if (featurep 'proof-toolbar)
+ ;; (proof-toolbar-setup))
+ ;;
+
+
+ (run-hooks 'thy-mode-hook)
+ (force-mode-line-update)
+ (if (null nomessage)
+ (message
+ (substitute-command-keys
+ "Isabelle theory-file mode. Use \\[thy-insert-template] to insert templates; \\[describe-mode] for help.")))
+ )
+
+(defun thy-mode-quiet ()
+ (interactive)
+ (thy-mode t))
+
+
+
+
+;;; "use" and "use_thy" with theory files ========================
+
+;;; FIXME: Isabelle has been improved, so the following code could
+;;; be cleaned up. Also set variable to allow automatic starting
+;;; of process by reading logic image.
+
+;;; NB: this is a mess at the moment because of the theory file
+;;; naming conventions. Really we need to parse the theory/ML
+;;; file - yuk!!
+;;; The next version of Isabelle will be more consistent.
+
+;(defun thy-use-file (&optional force-use_thy)
+; "Send the file of the current buffer to an Isabelle buffer with use_thy or use."
+; (interactive "P")
+; (let ((fname (buffer-file-name)))
+; (if fname
+; (isa-query-save (current-buffer))
+; (setq fname
+; (or (buffer-file-name)
+; (read-file-name "Use file: " nil nil t))))
+; (let*
+; ((has-thy-extn (string-match "\\.thy$" fname)) ; o/w assume ML.
+; (tname (if has-thy-extn
+; (substring fname 0 -4); cos use_thy is daft!
+; fname))
+; (use (if (or has-thy-extn force-use_thy)
+; "use_thy"
+; "use"))
+; (use-thy-string (concat use " \"" tname "\";"))
+; (logic (isa-guess-root)))
+; (thy-send-string logic use-thy-string))))
+
+;(defun thy-use-region (beg end)
+; "Send the region to an Isabelle buffer, with use"
+; (interactive "r")
+; (write-region beg end thy-use-tempname nil 'nomessage)
+; (let* ((use-thy-string (concat "use \"" thy-use-tempname "\";"))
+; (logic (isa-guess-root)))
+; (thy-send-string logic use-thy-string)))
+
+;(defun thy-copy-region (beg end &optional isa-buffer)
+; "Copy the region to an Isabelle buffer."
+; (interactive "r")
+; (let ((text (buffer-substring beg end))
+; (logic (isa-guess-root)))
+; (save-excursion
+; (thy-send-string logic text))))
+
+;(defun thy-use-line (&optional isabuffer)
+; "Send the current interactive ML line to an Isabelle buffer.
+;Advance to the next line."
+; (interactive)
+; (isa-apply-to-interactive-line 'thy-copy-region))
+
+;(defun thy-send-string (logic text &optional hide)
+; "Send TEXT to a buffer running LOGIC.
+;If LOGIC is nil, pick the first Isabelle buffer."
+; (require 'isa-mode)
+; (setq logic nil) ;;; #### HACK! This all needs changing for single-session.
+; (let ((cur-frm (selected-frame))) ; Preserve selected frame.
+; (if logic ; switch to Isabelle buffer, without
+; (isabelle-session logic) ; raising the frame.
+; ; (NB: this fails if was renamed).
+; (set-buffer
+; (or (car-safe (isa-find-buffers-in-mode 'isa-mode))
+; (error "Can't find an Isabelle buffer"))))
+; (if hide
+; (isa-send-string
+; (get-buffer-process (current-buffer))
+; text)
+; (isa-insert-ret text)) ; send use command
+; (select-frame cur-frm)))
+
+(defun thy-proofgeneral-send-string (logic text &optional hide)
+ ;; FIXME -- new function!
+ )
+
+;(defun thy-raise-windows ()
+; "Raise windows/frames associated with Isabelle session."
+; (interactive)
+; (isa-select-buffer isa-session-buffer t)
+; (let ((raise t))
+; (mapcar 'isa-display-if-active
+; isa-associated-buffers)))
+
+
+;(defun thy-guess-logic-in-use ()
+; (if (featurep 'isa-mode)
+; (let* ((buf (car-safe (isa-find-buffers-in-mode 'isa-mode)))
+; (log (and buf
+; (save-excursion
+; (set-buffer buf)
+; isa-logic-name))))
+; log)
+; nil))
+
+
+;(defvar thy-use-tempname ".region.ML"
+; "*Name of temporary file to hold region dring thy-use-region.")
+
+
+;(defconst thy-logic-image-regexp
+; "[lL][oO][gG][iI][cC] [iI][mM][aA][gG][eE]:[ \t]*\"?\\([^ \t\n\"]+\\)\"?[ \t]*$"
+; "Regexp for locating name of logic image file in a .thy or .ML file.")
+
+;(defvar isa-logic-parents
+; ;; I can't be bothered to write all of them in here,
+; ;; and anyway they're ambiguous. Use "Logic image:"
+; ;; instead. (Or find a way of getting emacs to track
+; ;; theory structure...)
+; '(("List" . "HOL") ("Prod" . "HOL") ("Nat" . "HOL")
+; ("Ord" . "HOL") ("Set" ."HOL") ("Sexp" . "HOL")
+; ("Univ" . "HOL") ("WF" . "HOL") ("Sum" . "HOL")
+; ("IFOL" . "FOL"))
+; "*An alist of parents of theories that live in logic files.")
+
+;(defun isa-guess-root ()
+; "Guess the root logic of the .thy or .ML file in current buffer.
+;Choice based on first name found by:
+; (i) special text: \"Logic Image: <name>\" toward start of file
+; (ii) guess work based on parent in THY = <parent> if a .thy file."
+; (save-excursion
+; (goto-char (point-min))
+; (cond
+; ((re-search-forward thy-logic-image-regexp 500 t)
+; (buffer-substring (match-beginning 1) (match-end 1)))
+; ((and (string-match "\\.thy$" (or (buffer-file-name) ""))
+; (re-search-forward
+; "\\w+[ \t\n]*=[ \t\n]*\\(\\w+\\)[ \t\n]*\\+") 500 t)
+; ;; Something looks like a parent theory:
+; ;; MyThy = HOL + ...
+; (let ((child
+; (buffer-substring (match-beginning 1) (match-end 1))))
+; (or (cdr-safe (assoc child isa-logic-parents))
+; child))))))
+
+;(defun isa-query-save (buffer)
+; (and (buffer-modified-p buffer)
+; (y-or-n-p (concat "Save file "
+; (buffer-file-name buffer)
+; "? "))
+; (save-excursion (set-buffer buffer) (save-buffer))))
+
+
+
+
+;;; Interfacing with sml-mode ========================
+
+;; extending sml-mode. This only works if you visit the theory file
+;; (or start Isabelle mode) first.
+;; This is probably fairly close to The Right Thing...
+
+(defun isa-sml-hook ()
+ "Hook to customize sml-mode for use with Isabelle."
+ ;(isa-menus) ; Add Isabelle main menu
+ ;; NB: these keydefs will affect other sml-mode buffers too!
+ (define-key sml-mode-map "\C-c\C-o" 'thy-find-other-file)
+ ; Disabled for proof general
+ ;(define-key sml-mode-map "\C-c\C-u" 'thy-use-file)
+ ;(define-key sml-mode-map "\C-c\C-r" 'thy-use-region)
+ ;(define-key sml-mode-map "\C-c\C-l" 'thy-use-line)
+ ;; listener minor mode removed: \C-c\C-c freed up
+ (define-key sml-mode-map "\C-c\C-t" 'thy-insert-id-header))
+
+(add-hook 'sml-mode-hook 'isa-sml-hook)
+
+(defun isa-sml-mode ()
+ "Invoke sml-mode after installing Isabelle hook."
+ (interactive)
+ (and (fboundp 'sml-mode) (sml-mode)))
+
+(defcustom isa-ml-file-extension ".ML"
+ "*File name extension to use for ML files."
+ :type 'string
+ :group 'isabelle)
+
+(defun thy-find-other-file (&optional samewindow)
+ "Find associated .ML or .thy file.
+Finds and switch to the associated ML file (when editing a theory file)
+or theory file (when editing an ML file).
+If SAMEWINDOW is non-nil (interactively, with an optional argument)
+the other file replaces the one in the current window."
+ (interactive "p")
+ (and
+ (buffer-file-name)
+ (let* ((fname (buffer-file-name))
+ (thyfile (string-match "\\.thy$" fname))
+ (mlfile (string-match
+ (concat (regexp-quote isa-ml-file-extension) "$") fname))
+ (basename (file-name-sans-extension fname))
+ (findfn (if samewindow 'find-file else 'find-file-other-window)))
+ (cond (thyfile
+ (funcall findfn (concat basename isa-ml-file-extension)))
+ (mlfile
+ (funcall findfn (concat basename ".thy")))))))
+
+
+;;; "minor" sml-mode inside theory files ==========
+
+(defvar thy-minor-sml-mode-map nil)
+
+(defun thy-install-sml-mode ()
+ (progn
+ (require 'sml-mode)
+ (setq thy-minor-sml-mode-map (copy-keymap sml-mode-map))
+ ;; Bind TAB to what it should be in sml-mode.
+ (define-key thy-minor-sml-mode-map "\t" 'indent-for-tab-command)
+ (define-key thy-minor-sml-mode-map "\C-c\C-m" 'thy-mode-quiet)
+ (define-key thy-minor-sml-mode-map "\C-c\C-t" 'thy-insert-template)))
+
+(defun thy-minor-sml-mode ()
+ "Invoke sml-mode as if a minor mode inside a theory file.
+This has no effect if thy-use-sml-mode is nil."
+ (interactive)
+ (if thy-use-sml-mode
+ (progn
+ (if (not (boundp 'sml-mode))
+ (thy-install-sml-mode))
+ (kill-all-local-variables)
+ (sml-mode) ; Switch to sml-mode
+ (setq major-mode 'thy-mode)
+ (setq mode-name "Theory Sml") ; looks like it's a minor-mode.
+ (use-local-map thy-minor-sml-mode-map) ; special map has \C-c\C-c binding.
+ (make-local-variable 'indent-line-function)
+ (setq indent-line-function 'thy-do-sml-indent)
+ (force-mode-line-update)
+ (message "Use C-c C-c to exit SML mode."))))
+
+(defun thy-do-sml-indent ()
+ "Run sml-indent-line in an Isabelle theory file, provided inside ML section.
+If not, will turn off simulated minor mode and run thy-indent-line."
+ (interactive)
+ (if (string= (thy-current-section) "ML") ; NB: Assumes that TAB key was
+ (sml-indent-line) ; bound to sml-indent-line.
+ (thy-mode t) ; (at least, it is now!).
+ (thy-indent-line)))
+
+
+(defun thy-insert-name (name)
+ "Insert NAME -- as a string if there are non-alphabetic characters in NAME."
+ (if (string-match "[a-zA-Z]+" name)
+ (insert name)
+ (insert "\"" name "\"")))
+
+(defun thy-insert-class (name supers)
+ (interactive
+ (list
+ (isa-read-id "Class name: ")
+ (isa-read-idlist "Super classes %s: ")))
+ (insert name)
+ (if supers (insert "\t< " (isa-splice-separator ", " supers)))
+ (indent-according-to-mode)
+ (forward-line 1))
+
+(defun thy-insert-default-sort (sort)
+ (interactive
+ (list
+ (isa-read-id "Default sort: ")))
+ (insert sort)
+ (indent-according-to-mode)
+ (thy-goto-next-section))
+
+(defun thy-insert-type (name no-of-args)
+ (interactive
+ (list
+ (isa-read-id "Type name: ")
+ (isa-read-num "Number of arguments: ")))
+ ;; make type variables for arguments. Daft things for >26!
+ (cond
+ ((zerop no-of-args))
+ ((= 1 no-of-args)
+ (insert "'a "))
+ (t
+ (insert "(")
+ (let ((i 0))
+ (while (< i no-of-args)
+ (if (> i 0) (insert ","))
+ (insert "'" (+ ?a i))
+ (setq i (1+ i))))
+ (insert ") ")))
+ (thy-insert-name name)
+ (indent-according-to-mode)
+ ;; forward line, although use may wish to add infix.
+ (forward-line 1))
+
+(defun thy-insert-arity (name param-sorts result-class)
+ (interactive
+ (list
+ (isa-read-id "Type name: ")
+ (isa-read-idlist "Parameter sorts %s: ")
+ (isa-read-id "Result class: ")))
+ (insert name " :: ")
+ (if param-sorts
+ (insert "(" (isa-splice-separator ", " param-sorts) ") "))
+ (insert result-class)
+ (indent-according-to-mode)
+ (forward-line 1))
+
+(defun thy-insert-const (name type)
+ ;; only does a single constant, no lists.
+ (interactive
+ (let* ((thename (isa-read-id "Constant name: "))
+ (thetype (isa-read-string (format "Type of `%s' : " thename))))
+ (list thename thetype)))
+ (thy-insert-name name)
+ (insert " ::\t \"" type "\"\t\t")
+ (indent-according-to-mode)
+ ;; no forward line in case user adds mixfix
+ )
+
+(defun thy-insert-rule (name)
+ (interactive
+ (list
+ (isa-read-id "Axiom name: ")))
+ (end-of-line 1)
+ (insert name "\t\"\"")
+ (backward-char)
+ (indent-according-to-mode))
+
+(defun thy-insert-template ()
+ "Insert a syntax template according to the current section"
+ (interactive)
+ (thy-check-mode)
+ (let* ((sect (thy-current-section))
+ (tmpl (cdr-safe (assoc sect thy-sections))))
+ ;; Ensure point is at start of an empty line.
+ (beginning-of-line)
+ (skip-chars-forward "\t ")
+ (if (looking-at sect)
+ (progn
+ (forward-line 1)
+ (skip-chars-forward "\t ")))
+ (if (looking-at "$")
+ nil
+ (beginning-of-line)
+ (newline)
+ (forward-line -1))
+ (cond ((stringp tmpl)
+ (insert tmpl)
+ (indent-according-to-mode))
+ ((null tmpl)) ; nil is a symbol!
+ ((symbolp tmpl)
+ (call-interactively tmpl)))))
+
+;;; === Functions for reading from the minibuffer.
+;;;
+
+; These could be improved, e.g. to enforce syntax for identifiers.
+; Unfortunately, Xemacs, and now Emacs too, lack a
+; read-no-blanks-input function!
+
+(defun isa-read-idlist (prompt &optional init)
+ "Read a list of identifiers from the minibuffer."
+ (let ((items init) item)
+ (while (not (string= ""
+ (setq item (read-string
+ (format prompt (or items ""))))))
+ (setq items (nconc items (list item))))
+ items))
+
+(defun isa-read-id (prompt &optional init)
+ "Read an identifier from the minibuffer."
+ ;; don't allow empty input
+ (let ((result ""))
+ (while (string= result "")
+ (setq result (read-string prompt init)))
+ result))
+
+(defun isa-read-string (prompt &optional init)
+ "Read a non-empty string from the minibuffer"
+ ;; don't allow empty input
+ (let ((result ""))
+ (while (string= result "")
+ (setq result (read-string prompt init)))
+ result))
+
+(defun isa-read-num (prompt)
+ "Read a number from the minibuffer."
+ (read-number prompt t))
+
+;(defun thy-read-thy-name ()
+; (let* ((default (car
+; (isa-file-name-cons-extension
+; (file-name-nondirectory
+; (abbreviate-file-name (buffer-file-name)))))))
+; default))
+
+(defun thy-read-thy-name ()
+ (let* ((default (car
+ (isa-file-name-cons-extension
+ (file-name-nondirectory
+ (abbreviate-file-name (buffer-file-name))))))
+ (name (read-string
+ (format "Name of theory [default %s]: " default))))
+ (if (string= name "") default name)))
+
+(defun thy-read-logic-image ()
+ (let* ((defimage "Pure")
+ ;; (or (thy-guess-logic-in-use)
+ ;; "Pure"))
+
+ (logic (read-string
+ (format "Name of logic image to use [default %s]: "
+ defimage))))
+ (if (string= logic "") defimage logic)))
+
+(defun thy-insert-header (name logic parents)
+ "Insert a theory file header, for LOGIC, theory NAME with PARENTS"
+ (interactive
+ (list
+ (thy-read-thy-name)
+ (thy-read-logic-image)
+ (isa-read-idlist "Parent theory %s: ")))
+ (let* ((parentplus (isa-splice-separator
+ " + "
+ (or parents (list (or logic "Pure")))))
+ (formalist (list
+ (cons "%t" name)
+ (cons "%p" parentplus))))
+ (thy-insert-id-header name logic)
+ (insert (isa-format formalist thy-template)))
+ (goto-char (point-min))
+ (thy-goto-next-section))
+
+(defun thy-insert-id-header (name logic)
+ "Insert an identification header, for theory NAME logic image LOGIC."
+ (interactive
+ (list
+ (thy-read-thy-name)
+ (thy-read-logic-image)))
+ (let* ((formalist (list
+ (cons "%f" (buffer-file-name))
+ (cons "%t" name)
+ (cons "%l" logic))))
+ (insert (isa-format formalist thy-id-header))))
+
+(defun thy-check-mode ()
+ (if (not (eq major-mode 'thy-mode))
+ (error "Not in Theory mode.")))
+
+
+(defconst thy-headings-regexp
+ (concat
+ "^\\s-*\\("
+ (substring (apply 'concat (mapcar
+ '(lambda (pair)
+ (concat "\\|" (car pair)))
+ (cdr thy-sections))) 2)
+ "\\)[ \t]*")
+ "Regular expression matching headings in theory files.")
+
+(defvar thy-mode-font-lock-keywords
+ (list
+ (list (proof-ids-to-regexp
+ (append '("infixl" "infixr" "binder")
+ (mapcar 'car (cdr thy-sections))))
+ 0 'font-lock-keyword-face)
+ ;; FIXME: needs more work. Get symbols in quotes, etc, etc.
+ (list "\\s-*\\(\\w+\\)\\s-*\\(::?\\)"
+ 2 'font-lock-preprocessor-face)
+ (list "\\s-*\\(\\w+\\)\\s-*::?"
+ 1 'font-lock-variable-name-face)
+ (list "\".*\"\\s-*\\(::?\\)"
+ 1 'font-lock-preprocessor-face)
+ (list "\"\\(.*\\)\"\\s-*\\(::?\\)"
+ 1 'font-lock-variable-name-face))
+; (list "^\\s-*\\(\\w*\\)\\s-*\\(::\\)"
+; 1 'font-lock-function-name-face
+; 2 'font-lock-preprocessor-face))
+ "Font lock keywords for thy-mode.")
+
+;;; movement between sections ===================================
+
+(defun thy-goto-next-section (&optional count noerror)
+ "Goto the next (or COUNT'th next) section of a theory file.
+Negative value for count means previous sections.
+If NOERROR is non-nil, failed search will not be signalled."
+ (interactive "p")
+ (condition-case nil
+ ;; string matching would probably be good enough
+ (cond ((and count (< count 0))
+ (let ((oldp (point)))
+ (beginning-of-line)
+ (thy-goto-top-of-section)
+ ;; not quite right here - should go to top
+ ;; of file, like top of section does.
+ (if (equal (point) oldp)
+ (progn
+ (re-search-backward thy-headings-regexp
+ nil nil (1+ (- count)))
+ (forward-line 1))))
+ t)
+ (t
+ (re-search-forward thy-headings-regexp nil nil count)
+ (forward-line 1)
+ t))
+ ;; could just move to top or bottom if this happens, instead
+ ;; of giving this error.
+ (search-failed (if noerror nil
+ (error "No more headings")))))
+
+(defun thy-goto-prev-section (&optional count noerror)
+ "Goto the previous section (or COUNT'th previous) of a theory file.
+Negative value for count means following sections.
+If NOERROR is non-nil, failed search will not be signalled."
+ (interactive)
+ (thy-goto-next-section (if count (- count) -1) noerror))
+
+(defun thy-goto-top-of-section ()
+ "Goto the top of the current section"
+ (interactive)
+ (if (re-search-backward thy-headings-regexp nil t)
+ (forward-line 1)
+ (goto-char (point-min))))
+
+(defun thy-current-section ()
+ "Return the current section of the theory file, as a string.
+\"top\" indicates no section."
+ (save-excursion
+ (let* ((gotsect (re-search-backward thy-headings-regexp nil t))
+ (start (if gotsect
+ (progn
+ (skip-chars-forward " \t")
+ (point)))))
+ (if (not start)
+ "top"
+ (skip-chars-forward "a-zA-z")
+ (buffer-substring start (point))))))
+
+
+
+;;; kill line ==================================================
+
+(defun thy-kill-line (&optional arg)
+ "As kill-line, except in a string will kill continuation backslashes also.
+Coalesces multiple lined strings by leaving single spaces."
+ (interactive "P")
+ (let ((str (thy-string-start))
+ (kill-start (point))
+ following-slash)
+ (if (not str)
+ ;; Usual kill line if not inside a string.
+ (kill-line arg)
+ (if arg
+ (forward-line (prefix-numeric-value arg))
+ (if (eobp)
+ (signal 'end-of-buffer nil)))
+ (setq kill-start (point))
+ (if (thy-string-start str) ; if still inside a string
+ (cond
+ ((looking-at "[ \t]*$") ; at end of line bar whitespace
+ (skip-chars-backward
+ " \t"
+ (save-excursion (beginning-of-line) (1+ (point))))
+ (backward-char)
+ (if (looking-at "\\\\") ; preceding backslash
+ (progn
+ (skip-chars-backward " \t")
+ (setq following-slash t)
+ (setq kill-start (min (point) kill-start)))
+ (goto-char kill-start))
+ (forward-line 1))
+ ((looking-at "[ \t]*\\\\[ \t]*$") ; before final backslash
+ (setq following-slash t)
+ (forward-line 1))
+ ((looking-at "\\\\[ \t]*\\\\[ \t]*$") ; an empty line!
+ (forward-line 1))
+ ((looking-at ".*\\(\\\\\\)[ \t]*$") ; want to leave backslash
+ (goto-char (match-beginning 1)))
+ ((and kill-whole-line (bolp))
+ (forward-line 1))
+ (t
+ (end-of-line))))
+ (if (and following-slash
+ (looking-at "[ \t]*\\\\")) ; delete following slash if
+ (goto-char (1+ (match-end 0)))) ; there's one
+ (kill-region kill-start (point)) ; do kill
+ (if following-slash
+ ;; did do just-one-space, but it's not nice to delete backwards
+ ;; too
+ (delete-region (point)
+ (save-excursion
+ (skip-chars-forward " \t")
+ (point)))))))
+
+
+;;; INDENTATION ==================================================
+
+;;; Could do with thy-correct-string function,
+;;; which does roughly the same as indent-region.
+;;; Then we could have an electric " that did this!
+
+;;; Could perhaps have used fill-prefix to deal with backslash
+;;; indenting, rather than lengthy code below?
+
+(defun thy-indent-line ()
+ "Indent the current line in an Isabelle theory file.
+If in the ML section, this switches into a simulated minor sml-mode."
+ (let ((sect (thy-current-section)))
+ (cond
+ ((and thy-use-sml-mode (string= sect "ML"))
+ (progn ; In "ML" section,
+ (thy-minor-sml-mode) ; switch to sml mode.
+ (sml-indent-line)))
+
+ (t (let ((indent (thy-calculate-indentation sect)))
+ (save-excursion
+ (beginning-of-line)
+ (let ((beg (point)))
+ (skip-chars-forward "\t ")
+ (delete-region beg (point)))
+ (indent-to indent))
+ (if (< (current-column)
+ (current-indentation))
+ (skip-chars-forward "\t ")))))))
+
+;; Better Emacs major modes achieve a kind of "transparency" to
+;; the user, where special indentation,etc. happens under your feet, but
+;; in a useful way that you soon get accustomed to. Worse modes
+;; cause frustration and repetitive re-editing of automatic indentation.
+;; I hope I've achieved something in the first category...
+
+(defun thy-calculate-indentation (sect)
+ "Calculate the indentation for the current line.
+SECT should be the string name of the current section."
+ (save-excursion
+ (beginning-of-line)
+ (or (thy-long-comment-string-indentation)
+ (if (looking-at "\\s-*$")
+ ;; Empty lines use indentation for section.
+ (thy-indentation-for sect)
+ (if (looking-at thy-headings-regexp)
+ thy-heading-indent
+ (progn
+ (skip-chars-forward "\t ")
+ (cond
+ ;; A comment?
+ ((looking-at "(\\*")
+ (thy-indentation-for sect))
+ ;; Anything else, use indentation for section
+ (t (thy-indentation-for sect)))))))))
+
+(defun thy-long-comment-string-indentation ()
+ "Calculate the indentation if inside multi-line comment or string.
+Also indent string contents."
+ (let* ((comstr (thy-comment-or-string-start))
+ (bolpos (save-excursion
+ (beginning-of-line)
+ (point)))
+ (multi (and comstr
+ (< comstr bolpos))))
+ (if (not multi)
+ nil
+ (save-excursion
+ (beginning-of-line)
+ (cond
+
+ ;; Inside a comment?
+ ((char-equal (char-after comstr) ?\( )
+ (forward-line -1)
+ (if (looking-at "[\t ]*(\\*")
+ (+ 3 (current-indentation))
+ (current-indentation)))
+
+ ;; Otherwise, a string.
+ ;; Enforce correct backslashing on continuing
+ ;; line and return cons of backslash indentation
+ ;; and string contents indentation for continued
+ ;; line.
+ (t
+ (let ((quote-col (save-excursion (goto-char comstr)
+ (current-column))))
+ (if thy-indent-strings
+ (thy-string-indentation comstr)
+ ;; just to right of matching "
+ (+ quote-col 1)))))))))
+
+(defun thy-string-indentation (start)
+ ;; Guess indentation for text inside a string
+ (let* ((startcol (save-excursion (goto-char start) (current-column)))
+ (pps-state (parse-partial-sexp (1+ start) (point)))
+ (par-depth (car pps-state)))
+ (cond (;; If not in nested expression, startcol+1
+ (zerop par-depth)
+ (1+ startcol))
+ (;; If in a nested expression, use position of opening bracket
+ (natnump par-depth)
+ (save-excursion
+ (goto-char (nth 1 pps-state))
+ (+ (current-column)
+ (cond ((looking-at "\\[|") 3)
+ (t 1)))))
+ (;; Give error for too many closing parens
+ t
+ (error "Mismatched parentheses")))))
+
+(defun thy-indentation-for (sect)
+ "Return the indentation for section SECT"
+ (if (string-equal sect "top")
+ thy-heading-indent
+ thy-indent-level))
+
+(defun thy-string-start (&optional min)
+ "Return position of start of string if inside one, nil otherwise."
+ (let ((comstr (thy-comment-or-string-start)))
+ (if (and comstr
+ (save-excursion
+ (goto-char comstr)
+ (looking-at "\"")))
+ comstr)))
+
+;;; Is this parsing still too slow? (better way? e.g., try setting
+;;; variable "char" and examining it, rather than finding current
+;;; state first - fewer branches in non-interesting cases, perhaps.
+;;; NB: it won't understand escape sequences in strings, such as \"
+
+(defun thy-comment-or-string-start (&optional min)
+ "Find if point is in a comment or string, starting parse from MIN.
+Returns the position of the comment or string start or nil.
+If MIN is nil, starts from top of current section.
+
+Doesn't understand nested comments."
+ (or min
+ (setq min
+ (save-excursion
+ (thy-goto-top-of-section) (point))))
+ (if (<= (point) min)
+ nil
+ (let ((pos (point))
+ (incomdepth 0)
+ incom instring) ; char
+ (goto-char min)
+ (while (< (point) pos)
+ ;; When inside a string, only look for its end
+ (if instring
+ (if (eq (char-after (point)) ?\") ; looking-at "\""
+ (setq instring nil))
+ ;; If inside a comment, look for a comment end
+ (if (> 0 incomdepth)
+ (if (and ; looking-at "\\*)"
+ (eq (char-after (point)) ?\*)
+ (eq (char-after (1+ (point))) ?\)))
+ (setq incomdepth (1- incomdepth)))
+ ;; If inside neither comment nor string, look for
+ ;; a string start.
+ (if (eq (char-after (point)) ?\") ; looking-at "\""
+ (setq instring (point))))
+ ;; Look for a comment start (unless inside a string)
+ (if (and
+ (eq (char-after (point)) ?\()
+ (eq (char-after (1+ (point))) ?\*))
+ (progn
+ (if (= 0 incomdepth) ; record start of main comment
+ (setq incom (point))) ; only
+ (setq incomdepth (1+ incomdepth)))))
+ (forward-char))
+ (if (> 0 incomdepth) incom instring))))
+
+
+
+
+(provide 'thy-mode)
+
+;;; end of thy-mode.el
diff --git a/isa/todo b/isa/todo
new file mode 100644
index 00000000..8e68bc23
--- /dev/null
+++ b/isa/todo
@@ -0,0 +1,84 @@
+-*- mode:outline -*-
+
+* Things to do for Isabelle
+
+See also ../todo for generic things to do, priority codes.
+
+** D Isabelle: I think show_sorts -> show_types, how can we reflect this ?
+
+** D Fix mode naming for Isabelle
+ (might like isa-proofscript-mode -> isa-mode;
+ but this conflicts with entry mechanism for thy/isa mode).
+
+** D Might be nice to unify menus a little more, e.g. add Isabelle for .thy
+
+ But several of the ops there are not relevant for theory files.
+ Well, favourites at least. What we have at the moment is verging
+ GUI-atrocity: one shouldn't have menus of the same name with
+ different entries, but should rather use greyed out.
+
+** C Improvements to Isabelle that would be nice for Proof General:
+
+ -- ability to remove theorem from theorem database, issued
+ when undoing qed
+
+
+** C Investigate fix for looping rewriting in Isabelle. Continual
+ and frequent messages from the prover lock out the user.
+ Is there any easy way of fixing this?
+
+** C X-Symbol support for theory files: bugs at the moment, because
+ of duplicate calls to proof-x-symbol-mode and mess with
+ font-lock initialization. Problem with current version:
+ visit a.thy, b.thy then turn on xsym. Broken in b.thy.
+ Seems okay visiting new buffers after that.
+ Must also check interaction with xsym-isa-latex stuff
+ may be broken by removal of mode hook settings.
+ [DvO reports okay].
+ (May need to split extra modes into two parts?)
+
+** B auto-adjust Pretty.setmargin when window is resized. Use
+ generic code once it's implemented.
+
+** D Implement completion for Isabelle using tables generated by
+ the running process. Ideally context sensitive.
+ Would be a nice addition. (1 week)
+
+** D Add useful specific commands for Isabelle. Many could
+ be added. Would be better to merge in Isamode's menus.
+ (however, probably 2 week's work to bring together Isamode
+ and proof.el, making some of Isamode generic)
+
+** D Switching to other file with C-c C-o could be more savy
+ with file names and extensions (use some standard function?)
+
+** X weird bug: interrupting Isabelle process (under sml-nj) sometimes
+ doesn't return, why? (see first half of interrupt error only:
+
+ *** Interrupt.
+ *** At command "time_use".
+
+ uncaught exception ERROR
+ raised at: library.ML:1100.35-1100.40
+ But not "uncaught exception" part.
+ What is worse: prompt disappears! But process still seems to be
+ there underneath. Not sure where this bug comes from.
+
+ Moreover, killing process then hangs Emacs with message
+ "cleaning up", and get error
+ (1) (error/warning) Error in process sentinel: (no-catch exited t)
+
+ To see if this is some SML/NJ or Isabelle weirdness, test in
+ xterm: use "ROOT.ML", interrrupt, use "ROOT.ML" again.
+ sig 11! (flaky hardware?)
+ /usr/lib/Isabelle_22-Sep-1999/../../share/smlnj/bin/sml: Fatal error -- unexpected fault, signal = 11, code = 0x2ad09c43
+ Not reliably repeatable, but:
+ ProofGeneral.isa_restart();
+ /usr/lib/Isabelle_22-Sep-1999/../../share/smlnj/bin/sml: Fatal error -- unexpected fault, signal = 11, code = 0x2af9e01b
+
+** X Write perl scripts to generate TAGS file for ML and thy files.
+ (60h, any volunteers?) (hard);
+
+** X Manage multiple proofs, perhaps by automatically inserting
+ push_proof() and pop_proof() commands into the proof script.
+ But would lead to unholy mess for script management! (hard!)
diff --git a/isa/x-symbol-isabelle.el b/isa/x-symbol-isabelle.el
new file mode 100644
index 00000000..f9938491
--- /dev/null
+++ b/isa/x-symbol-isabelle.el
@@ -0,0 +1,410 @@
+;; ID: $Id$
+;; Author: David von Oheimb
+;; Copyright 1998 Technische Universitaet Muenchen
+;; token language "Isabelle Symbols" for package x-symbol
+;;
+;; NB: Part of Proof General distribution.
+;;
+
+(defvar x-symbol-isabelle-required-fonts nil)
+
+;; FIXME da: these next two are also set in proof-x-symbol.el, but
+;; it's handy to use this file away from PG. In future could
+;; fix things so just (require 'proof-x-symbol) would be enough
+;; here.
+(defvar x-symbol-isabelle-name "Isabelle Symbol")
+(defvar x-symbol-isabelle-modeline-name "isa")
+
+(defvar x-symbol-isabelle-header-groups-alist nil)
+;'(("Operator" bigop operator)
+; ("Relation" relation)
+; ("Arrow, Punctuation" arrow triangle shape
+; white line dots punctuation quote parenthesis)
+; ("Symbol" symbol currency mathletter setsymbol)
+; ("Greek Letter" greek greek1)
+; ("Acute, Grave" acute grave))
+; "*If non-nil, used in isasym specific grid/menu."
+
+(defvar x-symbol-isabelle-class-alist
+ '((VALID "Isabelle Symbol" (x-symbol-info-face))
+ (INVALID "no Isabelle Symbol" (red x-symbol-info-face))))
+(defvar x-symbol-isabelle-class-face-alist nil)
+(defvar x-symbol-isabelle-electric-ignore "[:'][A-Za-z]\\|<=\\|\\[\\[\\|\\]\\]\\|~=")
+
+
+;; Bold, super- and subscripts
+
+(defun x-symbol-isabelle-make-ctrl-regexp (s)
+ (concat "\\(\\\\?\\\\<\\^" s ">\\)\\(\\\\?\\\\<[A-Za-z][A-Za-z0-9_']*>\\|[^\\]\\)"))
+
+(defconst x-symbol-isabelle-font-lock-bold-regexp
+ (x-symbol-isabelle-make-ctrl-regexp "bold")
+ "Regexp matching bold marker in Isabelle.")
+
+(defconst x-symbol-isabelle-font-lock-scripts-regexp
+ (x-symbol-isabelle-make-ctrl-regexp "su[bp]")
+ "Regexp matching super- and subscript markers in Isabelle.")
+
+(defun x-symbol-isabelle-match-bold (limit)
+ ;; checkdoc-params: (limit)
+ "Match and skip over bold face.
+Return nil if `x-symbol-mode' is nil.
+Uses `x-symbol-isabelle-font-lock-bold-regexp'."
+ (and (proof-ass x-symbol-enable)
+ (or (proof-looking-at x-symbol-isabelle-font-lock-bold-regexp)
+ (proof-re-search-forward x-symbol-isabelle-font-lock-bold-regexp limit t))))
+
+(defun x-symbol-isabelle-match-scripts (limit)
+ ;; checkdoc-params: (limit)
+ "Match and skip over super- and subscripts.
+Return nil if `x-symbol-mode' is nil.
+Uses `x-symbol-isabelle-font-lock-scripts-regexp'."
+ (and (proof-ass x-symbol-enable)
+ (or (proof-looking-at x-symbol-isabelle-font-lock-scripts-regexp)
+ (proof-re-search-forward x-symbol-isabelle-font-lock-scripts-regexp limit t))))
+
+(defvar x-symbol-isabelle-font-lock-keywords
+ '((x-symbol-isabelle-match-bold
+ (1 x-symbol-invisible-face t)
+ (2 'underline prepend))
+ (x-symbol-isabelle-match-scripts
+ (1 x-symbol-invisible-face t)
+ (2 (if (or (eq (char-after (+ 5 (match-beginning 1))) ?b)
+ (eq (char-after (+ 6 (match-beginning 1))) ?b))
+ 'x-symbol-sub-face 'x-symbol-sup-face) prepend)))
+ "Isabelle font-lock keywords for bold, super- and subscripts.")
+
+
+(defvar x-symbol-isabelle-master-directory 'ignore)
+(defvar x-symbol-isabelle-image-searchpath '("./"))
+(defvar x-symbol-isabelle-image-cached-dirs '("images/" "pictures/"))
+(defvar x-symbol-isabelle-image-file-truename-alist nil)
+(defvar x-symbol-isabelle-image-keywords nil)
+
+(defvar x-symbol-isabelle-case-insensitive nil)
+;(defvar x-symbol-isabelle-token-shape '(?\\ "\\\\\\<[A-Za-z][A-Za-z0-9_']*>\\a'" . "[A-Za-z]"))
+(defvar x-symbol-isabelle-token-shape nil)
+
+(defvar x-symbol-isabelle-exec-specs '(nil ("\\`\\\\<[A-Za-z][A-Za-z0-9_']*>\\'" .
+ "\\\\<[A-Za-z][A-Za-z0-9_']*>")))
+
+(defvar x-symbol-isabelle-input-token-ignore nil)
+(defun x-symbol-isabelle-default-token-list (tokens) tokens)
+
+
+(defvar x-symbol-isabelle-token-list 'x-symbol-isabelle-default-token-list)
+
+(defvar x-symbol-isabelle-symbol-table ; symbols (isabelle font)
+ '((visiblespace "\\<spacespace>")
+ (Gamma "\\<Gamma>")
+ (Delta "\\<Delta>")
+ (Theta "\\<Theta>")
+ (Lambda "\\<Lambda>")
+ (Pi "\\<Pi>")
+ (Sigma "\\<Sigma>")
+ (Phi "\\<Phi>")
+ (Psi "\\<Psi>")
+ (Omega "\\<Omega>")
+ (alpha "\\<alpha>")
+ (beta "\\<beta>")
+ (gamma "\\<gamma>")
+ (delta "\\<delta>")
+ (epsilon1 "\\<epsilon>")
+ (zeta "\\<zeta>")
+ (eta "\\<eta>")
+ (theta "\\<theta>")
+ (kappa1 "\\<kappa>")
+ (lambda "\\<lambda>")
+ (mu "\\<mu>")
+ (nu "\\<nu>")
+ (xi "\\<xi>")
+ (pi "\\<pi>")
+ (rho1 "\\<rho>")
+ (sigma "\\<sigma>")
+ (tau "\\<tau>")
+ (phi1 "\\<phi>")
+ (chi "\\<chi>")
+ (psi "\\<psi>")
+ (omega "\\<omega>")
+ (notsign "\\<not>")
+ (logicaland "\\<and>")
+ (logicalor "\\<or>")
+ (universal1 "\\<forall>")
+ (existential1 "\\<exists>")
+ (biglogicaland "\\<And>")
+ (ceilingleft "\\<lceil>")
+ (ceilingright "\\<rceil>")
+ (floorleft "\\<lfloor>")
+ (floorright "\\<rfloor>")
+ (bardash "\\<turnstile>")
+ (bardashdbl "\\<Turnstile>")
+ (semanticsleft "\\<lbrakk>")
+ (semanticsright "\\<rbrakk>")
+ (periodcentered "\\<cdot>")
+ (element "\\<in>")
+ (reflexsubset "\\<subseteq>")
+ (intersection "\\<inter>")
+ (union "\\<union>")
+ (bigintersection "\\<Inter>")
+ (bigunion "\\<Union>")
+ (sqintersection "\\<sqinter>")
+ (squnion "\\<squnion>")
+ (bigsqintersection "\\<Sqinter>")
+ (bigsqunion "\\<Squnion>")
+ (perpendicular "\\<bottom>")
+ (dotequal "\\<doteq>")
+ (wrong "\\<wrong>")
+ (equivalence "\\<equiv>")
+ (notequal "\\<noteq>")
+ (propersqsubset "\\<sqsubset>")
+ (reflexsqsubset "\\<sqsubseteq>")
+ (properprec "\\<prec>")
+ (reflexprec "\\<preceq>")
+ (propersucc "\\<succ>")
+ (approxequal "\\<approx>")
+ (similar "\\<sim>")
+ (simequal "\\<simeq>")
+ (lessequal "\\<le>")
+ (coloncolon "\\<Colon>")
+ (arrowleft "\\<leftarrow>")
+ (endash "\\<midarrow>")
+ (arrowright "\\<rightarrow>")
+ (arrowdblleft "\\<Leftarrow>")
+; (nil "\\<Midarrow>")
+ (arrowdblright "\\<Rightarrow>")
+ (frown "\\<frown>")
+ (mapsto "\\<mapsto>")
+ (leadsto "\\<leadsto>")
+ (arrowup "\\<up>")
+ (arrowdown "\\<down>")
+ (notelement "\\<notin>")
+ (multiply "\\<times>")
+ (circleplus "\\<oplus>")
+ (circleminus "\\<ominus>")
+ (circlemultiply "\\<otimes>")
+ (circleslash "\\<oslash>")
+ (propersubset "\\<subset>")
+ (infinity "\\<infinity>")
+ (box "\\<box>")
+ (lozenge1 "\\<diamond>")
+ (circ "\\<circ>")
+ (bullet "\\<bullet>")
+ (bardbl "\\<parallel>")
+ (radical "\\<surd>")
+ (copyright "\\<copyright>")))
+
+(defvar x-symbol-isabelle-xsymbol-table ; xsymbols
+ '((Xi "\\<Xi>")
+ (Upsilon1 "\\<Upsilon>")
+ (iota "\\<iota>")
+ (upsilon "\\<upsilon>")
+ (plusminus "\\<plusminus>")
+ (division "\\<div>")
+ (longarrowright "\\<longrightarrow>")
+ (longarrowleft "\\<longleftarrow>")
+ (longarrowboth "\\<longleftrightarrow>")
+ (longarrowdblright "\\<Longrightarrow>")
+ (longarrowdblleft "\\<Longleftarrow>")
+ (longarrowdblboth "\\<Longleftrightarrow>")
+ (brokenbar "\\<bar>")
+ (hyphen "\\<hyphen>")
+ (macron "\\<inverse>")
+ (exclamdown "\\<exclamdown>")
+ (questiondown "\\<questiondown>")
+ (guillemotleft "\\<guillemotleft>")
+ (guillemotright "\\<guillemotright>")
+ (degree "\\<degree>")
+ (onesuperior "\\<onesuperior>")
+ (onequarter "\\<onequarter>")
+ (twosuperior "\\<twosuperior>")
+ (onehalf "\\<onehalf>")
+ (threesuperior "\\<threesuperior>")
+ (threequarters "\\<threequarters>")
+ (paragraph "\\<paragraph>")
+ (registered "\\<registered>")
+ (ordfeminine "\\<ordfeminine>")
+ (masculine "\\<ordmasculine>")
+ (section "\\<section>")
+ (sterling "\\<pounds>")
+ (yen "\\<yen>")
+ (cent "\\<cent>")
+ (currency "\\<currency>")
+ (braceleft2 "\\<lbrace>")
+ (braceright2 "\\<rbrace>")
+ (top "\\<top>")
+ (congruent "\\<cong>")
+ (club "\\<clubsuit>")
+ (diamond "\\<diamondsuit>")
+ (heart "\\<heartsuit>")
+ (spade "\\<spadesuit>")
+ (arrowboth "\\<leftrightarrow>")
+ (greaterequal "\\<ge>")
+ (proportional "\\<propto>")
+ (partialdiff "\\<partial>")
+ (ellipsis "\\<dots>")
+ (aleph "\\<aleph>")
+ (Ifraktur "\\<Im>")
+ (Rfraktur "\\<Re>")
+ (weierstrass "\\<wp>")
+ (emptyset "\\<emptyset>")
+ (angle "\\<angle>")
+ (gradient "\\<nabla>")
+ (product "\\<Prod>")
+ (arrowdblboth "\\<Leftrightarrow>")
+ (arrowdblup "\\<Up>")
+ (arrowdbldown "\\<Down>")
+ (angleleft "\\<langle>")
+ (angleright "\\<rangle>")
+ (summation "\\<Sum>")
+ (integral "\\<integral>")
+ (circleintegral "\\<ointegral>")
+ (dagger "\\<dagger>")
+ (sharp "\\<sharp>")
+ (star "\\<star>")
+ (smltriangleright "\\<triangleright>")
+ (triangleleft "\\<lhd>")
+ (triangle "\\<triangle>")
+ (triangleright "\\<rhd>")
+ (trianglelefteq "\\<unlhd>")
+ (trianglerighteq "\\<unrhd>")
+ (smltriangleleft "\\<triangleleft>")
+ (natural "\\<natural>")
+ (flat "\\<flat>")
+ (amalg "\\<amalg>")
+ (Mho "\\<mho>")
+ (arrowupdown "\\<updown>")
+ (longmapsto "\\<longmapsto>")
+ (arrowdblupdown "\\<Updown>")
+ (hookleftarrow "\\<hookleftarrow>")
+ (hookrightarrow "\\<hookrightarrow>")
+ (rightleftharpoons "\\<rightleftharpoons>")
+ (leftharpoondown "\\<leftharpoondown>")
+ (rightharpoondown "\\<rightharpoondown>")
+ (leftharpoonup "\\<leftharpoonup>")
+ (rightharpoonup "\\<rightharpoonup>")
+ (asym "\\<asymp>")
+ (minusplus "\\<minusplus>")
+ (bowtie "\\<bowtie>")
+ (centraldots "\\<cdots>")
+ (circledot "\\<odot>")
+ (propersuperset "\\<supset>")
+ (reflexsuperset "\\<supseteq>")
+ (propersqsuperset "\\<sqsupset>")
+ (reflexsqsuperset "\\<sqsupseteq>")
+ (lessless "\\<lless>")
+ (greatergreater "\\<ggreater>")
+ (unionplus "\\<uplus>")
+ (smile "\\<smile>")
+ (reflexsucc "\\<succeq>")
+ (dashbar "\\<stileturn>")
+ (biglogicalor "\\<Or>")
+ (bigunionplus "\\<Uplus>")
+ (daggerdbl "\\<ddagger>")
+ (bigbowtie "\\<Join>")
+ (booleans "\\<bool>")
+ (complexnums "\\<complex>")
+ (natnums "\\<nat>")
+ (rationalnums "\\<rat>")
+ (realnums "\\<real>")
+ (integers "\\<int>")
+ (lesssim "\\<lesssim>")
+ (greatersim "\\<greatersim>")
+ (lessapprox "\\<lessapprox>")
+ (greaterapprox "\\<greaterapprox>")
+ (definedas "\\<triangleq>")
+ (cataleft "\\<lparr>")
+ (cataright "\\<rparr>")
+ (bigcircledot "\\<Odot>")
+ (bigcirclemultiply "\\<Otimes>")
+ (bigcircleplus "\\<Oplus>")
+ (coproduct "\\<Coprod>")
+ (cedilla "\\<cedilla>")
+ (diaeresis "\\<dieresis>")
+ (acute "\\<acute>")
+ (hungarumlaut "\\<hungarumlaut>")
+ (lozenge "\\<lozenge>")
+ (smllozenge "\\<struct>")
+ (dotlessi "\\<index>")
+ (euro "\\<euro>")
+ (zero1 "\\<zero>")
+ (one1 "\\<one>")
+ (two1 "\\<two>")
+ (three1 "\\<three>")
+ (four1 "\\<four>")
+ (five1 "\\<five>")
+ (six1 "\\<six>")
+ (seven1 "\\<seven>")
+ (eight1 "\\<eight>")
+ (nine1 "\\<nine>")
+ ))
+
+(defun x-symbol-isabelle-prepare-table (table)
+ (let*
+ ((is-isar (eq proof-assistant-symbol 'isar))
+ (prfx1 (if is-isar "" "\\"))
+ (prfx2 (if is-isar "\\" "")))
+ (mapcar (lambda (entry)
+ (list (car entry) '() (concat prfx1 (cadr entry)) (concat prfx2 (cadr entry))))
+ table)))
+
+(defvar x-symbol-isabelle-table
+ (x-symbol-isabelle-prepare-table
+ (append
+ (if (boundp 'x-symbol-isabelle-user-table) x-symbol-isabelle-user-table nil)
+ x-symbol-isabelle-symbol-table
+ x-symbol-isabelle-xsymbol-table)))
+
+(defvar x-symbol-user-table
+ (append
+ (if (boundp 'x-symbol-user-table) x-symbol-user-table nil)
+ '((bardash 180 (arrow) (direction east . perpendicular) nil (t "|-"))
+ (bardashdbl 182 (arrow) (direction east) nil (t "|=")))))
+
+
+;;;===========================================================================
+;;; Internal
+;;;===========================================================================
+
+(defvar x-symbol-isabelle-menu-alist nil
+ "Internal. Alist used for Isasym specific menu.")
+(defvar x-symbol-isabelle-grid-alist nil
+ "Internal. Alist used for Isasym specific grid.")
+
+(defvar x-symbol-isabelle-decode-atree nil
+ "Internal. Atree used by `x-symbol-token-input'.")
+(defvar x-symbol-isabelle-decode-alist nil
+ "Internal. Alist used for decoding of Isasym macros.")
+(defvar x-symbol-isabelle-encode-alist nil
+ "Internal. Alist used for encoding to Isasym macros.")
+
+(defvar x-symbol-isabelle-nomule-decode-exec nil
+ "Internal. File name of Isasym decode executable.")
+(defvar x-symbol-isabelle-nomule-encode-exec nil
+ "Internal. File name of Isasym encode executable.")
+
+
+
+;;;===========================================================================
+;;; useful key bindings
+;;;===========================================================================
+
+
+;; FIXME: these break some standard bindings, and should only be set
+;; for proof shell, script (or minibuffer) modes.
+
+;(global-set-key [(meta l)] 'x-symbol-INSERT-lambda)
+
+;(global-set-key [(meta n)] 'x-symbol-INSERT-notsign)
+;(global-set-key [(meta a)] 'x-symbol-INSERT-logicaland)
+;(global-set-key [(meta o)] 'x-symbol-INSERT-logicalor)
+;(global-set-key [(meta f)] 'x-symbol-INSERT-universal1)
+;(global-set-key [(meta t)] 'x-symbol-INSERT-existential1)
+
+;(global-set-key [(meta A)] 'x-symbol-INSERT-biglogicaland)
+;(global-set-key [(meta e)] 'x-symbol-INSERT-equivalence)
+;(global-set-key [(meta u)] 'x-symbol-INSERT-notequal)
+;(global-set-key [(meta m)] 'x-symbol-INSERT-arrowdblright)
+
+;(global-set-key [(meta i)] 'x-symbol-INSERT-longarrowright)
+
+(provide 'x-symbol-isabelle)
diff --git a/isar/BUGS b/isar/BUGS
new file mode 100644
index 00000000..88d9b757
--- /dev/null
+++ b/isar/BUGS
@@ -0,0 +1,7 @@
+-*- mode:outline -*-
+
+* Isabelle/Isar Proof General Bugs
+
+See also ../BUGS for generic bugs.
+
+Nothing specific here.
diff --git a/isar/Example.thy b/isar/Example.thy
new file mode 100644
index 00000000..4cf33e0b
--- /dev/null
+++ b/isar/Example.thy
@@ -0,0 +1,49 @@
+(* -*- isar -*-
+
+ Example proof document for Isabelle/Isar Proof General.
+
+ $Id$
+
+ The first line forces Isabelle/Isar Proof General, otherwise
+ you may get the theory mode of ordinary Isabelle Proof General
+ See the manual for other ways to select Isabelle/Isar PG.
+*)
+
+theory Example = Main:
+
+text {* Proper proof text -- naive version. *}
+
+theorem and_comms: "A & B --> B & A"
+proof
+ assume "A & B"
+ then show "B & A"
+ proof
+ assume B and A
+ then show ?thesis ..
+ qed
+qed
+
+
+text {* Proper proof text -- advanced version. *}
+
+theorem "A & B --> B & A"
+proof
+ assume "A & B"
+ then obtain B and A ..
+ then show "B & A" ..
+qed
+
+
+text {* Unstructured proof script. *}
+
+theorem "A & B --> B & A"
+ apply (rule impI)
+ apply (erule conjE)
+ apply (rule conjI)
+ apply assumption
+ apply assumption
+done
+
+end
+
+(* comment at the end *)
diff --git a/isar/README b/isar/README
new file mode 100644
index 00000000..beac6b96
--- /dev/null
+++ b/isar/README
@@ -0,0 +1,35 @@
+Isabelle/Isar Proof General
+
+Written by Markus Wenzel
+
+Status: supported
+Maintainer: Markus Wenzel
+Isabelle versions: Isabelle99-1, Isabelle99-2, Isabelle2002
+Isabelle homepage: http://www.cl.cam.ac.uk/Research/HVG/Isabelle/
+Isar homepage: http://isabelle.in.tum.de/Isar/
+
+========================================
+
+Isabelle/Isar Proof General has full support for multiple file
+scripting, with dependencies between theories communicated between
+Isabelle and Proof General.
+
+There is proper support for X Symbol, using the Isabelle print mode
+for X Symbol tokens. Many Isabelle theories have X Symbol syntax
+already defined and it's easy to add to your own theories.
+
+There is no support for proof by pointing yet, and no tags program.
+
+The script `interface' and file 'interface-setup.el' are used
+internally to start Isabelle Proof General via the 'Isabelle' shell
+command. This is the default way to invoke Proof General from the
+Isabelle perspective; it enables Isabelle to provide a consistent
+process and file-system environment, including the all-important
+isar-keywords.el file.
+
+Check the value of isabelle-prog-name.
+
+========================================
+
+$Id$
+
diff --git a/isar/interface b/isar/interface
new file mode 100644
index 00000000..46c78a58
--- /dev/null
+++ b/isar/interface
@@ -0,0 +1,236 @@
+#!/usr/bin/env bash
+#
+# $Id$
+#
+# Proof General interface wrapper for Isabelle.
+
+
+## self references
+
+THIS=$(cd "$(dirname "$0")"; pwd)
+SUPER=$(cd "$THIS/.."; pwd)
+KIND=$(basename "$(dirname "$0")")
+
+if [ "$KIND" = isar ]; then
+ ISAR=true
+else
+ ISAR=false
+fi
+
+
+## diagnostics
+
+usage()
+{
+ echo
+ echo "Usage: Isabelle [OPTIONS] [FILES ...]"
+ echo
+ echo " Options are:"
+ echo " -I BOOL use Isabelle/Isar instead of classic Isabelle (default $ISAR)"
+ echo " -P BOOL actually start Proof General (default true), otherwise"
+ echo " run plain tty session"
+ echo " -X BOOL configure the X-Symbol package on startup (default true)"
+ echo " -g GEOMETRY specify Emacs geometry"
+ echo " -k NAME use specific isar-keywords for named logic"
+ echo " -l NAME logic image name (default \$ISABELLE_LOGIC=$ISABELLE_LOGIC)"
+ echo " -m MODE add print mode for output"
+ echo " -p NAME Emacs program name (default xemacs)"
+ echo " -u BOOL use personal .emacs file (default true)"
+ echo " -w BOOL use window system (default true)"
+ echo " -x BOOL enable the X-Symbol package on startup (default false)"
+ echo
+ echo "Starts Proof General for Isabelle with theory and proof FILES"
+ echo "(default Scratch.thy)."
+ echo
+ echo " PROOFGENERAL_OPTIONS=$PROOFGENERAL_OPTIONS"
+ echo
+ exit 1
+}
+
+fail()
+{
+ echo "$1" >&2
+ exit 2
+}
+
+
+## process command line
+
+# options
+
+ISABELLE_OPTIONS=""
+START_PG="true"
+GEOMETRY=""
+KEYWORDS=""
+LOGIC="$ISABELLE_LOGIC"
+PROGNAME="xemacs"
+INITFILE="true"
+WINDOWSYSTEM="true"
+XSYMBOL=""
+XSYMBOLSETUP=true
+
+getoptions()
+{
+ OPTIND=1
+ while getopts "I:P:X:g:k:l:m:p:u:w:x:" OPT
+ do
+ case "$OPT" in
+ I)
+ ISAR="$OPTARG"
+ ;;
+ P)
+ START_PG="$OPTARG"
+ ;;
+ X)
+ XSYMBOLSETUP="$OPTARG"
+ ;;
+ g)
+ GEOMETRY="$OPTARG"
+ ;;
+ k)
+ KEYWORDS="$OPTARG"
+ ;;
+ l)
+ LOGIC="$OPTARG"
+ ;;
+ m)
+ if [ -z "$ISABELLE_OPTIONS" ]; then
+ ISABELLE_OPTIONS="-m $OPTARG"
+ else
+ ISABELLE_OPTIONS="$ISABELLE_OPTIONS -m $OPTARG"
+ fi
+ ;;
+ p)
+ PROGNAME="$OPTARG"
+ ;;
+ u)
+ INITFILE="$OPTARG"
+ ;;
+ w)
+ WINDOWSYSTEM="$OPTARG"
+ ;;
+ x)
+ XSYMBOL="$OPTARG"
+ ;;
+ \?)
+ usage
+ ;;
+ esac
+ done
+}
+
+getoptions $PROOFGENERAL_OPTIONS
+
+getoptions "$@"
+shift $(($OPTIND - 1))
+
+if [ "$ISAR" = true ]; then
+ KIND=isar
+ DEFAULT_FILES="Scratch.thy"
+else
+ KIND=isa
+ DEFAULT_FILES="Scratch.thy Scratch.ML"
+fi
+
+
+# args
+
+if [ "$#" -eq 0 ]; then
+ FILES="$DEFAULT_FILES"
+else
+ FILES=""
+ while [ "$#" -gt 0 ]; do
+ FILES="$FILES '$1'"
+ shift
+ done
+fi
+
+
+## smart X11 font installation
+
+function checkfonts ()
+{
+ XLSFONTS=$(xlsfonts -fn "-xsymb-xsymb0-*" 2>&1) || return 1
+
+ case "$XLSFONTS" in
+ xlsfonts:*)
+ return 1
+ ;;
+ esac
+
+ return 0
+}
+
+function installfonts ()
+{
+ checkfonts "$XSYMBOL_PATTERN" || eval $XSYMBOL_INSTALLFONTS
+}
+
+
+## main
+
+if [ "$START_PG" = false ]; then
+
+ [ "$ISAR" = true ] && ISABELLE_OPTIONS="$ISABELLE_OPTIONS -I"
+ exec "$ISABELLE" $ISABELLE_OPTIONS "$LOGIC"
+
+else
+
+ ARGS=""
+
+ [ -n "$GEOMETRY" ] && ARGS="$ARGS -geometry '$GEOMETRY'"
+
+ [ "$INITFILE" = false ] && ARGS="$ARGS -q"
+
+ if [ "$WINDOWSYSTEM" = true -a -n "$DISPLAY" ]; then
+ ARGS="$ARGS -T Isabelle"
+ [ -n "$XSYMBOL_INSTALLFONTS" -a "$XSYMBOLSETUP" = true ] && installfonts
+ else
+ ARGS="$ARGS -nw"
+ XSYMBOL=false
+ fi
+
+ [ ! "$XSYMBOLSETUP" = true ] && XSYMBOL_HOME=""
+
+
+ ARGS="$ARGS -l '$SUPER/isa/interface-setup.el'"
+
+ if [ -n "$KEYWORDS" ]; then
+ if [ -f "$ISABELLE_HOME_USER/etc/isar-keywords-$KEYWORDS.el" ]; then
+ ARGS="$ARGS -l '$ISABELLE_HOME_USER/etc/isar-keywords-$KEYWORDS.el'"
+ elif [ -f "$ISABELLE_HOME/etc/isar-keywords-$KEYWORDS.el" ]; then
+ ARGS="$ARGS -l '$ISABELLE_HOME/etc/isar-keywords-$KEYWORDS.el'"
+ else
+ fail "No isar-keywords file for '$KEYWORDS'"
+ fi
+ elif [ -f "$ISABELLE_HOME_USER/etc/isar-keywords.el" ]; then
+ ARGS="$ARGS -l '$ISABELLE_HOME_USER/etc/isar-keywords.el'"
+ elif [ -f "$ISABELLE_HOME/etc/isar-keywords.el" ]; then
+ ARGS="$ARGS -l '$ISABELLE_HOME/etc/isar-keywords.el'"
+ fi
+
+ for FILE in "$ISABELLE_HOME/etc/proofgeneral-settings.el" \
+ "$ISABELLE_HOME_USER/etc/proofgeneral-settings.el"
+ do
+ [ -f "$FILE" ] && ARGS="$ARGS -l '$FILE'"
+ done
+
+ case "$LOGIC" in
+ /*)
+ ;;
+ */*)
+ LOGIC="$PWD/$LOGIC"
+ ;;
+ esac
+
+ PROOFGENERAL_HOME="$SUPER"
+ PROOFGENERAL_ASSISTANTS="$KIND"
+ PROOFGENERAL_LOGIC="$LOGIC"
+ PROOFGENERAL_XSYMBOL="$XSYMBOL"
+
+ export PROOFGENERAL_HOME PROOFGENERAL_ASSISTANTS PROOFGENERAL_LOGIC PROOFGENERAL_XSYMBOL
+ export ISABELLE_OPTIONS
+
+ eval exec "$PROGNAME" "$ARGS" "$FILES"
+
+fi
diff --git a/isar/isar-keywords.el b/isar/isar-keywords.el
new file mode 100644
index 00000000..62ef9497
--- /dev/null
+++ b/isar/isar-keywords.el
@@ -0,0 +1,396 @@
+;;
+;; Keyword classification tables for Isabelle/Isar.
+;; This file generated by Isabelle99-2 -- DO NOT EDIT!
+;;
+;; $Id$
+;;
+
+(defconst isar-keywords-major
+ '("\\."
+ "\\.\\."
+ "ML"
+ "ML_command"
+ "ML_setup"
+ "ProofGeneral\\.context_thy_only"
+ "ProofGeneral\\.inform_file_processed"
+ "ProofGeneral\\.inform_file_retracted"
+ "ProofGeneral\\.kill_proof"
+ "ProofGeneral\\.restart"
+ "ProofGeneral\\.try_context_thy_only"
+ "ProofGeneral\\.undo"
+ "also"
+ "apply"
+ "apply_end"
+ "arities"
+ "assume"
+ "automaton"
+ "axclass"
+ "axioms"
+ "back"
+ "by"
+ "cannot_undo"
+ "case"
+ "cd"
+ "chapter"
+ "classes"
+ "classrel"
+ "clear_undos"
+ "coinductive"
+ "commit"
+ "constdefs"
+ "consts"
+ "context"
+ "datatype"
+ "declare"
+ "def"
+ "defaultsort"
+ "defer"
+ "defer_recdef"
+ "defs"
+ "disable_pr"
+ "done"
+ "enable_pr"
+ "end"
+ "exit"
+ "finally"
+ "fix"
+ "from"
+ "global"
+ "have"
+ "header"
+ "hence"
+ "hide"
+ "inductive"
+ "inductive_cases"
+ "init_toplevel"
+ "instance"
+ "judgment"
+ "kill"
+ "kill_thy"
+ "lemma"
+ "lemmas"
+ "let"
+ "local"
+ "method_setup"
+ "moreover"
+ "next"
+ "nonterminals"
+ "note"
+ "obtain"
+ "oops"
+ "oracle"
+ "parse_ast_translation"
+ "parse_translation"
+ "pr"
+ "prefer"
+ "presume"
+ "pretty_setmargin"
+ "primrec"
+ "print_antiquotations"
+ "print_ast_translation"
+ "print_attributes"
+ "print_binds"
+ "print_cases"
+ "print_claset"
+ "print_commands"
+ "print_context"
+ "print_facts"
+ "print_methods"
+ "print_simpset"
+ "print_syntax"
+ "print_theorems"
+ "print_theory"
+ "print_trans_rules"
+ "print_translation"
+ "proof"
+ "prop"
+ "pwd"
+ "qed"
+ "quit"
+ "recdef"
+ "recdef_tc"
+ "record"
+ "redo"
+ "remove_thy"
+ "rep_datatype"
+ "sect"
+ "section"
+ "setup"
+ "show"
+ "sorry"
+ "subsect"
+ "subsection"
+ "subsubsect"
+ "subsubsection"
+ "syntax"
+ "term"
+ "text"
+ "text_raw"
+ "then"
+ "theorem"
+ "theorems"
+ "theory"
+ "thm"
+ "thm_deps"
+ "thms_containing"
+ "thus"
+ "token_translation"
+ "touch_all_thys"
+ "touch_child_thys"
+ "touch_thy"
+ "translations"
+ "txt"
+ "txt_raw"
+ "typ"
+ "typed_print_translation"
+ "typedecl"
+ "typedef"
+ "types"
+ "ultimately"
+ "undo"
+ "undos_proof"
+ "update_thy"
+ "update_thy_only"
+ "use"
+ "use_thy"
+ "use_thy_only"
+ "welcome"
+ "with"
+ "{"
+ "}"))
+
+(defconst isar-keywords-minor
+ '("actions"
+ "and"
+ "binder"
+ "compose"
+ "con_defs"
+ "concl"
+ "congs"
+ "distinct"
+ "files"
+ "hide_action"
+ "hints"
+ "in"
+ "induction"
+ "infixl"
+ "infixr"
+ "initially"
+ "inject"
+ "inputs"
+ "internals"
+ "intros"
+ "is"
+ "monos"
+ "output"
+ "outputs"
+ "overloaded"
+ "post"
+ "pre"
+ "rename"
+ "restrict"
+ "signature"
+ "states"
+ "to"
+ "transitions"
+ "transrel"
+ "using"
+ "where"))
+
+(defconst isar-keywords-control
+ '("ProofGeneral\\.context_thy_only"
+ "ProofGeneral\\.inform_file_processed"
+ "ProofGeneral\\.inform_file_retracted"
+ "ProofGeneral\\.kill_proof"
+ "ProofGeneral\\.restart"
+ "ProofGeneral\\.try_context_thy_only"
+ "ProofGeneral\\.undo"
+ "cannot_undo"
+ "clear_undos"
+ "exit"
+ "init_toplevel"
+ "kill"
+ "quit"
+ "redo"
+ "undo"
+ "undos_proof"))
+
+(defconst isar-keywords-diag
+ '("ML"
+ "ML_command"
+ "cd"
+ "commit"
+ "disable_pr"
+ "enable_pr"
+ "header"
+ "kill_thy"
+ "pr"
+ "pretty_setmargin"
+ "print_antiquotations"
+ "print_attributes"
+ "print_binds"
+ "print_cases"
+ "print_claset"
+ "print_commands"
+ "print_context"
+ "print_facts"
+ "print_methods"
+ "print_simpset"
+ "print_syntax"
+ "print_theorems"
+ "print_theory"
+ "print_trans_rules"
+ "prop"
+ "pwd"
+ "remove_thy"
+ "term"
+ "thm"
+ "thm_deps"
+ "thms_containing"
+ "touch_all_thys"
+ "touch_child_thys"
+ "touch_thy"
+ "typ"
+ "update_thy"
+ "update_thy_only"
+ "use"
+ "use_thy"
+ "use_thy_only"
+ "welcome"))
+
+(defconst isar-keywords-theory-begin
+ '("theory"))
+
+(defconst isar-keywords-theory-switch
+ '("context"))
+
+(defconst isar-keywords-theory-end
+ '("end"))
+
+(defconst isar-keywords-theory-heading
+ '("chapter"
+ "section"
+ "subsection"
+ "subsubsection"))
+
+(defconst isar-keywords-theory-decl
+ '("ML_setup"
+ "arities"
+ "automaton"
+ "axclass"
+ "axioms"
+ "classes"
+ "classrel"
+ "coinductive"
+ "constdefs"
+ "consts"
+ "datatype"
+ "defaultsort"
+ "defer_recdef"
+ "defs"
+ "global"
+ "hide"
+ "inductive"
+ "judgment"
+ "lemmas"
+ "local"
+ "method_setup"
+ "nonterminals"
+ "oracle"
+ "parse_ast_translation"
+ "parse_translation"
+ "primrec"
+ "print_ast_translation"
+ "print_translation"
+ "recdef"
+ "record"
+ "rep_datatype"
+ "setup"
+ "syntax"
+ "text"
+ "text_raw"
+ "theorems"
+ "token_translation"
+ "translations"
+ "typed_print_translation"
+ "typedecl"
+ "types"))
+
+(defconst isar-keywords-theory-script
+ '("declare"
+ "inductive_cases"))
+
+(defconst isar-keywords-theory-goal
+ '("instance"
+ "lemma"
+ "recdef_tc"
+ "theorem"
+ "typedef"))
+
+(defconst isar-keywords-qed
+ '("\\."
+ "\\.\\."
+ "by"
+ "done"
+ "sorry"))
+
+(defconst isar-keywords-qed-block
+ '("qed"))
+
+(defconst isar-keywords-qed-global
+ '("oops"))
+
+(defconst isar-keywords-proof-heading
+ '("sect"
+ "subsect"
+ "subsubsect"))
+
+(defconst isar-keywords-proof-goal
+ '("have"
+ "hence"
+ "show"
+ "thus"))
+
+(defconst isar-keywords-proof-block
+ '("next"
+ "proof"))
+
+(defconst isar-keywords-proof-open
+ '("{"))
+
+(defconst isar-keywords-proof-close
+ '("}"))
+
+(defconst isar-keywords-proof-chain
+ '("finally"
+ "from"
+ "then"
+ "ultimately"
+ "with"))
+
+(defconst isar-keywords-proof-decl
+ '("also"
+ "let"
+ "moreover"
+ "note"
+ "txt"
+ "txt_raw"))
+
+(defconst isar-keywords-proof-asm
+ '("assume"
+ "case"
+ "def"
+ "fix"
+ "presume"))
+
+(defconst isar-keywords-proof-asm-goal
+ '("obtain"))
+
+(defconst isar-keywords-proof-script
+ '("apply"
+ "apply_end"
+ "back"
+ "defer"
+ "prefer"))
+
+(provide 'isar-keywords)
diff --git a/isar/isar-syntax.el b/isar/isar-syntax.el
new file mode 100644
index 00000000..7325f709
--- /dev/null
+++ b/isar/isar-syntax.el
@@ -0,0 +1,392 @@
+;; isar-syntax.el Syntax expressions for Isabelle/Isar
+;; Copyright (C) 1994-1998 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Maintainer: Markus Wenzel <wenzelm@in.tum.de>
+;;
+;; $Id$
+;;
+
+(require 'proof-syntax)
+(require 'isar-keywords)
+
+
+;; ----- character syntax
+
+(defun isar-init-syntax-table ()
+ "Set appropriate values for syntax table in current buffer."
+ (modify-syntax-entry ?\$ ".")
+ (modify-syntax-entry ?\/ ".")
+ (modify-syntax-entry ?\\ "w")
+ (modify-syntax-entry ?+ ".")
+ (modify-syntax-entry ?- ".")
+ (modify-syntax-entry ?= ".")
+ (modify-syntax-entry ?% ".")
+ (modify-syntax-entry ?< "w")
+ (modify-syntax-entry ?> "w")
+ (modify-syntax-entry ?\& ".")
+ (modify-syntax-entry ?. "w")
+ (modify-syntax-entry ?_ "w")
+ (modify-syntax-entry ?\' "w")
+ (modify-syntax-entry ?? "w")
+ (modify-syntax-entry ?\* ". 23")
+ (modify-syntax-entry ?\( "()1")
+ (modify-syntax-entry ?\) ")(4")
+ (modify-syntax-entry ?\{ "(}1")
+ (modify-syntax-entry ?\} "){4"))
+
+(defun isar-init-output-syntax-table ()
+ "Set appropriate values for syntax table for Isabelle output."
+ (isar-init-syntax-table)
+ ;; ignore strings so font-locking works
+ ;; inside them
+ (modify-syntax-entry ?\" " ")
+ (modify-syntax-entry ?\* ".")
+ (modify-syntax-entry ?\( "()")
+ (modify-syntax-entry ?\) ")(")
+ (modify-syntax-entry ?\{ "(}")
+ (modify-syntax-entry ?\} "){"))
+
+
+;; ----- keyword groups
+
+(defconst isar-keywords-theory-enclose
+ (append isar-keywords-theory-begin
+ isar-keywords-theory-switch
+ isar-keywords-theory-end))
+
+(defconst isar-keywords-theory
+ (append isar-keywords-theory-heading
+ isar-keywords-theory-decl
+ isar-keywords-theory-goal))
+
+(defconst isar-keywords-save
+ (append isar-keywords-qed
+ isar-keywords-qed-block
+ isar-keywords-qed-global))
+
+(defconst isar-keywords-proof-enclose
+ (append isar-keywords-proof-block
+ isar-keywords-proof-open
+ isar-keywords-proof-close
+ isar-keywords-qed-block))
+
+(defconst isar-keywords-proof
+ (append isar-keywords-proof-heading
+ isar-keywords-proof-goal
+ isar-keywords-proof-chain
+ isar-keywords-proof-decl
+ isar-keywords-qed))
+
+(defconst isar-keywords-proof-context
+ (append isar-keywords-proof-asm
+ isar-keywords-proof-asm-goal))
+
+(defconst isar-keywords-local-goal
+ (append isar-keywords-proof-goal
+ isar-keywords-proof-asm-goal))
+
+(defconst isar-keywords-improper
+ (append isar-keywords-theory-script
+ isar-keywords-proof-script
+ isar-keywords-qed-global))
+
+(defconst isar-keywords-outline
+ isar-keywords-theory-heading)
+
+(defconst isar-keywords-fume
+ (append isar-keywords-theory-begin
+ isar-keywords-theory-heading
+ isar-keywords-theory-decl
+ isar-keywords-theory-script
+ isar-keywords-theory-goal))
+
+(defconst isar-keywords-indent-open
+ (append isar-keywords-theory-goal
+ isar-keywords-proof-goal
+ isar-keywords-proof-asm-goal
+ isar-keywords-proof-open))
+
+(defconst isar-keywords-indent-close
+ (append isar-keywords-save
+ isar-keywords-proof-close))
+
+(defconst isar-keywords-indent-enclose
+ (append isar-keywords-proof-block
+ isar-keywords-proof-close
+ isar-keywords-qed-block))
+
+
+;; ----- regular expressions
+
+;; tuned version of proof-ids-to-regexp --- admit single non-word char
+;; as well (e.g. { })
+
+(defun isar-ids-to-regexp (l)
+ "Maps a non-empty list of tokens `l' to a regexp matching any element"
+ (mapconcat
+ (lambda (s) (if (proof-string-match "^\\W$" s) s (concat "\\<" s "\\>")))
+ l "\\|"))
+
+(defconst isar-long-id-stuff "\\([A-Za-z0-9'_.]+\\)")
+
+(defconst isar-id "\\([A-Za-z][A-Za-z0-9'_]*\\)")
+(defconst isar-idx (concat isar-id "\\(\\.[0-9]+\\)?"))
+
+(defconst isar-string "\"\\(\\([^\"]\\|\\\\\"\\)*\\)\"")
+
+(defconst isar-any-command-regexp
+ (isar-ids-to-regexp isar-keywords-major)
+ "Regexp matching any Isabelle/Isar command keyword.")
+
+(defconst isar-name-regexp
+ (concat "\\s-*\\(" isar-string "\\|" isar-id "\\)\\s-*")
+ "Regexp matching Isabelle/Isar names, with contents grouped.")
+
+(defconst isar-tac-regexp
+ "\\<[A-Za-z][A-Za-z0-9'_]*_tac\\>"
+ "Regexp matching old-style tactic names")
+
+(defconst isar-save-command-regexp
+ (proof-anchor-regexp (isar-ids-to-regexp isar-keywords-save)))
+
+(defconst isar-global-save-command-regexp
+ (proof-anchor-regexp (isar-ids-to-regexp isar-keywords-qed-global)))
+
+(defconst isar-goal-command-regexp
+ (proof-anchor-regexp (isar-ids-to-regexp isar-keywords-theory-goal)))
+
+(defconst isar-local-goal-command-regexp
+ (proof-anchor-regexp (isar-ids-to-regexp isar-keywords-local-goal)))
+
+(defconst isar-comment-start "(*")
+(defconst isar-comment-end "*)")
+(defconst isar-comment-start-regexp (regexp-quote isar-comment-start))
+(defconst isar-comment-end-regexp (regexp-quote isar-comment-end))
+
+(defconst isar-string-start-regexp "\"\\|{\\*")
+(defconst isar-string-end-regexp "\"\\|\\*}")
+
+
+;; antiquotations
+
+(defconst isar-antiq-regexp
+ (concat "\\(@{\\([^\"{}]+\\|" isar-string "\\)\\{0,7\\}}\\)")
+ "Regexp matching Isabelle/Isar antiquoations.")
+
+(defun isar-match-antiq (limit)
+ "Match Isabelle/Isar antiquotations."
+ (or
+ (and (proof-looking-at-syntactic-context)
+ (proof-looking-at isar-antiq-regexp))
+ (let (done ans)
+ (while (not done)
+ (if (proof-re-search-forward isar-antiq-regexp limit t)
+ (and (proof-looking-at-syntactic-context)
+ (setq done t) (setq ans t))
+ (setq done t)))
+ ans)))
+
+
+;; ----- Isabelle inner syntax hilite
+
+(defface isabelle-class-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "red"))
+ (((type x) (class color) (background dark))
+ (:foreground "red3"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defface isabelle-tfree-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "purple"))
+ (((type x) (class color) (background dark))
+ (:foreground "purple3"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defface isabelle-tvar-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "purple"))
+ (((type x) (class color) (background dark))
+ (:foreground "purple3"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defface isabelle-free-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "blue"))
+ (((type x) (class color) (background dark))
+ (:foreground "blue3"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defface isabelle-bound-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "green4"))
+ (((type x) (class color) (background dark))
+ (:foreground "green"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defface isabelle-var-name-face
+ '((((type x) (class color) (background light))
+ (:foreground "darkblue"))
+ (((type x) (class color) (background dark))
+ (:foreground "blue3"))
+ (t
+ (bold t)))
+ "*Face for Isabelle term / type hiliting"
+ :group 'proof-faces)
+
+(defconst isabelle-class-name-face 'isabelle-class-name-face)
+(defconst isabelle-tfree-name-face 'isabelle-tfree-name-face)
+(defconst isabelle-tvar-name-face 'isabelle-tvar-name-face)
+(defconst isabelle-free-name-face 'isabelle-free-name-face)
+(defconst isabelle-bound-name-face 'isabelle-bound-name-face)
+(defconst isabelle-var-name-face 'isabelle-var-name-face)
+
+(defvar isar-font-lock-keywords-1
+ (list
+ (cons (isar-ids-to-regexp isar-keywords-minor) 'font-lock-type-face)
+ (cons (isar-ids-to-regexp isar-keywords-control) 'proof-error-face)
+ (cons (isar-ids-to-regexp isar-keywords-diag) 'proof-tacticals-name-face)
+ (cons (isar-ids-to-regexp isar-keywords-theory-enclose) 'font-lock-preprocessor-face)
+ (cons (isar-ids-to-regexp isar-keywords-theory) 'font-lock-keyword-face)
+ (cons (isar-ids-to-regexp isar-keywords-proof-enclose) 'font-lock-preprocessor-face)
+ (cons (isar-ids-to-regexp isar-keywords-proof) 'font-lock-keyword-face)
+ (cons (isar-ids-to-regexp isar-keywords-proof-context) 'proof-declaration-name-face)
+ (cons (isar-ids-to-regexp isar-keywords-improper) 'font-lock-reference-face)
+ (cons isar-tac-regexp 'font-lock-reference-face)
+ '(isar-match-antiq (0 'font-lock-variable-name-face prepend))))
+
+(defvar isar-output-font-lock-keywords-1
+ (list
+ (cons (concat "\351" isar-long-id-stuff "\350") 'isabelle-class-name-face)
+ (cons (concat "\352'" isar-id "\350") 'isabelle-tfree-name-face)
+ (cons (concat "\353\\?'" isar-idx "\350") 'isabelle-tvar-name-face)
+ (cons (concat "\354" isar-id "\350") 'isabelle-free-name-face)
+ (cons (concat "\355" isar-id "\350") 'isabelle-bound-name-face)
+ (cons (concat "\356\\?" isar-idx "\350") 'isabelle-var-name-face)
+ (cons (concat "\357" isar-id "\350") 'proof-declaration-name-face)
+ (cons (concat "\357\\?" isar-idx "\350") 'proof-declaration-name-face))
+ "*Font-lock table for Isabelle terms.")
+
+(defvar isar-goals-font-lock-keywords
+ (append
+ (list
+ "^theory "
+ "^proof (prove):"
+ "^proof (state):"
+ "^proof (chain):"
+ "^goal .+:"
+ "^picking this:"
+ "^using this:"
+ "^this:"
+ "^term bindings:"
+ "^facts:"
+ "^cases:"
+ "^prems:"
+ "^fixed variables:"
+ "^structures:"
+ "^type constraints:"
+ "^default sorts:"
+ "^used type variable names:"
+ "^[Ff]lex-flex pairs:"
+ "^[Cc]onstants:"
+ "^[Vv]ariables:"
+ "^[Tt]ype variables:"
+ "^\\s-*[0-9][0-9]?\\. ")
+ isar-output-font-lock-keywords-1)
+ "*Font-lock table for Isabelle/Isar output.")
+
+
+;; ----- variations on undo
+
+(defconst isar-undo "undo;")
+(defconst isar-kill "kill;")
+
+(defun isar-remove (name)
+ (concat "init_toplevel; kill_thy \"" name "\";"))
+
+(defun isar-undos (i)
+ (if (> i 0) (concat "undos_proof " (int-to-string i) ";")
+ proof-no-command))
+
+(defun isar-cannot-undo (cmd)
+ (concat "cannot_undo \"" cmd "\";"))
+
+
+(defconst isar-undo-fail-regexp
+ (proof-anchor-regexp
+ (isar-ids-to-regexp (append isar-keywords-control isar-keywords-theory-end))))
+
+(defconst isar-undo-skip-regexp
+ (proof-anchor-regexp (proof-regexp-alt (isar-ids-to-regexp isar-keywords-diag) ";")))
+
+(defconst isar-undo-ignore-regexp
+ (proof-anchor-regexp "--"))
+
+(defconst isar-undo-remove-regexp
+ (concat
+ (proof-anchor-regexp (isar-ids-to-regexp isar-keywords-theory-begin))
+ isar-name-regexp))
+
+(defconst isar-undo-kill-regexp
+ (proof-anchor-regexp (isar-ids-to-regexp isar-keywords-theory-switch)))
+
+
+;; ----- function-menu
+
+(defconst isar-any-entity-regexp
+ (concat "\\(" (isar-ids-to-regexp isar-keywords-fume) "\\)"
+ "\\(" isar-name-regexp "[[:=]\\)?"))
+
+(defconst isar-named-entity-regexp
+ (concat "\\(" (isar-ids-to-regexp isar-keywords-fume) "\\)"
+ isar-name-regexp "[[:=]"))
+
+(defconst isar-unnamed-entity-regexp
+ (concat "\\(" (isar-ids-to-regexp isar-keywords-fume) "\\)"))
+
+(defconst isar-next-entity-regexps
+ (list isar-any-entity-regexp
+ (list isar-named-entity-regexp '(1 2))
+ (list isar-unnamed-entity-regexp 1)))
+
+
+;; ----- indentation
+
+(defconst isar-indent-any-regexp
+ (proof-regexp-alt isar-any-command-regexp "\\s(" "\\s)"))
+(defconst isar-indent-inner-regexp
+ (proof-regexp-alt "[[]()]"))
+(defconst isar-indent-enclose-regexp
+ (proof-regexp-alt (isar-ids-to-regexp isar-keywords-indent-enclose) "\\s)"))
+(defconst isar-indent-open-regexp
+ (proof-regexp-alt (isar-ids-to-regexp isar-keywords-indent-open) "\\s("))
+(defconst isar-indent-close-regexp
+ (proof-regexp-alt (isar-ids-to-regexp isar-keywords-indent-close) "\\s)"))
+
+
+;; ----- outline mode
+
+(defconst isar-outline-regexp
+ (concat "[ \t]*\\(" (isar-ids-to-regexp isar-keywords-outline) "\\)")
+ "Outline regexp for Isabelle/Isar documents")
+
+(defconst isar-outline-heading-end-regexp "\n")
+
+
+(provide 'isar-syntax)
diff --git a/isar/isar.el b/isar/isar.el
new file mode 100644
index 00000000..e26a7f91
--- /dev/null
+++ b/isar/isar.el
@@ -0,0 +1,564 @@
+;; isar.el Major mode for Isabelle/Isar proof assistant
+;; Copyright (C) 1994-1998 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Author / Maintainer: Markus Wenzel <wenzelm@in.tum.de>
+;;
+;; $Id$
+;;
+
+
+;; Add Isabelle image onto splash screen
+(customize-set-variable
+ 'proof-splash-extensions
+ '(list
+ nil
+ (proof-splash-display-image "isabelle_transparent" t)))
+
+;; In case Isar mode was invoked directly or by -*- isar -*- at
+;; the start of the file, ensure that Isar mode is used from now
+;; on for .thy files.
+;; FIXME: be less messy with auto-mode-alist here (remove dups)
+(setq auto-mode-alist
+ (cons '("\\.thy$" . isar-mode) auto-mode-alist))
+
+(require 'proof)
+(require 'isar-syntax)
+
+;; Completion table for Isabelle/Isar identifiers
+(defpgdefault completion-table isar-keywords-major)
+
+;; Add generic code for Isabelle and Isabelle/Isar
+(setq load-path (cons (concat proof-home-directory "isa/") load-path))
+(require 'isabelle-system)
+(require 'x-symbol-isabelle)
+
+(defcustom isar-web-page
+ "http://isabelle.in.tum.de/Isar/"
+ "URL of web page for Isabelle/Isar."
+ :type 'string
+ :group 'isabelle-isar)
+
+;; Adjust toolbar entries (must be done before proof-toolbar is loaded).
+
+(if proof-running-on-XEmacs
+ (setq isar-toolbar-entries
+ (remassoc 'qed (remassoc 'goal isar-toolbar-entries))))
+
+
+;;;
+;;; theory header
+;;;
+
+(defun isar-detect-header ()
+ "Detect new-style theory header in current buffer"
+ (let ((header-regexp (isar-ids-to-regexp '("header" "theory")))
+ (white-space-regexp "\\(\\s-\\|\n\\)+")
+ (cmt-end-regexp (regexp-quote proof-comment-end))
+ (cmt-start-regexp (regexp-quote proof-comment-start))
+ (found-header nil) forward-amount
+ (end (point-max)) (cont t) (cmt-level 0))
+ (save-excursion
+ (goto-char (point-min))
+ (while (and cont (< (point) end))
+ (setq forward-amount 1)
+ (cond
+ ;; comments
+ ((proof-looking-at cmt-start-regexp)
+ (setq forward-amount (length (match-string 0)))
+ (incf cmt-level))
+ ((proof-looking-at cmt-end-regexp)
+ (setq forward-amount (length (match-string 0)))
+ (decf cmt-level))
+ ((> cmt-level 0))
+ ;; white space
+ ((proof-looking-at white-space-regexp)
+ (setq forward-amount (length (match-string 0))))
+ ;; theory header
+ ((proof-looking-at header-regexp)
+ (setq found-header t)
+ (setq cont nil))
+ ;; bad stuff
+ (t
+ (setq cont nil)))
+ (and cont (forward-char forward-amount)))
+ found-header)))
+
+
+(defun isar-strip-terminators ()
+ "Remove explicit Isabelle/Isar command terminators `;' from the buffer."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (while (search-forward ";" (point-max) t)
+ (if (not (proof-buffer-syntactic-context))
+ (delete-backward-char 1)))))
+
+
+(defun isar-markup-ml (string)
+ "Return marked up version of ML command STRING for Isar."
+ (format "ML_command {* %s *};" string))
+
+
+(defun isar-mode-config-set-variables ()
+ "Configure generic proof scripting mode variables for Isabelle/Isar."
+ (setq
+ proof-assistant-home-page isar-web-page
+ proof-mode-for-script 'isar-mode
+ ;; proof script syntax
+ proof-terminal-char ?\; ; forcibly ends a command
+ proof-script-command-start-regexp (proof-regexp-alt
+ isar-any-command-regexp
+ (regexp-quote ";"))
+ proof-script-integral-proofs t
+ proof-comment-start isar-comment-start
+ proof-comment-end isar-comment-end
+ proof-comment-start-regexp isar-comment-start-regexp
+ proof-comment-end-regexp isar-comment-end-regexp
+ proof-string-start-regexp isar-string-start-regexp
+ proof-string-end-regexp isar-string-end-regexp
+
+ ;; Next few used for func-menu and recognizing goal..save regions in
+ ;; script buffer.
+ proof-save-command-regexp isar-save-command-regexp
+ proof-goal-command-regexp isar-goal-command-regexp
+ proof-goal-with-hole-regexp isar-named-entity-regexp ; da
+ proof-save-with-hole-regexp nil
+ proof-script-next-entity-regexps isar-next-entity-regexps
+
+ proof-indent-enclose-offset (- proof-indent)
+ proof-indent-open-offset 0
+ proof-indent-close-offset 0
+ proof-indent-any-regexp isar-indent-any-regexp
+; proof-indent-inner-regexp isar-indent-inner-regexp
+ proof-indent-enclose-regexp isar-indent-enclose-regexp
+ proof-indent-open-regexp isar-indent-open-regexp
+ proof-indent-close-regexp isar-indent-close-regexp
+
+ ;; proof engine commands
+ proof-showproof-command "pr"
+ proof-goal-command "lemma \"%s\""
+ proof-save-command "qed"
+ proof-context-command "print_context"
+ proof-info-command "welcome"
+ proof-kill-goal-command "ProofGeneral.kill_proof"
+ proof-find-theorems-command "thms_containing %s"
+ proof-shell-start-silent-cmd "disable_pr"
+ proof-shell-stop-silent-cmd "enable_pr"
+ ;; command hooks
+ proof-goal-command-p 'isar-goal-command-p
+ proof-really-save-command-p 'isar-global-save-command-p
+ proof-count-undos-fn 'isar-count-undos
+ proof-find-and-forget-fn 'isar-find-and-forget
+ ;; da: for pbp.
+ ;; proof-goal-hyp-fn 'isar-goal-hyp
+ proof-state-preserving-p 'isar-state-preserving-p
+ proof-shell-compute-new-files-list 'isar-shell-compute-new-files-list))
+
+(defun isar-shell-mode-config-set-variables ()
+ "Configure generic proof shell mode variables for Isabelle/Isar."
+ (setq
+ proof-shell-first-special-char ?\350
+
+ proof-shell-wakeup-char ?\372
+ proof-shell-annotated-prompt-regexp "^\\w*[>#] \372"
+
+ ;; This pattern is just for comint.
+ proof-shell-prompt-pattern "^\\w*[>#] "
+
+ ;; for issuing command, not used to track cwd in any way.
+ proof-shell-cd-cmd (isar-markup-ml "ThyLoad.add_path \"%s\"")
+
+ ;; Escapes for filenames inside ML strings.
+ ;; We also make a hack for a bug in Isabelle, by switching from
+ ;; backslashes to forward slashes if it looks like we're running
+ ;; on Windows.
+ proof-shell-filename-escapes
+ (if (fboundp 'win32-long-filename) ; rough test for XEmacs on win32
+ ;; Patterns to unixfy names.
+ ;; Jacques Fleuriot's patch in ML does this too: ("^[a-zA-Z]:" . "")
+ ;; But I'll risk leaving drive names in, not sure how to replace them.
+ '(("\\\\" . "/") ("\"" . "\\\""))
+ ;; Normal case: quotation for backslash, quote mark.
+ '(("\\\\" . "\\\\") ("\"" . "\\\"")))
+
+ proof-shell-proof-completed-regexp nil ; n.a.
+ proof-shell-interrupt-regexp "\364\\*\\*\\* Interrupt"
+ proof-shell-error-regexp "\364\\*\\*\\*"
+ proof-shell-abort-goal-regexp nil ; n.a.
+
+ ;; matches names of assumptions
+ proof-shell-assumption-regexp isar-id
+ ;; matches subgoal name
+ ;; da: not used at the moment, maybe after 3.0 used for
+ ;; proof-generic-goal-hyp-fn to get pbp-like features.
+ ;; proof-shell-goal-regexp "\370[ \t]*\\([0-9]+\\)\\."
+
+ proof-shell-start-goals-regexp "\366\n"
+ proof-shell-end-goals-regexp "\367"
+ proof-shell-goal-char ?\370
+
+ proof-assistant-setting-format 'isar-markup-ml
+ proof-shell-init-cmd (proof-assistant-settings-cmd)
+ proof-shell-restart-cmd "ProofGeneral.restart"
+
+ proof-shell-eager-annotation-start-length 1
+ proof-shell-eager-annotation-start "\360\\|\362"
+ proof-shell-eager-annotation-end "\361\\|\363"
+ ;; see isar-pre-shell-start for proof-shell-trace-output-regexp
+
+ ;; Some messages delimited by eager annotations
+ proof-shell-clear-response-regexp "Proof General, please clear the response buffer."
+ proof-shell-clear-goals-regexp "Proof General, please clear the goals buffer."
+
+ ;; Dirty hack to allow font-locking for output based on hidden
+ ;; annotations, see isar-output-font-lock-keywords-1
+ proof-shell-leave-annotations-in-output t
+
+ ;; === ANNOTATIONS === ones below here are broken
+ proof-shell-result-start "\372 Pbp result \373"
+ proof-shell-result-end "\372 End Pbp result \373"
+ proof-analyse-using-stack t
+ proof-shell-start-char ?\372
+ proof-shell-end-char ?\373
+ proof-shell-field-char ?\374
+
+ proof-shell-process-file
+ (cons
+ ;; Theory loader output
+ "Proof General, this file is loaded: \"\\(.*\\)\""
+ (lambda (str)
+ (match-string 1 str)))
+ proof-shell-retract-files-regexp
+ "Proof General, you can unlock the file \"\\(.*\\)\""
+ proof-shell-compute-new-files-list 'isar-shell-compute-new-files-list
+ proof-shell-inform-file-processed-cmd "ProofGeneral.inform_file_processed \"%s\""
+ proof-shell-inform-file-retracted-cmd "ProofGeneral.inform_file_retracted \"%s\"")
+ (add-hook 'proof-activate-scripting-hook 'isar-activate-scripting))
+
+
+;;;
+;;; Theory loader operations
+;;;
+
+(defun isar-remove-file (name files cmp-base)
+ (if (not files) nil
+ (let*
+ ((file (car files))
+ (rest (cdr files))
+ (same (if cmp-base (string= name (file-name-nondirectory file))
+ (string= name file))))
+ (if same (isar-remove-file name rest cmp-base)
+ (cons file (isar-remove-file name rest cmp-base))))))
+
+(defun isar-shell-compute-new-files-list (str)
+ "Compute the new list of files read by the proof assistant.
+This is called when Proof General spots output matching
+proof-shell-retract-files-regexp."
+ (let*
+ ((name (match-string 1 str))
+ (base-name (file-name-nondirectory name)))
+ (if (string= name base-name)
+ (isar-remove-file name proof-included-files-list t)
+ (isar-remove-file (file-truename name) proof-included-files-list nil))))
+
+(defun isar-activate-scripting ()
+ "Make sure the Isabelle/Isar toplevel is in a sane state."
+ (proof-cd-sync))
+
+
+;;
+;; Define the derived modes
+;;
+(eval-and-compile
+(define-derived-mode isar-shell-mode proof-shell-mode
+ "Isabelle/Isar shell" nil
+ (isar-shell-mode-config)))
+
+(eval-and-compile
+(define-derived-mode isar-response-mode proof-response-mode
+ "Isabelle/Isar response" nil
+ (isar-response-mode-config)))
+
+(eval-and-compile ; to define vars for byte comp.
+(define-derived-mode isar-goals-mode proof-goals-mode
+ "Isabelle/Isar proofstate" nil
+ (isar-goals-mode-config)))
+
+(eval-and-compile ; to define vars for byte comp.
+(define-derived-mode isar-mode proof-mode
+ "Isabelle/Isar script" nil
+ (isar-mode-config)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Code that's Isabelle/Isar specific ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;;
+;;; help menu
+;;;
+
+;;; da: how about a `C-c C-a h ?' for listing available keys?
+
+;;; NB: definvisible must come after derived modes because uses
+;;; isar-mode-map
+(proof-definvisible isar-help-antiquotations "print_antiquotations" [h A])
+(proof-definvisible isar-help-attributes "print_attributes" [h a])
+(proof-definvisible isar-help-cases "print_cases" [h c])
+(proof-definvisible isar-help-claset "print_claset" [h C])
+(proof-definvisible isar-help-commands "print_commands" [h o])
+(proof-definvisible isar-help-facts "print_facts" [h f])
+(proof-definvisible isar-help-syntax "print_syntax" [h i])
+(proof-definvisible isar-help-induct-rules "print_induct_rules" [h I])
+(proof-definvisible isar-help-methods "print_methods" [h m])
+(proof-definvisible isar-help-simpset "print_simpset" [h S])
+(proof-definvisible isar-help-binds "print_binds" [h b])
+(proof-definvisible isar-help-theorems "print_theorems" [h t])
+(proof-definvisible isar-help-trans-rules "print_trans_rules" [h T])
+
+(defpgdefault help-menu-entries
+ (append
+ isabelle-docs-menu
+ (list
+ (cons "Show me ..."
+ (list
+ ["antiquotations" isar-help-antiquotations t]
+ ["attributes" isar-help-attributes t]
+ ["cases" isar-help-cases t]
+ ["classical rules" isar-help-claset t]
+ ["commands" isar-help-commands t]
+ ["facts" isar-help-facts t]
+ ["inner syntax" isar-help-syntax t]
+ ["induct/cases rules" isar-help-induct-rules t]
+ ["methods" isar-help-methods t]
+ ["simplifier rules" isar-help-simpset t]
+ ["term bindings" isar-help-binds t]
+ ["theorems" isar-help-theorems t]
+ ["transitivity rules" isar-help-trans-rules t])))))
+
+;; undo proof commands
+(defun isar-count-undos (span)
+ "Count number of undos in a span, return the command needed to undo that far."
+ (let
+ ((case-fold-search nil) ;FIXME ??
+ (ct 0) str i)
+ (while span
+ (setq str (span-property span 'cmd))
+ (cond ((eq (span-property span 'type) 'vanilla)
+ (or (proof-string-match isar-undo-skip-regexp str)
+ (proof-string-match isar-undo-ignore-regexp str)
+ (setq ct (+ 1 ct))))
+ ((eq (span-property span 'type) 'pbp) ;FIXME dead code?
+ ;; this case probably redundant for Isabelle, unless
+ ;; we think of some nice ways of matching non-undoable
+ ;; commands.
+ (cond ((not (proof-string-match isar-undo-skip-regexp str))
+ (setq i 0)
+ (while (< i (length str))
+ (if (= (aref str i) proof-terminal-char)
+ (setq ct (+ 1 ct)))
+ (setq i (+ 1 i))))
+ (t nil))))
+ (setq span (next-span span 'type)))
+ (isar-undos ct)))
+
+;; undo theory commands
+(defun isar-find-and-forget (span)
+ "Return commands to be used to forget SPAN."
+ (let (str ans answers)
+ (while span
+ (setq str (span-property span 'cmd))
+ (setq ans nil)
+ (cond
+ ;; comment or diagnostic command: skip
+ ((or (eq (span-property span 'type) 'comment)
+ (proof-string-match isar-undo-skip-regexp str)
+ (proof-string-match isar-undo-ignore-regexp str)))
+ ;; finished goal: undo
+ ((eq (span-property span 'type) 'goalsave)
+ (setq ans isar-undo))
+ ;; open goal: skip and exit
+ ((proof-string-match isar-goal-command-regexp str)
+ (setq span nil))
+ ;; not undoable: fail and exit
+ ((proof-string-match isar-undo-fail-regexp str)
+ (setq answers nil)
+ (setq ans (isar-cannot-undo str))
+ (setq span nil))
+ ;; theory: remove and exit
+ ((proof-string-match isar-undo-remove-regexp str)
+ (setq ans (isar-remove (match-string 2 str)))
+ (setq span nil))
+ ;; context switch: kill
+ ((proof-string-match isar-undo-kill-regexp str)
+ (setq ans isar-kill))
+ ;; else: undo
+ (t
+ (setq ans isar-undo)))
+ (if ans (setq answers (cons ans answers)))
+ (if span (setq span (next-span span 'type))))
+ (if (null answers) proof-no-command (apply 'concat answers))))
+
+
+
+(defun isar-goal-command-p (str)
+ "Decide whether argument is a goal or not"
+ (proof-string-match isar-goal-command-regexp str))
+
+(defun isar-global-save-command-p (span str)
+ "Decide whether argument really is a global save command"
+ (or
+ (proof-string-match isar-global-save-command-regexp str)
+ (let ((ans nil) (lev 0) cmd)
+ (while (and (not ans) span (setq span (prev-span span 'type)))
+ (setq cmd (span-property span 'cmd))
+ (cond
+ ;; comment: skip
+ ((eq (span-property span 'type) 'comment))
+ ;; local qed: enter block
+ ((proof-string-match isar-save-command-regexp cmd)
+ (setq lev (+ lev 1)))
+ ;; local goal: leave block, or done
+ ((proof-string-match isar-local-goal-command-regexp cmd)
+ (if (> lev 0) (setq lev (- lev 1)) (setq ans 'no)))
+ ;; global goal: done
+ ((proof-string-match isar-goal-command-regexp cmd)
+ (setq ans 'yes))))
+ (eq ans 'yes))))
+
+(defvar isar-current-goal 1
+ "Last goal that emacs looked at.")
+
+(defun isar-state-preserving-p (cmd)
+ "Non-nil if command preserves the proofstate."
+ (proof-string-match isar-undo-skip-regexp cmd))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Commands specific to isar ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(proof-defshortcut isar-bold "\\<^bold>" [(control b)])
+(proof-defshortcut isar-super "\\<^sup>" [(control u)])
+(proof-defshortcut isar-sub "\\<^sub>" [(control l)])
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Isar shell startup and exit hooks ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;borrowed from plastic.el
+(defvar isar-shell-current-line-width nil
+ "Current line width of the Isabelle process's pretty printing module.
+ Its value will be updated whenever the corresponding screen gets
+ selected.")
+
+;borrowed from plastic.el
+(defun isar-shell-adjust-line-width ()
+ "Use Isabelle's pretty printing facilities to adjust output line width.
+ Checks the width in the `proof-goals-buffer'"
+ (let ((ans ""))
+ (and (buffer-live-p proof-goals-buffer)
+ (proof-shell-live-buffer)
+ (save-excursion
+ (set-buffer proof-goals-buffer)
+ (let ((current-width
+ ;; Actually, one might sometimes
+ ;; want to get the width of the proof-response-buffer
+ ;; instead. Never mind.
+ (max 20 (window-width (get-buffer-window proof-goals-buffer)))))
+
+ (if (equal current-width isar-shell-current-line-width) ()
+ (setq isar-shell-current-line-width current-width)
+ (set-buffer proof-shell-buffer)
+ (setq ans (format "pretty_setmargin %d;" (- current-width 4)))))))
+ ans))
+
+(defun isar-pre-shell-start ()
+ (setq proof-prog-name (isabelle-command-line))
+ (setq proof-mode-for-shell 'isar-shell-mode)
+ (setq proof-mode-for-goals 'isar-goals-mode)
+ (setq proof-mode-for-response 'isar-response-mode)
+ (setq proof-shell-trace-output-regexp "\375"))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Configuring proof and pbp mode and setting up various utilities ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun isar-preprocessing () ;dynamic scoping of `string'
+ "Insert sync markers - acts on variable STRING by dynamic scoping"
+ (if (proof-string-match isabelle-verbatim-regexp string)
+ (setq string (match-string 1 string))
+ (unless (proof-string-match ";[ \t]*\\'" string)
+ (setq string (concat string ";")))
+ (setq string (concat
+ "\\<^sync>"
+ (isar-shell-adjust-line-width)
+ ;; da: this was an attempted hack to deal with ML files,
+ ;; unfortunately Isar complains about not seeing a theory
+ ;; command first: ML_setup illegal at first line
+ ;; Another failure is that: (* comment *) foo;
+ ;; ignores foo. This could be fixed by scanning for
+ ;; comment end in proof-script.el's function
+ ;; proof-segment-upto-cmdstart (which becomes even more
+ ;; Isar specific, then...)
+ ;; (if (proof-string-match "\\.ML$" (buffer-name proof-script-buffer))
+ ;; (format "ML_command {* %s *};" string)
+ ;; string)
+ string
+ " \\<^sync>;"))))
+
+(defun isar-mode-config ()
+ (isar-mode-config-set-variables)
+ (isar-init-syntax-table)
+ (setq font-lock-keywords isar-font-lock-keywords-1)
+ (proof-config-done)
+ (set (make-local-variable 'outline-regexp) isar-outline-regexp)
+ (set (make-local-variable 'outline-heading-end-regexp) isar-outline-heading-end-regexp)
+ (setq blink-matching-paren-dont-ignore-comments t)
+ (add-hook 'proof-pre-shell-start-hook 'isar-pre-shell-start nil t)
+ (add-hook 'proof-shell-insert-hook 'isar-preprocessing))
+
+(defun isar-shell-mode-config ()
+ "Configure Proof General proof shell for Isabelle/Isar."
+ (isar-init-output-syntax-table)
+ (setq font-lock-keywords ;FIXME handle x-symbol stuff by generic code!?
+ (append isar-output-font-lock-keywords-1 x-symbol-isabelle-font-lock-keywords))
+ (isar-shell-mode-config-set-variables)
+ (proof-shell-config-done))
+
+(defun isar-response-mode-config ()
+ (setq font-lock-keywords ;FIXME handle x-symbol stuff by generic code!?
+ (append isar-output-font-lock-keywords-1 x-symbol-isabelle-font-lock-keywords))
+ (isar-init-output-syntax-table)
+ (proof-response-config-done))
+
+(defun isar-goals-mode-config ()
+ ;; FIXME: next two broken, of course, as is PBP everywhere except LEGO.
+ (setq pbp-change-goal "Show %s.")
+ (setq pbp-error-regexp proof-shell-error-regexp)
+ (isar-init-output-syntax-table)
+ (setq font-lock-keywords ;FIXME handle x-symbol stuff by generic code!?
+ (append isar-goals-font-lock-keywords x-symbol-isabelle-font-lock-keywords))
+ (proof-goals-config-done))
+
+
+;;
+;; x-symbol support
+;;
+;; The following settings configure the generic PG package; the main
+;; part is in isa/x-symbol-isabelle.el
+;;
+
+(setq
+ proof-xsym-activate-command
+ (isar-markup-ml "print_mode := ([\"xsymbols\",\"symbols\"] @ ! print_mode)")
+ proof-xsym-deactivate-command
+ (isar-markup-ml "print_mode := (Library.gen_rems (op =) (! print_mode, [\"xsymbols\",\"symbols\"]))"))
+
+
+(provide 'isar)
diff --git a/isar/todo b/isar/todo
new file mode 100644
index 00000000..c508181f
--- /dev/null
+++ b/isar/todo
@@ -0,0 +1,20 @@
+-*- mode:outline -*-
+
+* Things to do for Isabelle/Isar
+
+See also ../todo for generic things to do, priority codes.
+
+** C func-menu: observe proof-syntactic-context (general problem of
+func-menu setup?);
+
+** C undo 'use' command: unlock corresponding ML file;
+
+** C provide template for empty theory (or even just for Scratch.thy);
+
+** C proper proof-by-pointing support (hard; needs major reworking of
+Isabelle's pretty-printing subsystem);
+
+** C tune behaviour of goals/response buffers (e.g. hide empty
+response buffers when using 2 buffer model);
+
+** D support proof-next-error?
diff --git a/lego/BUGS b/lego/BUGS
new file mode 100644
index 00000000..bfe39752
--- /dev/null
+++ b/lego/BUGS
@@ -0,0 +1,53 @@
+-*- mode:outline -*-
+
+* LEGO Proof General Bugs
+
+See also ../BUGS for generic bugs.
+
+
+** PBP doesn't work on FSF, reason mentioned in generic bugs.
+
+** [FSF specific] `proof-zap-commas-region' does not work for Emacs
+
+ On lego/example.l . On *initially* fontifying the buffer,
+ commas are not zapped [unfontified]. However, when entering text,
+ commata are zapped correctly. Workaround: don't stare too much at commata
+
+** If LEGO attempts to write a (object) file in a non-writable directory
+
+ It forgets the protocol mechanism on how to interact with
+ Proof General and gets stuck. Workaround: Directly enter "Configure
+ AnnotateOn" in the Proof Shell to recover.
+
+** After a `Discharge', retraction ought to only be possible back
+
+ to the first declaration/definition which is discharged. However,
+ LEGO Proof General does not know that Discharge has such a non-local
+ effect. Workaround: retract back to the first declaration/definition
+ which is discharged.
+
+** A thorny issue is local definitions in a proof state.
+
+ LEGO cannot undo them explicitly. Workaround: retract back to a
+ command before a definition.
+
+** Normalisation commands such as `Dnf', `Hnf' `Normal' cannot be undone
+
+ in a proof state by Proof General. Workaround: retract back to the
+ start of the proof.
+
+** After LEGO has issued a `*** QED ***' you may undo steps in the proof
+
+ as long as you don't issue a `Save' command or start a new proof.
+ LEGO Proof General assumes that all proofs are terminated with a
+ proper `Save' command. Workaround: Always issue a `Save' command after
+ completing a proof. If you forget one, you should retract to a point
+ before the offending proof development.
+
+** legotags doesn't find all declarations.
+
+ It cannot handle lists e.g., with [x,y:nat]; it only tags x but not y.
+ [The same problem exists for coqtags]
+ Workaround: don't rely too much on the etags mechanism.
+
+
diff --git a/lego/README b/lego/README
new file mode 100644
index 00000000..273c3e90
--- /dev/null
+++ b/lego/README
@@ -0,0 +1,37 @@
+LEGO Proof General
+
+Written by Thomas Kleymann and Dilip Sequeira.
+Later maintainance by David Aspinall and Paul Callaghan.
+
+Status: supported
+Maintainer: Paul Callaghan / David Aspinall
+LEGO version: 1.3.1
+LEGO homepage: http://www.lfcs.informatics.ed.ac.uk/lego
+
+========================================
+
+LEGO Proof General has full support for multiple file scripting, and
+experimental support for proof by pointing.
+
+There is support for X Symbol, but not using a proper token language.
+
+There is a tags program, legotags.
+
+========================================
+
+Installation notes:
+
+Install legotags in a standard place or add <proofgeneral-home>/lego
+to your PATH.
+NB: You may need to change the path to perl at the top of the file.
+
+Generate a TAGS file for the Lego library by running
+ legotags `find . -name \*.l -print`
+in the root directory of the library.
+
+
+
+========================================
+
+$Id$
+
diff --git a/lego/example.l b/lego/example.l
new file mode 100644
index 00000000..535d5712
--- /dev/null
+++ b/lego/example.l
@@ -0,0 +1,15 @@
+(*
+ Example proof script for Lego Proof General.
+
+ $Id$
+*)
+
+Module example Import lib_logic;
+
+Goal {A,B:Prop}(A /\ B) -> (B /\ A);
+intros;
+Refine H;
+intros;
+andI;
+Immed;
+Save and_comms;
diff --git a/lego/example2.l b/lego/example2.l
new file mode 100644
index 00000000..37d1e563
--- /dev/null
+++ b/lego/example2.l
@@ -0,0 +1 @@
+Module example2 Import "readonly/readonly"; \ No newline at end of file
diff --git a/lego/lego-syntax.el b/lego/lego-syntax.el
new file mode 100644
index 00000000..363044de
--- /dev/null
+++ b/lego/lego-syntax.el
@@ -0,0 +1,117 @@
+;; lego-syntax.el Syntax of LEGO
+;; Copyright (C) 1994 - 1998 LFCS Edinburgh.
+;; Author: Thomas Kleymann and Dilip Sequeira
+;; Maintainer: Paul Callaghan <P.C.Callaghan@durham.ac.uk>
+
+;;
+;; $Id$
+;;
+
+(require 'proof-syntax)
+
+;; ----- keywords for font-lock.
+
+(defconst lego-keywords-goal '("$?Goal"))
+
+(defconst lego-keywords-save '("$?Save" "SaveFrozen" "SaveUnfrozen"))
+
+(defconst lego-commands
+ (append lego-keywords-goal lego-keywords-save
+ '("allE" "allI" "andE" "andI" "Assumption" "Claim"
+ "Cut" "Discharge" "DischargeKeep"
+ "echo" "exE" "exI" "Expand" "ExpAll"
+ "ExportState" "Equiv" "For" "Freeze" "Hnf" "Immed"
+ "impE" "impI" "Induction" "Inductive"
+ "Invert" "Init" "intros" "Intros" "Module" "Next"
+ "Normal" "notE" "notI" "orE" "orIL" "orIR" "qnify" "Qnify"
+ "Qrepl" "Record" "Refine" "Repeat" "Try" "Unfreeze"))
+ "Subset of LEGO keywords and tacticals which are terminated by a \?;")
+
+(defconst lego-keywords
+ (append lego-commands
+ '("Constructors" "Double" "ElimOver" "Fields" "Import" "Inversion"
+ "NoReductions" "Parameters" "Relation" "Theorems")))
+
+(defconst lego-tacticals '("Then" "Else" "Try" "Repeat" "For"))
+
+;; ----- regular expressions for font-lock
+(defconst lego-error-regexp "^\\(cannot assume\\|Error\\|Lego parser\\)"
+ "A regular expression indicating that the LEGO process has identified an error.")
+
+(defvar lego-id proof-id)
+
+(defvar lego-ids (concat lego-id "\\(\\s *,\\s *" lego-id "\\)*")
+ "*For font-lock, we treat \",\" separated identifiers as one identifier
+ and refontify commata using \\{lego-fixup-change}.")
+
+(defconst lego-arg-list-regexp "\\s *\\(\\[[^]]+\\]\\s *\\)*"
+ "Regular expression maching a list of arguments.")
+
+(defun lego-decl-defn-regexp (char)
+ (concat "\\[\\s *\\(" lego-ids "\\)" lego-arg-list-regexp char))
+; Examples
+; ^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^
+; [ sort =
+; [ sort [n:nat] =
+; [ sort [abbrev=...][n:nat] =
+
+(defconst lego-definiendum-alternative-regexp
+ (concat "\\(" lego-id "\\)" lego-arg-list-regexp "\\s * ==")
+ "Regular expression where the first match identifies the definiendum.")
+
+(defvar lego-font-lock-terms
+ (list
+
+ ; lambda binders
+ (list (lego-decl-defn-regexp "[:|?]") 1
+ 'proof-declaration-name-face)
+
+ ; let binders
+ (list lego-definiendum-alternative-regexp 1 'font-lock-function-name-face)
+ (list (lego-decl-defn-regexp "=") 1 'font-lock-function-name-face)
+
+ ; Pi and Sigma binders
+ (list (concat "[{<]\\s *\\(" lego-ids "\\)") 1
+ 'proof-declaration-name-face)
+
+ ;; Kinds
+ (cons (concat "\\<Prop\\>\\|\\<Type\\s *\\(("
+ lego-id ")\\)?") 'font-lock-type-face)
+
+ ;; Special hacks!!
+ (cons "Discharge.." 'font-lock-keyword-face)
+ (cons "\\*\\*\\* QED \\*\\*\\*" 'font-lock-keyword-face))
+ "*Font-lock table for LEGO terms.")
+
+;; Instead of "[^:]+", it may be better to use "lego-id". Furthermore,
+;; it might be safer to append "\\s-*:".
+(defconst lego-goal-with-hole-regexp
+ (concat "\\(" (proof-ids-to-regexp lego-keywords-goal) "\\)\\s-+\\([^(){},:]+\\)")
+ "Regular expression which matches an entry in `lego-keywords-goal'
+ and the name of the goal.")
+
+(defconst lego-save-with-hole-regexp
+ (concat "\\(" (proof-ids-to-regexp lego-keywords-save) "\\)\\s-+\\([^;]+\\)")
+ "Regular expression which matches an entry in
+ `lego-keywords-save' and the name of the goal.")
+
+(defvar lego-font-lock-keywords-1
+ (append
+ lego-font-lock-terms
+ (list
+ (cons (proof-ids-to-regexp lego-keywords) 'font-lock-keyword-face)
+ (cons (proof-ids-to-regexp lego-tacticals) 'proof-tacticals-name-face)
+ (list lego-goal-with-hole-regexp 2 'font-lock-function-name-face)
+ (list lego-save-with-hole-regexp 2 'font-lock-function-name-face))))
+
+(defun lego-init-syntax-table ()
+ "Set appropriate values for syntax table in current buffer."
+
+ (modify-syntax-entry ?_ "_")
+ (modify-syntax-entry ?\' "_")
+ (modify-syntax-entry ?\| ".")
+ (modify-syntax-entry ?\* ". 23")
+ (modify-syntax-entry ?\( "()1")
+ (modify-syntax-entry ?\) ")(4"))
+
+(provide 'lego-syntax)
diff --git a/lego/lego.el b/lego/lego.el
new file mode 100644
index 00000000..ea49805f
--- /dev/null
+++ b/lego/lego.el
@@ -0,0 +1,445 @@
+;; lego.el Major mode for LEGO proof assistants
+;; Copyright (C) 1994 - 1998 LFCS Edinburgh.
+;; Author: Thomas Kleymann and Dilip Sequeira
+;; Maintainer: Paul Callaghan <P.C.Callaghan@durham.ac.uk>
+
+;;
+;; $Id$
+;;
+
+(require 'proof)
+(require 'lego-syntax)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; User Configuration ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; I believe this is standard for Linux under RedHat -tms
+(defcustom lego-tags "/usr/lib/lego/lib_Type/"
+ "*The directory of the TAGS table for the LEGO library"
+ :type 'file
+ :group 'lego)
+
+(defcustom lego-test-all-name "test_all"
+ "*The name of the LEGO module which inherits all other modules of the
+ library."
+ :type 'string
+ :group 'lego)
+
+(defpgdefault help-menu-entries
+ '(["LEGO Reference Card" (browse-url lego-www-refcard) t]
+ ["LEGO library (WWW)" (browse-url lego-library-www-page) t]))
+
+(defpgdefault menu-entries
+ '(["intros" lego-intros t]
+ ["Intros" lego-Intros t]
+ ["Refine" lego-Refine t]))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Configuration of Generic Proof Package ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Users should not need to change this.
+
+(defvar lego-shell-process-output
+ '((lambda (cmd string) (proof-string-match "^Module" cmd)) .
+ (lambda (cmd string)
+ (setq proof-shell-delayed-output
+ ;;FIXME: This should be displayed in the minibuffer only
+ (cons 'insert "\n\nImports done!"))))
+ "Acknowledge end of processing import declarations.")
+
+(defconst lego-process-config
+ ;; da: I think "Configure AnnotateOn;" is only included here for
+ ;; safety since there is a bug in LEGO which turns it off
+ ;; inadvertently sometimes.
+ "Init XCC; Configure PrettyOn; Configure AnnotateOn;"
+ "Command to initialise the LEGO process.
+
+Initialises empty context and prepares XCC theory.
+Enables pretty printing.
+Activates extended printing routines required for Proof General.")
+
+(defconst lego-pretty-set-width "Configure PrettyWidth %s; "
+ "Command to adjust the linewidth for pretty printing of the LEGO
+ process.")
+
+(defconst lego-interrupt-regexp "Interrupt.."
+ "Regexp corresponding to an interrupt")
+
+;; ----- web documentation
+
+(defcustom lego-www-home-page "http://www.dcs.ed.ac.uk/home/lego/"
+ "Lego home page URL."
+ :type 'string
+ :group 'lego)
+
+(defcustom lego-www-latest-release
+ "http://www.dcs.ed.ac.uk/home/lego/html/release-1.3.1/"
+ "The WWW address for the latest LEGO release."
+ :type 'string
+ :group 'lego)
+
+(defcustom lego-www-refcard
+ (concat lego-www-latest-release "refcard.ps.gz")
+ "URL for the Lego reference card."
+ :type 'string
+ :group 'lego)
+
+(defcustom lego-library-www-page
+ (concat lego-www-latest-release "library/library.html")
+ "The HTML documentation of the LEGO library."
+ :type 'string
+ :group 'lego)
+
+
+;; ----- lego-shell configuration options
+
+(defvar lego-prog-name "lego"
+ "*Name of program to run as lego.")
+
+(defvar lego-shell-prompt-pattern "^\\(Lego>[ \201]*\\)+"
+ "*The prompt pattern for the inferior shell running lego.")
+
+(defvar lego-shell-cd "Cd \"%s\";"
+ "*Command of the inferior process to change the directory.")
+
+(defvar lego-shell-abort-goal-regexp
+ "KillRef: ok, not in proof state\\|Forget forced KillRef"
+ "*Regular expression indicating that the proof of the current goal
+ has been abandoned.")
+
+(defvar lego-shell-proof-completed-regexp "\\*\\*\\* QED \\*\\*\\*"
+ "*Regular expression indicating that the proof has been completed.")
+
+(defvar lego-save-command-regexp
+ (concat "^" (proof-ids-to-regexp lego-keywords-save)))
+(defvar lego-goal-command-regexp
+ (concat "^" (proof-ids-to-regexp lego-keywords-goal)))
+
+(defvar lego-kill-goal-command "KillRef;")
+(defvar lego-forget-id-command "Forget %s;")
+
+(defvar lego-undoable-commands-regexp
+ (proof-ids-to-regexp '("Dnf" "Refine" "Intros" "intros" "Next" "Normal"
+ "Qrepl" "Claim" "For" "Repeat" "Succeed" "Fail" "Try" "Assumption"
+ "UTac" "Qnify" "qnify" "andE" "andI" "exE" "exI" "orIL" "orIR" "orE" "ImpI"
+ "impE" "notI" "notE" "allI" "allE" "Expand" "Induction" "Immed"
+ "Invert")) "Undoable list")
+
+;; ----- outline
+
+(defvar lego-goal-regexp "\\?\\([0-9]+\\)")
+
+(defvar lego-outline-regexp
+ (concat "[[*]\\|"
+ (proof-ids-to-regexp
+ '("Discharge" "DischargeKeep" "Freeze" "$?Goal" "Module" "Record" "Inductive"
+ "Unfreeze"))))
+
+(defvar lego-outline-heading-end-regexp ";\\|\\*)")
+
+(defvar lego-shell-outline-regexp lego-goal-regexp)
+(defvar lego-shell-outline-heading-end-regexp lego-goal-regexp)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Derived modes - they're here 'cos they define keymaps 'n stuff ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define-derived-mode lego-shell-mode proof-shell-mode
+ "lego-shell"
+ ;; With nil argument for docstring, Emacs makes up a nice one.
+ nil
+ (lego-shell-mode-config))
+
+(define-derived-mode lego-mode proof-mode
+ "lego" nil
+ (lego-mode-config))
+
+(eval-and-compile
+ (define-derived-mode lego-response-mode proof-response-mode
+ "LEGOResp" nil
+ (setq font-lock-keywords lego-font-lock-terms)
+ (lego-init-syntax-table)
+ (proof-response-config-done)))
+
+(define-derived-mode lego-goals-mode proof-goals-mode
+ "LEGOGoals" "LEGO Proof State"
+ (lego-goals-mode-config))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Code that's lego specific ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; needs to handle Normal as well
+;; it should ignore Normal TReg Normal VReg and (Normal ...)
+(defun lego-count-undos (span)
+ "This is how to work out what the undo commands are.
+Given is the first SPAN which needs to be undone."
+ (let ((ct 0) str i)
+ (while span
+ (setq str (span-property span 'cmd))
+ (cond ((eq (span-property span 'type) 'vanilla)
+ (if (or (proof-string-match lego-undoable-commands-regexp str)
+ (and (proof-string-match "Equiv" str)
+ (not (proof-string-match "Equiv\\s +[TV]Reg" str))))
+ (setq ct (+ 1 ct))))
+ ((eq (span-property span 'type) 'pbp)
+ (setq i 0)
+ (while (< i (length str))
+ (if (= (aref str i) proof-terminal-char) (setq ct (+ 1 ct)))
+ (setq i (+ 1 i)))))
+ (setq span (next-span span 'type)))
+ ;; FIXME: make this stuff generic. This should be undo-n-times-cmd
+ (concat "Undo " (int-to-string ct) ";")))
+
+(defun lego-goal-command-p (str)
+ "Decide whether argument is a goal or not"
+ (proof-string-match lego-goal-command-regexp str))
+
+(defun lego-find-and-forget (span)
+ (let (str ans)
+ (while (and span (not ans))
+ (setq str (span-property span 'cmd))
+
+ (cond
+
+ ((eq (span-property span 'type) 'comment))
+
+ ((eq (span-property span 'type) 'goalsave)
+ (unless (eq (span-property span 'name) proof-unnamed-theorem-name)
+ (setq ans (format lego-forget-id-command (span-property span 'name)))))
+ ;; alternative definitions
+ ((proof-string-match lego-definiendum-alternative-regexp str)
+ (setq ans (format lego-forget-id-command (match-string 1 str))))
+ ;; declarations
+ ((proof-string-match (concat "\\`\\$?" (lego-decl-defn-regexp "[:|=]")) str)
+ (let ((ids (match-string 1 str))) ; returns "a,b"
+ (proof-string-match proof-id ids) ; matches "a"
+ (setq ans (format lego-forget-id-command (match-string 1 ids)))))
+
+ ((proof-string-match "\\`\\(Inductive\\|\\Record\\)\\s-*\\[\\s-*\\w+\\s-*:[^;]+\\`Parameters\\s-*\\[\\s-*\\(\\w+\\)\\s-*:" str)
+ (setq ans (format lego-forget-id-command (match-string 2 str))))
+
+ ((proof-string-match
+ "\\`\\(Inductive\\|Record\\)\\s-*\\[\\s-*\\(\\w+\\)\\s-*:" str)
+ (setq ans
+ (format lego-forget-id-command (match-string 2 str))))
+
+ ((proof-string-match "\\`\\s-*Module\\s-+\\(\\S-+\\)\\W" str)
+ (setq ans (format "ForgetMark %s;" (match-string 1 str)))))
+ ;; Carry on searching forward for something to forget
+ ;; (The first thing to be forget will forget everything following)
+ (setq span (next-span span 'type)))
+ (or ans proof-no-command)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Other stuff which is required to customise script management ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun lego-goal-hyp ()
+ (cond
+ ((looking-at lego-goal-regexp)
+ (cons 'goal (match-string 1)))
+ ((looking-at proof-shell-assumption-regexp)
+ (cons 'hyp (match-string 1)))
+ (t nil)))
+
+
+(defun lego-state-preserving-p (cmd)
+ (not (proof-string-match lego-undoable-commands-regexp cmd)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Commands specific to lego ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(proof-defshortcut lego-Intros "Intros " [(control I)])
+(proof-defshortcut lego-intros "intros " [(control i)])
+(proof-defshortcut lego-Refine "Refine " [(control r)])
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Lego shell startup and exit hooks ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar lego-shell-current-line-width nil
+ "Current line width of the LEGO process's pretty printing module.
+ Its value will be updated whenever the corresponding screen gets
+ selected.")
+
+;; The line width needs to be adjusted if the LEGO process is
+;; running and is out of sync with the screen width
+
+(defun lego-shell-adjust-line-width ()
+ "Use LEGO's pretty printing facilities to adjust output line width.
+Checks the width in the `proof-goals-buffer'"
+ (and (buffer-live-p proof-goals-buffer)
+ (proof-shell-live-buffer)
+ (save-excursion
+ (set-buffer proof-goals-buffer)
+ (let ((current-width
+ ;; Actually, one might sometimes
+ ;; want to get the width of the proof-response-buffer
+ ;; instead. Never mind.
+ (window-width (get-buffer-window proof-goals-buffer))))
+ (if (equal current-width lego-shell-current-line-width) ()
+ ; else
+ (setq lego-shell-current-line-width current-width)
+ (set-buffer proof-shell-buffer)
+ (insert (format lego-pretty-set-width (- current-width 1)))
+ )))))
+
+(defun lego-pre-shell-start ()
+ (setq proof-prog-name lego-prog-name
+ proof-mode-for-shell 'lego-shell-mode
+ proof-mode-for-response 'lego-response-mode
+ proof-mode-for-goals 'lego-goals-mode))
+
+
+(defun lego-mode-config ()
+
+ (setq proof-terminal-char ?\;)
+ (setq proof-comment-start "(*")
+ (setq proof-comment-end "*)")
+
+ (setq proof-assistant-home-page lego-www-home-page)
+
+ (setq proof-mode-for-script 'lego-mode)
+
+ (setq proof-showproof-command "Prf;"
+ proof-goal-command "Goal %s;"
+ proof-save-command "Save %s;"
+ proof-context-command "Ctxt;"
+ proof-info-command "Help;")
+
+ (setq proof-goal-command-p 'lego-goal-command-p
+ proof-completed-proof-behaviour 'closeany ; new in 3.0
+ proof-count-undos-fn 'lego-count-undos
+ proof-find-and-forget-fn 'lego-find-and-forget
+ proof-goal-hyp-fn 'lego-goal-hyp
+ proof-state-preserving-p 'lego-state-preserving-p)
+
+ (setq proof-save-command-regexp lego-save-command-regexp
+ proof-goal-command-regexp lego-goal-command-regexp
+ proof-save-with-hole-regexp lego-save-with-hole-regexp
+ proof-goal-with-hole-regexp lego-goal-with-hole-regexp
+ proof-kill-goal-command lego-kill-goal-command
+ proof-indent-any-regexp
+ (proof-regexp-alt (proof-ids-to-regexp lego-commands) "\\s(" "\\s)"))
+
+ (lego-init-syntax-table)
+
+ ;; da: I've moved these out of proof-config-done in proof-script.el
+ (setq pbp-goal-command "Pbp %s;")
+ (setq pbp-hyp-command "PbpHyp %s;")
+
+;; font-lock
+
+ (setq font-lock-keywords lego-font-lock-keywords-1)
+
+ (setq proof-font-lock-zap-commas t) ; enable the painful hack
+
+ (proof-config-done)
+
+;; outline
+
+ (make-local-variable 'outline-regexp)
+ (setq outline-regexp lego-outline-regexp)
+
+ (make-local-variable 'outline-heading-end-regexp)
+ (setq outline-heading-end-regexp lego-outline-heading-end-regexp)
+
+;; tags
+ (cond ((boundp 'tags-table-list)
+ (make-local-variable 'tags-table-list)
+ (setq tags-table-list (cons lego-tags tags-table-list))))
+
+ (and (boundp 'tag-table-alist)
+ (setq tag-table-alist
+ (append '(("\\.l$" . lego-tags)
+ ("lego" . lego-tags))
+ tag-table-alist)))
+
+ (setq blink-matching-paren-dont-ignore-comments t)
+
+;; hooks and callbacks
+
+ (add-hook 'proof-pre-shell-start-hook 'lego-pre-shell-start nil t)
+ (add-hook 'proof-shell-insert-hook 'lego-shell-adjust-line-width))
+
+(defun lego-equal-module-filename (module filename)
+ "Returns `t' if MODULE is equal to the FILENAME and `nil' otherwise.
+The directory and extension is stripped of FILENAME before the test."
+ (equal module
+ (file-name-sans-extension (file-name-nondirectory filename))))
+
+(defun lego-shell-compute-new-files-list (str)
+ "Function to update `proof-included-files list'.
+
+It needs to return an up to date list of all processed files. Its
+output is stored in `proof-included-files-list'. Its input is the
+string of which `lego-shell-retract-files-regexp' matched a
+substring.
+
+We assume that module identifiers coincide with file names."
+ (let ((module (match-string 1 str)))
+ (cdr (member-if
+ (lambda (filename) (lego-equal-module-filename module filename))
+ proof-included-files-list))))
+
+(defun lego-shell-mode-config ()
+ (setq proof-shell-prompt-pattern lego-shell-prompt-pattern
+ proof-shell-cd-cmd lego-shell-cd
+ proof-shell-abort-goal-regexp lego-shell-abort-goal-regexp
+ proof-shell-proof-completed-regexp lego-shell-proof-completed-regexp
+ proof-shell-error-regexp lego-error-regexp
+ proof-shell-interrupt-regexp lego-interrupt-regexp
+ proof-shell-assumption-regexp lego-id
+ proof-shell-first-special-char ?\360
+ proof-shell-wakeup-char ?\371
+ proof-shell-start-char ?\372
+ proof-shell-end-char ?\373
+ proof-shell-field-char ?\374
+ proof-shell-goal-char ?\375
+ proof-shell-eager-annotation-start "\376"
+ proof-shell-eager-annotation-start-length 1
+ proof-shell-eager-annotation-end "\377"
+ proof-shell-annotated-prompt-regexp "Lego> \371"
+ proof-shell-result-start "\372 Pbp result \373"
+ proof-shell-result-end "\372 End Pbp result \373"
+ proof-shell-start-goals-regexp "\372 Start of Goals \373"
+ proof-shell-end-goals-regexp "\372 End of Goals \373"
+ proof-shell-pre-sync-init-cmd "Configure AnnotateOn;"
+ proof-shell-init-cmd lego-process-config
+ proof-shell-restart-cmd lego-process-config
+ proof-analyse-using-stack nil
+ proof-shell-process-output-system-specific lego-shell-process-output
+ lego-shell-current-line-width nil
+
+ proof-shell-process-file
+ (cons "Creating mark \"\\(.*\\)\" \\[\\(.*\\)\\]"
+ (lambda (str) (let ((match (match-string 2 str)))
+ (if (equal match "") match
+ (concat (file-name-sans-extension match) ".l")))))
+
+ proof-shell-retract-files-regexp
+ "forgot back through Mark \"\\(.*\\)\""
+ font-lock-keywords lego-font-lock-keywords-1
+
+ proof-shell-compute-new-files-list
+ 'lego-shell-compute-new-files-list)
+
+ (lego-init-syntax-table)
+
+ (proof-shell-config-done))
+
+(defun lego-goals-mode-config ()
+ (setq pbp-change-goal "Next %s;"
+ pbp-error-regexp lego-error-regexp)
+ (setq font-lock-keywords lego-font-lock-terms)
+ (lego-init-syntax-table)
+ (proof-goals-config-done))
+
+
+(provide 'lego)
diff --git a/lego/legotags b/lego/legotags
new file mode 100644
index 00000000..631fa644
--- /dev/null
+++ b/lego/legotags
@@ -0,0 +1,91 @@
+#!/usr/local/bin/perl
+#
+# Or perhaps: /usr/local/bin/perl
+#
+# $Id$
+#
+undef $/;
+
+if($#ARGV<$[) {die "No Files\n";}
+open(tagfile,">TAGS") || die "Couldn't open TAGS: $!\n";
+
+while(<>)
+{
+ print "Tagging $ARGV\n";
+ $a=$_;
+ $cp=1;
+ $lp=1;
+ $tagstring="";
+
+ while(1)
+ {
+
+# ---- Get the next statement starting on a newline ----
+
+ if($a=~/^[ \t\n]*\(\*/)
+ { while($a=~/^\s*\(\*/)
+ { $d=1; $a=$'; $cp+=length $&; $lp+=(($wombat=$&)=~tr/\n/\n/);
+ while($d>0 && $a=~/\(\*|\*\)/)
+ { $a=$'; $cp+=2+length $`; $lp+=(($wombat=$`)=~tr/\n/\n/);
+ if($& eq "(*") {$d++} else {$d--};
+ }
+ if($d!=0) {die "Unbalanced Comment?";}
+ }
+ }
+
+ if($cp>1 && $a=~/.*\n/) {$a=$'; $cp+=length $&; $lp++;}
+ while($a=~/^\n/) {$cp++;$lp++;$a=$'}
+
+ if($a=~/^[^;]*;/)
+ { $stmt=$&;
+ $newa=$';
+ $newcp=$cp+length $&;
+ $newlp=$lp+(($wombat=$&)=~tr/\n/\n/); }
+ else { last;}
+
+# ---- The above embarrasses itself if there are semicolons inside comments
+# ---- inside commands. Could do better.
+
+# print "----- (",$lp,",",$cp,")\n", $stmt, "\n";
+
+ if($stmt=~/^([ \t]*\$?Goal\s*([\w\']+))\s*:/)
+ { $tagstring.=$1."\177".$2."\001".$lp.",".$cp."\n"; }
+
+ elsif($stmt=~/^([ \t]*\$?\[\s*[\w\']+)/)
+ { do adddecs($stmt,$1) }
+
+ elsif($stmt=~/^([ \t]*Inductive\s*\[\s*[\w\']+)/)
+ { do adddecs($stmt,$1) }
+
+# ---- we don't need to tag saves: all goals should be named!
+
+# elsif($stmt=~/([ \t]*\$?Save\s+([\w\']+))/)
+# { $tagstring.=$1."\177".$2."\001".$lp.",".$cp."\n"; }
+#
+# elsif($stmt=~/^([ \t]*\$?SaveUnfrozen\s+([\w\']+))/)
+# { $tagstring.=$1."\177".$2."\001".$lp.",".$cp."\n"; }
+
+# ---- Maybe do something smart with discharge as well?
+
+ $cp=$newcp; $lp=$newlp; $a=$newa;
+ }
+ print tagfile "\f\n".$ARGV.",".(length $tagstring)."\n".$tagstring;
+}
+close tagfile;
+
+
+sub adddecs {
+ $wk=$_[0];
+ $tag=$_[1];
+ while($wk=~/\[\s*([\w\']+)/)
+ { $tagstring.=$tag."\177".$1."\001".$lp.",".$cp."\n"; $wk=$';
+ while($wk=~/^\s*,\s*([\w\']+)/)
+ { $tagstring.=$tag."\177".$1."\001".$lp.",".$cp."\n"; $wk=$'; }
+ $d=1;
+ while($d>0 && $wk=~/\[|\]/)
+ { $wk=$'; if($& eq "[") {$d++} else {$d--};
+ }
+ }
+ 0;
+}
+
diff --git a/lego/readonly/readonly.l b/lego/readonly/readonly.l
new file mode 100644
index 00000000..11719f49
--- /dev/null
+++ b/lego/readonly/readonly.l
@@ -0,0 +1 @@
+Module readonly; \ No newline at end of file
diff --git a/lego/todo b/lego/todo
new file mode 100644
index 00000000..dc0b1f28
--- /dev/null
+++ b/lego/todo
@@ -0,0 +1,44 @@
+-*- mode:outline -*-
+
+* Things to do for LEGO
+
+See also ../todo for generic things to do, priority codes.
+
+** C Improve X-Symbol support.
+
+** D Fix Pbp implementation in LEGO itself (10h)
+
+** D In LEGO, apart from Goal...Save pairs, we have
+ declaration...discharge pairs. See the section "Granularity of
+ Atomic Commands" for a proposal on how to generalise the current
+ implementation so that it can also deal with "Discharge".
+ [See also the Coq problem with Sections] (6h)
+
+** D Inoking an "Expand" command produces a new proof state. But this is
+ incorrectly displayed in the response buffer and not the goals
+ buffer because special annotations are missing. Presumably, one
+ ought to replace "Toplevel.Pr()" by "Toplevel.PR()" in the
+ definition of "Expand" (see file newtop.sml [Version 1.4]). (30min)
+
+** D Even with the more flexible region model, with
+ proof-nested-goals-behaviour=closequick, Proof General doesn't
+ do quite the right thing. Forget for a definition when inside
+ a proofstate kills off the whole proofstate. Effectively,
+ the definition is *global* rather than local to the proofstate,
+ and could perhaps be lifted to before the goal
+ (with the lift-global nonsense not so daft after all? Editing
+ behind the user's back is still objectionable though).
+ Another alternative fix would be to trigger some retraction action
+ on seeing the "Abort" regexp, rather than assuming it is the result of
+ some retraction action. More generally this could be used for error
+ handling.
+
+** D Improve legotags. It cannot handle lists e.g., with
+ [x,y:nat];
+ it only tags x but not y. [The same problem exists for coqtags]
+
+** X Mechanism to save object file. Specifically, after having processed
+ a script (interactively), it would be nice if one could now save the
+ buffer in object format. At the moment, it only gets converted
+ (automatically) when it is read in indirectly at a later stage.
+ However, there is currently no LEGO command to do this. [4h]
diff --git a/lego/x-symbol-lego.el b/lego/x-symbol-lego.el
new file mode 100644
index 00000000..531810fa
--- /dev/null
+++ b/lego/x-symbol-lego.el
@@ -0,0 +1,82 @@
+;; x-symbol-coq.el
+;;
+;; David Aspinall, adapted from file supplied by David von Obheimb
+;;
+;; $Id$
+;;
+
+(defvar x-symbol-lego-symbol-table
+ '((longarrowright () "->" "\\<longrightarrow>")
+ (logicaland () "/\\" "\\<and>")
+ (logicalor () "\\/" "\\<or>")
+ ;; Some naughty ones, but probably what you'd like.
+ ;; FIXME: can we set context to prevent accidental use,
+ ;; e.g. sear<chi>ng ?
+ (Gamma () "Gamma" "\\<Gamma>")
+ (Delta () "Delta" "\\<Delta>")
+ (Theta () "Theta" "\\<Theta>")
+ (Lambda () "Lambda" "\\<Lambda>")
+ (Pi () "Pi" "\\<Pi>")
+ (Sigma () "Sigma" "\\<Sigma>")
+ (Phi () "Phi" "\\<Phi>")
+ (Psi () "Psi" "\\<Psi>")
+ (Omega () "Omega" "\\<Omega>")
+ (alpha () "alpha" "\\<alpha>")
+ (beta () "beta" "\\<beta>")
+ (gamma () "gamma" "\\<gamma>")
+ (delta () "delta" "\\<delta>")
+ (epsilon1 () "epsilon" "\\<epsilon>")
+ (zeta () "zeta" "\\<zeta>")
+ (eta () "eta" "\\<eta>")
+ (theta1 () "theta" "\\<theta>")
+ (kappa1 () "kappa" "\\<kappa>")
+ (lambda () "lambda" "\\<lambda>")
+ ; (mu () "mu" "\\<mu>")
+ ; (nu () "nu" "\\<nu>")
+ ; (xi () "xi" "\\<xi>")
+ ; (pi () "pi" "\\<pi>")
+ (rho () "rho" "\\<rho>")
+ (sigma () "sigma" "\\<sigma>")
+ (tau () "tau" "\\<tau>")
+ (phi1 () "phi" "\\<phi>")
+ ; (chi () "chi" "\\<chi>")
+ (psi () "psi" "\\<psi>")
+ (omega () "omega" "\\<omega>")))
+
+;; All the stuff X-Symbol complains about
+(defvar x-symbol-lego-master-directory 'ignore)
+(defvar x-symbol-lego-image-searchpath '("./"))
+(defvar x-symbol-lego-image-cached-dirs '("images/" "pictures/"))
+(defvar x-symbol-lego-image-keywords nil)
+(defvar x-symbol-lego-font-lock-keywords nil)
+(defvar x-symbol-lego-header-groups-alist nil)
+(defvar x-symbol-lego-class-alist
+ '((VALID "Lego Symbol" (x-symbol-info-face))
+ (INVALID "no Lego Symbol" (red x-symbol-info-face))))
+(defvar x-symbol-lego-class-face-alist nil)
+(defvar x-symbol-lego-electric-ignore nil)
+(defvar x-symbol-lego-required-fonts nil)
+(defvar x-symbol-lego-case-insensitive nil)
+;; Setting token shape prevents "philosophy" example, but still
+;; problems, e.g. delphi, false1. (Pierre)
+(defvar x-symbol-lego-token-shape '(?_ "[A-Za-z]+" . "[A-Za-z_]"))
+(defvar x-symbol-lego-table x-symbol-lego-symbol-table)
+(defun x-symbol-lego-default-token-list (tokens) tokens)
+(defvar x-symbol-lego-token-list 'x-symbol-lego-default-token-list)
+(defvar x-symbol-lego-input-token-ignore nil)
+
+;; internal stuff
+(defvar x-symbol-lego-exec-specs nil)
+(defvar x-symbol-lego-menu-alist nil)
+(defvar x-symbol-lego-grid-alist nil)
+(defvar x-symbol-lego-decode-atree nil)
+(defvar x-symbol-lego-decode-alist nil)
+(defvar x-symbol-lego-encode-alist nil)
+(defvar x-symbol-lego-nomule-decode-exec nil)
+(defvar x-symbol-lego-nomule-encode-exec nil)
+
+(warn "LEGO support for X-Symbol is highly incomplete! Please help improve it!
+Send improvements to x-symbol-lego.el to proofgen@dcs.ed.ac.uk")
+
+
+(provide 'x-symbol-lego)
diff --git a/papers/README b/papers/README
new file mode 100644
index 00000000..8d106538
--- /dev/null
+++ b/papers/README
@@ -0,0 +1,4 @@
+Papers are not included with the distribution at the moment.
+
+Please look under "Documentation" on the Proof General home page,
+http://www.proofgeneral.org
diff --git a/phox/.cvsignore b/phox/.cvsignore
new file mode 100644
index 00000000..79f631e7
--- /dev/null
+++ b/phox/.cvsignore
@@ -0,0 +1,12 @@
+config
+config.dos
+*~
+#*#
+*.o
+*.a
+*.cmo
+*.cmi
+*.cmx
+*.pho
+*.phi
+*.pht
diff --git a/phox/README b/phox/README
new file mode 100644
index 00000000..06f20189
--- /dev/null
+++ b/phox/README
@@ -0,0 +1,17 @@
+PhoX Proof General, for Phox.
+
+Written by Christophe Raffalli
+
+Status: supported
+Maintainer: Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>
+PhoX version: 0.7
+PhoX homepage: http://www.lama.univ-savoie.fr/~RAFFALLI/phox.html
+
+========================================
+
+This mode has support for script management with PhoX, and some
+other features ported from PhoX's own Emacs mode.
+
+
+$Id$
+
diff --git a/phox/example.phx b/phox/example.phx
new file mode 100644
index 00000000..a0edbe48
--- /dev/null
+++ b/phox/example.phx
@@ -0,0 +1,22 @@
+(*
+ Example proof script for AF2 Proof General
+
+ $Id$
+*)
+
+(*
+goal /\n:N (ack n N1 >= N2).
+intro 2.
+elim H.
+trivial.
+elim -1 [case] H0.
+trivial.
+trivial.
+save ack_lem7.
+*)
+
+prop (* test *) (* just un test *) test /\X (X -> X).
+print $0.
+trivial.
+save.
+
diff --git a/phox/phox-extraction.el b/phox/phox-extraction.el
new file mode 100644
index 00000000..b488d43e
--- /dev/null
+++ b/phox/phox-extraction.el
@@ -0,0 +1,170 @@
+;; $State$ $Date$ $Revision$
+;;--------------------------------------------------------------------------;;
+;;--------------------------------------------------------------------------;;
+;; program extraction.
+;;
+;; note : program extraction is still experimental This file is very
+;; dependant of the actual state of program extraction in phox.
+;;--------------------------------------------------------------------------;;
+;; configuration :
+
+(defvar phox-prog-orig "phox -pg" "original name of phox binary.")
+
+(defun phox-prog-flags-modify(option)
+"ask for a string that are options to pass to phox binary"
+(interactive "soption :")
+; pas d'analyse de la réponse,
+(let ((process))
+ (if (and phox-prog-name
+ (progn (string-match " \\|$" phox-prog-name)
+ (setq process
+ (substring phox-prog-name 0 (match-beginning 0))
+ )
+ )
+ (processp (get-process process))
+ (eq (process-status process) 'run))
+ (error "Error : exit phox process first !")
+ )
+(if (string-match "^ *$" option)
+ (progn
+ (message
+ "no option other than default ones will be passed to phox binary.")
+ (setq phox-prog-name phox-prog-orig))
+ (progn
+ (message (format "option %s will be passed to phox binary." option ))
+ (setq phox-prog-name (concat phox-prog-orig " " option))
+ )
+ )
+)
+)
+
+
+(defun phox-prog-flags-extract()
+"pass option -f to phox binary. A program can be extracted from
+proof of theorem_name with :
+compile theorem_name.
+output."
+(interactive)
+(phox-prog-flags-modify "-f")
+(message
+"WARNING : program extraction is experimental and can disturb the prover !")
+)
+
+(defun phox-prog-flags-erase()
+"no option to phox binary."
+(interactive)
+(phox-prog-flags-modify ""))
+
+; encore une fonction qui devrait être redéfinie en cas d'autres
+; options possibles que -f
+
+(defun phox-toggle-extraction()
+"toggle between extraction mode and ordinary mode for phox process."
+(interactive)
+(cond ((string-equal phox-prog-name phox-prog-orig) ;; à améliorer (espaces)
+ (phox-prog-flags-extract))
+ ((string-match "\-f$" phox-prog-name) (phox-prog-flags-erase))
+ (t (error "option must be empty or -f, use phox-prog-flags-modify.")))
+)
+
+;; commands
+
+; compilation
+(defun phox-compile-theorem(name)
+ "Interactive function :
+ask for the name of a theorem and send a compile command to PhoX for it."
+ (interactive "stheorem : ")
+ (proof-shell-invisible-command (concat "compile " name)))
+
+(defun phox-compile-theorem-on-cursor()
+"Interactive function :
+send a compile command to PhoX for the theorem which name is under the cursor."
+ (interactive)
+ (let (start end)
+ (save-excursion
+; (modify-syntax-entry ?\. "w")
+ (forward-word 1)
+ (setq start (point))
+ (forward-word -1)
+ (setq end (point)))
+ (if (char-equal (char-after (- end 1)) ?\.)(setq end (- end 1)))
+ (phox-compile-theorem (buffer-substring start end))))
+
+; extraction
+
+(defun phox-output ()
+
+"Interactive function :
+send output command to phox in order to obtain programs
+extracted from proofs of all compiled theorems."
+
+
+(interactive)
+(proof-shell-invisible-command "output"))
+
+(defun phox-output-theorem (name)
+"Interactive function :
+ask for the name of a theorem and send an output command to PhoX for it
+in order to obtain a programm extracted from the known proof of this theorem."
+ (interactive "stheorem : ")
+ (proof-shell-invisible-command (concat "output " name)))
+
+(defun phox-output-theorem-on-cursor()
+"Interactive function :
+send an output command to PhoX for the theorem which name is under the cursor
+in order to obtain a programm extracted from the known proof of this theorem."
+ (interactive)
+ (let (start
+ end
+; (syntax (char-to-string (char-syntax ?\.)))
+ )
+ (save-excursion
+; (modify-syntax-entry ?\. "w") ; à modifier globablement ?
+ (forward-word 1)
+ (setq start (point))
+ (forward-word -1)
+ (setq end (point)))
+; (modify-syntax-entry ?\. syntax)
+ (if (char-equal (char-after (- end 1)) ?\.)(setq end (- end 1)))
+ (phox-output-theorem (buffer-substring start end))))
+
+; Definitions of lambda-mu terms (tdef nom_de_term = terme.) and
+; normalization (eval term.) have to be "visible" proof commands.
+
+;; menu
+
+ (defvar phox-extraction-menu
+ '("Extraction"
+ ["Program extraction enabled"
+ phox-toggle-extraction
+ :style radio
+ :selected(string-match "\-f$" phox-prog-name)
+ ]
+ ["------------------------------" nil nil
+ ]
+ ["Compile theorem on cursor" phox-compile-theorem-on-cursor
+ :active(string-match "\-f$" phox-prog-name)
+ ]
+ ["Extraction for theorem on cursor" phox-output-theorem-on-cursor
+ :active(string-match "\-f$" phox-prog-name)
+ ]
+ ["Extraction for all compiled theorems" phox-output
+ :active(string-match "\-f$" phox-prog-name)
+ ]
+ ["------------------------------" nil nil
+ ]
+ ["Compile theorem : " phox-compile-theorem
+ :active(string-match "\-f$" phox-prog-name)
+ ]
+ ["Extraction for theorem : " phox-output-theorem
+ :active(string-match "\-f$" phox-prog-name)
+ ]
+ )
+"A list of menu items to deal with program extraction.
+Warning, program extraction is still experimental
+and can disturb the prover !"
+)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'phox-extraction)
diff --git a/phox/phox-font.el b/phox/phox-font.el
new file mode 100644
index 00000000..49e9d0ed
--- /dev/null
+++ b/phox/phox-font.el
@@ -0,0 +1,87 @@
+;;--------------------------------------------------------------------------;;
+;;--------------------------------------------------------------------------;;
+;; Font lock keywords
+;;--------------------------------------------------------------------------;;
+
+(defconst phox-font-lock-keywords
+ (list
+;commands
+ '("(\\*\\([^*]\\|\\*+[^*)]\\)*\\(\\*+)\\|\\**$\\)"
+ 0 'font-lock-comment-face t)
+ '("\"\\([^\\\"]\\|\\\\.\\)*\""
+ 0 'font-lock-string-face t)
+ (cons (concat "\\([ \t]\\|^\\)\\("
+ "Cst\\|"
+ "Data\\|"
+ "I\\(mport\\|nductive\\)\\|"
+ "Use\\|"
+ "Sort\\|"
+ "new_\\(intro\\|elim\\|rewrite\\)\\|"
+ "a\\(dd_path\\|uthor\\)\\|"
+ "c\\(l\\(aim\\|ose_def\\)\\|or\\(ollary\\)?\\)\\|"
+ "d\\(e\\(f\\(_thlist\\)?\\|l\\(_proof\\)\\)\\|ocuments\\|epend\\)\\|"
+ "e\\(lim_after_intro\\|xport\\|del\\|show\\)\\|"
+ "f\\(act\\|lag\\)\\|"
+ "goal\\|"
+ "in\\(clude\\|stitute\\)\\|"
+ "lem\\(ma\\)?\\|"
+ "p\\(ath\\|r\\(int\\(_sort\\)?\\|iority\\|op\\(osition\\)?\\|ove_claim\\)\\)\\|"
+ "quit\\|"
+ "s\\(ave\\|earch\\)\\|"
+ "t\\(ex\\(_syntax\\)?\\|heo\\(rem\\)?\\|itle\\)"
+ "\\)[ \t\n\r.]")
+ '(0 'font-lock-keyword-face t))
+;proof command
+ (cons (concat "\\([ \t]\\|^\\)\\("
+ "a\\(bort\\|fter\\|pply\\|xiom\\)\\|"
+ "by_absurd\\|"
+ "constraints\\|"
+ "elim\\|"
+ "from\\|"
+ "goals\\|"
+ "in\\(tros?\\|stance\\)\\|"
+ "l\\(oc\\(al\\|k\\)\\|efts?\\)\\|"
+ "next\\|"
+ "prove\\|"
+ "r\\(e\\(write\\(_hyp\\)?\\|name\\)\\|mh\\)\\|"
+ "s\\(elect\\|lh\\)\\|"
+ "trivial\\|"
+ "u\\(se\\|n\\(do\\|fold\\(_hyp\\)?\\|lock\\)\\)"
+ "\\)[ \t.]")
+ '(0 'font-lock-type-face t))))
+
+;;--------------------------------------------------------------------------;;
+;;--------------------------------------------------------------------------;;
+;; phox-sym-lock tables
+;;--------------------------------------------------------------------------;;
+
+(if proof-running-on-XEmacs (require 'phox-sym-lock))
+
+;; to change this table, xfd -fn '-adobe-symbol-*--12-*' may be
+;; used to determine the symbol character codes.
+(defconst phox-sym-lock-keywords-table
+ '((">=" 0 1 179)
+ ("<=" 0 1 163)
+ ("!=" 0 1 185)
+ (":<" 0 1 206)
+ ("[^:]\\(:\\)[^:= \n\t\r]" 1 7 206)
+ ("\\\\/" 0 1 36)
+ ("/\\\\" 0 1 34)
+ ("\\<or\\>" 0 3 218)
+ ("&" 0 1 217)
+ ("<->" 0 1 171)
+ ("=>" 0 1 222)
+ ("->" 0 1 174)
+ ("~" 0 1 216)
+ ("\\\\" 0 1 108)))
+; "If non nil: Overrides default Phox-Sym-Lock patterns for PhoX.")
+
+(defun phox-sym-lock-start ()
+ (if (and (featurep 'phox-sym-lock) phox-sym-lock)
+ (progn
+ (setq phox-sym-lock-color
+ (face-foreground 'font-lock-function-name-face))
+ (if (not phox-sym-lock-keywords)
+ (phox-sym-lock phox-sym-lock-keywords-table)))))
+
+(provide 'phox-font)
diff --git a/phox/phox-fun.el b/phox/phox-fun.el
new file mode 100644
index 00000000..7592a87e
--- /dev/null
+++ b/phox/phox-fun.el
@@ -0,0 +1,427 @@
+;; $State$ $Date$ $Revision$
+;; syntax
+
+(setq
+ phox-forget-id-command "del %s.\n"
+ phox-forget-proof-command "del_proof %s.\n"
+ phox-forget-new-elim-command "edel elim %s.\n"
+ phox-forget-new-intro-command "edel intro %s.\n"
+ phox-forget-new-rewrite-command "edel rewrite %s.\n"
+ phox-forget-close-def-command "edel closed %s.\n"
+; phox-comments-regexp : a sequence of comments and white spaces
+ phox-comments-regexp "[ \n\t\r]*\\((\\*\\([^*]\\|\\(\\*[^)]\\)\\)*\\*)[ \n\t\r]*\\)*"
+; phox-strict-comments-regexp : a not empty sequence of comments and white spaces
+ phox-strict-comments-regexp "\\([ \n\t\r]+\\((\\*\\([^*]\\|\\(\\*[^)]\\)\\)*\\*)[ \n\t\r]*\\)*\\|\\((\\*\\([^*]\\|\\(\\*[^)]\\)\\)*\\*)[ \n\t\r]*\\)+\\)"
+ phox-ident-regexp "\\(\\([^() \n\t\r=\\[.]\\|\\(\\.[^() \n\t\r]\\)\\)+\\)"
+ phox-inductive-option "\\(\\[[^]]*]\\)?"
+ phox-spaces-regexp "[ \n\t\r]*"
+ phox-sy-definition-regexp (concat
+ "\\(Cst\\|def\\)"
+ phox-comments-regexp
+ "\\(\\(rInfix\\|lInfix\\|Infix\\|Prefix\\|Postfix\\)[^\"]+\"\\([^\"]+\\)\\)")
+ phox-sy-inductive-regexp (concat
+ "Inductive"
+ phox-comments-regexp
+ phox-inductive-option
+ phox-comments-regexp
+ "\\(\\(rInfix\\|lInfix\\|Infix\\|Prefix\\|Postfix\\)[^\"]+\"\\([^\"]+\\)\\)")
+ phox-inductive-regexp (concat
+ "Inductive"
+ phox-comments-regexp
+ phox-inductive-option
+ phox-comments-regexp
+ phox-ident-regexp)
+ phox-data-regexp (concat
+ "Data"
+ phox-comments-regexp
+ phox-inductive-option
+ phox-comments-regexp
+ phox-ident-regexp)
+ phox-definition-regexp (concat
+ "\\(Cst\\|def\\(_thlist\\)?\\|claim\\|Sort\\)"
+ phox-comments-regexp
+ phox-ident-regexp)
+ phox-prove-claim-regexp (concat
+ "prove_claim"
+ phox-comments-regexp
+ phox-ident-regexp)
+ phox-new-elim-regexp (concat
+ "new_elim\\([^.]\\|\\(\\.[^ \n\t\r]\\)\\)*[ \n\t\r)]"
+ phox-ident-regexp)
+ phox-new-intro-regexp (concat
+ "new_intro\\([^.]\\|\\(\\.[^ \n\t\r]\\)\\)*[ \n\t\r)]"
+ phox-ident-regexp)
+ phox-new-rewrite-regexp (concat
+ "new_rewrite\\([^.]\\|\\(\\.[^ \n\t\r]\\)\\)*[ \n\t\r)]"
+ phox-ident-regexp)
+ phox-close-def-regexp (concat
+ "close_def"
+ phox-comments-regexp
+ "\\(\\([^.]\\|\\(\\.[^ \n\t\r]\\)\\)+\\)[. \n\t\r]")
+)
+
+
+(defun phox-init-syntax-table (&optional TABLE)
+ "Set appropriate values for syntax table in current buffer,
+or for optional argument TABLE."
+;; useful for using forward-word
+ (modify-syntax-entry ?_ "w" TABLE)
+ (modify-syntax-entry ?\. "w" TABLE)
+;; Configure syntax table for block comments
+ (modify-syntax-entry ?\* ". 23" TABLE)
+ (modify-syntax-entry ?\( "()1" TABLE)
+ (modify-syntax-entry ?\) ")(4" TABLE)
+;; à compléter éventuellement
+)
+
+
+;; completions :
+
+(defvar phox-top-keywords
+'(
+"goal"
+"restart"
+"quit"
+"theorem"
+"claim"
+"cst"
+"Cst"
+"def"
+"def_thlist"
+"del"
+"del_proof"
+"Sort"
+"close_def"
+"edel"
+"new_elim"
+"new_intro"
+"new_rewrite"
+"Data"
+"Inductive"
+"add_path"
+"Import"
+"include"
+"Use"
+"tex_syntax"
+"depend"
+"eshow"
+"flag"
+"path"
+"print"
+"print_sort"
+"priority"
+"prove_claim"
+"search"
+"compile"
+"tdef"
+"eval"
+"output"
+"compile"
+"compute"
+"Local"
+)
+"Names of phox top commands."
+)
+
+(defvar phox-proof-keywords
+'(
+"axiom"
+"elim"
+"intro"
+"intros"
+"apply"
+"by_absurd"
+"from"
+"left"
+"lefts"
+"prove"
+"use"
+"auto"
+"trivial"
+"rewrite"
+"rewrite_hyp"
+"unfold"
+"unfold_hyp"
+"constraints"
+"instance"
+"lock"
+"unlock"
+"goals"
+"after"
+"next"
+"select"
+"local"
+"rename"
+"rmh"
+"slh"
+"abort"
+"save"
+"undo"
+"Try"
+)
+"Name of phox proof commands."
+)
+
+
+
+(defun phox-find-and-forget (span)
+ (let (str ans tmp (lsp -1))
+ (while span
+ (setq str (span-property span 'cmd))
+
+ (cond
+
+ ((eq (span-property span 'type) 'comment))
+
+ ((eq (span-property span 'type) 'goalsave)
+ (if (proof-string-match phox-prove-claim-regexp str)
+ (setq ans (concat (format phox-forget-proof-command
+ (match-string 4 str)) ans))
+ (setq ans (concat (format phox-forget-id-command
+ (span-property span 'name)) ans))))
+
+ ((proof-string-match phox-new-elim-regexp str)
+ (setq ans
+ (concat (format phox-forget-new-elim-command
+ (match-string 3 str)) ans)))
+
+ ((proof-string-match phox-new-intro-regexp str)
+ (setq ans
+ (concat (format phox-forget-new-intro-command
+ (match-string 3 str)) ans)))
+
+ ((proof-string-match phox-new-rewrite-regexp str)
+ (setq ans
+ (concat (format phox-forget-new-rewrite-command
+ (match-string 3 str)) ans)))
+
+ ((proof-string-match phox-close-def-regexp str)
+ (setq ans
+ (concat (format phox-forget-close-def-command
+ (match-string 4 str)) ans)))
+
+ ((proof-string-match phox-sy-definition-regexp str)
+ (setq ans
+ (concat (format phox-forget-id-command
+ (concat "$" (match-string 7 str))) ans)))
+
+ ((proof-string-match phox-sy-inductive-regexp str)
+ (setq ans
+ (concat (format phox-forget-id-command
+ (concat "$" (match-string 10 str))) ans)))
+
+ ((proof-string-match phox-inductive-regexp str)
+ (setq ans
+ (concat (format phox-forget-id-command
+ (match-string 8 str)) ans)))
+
+ ((proof-string-match phox-data-regexp str)
+ (setq
+ name (match-string 8 str)
+ sname (concat (downcase (substring name 0 1))
+ (substring name 1 nil))
+ ans (concat (format phox-forget-id-command
+ sname) ans)))
+
+ ((proof-string-match phox-definition-regexp str)
+ (setq ans (concat (format phox-forget-id-command
+ (match-string 6 str)) ans))))
+
+ (setq lsp (span-start span))
+ (setq span (next-span span 'type)))
+
+ (or ans proof-no-command)))
+
+;;
+;; Doing commands
+;;
+
+(defun phox-assert-next-command-interactive ()
+ "Process until the end of the next unprocessed command after point.
+If inside a comment, just process until the start of the comment."
+ (interactive)
+ (if (and (> (point) 1) (char-equal (char-before (point)) ?\.)) (insert "\n"))
+ (proof-with-script-buffer
+ (proof-maybe-save-point
+ (goto-char (proof-queue-or-locked-end))
+ (proof-assert-next-command))
+ (proof-maybe-follow-locked-end)))
+
+;;--------------------------------------------------------------------------;;
+;; Obtaining some informations on the system.
+;;
+;;--------------------------------------------------------------------------;;
+;; All the commands in section "Obtaining some informations on the
+;; system." (see cmd_top.tex) are associated to a
+;; function, and appear in the submenu "State" [pr].
+
+(defun phox-depend-theorem(theorem)
+ "Interactive function :
+ask for a string and and send a depend command to PhoX for it.
+
+Gives the list of all axioms which have been used to prove the theorem."
+
+(interactive "stheorem: ")
+(proof-shell-invisible-command (concat "depend " theorem)))
+
+(defun phox-eshow-extlist(extlist)
+ "Interactive function :
+ask for a string and send an eshow command to PhoX for it.
+
+Shows the given extension-list. Possible extension lists are : rewrite
+(the list of rewriting rules introduced by the new_rewrite command),
+elim, intro, (the introduction and elimination rules introduced by the
+new_elim and new_intro {-t} commands), closed (closed definitions
+introduced by the close_def command) and tex (introduced by the
+tex_syntax command)."
+
+(interactive "sextension list: ")
+(proof-shell-invisible-command (concat "eshow " extlist)))
+
+(defun phox-flag-name(name)
+"Interactive function :
+ask for a string and send a flag command to PhoX for it.
+
+ Print the value of an internal flag of the
+ system. The different flags are listed in the doc, see flag."
+
+(interactive "sname: ")
+(proof-shell-invisible-command (concat "flag " name)))
+
+
+(defun phox-path()
+"Interactive function :
+ send a path command to PhoX.
+
+ Prints the list of all paths. This path list is used to find
+ files when using the include command."
+
+
+(interactive)
+(proof-shell-invisible-command "path"))
+
+(defun phox-print-expression(expr)
+"Interactive function :
+ask for a string and send a print command to PhoX for it.
+
+ In case argument expr
+ is a closed expression of the language in use, prints it and gives its
+ sort, gives an (occasionally) informative error message otherwise. In
+ case expr is a defined expression (constant, theorem ...)
+ gives the definition."
+
+(interactive "sexpr: ")
+(proof-shell-invisible-command (concat "print " expr)))
+
+(defun phox-print-sort-expression(expr)
+"Interactive function :
+ask for a string and send a print_sort command to PhoX for it.
+
+ Similar to print, but gives more information on sorts of bounded
+ variable in expressions."
+
+(interactive "sexpr: ")
+(proof-shell-invisible-command (concat "print_sort " expr)))
+
+
+(defun phox-priority-symbols-list(symblist)
+"Interactive function :
+ask for a string and send a priority command to PhoX for it.
+
+ Print the priority of the given symbols. If no symbol are
+ given, print the priority of all infix and prefix symbols.
+."
+
+(interactive "slist of symbols (possibly empty): ")
+(proof-shell-invisible-command (concat "priority" symblist)))
+
+
+(defun phox-search-string(string type)
+ "Interactive function:
+ask for a string and possibly a type and send a search command to PhoX for it.
+
+ Prints the list of all loaded symbols which have type and whose name
+ contains the string. If no type is given, it prints all symbols whose
+ name contains string."
+
+(interactive
+"sstring :
+stype (nothing for any type, 'a as type parameter) :")
+(proof-shell-invisible-command (concat "search \"" string "\" " type)))
+
+;; The followings are proof commands (doc in cmd_proof.tex) :
+
+(defun phox-constraints()
+"Interactive function :
+ send a constraints command to PhoX.
+
+ Prints the constraints which should be fulfilled by unification variables,
+ only works in proofs."
+
+
+(interactive)
+(proof-shell-invisible-command "constraints"))
+
+(defun phox-goals()
+"Interactive function :
+ send a goals command to PhoX.
+
+ Prints the list of all remaining goals, only works in proofs."
+
+
+(interactive)
+(proof-shell-invisible-command "goals"))
+
+;; menu
+
+(defvar phox-state-menu
+ '("State"
+["dependencies of a theorem" phox-depend-theorem t]
+["show an extension list" phox-eshow-extlist t]
+["value of a flag" phox-flag-name t]
+["list of all paths" phox-path t]
+["print expression" phox-print-expression t]
+["print expression with sorts" phox-print-sort-expression t]
+["priority of symbols (all if arg. empty)" phox-priority-symbols-list t]
+["search for loaded symbols matching string" phox-search-string t]
+["------------------" nil nil]
+["constraints (proof command)" phox-constraints t]
+["goals (proof command)" phox-goals t]
+)
+"Phox menu for informations on state of the system."
+)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;--------------------------------------------------------------------------;;
+;;
+;; Deleting symbols
+;;
+;;--------------------------------------------------------------------------;;
+;; obsolète probablement, sinon à modifier pour en étendre la portée.
+
+(defun phox-delete-symbol(symbol)
+ "Interactive function :
+ask for a symbol and send a delete command to PhoX for it."
+ (interactive "ssymbol : ")
+ (proof-shell-invisible-command (concat "del " symbol)))
+
+(defun phox-delete-symbol-on-cursor()
+"Interactive function :
+send a delete command to PhoX for the symbol whose name is under the cursor."
+ (interactive)
+ (let (start end)
+ (save-excursion
+ (forward-word -1)
+ (setq start (point))
+ (forward-word 1)
+ (setq end (point)))
+ (if (char-equal (char-after (- end 1)) ?\.)(setq end (- end 1)))
+ (phox-delete-symbol (buffer-substring start end))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(provide 'phox-fun)
+
+
+ \ No newline at end of file
diff --git a/phox/phox-outline.el b/phox/phox-outline.el
new file mode 100644
index 00000000..766bddb3
--- /dev/null
+++ b/phox/phox-outline.el
@@ -0,0 +1,57 @@
+;;--------------------------------------------------------------------------;;
+;;--------------------------------------------------------------------------;;
+;; PARAMÉTRAGE du MODE outline
+;;--------------------------------------------------------------------------;;
+
+
+(setq phox-outline-title-regexp "\\((\\*[ \t\n]*title =\\)")
+(setq phox-outline-section-regexp "\\((\\*\\*+\\)")
+(setq phox-outline-save-regexp "\\((\\*#\\)")
+(setq
+ phox-outline-theo-regexp
+ "\\((\\*lem\\)\\|\\((\\*prop\\)\\|\\((\\*fact\\)\\|\\((\\*theo\\)\\|\\((\\*def\\)\\|\\((\\*cst\\)")
+(setq
+ phox-outline-theo2-regexp
+ "\\(lem\\)\\|\\(prop\\)\\|\\(fact\\)\\|\\(theo\\)\\|\\(def\\)\\|\\(cst\\)\\|\\(claim\\)\\|\\(new_\\)")
+
+(setq
+ phox-outline-regexp
+ (concat
+ phox-outline-title-regexp "\\|"
+ phox-outline-section-regexp "\\|"
+ phox-outline-save-regexp "\\|"
+ phox-outline-theo-regexp "\\|"
+ phox-outline-theo2-regexp))
+
+(setq phox-outline-heading-end-regexp "\\(\\*)[ \t]*\n\\)\\|\\(\\.[ \t]*\n\\)")
+
+;(if phox-outline
+; (add-hook 'phox-mode-hook '(lambda()(outline-minor-mode 1)))
+; )
+
+(defun phox-outline-level()
+ "Find the level of current outline heading in some PhoX libraries."
+ (let ((retour 0))
+ (save-excursion
+ (cond ((looking-at phox-outline-title-regexp) 1)
+ ((looking-at phox-outline-section-regexp)
+ (min 6 (- (match-end 0) (match-beginning 0)))) ; valeur maxi 6
+ ((looking-at phox-outline-theo-regexp) 7)
+ ((looking-at (concat phox-outline-save-regexp "\\|"
+ phox-outline-theo2-regexp )
+ ) 8)
+ )
+ )))
+
+(defun phox-setup-outline ()
+ "Set up local variable for outline mode"
+ (make-local-variable 'outline-heading-end-regexp)
+ (setq outline-heading-end-regexp phox-outline-heading-end-regexp)
+ (make-local-variable 'outline-regexp)
+ (setq outline-regexp phox-outline-regexp)
+ (make-local-variable 'outline-level)
+ (setq outline-level 'phox-outline-level)
+ (outline-minor-mode 1)
+)
+
+(provide 'phox-outline) \ No newline at end of file
diff --git a/phox/phox-sym-lock.el b/phox/phox-sym-lock.el
new file mode 100644
index 00000000..efee6088
--- /dev/null
+++ b/phox/phox-sym-lock.el
@@ -0,0 +1,363 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; phox-sym-lock.el - Extension of Font-Lock mode for symbol fontification.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Copyright © 1997-1998 Albert Cohen, all rights reserved.
+;; Copying is covered by the GNU General Public License.
+;;
+;; This program 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 program 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.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; History
+;;
+;; first prototype by wg <wg@cs.tu-berlin.de> 5-96
+;; tweaked by Steve Dunham <dunham@gdl.msu.edu> 5-96
+;; rewritten and enhanced by Albert Cohen <Albert.Cohen@prism.uvsq.fr> 3-97
+;; new symbol-face format and ergonomy improvement by Albert Cohen 2-98
+;; major step towards portability and customization by Albert Cohen 5-98
+;; removed bug with multiple appends in hook by Albert Cohen 3-99
+;; removed phox-sym-lock-face&atom which where not working by C Raffalli 4-2000
+
+;; more about symbol font ? check out: xfd -fn '-adobe-symbol-*--12-*'
+
+(require 'font-lock)
+(require 'atomic-extents)
+
+(defvar phox-sym-lock-sym-count 0
+ "Counter for internal symbols.")
+
+(defvar phox-sym-lock-ext-start nil "Temporary for atomicization.")
+(make-variable-buffer-local 'phox-sym-lock-ext-start)
+(defvar phox-sym-lock-ext-end nil "Temporary for atomicization.")
+(make-variable-buffer-local 'phox-sym-lock-ext-end)
+
+(defvar phox-sym-lock-font-size nil
+ "Default size for Phox-Sym-Lock symbol font.")
+(make-variable-buffer-local 'phox-sym-lock-font-size)
+(put 'phox-sym-lock-font-size 'permanent-local t)
+
+(defvar phox-sym-lock-keywords nil
+ "Similar to `font-lock-keywords'.")
+(make-variable-buffer-local 'phox-sym-lock-keywords)(put 'phox-sym-lock-keywords 'permanent-local t)
+
+(defvar phox-sym-lock-enabled nil
+ "Phox-Sym-Lock switch.")
+(make-variable-buffer-local 'phox-sym-lock-enabled)
+(put 'phox-sym-lock-enabled 'permanent-local t)
+
+(defvar phox-sym-lock-color (face-foreground 'default)
+ "*Phox-Sym-Lock default color in `font-lock-use-colors' mode.")
+(make-variable-buffer-local 'phox-sym-lock-color)
+(put 'phox-sym-lock-color 'permanent-local t)
+
+(defvar phox-sym-lock-mouse-face 'default
+ "*Face for symbols when under mouse.")
+(make-variable-buffer-local 'phox-sym-lock-mouse-face)
+(put 'phox-sym-lock-mouse-face 'permanent-local t)
+
+(defvar phox-sym-lock-mouse-face-enabled t
+ "Mouse face switch.")
+(make-variable-buffer-local 'phox-sym-lock-mouse-face-enabled)
+(put 'phox-sym-lock-mouse-face-enabled 'permanent-local t)
+
+(defconst phox-sym-lock-with-mule (featurep 'mule)
+ "Are we using Mule Xemacs ?")
+
+(defun phox-sym-lock-gen-symbol (&optional prefix)
+ "Generate a new internal symbol."
+ ;; where is the standard function to do this ?
+ (setq phox-sym-lock-sym-count (+ phox-sym-lock-sym-count 1))
+ (intern (concat "phox-sym-lock-gen-" (or prefix "")
+ (int-to-string phox-sym-lock-sym-count))))
+
+
+(defun phox-sym-lock-make-symbols-atomic (&optional begin end)
+ "Function to make symbol faces atomic."
+ (if phox-sym-lock-enabled
+ (map-extents
+ (lambda (extent maparg)
+ (let ((face (extent-face extent)) (ext))
+ (if (and face (setq ext (face-property face 'phox-sym-lock-remap)))
+ (progn
+ (if (numberp ext)
+ (set-extent-endpoints
+ extent (- (extent-start-position extent) ext)
+ (extent-end-position extent)))
+ (if ext
+ (progn
+ (if phox-sym-lock-mouse-face-enabled
+ (set-extent-property extent 'mouse-face
+ phox-sym-lock-mouse-face))
+ (set-extent-property extent 'atomic t)
+ (set-extent-property extent 'start-open t))))))
+ nil)
+ (current-buffer)
+ (if begin (save-excursion (goto-char begin) (beginning-of-line) (point))
+ (point-min))
+ (if end (save-excursion (goto-char end) (end-of-line) (point))
+ (point-max))
+ nil nil)))
+
+(defun phox-sym-lock-compute-font-size ()
+ "Computes the size of the \"better\" symbol font."
+ (let ((font-reg (if proof-running-on-win32
+ "[^:]*:[^:]*:\\([^:]*\\):[^:]*:[^:]*"
+ "-[^-]*-[^-]*-[^-]*-[^-]*-[^-]*-[^-]*-\\([^-]*\\)-.*"))
+ (font-pat (if proof-running-on-win32
+ "Symbol:Regular:*::Symbol"
+ "-adobe-symbol-medium-r-normal--*")))
+ (let (
+; face-height is not very good on win32. Why ?
+ (num (if (and (not proof-running-on-win32) (fboundp 'face-height))
+ (face-height 'default)
+ (let ((str (face-font-name 'default)))
+ (if
+ (string-match font-reg str)
+ (string-to-number (substring str (match-beginning 1)
+ (match-end 1)))))))
+ (maxsize 100) (size) (oldsize)
+ (lf (list-fonts font-pat)))
+ (while (and lf maxsize)
+ (if
+ (string-match font-reg
+ (car lf))
+ (let ((str-size (substring (car lf) (match-beginning 1)
+ (match-end 1))))
+ ; test for variable size fonts. Hope it is generic ?
+ (if (or (equal str-size "*")(equal str-size ""))
+ (progn
+ (setq oldsize num)
+ (setq lf nil))
+ (setq size (string-to-number str-size))
+ (if (and (> size num) (< size maxsize))
+ (setq lf nil)
+ (setq oldsize size)))))
+ (setq lf (cdr lf)))
+ (number-to-string (if (and oldsize (< oldsize maxsize)) oldsize num)))))
+
+(defvar phox-sym-lock-font-name
+ (if window-system
+ (if proof-running-on-win32
+ (concat "Symbol:Regular:"
+ (if phox-sym-lock-font-size phox-sym-lock-font-size
+ (phox-sym-lock-compute-font-size))
+ "::Symbol")
+ (concat "-adobe-symbol-medium-r-normal--"
+ (if phox-sym-lock-font-size phox-sym-lock-font-size
+ (phox-sym-lock-compute-font-size))
+ "-*-*-*-p-*-adobe-fontspecific"))
+ "")
+ "Name of the font used by Phox-Sym-Lock.")
+(make-variable-buffer-local 'phox-sym-lock-font-name)
+(put 'phox-sym-lock-font-name 'permanent-local t)
+
+(make-face 'phox-sym-lock-adobe-symbol-face)
+(if phox-sym-lock-with-mule
+ (progn
+ (make-charset 'phox-sym-lock-cset-left "Char set for symbol font"
+ (list 'registry "adobe-fontspecific"
+ 'dimension 1
+ 'chars 94
+ 'final 53
+ 'graphic 0))
+ (make-charset 'phox-sym-lock-cset-right "Char set for symbol font"
+ (list 'registry "adobe-fontspecific"
+ 'dimension 1
+ 'chars 94
+ 'final 54
+ 'graphic 1))
+ (set-face-property 'phox-sym-lock-adobe-symbol-face
+ 'font phox-sym-lock-font-name nil
+ '(mule-fonts) 'prepend))
+ (set-face-font 'phox-sym-lock-adobe-symbol-face phox-sym-lock-font-name 'global))
+
+(defun phox-sym-lock-set-foreground ()
+ "Set foreground color of Phox-Sym-Lock faces."
+ (if (and (boundp 'phox-sym-lock-defaults) phox-sym-lock-defaults)
+ (let ((l (car phox-sym-lock-defaults))
+ (color (if (and (boundp 'font-lock-use-fonts) font-lock-use-fonts)
+ (face-foreground 'default) phox-sym-lock-color)))
+ (if (and (consp l) (eq (car l) 'quote)) (setq l (eval l)))
+ (if (symbolp l) (setq l (eval l)))
+ (dolist (c l)
+ (setq c (nth 2 c))
+ (if (consp c) (setq c (eval c)))
+ (if (string-match "-adobe-symbol-" (font-name (face-font c)))
+ (set-face-foreground c color))))))
+
+(defun phox-sym-lock-translate-char (char)
+ (if phox-sym-lock-with-mule
+ (let ((code (if (integerp char) char (char-int char))))
+ (if (< code 128)
+ (make-char 'phox-sym-lock-cset-left obj)
+ (make-char 'phox-sym-lock-cset-right (- obj 128))))
+ char))
+
+(defun phox-sym-lock-translate-char-or-string (obj)
+ (if (stringp obj)
+ (if phox-sym-lock-with-mule
+ (concat (mapcar phox-sym-lock-translate-char obj))
+ (obj))
+ (make-string 1 (phox-sym-lock-translate-char obj))))
+
+(defun phox-sym-lock-remap-face (pat pos obj atomic)
+ "Make a temporary face which remaps the POS char of PAT to the
+given OBJ under `phox-sym-lock-adobe-symbol-face' and all other characters to
+the empty string. OBJ may either be a string or a character."
+ (let* ((name (phox-sym-lock-gen-symbol "face"))
+ (table (make-display-table))
+ (tface (make-face name "phox-sym-lock-remap-face" t)))
+ (fillarray table "")
+ (aset table (string-to-char (substring pat (1- pos) pos))
+ (phox-sym-lock-translate-char-or-string obj))
+ (set-face-foreground tface (if (and (boundp 'font-lock-use-fonts)
+ font-lock-use-fonts)
+ (face-foreground 'default) phox-sym-lock-color))
+ (set-face-property tface 'display-table table)
+ (set-face-property tface 'font (face-font 'phox-sym-lock-adobe-symbol-face))
+ (set-face-property tface 'phox-sym-lock-remap atomic) ; mark it
+ tface ; return face value and not face name
+ ; the temporary face would be otherwise GCed
+ ))
+
+(defvar phox-sym-lock-clear-face
+ (let* ((name (phox-sym-lock-gen-symbol "face"))
+ (table (make-display-table))
+ (tface (make-face name "phox-sym-lock-remap-face" t)))
+ (fillarray table "")
+ (set-face-property tface 'display-table table)
+ (set-face-property tface 'phox-sym-lock-remap 1) ; mark it
+ tface
+ ;; return face value and not face name
+ ;; the temporary face would be otherwise GCed
+ ))
+
+(defun phox-sym-lock (fl)
+ "Create font-lock table entries from a list of (PAT NUM POS OBJ) where
+PAT (at NUM) is substituted by OBJ under `phox-sym-lock-adobe-symbol-face'. The
+face's extent will become atomic."
+ (message "Computing Phox-Sym-Lock faces...")
+ (setq phox-sym-lock-keywords (phox-sym-lock-rec fl))
+ (setq phox-sym-lock-enabled t)
+ (message "Computing Phox-Sym-Lock faces... done."))
+
+(defun phox-sym-lock-rec (fl)
+ (let ((f (car fl)))
+ (if f
+ (cons (apply 'phox-sym-lock-atom-face f)
+ (phox-sym-lock-rec (cdr fl))))))
+
+(defun phox-sym-lock-atom-face (pat num pos obj &optional override)
+ "Define an entry for the font-lock table which substitutes PAT (at NUM) by
+OBJ under `phox-sym-lock-adobe-symbol-face'. The face extent will become atomic."
+ (list pat num (phox-sym-lock-remap-face pat pos obj t) override))
+
+(defun phox-sym-lock-pre-idle-hook-first ()
+ (condition-case nil
+ (if (and phox-sym-lock-enabled font-lock-old-extent)
+ (setq phox-sym-lock-ext-start (extent-start-position font-lock-old-extent)
+ phox-sym-lock-ext-end (extent-end-position font-lock-old-extent))
+ (setq phox-sym-lock-ext-start nil))
+ (error (setq phox-sym-lock-ext-start nil))))
+
+(defun phox-sym-lock-pre-idle-hook-last ()
+ (condition-case nil
+ (if (and phox-sym-lock-enabled phox-sym-lock-ext-start)
+ (phox-sym-lock-make-symbols-atomic phox-sym-lock-ext-start phox-sym-lock-ext-end))
+ (error (warn "Error caught in `phox-sym-lock-pre-idle-hook-last'"))))
+
+(add-hook 'font-lock-after-fontify-buffer-hook
+ 'phox-sym-lock-make-symbols-atomic)
+
+(defun phox-sym-lock-enable ()
+ "Enable Phox-Sym-Lock on this buffer."
+ (interactive)
+ (if (not phox-sym-lock-keywords)
+ (error "No Phox-Sym-Lock keywords defined!")
+ (setq phox-sym-lock-enabled t)
+ (if font-lock-mode
+ (progn
+ (setq font-lock-keywords nil) ; Font-Lock explicit-defaults bug!
+ (font-lock-set-defaults t)
+ (font-lock-fontify-buffer)))
+ (message "Phox-Sym-Lock enabled.")))
+
+(defun phox-sym-lock-disable ()
+ "Disable Phox-Sym-Lock on this buffer."
+ (interactive)
+ (if (not phox-sym-lock-keywords)
+ (error "No Phox-Sym-Lock keywords defined!")
+ (setq phox-sym-lock-enabled nil)
+ (if font-lock-mode
+ (progn
+ (setq font-lock-keywords nil) ; Font-Lock explicit-defaults bug!
+ (font-lock-set-defaults t)
+ (font-lock-fontify-buffer)))
+ (message "Phox-Sym-Lock disabled.")))
+
+(defun phox-sym-lock-mouse-face-enable ()
+ "Enable special face for symbols under mouse."
+ (interactive)
+ (setq phox-sym-lock-mouse-face-enabled t)
+ (if phox-sym-lock-enabled
+ (font-lock-fontify-buffer)))
+
+(defun phox-sym-lock-mouse-face-disable ()
+ "Disable special face for symbols under mouse."
+ (interactive)
+ (setq phox-sym-lock-mouse-face-enabled nil)
+ (if phox-sym-lock-enabled
+ (font-lock-fontify-buffer)))
+
+(defun phox-sym-lock-font-lock-hook ()
+ "Function called by `font-lock-mode' for initialization purposes."
+ (add-hook 'pre-idle-hook 'phox-sym-lock-pre-idle-hook-first)
+ (add-hook 'pre-idle-hook 'phox-sym-lock-pre-idle-hook-last t)
+ (add-menu-button '("Options" "Syntax Highlighting")
+ ["Phox-Sym-Lock"
+ (if phox-sym-lock-enabled (phox-sym-lock-disable) (phox-sym-lock-enable))
+ :style toggle :selected phox-sym-lock-enabled
+ :active phox-sym-lock-keywords] "Automatic")
+ (if (and (featurep 'phox-sym-lock) phox-sym-lock-enabled
+ font-lock-defaults (boundp 'phox-sym-lock-keywords))
+ (progn
+ (phox-sym-lock-patch-keywords)
+ (phox-sym-lock-set-foreground))))
+
+(defun font-lock-set-defaults (&optional explicit-defaults)
+ (when
+ (and
+ (featurep 'font-lock)
+ (if font-lock-auto-fontify
+ (not (memq major-mode font-lock-mode-disable-list))
+ (memq major-mode font-lock-mode-enable-list))
+ (font-lock-set-defaults-1 explicit-defaults)
+ (phox-sym-lock-patch-keywords))
+ (turn-on-font-lock)))
+
+(defun phox-sym-lock-patch-keywords ()
+ (if (and font-lock-keywords phox-sym-lock-enabled
+ (boundp 'phox-sym-lock-keywords)
+ (listp (car font-lock-keywords))
+ (listp (cdar font-lock-keywords))
+ (listp (cddar font-lock-keywords))
+ (or (listp (caddar font-lock-keywords))
+ (not (string-match
+ "phox-sym-lock"
+ (symbol-name
+ (face-name (cadr (cdar
+ font-lock-keywords))))))))
+ (setq font-lock-keywords (append phox-sym-lock-keywords
+ font-lock-keywords))) t)
+
+(add-hook 'font-lock-mode-hook 'phox-sym-lock-font-lock-hook)
+
+(provide 'phox-sym-lock)
diff --git a/phox/phox-tags.el b/phox/phox-tags.el
new file mode 100644
index 00000000..da91f022
--- /dev/null
+++ b/phox/phox-tags.el
@@ -0,0 +1,119 @@
+;; $State$ $Date$ $Revision$
+;;--------------------------------------------------------------------------;;
+;;--------------------------------------------------------------------------;;
+;; gestion des TAGS
+;;--------------------------------------------------------------------------;;
+
+; sous xemacs, visit-tags-table n'a pas d'argument optionnel. Sous gnu emacs :
+
+; Normally M-x visit-tags-table sets the global value of `tags-file-name'.
+; With a prefix arg, set the buffer-local value instead.
+
+; mieux vaut sous gnu emacs gérer la variable tags-table-list, qui
+; n'existe pas sous xemacs.
+; Sous xemacs il faut gérer la variable tag-table-alist qui n'existe pas
+; sous gnu emacs.
+
+
+(require 'etags)
+
+
+(defun phox-tags-add-table(table)
+ "add tags table"
+ (interactive "D directory, location of a file named TAGS to add : ")
+ (if proof-running-on-XEmacs
+ (let ((association (cons buffer-file-name table)))
+ (if (member association tag-table-alist)
+ (message (concat table " already loaded."))
+ (setq tag-table-alist (cons association tag-table-alist))))
+ ; gnu emacs
+ (if (member table tags-table-list)
+ (message (concat table " already loaded."))
+; (make-local-variable 'tags-table-list) ; ne fonctionne pas
+ (setq tags-table-list (cons table tags-table-list))
+ )
+ )
+ )
+
+(defun phox-tags-reset-table()
+ "Set tags-table-list to nil."
+ (interactive)
+; (make-local-variable 'tags-table-list)
+ (if proof-running-on-XEmacs
+ (progn
+ (setq tag-table-alist (remassoc buffer-file-name tag-table-alist)))
+ (setq tags-table-list nil))
+ )
+
+(defun phox-tags-add-doc-table()
+ "Add tags in text documentation."
+ (interactive)
+ (phox-tags-add-table (concat phox-doc-dir "/text/TAGS"))
+ )
+
+(defun phox-tags-add-lib-table()
+ "Add tags in libraries."
+ (interactive)
+ (phox-tags-add-table (concat phox-lib-dir "/TAGS"))
+ )
+
+(defun phox-tags-add-local-table()
+ "Add the tags table created with function phox-create-local-table."
+ (interactive)
+ (phox-tags-add-table (concat buffer-file-name "TAGS"))
+ )
+
+(defun phox-tags-create-local-table()
+ "create table on local buffer"
+ (interactive)
+ (shell-command (concat phox-etags
+ " -o "
+ (file-name-nondirectory (buffer-file-name))
+ "TAGS "
+ (file-name-nondirectory (buffer-file-name))))
+ )
+
+
+(defun phox-complete-tag()
+"Complete symbol using tags table. Works with FSF emacs.
+ Problems with xemacs."
+;; xemacs build a table for completion, tag-completion-table this table
+;; donnot contains key words that use ".". There is a problem with
+;; syntax-table. In xemacs you need to redefine
+;; add-to-tag-completion-table, in order to add your file-type and
+;; syntax-table. The modification is very simple, there should be an
+;; hook for that.
+;;
+(interactive)
+(if proof-running-on-XEmacs
+ (tag-complete-symbol)
+ (complete-tag)
+ )
+)
+
+;; menu
+
+(defvar phox-tags-menu
+ '("Tags"
+ ["create a tags table for local buffer" phox-tags-create-local-table t]
+ ["------------------" nil nil]
+ ["add table" phox-tags-add-table t]
+ ["add local table" phox-tags-add-local-table t]
+ ["add table for libraries" phox-tags-add-lib-table t]
+ ["add table for text doc" phox-tags-add-doc-table t]
+ ["reset tags table list" phox-tags-reset-table t]
+ ["------------------" nil nil]
+ ["Find theorem, definition ..." find-tag t]
+ ["complete theorem, definition ..." phox-complete-tag t]
+ )
+"Phox menu for dealing with tags"
+)
+
+;; default
+
+(if phox-tags-doc (add-hook 'phox-mode-hook 'phox-tags-add-doc-table))
+
+(provide 'phox-tags)
+
+
+
diff --git a/phox/phox.el b/phox/phox.el
new file mode 100644
index 00000000..2f0680e9
--- /dev/null
+++ b/phox/phox.el
@@ -0,0 +1,256 @@
+;; $State$ $Date$ $Revision$
+
+(require 'proof) ; load generic parts
+
+;; Adjust toolbar entries. (Must be done
+;; before proof-toolbar is loaded).
+
+(if proof-running-on-XEmacs (setq phox-toolbar-entries
+ (remassoc 'context phox-toolbar-entries)))
+
+
+;; ======== User settings for PhoX ========
+;;
+;; Defining variables using customize is pretty easy.
+;; You should do it at least for your prover-specific user options.
+;;
+;; proof-site provides us with two customization groups
+;; automatically: (based on the name of the assistant)
+;;
+;; 'phox - User options for PhoX Proof General
+;; 'phox-config - Configuration of PhoX Proof General
+;; (constants, but may be nice to tweak)
+;;
+;; The first group appears in the menu
+;; ProofGeneral -> Customize -> PhoX
+;; The second group appears in the menu:
+;; ProofGeneral -> Internals -> PhoX config
+;;
+
+(defcustom phox-prog-name "phox -pg"
+ "*Name of program to run PhoX."
+ :type 'file
+ :group 'phox)
+
+(defcustom phox-sym-lock t
+ "*Whether to use sym-lock or not."
+ :type 'boolean
+ :group 'phox)
+
+(defcustom phox-web-page
+ "http://www.lama.univ-savoie.fr/~RAFFALLI/phox.html"
+ "URL of web page for PhoX."
+ :type 'string
+ :group 'phox-config)
+
+(defcustom phox-doc-dir
+ "/usr/local/doc/phox"
+ "The name of the root documentation directory for PhoX."
+ :type 'string
+ :group 'phox-config)
+
+(defcustom phox-lib-dir
+ "/usr/local/lib/phox"
+ "The name of the root directory for PhoX libraries."
+ :type 'string
+ :group 'phox-config)
+
+(defcustom phox-tags-program
+ (concat phox-doc-dir "/tools/phox_etags.sh")
+ "Program to run to generate TAGS table for proof assistant."
+ :type 'string
+ :group 'phox-config)
+
+(defcustom phox-tags-doc
+ t
+ "*If non nil, tags table for PhoX text documentation is loaded."
+ :type 'boolean
+ :group 'phox-config)
+
+(defcustom phox-etags
+ (concat phox-doc-dir "/tools/phox_etags.sh")
+ "Command to build tags table."
+ :type 'string
+ :group 'phox-config)
+
+(require 'phox-fun)
+(require 'phox-font)
+(require 'phox-extraction)
+(require 'phox-tags)
+(require 'phox-outline)
+
+
+;; ----- PhoX specific menu
+
+(defpgdefault menu-entries
+ (cons
+ phox-state-menu
+ (cons
+ phox-tags-menu
+ (cons
+ phox-extraction-menu
+;; not useful ?
+; '(["Delete symbol around cursor" phox-delete-symbol-around-point t]
+; ["Delete symbol" phox-delete-symbol t])
+ nil)))
+ )
+
+;;
+;; ======== Configuration of generic modes ========
+;;
+
+(defun phox-config ()
+ "Configure Proof General scripting for PhoX."
+ (setq
+ proof-terminal-char ?\. ; ends every command
+ proof-script-command-end-regexp "[.]\\([ \t\n\r]\\)"
+ proof-comment-start "(*"
+ proof-comment-end "*)"
+ proof-state-command "goals."
+ proof-goal-command-regexp
+ "\\`\\(goal[ \t\n\r]\\|pro\\(p\\(osition\\)?\\|ve_claim\\)\\|lem\\(ma\\)?\\|fact\\|cor\\(ollary\\)?\\|theo\\(rem\\)?\\)"
+ proof-save-command-regexp "\\`save"
+ proof-goal-with-hole-regexp
+ (concat
+ "\\`\\(pro\\(p\\(osition\\)?\\|ve_claim\\)\\(osition\\)?\\|lem\\(ma\\)?\\|fact\\|cor\\(ollary\\)?\\|theo\\(rem\\)?\\)"
+ phox-strict-comments-regexp
+ phox-ident-regexp)
+ proof-goal-with-hole-result 15
+ proof-save-with-hole-regexp
+ (concat
+ "\\`save"
+ phox-strict-comments-regexp
+ phox-ident-regexp)
+ proof-save-with-hole-result 8
+ proof-ignore-for-undo-count "\\`\\(constraints\\|flag\\|goals\\|pri\\(nt\\(_sort\\)?\\|ority\\)\\|eshow\\|search\\|depend\\)"
+ proof-non-undoables-regexp "\\`\\(undo\\|abort\\)"
+ proof-shell-error-regexp "^\\([^ \n\t\r]* \\)?\\(\\(e\\|E\\)rror\\)\\|\\(\\(f\\|F\\)ailure\\)"
+ proof-goal-command "goal %s."
+ proof-save-command "save %s."
+ proof-kill-goal-command "abort."
+ proof-showproof-command "goals."
+ proof-undo-n-times-cmd "undo %s."
+ proof-find-and-forget-fn 'phox-find-and-forget
+ proof-find-theorems-command "search \"%s\"."
+ proof-auto-multiple-files nil
+ font-lock-keywords phox-font-lock-keywords
+ )
+ (phox-init-syntax-table)
+;; the following is only useful for xemacs
+ (define-key phox-mode-map [(meta ?.)] 'phox-complete-tag)
+)
+
+(defun phox-shell-config ()
+ "Configure Proof General shell for PhoX."
+ (setq
+ ;proof-shell-cd-cmd "cd \"%s\""
+ proof-shell-prompt-pattern "\\(>phox> \\)\\|\\(%phox% \\)"
+ proof-shell-annotated-prompt-regexp "\\(>phox> \\)\\|\\(%phox% \\)"
+ proof-shell-interrupt-regexp "Interrupt"
+ proof-shell-start-goals-regexp "^\\(Here \\(are\\|is\\) the goal\\)\\|\\([0-9]* goals? created\\)"
+ proof-shell-end-goals-regexp "^End of goals."
+ proof-shell-quit-cmd "quit."
+ proof-shell-restart-cmd "restart."
+ proof-shell-proof-completed-regexp "^.*^proved"
+ ;; proof-shell-first-special-char ?\371
+ ;; proof-shell-wakeup-char ?\371
+ ;; proof-shell-start-char ?\371
+ ;; proof-shell-end-char ?\372
+ ;; proof-shell-goal-char ?\373
+ ;; proof-shell-field-char ?\374
+ ;; proof-shell-eager-annotation-start "\376"
+ ;; proof-shell-eager-annotation-start-length 1
+ ;; proof-shell-eager-annotation-end "\377"
+; proof-shell-annotated-prompt-regexp "Lego> \371"
+; proof-shell-result-start "\372 Pbp result \373"
+; proof-shell-result-end "\372 End Pbp result \373"
+; proof-shell-start-goals-regexp "\372 Start of Goals \373"
+; proof-shell-end-goals-regexp "\372 End of Goals \373"
+; proof-shell-pre-sync-init-cmd "Configure AnnotateOn;"
+))
+
+
+;;
+;; ======== Defining the derived modes ========
+;;
+
+;; The name of the script mode is always <proofsym>-script,
+;; but the others can be whatever you like.
+;;
+;; The derived modes set the variables, then call the
+;; <mode>-config-done function to complete configuration.
+
+(define-derived-mode phox-mode proof-mode
+ "PhoX script" nil
+ (phox-config)
+ (phox-sym-lock-start)
+ (proof-config-done)
+ (phox-setup-outline)
+ (define-key phox-mode-map [(control j)]
+ 'phox-assert-next-command-interactive)
+ ;; with the previous binding,
+ ;; it is nice to do : xmodmap -e "keysym KP_Enter = Linefeed"
+
+ (define-key phox-mode-map [(control c) (meta d)]
+ 'phox-delete-symbol-on-cursor)
+)
+
+(define-derived-mode phox-shell-mode proof-shell-mode
+ "PhoX shell" nil
+ (phox-shell-config)
+ (proof-shell-config-done))
+
+(define-derived-mode phox-response-mode proof-response-mode
+ "PhoX response" nil
+ (setq
+ font-lock-keywords phox-font-lock-keywords
+ proof-output-fontify-enable t)
+ (phox-sym-lock-start)
+ (proof-response-config-done)
+ (font-lock-mode))
+
+(define-derived-mode phox-goals-mode proof-goals-mode
+ "PhoX goals" nil
+ (setq
+ font-lock-keywords phox-font-lock-keywords
+ proof-output-fontify-enable t)
+ (phox-sym-lock-start)
+ (proof-goals-config-done)
+ (font-lock-mode))
+
+;; The response buffer and goals buffer modes defined above are
+;; trivial. In fact, we don't need to define them at all -- they
+;; would simply default to "proof-response-mode" and "pbp-mode".
+
+;; A more sophisticated instantiation might set font-lock-keywords to
+;; add highlighting, or some of the proof by pointing markup
+;; configuration for the goals buffer.
+
+;; The final piece of magic here is a hook which configures settings
+;; to get the proof shell running. Proof General needs to know the
+;; name of the program to run, and the modes for the shell, response,
+;; and goals buffers.
+
+(add-hook 'proof-pre-shell-start-hook 'phox-pre-shell-start)
+
+(defun phox-pre-shell-start ()
+ (setq proof-prog-name phox-prog-name)
+ (setq proof-mode-for-shell 'phox-shell-mode)
+ (setq proof-mode-for-response 'phox-response-mode)
+ (setq proof-mode-for-goals 'phox-goals-mode))
+
+; completions
+; dans completions.el
+;(setq completion-min-length 6)
+;(setq completion-prefix-min-length 3) les mots de moins de 6 caractères
+; ne sont pas pris en compte. Les prefixes de moins de 3 caractères ne
+; sont pas non plus pris en compte.
+
+; (set-variable 'phox-completion-table
+(defpgdefault completion-table
+(append phox-top-keywords phox-proof-keywords)
+)
+
+(provide 'phox)
+
+
diff --git a/plastic/README b/plastic/README
new file mode 100644
index 00000000..729b7530
--- /dev/null
+++ b/plastic/README
@@ -0,0 +1,13 @@
+Plastic Proof General
+
+Written by Paul Callaghan
+
+Status: under development together with Plastic
+Maintainer: Paul Callaghan
+Plastic version: ??
+Plastic homepage: http://www.dur.ac.uk/CARG/plastic.html
+
+========================================
+
+$Id$
+
diff --git a/plastic/plastic-syntax.el b/plastic/plastic-syntax.el
new file mode 100644
index 00000000..2bfead81
--- /dev/null
+++ b/plastic/plastic-syntax.el
@@ -0,0 +1,118 @@
+;; plastic-syntax.el - Syntax of Plastic
+;; Author: Paul Callaghan <P.C.Callaghan@durham.ac.uk>
+;; Maintainer: <author>
+;; $Id$
+
+;; adapted from the following, by Paul Callaghan
+;; ;; lego-syntax.el Syntax of LEGO
+;; ;; Copyright (C) 1994 - 1998 LFCS Edinburgh.
+;; ;; Author: Thomas Kleymann and Dilip Sequeira
+;; ;; Maintainer: Paul Callaghan <P.C.Callaghan@durham.ac.uk>
+;; ;; lego-syntax.el,v 2.10 1998/11/06 16:18:55 tms Exp
+
+
+(require 'proof-syntax)
+
+;; ----- keywords for font-lock.
+
+(defconst plastic-keywords-goal '("$?Goal"))
+
+(defconst plastic-keywords-save '("$?Save" "SaveFrozen" "SaveUnfrozen"))
+
+(defconst plastic-commands
+ (append plastic-keywords-goal plastic-keywords-save
+ '("allE" "allI" "andE" "andI" "Assumption" "Claim" "Coercion"
+ "Cut" "Discharge" "DischargeKeep"
+ "echo" "exE" "exI" "Expand" "ExpAll"
+ "ExportState" "Equiv" "For" "Freeze" "Hnf" "Immed"
+ "impE" "impI" "Induction" "Inductive"
+ "Invert" "Init" "intros" "Intros" "Module" "Next"
+ "Normal" "notE" "notI" "orE" "orIL" "orIR" "qnify" "Qnify"
+ "Qrepl" "Record" "Refine" "Repeat" "Try" "Unfreeze"))
+ "Subset of Plastic keywords and tacticals which are terminated by a \?;")
+
+(defconst plastic-keywords
+ (append plastic-commands
+ '("Constructors" "Double" "ElimOver" "Fields" "Import" "Inversion"
+ "NoReductions" "Parameters" "Relation" "Theorems")))
+
+(defconst plastic-tacticals '("Then" "Else" "Try" "Repeat" "For"))
+
+;; ----- regular expressions for font-lock
+(defconst plastic-error-regexp "^\\(FAIL\\)"
+ "A regular expression indicating that the Plastic process has identified an error.")
+
+(defvar plastic-id proof-id)
+
+(defvar plastic-ids (concat plastic-id "\\(\\s *,\\s *" plastic-id "\\)*")
+ "*For font-lock, we treat \",\" separated identifiers as one identifier
+ and refontify commata using \\{plastic-fixup-change}.")
+
+(defconst plastic-arg-list-regexp "\\s *\\(\\[[^]]+\\]\\s *\\)*"
+ "Regular expression maching a list of arguments.")
+
+(defun plastic-decl-defn-regexp (char)
+ (concat "\\[\\s *\\(" plastic-ids "\\)" plastic-arg-list-regexp char))
+; Examples
+; ^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^
+; [ sort =
+; [ sort [n:nat] =
+; [ sort [abbrev=...][n:nat] =
+
+(defconst plastic-definiendum-alternative-regexp
+ (concat "\\(" plastic-id "\\)" plastic-arg-list-regexp "\\s * ==")
+ "Regular expression where the first match identifies the definiendum.")
+
+(defvar plastic-font-lock-terms
+ (list
+
+ ; lambda binders
+ (list (plastic-decl-defn-regexp "[:|?]") 1
+ 'proof-declaration-name-face)
+
+ ; let binders
+ (list plastic-definiendum-alternative-regexp 1 'font-lock-function-name-face)
+ (list (plastic-decl-defn-regexp "=") 1 'font-lock-function-name-face)
+
+ ; Pi and Sigma binders
+ (list (concat "[{<]\\s *\\(" plastic-ids "\\)") 1
+ 'proof-declaration-name-face)
+
+ ;; Kinds
+ (cons (concat "\\<Prop\\>\\|\\<Type\\s *\\(("
+ plastic-id ")\\)?") 'font-lock-type-face))
+ "*Font-lock table for Plastic terms.")
+
+;; Instead of "[^:]+", it may be better to use "plastic-id". Furthermore,
+;; it might be safer to append "\\s-*:".
+(defconst plastic-goal-with-hole-regexp
+ (concat "\\(" (proof-ids-to-regexp plastic-keywords-goal) "\\)\\s-+\\([^:]+\\)")
+ "Regular expression which matches an entry in `plastic-keywords-goal'
+ and the name of the goal.")
+
+(defconst plastic-save-with-hole-regexp
+ (concat "\\(" (proof-ids-to-regexp plastic-keywords-save) "\\)\\s-+\\([^;]+\\)")
+ "Regular expression which matches an entry in
+ `plastic-keywords-save' and the name of the goal.")
+
+(defvar plastic-font-lock-keywords-1
+ (append
+ plastic-font-lock-terms
+ (list
+ (cons (proof-ids-to-regexp plastic-keywords) 'font-lock-keyword-face)
+ (cons (proof-ids-to-regexp plastic-tacticals) 'proof-tacticals-name-face)
+ (list plastic-goal-with-hole-regexp 2 'font-lock-function-name-face)
+ (list plastic-save-with-hole-regexp 2 'font-lock-function-name-face))))
+
+(defun plastic-init-syntax-table ()
+ "Set appropriate values for syntax table in current buffer."
+
+ (modify-syntax-entry ?_ "_")
+ (modify-syntax-entry ?\' "_")
+ (modify-syntax-entry ?\| ".")
+ (modify-syntax-entry ?\* ". 23")
+ (modify-syntax-entry ?\( "()1")
+ (modify-syntax-entry ?\) ")(4"))
+
+
+(provide 'plastic-syntax)
diff --git a/plastic/plastic.el b/plastic/plastic.el
new file mode 100644
index 00000000..185ebd48
--- /dev/null
+++ b/plastic/plastic.el
@@ -0,0 +1,684 @@
+;; plastic.el - Major mode for Plastic proof assistant
+;; Author: Paul Callaghan <P.C.Callaghan@durham.ac.uk>
+;; Maintainer: <author>
+;; $Id$
+
+;; adapted from the following, by Paul Callaghan
+;; ;; lego.el Major mode for LEGO proof assistants
+;; ;; Copyright (C) 1994 - 1998 LFCS Edinburgh.
+;; ;; Author: Thomas Kleymann and Dilip Sequeira
+;; ;; Maintainer: Paul Callaghan <P.C.Callaghan@durham.ac.uk>
+;; ;;
+;; ;; lego.el,v 2.27 1998/11/25 12:56:47 da Exp
+
+;; NOTES:
+;; remember to prefix all potential cmds with plastic-lit-string
+;; alternative is to fix the filtering
+
+
+(require 'proof)
+(require 'plastic-syntax)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; User Configuration ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; I believe this is standard for Linux under RedHat -tms
+(defcustom plastic-tags "TO BE DONE"
+ "*The directory of the TAGS table for the Plastic library"
+ :type 'file
+ :group 'plastic)
+
+(defcustom plastic-test-all-name "need_a_global_lib"
+ "*The name of the LEGO module which inherits all other modules of the
+ library."
+ :type 'string
+ :group 'plastic)
+
+(defvar plastic-lit-string
+ ">"
+ "*Prefix of literate lines. Set to empty string to get non-literate mode")
+
+(defcustom plastic-help-menu-list
+ '(["The PLASTIC Reference Card" (browse-url plastic-www-refcard) t]
+ ["The PLASTIC library (WWW)" (browse-url plastic-library-www-page) t])
+ "List of menu items, as defined in `easy-menu-define' for Plastic
+ specific help."
+ :type '(repeat sexp)
+ :group 'plastic)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Configuration of Generic Proof Package ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Users should not need to change this.
+
+(defvar plastic-shell-process-output
+ '((lambda (cmd string) (proof-string-match "^Module" cmd)) .
+ (lambda (cmd string)
+ (setq proof-shell-delayed-output
+ ;;FIXME: This should be displayed in the minibuffer only
+ (cons 'insert "\n\nImports done!"))))
+ "Acknowledge end of processing import declarations.")
+
+(defconst plastic-process-config
+ (concat plastic-lit-string
+ " &S ECHO No PrettyPrinting configuration implemented;\n")
+ "Command to enable pretty printing of the Plastic process.
+ Proof-General annotations triggered by a cmd-line opt
+ ")
+
+(defconst plastic-pretty-set-width "&S ECHO no PrettyWidth ;\n"
+ "Command to adjust the linewidth for pretty printing of the Plastic
+ process.")
+
+(defconst plastic-interrupt-regexp "Interrupt.."
+ "Regexp corresponding to an interrupt")
+
+
+;; ----- web documentation
+
+(defcustom plastic-www-home-page "http://www.dur.ac.uk/CARG/plastic.html"
+ "Plastic home page URL."
+ :type 'string
+ :group 'plastic)
+
+(defcustom plastic-www-latest-release
+ (concat plastic-www-home-page "/current")
+ "The WWW address for the latest Plastic release."
+ :type 'string
+ :group 'plastic)
+
+(defcustom plastic-www-refcard
+ plastic-www-home-page
+ "URL for the Plastic reference card."
+ :type 'string
+ :group 'plastic)
+
+(defcustom plastic-library-www-page
+ (concat plastic-www-home-page "/library")
+ "The HTML documentation of the Plastic library."
+ :type 'string
+ :group 'plastic)
+
+
+
+;; ----- plastic-shell configuration options
+
+(defcustom plastic-base
+ "/usr/local/plastic"
+ ;; da: was
+ ;; "PLASTIC_BASE:TO_BE_CUSTOMISED"
+ "*base dir of plastic distribution"
+ :type 'string
+ :group 'plastic)
+
+(defvar plastic-prog-name
+ (concat plastic-base "/bin/plastic")
+ "*Name of program to run as plastic.")
+
+(defun plastic-set-default-env-vars ()
+ "defaults for the expected lib vars."
+ (cond
+ ((not (getenv "PLASTIC_LIB"))
+ (setenv "PLASTIC_LIB" (concat plastic-base "/lib"))
+ (setenv "PLASTIC_TEST" (concat plastic-base "/test"))
+ )))
+
+(defvar plastic-shell-prompt-pattern "^\\(LF>[ \201]*\\)+"
+ "*The prompt pattern for the inferior shell running plastic.")
+
+(defvar plastic-shell-cd
+ (concat plastic-lit-string " &S ECHO no cd ;\n")
+ "*Command of the inferior process to change the directory.")
+
+(defvar plastic-shell-abort-goal-regexp "KillRef: ok, not in proof state"
+ "*Regular expression indicating that the proof of the current goal
+ has been abandoned.")
+
+(defvar plastic-shell-proof-completed-regexp "\\*\\*\\* QED \\*\\*\\*"
+ "*Regular expression indicating that the proof has been completed.")
+
+(defvar plastic-save-command-regexp
+ (concat "^" (proof-ids-to-regexp plastic-keywords-save)))
+(defvar plastic-goal-command-regexp
+ (concat "^" (proof-ids-to-regexp plastic-keywords-goal)))
+
+(defvar plastic-kill-goal-command
+ (concat plastic-lit-string " &S ECHO KillRef not applicable;"))
+(defvar plastic-forget-id-command
+ (concat plastic-lit-string " &S Forget "))
+
+(defvar plastic-undoable-commands-regexp
+ (proof-ids-to-regexp '("Refine" "Intros" "intros" "Normal" "Claim" "Immed"))
+ "Undoable list")
+
+;; "Dnf" "Refine" "Intros" "intros" "Next" "Normal"
+;; "Qrepl" "Claim" "For" "Repeat" "Succeed" "Fail" "Try" "Assumption"
+;; "UTac" "Qnify" "qnify" "andE" "andI" "exE" "exI" "orIL" "orIR" "orE" "ImpI"
+;; "impE" "notI" "notE" "allI" "allE" "Expand" "Induction" "Immed"
+;; "Invert"
+
+;; ----- outline
+
+(defvar plastic-goal-regexp "\\?\\([0-9]+\\)")
+
+(defvar plastic-outline-regexp
+ (concat "[[*]\\|"
+ (proof-ids-to-regexp
+ '("Discharge" "DischargeKeep" "Freeze" "$?Goal" "Module" "Record" "Inductive"
+ "Unfreeze"))))
+
+(defvar plastic-outline-heading-end-regexp ";\\|\\*)")
+
+(defvar plastic-shell-outline-regexp plastic-goal-regexp)
+(defvar plastic-shell-outline-heading-end-regexp plastic-goal-regexp)
+
+(defvar plastic-error-occurred
+ nil
+ "flag for whether undo is required for try or minibuffer cmds")
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Derived modes - they're here 'cos they define keymaps 'n stuff ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define-derived-mode plastic-shell-mode proof-shell-mode
+ "plastic-shell"
+ ;; With nil argument for docstring, Emacs makes up a nice one.
+ nil
+ (plastic-shell-mode-config))
+
+(define-derived-mode plastic-mode proof-mode
+ "plastic"
+ nil
+ (plastic-mode-config)
+ (easy-menu-change (list proof-general-name) (car proof-help-menu)
+ (append (cdr proof-help-menu) plastic-help-menu-list)))
+
+(eval-and-compile
+ (define-derived-mode plastic-response-mode proof-response-mode
+ "PlasticResp" nil
+ (setq font-lock-keywords plastic-font-lock-terms)
+ (plastic-init-syntax-table)
+ (proof-response-config-done)))
+
+(define-derived-mode plastic-goals-mode proof-goals-mode
+ "PlasticGoals" "Plastic Goal State"
+ (plastic-goals-mode-config))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Code that's plastic specific ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun plastic-count-undos (span)
+ "This is how to work out what the undo commands are.
+Given is the first SPAN which needs to be undone."
+ (let ((ct 0) string i)
+ (while span
+ (setq string (span-property span 'cmd))
+ (plastic-preprocessing) ;; dynamic scope, on string
+ (cond ((eq (span-property span 'type) 'vanilla)
+ (if (or (proof-string-match plastic-undoable-commands-regexp string)
+ (and (proof-string-match "Equiv" string)
+ (not (proof-string-match "Equiv\\s +[TV]Reg" string))))
+ (setq ct (+ 1 ct))))
+ ((eq (span-property span 'type) 'pbp)
+ (setq i 0)
+ (while (< i (length string))
+ (if (= (aref string i) proof-terminal-char) (setq ct (+ 1 ct)))
+ (setq i (+ 1 i)))))
+ (setq span (next-span span 'type)))
+ (concat plastic-lit-string " &S Undo x" (int-to-string ct) proof-terminal-string)))
+
+(defun plastic-goal-command-p (str)
+ "Decide whether argument is a goal or not" ;; NEED CHG.
+ (proof-string-match plastic-goal-command-regexp str))
+
+(defun plastic-find-and-forget (span)
+ ;; count the number of spans to undo.
+ ;; all spans are equal...
+ ;; (NB the 'x' before the id is required so xNN looks like an id,
+ ;; so that Undo can be implemented via the tmp_cmd route.)
+ (let (string (spans 0))
+ (while span
+ (setq string (span-property span 'cmd))
+ (plastic-preprocessing) ;; dynamic scope, on string
+
+ (cond
+ ((null string) nil)
+ ((or (string-match "^\\s-*import" string)
+ (string-match "^\\s-*test" string)
+ (string-match "^\\s-*\\$" string)
+ (string-match "^\\s-*#" string))
+ (if (yes-or-no-p-dialog-box
+ (concat "Can't Undo imports yet\n"
+ "You have to exit prover for this\n"
+ "Continue with Exit?"))
+ (proof-shell-exit)
+ nil) ) ;; see if the user wants to quit.
+ (t (incf spans))
+ )
+ (setq span (next-span span 'type))
+
+ )
+ (concat plastic-lit-string " &S Undo x" (int-to-string spans) proof-terminal-string) ))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Other stuff which is required to customise script management ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun plastic-goal-hyp () ;; not used.
+ (cond
+ ((looking-at plastic-goal-regexp)
+ (cons 'goal (match-string 1)))
+ ((looking-at proof-shell-assumption-regexp)
+ (cons 'hyp (match-string 1)))
+ (t nil)))
+
+
+;; NEED TO REFINE THIS (may99)
+
+(defun plastic-state-preserving-p (cmd)
+ (not (proof-string-match plastic-undoable-commands-regexp cmd)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Commands specific to plastic ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(proof-defshortcut plastic-Intros
+ (concat plastic-lit-string " Intros ") ?I)
+(proof-defshortcut plastic-intros
+ (concat plastic-lit-string " intros ") ?i)
+(proof-defshortcut plastic-Refine
+ (concat plastic-lit-string " Refine ") ?i)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Plastic shell startup and exit hooks ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar plastic-shell-current-line-width nil
+ "Current line width of the Plastic process's pretty printing module.
+ Its value will be updated whenever the corresponding screen gets
+ selected.")
+
+;; The line width needs to be adjusted if the PLASTIC process is
+;; running and is out of sync with the screen width
+
+(defun plastic-shell-adjust-line-width ()
+ "Use Plastic's pretty printing facilities to adjust output line width.
+ Checks the width in the `proof-goals-buffer'
+ ACTUALLY - still need to work with this. (pcc, may99)"
+ (and (buffer-live-p proof-goals-buffer)
+ (proof-shell-live-buffer)
+ (save-excursion
+ (set-buffer proof-goals-buffer)
+ (let ((current-width
+ ;; Actually, one might sometimes
+ ;; want to get the width of the proof-response-buffer
+ ;; instead. Never mind.
+ (window-width (get-buffer-window proof-goals-buffer))))
+
+ (if (equal current-width plastic-shell-current-line-width) ()
+ ; else
+ (setq plastic-shell-current-line-width current-width)
+ (set-buffer proof-shell-buffer)
+ (insert (format plastic-pretty-set-width (- current-width 1)))
+ )))))
+
+(defun plastic-pre-shell-start ()
+ (setq proof-prog-name (concat plastic-prog-name "")
+ ;; set cmd-line flag
+ proof-mode-for-shell 'plastic-shell-mode
+ proof-mode-for-response 'plastic-response-mode
+ proof-mode-for-goals 'plastic-goals-mode)
+
+ (setenv "PROOF_GENERAL" "") ;; signal to plastic, use annotations
+ )
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Configuring proof mode and setting up various utilities ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun plastic-mode-config ()
+ ;; da: this is now a user-option, please set it in your .emacs
+ ;; via customize mechanism.
+ ;; (setq proof-electric-terminator-enable t) ;; force semicolons active.
+
+ (setq proof-terminal-char ?\;)
+ (setq proof-comment-start "(*") ;; these still active
+ (setq proof-comment-end "*)")
+
+ (setq proof-assistant-home-page plastic-www-home-page)
+ (setq proof-mode-for-script 'plastic-mode)
+
+ (setq proof-showproof-command (concat plastic-lit-string " &S PrfCtxt")
+ proof-goal-command (concat plastic-lit-string " Claim %s;")
+ proof-save-command (concat plastic-lit-string " Save %s;") ;; analogue?
+ proof-context-command (concat plastic-lit-string " &S Ctxt 20"))
+
+ (setq proof-showproof-command (concat plastic-lit-string " &S PrfCtxt")
+ proof-goal-command (concat plastic-lit-string " Claim %s;")
+ proof-save-command (concat plastic-lit-string " Save %s;") ;; analogue?
+ proof-context-command (concat plastic-lit-string " &S Ctxt 20")
+ ;; show 20 things; see ^c+C...
+ proof-info-command (concat plastic-lit-string " &S Help"))
+
+ (setq proof-goal-command-p 'plastic-goal-command-p
+ proof-count-undos-fn 'plastic-count-undos
+ proof-find-and-forget-fn 'plastic-find-and-forget
+ proof-goal-hyp-fn 'plastic-goal-hyp
+ proof-state-preserving-p 'plastic-state-preserving-p)
+
+ (setq proof-save-command-regexp plastic-save-command-regexp
+ proof-goal-command-regexp plastic-goal-command-regexp
+ proof-save-with-hole-regexp plastic-save-with-hole-regexp
+ proof-goal-with-hole-regexp plastic-goal-with-hole-regexp
+ proof-kill-goal-command plastic-kill-goal-command
+ proof-indent-any-regexp
+ (proof-regexp-alt
+ (proof-ids-to-regexp plastic-commands)
+ "\\s(" "\\s)"))
+
+ (plastic-init-syntax-table)
+
+ ;; da: I've moved these out of proof-config-done in proof-script.el
+ (setq pbp-goal-command (concat "UNIMPLEMENTED"))
+ (setq pbp-hyp-command (concat "UNIMPLEMENTED"))
+
+;; font-lock
+
+ (setq font-lock-keywords plastic-font-lock-keywords-1)
+
+;; FIXME da: this is done generically now. If you want
+;; the zap commas behaviour, set proof-font-lock-zap-commas=t here.
+;; (and (boundp 'font-lock-always-fontify-immediately)
+;; (setq font-lock-always-fontify-immediately t))
+
+
+ (proof-config-done)
+
+;; outline
+
+ (make-local-variable 'outline-regexp)
+ (setq outline-regexp plastic-outline-regexp)
+
+ (make-local-variable 'outline-heading-end-regexp)
+ (setq outline-heading-end-regexp plastic-outline-heading-end-regexp)
+
+;; tags
+ (cond ((boundp 'tags-table-list)
+ (make-local-variable 'tags-table-list)
+ (setq tags-table-list (cons plastic-tags tags-table-list))))
+
+ (and (boundp 'tag-table-alist)
+ (setq tag-table-alist
+ (append '(("\\.lf$" . plastic-tags)
+ ("plastic" . plastic-tags))
+ tag-table-alist)))
+
+ (setq blink-matching-paren-dont-ignore-comments t)
+
+;; hooks and callbacks
+
+ (add-hook 'proof-pre-shell-start-hook 'plastic-pre-shell-start nil t)
+ (add-hook 'proof-shell-insert-hook 'plastic-shell-adjust-line-width)
+ (add-hook 'proof-shell-handle-error-or-interrupt-hook 'plastic-had-error)
+ (add-hook 'proof-shell-insert-hook 'plastic-preprocessing)
+
+;; (add-hook 'proof-shell-handle-error-or-interrupt-hook
+;; (lambda()(goto-char (search-forward (char-to-string proof-terminal-char)))))
+
+;; (add-hook 'proof-shell-handle-delayed-output-hook `plastic-show-shell-buffer t)
+;; this forces display of shell-buffer after each cmd, rather than goals-buffer
+;; it is not always necessary - could always add it as a toggle option?
+
+;; set up the env.
+ (plastic-set-default-env-vars)
+ )
+
+(defun plastic-show-shell-buffer ()
+ "switch buffers."
+ (display-buffer proof-shell-buffer)
+ )
+
+
+(defun plastic-equal-module-filename (module filename)
+ "Returns `t' if MODULE is equal to the FILENAME and `nil' otherwise.
+The directory and extension is stripped of FILENAME before the test."
+ (equal module
+ (file-name-sans-extension (file-name-nondirectory filename))))
+
+(defun plastic-shell-compute-new-files-list (str)
+ "Function to update `proof-included-files list'.
+
+It needs to return an up to date list of all processed files. Its
+output is stored in `proof-included-files-list'. Its input is the
+string of which `plastic-shell-retract-files-regexp' matched a
+substring.
+
+We assume that module identifiers coincide with file names."
+ (let ((module (match-string 1 str)))
+ (cdr (member-if
+ (lambda (filename) (plastic-equal-module-filename module filename))
+ proof-included-files-list))))
+
+
+
+(defun plastic-shell-mode-config ()
+ (setq proof-shell-prompt-pattern plastic-shell-prompt-pattern
+ proof-shell-cd-cmd plastic-shell-cd
+ proof-shell-abort-goal-regexp plastic-shell-abort-goal-regexp
+ proof-shell-proof-completed-regexp plastic-shell-proof-completed-regexp
+ proof-shell-error-regexp plastic-error-regexp
+ proof-shell-interrupt-regexp plastic-interrupt-regexp
+ ;; DEAD proof-shell-noise-regexp "Discharge\\.\\. "
+ proof-shell-assumption-regexp plastic-id
+ proof-shell-goal-regexp plastic-goal-regexp
+ proof-shell-first-special-char ?\360
+ proof-shell-wakeup-char ?\371 ;; only for first send?
+;; proof-shell-wakeup-char nil ;; NIL turns off annotations.
+ proof-shell-start-char ?\372
+ proof-shell-end-char ?\373
+ proof-shell-field-char ?\374
+ proof-shell-goal-char ?\375
+ proof-shell-eager-annotation-start "\376"
+ ;; FIXME da: if p-s-e-a-s is implemented, you should set
+ ;; proof-shell-eager-annotation-start-length=1 to
+ ;; avoid possibility of duplicating short messages.
+ proof-shell-eager-annotation-end "\377"
+
+ proof-shell-annotated-prompt-regexp "LF> \371"
+ proof-shell-result-start "\372 Pbp result \373"
+ proof-shell-result-end "\372 End Pbp result \373"
+ proof-shell-start-goals-regexp "\372 Start of Goals \373"
+ proof-shell-end-goals-regexp "\372 End of Goals \373"
+
+ proof-shell-init-cmd plastic-process-config
+ proof-shell-restart-cmd plastic-process-config
+ proof-analyse-using-stack nil
+ proof-shell-process-output-system-specific plastic-shell-process-output
+ plastic-shell-current-line-width nil
+
+ proof-shell-process-file
+ (cons "Creating mark \"\\(.*\\)\" \\[\\(.*\\)\\]"
+ (lambda (str) (let ((match (match-string 2 str)))
+ (if (equal match "") match
+ (concat (file-name-sans-extension match) ".l")))))
+
+ proof-shell-retract-files-regexp "forgot back through Mark \"\\(.*\\)\""
+ font-lock-keywords plastic-font-lock-keywords-1
+
+ proof-shell-compute-new-files-list 'plastic-shell-compute-new-files-list)
+
+ (plastic-init-syntax-table)
+
+ (proof-shell-config-done)
+ )
+
+(defun plastic-goals-mode-config ()
+ (setq pbp-change-goal "Next %s;"
+ pbp-error-regexp plastic-error-regexp)
+ (setq font-lock-keywords plastic-font-lock-terms)
+ (plastic-init-syntax-table)
+ (proof-goals-config-done))
+
+
+
+;;;;;;;;;;;;;;;;;
+;; MY new additions.
+
+(defun plastic-small-bar () (interactive) (insert "%------------------------------\n"))
+
+(defun plastic-large-bar () (interactive) (insert "%-------------------------------------------------------------------------------\n"))
+
+(defun plastic-preprocessing ()
+ "clear comments and remove literate marks (ie, \\n> ) - acts on var string"
+
+ ;; might want to use proof-string-match here if matching is going to be
+ ;; case sensitive (see docs)
+
+ (if (= 0 (length plastic-lit-string))
+ string ;; no-op if non-literate
+
+ ;; remaining lines are the Else. (what, no 'return'?)
+ (setq string (concat "\n" string " ")) ;; seed routine below, & extra char
+ (let* ;; da: let* not really needed, added to nuke byte-comp warnings.
+ ( (i 0)
+ (l (length string))
+ (eat-rest (lambda ()
+ (aset string i ?\ ) ;; kill the \n or "-" at least
+ (incf i)
+ (while (and (< i l) (/= (aref string i) ?\n))
+ (aset string i ?\ )
+ (incf i) )))
+ (keep-rest (lambda ()
+ (loop for x in (string-to-list plastic-lit-string)
+ do (aset string i ?\ ) (incf i))
+ (while (and (< i l)
+ (/= (aref string i) ?\n)
+ (/= (aref string i) ?-))
+ (incf i) )))
+ )
+ (while (< i l)
+ (cond
+ ((eq 0 (string-match "--" (substring string i)))
+ (funcall eat-rest)) ;; comment.
+ ((eq 0 (string-match "\n\n" (substring string i)))
+ (aset string i ?\ )
+ (incf i)) ;; kill repeat \n
+
+ ((= (aref string i) ?\n) ;; start of new line
+ (aset string i ?\ ) (incf i) ;; remove \n
+
+ (if (eq 0 (string-match plastic-lit-string
+ (substring string i)))
+ (funcall keep-rest) ;; code line.
+ (funcall eat-rest) ;; non-code line
+ ))
+
+ (t (incf i)) ;; else include.
+ )
+ )
+ (setq string (replace-in-string string " *" " "))
+ (setq string (replace-in-string string "^ *" ""))
+ (if (string-match "^\\s-*$" string)
+ (setq string (concat "ECHO comment line" proof-terminal-string))
+ string)
+ )))
+
+
+(defun plastic-all-ctxt ()
+ "show the full ctxt"
+ (interactive)
+ (proof-shell-invisible-command
+ (concat plastic-lit-string " &S Ctxt" proof-terminal-string))
+ )
+
+(defun plastic-send-one-undo ()
+ "send an Undo cmd"
+ ;; FIXME etc
+ ;; is like this because I don't want the undo output to be shown.
+ (proof-shell-insert (concat plastic-lit-string " &S Undo;")
+ 'proof-done-invisible))
+
+;; hacky expt version.
+;; still don't understand the significance of cmd!
+
+(defun plastic-minibuf-cmd (cmd)
+ "do minibuffer cmd then undo it, if error-free."
+ (plastic-reset-error)
+ (interactive
+ (list (read-string "Command: " nil 'proof-minibuffer-history)))
+ (if (and proof-state-preserving-p
+ (not (funcall proof-state-preserving-p cmd)))
+ (error "Command is not state preserving, I won't execute it!"))
+ (proof-shell-invisible-command cmd)
+ (plastic-call-if-no-error 'plastic-send-one-undo))
+
+(defun plastic-minibuf ()
+ "do minibuffer cmd then undo it, if error-free."
+ (interactive)
+ (plastic-reset-error)
+ (plastic-send-minibuf)
+ (plastic-call-if-no-error 'plastic-send-one-undo))
+
+(defun plastic-synchro ()
+ "do minibuffer cmd BUT DON'T UNDO IT - use if things go wrong!"
+ (interactive)
+ (plastic-send-minibuf))
+
+(defun plastic-send-minibuf ()
+ "take cmd from minibuffer - see doc for proof-minibuffer-cmd"
+ (interactive)
+ (let (cmd)
+ (setq cmd (read-string "Command: " nil 'proof-minibuffer-history))
+ (setq cmd (concat plastic-lit-string " " cmd proof-terminal-string))
+ (proof-shell-invisible-command cmd)))
+
+(defun plastic-had-error ()
+ "sets var plastic-error-occurred, called from hook"
+ (if (eq proof-shell-error-or-interrupt-seen 'error)
+ (setq plastic-error-occurred t)))
+(defun plastic-reset-error ()
+ "UNsets var plastic-error-occurred, before minibuffer or try cmd"
+ (setq plastic-error-occurred nil))
+(defun plastic-call-if-no-error (fn)
+ "wait for proof process to be idle, and call fn if error-free."
+ (while proof-shell-busy (sleep-for 0.25))
+ (if (not plastic-error-occurred) (funcall fn)))
+
+(defun plastic-show-shell ()
+ "shortcut to shell buffer"
+ (interactive)
+ (proof-switch-to-buffer proof-shell-buffer))
+
+;; pcc macros etc
+;; da: I've moved these key defs out of plastic-mode-config
+
+(define-key plastic-keymap ?s 'plastic-small-bar)
+(define-key plastic-keymap ?l 'plastic-large-bar)
+(define-key plastic-keymap ?a 'plastic-all-ctxt)
+(define-key plastic-keymap [(control c) (control v)] 'plastic-minibuf)
+(define-key plastic-keymap [(control c) (control o)] 'plastic-synchro)
+(define-key plastic-keymap [(control c) (control s)] 'plastic-show-shell)
+
+
+
+;; original end.
+
+;;;;;;;;;;;;;;;;;
+;; hacky overriding of the toolbar command
+;; my version handles literate characters.
+;; (should do better for long-term though)
+
+(defalias 'proof-toolbar-command 'plastic-minibuf-cmd)
+
+;;;
+
+(provide 'plastic)
diff --git a/plastic/test.lf b/plastic/test.lf
new file mode 100644
index 00000000..7c163d3d
--- /dev/null
+++ b/plastic/test.lf
@@ -0,0 +1,64 @@
+EXAMPLE FILE: less than or equal on Nat
+
+%---------------------------------------
+Nat
+
+> Inductive
+> [Nat : Type]
+> Constructors
+> [zero : Nat]
+> [succ : (n:Nat)Nat];
+
+> [plus [m:Nat] = E_Nat ([_:Nat]Nat) m ([_:Nat]succ) ];
+
+
+-----------------------
+Non-dependent Pi type.
+
+> Inductive
+> [A,B:Type]
+> [Pi_ : Type]
+> Constructors
+> [La_ : (f:(x:El A)El B)Pi_ ];
+
+
+application of Pi_ types, ie conversion to a dependent product.
+
+> Claim ap_ : (A,B:Type) Pi_ A B -> A -> B;
+> Intros A B f x;
+> Refine E_Pi_ ? ? ([_:?]B);
+> Refine f;
+> Intros fo;
+> Refine fo x;
+> ReturnAll;
+> ap_;
+
+
+
+%---------------------------------------
+Combined leq with if-branch - thus avoiding Boolean type.
+
+Notice that we have to prove (Pi_ Nat T) by induction on x, since we can't
+eliminate over (Nat -> T) in LF.
+
+
+> Claim if_leq : (x,y:Nat)(T:Type)T -> T -> T;
+> Intros x y T leq not_leq;
+> Refine ap_ ? ? (ap_ ? ? ? x) y;
+
+> Refine La_;
+> Intros x1;
+> Refine E_Nat ([_:?]Pi_ Nat T) ?x_z ?x_s x1;
+> x_z Refine La_ ? ? ([_:?]leq);
+> Intros x1_ f_x1_;
+> Refine La_;
+> Intros y1;
+> Refine E_Nat ([_:?]T) ?y_z ?y_s y1;
+> y_z Refine not_leq;
+> Intros y1_ _;
+> Refine ap_ ? ? f_x1_ y1_;
+> ReturnAll;
+
+> if_leq;
+
+
diff --git a/plastic/todo b/plastic/todo
new file mode 100644
index 00000000..5ea74023
--- /dev/null
+++ b/plastic/todo
@@ -0,0 +1,10 @@
+-*- mode:outline -*-
+
+* Things to do for Plastic
+
+See also ../todo for generic things to do, priority codes.
+
+** Add as part of main distribution when Plastic ready
+
+ Edit Makefile.devel
+
diff --git a/todo b/todo
new file mode 100644
index 00000000..b5df1a76
--- /dev/null
+++ b/todo
@@ -0,0 +1,958 @@
+-*- mode:outline -*-
+
+* Proof General Low-level List of Things to Do
+
+$Id$
+
+This is an outline file. Use C-c C-n, C-c C-p or menu to navigate.
+
+** 0. Contents
+
+ 1. Priorities
+ 2. Things to do in the generic interface
+ 3. Things to do for the documentation
+ 4. FSF Emacs issues
+ 5. Things to do for Proof-by-Pointing
+ 6. Things to do for Web Pages, Distribution
+ 7. Future improvements to take advantage of newer Emacsen
+ 8. Bugs in other software beyond our control
+ 9. Stable version release checklist
+10. Things to do for Proof General Project
+
+ See <prover>/todo for things to do for each prover.
+
+** 1. Priorities
+
+A (High) e.g. to be fixed ASAP for next pre-release
+B e.g. to be fixed before next release
+C (Medium) e.g. would be nice to fix before next release; not crucial
+D e.g. desirable to fix at some point
+X (Low) e.g. probably not worth spending time on
+
+
+** 2. Things to in the generic interface
+
+*** B Documentation:
+ Check new doc for hiding; add doc for dependencies, tracing.
+ Moving spans; navigating through locked region.
+
+
+*** C Fix byte compilation
+ Problem with proof-ass macro mechanism -- gets expanded during compilation.
+
+*** C The PG isabelle-completion-table seems to be subject to case-fold, which
+ it shouldn't be: \<sqinter> does not work, but \<Sqinter> is OK.
+
+*** C Ignore table entries for non-existent directories in proof-site.el
+
+*** B generalize from Isabelle's "atomic scripting" theory file mode
+ to allow other instances which do not allow incremental
+ processing of files in major or auxiliary file types.
+ E.g. twelf ACL2.
+ Also, add the atomic scripting handling for Isabelle/Isar.
+
+*** B Move over to new better designed parsing function mechanism.
+
+*** C ChangeLog generation still not right.
+ Suggested fix: use the prefix that rcs2log generates, without prepending.
+ Take a tail of the current ChangeLog and use that as the starting point,
+ perhaps?
+
+*** D RPM package todos:
+ - get specific doc files into RPM package (subdirs of doc/)
+ - Think about adding wmconfig stuff (icons in images/ now)
+
+*** C Fix the doc makefiles to adapt the image flag in PG-adapting.tex
+ properly, for dvi/ps targets
+
+*** D some renaming for uniformity:
+
+ proof-comment-start -> proof-script-comment-start, ditto end
+
+*** B Generalize electric terminator mode for other parsing mechanisms.
+
+*** B Add parameter for help function so HOL help works nicely
+
+*** B Make tags support in lego.el and coq.el a bit more generic.
+ Use customization option proof-tags-support.
+
+*** B Display functions: does auto-delete-windows work with
+ window-dedicated as it should? (I thought it would switch
+ between 2/3 bufs as appropriate?).
+
+*** B Clean up assert-until-point stuff: should have just one
+ function, as a subroutine of assert-next-command; and no bizarre
+ never-used arguments!
+
+*** B proof-shell-restart should clear response buffer (only noticed with
+ proof-tidy-response=nil)
+
+*** B Continue programme of making adaptation easier.
+
+*** C Fix up sources to conform to library header conventions
+ see (lispref)Library Headers.
+
+*** C Proof shell exit function -- could try sending an interrupt first
+ if the process is busy, just to be polite (and avoid the 10 second
+ wait before it gets killed).
+
+*** C make pretty printer line width altering generic.
+ Make a generic hook (or hook-constructing macro) to adjust
+ pretty printer line widths, a la LEGO. Maybe find a better
+ place to do this that in the proof-shell-insert-hook (should
+ be triggered by resize events).
+
+*** C X-Symbol: is there a function to input in the minibuffer using
+ a token language?
+
+*** C Investigate possible toolbar refresh problems.
+ Sometimes extra clicks *are* needed. Why?
+
+*** C Consider supporting imenu instead, or as well as, func-menu.
+
+*** C New modules:
+ proof-shell-{start,end,goal,blah} -> proof-goals-{blah}
+ pbp-{blah} -> proof-goals-{blah}, new proof-goals.el
+ Low-level commands in proof-script.el -> proof-core.el
+
+*** C Improved configurability of command settings, etc.
+ We should let command settings, etc, be a special type
+ which can be one of three things:
+
+ 'string -- send this as a command to assistant
+ 'function -- call this interactively to return either
+ 'string -- send this as a command
+ nil -- do nothing (function does work).
+
+ This way we cover commands which need prompting for extra
+ args, as well as elisp functions which do whatever's necessary.
+ Then use a generic function "proof-invoke-function" or similar.
+
+*** C Usability enhancement:
+ Movement of point after assert/retract commands
+ - configure by default for one command/line.
+ - Add option for many commands per line.
+ - Maybe shell like behaviour with pressing return?
+
+*** C Usability enhancement:
+ - Fix proof-script-command-separator and
+ proof-one-command-per-line flag, document them.
+
+*** C Support an extended version of dynamic abbreviations, to work
+ for commands rather than words. Should behave a bit like a history
+ mechanism in shell buffer: use M-n M-p to scroll up and down
+ through previous and forthcoming (matching) commands.
+
+*** C TESTING.
+ - Add automatic testing mechanism to test user-level functions PG
+ - Test schedule for things to try with a new instantiation
+
+*** C Is there a way to make colours defined for x work in mswindows too?
+
+ defface specs with (type x) seem to work fine with (type mswindows) too.
+ Hassle to duplicate, is there an easy way to cover both?
+
+*** C Improve proof-easy-config mechanism.
+
+ Let it be redoable by initializing some of the variables to
+ default values to begin with(?). e.g. proof-script-next-entity-regexps.
+ Convention is that everything must be set in proof-easy-config body.
+ Use custom to set everything to its default value from proof-config,
+ before invoking the body.
+
+*** C Add a new configuration setting for matching proof commands
+ which have no undo effect --- should be treated like comments
+ for undo. Perhaps would be useful for Isabelle, HOL, at least,
+ although it's tricky to see how it would be completely *safe*.
+
+*** C Display buffer clearing: response buffer is cleared
+ too often/eagerly, perhaps? The output find-theorems or
+ similar doesn't last beyond a single proof step.
+ The problem is that we want to erase irrelevant
+ output from the response buffer for the previous
+ proof step. Consider making output from invisible
+ command persistent.
+ See attempted patch in
+ etc/patches/fix-attempt-for-eager-cleaning.txt
+
+*** C Add to proof-config those variables created in proof-easy-config for
+ font lock and syntax entries. Use these instead of primitive
+ elisp in the other configs, too.
+
+*** C Improvements to customization mechanism: watch the use
+ of customize-set-variable, odd for users who think it
+ means they've changed a setting!
+ (currently: next-entity-regexps, proof-splash-settings for Isabelle).
+
+*** C Add improvements to script movement in electric terminator mode.
+ Some commented regions in code. E.g. automatic newline/space after
+ C-c C-BS.
+
+*** C Make proof-{script,shell,goals,resp}-font-lock-keywords the
+ default way of setting font-lock-keywords, removing from
+ proof-easy-config and changing each supported prover instance.
+
+*** D Settings mechanism could be generalised for non-persistent settings
+
+ local settings:
+ E.g. Coq has some settings which are local: "Focus" which
+ it doesn't make sense to save between sessions or issue
+ at the start of the session.
+
+ Ideal would be to specify context when local settings are
+ relevant, as a predicate.
+
+*** D Modify response display routine a bit to center around recent output,
+ or display top, for long output. Makes better sense for big
+ screen-fulls, perhaps? Or maybe display top with an itimer to
+ move to the bottom after a couple of seconds delay, would be a
+ nice effect.
+
+*** D Scheme to detect type of buffer and choose between possible modes.
+ Help select Isar over Isa, maybe sml over HOL etc?
+
+*** D Fix the sentinel infinite loop bug which occurs in some cases
+ when proof shell startup fails. Same message is printed over
+ and over. Infinite in FSF Emacs. Why? See note at
+ end of proof-shell. [2hrs]
+
+
+*** D See if there is a way of postponing func-menu loading.
+
+*** D Quit timeout enhancement: instead of killing immediately after
+ timeout, could give a message "not responding, kill immediately?"
+
+*** D Implement proof-generic-find-and-forget
+ <...>-count-undos, to simplify prover-specific code.
+ Complete reengineering of *-count-undos and
+ *-find-and-forget at generic level
+
+*** D Package management for X-Emacs.
+ - arrange into X-Emacs package layout
+ - install under ~/.xemacs
+
+*** D Consider proof-generic-goal-hyp function, for proof by
+ pointing support. Based on `proof-shell-goal-regexp' which
+ I accidently introduced at one point.
+
+*** D Make code robust against accidental deletion of response/goals
+ buffer. Add functions proof-get-or-create-{response,goals}-buffer.
+ [30 mins]
+
+*** D Making undoing better.
+ Rather than calculating an undo command each time an undo command
+ is needed, another idea would be to keep the undo command in the
+ span. Then when we amalgamate spans we can construct new undo
+ commands. When we come to issue an undo, we either need to do
+ each undo step in turn in reverse, just the final one, or perhaps
+ some proof-assistant dependent filtering/modification of the
+ set. At the moment, though, PG is rather keen on issuing just
+ one command to forget to some specific place in the script.
+ [Maybe a design principle is that spans should coincide with
+ undoable regions]
+
+*** D proof-script-next-entity-regexps:
+ "However, it does not parse strings, comments, or parentheses."
+ Actually we could improve the generic code to ignore
+ headings which buffer-syntactic-context suggests are inside
+ comments or strings.
+
+*** D Change the name of "automatic multiple files" to something
+ more comprehensible.
+
+*** D Strange problem when running in tty mode: c-c c-RET seems to be
+ impossible to type. Consider binding C-c RET instead when
+ running on a console.
+
+*** D Tidy up library-loading and dependencies. (Probably do
+ this at the same time as organizing for the XEmacs
+ packaging mechanism)
+
+*** D Make compile should give error if any elisp compile fails.
+
+*** D Check support for proof-guess-command-line, new generic setting
+ added by Patrick. Don't know if anyone can use it, actually.
+
+*** D Usability enhancement:
+ - Fix asymmetry between "doing" and "undoing": doing will skip comments,
+ undoing will not. e.g. test case: (* tester *) intros;
+
+*** D Robustify and cleanup code by allowing functions in place of regexps
+ for proof-goal-command-regexp and proof-save-command-regexp.
+ New names: proof-goal-command-match, proof-save-command-match.
+ Then we can remove duplicity and simplify code.
+
+*** D BUGLETS:
+ - Response buffer doesn't scroll to display o/p (it does for debug msgs,
+ oddly). This might have been a 1998 design decision.
+ Maybe it should be a user option?
+ - XEmacs pg forces on font-lock, should it?
+
+*** D SMALL DELTAS:
+ - Consider setting proof-mode-for-script automatically?
+ Is it ever needed in the shell before the script mode has
+ been entered?
+ - In case active terminator leads to an error, delete it again?
+ (problem synchronizing)
+ - Improvements to script navigation commands. Would like some
+ uniformity with proof-find-next-terminator, and a better
+ implementation. Maybe we have four commands: find command start,
+ command end, and move to next command/previous command.
+
+*** D Make completion more generic. For Isabelle and Lego, we can build a
+ completion table by querying the process, which is better than
+ messing with tags.
+
+*** D outline configuration should be generic (or else documented for
+ each prover separately, since not guaranteed to work for all).
+
+*** D Check matching code carefully, in view of bug reported (now fixed)
+ for Isabelle.
+ Examine syntax tables for all instances, and whether
+ word matching is based on whitespace constituents or non-word
+ constituents. [6 hrs]
+
+*** D Implement proof-auto-retract idea. [4hrs]
+
+*** D da: Suggested improvement to interface for included files:
+ Currently have two cases: processing a single file, and
+ retracting which updates the included file list arbitrarily
+ (but assumes that only removals are made). A simpler and
+ more general interface would be to just have the second
+ case, and automatically find removed files and added files
+ between two versions of proof-included-files-list and
+ unlock or lock buffers appropriately. We could provide
+ a useful default function based on three regexps:
+ retract-file-regexp, add-file-regexp, clear-filelist-regexp.
+ Master regexp process-file-regexp would match all of
+ these cases. Could be multiple matches of the three above
+ within a single process-file-regexp to avoid processing
+ lots of urgent messages. (3h)
+
+*** D da: goal-hyp: this should be more generic. At the moment, there are
+ generic variables which are only used in the specific code:
+ proof-shell-goal-regexp and proof-shell-assumption-regexp.
+ This is confusing. I suggest making lego-goal-hyp the
+ default behaviour for proof-goal-hyp-fn a hook function.
+ That will work for Isabelle too. (15 mins)
+
+*** D proof-goal-command-regexp: the syntax of Coq spoils the
+ uniform use of a regexp to match a goal (since it allows
+ goals to begin Definition ...). Nonetheless, it would be
+ for this not to mean that everyone else needs to set
+ proof-goal-command-p. Perhaps some crucial regexps can
+ be used via proof-string-match-p which would allow a
+ function to be invoked instead? (Cf font lock).
+ Or via a new generic mechanism for matching or invoking a fn.
+
+*** D ROBUSTness: deal gracefully with possibility that goals buffer is
+ killed during session. (2h)
+
+*** D Add support to filter out unwanted noise from the prover by setting
+ up a regular expression proof-shell-noise-regexp [2hr]
+
+*** D support for templates e.g., in LEGO it would be nice if, by default,
+ fresh buffers corrsponding to file foo.l would automatically insert
+ "Module foo;" Probably by using a generic Emacs package. [2hr]
+
+*** D Review and prune "FIXME notes" which are notes about ongoing fixes
+ or sometimes things to do. [6hr]
+
+*** D Write proof-define-derived-mode which automatically adds a
+ call back hook somehow corresponding to our "proof-config-done"
+ mess. Propose this to maintainer of derived.el. (1.5hrs)
+
+*** D Improve proof-goal-command and proof-save-command:
+ `proof-goal-command' should be more flexible and support a
+ placeholder for the name and the actual goal. In LEGO, we have
+ Goal foo : absurd;
+ ...
+ Save foo;
+ Perhaps functions at the generic level to make suitable
+ values for the hook, e.g.,
+
+ (setq proof-goal-command (proof-prompt-named-goal "Goal %s :" "%s;"))
+
+*** D Multiple files: handle failures in reading ancestors.
+
+*** D Provide a sensible default frame/buffer layout (4h)
+
+*** D Implement mouse drag-and-drop support for selecting subterms in the
+ goals buffer and copying them in a script buffer. This could be
+ implemented by defining button2 in the response buffer and setting
+ button2up in script buffers. (1h)
+
+*** D Add support to proof.el for *not* setting variables for
+ commands which aren't supported by a prover. For example,
+ in Isabelle there is no such thing as killing a goal.
+
+*** D proof-find-next-terminator is too slow when it needs to parse
+ a long buffer. Generally a performance problem with
+ proof-segment-up-to.
+
+
+*** D Implement proof-find-previous-terminator and bind it to C-c C-a
+ (45min)
+
+*** D Implement a function to undo to the previous goal.
+
+*** D Remove duplication of variables e.g., proof-prog-name and
+ lego-prog-name for Coq and Lego. (1h)
+
+*** D Display management is much better than it was, but perhaps
+ not quite as good as it could be. It might be nice to
+ display both the goals and response buffer occasionally
+ (even with window-dedicated disabled).
+ e.g. when proof-shell-erase-response-flag is non-nil
+ and the goals buffer is updated: might like to still
+ see what was in the response buffer.
+
+*** D Oddities:
+ Response buffer doesn't get cleared after completion
+ of a proof followed by retraction of whole file.
+ On other cases of retraction, it does.
+ Perhaps retraction should set the flag to ensure
+ it's cleared.
+
+*** D Is it possible to let C-c C-c (SIGINT) issue additional process input?
+ Poly/ML requires an 'f' at the interrupt handler's prompt to proceed, or
+ rather, to fail gracefully.
+
+*** D More flexible help configuration is needed. HOL has some nice
+ on-line help but no way in PG to help by library. Perhaps
+ a help browser is needed? At least, optional arg to help command.
+ [patch ready and waiting to go in]
+
+*** X X-Symbol improvements: see if we can get support for
+ proof-xsym-extra-modes outside PG (just by loading proof-site).
+ Will be handy for Isabelle's .itex Isabelle-LaTeX files.
+ Then we can parameterise more of the xsym support, and
+ remove spurious settings of calculated stuff from
+ x-symbol-isa.el (see FIXME comments in v3.1 there).
+
+*** X X-Symbol improvement: turning it on/off seems to move point.
+
+*** X Why does dired get loaded when PG loads? (Can we speed
+ loading by avoiding a particular function?)
+
+*** X Process handling output.
+ Handling mixtures of urgent and non-urgent messages:
+ at the moment any non-urgent output *before* an urgent
+ message will not be displayed in the response buffer.
+ Accept this as a feature for now.
+
+*** X Internal improvements for marking up proof assistant output.
+ We need a better mechanism for allowing "invisible" mark up
+ of assistant output based on annotations. Present code
+ allows proof-shell-leave-annotations-in-output=t to work
+ together with font-lock to do mark up.
+ Instead we need something more like what enriched-mode does
+ (although I've just tried it and I foound that copying with
+ the mouse ignores the text properties, but copying with the
+ keyboard copies them!). It uses a general library
+ format.el for reading and writing files in multiple formats.
+ This is not quite what we want for our purpose, but it might be a
+ closer approximation than using font-lock-fontify and
+ deleting the special characters. It would allow sgml-like
+ markupo in the future, too.
+ Or maybe w3's code for HTML mark up could be borrowed.
+
+*** X Idea: introduce a dynamic follow mode which follows
+ proof-locked-end rather than proof-queue-or-locked-end.
+ Would be annoying for interactive use though, point would
+ jump from under fingers (although no typing anyway, hardly
+ matters). Alternative is dynamic recenter mode to
+ keep end of locked region in buffer.
+
+*** X Improve goto button image [suggestion from Markus]
+ Is it possible to avoid the arrows to touch in the middle,
+ emphasizing the 'point' a bit more. The arrows look a bit outwards
+ bent, too.
+
+*** X Check compilation okay, check on use of eval-and-compile.
+
+*** X Difference in menubar appearance depending on whether X-Symbol
+ is loaded before Proof General or not.
+
+*** X Update logo to include new "???" prover badge
+ from graphics file elsewhere (da)
+
+*** X bug: outline mode when proof-strict-read-only is nil ought to
+ work, but there may be problems.
+
+*** X CVS repository issues.
+ Where are obsolete 'fileattr' files generated from/maintained?
+ Should junk these (which appear to say that tms is watching everything).
+
+*** X Fixup display problems.
+ The window dedicated stuff is a real pain and I've
+ spent ages inserting workarounds. Why do we want it??
+ The latest problem is that with
+ (setq special-display-regexps
+ (cons "\\*Inferior .*-\\(goals\\|response\\)\\*"
+ special-display-regexps))
+ I get the script buffer made into a dedicated buffer,
+ presumably because the wrong window is selected in
+ proof-display-and-keep-buffer?
+ [da: can't repeat this now, presume it has gone away?]
+
+*** X Add other image sources to images/ directory.
+ Add target to html/images to remove images generated from
+ the image directory.
+
+*** X splash screen: report XEmacs problem of not displaying transparent
+ gif properly.
+
+*** X Allow bib-cite style clicking on Load/Import commands to go
+ to file.
+
+*** X Images for splash screen: could add xpm files for logos
+ so that XEmacs displays transparent parts properly.
+ (Probably not worth effort of distributing more files).
+
+*** X Customization mechanism: is there a way to make saved settings
+ not be overwritten by setq's in the code? Need to think how
+ to do this, something like customize-set-variable-if-unchanged
+ Otherwise no so useful for people to use customize for
+ prover config settings (we'd need to shadow them all again for
+ each assistant for this to work smoothly).
+ Sure sign saving will fail is when you see "this option has
+ been changed outside customization buffer"
+ At the moment even setting config variables in a hook is tricky,
+ because proof-config-done is called before the hook variables for the
+ new mode are. Our new version of define-derived-mode needs
+ to address this.
+
+*** X Proofs in Isabelle scripts can be non-interactive. Non-interactive
+ proofs have only one command, effectively. It might be useful
+ to find a way to integrate these into Proof General nicely.
+
+*** X Code in proof.el assumes all characters with top bit set are special
+ instructions to Emacs. This is rather arrogant, and precludes proof
+ systems which utilize 8-bit character sets! Needs repair. (3h)
+
+*** X Span convenience functions for special 'type property.
+ Could put these in proof.el or somewhere.
+
+*** X Cleanup handling of proof-terminal-string. At the moment some
+ commands need to have the terminal string, some don't.
+ da: I suggest removing proof-terminal-string altogether and
+ adding back the semi-colons or fullstops at the specific level.
+ It's not a big deal and would support other provers which
+ may use a mixture of terminators, or no terminators at all.
+ Wait until it's a problem for somebody.
+ [Trouble with this is that terminators are used for active
+ terminator mode, among several other things]
+
+*** X Functions for next,previous input a la shell mode, but in proof
+ script buffer (5h, da).
+
+*** (defsubst set-span-type-property (span val)
+ "Set type property of SPAN to VAL"
+ (set-span-property span 'type val))
+
+*** (defsubst span-type-property (span)
+ "Get type property of SPAN"
+ (span-property span 'type))
+
+*** etc. (1hr)
+
+*** X Read-only mode of extents sometimes gets in the way: for example,
+ if file changes on disk, can't reload it via usual functions.
+ Can this be improved? Always have to retract first, and that
+ leaves stuff around.
+
+*** X toolbar icons: Automatically generate reduced and
+ pressed/greyed-out versions from gimp xcf files.
+ (1 day's gimp hacking)
+
+*** X Proof General customization: how should it work?
+ Presently we have a bunch of variables in proof.el which are
+ set from a bunch of similarly named variables in <engine>-syntax.el.
+ Seems a bit daft: why not just have the customization in
+ one place, and settings hardwired in <engine>-syntax.el.
+ That way we can see which settings are part of instantiation of
+ proof.el, and which are part of cusomization for <engine>.
+
+*** X Moreover, I think it would be nice to change the architecture
+ to make customization for new provers much easier.
+ The standard use of 'define-derived-mode' could be invoked
+ automatically in proof-site, and we could easily get away from the
+ kludge of proof-config-done and friends.
+ (Compare this to the way font-lock works automatically for XEmacs
+ when the right variable name is set, but for FSF Emacs you have
+ to write something special).
+ The objection to doing this is based on the idea that we should use
+ an object-like inheritance mechanism to define the new modes.
+ But if this is forgone, it might even be possible to add
+ support for new assistants entirely via the customize mechanism,
+ without any knowledge of elisp apart from regular expressions!
+ [see proof-easy-config.el]
+
+*** X Support a history of proof commands, with a "redo" command to
+ redo undo-to-point or sequences of toolbar undo's.
+
+*** X Provers with sophisticated/configurable syntax should tell Emacs
+ about their syntax somehow, rather than trying to duplicate
+ specifications inside Emacs.
+ Maybe some particular ATerm format would help with this?
+
+*** X Comment support is not very generic: we don't support end-of-line
+ terminated comments. Is there any case where this might be
+ worthwhile? (2h to add it).
+
+*** X Make process handling smarter: because Emacs is single-threaded,
+ no process output can be dealt with when we are running some
+ command. This means that it would be safe to extend the
+ red region, by putting more commands on the queue. Also it would
+ be safe to implement a clever undo command which worked on the
+ red region: if there are commands waiting to be processed, we
+ could remove them from the queue. If there are no commands waiting,
+ we have to wait until something becomes blue to undo it by sending
+ a command to the process.
+
+*** X Ideas for efficiency improvements. Rather than repeatedly
+ re-parsing the buffer, we could parse the whole buffer *once*
+ and make adjustments after edits, like font-lock. We could
+ make an extent for every command, and set it to "blue", "red"
+ or "clear" as appropriate. (This would allow proofs to be
+ sent out-of-order to the proof process too, although perhaps
+ that's not so nice).
+ The function proof-segment-up-to could be made to cache its
+ result.
+
+*** X proof-mark-buffer-atomic marks the buffer as only containing
+ comments if the first ACS is a goal-save span. This is however not a
+ problem for LEGO and Isabelle. (30 min)
+
+*** X Add support for XEmacs 21 packaging. Make suitable updates available
+ on web page, and make RPM put things in the right place so no .emacs
+ file may need editing(?). [2 days]
+
+*** X The narrowing issue
+ Code uses (point-min) and (point-max) everywhere.
+ Most primitive functions give error if given arguments outside
+ a restriction. However, most places these are used in PG we really
+ mean the start or end of the buffer (e.g. when parsing).
+ The only way to fix this seems to be with messy
+ (save-restriction (widen) ... sequences.
+
+*** X Solaris bugs: font locking and button enabling.
+
+ [Markus]: I can only produce this problem on Solaris, where we have
+ both a mule and non-mule version of xemacs-21.1.8. On my Linux box
+ at home there is no problem present (using xemacs-21.1.7-mule).
+
+ Note that on the Solaris boxes the problem is already exhibited by
+ visiting a new/empty thy file: buttons are off and are not enabled
+ by typing new stuff.
+
+ Moved down the list now, instead we disable button enablers on
+ Solaris.
+
+*** X Multiple session architecture (difficult)
+
+ With some major re-engineering, PG could be made to work with multiple
+ provers at once, and multiple instances of the same prover.
+
+ Ideas: - introduce "session" notion
+ - have list of current sessions in progress,
+ values of active scripting buffer and other per-session vars
+ for each one
+ - proof shell filter and other functions must automatically
+ switch context to correct session
+ - force everybody to use proof-easy-config macro, and set
+ <prover>-var automatically from <proof>-var there,
+ to get defaults for new sessions.
+
+
+
+
+
+** 3. Things to do for the documentation
+
+*** A Doc new bits: proof-next-error
+
+*** A Doc new bits: font lock keywords, filename %e, %r.
+ Added proof-{script,shell,goals,resp}-font-lock-keywords.
+ Presently used only in proof-easy-config, will put into other
+ mechanism for 3.2
+
+*** A Doc new bits: win32 support
+
+*** A Doc new bits: settings mechanism via defpacustom
+
+*** C Update front page image
+ - Should include ??? logo to represent other provers
+
+*** B Manual improvements before techreport publishing (see notes at end also):
+ - Mention configuring function menus, outline.
+ - Consider splitting up chapter 9?
+ - document mouse functions, proof-cd, process quit timeout,
+ X-Symbol, prog-name-guess, new menu functions for display.
+ - general tips on what to do when things go wrong: try
+ interrupt, restart, finally exit proof assistant.
+ - improvements after feedback from users.
+ - add screenshots?
+ - add more index entries
+
+*** B Add something to better document two-buffer versus three-buffer
+ interaction modes, and the use of proof-window-dedicated to
+ trigger three buffer mode.
+
+*** C Documentation in pdf format: need to fix inclusion of image
+ problem.
+
+*** D Fix INFO-DIR-ENTRY in doc/ProofGeneral.texi to put Proof General
+ info file into a good place.
+
+*** D texi-docstring-magic: first time deffn's, etc, are added, whitespace
+ after magic comment is left.
+
+*** B Doc enhancement: explain conditions for switching buffers and auto
+ switching of scripting buffers. (See doc of
+ proof-auto-action-when-switching-scripting)
+
+
+
+** 4. FSF Emacs issues
+
+*** C Changed implementation of overlays inside Emacs itself. We seem to
+ need 'priority property of overlays for queue and locked to make
+ sure the colours show through. Even then highlighting is strange,
+ and background face spoils the others. Transparent?
+ Same priority: we get mouse highlighting but no face property.
+ Higher priority: we get blanking as mouse highlighting. Yuk.
+ ACTION: check Emacs Lispref for hints. Maybe ask on newsgroup.
+
+*** X `proof-zap-commas-region' does not work for Emacs 20.4 on
+ lego/example.l . On *initially* fontifying the buffer,
+ commas are not zapped. However, when entering text (on
+ a particular line), commata are zapped correctly. (4h)
+
+
+
+** 5. Things to do for Proof-by-Pointing
+
+*** B Unify proof-insert-pbp-command and proof-shell-insert-loopback-cmd.
+ Add some debugging messages in proof-done-advancing to indicate
+ Maybe pbp should be a new class of "'pbpadvancing" since we don't
+ want to allow the flexible queue manipulation here? Think on it.
+
+*** B Change proof by pointing (pbp) stuff into proofstate buffer stuff.
+ Outsource actual pbp/goals functionality
+ (separate pbp annotations from other annotations).
+ Rename pbp-mode to response-mode or goals-mode (which doesn't
+ support any actual proof-by-pointing), Make a file
+ proof-goals.el. [4 hrs]
+
+*** C Usability enhancement: have a ballon-help style popup (in the
+ minibuffer) to indicate what command pbp will choose, without
+ actually running it.
+
+*** C Fixing up errors caused by pbp-generated commands; currently, script
+ management unwisely assumes that pbp commands cannot fail.
+ da: Is this still true? It looks fine to me. I think "failure"
+ should mean generates an error. With LEGO pbp, it uses "Try"
+ tactic which always succeeds, whether or not something gets done.
+
+*** C In case of pbp failure (real failure), we might keep a flag
+ to indicate that the next pbp command should delete the
+ previous pbp command's insertion into the buffer, to replace
+ it with another one.
+
+*** X pbp code doesn't quite accord with the tech report; in particular it
+ decodes annotations eagerly. Lazily would be faster, and it's what
+ the tech report claims --- djs: probably not much faster, actually.
+
+
+
+
+
+
+** 6. Things to do for Web Pages, Distribution
+
+*** B Add some one-stop-shop pages. Ask permission to redistribute
+ packages for PAs. Maybe do Windows and Linux versions.
+
+*** B Remove fileshow urls in html
+
+*** C Web pages: fix features page to look better / remove HTML errors.
+
+*** C Validate pages.
+ Current failures for HTML 4.0 to do with CGI-style arguments with "&",
+ this is a problem with PHP3 really.
+
+*** C Add an animation, showing proof replay.
+
+*** C Wanted for links: something to UITP. Are there any pages?
+
+*** C Broken (old) links:
+ (Applications of a Type Theory based Proof Assistant)
+ http://www.dcs.ed.ac.uk/lfcs/research/logic_and_proof/attbpa.html
+
+*** C Reduce text size and front page image, for 1024x768 screens.
+
+*** D Restructure so that page titles are different to help
+ browsing. (Move links_arr from header.html somewhere new,
+ and set $pg_title appropriately before head.html is included).
+
+*** C Add etc/announce somewhere.
+
+*** X Convert to SSI only plus a meta-generation phase?
+
+*** X Add status bar messages to navigation bar
+
+*** X Get rid of footer() function.
+
+
+
+
+** 7. Future improvements to take advantage of newer Emacsen
+
+*** X XEmacs 21.2 compatibility/improvements
+
+**** Accelerators for PG menus? (how to customize?)
+
+**** Use one-shot-hook for splash display
+
+*** X FSF and XEmacs improvements
+
+**** Indirect Buffers
+ Maybe a cunning way to implement the response buffer and goals
+ buffer, since they're basically variants on displaying fragments of
+ the shell buffer output. Appears in XEmacs 21.2, FSF 20.5
+
+
+
+
+
+
+** 8. Bugs in other software beyond our control
+
+*** X Code for find-alternate-file has annoying habit of nullifying
+ buffer-file-name before kill functions are called, on a buffer
+ named ** lose **. This means PG has to keep a copy of the
+ buffer file name to handle proof-included-files-list nicely.
+ Would be better if (X)Emacs code didn't do this.
+
+*** X useful if call-process would keep last error state
+ (primarily for exec-to-string, in case of errors)
+
+*** X Odd behaviour of font-lock in script buffers when long strings
+contain lines with stuff that looks lisp-ish. e.g. "(asd . ads)"
+
+*** X oddity: startup delay when running XEmacs remotely and local display
+is 8 bit. Suspect an XEmacs issue to do with face allocations. Also
+huge delay in buffers for Isabelle mode which try to highlight binders
+(removed because they appear inside strings anyway)
+
+*** X spurious byte comp warning in XEmacs 21.1.4:
+ While compiling proof-x-symbol-encode-shell-input:
+ ** buffer-substring called with 3 args, but requires 0-3
+ for this code:
+ (prog1 (buffer-substring)
+ (kill-buffer (current-buffer))
+
+*** X Error with pdftexinfo (hacked version of teTeX pre-release, 1.0.6).
+Gives problem with @value{blah} inside @pdfurl. May be absent from
+pdftexinfo.tex, but that version doesn't seem to generate web links?
+
+*** (/usr/share/texmf.local/pdftex/texinfo/pdftexinfo.tex
+Loading texinfo [version 1999-09-25.10]: Basics, pdf,
+(/usr/share/texmf/pdftex/plain/misc/pdfcolor.tex) fonts, page headings,
+tables, conditionals, indexing, sectioning, toc, environments, defuns, macros,
+cross references, (/usr/share/texmf/tex/plain/dvips/epsf.tex) localization,
+and turning on texinfo input format.)) (ProofGeneral.aux) [1[/usr/share/texmf/d
+vips/config/pdftex.map][/usr/share/texmf.local/dvips/config/dalucida.map][/usr/
+share/texmf.local/dvips/adobe/agaramon/pad.map][/usr/share/texmf.local/dvips/co
+nfig/wp1.map][/usr/share/texmf.local/dvips/config/mscore.map][/usr/share/texmf.
+local/dvips/config/barbedor-ttf.map][/usr/share/texmf.local/dvips/config/goodtt
+.map]] [2] (Preface)
+! Undefined control sequence.
+@indexbreaks ->@catcode `@-=@active @let -
+ @realdash
+@value ...ode `@-=12 @catcode `@_=12 @indexbreaks
+ @let _@normalunderscore @v...
+<argument> @value
+ {URLpghome}
+@pdfurl ...r{/Subtype /Link /A << /S /URI /URI (#1
+ ) >>}@endgroup
+@douref ...->@begingroup @unsepspaces @pdfurl {#1}
+ @setbox 0 = @hbox {@ignore...
+l.264 @uref{@value{URLpghome}}
+ . Visit this page for
+? x
+<cmtt10.pfb><cmsy10.pfb><8r.enc><bsfr8a.pfb><bsfc8a.pfb>
+Output written on ProofGeneral.pdf (2 pages, 54702 bytes).
+
+
+
+
+
+
+
+
+
+
+
+** 9. New Stable Version Release checklist
+
+
+*** 0. Make all files have same CVS branch with cvs commit -f
+*** 1. Tests: multiple file test suites for LEGO, Isabelle; other egs
+*** 2. Check case with FSF Emacs
+*** 3. Check case with compiled code, for XEmacs only.
+ (Wait for error reports for FSF Emacs)
+ Even if the code is faulty afterwards, compiling is
+ worthwhile just because it shows up bugs in unbound variables, etc.
+*** 4. Dates and versions updated.
+ Check README, doc/ProofGeneral.texi, html/download.html, others.
+*** 5. ProofGeneral.texi docstring magic is up-to-date: cd doc; make magic
+*** 6. Update Emacs and prover versions in texi, html/
+*** 7. Check web page references from other places.
+*** 8. Validate web pages if they're changed much.
+*** 9. Update and distribute etc/announce.
+*** 10. Message to PG mailing list.
+
+
+
+
+
+
+** 10. Things to do for Proof General Project
+
+
+*** A Make informatics research reports from latest docs.
+
+*** A Try to get small project grant from LFCS to help with
+ development of Proof General. Latest news: success is
+ doubtful. Needs a self-contained project that
+ *would be useful to LFCS*.
+ One idea: an LFCS CDROM featuring Proof General and
+ bundled with other theorem provers? How much does a
+ short-run (200 CDs?) cost?
+
+*** A Write grant proposal on white paper for Proof General Kit.
+
+*** A Find new people to help advance and develop Proof General.
+ Getting more instances would be a good way. Also encouraging
+ feedback. Hear stories of bugs by word-of-mouth, they don't
+ get reported often enough.
+ Consider passing on project elsewhere if no LFCS interest.
+
+*** A Polish ProofGeneral.texi and publish as a tech report
+ For PG 3.2, probably.
+
+*** A Write paper on design and development of Proof General.
+
+*** A Write white paper on future of PG project.
+
+*** A Add more PG projects, publicise them.
+
+*** A Push PG research directions:
+ - configuration management / dependency organization
+ - ideas about proof engineering cf software engineering
+ - research on ways of conducting a formalization, cf
+ ways of writing a program. Common idioms that PG could
+ help with.
diff --git a/twelf/README b/twelf/README
new file mode 100644
index 00000000..2d91f558
--- /dev/null
+++ b/twelf/README
@@ -0,0 +1,27 @@
+Twelf Proof General, for Twelf.
+
+Written by David Aspinall.
+
+Status: not officially supported yet
+Maintainer: volunteer required
+Twelf version: Twelf 1.2 (and later, I hope)
+Twelf homepage: http://www.twelf.org
+
+========================================
+
+
+This is a "technology demonstration" of Proof General for Twelf.
+
+It has basic script management support, with some support for
+decoration taken from the present Twelf Emacs mode.
+
+There is support for X Symbol, but not using a proper token language,
+and it seems fairly broken because Twelf's syntax highlighting
+doesn't work properly with font lock.
+
+I have written this in the hope that somebody from the Twelf community
+will adopt it, maintain and improve it, and thus turn it into a proper
+instantiation of Proof General.
+
+$Id$
+
diff --git a/twelf/example.elf b/twelf/example.elf
new file mode 100644
index 00000000..b4281734
--- /dev/null
+++ b/twelf/example.elf
@@ -0,0 +1,64 @@
+%%%
+%%% Example script for Twelf Proof General.
+%%%
+%%% $Id$
+%%%
+
+%%% Rather than a proof this file is just a signature,
+%%% bunch of declarations. Would be nice to have something
+%%% closer to other systems for pedagogical purposes...
+%%% (i.e. proving commutativity of conjunction in ND fragment
+%%% of this logic)
+
+%%% Intuitionistic propositional calculus
+%%% Positive fragment with implies, and, true.
+%%% Two formulations here: natural deduction and Hilbert-style system.
+%%% Author: Frank Pfenning
+
+% Type of propositions.
+o : type.
+%name o A.
+
+% Syntax: implication, plus a few constants.
+=> : o -> o -> o. %infix right 10 =>.
+& : o -> o -> o. %infix right 11 &.
+true : o.
+
+% Provability.
+|- : o -> type. %prefix 9 |-.
+%name |- P.
+
+% Axioms.
+K : |- A => B => A.
+S : |- (A => B => C) => (A => B) => A => C.
+ONE : |- true.
+PAIR : |- A => B => A & B.
+LEFT : |- A & B => A.
+RIGHT : |- A & B => B.
+
+% Inference Rule.
+MP : |- A => B -> |- A -> |- B.
+
+% Natural Deduction.
+
+! : o -> type. %prefix 9 !.
+%name ! D.
+
+trueI : ! true.
+andI : ! A -> ! B -> ! A & B.
+andEL : ! A & B -> ! A.
+andER : ! A & B -> ! B.
+impliesI : (! A -> ! B) -> ! A => B.
+impliesE : ! A => B -> ! A -> ! B.
+
+% Normal deductions (for faster search)
+!^ : o -> type.
+!v : o -> type.
+
+trueI^ : !^ true.
+andI^ : !^ A -> !^ B -> !^ (A & B).
+andEvL : !v (A & B) -> !v A.
+andEvR : !v (A & B) -> !v B.
+impI^ : (!v A -> !^ B) -> !^ (A => B).
+impEv : !v (A => B) -> !^ A -> !v B.
+close : !v A -> !^ A.
diff --git a/twelf/twelf-font.el b/twelf/twelf-font.el
new file mode 100644
index 00000000..97b68527
--- /dev/null
+++ b/twelf/twelf-font.el
@@ -0,0 +1,444 @@
+;; twelf-font.el Font lock configuration for Twelf
+;;
+;; Author: Frank Pfenning
+;; Taken from Twelf's emacs mode and
+;; adapted for Proof General by David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;;
+
+(require 'font-lock)
+
+;; FIXME da: integrate with PG's face mechanism?
+;; (but maybe keep twelf faces to help users)
+;; Also should add font locking.
+
+;; FIXME da: the twelf faces don't work with PG's
+;; background colouring, why?
+
+
+;; modify the syntax table so _ and ' are word constituents
+;; otherwise the regexp's for identifiers become very complicated
+;; FIXME: fn undef'd(set-word ?\_)
+;; FIXME: fn (set-word ?\')
+
+;; setting faces here...
+;; use devices to improve portability?
+;; make it dependent on light background vs dark background
+;; tie in X resources?
+
+(defun twelf-font-create-face (face from-face color)
+ "Creates a Twelf font from FROM-FACE with COLOR."
+ (make-face face)
+ ;(reset-face face) ; seems to be necessary, but why?
+ (copy-face from-face face)
+ (if color (set-face-foreground face color)))
+
+(defvar twelf-font-dark-background nil
+ "*T if the background of Emacs is to be considered dark.")
+
+;; currently we not using bold or italics---some font families
+;; work poorly with that kind of face.
+(cond (twelf-font-dark-background
+ (twelf-font-create-face 'twelf-font-keyword-face 'default nil)
+ (twelf-font-create-face 'twelf-font-comment-face 'font-lock-comment-face
+ nil)
+ (twelf-font-create-face 'twelf-font-percent-key-face 'default "Plum")
+ (twelf-font-create-face 'twelf-font-decl-face 'default "Orange")
+ (twelf-font-create-face 'twelf-font-parm-face 'default "Orange")
+ (twelf-font-create-face 'twelf-font-fvar-face 'default "SpringGreen")
+ (twelf-font-create-face 'twelf-font-evar-face 'default "Aquamarine"))
+ (t
+ (twelf-font-create-face 'twelf-font-keyword-face 'default nil)
+ (twelf-font-create-face 'twelf-font-comment-face 'font-lock-comment-face
+ nil)
+ (twelf-font-create-face 'twelf-font-percent-key-face 'default "MediumPurple")
+ (twelf-font-create-face 'twelf-font-decl-face 'default "FireBrick")
+ (twelf-font-create-face 'twelf-font-parm-face 'default "Green4")
+ (twelf-font-create-face 'twelf-font-fvar-face 'default "Blue1")
+ (twelf-font-create-face 'twelf-font-evar-face 'default "Blue4")))
+
+;; Note that the order matters!
+
+(defvar twelf-font-patterns
+ '(
+ ;; delimited comments, perhaps should use different font
+ ;;("%{" "}%" comment)
+ (twelf-font-find-delimited-comment . twelf-font-comment-face)
+ ;; single-line comments
+ ;; replace \\W by \\s- for whitespace?
+ ("%\\W.*$" 0 twelf-font-comment-face)
+ ;; %keyword declarations
+ ("\\(%infix\\|%prefix\\|%prefix\\|%postfix\\|%name\\|%solve\\|%query\\|%mode\\|%terminates\\|%theorem\\|%prove\\).*$"
+ 1 twelf-font-percent-key-face nil)
+ ;; keywords, omit punctuations for now.
+ ("\\(\\<<-\\>\\|\\<->\\>\\|\\<type\\>\\|\\<=\\>\\|\\<_\\>\\)"
+ ;; for LLF, no punctuation marks
+;;"\\(\\<<-\\>\\|\\<->\\>\\|\\<o-\\>\\|\\<-o\\>\\|\\<<T>\\>\\|\\<&\\>\\|\\^\\|()\\|\\<type\\>\\|\\<sigma\\>\\)"
+ ;; for LLF, with punctuation marks
+ ;;"\\([][:.(){},]\\|\\<<-\\>\\|\\<->\\>\\|\\<o-\\>\\|\\<-o\\>\\|\\<<T>\\>\\|\\<&\\>\\|\\^\\|()\\|\\<type\\>\\|\\<sigma\\>\\)"
+ ;; for Elf, no punction marks
+ ;;"\\(\\<<-\\>\\|\\<->\\>\\|\\<type\\>\\|\\<sigma\\>\\)"
+ ;; for Elf, including punctuation marks
+ ;;"\\([][:.(){}]\\|\\<<-\\>\\|\\<->\\>\\|\\<type\\>\\|\\<sigma\\>\\)"
+ . twelf-font-keyword-face)
+ ;; declared constants
+ (twelf-font-find-decl . twelf-font-decl-face)
+ ;; parameters
+ (twelf-font-find-parm . twelf-font-parm-face)
+ ;; quantified existentials
+ (twelf-font-find-evar . twelf-font-evar-face)
+ ;; lower-case identifiers (almost = constants)
+ ;;("\\<\\([a-z!&$^+/<=>?@~|#*`;,]\\|\\-\\|\\\\\\)\\w*\\>"
+ ;; nil black)
+ ;; upper-case identifiers (almost = variables)
+ ("\\<[A-Z_]\\w*\\>" . twelf-font-fvar-face)
+ ;; numbers and quoted identifiers omitted for now
+ )
+ "Highlighting patterns for Twelf mode.
+This generally follows the syntax of the FONT-LOCK-KEYWORDS variable,
+but allows an arbitrary function to be called instead of just
+regular expressions."
+ )
+
+(defun twelf-font-fontify-decl ()
+ "Fontifies the current Twelf declaration."
+ (interactive)
+ (let* ((region (twelf-current-decl))
+ (start (nth 0 region))
+ (end (nth 1 region)))
+ (save-excursion
+ (font-lock-unfontify-region start end)
+ (twelf-font-fontify-region start end))))
+
+(defun twelf-font-fontify-buffer ()
+ "Fontitifies the current buffer as Twelf code."
+ (interactive)
+ (save-excursion
+ (font-lock-unfontify-region (point-min) (point-max)) ; t optional in XEmacs
+ (twelf-font-fontify-region (point-min) (point-max))))
+
+(defun twelf-font-unfontify ()
+ "Removes fontification from current buffer."
+ (interactive)
+ (font-lock-unfontify-region (point-min) (point-max))) ; t optional in XEmacs
+
+(defvar font-lock-message-threshold 6000) ; in case we are running FSF Emacs
+
+(defun twelf-font-fontify-region (start end)
+ "Go through TWELF-FONT-PATTERNS, fontifying according to given functions"
+ (save-restriction
+ (narrow-to-region start end)
+ (if (and font-lock-verbose
+ (>= (- end start) font-lock-message-threshold))
+ (message "Fontifying %s... (semantically...)" (buffer-name)))
+ (let ((patterns twelf-font-patterns)
+ (case-fold-search nil) ; in Twelf, never case-fold
+ (modified (buffer-modified-p)) ; for FSF Emacs 19
+ pattern
+ fun-or-regexp
+ instructions
+ face
+ match-index
+ allow-overlap-p
+ region)
+ (while patterns
+ (setq pattern (car patterns))
+ (setq patterns (cdr patterns))
+ (goto-char start)
+ (cond ((stringp pattern)
+ (setq match-index 0)
+ (setq face 'font-lock-keyword-face)
+ (setq allow-overlap-p nil))
+ ((listp pattern)
+ (setq fun-or-regexp (car pattern))
+ (setq instructions (cdr pattern))
+ (cond ((integerp instructions)
+ (setq match-index instructions)
+ (setq face 'font-lock-keyword-face)
+ (setq allow-overlap-p nil))
+ ((symbolp instructions)
+ (setq match-index 0)
+ (setq face instructions)
+ (setq allow-overlap-p nil))
+ ((listp instructions)
+ (setq match-index (nth 0 instructions))
+ (setq face (nth 1 instructions))
+ (setq allow-overlap-p (nth 2 instructions)))
+ (t (error "Illegal font-lock-keyword instructions"))))
+ (t (error "Illegal font-lock-keyword instructions")))
+ (cond ((symbolp fun-or-regexp) ; a function to call
+ (while
+ (setq region (funcall fun-or-regexp end))
+ ;; END is limit of forward search, start at point
+ ;; and move point
+ ;; check whether overlap is permissible!
+ (twelf-font-highlight (car region) (cdr region)
+ face allow-overlap-p)))
+ ((stringp fun-or-regexp) ; a pattern to find
+ (while
+ (re-search-forward fun-or-regexp end t)
+ (goto-char (match-end match-index)) ; back-to-back font hack
+ (twelf-font-highlight (match-beginning match-index)
+ (match-end match-index)
+ face
+ allow-overlap-p)))
+ (t (error "Illegal font-lock-keyword instructions"))))
+ ;; For FSF Emacs 19: mark buffer not modified, if it wasn't before
+ ;; fontification.
+ (and (not modified) (buffer-modified-p) (set-buffer-modified-p nil))
+ (if (and font-lock-verbose
+ (>= (- end start) font-lock-message-threshold))
+ (message "Fontifying %s... done" (buffer-name))))))
+
+(defun twelf-font-highlight (start end face allow-overlap-p)
+ "Highlight region between START and END with FONT.
+If already highlighted and ALLOW-OVERLAP-P is nil, don't highlight."
+ (or (= start end)
+ ;;(if allow-overlap-p nil (font-lock-any-faces-p start (1- end)))
+ ;; different in XEmacs 19.16? font-lock-any-faces-p subtracts 1.
+ (if allow-overlap-p nil (font-lock-any-faces-p start end))
+ (font-lock-set-face start end face)))
+
+(defun twelf-font-find-delimited-comment (limit)
+ "Find a delimited Twelf comment and return (START . END), nil if none."
+ (let ((comment-level nil)
+ (comment-start nil))
+ (if (search-forward "%{" limit t)
+ (progn
+ (setq comment-start (- (point) 2))
+ (setq comment-level 1)
+ (while (and (> comment-level 0)
+ (re-search-forward "\\(%{\\)\\|\\(}%\\)"
+ limit 'limit))
+ (cond
+ ((match-beginning 1) (setq comment-level (1+ comment-level)))
+ ((match-beginning 2) (setq comment-level (1- comment-level)))))
+ (cons comment-start (point)))
+ nil)))
+
+;; doesn't work yet with LIMIT!!!
+;; this should never be done in incremental-highlighting mode
+(defun twelf-font-find-decl (limit)
+ "Find an Twelf constant declaration and return (START . END), nil if none."
+ (let (start
+ end
+ ;; Turn off error messages
+ (id (twelf-next-decl nil nil)))
+ ;; ignore limit for now because of global buffer restriction
+ (if (null id) ; (or (null id) (> (point) limit))
+ nil
+ (skip-chars-backward *whitespace*)
+ (setq end (point))
+ (beginning-of-line 1)
+ (setq start (point))
+ (twelf-end-of-par)
+ (cons start end))))
+
+(defun twelf-font-find-binder (var-pattern limit occ-face)
+ "Find Twelf binder whose bound variable matches var-pattern.
+Returns (START . END) if found, NIL if there is none before LIMIT.
+Binders have the form [x],[x:A],{y},{y:A}.
+As a side-effect, it highlights all occurrences of the bound
+variable using the variable OCC-FACE."
+ (let (start
+ end
+ par-end
+ scope-start
+ scope-end
+ word
+ (found nil))
+ ;;; At the moment, ignore limit since restriction is done globally
+ ;; (save-restriction
+ ;; (narrow-to-region (point) limit)
+ (while (not found)
+ (skip-chars-forward "^[{%")
+ (while (looking-at *twelf-comment-start*)
+ (cond ((looking-at "%{")
+ (condition-case nil (forward-sexp 1)
+ (error (goto-char (point-max))))
+ (or (eobp) (forward-char 1)))
+ (t
+ (end-of-line 1)))
+ (skip-chars-forward "^[{%"))
+ (if (eobp)
+ (setq found 'eob)
+ (forward-char 1)
+ (skip-chars-forward *whitespace*)
+ (if (looking-at var-pattern)
+ ;;"\\<\\w+\\>"
+ ;;"\\<[-a-z!&$^+/\\<=>?@~|#*`;,]\\w*\\>"
+ (setq found t))))
+ (if (eq found 'eob)
+ nil
+ (setq start (match-beginning 0))
+ (setq end (match-end 0))
+ (setq word (buffer-substring start end))
+ ;; find scope of quantifier
+ (twelf-end-of-par)
+ (setq par-end (point))
+ (goto-char end)
+ (condition-case nil (up-list 1) ; end of quantifier
+ (error (goto-char par-end)))
+ (setq scope-start (min (point) par-end))
+ (condition-case nil (up-list 1) ; end of scope
+ (error (goto-char par-end)))
+ (setq scope-end (min (point) par-end))
+ (goto-char scope-start)
+ (while
+ ;; speed here???
+ (search-forward-regexp (concat "\\<" (regexp-quote word) "\\>")
+ scope-end 'limit)
+ ;; Check overlap here!!! --- current bug if in comment
+ (font-lock-set-face (match-beginning 0) (match-end 0)
+ occ-face))
+ (goto-char end)
+ (cons start end)))
+ ;;)
+ )
+
+(defun twelf-font-find-parm (limit)
+ "Find bound Twelf parameters and return (START . END), NIL if none.
+Also highlights all occurrences of the parameter.
+For these purposes, a parameter is a bound, lower-case identifier."
+ (twelf-font-find-binder "\\<[-a-z!&$^+/\\<=>?@~|#*`;,]\\w*\\>"
+ limit 'twelf-font-parm-face))
+
+(defun twelf-font-find-evar (limit)
+ "Find bound Twelf existential variable return (START . END), NIL if none.
+Also highlights all occurrences of the existential variable.
+For these purposes, an existential variable is a bound, upper-case identifier."
+ (twelf-font-find-binder "\\<[A-Z_]\\w*\\>"
+ limit 'twelf-font-evar-face))
+
+; next two are now in twelf.el
+;(define-key twelf-mode-map "\C-c\C-l" 'twelf-font-fontify-decl)
+;(define-key twelf-mode-map "\C-cl" 'twelf-font-fontify-buffer)
+
+
+;;;
+;;;
+;;; This comes from twelf-old.el but is needed for fontification,
+;;;
+;;; Perhaps some of these parsing functions will need reusing
+;;; for sending input to server properly?
+;;;
+
+;;; FIXME: some of names need fixing for safe conventions.
+
+(defun twelf-current-decl ()
+ "Returns list (START END COMPLETE) for current Twelf declaration.
+This should be the declaration or query under or just before
+point within the nearest enclosing blank lines.
+If declaration ends in `.' then COMPLETE is t, otherwise nil."
+ (let (par-start par-end complete)
+ (save-excursion
+ ;; Skip backwards if between declarations
+ (if (or (eobp) (looking-at (concat "[" *whitespace* "]")))
+ (skip-chars-backward (concat *whitespace* ".")))
+ (setq par-end (point))
+ ;; Move forward from beginning of decl until last
+ ;; declaration before par-end is found.
+ (if (not (bobp)) (backward-paragraph 1))
+ (setq par-start (point))
+ (while (and (twelf-end-of-par par-end)
+ (< (point) par-end))
+ (setq par-start (point)))
+ ;; Now par-start is at end of preceding declaration or query.
+ (goto-char par-start)
+ (skip-twelf-comments-and-whitespace)
+ (setq par-start (point))
+ ;; Skip to period or consective blank lines
+ (setq complete (twelf-end-of-par))
+ (setq par-end (point)))
+ (list par-start par-end complete)))
+
+(defun twelf-next-decl (filename error-buffer)
+ "Set point after the identifier of the next declaration.
+Return the declared identifier or `nil' if none was found.
+FILENAME and ERROR-BUFFER are used if something appears wrong."
+ (let ((id nil)
+ end-of-id
+ beg-of-id)
+ (skip-twelf-comments-and-whitespace)
+ (while (and (not id) (not (eobp)))
+ (setq beg-of-id (point))
+ (if (zerop (skip-chars-forward *twelf-id-chars*))
+ ;; Not looking at id: skip ahead
+ (skip-ahead filename (current-line-absolute) "No identifier"
+ error-buffer)
+ (setq end-of-id (point))
+ (skip-twelf-comments-and-whitespace)
+ (if (not (looking-at ":"))
+ ;; Not looking at valid decl: skip ahead
+ (skip-ahead filename (current-line-absolute end-of-id) "No colon"
+ error-buffer)
+ (goto-char end-of-id)
+ (setq id (buffer-substring beg-of-id end-of-id))))
+ (skip-twelf-comments-and-whitespace))
+ id))
+
+(defconst *whitespace* " \t\n\f"
+ "Whitespace characters to be skipped by various operations.")
+
+(defconst *twelf-comment-start* (concat "%[%{" *whitespace* "]")
+ "Regular expression to match the start of a Twelf comment.")
+
+(defconst *twelf-id-chars* "a-z!&$^+/<=>?@~|#*`;,\\-\\\\A-Z_0-9'"
+ "Characters that constitute Twelf identifiers.")
+
+(defun skip-twelf-comments-and-whitespace ()
+ "Skip Twelf comments (single-line or balanced delimited) and white space."
+ (skip-chars-forward *whitespace*)
+ (while (looking-at *twelf-comment-start*)
+ (cond ((looking-at "%{") ; delimited comment
+ (condition-case nil (forward-sexp 1)
+ (error (goto-char (point-max))))
+ (or (eobp) (forward-char 1)))
+ (t ; single-line comment
+ (end-of-line 1)))
+ (skip-chars-forward *whitespace*)))
+
+(defun twelf-end-of-par (&optional limit)
+ "Skip to presumed end of current Twelf declaration.
+Moves to next period or blank line (whichever comes first)
+and returns t if period is found, nil otherwise.
+Skips over comments (single-line or balanced delimited).
+Optional argument LIMIT specifies limit of search for period."
+ (if (not limit)
+ (save-excursion
+ (forward-paragraph 1)
+ (setq limit (point))))
+ (while (and (not (looking-at "\\."))
+ (< (point) limit))
+ (skip-chars-forward "^.%" limit)
+ (cond ((looking-at *twelf-comment-start*)
+ (skip-twelf-comments-and-whitespace))
+ ((looking-at "%")
+ (forward-char 1))))
+ (cond ((looking-at "\\.")
+ (forward-char 1)
+ t)
+ (t ;; stopped at limit
+ nil)))
+
+(defun skip-ahead (filename line message error-buffer)
+ "Skip ahead when syntactic error was found.
+A parsable error message constited from FILENAME, LINE, and MESSAGE is
+deposited in ERROR-BUFFER."
+ (if error-buffer
+ (save-excursion
+ (set-buffer error-buffer)
+ (goto-char (point-max))
+ (insert filename ":" (int-to-string line) " Warning: " message "\n")
+ (setq *twelf-error-pos* (point))))
+ (twelf-end-of-par))
+
+(defun current-line-absolute (&optional char-pos)
+ "Return line number of CHAR-POS (default: point) in current buffer.
+Ignores any possible buffer restrictions."
+ (1+ (count-lines 1 (or char-pos (point)))))
+
+
+(provide 'twelf-font)
diff --git a/twelf/twelf-old.el b/twelf/twelf-old.el
new file mode 100644
index 00000000..61b21745
--- /dev/null
+++ b/twelf/twelf-old.el
@@ -0,0 +1,2661 @@
+;; twelf-old.el Port of old Twelf Emacs mode
+;;
+;; Author: Frank Pfenning
+;; Adapted for Proof General by David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;;
+
+;; FIXME: have copied over directly!
+
+;;; Modes and utilities for Twelf programming. This package supports (1)
+;;; editing Twelf source files with reasonable indentation, (2) managing
+;;; configurations of Twelf source files, including TAGS tables, (3)
+;;; communication with an inferior Twelf server to type-check and execute
+;;; declarations and queries, (4) interaction with an inferior Twelf process
+;;; in SML.
+;;;
+;;; For documentation, type C-h m in Twelf mode, or see the function
+;;; twelf-mode below
+;;;
+;;; Author: Frank Pfenning
+;;; Thu Oct 7 19:48:50 1993 (1.0 created)
+;;; Fri Jan 6 09:06:38 1995 (2.0 major revision)
+;;; Tue Jun 16 15:49:31 1998 (3.0 major revision)
+;;;
+;;;======================================================================
+;;; For the `.emacs' file (copied from init.el)
+;;;======================================================================
+;;;
+;;; ;; Tell Emacs where the Twelf libraries are.
+;;; (setq load-path
+;;; (cons "/afs/cs/project/twelf/research/twelf/emacs" load-path))
+;;;
+;;; ;; Autoload libraries when Twelf-related major modes are started.
+;;; (autoload 'twelf-mode "twelf" "Major mode for editing Twelf source." t)
+;;; (autoload 'twelf-server "twelf" "Run an inferior Twelf server." t)
+;;; (autoload 'twelf-sml "twelf" "Run an inferior Twelf-SML process." t)
+;;;
+;;; ;; Switch buffers to Twelf mode based on filename extension,
+;;; ;; which is one of .elf, .quy, .thm, or .cfg.
+;;; (setq auto-mode-alist
+;;; (cons '("\\.elf$" . twelf-mode)
+;;; (cons '("\\.quy$" . twelf-mode)
+;;; (cons '("\\.thm$" . twelf-mode)
+;;; (cons '("\\.cfg$" . twelf-mode)
+;;; auto-mode-alist)))))
+;;;
+;;; ;; Default Twelf server program location
+;;; (setq twelf-server-program
+;;; "/afs/cs/project/twelf/research/twelf/bin/twelf-server")
+;;;
+;;; ;; Default Twelf SML program location
+;;; (setq twelf-sml-program
+;;; "/afs/cs/project/twelf/misc/smlnj/bin/sml-cm")
+;;;
+;;; ;; Default documentation location (in info format)
+;;; (setq twelf-info-file
+;;; "/afs/cs/project/twelf/research/twelf/doc/info/twelf.info")
+;;;
+;;; ;; Automatically highlight Twelf sources using font-lock
+;;; (add-hook 'twelf-mode-hook 'twelf-font-fontify-buffer)
+;;;
+;;;======================================================================
+;;; Command Summary
+;;;======================================================================
+;;;
+;;; Quick summary of Twelf mode, generated from C-h b:
+;;;
+;;; --- Editing Commands ---
+;;; TAB twelf-indent-line
+;;; DEL backward-delete-char-untabify
+;;; M-C-q twelf-indent-decl
+;;;
+;;; --- Type Checking ---
+;;; C-c C-c twelf-save-check-config
+;;; C-c C-s twelf-save-check-file
+;;; C-c C-d twelf-check-declaration
+;;; C-c c twelf-type-const
+;;; C-c C-u twelf-server-display
+;;;
+;;; --- Error Tracking ---
+;;; C-c ` twelf-next-error
+;;; C-c = twelf-goto-error
+;;;
+;;; --- Syntax Highlighting ---
+;;; C-c C-l twelf-font-fontify-decl
+;;; C-c l twelf-font-fontify-buffer
+;;;
+;;; --- Server State ---
+;;; C-c < twelf-set
+;;; C-c > twelf-get
+;;; C-c C-i twelf-server-interrupt
+;;; M-x twelf-server
+;;; M-x twelf-server-configure
+;;; M-x twelf-server-quit
+;;; M-x twelf-server-restart
+;;; M-x twelf-server-send-command
+;;;
+;;; --- Timers ---
+;;; M-x twelf-timers-reset
+;;; M-x twelf-timers-show
+;;; M-x twelf-timers-check
+;;;
+;;; --- Tags (standard Emacs etags package) ---
+;;; M-x twelf-tag
+;;; M-. find-tag (standard binding)
+;;; C-x 4 . find-tag-other-window (standard binding)
+;;; C-c q tags-query-replace (Twelf mode binding)
+;;; C-c s tags-search (Twelf mode binding)
+;;; M-, tags-loop-continue (standard binding)
+;;; visit-tags-table, list-tags, tags-apropos
+;;;
+;;; --- Communication with inferior Twelf-SML process (not Twelf Server) ---
+;;; M-x twelf-sml
+;;; C-c C-e twelf-sml-send-query
+;;; C-c C-r twelf-sml-send-region
+;;; C-c RET twelf-sml-send-newline
+;;; C-c ; twelf-sml-send-semicolon
+;;; C-c d twelf-sml-cd
+;;; M-x twelf-sml-quit
+;;;
+;;; --- Variables ---
+;;; twelf-indent amount of indentation for nested Twelf expressions
+;;;
+;;;======================================================================
+;;; Some Terminology
+;;;======================================================================
+;;;
+;;; Twelf Server --- an inferior process that services requests to type-check,
+;;; load, or execute declarations and queries. It is usually attached to the
+;;; buffer *twelf-server*. Requests are generated by Emacs from user commands,
+;;; or may be typed directly into the Twelf server buffer.
+;;;
+;;; Current configuration --- A configuration is an ordered list of
+;;; Twelf source files in dependency order. It is usually initialized
+;;; and maintained in a file sources.cfg. The current configuration is
+;;; also the bases for the TAGS file created by twelf-tags. This allows
+;;; quick jumping to declaration sites for constants, or to apply
+;;; searches or replacements to all files in a configuration.
+;;;
+;;; Current Twelf declaration --- When checking individual declarations
+;;; Emacs must extract it from the current buffer and then send it to
+;;; the server. This is necessarily based on a heuristic, since Emacs
+;;; does not know enough in order to parse Twelf source properly in all
+;;; cases, but it knows the syntax for comments, Twelf identifiers, and
+;;; matching delimiters. Search for the end or beginning of a
+;;; declaration is always limited by double blank lines in order to be
+;;; more robust (in case a period is missing at the end of a
+;;; declaration). If the point falls between declarations, the
+;;; declaration after the point is considered current.
+;;;
+;;; Twelf-SML --- During development or debugging of the Twelf
+;;; implementation itself it is often useful to interact with SML, the
+;;; language in which Twelf is implementated, rather than using an Twelf
+;;; server. This is an inferior SML process which may run a Twelf
+;;; query interpreter.
+;;;
+;;;======================================================================
+;;; Change Log
+;;;======================================================================
+;;;
+;;; Thu Jun 3 14:51:35 1993 -fp
+;;; Added variable display-elf-queries. If T (default) redisplays Elf
+;;; buffer after a query has been sent. Delays one second after sending
+;;; the query which is rather arbitrary.
+;;; Wed Jun 30 19:57:58 1993
+;;; - Error messages in the format line0.col0-line1.col1 can now be parsed.
+;;; - Error from std_in, either interactive or through elf-send-query
+;;; can now be tracked.
+;;; - Added simple directory tracking and function elf-cd, bound to C-c d.
+;;; - improved filename completion in Elf mode under Lucid Emacs.
+;;; - replaced tail recursion in elf-indent-line by a while loop.
+;;; - changed elf-input-filter to ignore one character inputs.
+;;; - elf-error-marker is now updated on every interactive input or send.
+;;; - added commands elf-send-newline, bound to C-c RET
+;;; and elf-send-semicolon, bound to C-c ;.
+;;; These are useful when sending queries from a buffer with examples.
+;;; Fri Sep 3 15:02:10 1993
+;;; Changed definition of elf-current-paragraph so that it recognizes
+;;; individual declarations within a traditional ``paragraph'' (separated
+;;; by blank lines).
+;;; Fri Oct 22 10:05:08 1993
+;;; Changed elf-send-query to ensure that the Elf process expects a query
+;;; If the Elf process is at the SML prompt, it starts a top level.
+;;; If the Elf process is waiting after printing an answer substitution,
+;;; it sends a RET.
+;;; This is based on a heuristic analysis of the contents of the Elf buffer.
+;;; Fri Dec 16 15:27:14 1994
+;;; Changed elf-error-marker to elf-error-pos, since it moved in undesirable
+;;; ways in Emacs 19.
+;;; Fri Jan 6 09:06:54 1995
+;;; Major revision: incorporating elf-server.el and elf-tag.el
+;;; Thu Jan 12 14:31:36 1995
+;;; Finished major revision (version 2.0)
+;;; Sat Jun 13 12:14:34 1998
+;;; Renamed to Twelf and incorporated menus from elf-menu.el
+;;; Major revision for Twelf 1.2 release
+;;; Q: Improve tagging for %keyword declarations?
+;;; Thu Jun 25 08:52:41 1998
+;;; Finished major revision (version 3.0)
+;;; Fri Oct 2 11:06:15 1998
+;;; Added NT Emacs bug workaround
+
+(require 'comint)
+(require 'auc-menu)
+
+;;;----------------------------------------------------------------------
+;;; User visible variables
+;;;----------------------------------------------------------------------
+
+(defvar twelf-indent 3
+ "*Indent for Twelf expressions.")
+
+(defvar twelf-infix-regexp ":\\|\\<->\\>\\|\\<<-\\>\\|\\<=\\>"
+ "*Regular expression to match Twelf infix operators.
+Match must exclude surrounding whitespace. This is used for indentation.")
+
+(defvar twelf-server-program "twelf-server"
+ "*Default Twelf server program.")
+
+(defvar twelf-info-file "twelf.info"
+ "*Default info file for Twelf.")
+
+(defvar twelf-server-display-commands nil
+ "*If non-nil, the Twelf server buffer will be displayed after each command.
+Normally, the Twelf server buffer is displayed only after some selected
+commands or if a command is given a prefix argument.")
+
+(defvar twelf-highlight-range-function 'twelf-highlight-range-zmacs
+ "*Function which highlights the range analyzed by the server.
+This is called for certain commands which apply to a subterm at point.
+You may want to change this for FSF Emacs, XEmacs and/or highlight packages.")
+
+(defvar twelf-focus-function 'twelf-focus-noop
+ "*Function which focusses on the current declaration or query.
+This is called for certain commands which pick out (a part of) a declaration
+or query. You may want to change this for FSF Emacs, XEmacs and/or highlight
+packages.")
+
+(defvar twelf-server-echo-commands t
+ "*If nil, Twelf server commands will not be echoed in the Twelf server buffer.")
+
+(defvar twelf-save-silently nil
+ "*If non-nil, modified buffers are saved without confirmation
+before `twelf-check-config' if they belong to the current configuration.")
+
+(defvar twelf-server-timeout 5
+ "*Number of seconds before the server is considered delinquent.
+This is unsupported in some versions of Emacs.")
+
+(defvar twelf-sml-program "twelf-sml"
+ "*Default Twelf-SML program.")
+
+(defvar twelf-sml-args '()
+ "*Arguments to Twelf-SML program.")
+
+(defvar twelf-sml-display-queries t
+ "*If nil, the Twelf-SML buffer will not be selected after a query.")
+
+(defvar twelf-mode-hook '()
+ "List of hook functions to run when switching to Twelf mode.")
+
+(defvar twelf-server-mode-hook '()
+ "List of hook functions to run when switching to Twelf Server mode.")
+
+(defvar twelf-config-mode-hook '()
+ "List of hook functions to run when switching to Twelf Config minor mode.")
+
+(defvar twelf-sml-mode-hook '()
+ "List of hook functions for Twelf-SML mode.")
+
+(defvar twelf-to-twelf-sml-mode '()
+ "List of hook functions for 2Twelf-SML minor mode.")
+
+(defvar twelf-config-mode nil
+ "Non-NIL means the Twelf Config minor mode is in effect.")
+
+;;;----------------------------------------------------------------------
+;;; Internal variables
+;;;----------------------------------------------------------------------
+
+(defvar *twelf-server-buffer-name* "*twelf-server*"
+ "The default name for the Twelf server buffer.")
+
+(defvar *twelf-server-buffer* nil
+ "The buffer with the Twelf server if one exists.")
+
+(defvar *twelf-server-process-name* "twelf-server"
+ "Name of the Twelf server process.")
+
+(defvar *twelf-config-buffer* nil
+ "The current Twelf configuration buffer if one exists.")
+
+(defvar *twelf-config-time* nil
+ "The modification time of Twelf configuration file when read by the server.")
+
+(defvar *twelf-config-list* nil
+ "The reversely ordered list with files in the current Twelf configuration.")
+
+(defvar *twelf-server-last-process-mark* 0
+ "The process mark before the last command in the Twelf server buffer.")
+
+(defvar *twelf-last-region-sent* nil
+ "Contains a list (BUFFER START END) identifying the last region sent
+to the Twelf server or Twelf-SML process for error tracking.
+If nil, then the last input was interactive.
+If t, then the last input was interactive, but has already been copied
+to the end of the Twelf-SML buffer.")
+
+(defvar *twelf-last-input-buffer* nil
+ "Last buffer to which input was sent.
+This is used by the error message parser.")
+
+(defvar *twelf-error-pos* 0
+ "Last error position in the server buffer.")
+
+(defconst *twelf-read-functions*
+ '((nat . twelf-read-nat)
+ (bool . twelf-read-bool)
+ (limit . twelf-read-limit)
+ (strategy . twelf-read-strategy))
+ "Association between Twelf parameter types and their Emacs read functions.")
+
+(defconst *twelf-parm-table*
+ '(("chatter" . nat)
+ ("doubleCheck" . bool)
+ ("Print.implicit" . bool)
+ ("Print.depth" . limit)
+ ("Print.length" . limit)
+ ("Print.indent" . nat)
+ ("Print.width" . nat)
+ ("Prover.strategy" . strategy)
+ ("Prover.maxSplit" . nat)
+ ("Prover.maxRecurse" . nat))
+ "Association between Twelf parameters and their types.")
+
+(defvar twelf-chatter 3
+ "Chatter level in current Twelf server.
+Maintained to present reasonable menus.")
+
+;(defvar twelf-trace 0
+; "Trace level in current Twelf server.
+;Maintained to present reasonable menus.")
+
+(defvar twelf-double-check "false"
+ "Current value of doubleCheck Twelf parameter.")
+
+(defvar twelf-print-implicit "false"
+ "Current value of Print.implicit Twelf parameter.")
+
+(defconst *twelf-track-parms*
+ '(("chatter" . twelf-chatter)
+ ;("trace" . twelf-trace)
+ ("doubleCheck" . twelf-double-check)
+ ("Print.implicit" . twelf-print-implicit))
+ "Association between Twelf parameters and Emacs tracking variables.")
+
+;;;----------------------------------------------------------------------
+;;; Basic key bindings
+;;;----------------------------------------------------------------------
+
+(defun install-basic-twelf-keybindings (map)
+ "General key bindings for Twelf and Twelf Server modes."
+ ;; Additional tag keybindings
+ (define-key map "\C-cq" 'tags-query-replace)
+ (define-key map "\C-cs" 'tags-search)
+ ;; Server state
+ (define-key map "\C-c<" 'twelf-set)
+ (define-key map "\C-c>" 'twelf-get)
+ ;; Error handling
+ (define-key map "\C-c`" 'twelf-next-error)
+ (define-key map "\C-c=" 'twelf-goto-error)
+ ;; Proper indentation
+ (define-key map "\e\C-q" 'twelf-indent-decl)
+ (define-key map "\t" 'twelf-indent-line)
+ (define-key map "\177" 'backward-delete-char-untabify)
+ ;; Info documentation
+ (define-key map "\C-c\C-h" 'twelf-info)
+ )
+
+;;;----------------------------------------------------------------------
+;;; Twelf mode
+;;; This mode should be used for files with Twelf declarations,
+;;; usually *.elf, *.quy, or *.thm, and Twelf configuration files *.cfg
+;;;----------------------------------------------------------------------
+
+(defun install-twelf-keybindings (map)
+ "Install the key bindings for the Twelf mode."
+ (define-key map "\C-cl" 'twelf-font-fontify-buffer) ;autoload twelf-font
+ (define-key map "\C-c\C-l" 'twelf-font-fontify-decl) ;autoload twelf-font
+ (define-key map "\C-c\C-i" 'twelf-server-interrupt)
+ (define-key map "\C-c\C-u" 'twelf-server-display)
+ (define-key map "\C-cc" 'twelf-type-const)
+ ;(define-key map "\C-ce" 'twelf-expected-type-at-point)
+ ;(define-key map "\C-cp" 'twelf-type-at-point)
+ ;(define-key map "\C-c." 'twelf-complete)
+ ;(define-key map "\C-c?" 'twelf-completions-at-point)
+ (define-key map "\C-c\C-d" 'twelf-check-declaration)
+ (define-key map "\C-c\C-s" 'twelf-save-check-file)
+ (define-key map "\C-c\C-c" 'twelf-save-check-config)
+ )
+
+(defvar twelf-mode-map nil
+ "The keymap used in Twelf mode.")
+
+(cond ((not twelf-mode-map)
+ (setq twelf-mode-map (make-sparse-keymap))
+ (install-basic-twelf-keybindings twelf-mode-map)
+ (install-twelf-keybindings twelf-mode-map)))
+
+;;;----------------------------------------------------------------------
+;;; General editing and indentation
+;;;----------------------------------------------------------------------
+
+(defvar twelf-mode-syntax-table nil
+ "The syntax table used in Twelf mode.")
+
+(defun set-twelf-syntax (char entry)
+ (modify-syntax-entry char entry twelf-mode-syntax-table))
+(defun set-word (char) (set-twelf-syntax char "w "))
+(defun set-symbol (char) (set-twelf-syntax char "_ "))
+
+(defun map-string (func string)
+ (if (string= "" string)
+ ()
+ (funcall func (string-to-char string))
+ (map-string func (substring string 1))))
+
+(if twelf-mode-syntax-table
+ ()
+ (setq twelf-mode-syntax-table (make-syntax-table))
+ ;; A-Z and a-z are already word constituents
+ ;; For fontification, it would be better if _ and ' were word constituents
+ (map-string 'set-word "!&$^+/<=>?@~|#*`;,-0123456789\\") ; word constituents
+ (map-string 'set-symbol "_'") ; symbol constituents
+ ;; Delimited comments are %{ }%, see 1234 below.
+ (set-twelf-syntax ?\ " ") ; whitespace
+ (set-twelf-syntax ?\t " ") ; whitespace
+ (set-twelf-syntax ?% "< 14") ; comment begin
+ (set-twelf-syntax ?\n "> ") ; comment end
+ (set-twelf-syntax ?: ". ") ; punctuation
+ (set-twelf-syntax ?. ". ") ; punctuation
+ (set-twelf-syntax ?\( "() ") ; open delimiter
+ (set-twelf-syntax ?\) ")( ") ; close delimiter
+ (set-twelf-syntax ?\[ "(] ") ; open delimiter
+ (set-twelf-syntax ?\] ")[ ") ; close delimiter
+ (set-twelf-syntax ?\{ "(}2 ") ; open delimiter
+ (set-twelf-syntax ?\} "){ 3") ; close delimiter
+ ;; Actually, strings are illegal but we include:
+ (set-twelf-syntax ?\" "\" ") ; string quote
+ ;; \ is not an escape, but a word constituent (see above)
+ ;;(set-twelf-syntax ?\\ "/ ") ; escape
+ )
+
+(defconst *whitespace* " \t\n\f"
+ "Whitespace characters to be skipped by various operations.")
+
+(defconst *twelf-comment-start* (concat "%[%{" *whitespace* "]")
+ "Regular expression to match the start of a Twelf comment.")
+
+(defconst *twelf-id-chars* "a-z!&$^+/<=>?@~|#*`;,\\-\\\\A-Z_0-9'"
+ "Characters that constitute Twelf identifiers.")
+
+(defun skip-twelf-comments-and-whitespace ()
+ "Skip Twelf comments (single-line or balanced delimited) and white space."
+ (skip-chars-forward *whitespace*)
+ (while (looking-at *twelf-comment-start*)
+ (cond ((looking-at "%{") ; delimited comment
+ (condition-case nil (forward-sexp 1)
+ (error (goto-char (point-max))))
+ (or (eobp) (forward-char 1)))
+ (t ; single-line comment
+ (end-of-line 1)))
+ (skip-chars-forward *whitespace*)))
+
+(defun twelf-end-of-par (&optional limit)
+ "Skip to presumed end of current Twelf declaration.
+Moves to next period or blank line (whichever comes first)
+and returns t if period is found, nil otherwise.
+Skips over comments (single-line or balanced delimited).
+Optional argument LIMIT specifies limit of search for period."
+ (if (not limit)
+ (save-excursion
+ (forward-paragraph 1)
+ (setq limit (point))))
+ (while (and (not (looking-at "\\."))
+ (< (point) limit))
+ (skip-chars-forward "^.%" limit)
+ (cond ((looking-at *twelf-comment-start*)
+ (skip-twelf-comments-and-whitespace))
+ ((looking-at "%")
+ (forward-char 1))))
+ (cond ((looking-at "\\.")
+ (forward-char 1)
+ t)
+ (t ;; stopped at limit
+ nil)))
+
+(defun twelf-current-decl ()
+ "Returns list (START END COMPLETE) for current Twelf declaration.
+This should be the declaration or query under or just before
+point within the nearest enclosing blank lines.
+If declaration ends in `.' then COMPLETE is t, otherwise nil."
+ (let (par-start par-end complete)
+ (save-excursion
+ ;; Skip backwards if between declarations
+ (if (or (eobp) (looking-at (concat "[" *whitespace* "]")))
+ (skip-chars-backward (concat *whitespace* ".")))
+ (setq par-end (point))
+ ;; Move forward from beginning of decl until last
+ ;; declaration before par-end is found.
+ (if (not (bobp)) (backward-paragraph 1))
+ (setq par-start (point))
+ (while (and (twelf-end-of-par par-end)
+ (< (point) par-end))
+ (setq par-start (point)))
+ ;; Now par-start is at end of preceding declaration or query.
+ (goto-char par-start)
+ (skip-twelf-comments-and-whitespace)
+ (setq par-start (point))
+ ;; Skip to period or consective blank lines
+ (setq complete (twelf-end-of-par))
+ (setq par-end (point)))
+ (list par-start par-end complete)))
+
+(defun twelf-mark-decl ()
+ "Marks current Twelf declaration and moves point to its beginning."
+ (interactive)
+ (let* ((par (twelf-current-decl))
+ (par-start (nth 0 par))
+ (par-end (nth 1 par)))
+ (push-mark par-end)
+ (goto-char par-start)))
+
+(defun twelf-indent-decl ()
+ "Indent each line of the current Twelf declaration."
+ (interactive)
+ (let* ((par (twelf-current-decl))
+ (par-start (nth 0 par))
+ (par-end (nth 1 par)))
+ (goto-char par-start)
+ (twelf-indent-lines (count-lines par-start par-end))))
+
+(defun twelf-indent-region (from to)
+ "Indent each line of the region as Twelf code."
+ (interactive "r")
+ (cond ((< from to)
+ (goto-char from)
+ (twelf-indent-lines (count-lines from to)))
+ ((> from to)
+ (goto-char to)
+ (twelf-indent-lines (count-lines to from)))
+ (t nil)))
+
+(defun twelf-indent-lines (n)
+ "Indent N lines starting at point."
+ (interactive "p")
+ (while (> n 0)
+ (twelf-indent-line)
+ (forward-line 1)
+ (setq n (1- n))))
+
+(defun twelf-comment-indent ()
+ "Calculates the proper Twelf comment column.
+Currently does not deal specially with pragmas."
+ (cond ((looking-at "%%%")
+ 0)
+ ((looking-at "%[%{]")
+ (car (twelf-calculate-indent)))
+ (t
+ (skip-chars-backward " \t")
+ (max (if (bolp) 0 (1+ (current-column))) comment-column))))
+
+(defun looked-at ()
+ "Returns the last string matched against.
+Beware of intervening, even unsuccessful matches."
+ (buffer-substring (match-beginning 0) (match-end 0)))
+
+(defun twelf-indent-line ()
+ "Indent current line as Twelf code.
+This recognizes comments, matching delimiters, and standard infix operators."
+ (interactive)
+ (let ((old-point (point)))
+ (beginning-of-line)
+ (let* ((indent-info (twelf-calculate-indent))
+ (indent-column (nth 0 indent-info))
+ (indent-type (nth 1 indent-info))
+ (indent-string (nth 2 indent-info)))
+ (skip-chars-forward " \t") ; skip whitespace
+ (let ((fwdskip (- old-point (point))))
+ (cond ((looking-at "%%%")
+ (twelf-indent-line-to 0 fwdskip)) ; %%% comment at column 0
+ ((looking-at "%[%{]") ; delimited or %% comment
+ (twelf-indent-line-to indent-column fwdskip))
+ ((looking-at *twelf-comment-start*) ; indent single-line comment
+ (indent-for-comment)
+ (forward-char -1))
+ ((looking-at "%") ; %keyword declaration
+ (twelf-indent-line-to indent-column fwdskip))
+ ((looking-at twelf-infix-regexp) ; looking at infix operator
+ (if (string= indent-string (looked-at))
+ ;; indent string is the same as the one we are looking at
+ (twelf-indent-line-to indent-column fwdskip)
+ (twelf-indent-line-to (+ indent-column twelf-indent) fwdskip)))
+ ((eq indent-type 'delimiter) ; indent after delimiter
+ (twelf-indent-line-to (+ indent-column twelf-indent) fwdskip))
+ ((eq indent-type 'limit) ; no delimiter or infix found.
+ (twelf-indent-line-to indent-column fwdskip))
+ ((eq indent-type 'infix)
+ (twelf-indent-line-to (+ indent-column twelf-indent) fwdskip)))))))
+
+(defun twelf-indent-line-to (indent fwdskip)
+ "Indent current line to INDENT then skipping to FWDSKIP if positive.
+Assumes point is on the first non-whitespace character of the line."
+ (let ((text-start (point))
+ (shift-amount (- indent (current-column))))
+ (if (= shift-amount 0)
+ nil
+ (beginning-of-line)
+ (delete-region (point) text-start)
+ (indent-to indent))
+ (if (> fwdskip 0)
+ (forward-char fwdskip))))
+
+(defun twelf-calculate-indent ()
+ "Calculate the indentation and return a list (INDENT INDENT-TYPE STRING).
+INDENT is a natural number,
+INDENT-TYPE is 'DELIMITER, 'INFIX, or 'LIMIT, and
+STRING is the delimiter, infix operator, or the empty string, respectively."
+ (save-excursion
+ (let* ((par (twelf-current-decl))
+ (par-start (nth 0 par))
+ (par-end (nth 1 par))
+ (par-complete (nth 2 par))
+ (limit (cond ((> par-start (point)) (point))
+ ((and (> (point) par-end) par-complete) par-end)
+ (t par-start))))
+ (twelf-dsb limit))))
+
+(defun twelf-dsb (limit)
+ "Scan backwards from point to find opening delimiter or infix operator.
+This currently does not deal with comments or mis-matched delimiters.
+Argument LIMIT specifies bound for backwards search."
+ (let ((result nil)
+ (lparens 0) (lbraces 0) (lbrackets 0))
+ (while (not result)
+ (if (or (= lparens 1) (= lbraces 1) (= lbrackets 1))
+ (setq result (list (current-column) 'delimiter (looked-at)))
+ (if (re-search-backward (concat "[][{}()]\\|" twelf-infix-regexp)
+ limit 'limit) ; return 'LIMIT if limit reached
+ (let ((found (looked-at)))
+ (cond
+ ((string= found "(") (setq lparens (1+ lparens)))
+ ((string= found ")") (setq lparens (1- lparens)))
+ ((string= found "{") (setq lbraces (1+ lbraces)))
+ ((string= found "}") (setq lbraces (1- lbraces)))
+ ((string= found "[") (setq lbrackets (1+ lbrackets)))
+ ((string= found "]") (setq lbrackets (1- lbrackets)))
+ (t;; otherwise, we are looking at an infix operator
+ (if (and (= lparens 0) (= lbraces 0) (= lbrackets 0))
+ (setq result (list (current-column) 'infix found))
+ nil)))) ; embedded - skip
+ (setq result (list 0 'limit ""))))) ; reached the limit, no indent
+ result))
+
+(defun twelf-mode-variables ()
+ "Set up local variables for Twelf mode."
+ (set-syntax-table twelf-mode-syntax-table)
+ ;; Paragraphs are separated by blank lines or ^L.
+ (make-local-variable 'paragraph-start)
+ (setq paragraph-start "^[ \t\f]*$")
+ (make-local-variable 'paragraph-separate)
+ (setq paragraph-separate paragraph-start)
+ (make-local-variable 'indent-line-function)
+ (setq indent-line-function 'twelf-indent-line)
+ (make-local-variable 'comment-start)
+ (setq comment-start "%")
+ (make-local-variable 'comment-start-skip)
+ (setq comment-start-skip "%+{?[ \t]*")
+ (make-local-variable 'comment-end)
+ (setq comment-end "")
+ (make-local-variable 'comment-column)
+ (setq comment-column 40)
+ ;; (make-local-variable 'parse-sexp-ignore-comments)
+ ;; (setq parse-sexp-ignore-comments t)
+ )
+
+(defun twelf-mode ()
+ "Major mode for editing Twelf code.
+Tab indents for Twelf code.
+Delete converts tabs to spaces as it moves back.
+M-C-q indents all lines in current Twelf declaration.
+
+Twelf mode also provides commands to maintain groups of Twelf source
+files (configurations) and communicate with an Twelf server which
+processes declarations. It also supports quick jumps to the (presumed)
+source of error message that may arise during parsing or type-checking.
+
+Customisation: Entry to this mode runs the hooks on twelf-mode-hook.
+See also the hints for the .emacs file given below.
+
+Mode map
+========
+\\{twelf-mode-map}
+\\<twelf-mode-map>
+Overview
+========
+
+The basic architecture is that Emacs sends commands to an Twelf server
+which runs as an inferior process, usually in the buffer *twelf-server*.
+Emacs in turn interprets or displays the replies from the Twelf server.
+Since a typical Twelf application comprises several files, Emacs
+maintains a configuration in a file, usally called sources.cfg. This
+file contains a list of files, each on a separate line, in dependency
+order. The `%' character starts a comment line. A configuration is
+established with the command \\[twelf-server-configure].
+
+A new file is switched to Twelf mode if a file has extension `.elf',
+`.quy', `.thm' or `.cfg' and the `auto-mode-alist' is set correctly (see
+init.el).
+
+The files in the current configuration can be checked in sequence with
+\\[twelf-save-check-config], the current file with
+\\[twelf-save-check-file], individual declarations with
+\\[twelf-check-declaration]. These, like many other commands, take an
+optional prefix arguments which means to display the Twelf server buffer
+after the processing of the configuration, file, or declaration. If an
+error should arise during these or related operations a message is
+issued both in the server buffer and Emacs, and the command
+\\[twelf-next-error] visits the presumed source of the type error in a
+separate buffer.
+
+Summary of most common commands:
+ M-x twelf-save-check-config \\[twelf-save-check-config] save, check & load configuration
+ M-x twelf-save-check-file \\[twelf-save-check-file] save, check & load current file
+ M-x twelf-check-declaration \\[twelf-check-declaration] type-check declaration at point
+ M-x twelf-server-display \\[twelf-server-display] display Twelf server buffer
+
+It is important to remember that the commands to save and check
+a file or check a declaration may change the state of the global
+signature maintained in Twelf. After a number of changes it is usually
+a good idea to return to a clean slate with \\[twelf-save-check-config].
+
+Individual Commands
+===================
+
+Configurations, Files and Declarations
+
+ twelf-save-check-config \\[twelf-save-check-config]
+ Save its modified buffers and then check the current Twelf configuration.
+ With prefix argument also displays Twelf server buffer.
+ If necessary, this will start up an Twelf server process.
+
+ twelf-save-check-file \\[twelf-save-check-file]
+ Save buffer and then check it by giving a command to the Twelf server.
+ With prefix argument also displays Twelf server buffer.
+
+ twelf-check-declaration \\[twelf-check-declaration]
+ Send the current declaration to the Twelf server process for checking.
+ With prefix argument, subsequently display Twelf server buffer.
+
+Subterm at Point
+
+ twelf-type-const \\[twelf-type-const]
+ Display the type of the constant before point.
+ Note that the type of the constant will be `absolute' rather than the
+ type of the particular instance of the constant.
+
+Error Tracking
+
+ twelf-next-error \\[twelf-next-error]
+ Find the next error by parsing the Twelf server or Twelf-SML buffer.
+
+ twelf-goto-error \\[twelf-goto-error]
+ Go to the error reported on the current line or below.
+
+Server State
+
+ twelf-set PARM VALUE \\[twelf-set]
+ Sets the Twelf server parameter PARM to VALUE.
+ Prompts for PARM when called interactively, using completion for legal
+ parameters.
+
+ twelf-get PARM \\[twelf-get]
+ Print the current value the Twelf server parameter PARM.
+
+ twelf-server-interrupt \\[twelf-server-interrupt]
+ Interrupt the Twelf server-process.
+
+ twelf-server \\[twelf-server]
+ Start a Twelf server process in a buffer named *twelf-server*.
+
+ twelf-server-configure \\[twelf-server-configure]
+ Set the current configuration of the Twelf server.
+
+ twelf-reset \\[twelf-reset]
+ Reset the global signature in the Twelf server process.
+
+ twelf-server-quit \\[twelf-server-quit]
+ Kill the Twelf server process.
+
+ twelf-server-restart \\[twelf-server-restart]
+ Restarts server and re-initializes configuration.
+ This is primarily useful during debugging of the Twelf server code or
+ if the Twelf server is hopelessly wedged.
+
+ twelf-server-send-command \\[twelf-server-send-command]
+ Send arbitrary string to Twelf server.
+
+Tags (for other, M-x apropos tags or see `etags' documentation)
+
+ twelf-tag \\[twelf-tag]
+ Create tags file TAGS for current configuration.
+ If current configuration is names CONFIGx, tags file will be named TAGx.
+ Errors are displayed in the Twelf server buffer.
+
+Timers
+
+ twelf-timers-reset \\[twelf-timers-reset]
+ Reset Twelf timers.
+
+ twelf-timers-show \\[twelf-timers-show]
+ Show and reset Twelf timers.
+
+ twelf-timers-check \\[twelf-timers-check]
+ Show, but do not reset Twelf timers.
+
+Editing
+
+ twelf-indent-decl \\[twelf-indent-decl]
+ Indent each line in current declaration as Twelf code.
+
+ twelf-indent-region \\[twelf-indent-region]
+ Indent each line of the region as Twelf code.
+
+Minor Modes
+===========
+
+An associated minor modes is 2Twelf-SML (toggled with
+twelf-to-twelf-sml-mode). This means that we assume communication
+is an inferior Twelf-SML process and not a Twelf server.
+
+Related Major Modes
+===================
+
+Related major modes are Twelf Server (for the Twelf server buffer) and
+Twelf-SML (for an inferior Twelf-SML process). Both modes are based on
+the standard Emacs comint package and inherit keybindings for retrieving
+preceding input.
+
+Customization
+=============
+
+The following variables may be of general utility.
+
+ twelf-indent amount of indentation for nested Twelf expressions
+ twelf-mode-hook hook to run when entering Twelf mode
+ twelf-server-program full pathname of Twelf server program
+ twelf-server-mode-hook hook to run when entering Twelf server mode
+ twelf-info-file name of Twelf info file with documentation
+
+The following is a typical section of a .emacs initialization file
+which can be found in the file init.el.
+
+(setq load-path (cons \"/afs/cs/project/twelf/research/twelf/emacs\" load-path))
+
+(autoload 'twelf-mode \"twelf\" \"Major mode for editing Twelf source.\" t)
+(autoload 'twelf-server \"twelf\" \"Run an inferior Twelf server.\" t)
+(autoload 'twelf-sml \"twelf\" \"Run an inferior Twelf-SML process.\" t)
+
+(setq auto-mode-alist
+ (cons '(\"\\.elf$\" . twelf-mode)
+ (cons '(\"\\.quy$\" . twelf-mode)
+ (cons '(\"\\.thm$\" . twelf-mode)
+ (cons '(\"\\.cfg$\" . twelf-mode)
+ auto-mode-alist)))))
+
+(setq twelf-server-program
+ \"/afs/cs/project/twelf/research/twelf/bin/twelf-server\")
+
+(setq twelf-sml-program
+ \"/afs/cs/project/twelf/misc/smlnj/bin/sml-cm\")
+
+(setq twelf-info-file
+ \"/afs/cs/project/twelf/research/twelf/doc/info/twelf.info\")
+"
+ (interactive)
+ (kill-all-local-variables)
+ (twelf-mode-variables)
+ (use-local-map twelf-mode-map)
+ (setq major-mode 'twelf-mode)
+ (setq mode-name "Twelf")
+ (twelf-config-mode-check)
+ (twelf-add-menu) ; add Twelf menu to menubar
+ ;; disable twelf-add-to-config-check: require explicit add-file
+ ;; (twelf-add-to-config-check)
+ (run-hooks 'twelf-mode-hook))
+
+;;;----------------------------------------------------------------------
+;;; Reading info file
+;;;----------------------------------------------------------------------
+
+(defun twelf-info (&optional file)
+ "Enter Info, starting with the Twelf node
+Optional argument FILE specifies the info file.
+
+In interactive use, a prefix arguments directs this command to
+read a file name from the minibuffer."
+ (interactive (if current-prefix-arg
+ (list (read-file-name "Info file name: " nil nil t))))
+ (info (or file twelf-info-file)))
+
+;;;----------------------------------------------------------------------
+;;; Error message parsing
+;;;----------------------------------------------------------------------
+
+(defconst twelf-error-regexp
+ "^.+:[-0-9.:]+.* \\(Error\\|Warning\\):"
+ "Regexp for matching Twelf error.")
+
+(defconst twelf-error-fields-regexp
+ "^[-=? \t]*\\(.+\\):\
+\\([0-9]+\\)\\(\\.\\([0-9]+\\)\\)?\\(-\\([0-9]+\\)\\(\\.\\([0-9]+\\)\\)?\\)?\
+.+\\(Error\\|Warning\\):"
+ "Regexp to extract fields of Twelf error.")
+
+(defconst twelf-error-decl-regexp
+ "^[-=? \t]*\\(.+\\)::\\([^ \t\n]+\\) "
+ "Regexp to extract filename and identifier from declaration error.")
+
+(defun looked-at-nth (n)
+ (let ((b (match-beginning n))
+ (e (match-end n)))
+ (if (or (null b) (null e)) nil
+ (buffer-substring (match-beginning n) (match-end n)))))
+
+(defun looked-at-nth-int (n)
+ (let ((str (looked-at-nth n)))
+ (if (null str) nil
+ (string-to-int str))))
+
+(defun twelf-error-parser (pt)
+ "Standard parser for Twelf errors.
+Returns a 5-element list (FILE START-LINE START-COL END-LINE END-COL)
+or (\"Local\" START-CHAR NIL END-CHAR NIL)."
+ (save-excursion
+ (goto-char pt)
+ (re-search-forward twelf-error-fields-regexp)
+ (list (looked-at-nth 1) ; file or "Local" or "stdIn"
+ (looked-at-nth-int 2) ; start line or char
+ (looked-at-nth-int 4) ; start column, if given, else nil
+ (looked-at-nth-int 6) ; end line, if given, else nil or char
+ (looked-at-nth-int 8) ; end column, if given, else nil
+ )))
+
+(defun twelf-error-decl (pos)
+ "Determines if the error is identified only by its declaration."
+ (save-excursion
+ (goto-char pos)
+ (looking-at twelf-error-decl-regexp)))
+
+(defun twelf-mark-relative (line0 col0 line1 col1)
+ "Mark error region if location is given relative to a buffer position."
+ (if (not (= line0 1))
+ (forward-line (1- line0)))
+ ;; work around bug: from stdIn, first line is off by one.
+ (forward-char (if (not (= line0 1)) (1- col0) (1- (1- col0))))
+ ;; select region, if non-empty
+ (cond ((not (null line1))
+ (push-mark (point))
+ (cond ((not (= line1 line0))
+ (forward-line (- line1 line0))
+ (forward-char (1- col1)))
+ (t (forward-char (- col1 col0))))
+ (exchange-point-and-mark)
+ (funcall twelf-highlight-range-function (point) (mark)))))
+
+(defun twelf-mark-absolute (line0 col0 line1 col1)
+ "Mark error region if location is given as absolute buffer position."
+ (cond ((and line0 col0 line1 col1) ; line0.col0-line1.col1 range
+ (goto-line line0)
+ ;; don't use move-to-column since <tab> is 1 char to lexer
+ (forward-char (1- col0))
+ ;; select region, if non-empty
+ (push-mark (point))
+ (goto-line line1)
+ (forward-char (1- col1))
+ (exchange-point-and-mark)
+ (funcall twelf-highlight-range-function (point) (mark)))
+ ((and (null col0) (null col1)) ; char0-char1 range
+ (goto-char line0)
+ (push-mark (point))
+ (goto-char line1)
+ (exchange-point-and-mark)
+ (funcall twelf-highlight-range-function (point) (mark)))
+ ((and line0 col0) ; beginning line0.col0
+ (goto-line line0)
+ (forward-char (1- col0)))
+ (line0 ; beginning char0
+ (goto-char line0))
+ (t (error "Unrecognized format for error location"))))
+
+(defun twelf-find-decl (filename id)
+ "In FILENAME find probable declaration of ID."
+ (if (not (file-readable-p filename))
+ (error "Cannot read file %s" filename)
+ (switch-to-buffer-other-window (find-file-noselect filename))
+ (goto-char (point-min))
+ (let ((done nil)
+ decl-id)
+ (while (not done)
+ (setq decl-id (twelf-next-decl filename *twelf-last-input-buffer*))
+ (if (not decl-id)
+ (error "Declaration of %s not found in file %s." id filename)
+ (setq done (string= decl-id id))
+ (if (not done) (twelf-end-of-par)))))))
+
+(defun twelf-next-error ()
+ "Find the next error by parsing the Twelf server or Twelf-SML buffer.
+Move the error message on the top line of the window;
+put the cursor at the beginning of the error source. If the
+error message specifies a range, the mark is placed at the end."
+ (interactive)
+ (let ((case-fold-search nil)
+ (twelf-buffer (or *twelf-last-input-buffer*
+ (error "Cannot determine process buffer with last input")))
+ error-begin)
+ (pop-to-buffer twelf-buffer)
+ (goto-char *twelf-error-pos*) ; go to last error
+ (if (not (re-search-forward twelf-error-regexp (point-max) t))
+ (error "No error message found.")
+ (setq error-begin (match-beginning 0))
+ (setq *twelf-error-pos* (point))
+ (set-window-start (get-buffer-window twelf-buffer)
+ (save-excursion (beginning-of-line) (point)))
+ (if (twelf-error-decl error-begin)
+ (twelf-find-decl (looked-at-nth 1) (looked-at-nth 2))
+ (let* ((parse (twelf-error-parser error-begin))
+ (file (nth 0 parse))
+ (line0 (nth 1 parse))
+ (col0 (nth 2 parse))
+ (line1 (nth 3 parse))
+ (col1 (nth 4 parse)))
+ (cond ((equal file "stdIn")
+ ;; Error came from direct input
+ (cond ((null *twelf-last-region-sent*)
+ ;; from last interactive input in the Twelf buffer
+ (goto-char (point-max))
+ (comint-previous-input 1)
+ (setq *twelf-last-region-sent* t)
+ (goto-char (process-mark
+ (get-buffer-process twelf-buffer)))
+ (twelf-mark-relative line0 col0 line1 col1))
+ ((eq *twelf-last-region-sent* t)
+ ;; from the waiting input in the Twelf buffer
+ (goto-char (process-mark
+ (get-buffer-process twelf-buffer)))
+ (twelf-mark-relative line0 col0 line1 col1))
+ (t
+ ;; from a region sent from some buffer
+ (let ((buf (nth 0 *twelf-last-region-sent*))
+ (start (nth 1 *twelf-last-region-sent*)))
+ (switch-to-buffer-other-window buf)
+ (goto-char start)
+ (twelf-mark-relative line0 col0 line1 col1)))))
+ ((equal file "Local")
+ ;; Error came from local input, usually to a server process
+ ;; in this case the address relative, and expressed in
+ ;; characters, rather than lines.
+ (let ((local-buffer (nth 0 *twelf-last-region-sent*))
+ ;; Local characters seem to be off by two
+ (char0 (+ (nth 1 *twelf-last-region-sent*) (- line0 2)))
+ (char1 (+ (nth 1 *twelf-last-region-sent*) (- line1 2))))
+ (switch-to-buffer-other-window local-buffer)
+ (goto-char char1)
+ (push-mark)
+ (goto-char char0)
+ (exchange-point-and-mark)))
+ ((file-readable-p file)
+ ;; Error came from a source file
+ (switch-to-buffer-other-window (find-file-noselect file))
+ (twelf-mark-absolute line0 col0 line1 col1))
+ (t
+ (error (concat "Can't read file " file)))))))))
+
+(defun twelf-goto-error ()
+ "Go to the error reported on the current line or below.
+Also updates the error cursor to the current line."
+ (interactive)
+ (pop-to-buffer (or *twelf-last-input-buffer*
+ (error "Cannot determine process buffer with last input")))
+ (beginning-of-line)
+ (setq *twelf-error-pos* (point))
+ (twelf-next-error))
+
+;;;----------------------------------------------------------------------
+;;; NT Emacs bug workaround
+;;;----------------------------------------------------------------------
+
+(defun twelf-convert-standard-filename (filename)
+ "Convert FILENAME to form appropriate for Twelf Server of current OS."
+ (cond ((eq system-type 'windows-nt)
+ (while (string-match "/" filename)
+ (setq filename (replace-match "\\" t t filename)))
+ filename)
+ (t (convert-standard-filename filename))))
+
+;;;----------------------------------------------------------------------
+;;; Communication with Twelf server
+;;;----------------------------------------------------------------------
+
+(defun string-member (x l)
+ (if (null l) nil
+ (or (string-equal x (car l)) (string-member x (cdr l)))))
+
+;(defun twelf-add-to-config-check ()
+; "Ask if current file should be added to the current Twelf configuration."
+; (let ((file-name (buffer-file-name)))
+; (if (and (not (string-member file-name *twelf-config-list*))
+; (not (null *twelf-config-buffer*))
+; (yes-or-no-p "Add to the current configuration? "))
+; (twelf-server-add-file file-name))))
+
+(defun twelf-config-proceed-p (file-name)
+ "Ask if to proceed if FILE-NAME is not in current configuration."
+ (if (and (not (string-member file-name *twelf-config-list*))
+ (not (yes-or-no-p "File not in current configuration. Save? ")))
+ nil
+ t))
+
+(defun twelf-save-if-config (buffer)
+ "Ask if BUFFER should be saved if in the current configuration.
+Always save if the variable `twelf-save-silently' is non-nil."
+ (let ((file-name (buffer-file-name buffer)))
+ (if (and (buffer-modified-p buffer)
+ file-name
+ (string-member file-name *twelf-config-list*))
+ (if twelf-save-silently
+ (save-buffer)
+ (pop-to-buffer buffer)
+ (if (yes-or-no-p (concat "Save " file-name "? "))
+ (save-buffer))))))
+
+(defun twelf-config-save-some-buffers ()
+ "Cycle through all buffers and save those in the current configuration."
+ (mapcar 'twelf-save-if-config (buffer-list)))
+
+(defun twelf-save-check-config (&optional displayp)
+ "Save its modified buffers and then check the current Twelf configuration.
+With prefix argument also displays Twelf server buffer.
+If necessary, this will start up an Twelf server process."
+ (interactive "P")
+ (let ((current-file-name (buffer-file-name)))
+ (cond ((and current-file-name
+ (not buffer-read-only)
+ (buffer-modified-p)
+ (twelf-config-proceed-p current-file-name))
+ (save-buffer)))
+ (save-excursion
+ (twelf-config-save-some-buffers))
+ (twelf-check-config displayp)))
+
+(defun twelf-check-config (&optional displayp)
+ "Check the current Twelf configuration.
+With prefix argument also displays Twelf server buffer.
+If necessary, this will start up an Twelf server process."
+ (interactive "P")
+ (if (not *twelf-config-buffer*)
+ (call-interactively 'twelf-server-configure))
+ (twelf-server-sync-config)
+ (twelf-focus nil nil)
+ (twelf-server-send-command "Config.load")
+ (twelf-server-wait displayp))
+
+(defun twelf-save-check-file (&optional displayp)
+ "Save buffer and then check it by giving a command to the Twelf server.
+In Twelf Config minor mode, it reconfigures the server.
+With prefix argument also displays Twelf server buffer."
+ (interactive "P")
+ (save-buffer)
+ (if twelf-config-mode
+ (twelf-server-configure (buffer-file-name) "Server OK: Reconfigured")
+ (let* ((save-file (buffer-file-name))
+ (check-file (file-relative-name save-file (twelf-config-directory)))
+ (check-file-os (twelf-convert-standard-filename check-file)))
+ (twelf-server-sync-config)
+ (twelf-focus nil nil)
+ (twelf-server-send-command (concat "loadFile " check-file-os))
+ (twelf-server-wait displayp))))
+
+(defun twelf-buffer-substring (start end)
+ "The substring of the current buffer between START and END.
+The location is recorded for purposes of error parsing."
+ (setq *twelf-last-region-sent* (list (current-buffer) start end))
+ (buffer-substring start end))
+
+(defun twelf-buffer-substring-dot (start end)
+ "The substring of the current buffer between START and END plus
+an end-of-input marker, `%.'. The location of the input is recorded
+for purposes of error parsing."
+ (concat (twelf-buffer-substring start end) "%."))
+
+(defun twelf-check-declaration (&optional displayp)
+ "Send the current declaration to the Twelf server process for checking.
+With prefix argument also displays Twelf server buffer."
+ (interactive "P")
+ (let* ((par (twelf-current-decl))
+ (par-start (nth 0 par))
+ (par-end (nth 1 par))
+ (decl (twelf-buffer-substring-dot par-start par-end)))
+ (twelf-focus par-start par-end)
+ (twelf-server-send-command (concat "readDecl\n" decl))
+ (twelf-server-wait displayp)))
+
+;(defun twelf-highlight-range (par-start par-end &optional offset)
+; "Set point and mark to encompass the range analyzed by the Twelf server."
+; (let* ((range (twelf-parse-range))
+; (range-start (nth 0 range))
+; (range-end (nth 1 range))
+; (offset (if (null offset) 0 offset)))
+; (if (and (integerp range-start) (integerp range-end))
+; (progn (goto-char (+ (- (+ par-start range-end) 2) offset))
+; (push-mark (- (+ par-start range-start) 2))
+; (funcall twelf-highlight-range-function (point) (mark))))))
+
+(defun twelf-highlight-range-zmacs (start end)
+ "Highlight range as zmacs region. Assumes point and mark are set.
+Does nothing if function zmacs-activate-region is undefined."
+ (if (fboundp 'zmacs-activate-region)
+ (zmacs-activate-region)))
+
+(defun twelf-focus (&optional start end)
+ "Focus on region between START and END as current declaration or query. If
+START and END are nil, then no focus exists. This intermediary just calls
+the appropriate function."
+ (funcall twelf-focus-function start end))
+
+(defun twelf-focus-noop (start end)
+ "This default focus function does nothing."
+ ())
+
+;; Not yet available in Twelf 1.2 -fp
+
+;(defun twelf-type-at-point ()
+; "Display the type of the subterm at the point in the current Twelf decl.
+
+;The subterm at point is the smallest subterm whose printed representation
+;begins to the left of point and extends up to or beyond point. After this and
+;similar commands applicable to subterms, the current region (between mark and
+;point) is set to encompass precisely the selected subterm. In XEmacs,
+;it will thus be highlighted under many circumstances. In other versions
+;of Emacs \\[exchange-point-and-mark] will indicate the extent of the region.
+
+;The type computed for the subterm at point takes contextual information into
+;account. For example, if the subterm at point is a constant with implicit
+;arguments, the type displayed will be the instance of the constant (unlike
+;M-x twelf-type-const (\\[twelf-type-const]), which yields the absolute type of a constant)."
+
+; (interactive)
+; (let* ((par (twelf-current-decl))
+; (par-start (nth 0 par))
+; (par-end (nth 1 par))
+; (decl (twelf-buffer-substring-dot par-start par-end)))
+; (twelf-focus par-start par-end)
+; (twelf-server-send-command
+; (concat "type-at "
+; (twelf-current-syncat) " "
+; (int-to-string (+ (- (point) par-start) 2)) "\n"
+; decl))
+; (twelf-server-wait t)
+; (twelf-highlight-range par-start par-end)))
+
+;(defun twelf-expected-type-at-point ()
+; "Display the type expected at the point in the current declaration.
+
+;This replaces the subterm at point by an underscore _ and determines
+;the type that _ would have to have for the whole declaration to be valid.
+;This is useful for debugging in places where inconsistent type constraints
+;have arisen. Error messages may be given, but will not be correctly
+;interpreted by Emacs, since the string sent to the server may be different
+;from the declaration in the buffer.
+
+;For a definition of the subterm at point, see function twelf-type-at-point."
+; (interactive)
+; (let* ((par (twelf-current-decl))
+; (par-start (nth 0 par))
+; (par-end (nth 1 par))
+; (par-initial-end nil)
+; (par-final-start nil)
+; modified-decl)
+; ;; (exp-present (not (looking-at (concat "[" *whitespace* "]"))))
+; (backward-sexp 1)
+; (setq par-initial-end (point))
+; (forward-sexp 1)
+; (setq par-final-start (point))
+; (setq modified-decl
+; (concat (twelf-buffer-substring par-start par-initial-end)
+; "_" (twelf-buffer-substring-dot par-final-start par-end)))
+; ;; Error messages here are not accurate. Nontheless:
+; (setq *twelf-last-region-sent* (list (current-buffer) par-start par-end))
+; (twelf-focus par-start par-end)
+; (twelf-server-send-command
+; (concat "type-at "
+; (twelf-current-syncat) " "
+; (int-to-string (1+ (+ (- par-initial-end par-start) 2))) "\n"
+; modified-decl))
+; (twelf-server-wait t)
+; (twelf-highlight-range par-start par-end
+; (1- (- par-final-start par-initial-end)))))
+
+;(defun twelf-parse-range ()
+; "Parse a range as returned by the Twelf server and return as a list."
+; (save-window-excursion
+; (let ((twelf-server-buffer (twelf-get-server-buffer)))
+; (set-buffer twelf-server-buffer)
+; (goto-char *twelf-server-last-process-mark*)
+; ;; We are now at the beginning of the output
+; (re-search-forward "^\\[\\([0-9]+\\),\\([0-9]+\\))")
+; (list (looked-at-nth-int 1) (looked-at-nth-int 2)))))
+
+(defun twelf-type-const ()
+ "Display the type of the constant before point.
+Note that the type of the constant will be `absolute' rather than the
+type of the particular instance of the constant."
+ (interactive)
+ (let ((previous-point (point)))
+ (skip-chars-backward *whitespace* (point-min))
+ (skip-chars-forward *twelf-id-chars* (point-max))
+ (let ((end-of-id (point)))
+ (skip-chars-backward *twelf-id-chars* (point-min))
+ (let ((c (if (= (point) end-of-id)
+ ;; we didn't move. this should eventually become a
+ ;; completing-read
+ (read-string "Constant: ")
+ (buffer-substring (point) end-of-id))))
+ (twelf-server-send-command (concat "decl " c))
+ (twelf-server-wait t) ; Wait for and display reply
+ (goto-char previous-point)))))
+
+;; Unused? -fp
+;(defun twelf-backwards-parse-arglist ()
+; "Parse an argument list template as returned by the server."
+; (save-window-excursion
+; (let ((twelf-server-buffer (twelf-get-server-buffer)))
+; (set-buffer twelf-server-buffer)
+; (goto-char *twelf-server-last-process-mark*)
+; ;; Should be right at the beginning of the output.
+; ;; (re-search-forward "^arglist") ;
+; ;; (beginning-of-line 2)
+; (let ((arglist-begin (point)))
+; (skip-chars-forward "^." (point-max))
+; (buffer-substring arglist-begin (point))))))
+
+;; Not yet ported to Twelf 1.2
+;(defun twelf-show-region-in-window (start end)
+; "Change window parameters so it precisely shows the given region."
+; (enlarge-window (- (max (count-lines start end) window-min-height)
+; (window-height)))
+; (set-window-start (selected-window) start))
+
+;(defun twelf-show-menu ()
+; "Display the Twelf server buffer to show menu of possible completions."
+; (let ((old-buffer (current-buffer))
+; (twelf-server-buffer (twelf-get-server-buffer))
+; region-start region-end)
+; (switch-to-buffer-other-window twelf-server-buffer)
+; (goto-char *twelf-server-last-process-mark*)
+; (if (re-search-forward "-\\.$" (point-max) t)
+; (progn
+; (forward-char 1)
+; (setq region-start (point))
+; (if (re-search-forward "^-\\." (point-max) t)
+; (setq region-end (point))
+; (error "List of alternatives not terminated by -.")))
+; (error "No alternatives found."))
+; (twelf-show-region-in-window region-start region-end)
+; (switch-to-buffer-other-window old-buffer)))
+
+;(defun twelf-completions-at-point ()
+; "List the possible completions of the term at point based on type information.
+
+;The possible completions are numbered, and the function twelf-complete
+;(\\[twelf-complete]) can be used subsequently to replace the term at point with
+;one of the alternatives.
+
+;Above the display of the alternatives, the type of the subterm at
+;point is shown, since it is this type which is the basis for listing
+;the possible completions.
+
+;In the list alternatives, a variable X free in the remaining declaration
+;is printed ^X, and a bound variable x may be printed as !x. These marks
+;are intended to aid in the understanding of the alternatives, but
+;must be removed in case the alternative is copied literally into the
+;input declaration (as, for example, with the \\[twelf-complete] command)."
+; (interactive)
+; (let* ((par (twelf-current-decl))
+; (par-start (nth 0 par))
+; (par-end (nth 1 par))
+; (decl (twelf-buffer-substring-dot par-start par-end)))
+; (twelf-focus par-start par-end)
+; (twelf-server-send-command
+; (concat "complete-at "
+; (twelf-current-syncat) " "
+; (int-to-string (+ (- (point) par-start) 2)) "\n"
+; decl))
+; (twelf-server-wait nil)
+; (twelf-highlight-range par-start par-end)
+; (twelf-show-menu)))
+
+;(defun twelf-complete (n)
+; "Pick the alternative N from among possible completions.
+;This replaces the current region with the given pattern.
+;The list of completions must be generated with the command
+;twelf-completions-at-point (\\[twelf-completions-at-point])."
+; (interactive "NAlternative: ")
+; (let (start completion)
+; (save-excursion
+; (set-buffer (twelf-get-server-buffer))
+; (goto-char *twelf-server-last-process-mark*)
+; (if (not (re-search-forward (concat "^" (int-to-string n) "\\. ")
+; (point-max) t))
+; (error "No alternative %d found in Twelf server buffer." n))
+; (setq start (point))
+; (if (not (search-forward " ::" (point-max) t))
+; (error "List of completions not well-formed."))
+; (backward-char 3)
+; (setq completion (buffer-substring start (point))))
+; (delete-region (point) (mark))
+; (insert "(" completion ")")
+; (twelf-show-menu)))
+
+;;;----------------------------------------------------------------------
+;;; Twelf server mode (major mode)
+;;; This is for the buffer with the Twelf server process, to facilitate
+;;; direct interaction (which should rarely be necessary)
+;;;----------------------------------------------------------------------
+
+(defvar twelf-server-mode-map nil
+ "The keymap used in twelf-server mode.")
+
+(cond ((not twelf-server-mode-map)
+ (setq twelf-server-mode-map (copy-keymap comint-mode-map))
+ (install-basic-twelf-keybindings twelf-server-mode-map)
+ ;; C-c C-c is bound to twelf-save-check config in Twelf mode
+ (define-key twelf-server-mode-map "\C-c\C-c" 'twelf-save-check-config)
+ ;; Bind the function shadowed by the previous definition to C-c C-i
+ (define-key twelf-server-mode-map "\C-c\C-i" 'comint-interrupt-subjob)
+ ))
+
+(defconst twelf-server-cd-regexp "^\\s *OS\\.chDir\\s *\\(.*\\)"
+ "Regular expression used to match cd commands in Twelf server buffer.")
+
+(defun looked-at-string (string n)
+ "Substring of STRING consisting of Nth match."
+ (substring string (match-beginning n) (match-end n)))
+
+(defun twelf-server-directory-tracker (input)
+ "Checks input for cd commands and changes default directory in buffer.
+As a side effect, it resets *twelf-error-pos* and *twelf-last-region-sent*
+to indicate interactive input. Used as comint-input-filter-function in Twelf
+server buffer."
+ (if (twelf-input-filter input)
+ (setq *twelf-last-region-sent* nil))
+ (setq *twelf-last-input-buffer* (current-buffer))
+ (setq *twelf-error-pos* (marker-position (process-mark (twelf-server-process))))
+ (cond ((string-match twelf-server-cd-regexp input)
+ (let ((expanded-dir (expand-dir (looked-at-string input 1))))
+ (setq default-directory expanded-dir)
+ (pwd)))
+ ((string-match "^set\\s +chatter\\s +\\([0-9]\\)+" input)
+ (setq twelf-chatter (string-to-int (looked-at-string input 1))))
+ ;;((string-match "^set\\s +trace\\s +\\([0-9]\\)+" input)
+ ;; (setq twelf-trace (string-to-int (looked-at-string input 1))))
+ ((string-match "^set\\s-+\\(\\S-+\\)\\s-+\\(\\w+\\)" input)
+ (if (assoc (looked-at-string input 1) *twelf-track-parms*)
+ (set (cdr (assoc (looked-at-string input 1) *twelf-track-parms*))
+ (looked-at-string input 2))))))
+
+(defun twelf-input-filter (input)
+ "Function to filter strings before they are saved in input history.
+We filter out all whitespace and anything shorter than two characters."
+ (and (not (string-match "\\`\\s *\\'" input))
+ (> (length input) 1)))
+
+(defun twelf-server-mode ()
+ "Major mode for interacting with an inferior Twelf server process.
+Runs twelf-server-mode-hook.
+
+The following commands are available:
+\\{twelf-server-mode-map}"
+ (interactive)
+ (kill-all-local-variables)
+ ;; Initialize comint parameters
+ (comint-mode)
+ (setq comint-prompt-regexp "^") ;; no prompt
+ (setq comint-input-filter 'twelf-input-filter)
+ ;;changed for XEmacs 19.16
+ ;;(setq comint-input-sentinel 'twelf-server-directory-tracker)
+ (add-hook 'comint-input-filter-functions 'twelf-server-directory-tracker
+ nil t)
+ (twelf-mode-variables)
+ ;; For sequencing through error messages:
+ (make-local-variable '*twelf-error-pos*)
+ (setq *twelf-error-pos* (point-max))
+ ;; Set mode and keymap
+ (setq major-mode 'twelf-server-mode)
+ (setq mode-name "Twelf Server")
+ (setq mode-line-process '(": %s"))
+ (use-local-map twelf-server-mode-map)
+ (twelf-server-add-menu) ; add Twelf Server menu
+ ;; Run user specified hooks, if any
+ (run-hooks 'twelf-server-mode-hook))
+
+;;;----------------------------------------------------------------------
+;;; Functions to support use of the Twelf server
+;;;----------------------------------------------------------------------
+
+(defun twelf-parse-config ()
+ "Starting at point, parse a configuration file."
+ (let ((filelist nil))
+ (skip-chars-forward *whitespace*)
+ (while (not (eobp)) ; end of buffer?
+ (cond ((looking-at "%") ; comment through end of line
+ (end-of-line))
+ (t (let ((begin-point (point))) ; parse filename starting at point
+ (skip-chars-forward (concat "^" *whitespace*))
+ (let* ((file-name (buffer-substring begin-point (point)))
+ (absolute-file-name
+ (expand-file-name file-name default-directory)))
+ (if (file-readable-p absolute-file-name)
+ (setq filelist (cons absolute-file-name filelist))
+ (error "File %s not readable." file-name))))))
+ (skip-chars-forward *whitespace*))
+ filelist))
+
+(defun twelf-server-read-config ()
+ "Read the configuration and initialize *twelf-config-list*."
+ (if (or (not (bufferp *twelf-config-buffer*))
+ (null (buffer-name *twelf-config-buffer*)))
+ (error "No current configuration buffer"))
+ (set-buffer *twelf-config-buffer*)
+ (goto-char (point-min))
+ (twelf-parse-config))
+
+(defun twelf-server-sync-config ()
+ "Synchronize the configuration file, buffer, and Twelf server."
+ (if (or (not (bufferp *twelf-config-buffer*))
+ (null (buffer-name *twelf-config-buffer*)))
+ (error "No current configuration buffer"))
+ (if (and twelf-config-mode
+ (not (equal *twelf-config-buffer* (current-buffer)))
+ (yes-or-no-p "Buffer is different from current configuration, reconfigure server? "))
+ (twelf-server-configure (buffer-file-name (current-buffer))
+ "Server OK: Reconfigured"))
+ (save-excursion
+ (set-buffer *twelf-config-buffer*)
+ (if (buffer-modified-p *twelf-config-buffer*)
+ (progn
+ (display-buffer *twelf-config-buffer*)
+ (if (yes-or-no-p "Config buffer has changed, save new version? ")
+ (save-buffer)
+ (message "Checking old configuration"))))
+ (if (not (verify-visited-file-modtime *twelf-config-buffer*))
+ (if (yes-or-no-p "Config file has changed, read new contents? ")
+ (revert-buffer t t)))
+ (if (not (equal (visited-file-modtime) *twelf-config-time*))
+ (progn
+ (display-buffer *twelf-config-buffer*)
+ (if (yes-or-no-p "Config file has changed, reconfigure server? ")
+ (twelf-server-configure (buffer-file-name *twelf-config-buffer*)
+ "Server OK: Configured")
+ (if (not (yes-or-no-p "Ask next time? "))
+ (setq *twelf-config-time* (visited-file-modtime))))))))
+
+(defun twelf-get-server-buffer (&optional createp)
+ "Get the current Twelf server buffer.
+Optional argument CREATEP indicates if the buffer should be
+created if it doesn't exist."
+ (if (and (bufferp *twelf-server-buffer*)
+ (not (null (buffer-name *twelf-server-buffer*))))
+ *twelf-server-buffer*
+ (if createp
+ (let ((twelf-server-buffer
+ (get-buffer-create *twelf-server-buffer-name*)))
+ (save-window-excursion
+ (set-buffer twelf-server-buffer)
+ (twelf-server-mode)
+ (setq *twelf-server-buffer* twelf-server-buffer))
+ twelf-server-buffer)
+ (error "No Twelf server buffer"))))
+
+(defun twelf-init-variables ()
+ "Initialize variables that track Twelf server state."
+ (setq twelf-chatter 3)
+ ;;(setq twelf-trace 0)
+ (setq twelf-double-check "false")
+ (setq twelf-print-implicit "false"))
+
+(defun twelf-server (&optional program)
+ "Start an Twelf server process in a buffer named *twelf-server*.
+Any previously existing process is deleted after confirmation.
+Optional argument PROGRAM defaults to the value of the variable
+twelf-server-program.
+This locally re-binds `twelf-server-timeout' to 15 secs."
+ (interactive)
+ (let* ((default-program (if (null program) twelf-server-program program))
+ (default-dir (file-name-directory default-program))
+ (program (expand-file-name
+ (if (null program)
+ (read-file-name (concat "Twelf server: (default "
+ (file-name-nondirectory
+ default-program)
+ ") ")
+ default-dir
+ default-program
+ t)
+ program)))
+ ;; longer timeout during startup
+ (twelf-server-timeout 15))
+ ;; We save the program name as the default for the next time a server is
+ ;; started in this session.
+ (setq twelf-server-program program))
+ (save-window-excursion
+ (let* ((twelf-server-buffer (twelf-get-server-buffer t))
+ (twelf-server-process (get-buffer-process twelf-server-buffer)))
+ (set-buffer twelf-server-buffer)
+ (if (not (null twelf-server-process))
+ (if (yes-or-no-p "Kill current server process? ")
+ (delete-process twelf-server-process)
+ (error "Twelf Server restart aborted")))
+ (goto-char (point-max))
+ (setq *twelf-server-last-process-mark* (point))
+ ;; initialize variables
+ (twelf-init-variables)
+ (start-process *twelf-server-process-name*
+ twelf-server-buffer
+ twelf-server-program)
+ (twelf-server-wait)
+ (twelf-server-process))))
+
+(defun twelf-server-process (&optional buffer)
+ "Return the twelf server process, starting one if none exists."
+ (let* ((twelf-server-buffer (if (null buffer) (twelf-get-server-buffer t)
+ buffer))
+ (twelf-server-process (get-buffer-process twelf-server-buffer)))
+ (if (not (null twelf-server-process))
+ twelf-server-process
+ (twelf-server))))
+
+(defun twelf-server-display (&optional selectp)
+ "Display Twelf server buffer, moving to the end of output.
+With prefix argument also selects the Twelf server buffer."
+ (interactive "P")
+ (display-server-buffer)
+ (if selectp (pop-to-buffer (twelf-get-server-buffer))))
+
+(defun display-server-buffer (&optional buffer)
+ "Display the Twelf server buffer so that the end of output is visible."
+ (let* ((twelf-server-buffer (if (null buffer) (twelf-get-server-buffer)
+ buffer))
+ (_ (set-buffer twelf-server-buffer))
+ (twelf-server-process (twelf-server-process twelf-server-buffer))
+ (proc-mark (process-mark twelf-server-process))
+ (_ (display-buffer twelf-server-buffer))
+ (twelf-server-window (get-buffer-window twelf-server-buffer)))
+ (if (not (pos-visible-in-window-p proc-mark twelf-server-window))
+ (progn
+ (push-mark proc-mark)
+ (set-window-point twelf-server-window proc-mark)))
+ (sit-for 0)))
+
+(defun twelf-server-send-command (command)
+ "Send a string COMMAND to the Twelf server."
+ (interactive "sCommand: ")
+ (let* ((input (concat command "\n"))
+ (twelf-server-buffer (twelf-get-server-buffer))
+ (twelf-server-process (twelf-server-process twelf-server-buffer)))
+ (if twelf-server-echo-commands
+ (let ((previous-buffer (current-buffer)))
+ (if twelf-server-display-commands
+ (display-server-buffer twelf-server-buffer))
+ (set-buffer twelf-server-buffer)
+ (goto-char (point-max))
+ (insert input)
+ (set-marker (process-mark twelf-server-process) (point-max))
+ (setq *twelf-error-pos* (point-max))
+ (set-buffer previous-buffer)))
+ (setq *twelf-last-input-buffer* twelf-server-buffer)
+ (setq *twelf-server-last-process-mark*
+ (marker-position (process-mark twelf-server-process)))
+ (comint-send-string twelf-server-process input)))
+
+(defun twelf-accept-process-output (process timeout)
+ "Incompatibility workaround for versions of accept-process-output.
+In case the function accepts no TIMEOUT argument, we wait potentially
+forever (until the user aborts, typically with \\[keyboard-quit])."
+ (condition-case nil ; do not keep track of error message
+ (accept-process-output process timeout)
+ (wrong-number-of-arguments
+ (accept-process-output process))))
+
+(defun twelf-server-wait (&optional displayp ok-message abort-message)
+ "Wait for server acknowledgment and beep if error occurred.
+If optional argument DISPLAYP is non-NIL, or if an error occurred, the
+Twelf server buffer is displayed. Optional second and third arguments
+OK-MESSAGE and ABORT-MESSAGE are the strings to show upon successful
+completion or abort of the server which default to \"Server OK\" and
+\"Server ABORT\"."
+ (let* ((chunk-count 0)
+ (last-point *twelf-server-last-process-mark*)
+ (previous-buffer (current-buffer))
+ (previous-match-data (match-data))
+ (twelf-server-buffer (twelf-get-server-buffer))
+ (twelf-server-process (get-buffer-process twelf-server-buffer)))
+ (unwind-protect
+ (catch 'done
+ (set-buffer twelf-server-buffer)
+ (while t
+ (goto-char last-point)
+ (if (re-search-forward "\\(%% OK %%\n\\)\\|\\(%% ABORT %%\n\\)"
+ (point-max) 'limit)
+ (cond ((match-beginning 1)
+ (if displayp
+ (display-server-buffer twelf-server-buffer))
+ (message (or ok-message "Server OK"))
+ (throw 'done nil))
+ ((match-beginning 2)
+ (display-server-buffer twelf-server-buffer)
+ (error (or abort-message "Server ABORT"))
+ (throw 'done nil)))
+ (cond ((or (not (twelf-accept-process-output
+ twelf-server-process twelf-server-timeout))
+ (= last-point (point)))
+ (display-server-buffer twelf-server-buffer)
+ (message "Server TIMEOUT, continuing Emacs")
+ (throw 'done nil))
+ (t (setq chunk-count (+ chunk-count 1))
+ (if (= (mod chunk-count 10) 0)
+ (message (make-string (/ chunk-count 10) ?#)))
+ (sit-for 0))))))
+ (store-match-data previous-match-data)
+ (set-buffer previous-buffer))))
+
+(defun twelf-server-quit ()
+ "Kill the Twelf server process."
+ (interactive)
+ (twelf-server-send-command "OS.exit"))
+
+(defun twelf-server-interrupt ()
+ "Interrupt the Twelf server process."
+ (interactive)
+ (interrupt-process (twelf-server-process)))
+
+(defun twelf-reset ()
+ "Reset the global signature of Twelf maintained by the server."
+ (interactive)
+ (twelf-server-send-command "reset"))
+
+(defun twelf-config-directory ()
+ "Returns directory with current Twelf server configuration."
+ (let ((config-file (buffer-file-name *twelf-config-buffer*)))
+ (file-name-directory config-file)))
+
+;(defun relativize-file-name (filename dir)
+; "Relativize FILENAME with respect to DIR, if possible."
+; (if (string= dir (file-name-directory filename))
+; (file-name-nondirectory filename)
+; filename))
+
+(defun twelf-server-configure (config-file &optional ok-message)
+ "Initializes the Twelf server configuration from CONFIG-FILE.
+A configuration file is a list of relative file names in
+dependency order. Lines starting with % are treated as comments.
+Starts a Twelf servers if necessary."
+ (interactive
+ (list (if twelf-config-mode (buffer-file-name)
+ (expand-file-name
+ (read-file-name "Visit config file: (default sources.cfg) "
+ default-directory
+ (concat default-directory "sources.cfg")
+ nil ; don't require match for now
+ )))))
+ (let* ((config-file (if (file-directory-p config-file)
+ (concat config-file "sources.cfg")
+ config-file))
+ (config-file-os (twelf-convert-standard-filename config-file))
+ (config-dir (file-name-directory config-file))
+ (config-dir-os (twelf-convert-standard-filename config-dir))
+ (config-buffer (set-buffer (or (get-file-buffer config-file)
+ (find-file-noselect config-file))))
+ config-list)
+ (setq *twelf-config-buffer* config-buffer)
+ (if (and (not (verify-visited-file-modtime (get-file-buffer config-file)))
+ (yes-or-no-p "Config file has changed, read new contents? "))
+ (revert-buffer t t))
+ (setq config-list (twelf-server-read-config))
+ (twelf-server-process) ; Start process if necessary
+ (let* ((_ (set-buffer (twelf-get-server-buffer)))
+ (cd-command
+ (if (equal default-directory config-dir)
+ nil
+ (setq default-directory config-dir)
+ (concat "OS.chDir " config-dir-os)))
+ (_ (set-buffer config-buffer)))
+ (cond ((not (null cd-command))
+ (twelf-server-send-command cd-command)
+ (twelf-server-wait nil ""
+ "Server ABORT: Could not change directory")))
+ (twelf-server-send-command
+ (concat "Config.read " config-file-os))
+ (twelf-server-wait nil (or ok-message "Server OK")
+ "Server ABORT: Could not be configured")
+ ;; *twelf-config-buffer* should still be current buffer here
+ (setq *twelf-config-time* (visited-file-modtime))
+ (setq *twelf-config-list* config-list))))
+
+;(defun twelf-server-add-file (filename)
+; "Adds a file to the current configuration."
+; (interactive
+; (list (expand-file-name
+; (read-file-name "File to add: " (twelf-config-directory)))))
+; (let ((relative-file (file-relative-name filename (twelf-config-directory)))
+; temp-time)
+; (save-excursion
+; (set-buffer *twelf-config-buffer*)
+; (goto-char (point-max))
+; (if (not (= (point) (point-min)))
+; (progn
+; (backward-char 1)
+; (if (looking-at "\n")
+; (forward-char 1)
+; (forward-char 1)
+; (insert "\n"))))
+; (insert (concat relative-file "\n"))
+; (save-buffer)
+; (setq temp-time (visited-file-modtime)))
+; (twelf-server-send-command
+; (concat "Config.read " (buffer-file-name *twelf-config-buffer*)))
+; (twelf-server-wait nil "" "Server ABORT: File could not be added to configuration")
+; (setq *twelf-config-list* (cons filename *twelf-config-list*))
+; (setq *twelf-config-time* temp-time)))
+
+(defun natp (x)
+ "Checks if X is an integer greater or equal to 0."
+ (and (integerp x) (>= x 0)))
+
+(defun twelf-read-nat ()
+ "Reads a natural number from the minibuffer."
+ (let ((num nil))
+ (while (not (natp num))
+ (setq num (read-from-minibuffer "Number: " (if num (prin1-to-string num))
+ nil t t))
+ (if (not (natp num)) (beep)))
+ num))
+
+(defun twelf-read-bool ()
+ "Read a boolean in mini-buffer."
+ (completing-read "Boolean: "
+ '(("true" . true) ("false" . false))
+ nil t))
+
+(defun twelf-read-limit ()
+ "Read a limit (* or natural number) in mini-buffer."
+ (let ((input (read-string "Limit (* or nat): ")))
+ (if (equal input "*")
+ input
+ (let ((n (string-to-int input)))
+ (if (and (integerp n) (> n 0))
+ n
+ (error "Number must be non-negative integer"))))))
+
+(defun twelf-read-strategy ()
+ "Read a strategy in mini-buffer."
+ (completing-read "Strategy: "
+ '(("FRS" . "FRS") ("RFS" . "RFS"))
+ nil t))
+
+(defun twelf-read-value (argtype)
+ "Call the read function appropriate for ARGTYPE and return result."
+ (funcall (cdr (assoc argtype *twelf-read-functions*))))
+
+(defun twelf-set (parm value)
+ "Sets the Twelf parameter PARM to VALUE.
+When called interactively, prompts for parameter and value, supporting
+completion."
+ (interactive
+ (let* ((parm (completing-read
+ "Parameter: " *twelf-parm-table* nil t))
+ (argtype (cdr (assoc parm *twelf-parm-table*)))
+ (value (twelf-read-value argtype)))
+ (list parm value)))
+ (track-parm parm value) ; track, if necessary
+ (twelf-server-send-command (concat "set " parm " " value)))
+
+(defun twelf-set-parm (parm)
+ "Prompts for and set the value of Twelf parameter PARM.
+Used in menus."
+ (let* ((argtype (cdr (assoc parm *twelf-parm-table*)))
+ (value (and argtype (twelf-read-value argtype))))
+ (if (null argtype)
+ (error "Unknown parameter")
+ (twelf-set parm value))))
+
+(defun track-parm (parm value)
+ "Tracks Twelf parameter values in Emacs."
+ (if (assoc parm *twelf-track-parms*)
+ (set (cdr (assoc parm *twelf-track-parms*)) value)))
+
+(defun twelf-toggle-double-check ()
+ "Toggles doubleCheck parameter of Twelf."
+ (let ((value (if (string-equal twelf-double-check "false")
+ "true" "false")))
+ (twelf-set "doubleCheck" value)))
+
+(defun twelf-toggle-print-implicit ()
+ "Toggles Print.implicit parameter of Twelf."
+ (let ((value (if (string-equal twelf-print-implicit "false")
+ "true" "false")))
+ (twelf-set "Print.implicit" value)))
+
+(defun twelf-get (parm)
+ "Prints the value of the Twelf parameter PARM.
+When called interactively, promts for parameter, supporting completion."
+ (interactive (list (completing-read "Parameter: " *twelf-parm-table* nil t)))
+ (twelf-server-send-command (concat "get " parm))
+ (twelf-server-wait)
+ (save-window-excursion
+ (let ((twelf-server-buffer (twelf-get-server-buffer)))
+ (set-buffer twelf-server-buffer)
+ (goto-char *twelf-server-last-process-mark*)
+ ;; We are now at the beginning of the output
+ (end-of-line 1)
+ (message (buffer-substring *twelf-server-last-process-mark* (point))))))
+
+(defun twelf-timers-reset ()
+ "Reset the Twelf timers."
+ (interactive)
+ (twelf-server-send-command "Timers.reset"))
+
+(defun twelf-timers-show ()
+ "Show and reset the Twelf timers."
+ (interactive)
+ (twelf-server-send-command "Timers.show")
+ (twelf-server-wait t))
+
+(defun twelf-timers-check ()
+ "Show the Twelf timers without resetting them."
+ (interactive)
+ (twelf-server-send-command "Timers.show")
+ (twelf-server-wait t))
+
+(defun twelf-server-restart ()
+ "Restarts server and re-initializes configuration.
+This is primarily useful during debugging of the Twelf server code or
+if the Twelf server is hopelessly wedged."
+ (interactive)
+ (twelf-server twelf-server-program)
+ (twelf-server-configure (if *twelf-config-buffer*
+ (buffer-file-name *twelf-config-buffer*)
+ "sources.cfg")
+ "Server configured, now checking...")
+ (twelf-check-config))
+
+;;;----------------------------------------------------------------------
+;;; Twelf Config minor mode
+;;;----------------------------------------------------------------------
+
+(defun twelf-config-mode (&optional prefix)
+ "Toggles minor mode for Twelf configuration files.
+This affects \\<twelf-mode-map>
+ twelf-server-configure (\\[twelf-server-configure])
+ twelf-save-check-config (\\[twelf-save-check-config])
+"
+ (interactive "P")
+ (make-local-variable 'twelf-config-mode)
+ (cond ((not (assq 'twelf-config-mode minor-mode-alist))
+ (setq minor-mode-alist
+ (cons '(twelf-config-mode " Config") minor-mode-alist))))
+ (cond ((or (not twelf-config-mode) prefix)
+ (setq twelf-config-mode t)
+ (run-hooks 'twelf-config-mode-hook))
+ (t (setq twelf-config-mode t))))
+
+(defun twelf-config-mode-check (&optional buffer)
+ "Switch on the Twelf Config minor mode if the ends in `.cfg'."
+ (if (string-match "\\.cfg$" (buffer-file-name (or buffer (current-buffer))))
+ (twelf-config-mode t)))
+
+;;;----------------------------------------------------------------------
+;;; Support for creating a TAGS file for current Twelf server configuration
+;;;----------------------------------------------------------------------
+
+(defun twelf-tag (&optional tags-filename)
+ "Create tags file for current configuration.
+If the current configuration is sources.cfg, the tags file is TAGS.
+If current configuration is named FILE.cfg, tags file will be named FILE.tag
+Errors are displayed in the Twelf server buffer.
+Optional argument TAGS-FILENAME specifies alternative filename."
+ (interactive)
+ (twelf-server-sync-config)
+ (let* ((error-buffer (twelf-get-server-buffer))
+ (config-filename (buffer-file-name *twelf-config-buffer*))
+ (tags-file
+ (or tags-filename
+ (if (string-equal "sources.cfg"
+ (file-name-nondirectory config-filename))
+ (concat (file-name-directory config-filename "TAGS"))
+ (concat (file-name-sans-extension config-filename)
+ ".tag")))))
+ (save-excursion
+ (set-buffer error-buffer)
+ (goto-char (point-max))
+ (insert "Tagging configuration " config-filename " in file " tags-file "\n"))
+ (set-buffer *twelf-config-buffer*)
+ (twelf-tag-files (rev-relativize *twelf-config-list* default-directory)
+ tags-file error-buffer)
+ (if (get-buffer-process error-buffer)
+ (set-marker (process-mark (get-buffer-process error-buffer))
+ (point-max)))))
+
+(defun twelf-tag-files (filelist &optional tags-filename error-buffer)
+ "Create tags file for FILELIST, routing errors to buffer *tags-errors*.
+Optional argument TAGS-FILENAME specifies alternative filename (default: TAGS),
+optional argument ERROR-BUFFER specifies alternative buffer for error message
+(default: *tags-errors*)."
+ (let* ((tags-filename (or tags-filename "TAGS"))
+ (tags-buffer (find-file-noselect tags-filename))
+ (error-buffer (or error-buffer (new-temp-buffer "*tags-errors*"))))
+ (save-excursion
+ (set-buffer tags-buffer)
+ (if (equal (point-min) (point-max))
+ nil
+ ;;(pop-to-buffer tags-buffer)
+ ;;(if (yes-or-no-p "Delete current tags information? ")
+ (delete-region (point-min) (point-max))
+ ;;)
+ ))
+ (switch-to-buffer-other-window error-buffer)
+ (while (not (null filelist))
+ (twelf-tag-file (car filelist) tags-buffer error-buffer)
+ (setq filelist (cdr filelist)))
+ (save-excursion
+ (set-buffer tags-buffer)
+ (save-buffer))))
+
+(defun twelf-tag-file (filename tags-buffer error-buffer)
+ "Deposit tag information for FILENAME in TAGS-BUFFER, errors in ERROR-BUFFER."
+ (let ((src-buffer (find-file-noselect filename))
+ file-start file-end end-of-id tag-string)
+ (save-excursion
+ (set-buffer tags-buffer)
+ (goto-char (point-max))
+ (insert "\f\n" filename ",0\n")
+ (setq file-start (point))
+ (save-excursion
+ (set-buffer src-buffer)
+ (goto-char (point-min))
+ (while (twelf-next-decl filename error-buffer)
+ (setq end-of-id (point))
+ (beginning-of-line 1)
+ (setq tag-string
+ (concat (buffer-substring (point) end-of-id)
+ "\C-?" (current-line-absolute) "," (point) "\n"))
+ (goto-char end-of-id)
+ (if (not (twelf-end-of-par))
+ (let ((error-line (current-line-absolute)))
+ (save-excursion
+ (set-buffer error-buffer)
+ (goto-char (point-max))
+ (insert filename ":" (int-to-string error-line)
+ " Warning: missing period\n"))))
+ (save-excursion
+ (set-buffer tags-buffer)
+ (insert tag-string))))
+ (setq file-end (point-max))
+ (goto-char (- file-start 2))
+ (delete-char 1)
+ (insert (int-to-string (- file-end file-start)))
+ (goto-char (point-max)))))
+
+(defun twelf-next-decl (filename error-buffer)
+ "Set point after the identifier of the next declaration.
+Return the declared identifier or `nil' if none was found.
+FILENAME and ERROR-BUFFER are used if something appears wrong."
+ (let ((id nil)
+ end-of-id
+ beg-of-id)
+ (skip-twelf-comments-and-whitespace)
+ (while (and (not id) (not (eobp)))
+ (setq beg-of-id (point))
+ (if (zerop (skip-chars-forward *twelf-id-chars*))
+ ;; Not looking at id: skip ahead
+ (skip-ahead filename (current-line-absolute) "No identifier"
+ error-buffer)
+ (setq end-of-id (point))
+ (skip-twelf-comments-and-whitespace)
+ (if (not (looking-at ":"))
+ ;; Not looking at valid decl: skip ahead
+ (skip-ahead filename (current-line-absolute end-of-id) "No colon"
+ error-buffer)
+ (goto-char end-of-id)
+ (setq id (buffer-substring beg-of-id end-of-id))))
+ (skip-twelf-comments-and-whitespace))
+ id))
+
+(defun skip-ahead (filename line message error-buffer)
+ "Skip ahead when syntactic error was found.
+A parsable error message constited from FILENAME, LINE, and MESSAGE is
+deposited in ERROR-BUFFER."
+ (if error-buffer
+ (save-excursion
+ (set-buffer error-buffer)
+ (goto-char (point-max))
+ (insert filename ":" (int-to-string line) " Warning: " message "\n")
+ (setq *twelf-error-pos* (point))))
+ (twelf-end-of-par))
+
+(defun current-line-absolute (&optional char-pos)
+ "Return line number of CHAR-POS (default: point) in current buffer.
+Ignores any possible buffer restrictions."
+ (1+ (count-lines 1 (or char-pos (point)))))
+
+(defun new-temp-buffer (&optional name)
+ "Create or delete contents of buffer named \"*temp*\" and return it.
+Optional argument NAME specified an alternative name."
+ (if (not name) (setq name "*temp*"))
+ (if (get-buffer name)
+ (save-excursion
+ (set-buffer name)
+ (delete-region (point-min) (point-max))
+ (get-buffer name))
+ (get-buffer-create name)))
+
+(defun rev-relativize (filelist dir)
+ "Reverse and relativize FILELIST with respect to DIR."
+ (let ((newlist nil))
+ (while (not (null filelist))
+ (setq newlist
+ (cons (file-relative-name (car filelist) dir) newlist))
+ (setq filelist (cdr filelist)))
+ newlist))
+
+
+;;;----------------------------------------------------------------------
+;;; Twelf-SML mode
+;;;----------------------------------------------------------------------
+
+(defvar twelf-sml-mode-map nil
+ "The keymap used in Twelf-SML mode.")
+
+(cond ((not twelf-sml-mode-map)
+ ;;(setq twelf-sml-mode-map (full-copy-sparse-keymap comint-mode-map))
+ ;; fixed for Emacs 19.25. -fp Thu Oct 27 09:08:44 1994
+ (setq twelf-sml-mode-map (copy-keymap comint-mode-map))
+ (install-basic-twelf-keybindings twelf-sml-mode-map)
+ ))
+
+(defconst twelf-sml-prompt-regexp "^\\- \\|^\\?\\- ")
+
+(defun expand-dir (dir)
+ "Expand argument and check that it is a directory."
+ (let ((expanded-dir (file-name-as-directory (expand-file-name dir))))
+ (if (not (file-directory-p expanded-dir))
+ (error "%s is not a directory" dir))
+ expanded-dir))
+
+(defun twelf-sml-cd (dir)
+ "Make DIR become the Twelf-SML process' buffer's default directory and
+furthermore issue an appropriate command to the inferior Twelf-SML process."
+ (interactive "DChange default directory: ")
+ (let ((expanded-dir (expand-dir dir)))
+ (save-excursion
+ (set-buffer (twelf-sml-process-buffer))
+ (setq default-directory expanded-dir)
+ (comint-simple-send (twelf-sml-process) (concat "Twelf.OS.chDir \"" expanded-dir "\";")))
+ ;;(pwd)
+ ))
+
+(defconst twelf-sml-cd-regexp "^\\s *cd\\s *\"\\([^\"]*\\)\""
+ "Regular expression used to match cd commands in Twelf-SML buffer.")
+
+(defun twelf-sml-directory-tracker (input)
+ "Checks input for cd commands and changes default directory in buffer.
+As a side-effect, it sets *twelf-last-region-sent* to NIL to indicate interactive
+input. As a second side-effect, it resets the *twelf-error-pos*.
+Used as comint-input-sentinel in Twelf-SML buffer."
+ (if (twelf-input-filter input)
+ (setq *twelf-last-region-sent* nil))
+ (setq *twelf-last-input-buffer* (current-buffer))
+ (setq *twelf-error-pos* (marker-position (process-mark (twelf-sml-process))))
+ (cond ((string-match twelf-sml-cd-regexp input)
+ (let ((expanded-dir (expand-dir (substring input
+ (match-beginning 1)
+ (match-end 1)))))
+ (setq default-directory expanded-dir)
+ (pwd)))))
+
+(defun twelf-sml-mode ()
+ "Major mode for interacting with an inferior Twelf-SML process.
+
+The following commands are available:
+\\{twelf-sml-mode-map}
+
+An Twelf-SML process can be started with \\[twelf-sml].
+
+Customisation: Entry to this mode runs the hooks on twelf-sml-mode-hook.
+
+You can send queries to the inferior Twelf-SML process from other buffers.
+
+Commands:
+Return after the end of the process' output sends the text from the
+ end of process to point.
+Return before the end of the process' output copies the current line
+ to the end of the process' output, and sends it.
+Delete converts tabs to spaces as it moves back.
+Tab indents for Twelf; with argument, shifts rest
+ of expression rigidly with the current line.
+C-M-q does Tab on each line starting within following expression.
+Paragraphs are separated only by blank lines. % start single comments,
+delimited comments are enclosed in %{...}%.
+If you accidentally suspend your process, use \\[comint-continue-subjob]
+to continue it."
+ (interactive)
+ (kill-all-local-variables)
+ (comint-mode)
+ (setq comint-prompt-regexp twelf-sml-prompt-regexp)
+ (setq comint-input-filter 'twelf-input-filter)
+ ;; changed for XEmacs 19.16 Sat Jun 13 11:28:53 1998
+ (add-hook 'comint-input-filter-functions 'twelf-sml-directory-tracker
+ nil t)
+ (twelf-mode-variables)
+
+ ;; For sequencing through error messages:
+ (make-local-variable '*twelf-error-pos*)
+ (setq *twelf-error-pos* (point-max))
+ ;; Workaround for problem with Lucid Emacs version of comint.el:
+ ;; must exclude double quotes " and must include $ and # in filenames.
+ (make-local-variable 'comint-match-partial-pathname-chars)
+ (setq comint-match-partial-pathname-chars
+ "^][<>{}()!^&*\\|?`'\" \t\n\r\b")
+
+ (setq major-mode 'twelf-sml-mode)
+ (setq mode-name "Twelf-SML")
+ (setq mode-line-process '(": %s"))
+ (use-local-map twelf-sml-mode-map)
+
+ (run-hooks 'twelf-sml-mode-hook))
+
+(defun twelf-sml (&optional cmd)
+ "Run an inferior Twelf-SML process in a buffer *twelf-sml*.
+If there is a process already running in *twelf-sml*, just
+switch to that buffer. With argument, allows you to change the program
+which defaults to the value of twelf-sml-program. Runs the hooks from
+twelf-sml-mode-hook (after the comint-mode-hook is run).
+
+Type \\[describe-mode] in the process buffer for a list of commands."
+ (interactive (list (and current-prefix-arg
+ (read-string "Run Twelf-SML: " twelf-sml-program))))
+ (let ((cmd (or cmd twelf-sml-program)))
+ (cond ((not (comint-check-proc (twelf-sml-process-buffer)))
+ ;; process does not already exist
+ (set-buffer (apply 'make-comint "twelf-sml" cmd nil twelf-sml-args))
+ ;; in case we are using SML mode (for error tracking)
+ (if (boundp 'sml-buffer)
+ (set 'sml-buffer (twelf-sml-process-buffer)))
+ (twelf-sml-mode))))
+ (switch-to-buffer (twelf-sml-process-buffer)))
+
+(defun switch-to-twelf-sml (eob-p)
+ "Switch to the Twelf-SML process buffer.
+With argument, positions cursor at end of buffer."
+ (interactive "P")
+ (if (twelf-sml-process-buffer)
+ (pop-to-buffer (twelf-sml-process-buffer))
+ (error "No current process buffer. "))
+ (cond (eob-p
+ (push-mark)
+ (goto-char (point-max)))))
+
+(defun display-twelf-sml-buffer (&optional buffer)
+ "Display the Twelf-SML buffer so that the end of output is visible."
+ ;; Accept output from Twelf-SML process
+ (sit-for 1)
+ (let* ((twelf-sml-buffer (if (null buffer) (twelf-sml-process-buffer)
+ buffer))
+ (_ (set-buffer twelf-sml-buffer))
+ (twelf-sml-process (twelf-sml-process))
+ (proc-mark (process-mark twelf-sml-process))
+ (_ (display-buffer twelf-sml-buffer))
+ (twelf-sml-window (get-buffer-window twelf-sml-buffer)))
+ (if (not (pos-visible-in-window-p proc-mark twelf-sml-window))
+ (progn
+ (push-mark proc-mark)
+ (set-window-point twelf-sml-window proc-mark)))))
+
+(defun twelf-sml-send-string (string)
+ "Send the given string to the Twelf-SML process."
+ (setq *twelf-last-input-buffer* (twelf-sml-process-buffer))
+ (comint-send-string (twelf-sml-process) string))
+
+(defun twelf-sml-send-region (start end &optional and-go)
+ "Send the current region to the inferior Twelf-SML process.
+Prefix argument means switch-to-twelf-sml afterwards.
+If the region is short, it is sent directly, via COMINT-SEND-REGION."
+ (interactive "r\nP")
+ (if (> start end)
+ (twelf-sml-send-region end start and-go)
+ ;; (setq twelf-sml-last-region-sent (list (current-buffer) start end))
+ (let ((cur-buffer (current-buffer))
+ (twelf-sml-buffer (twelf-sml-process-buffer)))
+ (switch-to-buffer twelf-sml-buffer)
+ ;; (setq sml-error-pos (marker-position (process-mark (twelf-sml-process))))
+ (setq *twelf-last-input-buffer* twelf-sml-buffer)
+ (switch-to-buffer cur-buffer))
+ (comint-send-region (twelf-sml-process) start end)
+ (if (not (string= (buffer-substring (1- end) end) "\n"))
+ (comint-send-string (twelf-sml-process) "\n"))
+ ;; Next two lines mess up when an Twelf error occurs, since the
+ ;; newline is not read and later messes up counting.
+ ;; (if (not and-go)
+ ;; (comint-send-string (twelf-sml-process) "\n"))
+ (if and-go (switch-to-twelf-sml t)
+ (if twelf-sml-display-queries (display-twelf-sml-buffer)))))
+
+(defun twelf-sml-send-query (&optional and-go)
+ "Send the current declaration to the inferior Twelf-SML process as a query.
+Prefix argument means switch-to-twelf-sml afterwards."
+ (interactive "P")
+ (let* ((par (twelf-current-decl))
+ (query-start (nth 0 par))
+ (query-end (nth 1 par)))
+ (twelf-sml-set-mode 'TWELF)
+ (twelf-sml-send-region query-start query-end and-go)))
+
+(defun twelf-sml-send-newline (&optional and-go)
+ "Send a newline to the inferior Twelf-SML process.
+If a prefix argument is given, switches to Twelf-SML buffer afterwards."
+ (interactive "P")
+ (twelf-sml-send-string "\n")
+ (if and-go (switch-to-twelf-sml t)
+ (if twelf-sml-display-queries (display-twelf-sml-buffer))))
+
+(defun twelf-sml-send-semicolon (&optional and-go)
+ "Send a semi-colon to the inferior Twelf-SML process.
+If a prefix argument is given, switched to Twelf-SML buffer afterwards."
+ (interactive "P")
+ (twelf-sml-send-string ";\n")
+ (if and-go (switch-to-twelf-sml t)
+ (if twelf-sml-display-queries (display-twelf-sml-buffer))))
+
+(defun twelf-sml-status (&optional buffer)
+ "Returns the status of the Twelf-SML process.
+This employs a heuristic, looking at the contents of the Twelf-SML buffer.
+Results:
+ NONE --- no process
+ ML --- ML top level
+ TWELF --- Twelf top level
+ MORE --- asking whether to find the next solution
+ UNKNOWN --- process is running, but can't tell status."
+ (let* ((twelf-sml-buffer (or buffer (twelf-sml-process-buffer)))
+ (twelf-sml-process (get-buffer-process twelf-sml-buffer)))
+ (if (null twelf-sml-process)
+ 'NONE
+ (save-excursion
+ (set-buffer twelf-sml-buffer)
+ (let ((buffer-end (buffer-substring (max (point-min) (- (point-max) 3))
+ (point-max))))
+ (cond ((string-match "\\?- " buffer-end) 'TWELF)
+ ((string-match "\n- " buffer-end) 'ML)
+ ((string-match "More\\? " buffer-end) 'MORE)
+ (t 'UNKNOWN)))))))
+
+(defvar twelf-sml-init "Twelf.Config.load (Twelf.Config.read \"sources.cfg\");\n"
+ "Initial command sent to Twelf-SML process when started during twelf-sml-set-mode 'TWELF.")
+
+(defun twelf-sml-set-mode (mode &optional buffer)
+ "Attempts to read and if necessary correct the mode of the Twelf-SML buffer.
+This does not check if the status has been achieved. It returns NIL
+if the status is unknown and T if it believes the status should have
+been achieved. This allows for asynchronous operation."
+ (cond
+ ((eq mode 'ML)
+ (let ((status (twelf-sml-status)))
+ (cond ((eq status 'NONE) (twelf-sml) 't)
+ ((eq status 'ML) 't)
+ ((eq status 'TWELF) (twelf-sml-send-string "") 't)
+ ((eq status 'MORE) (twelf-sml-send-string "q\n") 't)
+ ((eq status 'UNKNOWN) nil))))
+ ((eq mode 'TWELF)
+ (let ((status (twelf-sml-status)))
+ (cond ((eq status 'NONE)
+ (twelf-sml)
+ (twelf-sml-send-string twelf-sml-init)
+ (twelf-sml-send-string "Twelf.top ();\n") 't)
+ ((eq status 'ML)
+ (twelf-sml-send-string "Twelf.top ();\n") 't)
+ ((eq status 'TWELF) 't)
+ ((eq status 'MORE) (twelf-sml-send-string "\n") 't)
+ ((eq status 'UNKNOWN) nil))))
+ (t (error "twelf-sml-set-mode: illegal mode %s" mode))))
+
+(defun twelf-sml-quit ()
+ "Kill the Twelf-SML process."
+ (interactive)
+ (kill-process (twelf-sml-process)))
+
+(defun twelf-sml-process-buffer ()
+ "Returns the current Twelf-SML process buffer."
+ (get-buffer "*twelf-sml*"))
+
+(defun twelf-sml-process (&optional buffer)
+ "Returns the current Twelf-SML process."
+ (let ((proc (get-buffer-process (or buffer (twelf-sml-process-buffer)))))
+ (or proc
+ (error "No current process."))))
+
+;;;----------------------------------------------------------------------
+;;; 2Twelf-SML minor mode for Twelf
+;;; Some keybindings now refer to Twelf-SML instead of the Twelf server.
+;;; Toggle with twelf-to-twelf-sml-mode
+;;;----------------------------------------------------------------------
+
+(defvar twelf-to-twelf-sml-mode nil
+ "Non-NIL means the minor mode is in effect.")
+
+(defun install-twelf-to-twelf-sml-keybindings (map)
+ ;; Process commands:
+ (define-key map "\C-c\C-r" 'twelf-sml-send-region)
+ (define-key map "\C-c\C-e" 'twelf-sml-send-query)
+ (define-key map "\C-c\C-m" 'twelf-sml-send-newline)
+ (define-key map "\C-c\n" 'twelf-sml-send-newline)
+ (define-key map "\C-c;" 'twelf-sml-send-semicolon)
+ (define-key map "\C-cd" 'twelf-sml-cd)
+ )
+
+(defvar twelf-to-twelf-sml-mode-map nil
+ "Keymap for twelf-to-twelf-sml minor mode.")
+
+(cond ((not twelf-to-twelf-sml-mode-map)
+ (setq twelf-to-twelf-sml-mode-map (make-sparse-keymap))
+ (install-basic-twelf-keybindings twelf-to-twelf-sml-mode-map)
+ (install-twelf-keybindings twelf-to-twelf-sml-mode-map)
+ ;; The next line shadows certain bindings to refer to
+ ;; Twelf-SML instead of the Twelf server.
+ (install-twelf-to-twelf-sml-keybindings twelf-to-twelf-sml-mode-map)))
+
+(defun twelf-to-twelf-sml-mode (&optional prefix)
+ "Toggles minor mode for sending queries to Twelf-SML instead of Twelf server.
+Specifically: \\<twelf-to-twelf-sml-mode-map>
+ \\[twelf-sml-send-query] (for sending queries),
+ \\[twelf-sml-send-newline] (for sending newlines) and
+ \\[twelf-sml-send-semicolon] (for sending `;')
+are rebound.
+
+Mode map
+========
+\\{twelf-to-twelf-sml-mode-map}
+"
+ (interactive "P")
+ (make-local-variable 'twelf-to-twelf-sml-mode)
+ (cond ((not (assq 'twelf-to-twelf-sml-mode minor-mode-alist))
+ (setq minor-mode-alist
+ (cons '(twelf-to-twelf-sml-mode " 2Twelf-SML")
+ minor-mode-alist))))
+ (cond ((or (not twelf-to-twelf-sml-mode) prefix)
+ (setq twelf-to-twelf-sml-mode t)
+ (use-local-map twelf-to-twelf-sml-mode-map)
+ (run-hooks 'twelf-to-twelf-sml-mode-hook))
+ (t
+ (setq twelf-to-twelf-sml-mode nil)
+ (use-local-map twelf-mode-map))))
+
+;;;----------------------------------------------------------------------
+;;; Twelf mode menus
+;;; requires auc-menu utilities
+;;;----------------------------------------------------------------------
+
+(cond
+ ((string-match "XEmacs" emacs-version) ;; XEmacs nee Lucid Emacs
+ (defun radio (label callback condition)
+ (vector label callback ':style 'radio ':selected condition))
+ (defun toggle (label callback condition)
+ (vector label callback ':style 'toggle ':selected condition))
+ (defun disable-form (label callback condition)
+ (vector label callback condition))
+ )
+ (t ;; FSF Emacs 19
+ (defun radio (label callback condition)
+ (vector label callback t))
+ (defun toggle (label callback condition)
+ (vector label callback t))
+ (defun disable-form (label callback condition)
+ (cond ((symbolp condition) (vector label callback condition))
+ (t (vector label callback t))))
+ ))
+
+(defconst twelf-at-point-menu
+ '("At Point"
+ ["Constant" twelf-type-const t]
+ ;["Type" twelf-type-at-point nil] ;disabled for Twelf 1.2
+ ;["Expected Type" twelf-expected-type-at-point nil] ;disabled
+ ;["List Completions" twelf-completions-at-point nil] ;disabled
+ ;["Complete" twelf-complete nil] ;disabled
+ )
+ "Menu for commands applying at point.")
+
+(defconst twelf-server-state-menu
+ '("Server State"
+ ["Configure" twelf-server-configure t]
+ ["Interrupt" twelf-server-interrupt t]
+ ["Reset" twelf-reset t]
+ ["Start" twelf-server t]
+ ["Restart" twelf-server-restart t]
+ ["Quit" twelf-server-quit t])
+ "Menu for commands affecting server state.")
+
+(defconst twelf-error-menu
+ '("Error Tracking"
+ ["Next" twelf-next-error t]
+ ["Goto" twelf-goto-error t])
+ "Menu for error commands.")
+
+(defconst twelf-tags-menu
+ '("Tags"
+ ["Find" find-tag t]
+ ["Find Other Window" find-tag-other-window t]
+ ["Query Replace" tags-query-replace t]
+ ["Search" tags-search t]
+ ["Continue" tags-loop-continue t]
+ ["Create/Update" twelf-tag t])
+ "Menu for tag commands.")
+
+(defun twelf-toggle-server-display-commands ()
+ (setq twelf-server-display-commands (not twelf-server-display-commands)))
+
+(defconst twelf-options-menu
+ (` ("Options"
+ (, (toggle "Display Commands" '(twelf-toggle-server-display-commands)
+ 'twelf-server-display-commands))
+ ("chatter"
+ (, (radio "0" '(twelf-set "chatter" 0) '(= twelf-chatter 0)))
+ (, (radio "1" '(twelf-set "chatter" 1) '(= twelf-chatter 1)))
+ (, (radio "2" '(twelf-set "chatter" 2) '(= twelf-chatter 2)))
+ (, (radio "3*" '(twelf-set "chatter" 3) '(= twelf-chatter 3)))
+ (, (radio "4" '(twelf-set "chatter" 4) '(= twelf-chatter 4)))
+ (, (radio "5" '(twelf-set "chatter" 5) '(= twelf-chatter 5)))
+ (, (radio "6" '(twelf-set "chatter" 6) '(= twelf-chatter 6))))
+ (, (toggle "doubleCheck" '(twelf-toggle-double-check)
+ '(string-equal twelf-double-check "true")))
+ ("Print."
+ (, (toggle "implicit" '(twelf-toggle-print-implicit)
+ '(string-equal twelf-print-implicit "true")))
+ ["depth" (twelf-set-parm "Print.depth") t]
+ ["length" (twelf-set-parm "Print.length") t]
+ ["indent" (twelf-set-parm "Print.indent") t]
+ ["width" (twelf-set-parm "Print.width") t])
+ ("Prover."
+ ["strategy" (twelf-set-parm "Prover.strategy") t]
+ ["maxSplit" (twelf-set-parm "Prover.maxSplit") t]
+ ["maxRecurse" (twelf-set-parm "Prover.maxRecurse") t])
+ ;;["Trace" nil nil]
+ ;; (, (radio "0" '(twelf-set "trace" 0) '(= twelf-trace 0)))
+ ;; (, (radio "1" '(twelf-set "trace 1) '(= twelf-trace 1)))
+ ;; (, (radio "2" '(twelf-set "trace" 2) '(= twelf-trace 2))))
+ ;;["Untrace" nil nil]
+ ;;(, (disable-form "Untrace" '(twelf-set "trace" 0)
+ ;; '(not (= twelf-trace 0))))
+ ["Reset Menubar" twelf-reset-menu t]))
+ "Menu to change options in Twelf mode.")
+
+(defconst twelf-timers-menu
+ '("Timing"
+ ["Show and Reset" twelf-timers-show t]
+ ["Check" twelf-timers-check t]
+ ["Reset" twelf-timers-reset t]))
+
+;(autoload 'toggle-twelf-font-immediate "twelf-font"
+; "Toggle experimental immediate highlighting in font-lock mode.")
+(autoload 'twelf-font-fontify-decl "twelf-font"
+ "Fontify current declaration using font-lock minor mode.")
+(autoload 'twelf-font-fontify-buffer "twelf-font"
+ "Fontify current buffer using font-lock minor mode.")
+
+(defconst twelf-syntax-menu
+ (` ("Syntax Highlighting"
+ ["Highlight Declaration" twelf-font-fontify-decl t]
+ ["Highlight Buffer" twelf-font-fontify-buffer t]
+ ;(, (toggle "Immediate Highlighting" 'toggle-twelf-font-immediate
+ ;'font-lock-mode))
+ ))
+ "Menu for syntax highlighting in Twelf mode.")
+
+(easy-menu-define twelf-menu (list twelf-mode-map)
+ "Menu for Twelf mode.
+This may be selected from the menubar. In XEmacs, also bound to Button3."
+ (list
+ "Twelf"
+ ["Display Server" twelf-server-display t]
+ ["Check Configuration" twelf-save-check-config t]
+ ["Check File" twelf-save-check-file t]
+ ["Check Declaration" twelf-check-declaration t]
+ twelf-at-point-menu
+ twelf-error-menu
+ twelf-options-menu
+ twelf-syntax-menu
+ twelf-tags-menu
+ twelf-timers-menu
+ twelf-server-state-menu
+ ["Info" twelf-info t]))
+
+(defun twelf-add-menu ()
+ "Add Twelf menu to menubar."
+ (easy-menu-add twelf-menu twelf-mode-map))
+
+(defun twelf-remove-menu ()
+ "Remove Twelf menu from menubar."
+ (easy-menu-remove twelf-menu))
+
+(defun twelf-reset-menu ()
+ "Reset Twelf menu."
+ (twelf-remove-menu)
+ (twelf-add-menu))
+
+;;;----------------------------------------------------------------------
+;;; Twelf Server mode menu
+;;;----------------------------------------------------------------------
+
+(easy-menu-define twelf-server-menu (list twelf-server-mode-map)
+ "Menu for Twelf Server mode.
+This may be selected from the menubar. In XEmacs, also bound to Button3."
+ (list
+ "Twelf-Server"
+ ;; ["Display Server" twelf-server-display t]
+ ["Check Configuration" twelf-save-check-config t]
+ ;; ["Check File" twelf-save-check-file nil]
+ ;; ["Check Declaration" twelf-check-declaration nil]
+ ;; ["Check Query" twelf-check-query nil]
+ ;; ["Solve Query" twelf-solve-query nil]
+ ;; ["At Point" () nil]
+ twelf-error-menu
+ twelf-options-menu
+ twelf-tags-menu
+ twelf-server-state-menu
+ ["Info" twelf-info t]))
+
+(defun twelf-server-add-menu ()
+ "Add Twelf menu to menubar."
+ (easy-menu-add twelf-server-menu twelf-server-mode-map))
+
+(defun twelf-server-remove-menu ()
+ "Remove Twelf menu from menubar."
+ (easy-menu-remove twelf-server-menu))
+
+(defun twelf-server-reset-menu ()
+ "Reset Twelf menu."
+ (twelf-server-remove-menu)
+ (twelf-server-add-menu))
+
+(provide 'twelf-old)
+
diff --git a/twelf/twelf.el b/twelf/twelf.el
new file mode 100644
index 00000000..5d712bb5
--- /dev/null
+++ b/twelf/twelf.el
@@ -0,0 +1,208 @@
+;; twelf.el Proof General instance for Twelf
+;;
+;; Copyright (C) 2000 LFCS Edinburgh.
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id$
+;;
+;;
+;; TODO before 3.2:
+;; Info doc menu entry
+;; X-Symbol upgrade/test? Mule XE better?
+;;
+
+
+(require 'proof-easy-config) ; easy configure mechanism
+
+(require 'twelf-font) ; font lock configuration
+;; (require 'twelf-old)
+;; FIXME: put parts of old code into twelf-syntax or similar
+
+;;
+;; User configuration settings for Twelf PG
+;;
+(defcustom twelf-root-dir
+ "/usr/local/twelf/"
+ "*Root of twelf installation. Default /usr/local/twelf suits RPM package."
+ :type 'file
+ :group 'twelf)
+
+(defcustom twelf-info-dir
+ (concat twelf-root-dir "doc/info/")
+ "*Directory of Twelf Infor files."
+ :type 'file
+ :group 'twelf)
+
+;;
+;; Instantiation of Proof General
+;;
+(proof-easy-config 'twelf "Twelf"
+ proof-prog-name "twelf-server"
+ proof-assistant-home-page "http://www.cs.cmu.edu/~twelf/"
+
+ proof-script-use-new-parser t ;; FIXME: remove for PG 3.3
+ proof-terminal-char ?\.
+ proof-comment-start "%" ;; for inserting comments
+ proof-comment-end ""
+ proof-comment-start-regexp "%[%{ \t\n\f]" ;; recognizing
+ proof-comment-end-regexp "%}\\|\n" ;; comments
+
+ proof-shell-auto-terminate-commands nil ; server commands don't end with .
+ proof-shell-strip-crs-from-input nil ; server needs CRs with readDecl
+
+ proof-auto-multiple-files t
+ proof-shell-cd-cmd "OS.chDir %s"
+ proof-shell-prompt-pattern "%% OK %%\n"
+ proof-shell-interrupt-regexp "interrupt"
+
+ proof-shell-annotated-prompt-regexp "%% [OA][KB]O?R?T? %%\n"
+ proof-shell-error-regexp "Server error:"
+ proof-shell-quit-cmd "quit"
+ proof-shell-restart-cmd "reset"
+
+ ;; "Eager annotations" mark messages Proof General should display
+ ;; or recognize while the prover is pontificating
+ proof-shell-eager-annotation-start
+ "^\\[Opening \\|\\[Closing "
+ proof-shell-eager-annotation-end "\n")
+
+
+;; unset: all of the interactive proof commands
+;; These don't really apply, I don't think, because Twelf
+;; only has fully automatic prover at the moment.
+;; Also, there is no concept of "undo" to remove declarations
+;; (can simply repeat them, tho.)
+;; proof-goal-command-regexp "^%theorem"
+;; proof-save-command-regexp "" ;; FIXME: empty?
+;; proof-goal-with-hole-regexp "^%theorem\w-+\\(.*\\)\w-+:"
+;; proof-save-with-hole-regexp "" ;; FIXME
+;; proof-non-undoables-regexp
+;; proof-goal-command "%theorem %s."
+;; proof-save-command "%prove "
+;; remaining strings are left over from Isabelle example
+;; proof-kill-goal-command "Goal \"PROP no_goal_set\";"
+;; proof-showproof-command "pr()"
+;; proof-undo-n-times-cmd "pg_repeat undo %s;"
+;; proof-shell-start-goals-regexp "Level [0-9]"
+;; proof-shell-end-goals-regexp "val it"
+;; proof-shell-init-cmd
+;; proof-shell-proof-completed-regexp "^No subgoals!"
+
+
+;;
+;; Twelf server doesn't take declarations directly:
+;; we need to pre-process script input slightly
+;;
+
+(defun twelf-add-read-declaration ()
+ "A hook value for `proof-shell-insert-hook'."
+ (if (eq action 'proof-done-advancing)
+ (setq string (concat "readDecl\n" string))))
+
+(add-hook 'proof-shell-insert-hook 'twelf-add-read-declaration)
+
+
+;;
+;; Syntax table
+;;
+
+;; Taken from old Emacs mode, renamed fns to be convention compliant
+(defun twelf-set-syntax (char entry)
+ (modify-syntax-entry char entry twelf-mode-syntax-table))
+(defun twelf-set-word (char) (twelf-set-syntax char "w "))
+(defun twelf-set-symbol (char) (twelf-set-syntax char "_ "))
+
+(defun twelf-map-string (func string)
+ (if (string= "" string)
+ ()
+ (funcall func (string-to-char string))
+ (twelf-map-string func (substring string 1))))
+
+;; A-Z and a-z are already word constituents
+;; For fontification, it would be better if _ and ' were word constituents
+(twelf-map-string
+ 'twelf-set-word "!&$^+/<=>?@~|#*`;,-0123456789\\") ; word constituents
+(twelf-map-string 'twelf-set-symbol "_'") ; symbol constituents
+;; Delimited comments are %{ }%, see 1234 below.
+(twelf-set-syntax ?\ " ") ; whitespace
+(twelf-set-syntax ?\t " ") ; whitespace
+; da: this old entry is wrong: it says % always starts a comment
+;(twelf-set-syntax ?% "< 14") ; comment begin
+; This next one is much better,
+(twelf-set-syntax ?% ". 14") ; comment begin/second char
+(twelf-set-syntax ?\n "> ") ; comment end
+(twelf-set-syntax ?: ". ") ; punctuation
+(twelf-set-syntax ?. ". ") ; punctuation
+(twelf-set-syntax ?\( "() ") ; open delimiter
+(twelf-set-syntax ?\) ")( ") ; close delimiter
+(twelf-set-syntax ?\[ "(] ") ; open delimiter
+(twelf-set-syntax ?\] ")[ ") ; close delimiter
+;(twelf-set-syntax ?\{ "(}2 ") ; open delimiter
+;(twelf-set-syntax ?\} "){ 3") ; close delimiter
+;; Actually, strings are illegal but we include:
+(twelf-set-syntax ?\" "\" ") ; string quote
+;; \ is not an escape, but a word constituent (see above)
+;;(twelf-set-syntax ?\\ "/ ") ; escape
+
+
+
+;;
+;; Syntax highlighting (from twelf-old.el, NEEDS WORK)
+;;
+;; Highlighting is maybe a nuisance for twelf because of its funny syntax.
+;; But font lock could perhaps be got to work with recent versions.
+;; That would be better than the present mechanism, which doesn't lock,
+;; doesn't work well with X Symbol (which really needs locking), and
+;; even breaks the background colouring for some reason (presumably
+;; the Twelf faces)
+
+(require 'twelf-font)
+(add-hook 'twelf-mode-hook 'twelf-mode-extra-config)
+
+(defun twelf-mode-extra-config ()
+ (make-local-hook 'font-lock-after-fontify-buffer-hook)
+ (add-hook 'font-lock-after-fontify-buffer-hook
+ 'twelf-font-fontify-buffer nil 'local)
+ (font-lock-mode))
+
+(defconst twelf-syntax-menu
+ '("Syntax Highlighting"
+ ["Highlight Declaration" twelf-font-fontify-decl t]
+ ["Highlight Buffer" twelf-font-fontify-buffer t]
+ ;;(, (toggle "Immediate Highlighting" 'toggle-twelf-font-immediate
+ ;;'font-lock-mode))
+ )
+ "Menu for syntax highlighting in Twelf mode.")
+
+
+;;
+;; Setting Twelf options via Proof General
+;;
+
+(defpacustom chatter 1
+ "Value for chatter."
+ :type 'integer
+ :setting "set chatter %i")
+
+(defpacustom double-check nil
+ "Double-check declarations after type reconstruction."
+ :type 'boolean
+ :setting "set doubleCheck %b")
+(defpacustom print-implicit nil
+ "Show implicit arguments."
+ :type 'boolean
+ :setting "set Print.implict %b")
+
+;; etc
+
+
+;;
+;; Twelf menu
+;;
+
+(defpgdefault menu-entries
+ (cdr twelf-syntax-menu))
+
+
+(provide 'twelf) \ No newline at end of file
diff --git a/twelf/x-symbol-twelf.el b/twelf/x-symbol-twelf.el
new file mode 100644
index 00000000..58f3fa08
--- /dev/null
+++ b/twelf/x-symbol-twelf.el
@@ -0,0 +1,87 @@
+;; x-symbol-twelf.el
+;;
+;; David Aspinall, adapted from file supplied by David von Obheimb
+;;
+;; $Id$
+;;
+
+(defvar x-symbol-twelf-symbol-table
+ '((arrowright () "->" "\\<rightarrow>")
+ (longarrowright () "0->" "\\<longrightarrow>")
+ (longarrowdblright () "==>" "\\<Longrightarrow>")
+ (logicaland () "/\\" "\\<and>")
+ (logicalor () "\\/" "\\<or>")
+ (equivalence () "<->" "\\<equiv>")
+ (existential1 () "EX" "\\<exists>")
+ (universal1 () "ALL" "\\<forall>")
+ (bardash () "|-" "\\<turnstile>")
+ ;; some naughty ones, but probably what you'd like
+ ;; (a mess in words like "searching" "philosophy" etc!!)
+ (Gamma () "Gamma" "\\<Gamma>")
+ (Delta () "Delta" "\\<Delta>")
+ (Theta () "Theta" "\\<Theta>")
+ (Lambda () "Lambda" "\\<Lambda>")
+ (Pi () "Pi" "\\<Pi>")
+ (Sigma () "Sigma" "\\<Sigma>")
+ (Phi () "Phi" "\\<Phi>")
+ (Psi () "Psi" "\\<Psi>")
+ (Omega () "Omega" "\\<Omega>")
+ (alpha () "alpha" "\\<alpha>")
+ (beta () "beta" "\\<beta>")
+ (gamma () "gamma" "\\<gamma>")
+ (delta () "delta" "\\<delta>")
+ (epsilon1 () "epsilon" "\\<epsilon>")
+ (zeta () "zeta" "\\<zeta>")
+ (eta () "eta" "\\<eta>")
+ (theta1 () "theta" "\\<theta>")
+ (kappa1 () "kappa" "\\<kappa>")
+ (lambda () "lambda" "\\<lambda>")
+; (mu () "mu" "\\<mu>")
+; (nu () "nu" "\\<nu>")
+; (xi () "xi" "\\<xi>")
+; (pi () "pi" "\\<pi>")
+ (rho () "rho" "\\<rho>")
+ (sigma () "sigma" "\\<sigma>")
+ (tau () "tau" "\\<tau>")
+ (phi1 () "phi" "\\<phi>")
+; (chi () "chi" "\\<chi>")
+ (psi () "psi" "\\<psi>")
+ (omega () "omega" "\\<omega>")))
+
+;; All the stuff X-Symbol complains about
+(defvar x-symbol-twelf-master-directory 'ignore)
+(defvar x-symbol-twelf-image-searchpath '("./"))
+(defvar x-symbol-twelf-image-cached-dirs '("images/" "pictures/"))
+(defvar x-symbol-twelf-image-keywords nil)
+(defvar x-symbol-twelf-font-lock-keywords nil)
+(defvar x-symbol-twelf-header-groups-alist nil)
+(defvar x-symbol-twelf-class-alist
+ '((VALID "Twelf Symbol" (x-symbol-info-face))
+ (INVALID "no Twelf Symbol" (red x-symbol-info-face))))
+(defvar x-symbol-twelf-class-face-alist nil)
+(defvar x-symbol-twelf-electric-ignore nil)
+(defvar x-symbol-twelf-required-fonts nil)
+(defvar x-symbol-twelf-case-insensitive nil)
+;; Setting token shape prevents "philosophy" example, but still
+;; problems, e.g. delphi, false1. (Pierre)
+(defvar x-symbol-twelf-token-shape '(?_ "[A-Za-z]+" . "[A-Za-z_]"))
+(defvar x-symbol-twelf-table x-symbol-twelf-symbol-table)
+(defun x-symbol-twelf-default-token-list (tokens) tokens)
+(defvar x-symbol-twelf-token-list 'x-symbol-twelf-default-token-list)
+(defvar x-symbol-twelf-input-token-ignore nil)
+
+;; internal stuff
+(defvar x-symbol-twelf-exec-specs nil)
+(defvar x-symbol-twelf-menu-alist nil)
+(defvar x-symbol-twelf-grid-alist nil)
+(defvar x-symbol-twelf-decode-atree nil)
+(defvar x-symbol-twelf-decode-alist nil)
+(defvar x-symbol-twelf-encode-alist nil)
+(defvar x-symbol-twelf-nomule-decode-exec nil)
+(defvar x-symbol-twelf-nomule-encode-exec nil)
+
+(warn "Twelf support for X-Symbol is highly incomplete! Please help improve it!
+Send improvements to x-symbol-twelf.el to proofgen@dcs.ed.ac.uk")
+
+
+(provide 'x-symbol-twelf)