aboutsummaryrefslogtreecommitdiff
path: root/generic
diff options
context:
space:
mode:
authorDavid Aspinall1998-10-01 14:20:10 +0000
committerDavid Aspinall1998-10-01 14:20:10 +0000
commit3cac405701bfd44ba9f6ebf469f52f0f91c6d0a3 (patch)
tree480f2e8c91e821441fbcfe8a50539dcc7f63d476 /generic
parentc1001a0e605a185570186fd4f967acf0c8f48bc3 (diff)
Added docstrings and comments.
Removed last of "not authorized for this documentation" nonsense. Replaced constant string "COMMENT" by proof-no-command. Begun work on new functions: proof-{next,previous}-matching-command. Work on proof-issue-goal, proof-issue-save (rough edges left as FIXMEs).
Diffstat (limited to 'generic')
-rw-r--r--generic/proof.el273
1 files changed, 211 insertions, 62 deletions
diff --git a/generic/proof.el b/generic/proof.el
index 2da75b39..cd983c0e 100644
--- a/generic/proof.el
+++ b/generic/proof.el
@@ -76,7 +76,7 @@ output format.")
:group 'proof-general)
(defcustom proof-one-command-per-line nil
- "*If non-nil, expect newlines after each proof command in a script."
+ "*If non-nil, format for newlines after each proof command in a script."
:type 'boolean
:group 'proof-general)
@@ -111,10 +111,9 @@ The script buffer's comment-end is set to this string plus a space.")
(defvar proof-count-undos-fn nil
"Compute number of undos in a target segment")
-;; FIXME da: "COMMENT" should be defconst'd somewhere.
(defvar proof-find-and-forget-fn nil
- "Function to return a command to forget back to before its argument span.
-The special string COMMENT means there is nothing to do.")
+ "Function returning a command string to forget back to before its argument span.
+The special string proof-no-command means there is nothing to do.")
(defvar proof-goal-hyp-fn nil
"A function which returns cons cell if point is at a goal/hypothesis.
@@ -207,6 +206,7 @@ when parsing the proofstate output")
"A regular expression indicating that the PROOF process has
identified an error.")
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Internal variables used by scripting and pbp ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -222,22 +222,24 @@ when parsing the proofstate output")
"End-of-line string for proof process.")
(defvar proof-re-end-of-cmd nil
- "You are not authorised for this information.")
+ "Regexp matching end of command. Based on proof-terminal-string.
+Set in proof-config-done.")
(defvar proof-re-term-or-comment nil
- "You are not authorised for this information.")
+ "Regexp matching terminator, comment start, or comment end.
+Set in proof-config-done.")
(defvar proof-marker nil
- "You are not authorised for this information.")
+ "Marker in proof shell buffer pointing to previous command input.")
(defvar proof-shell-buffer nil
- "The process buffer which communicates with the prover.")
+ "Process buffer where the proof assistant is run.")
(defvar proof-script-buffer nil
- "The currently-active scripting buffer.")
+ "Currently-active scripting buffer.")
(defvar proof-pbp-buffer nil
- "You are not authorised for this information.")
+ "The response buffer (also known as the goals or pbp buffer).")
(defvar proof-shell-busy nil
"A lock indicating that the proof shell is processing.
@@ -249,6 +251,9 @@ an error.")
(defvar proof-action-list nil "action list")
+(defconst proof-no-command "COMMENT"
+ "String used as a nullary action (send no command to the proof assistant)")
+
(defvar proof-included-files-list nil
"List of files currently included in proof process.
Each element in the list is a tuple of the form (module . file) where
@@ -258,7 +263,7 @@ module is identifies the buffer and file is the file name of the module.")
"An indication in the modeline that this is the *active* buffer")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; A couple of small utilities ;;
+;; A few small utilities ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun proof-message (str)
@@ -297,14 +302,6 @@ The argument KBL is a list of tuples (k . f) where `k' is a keybinding
(string-match (concat "[^" separator "]")
s end-of-word-occurence)) separator)))))
-;; FIXME da: this doesn't belong here, it's only used by lego.
-;; (and it shouldn't be called w3-* !!)
-(defun w3-remove-file-name (address)
- "Remove the file name in a World Wide Web address"
- (string-match "://[^/]+/" address)
- (concat (substring address 0 (match-end 0))
- (file-name-directory (substring address (match-end 0)))))
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Basic code for the locked region and the queue region ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -421,7 +418,7 @@ The argument KBL is a list of tuples (k . f) where `k' is a keybinding
;;; in case Emacs is not aware of read-shell-command-map
-;; FIXME da: this might obliterate user's customizations
+;; FIXME da: nasty, this might obliterate user's customizations
;; to read-shell-command-map.
(defvar read-shell-command-map
(let ((map (make-sparse-keymap)))
@@ -462,6 +459,8 @@ The argument KBL is a list of tuples (k . f) where `k' is a keybinding
(and (re-search-forward r nil t)
(cons (buffer-substring (setq p (match-beginning p)) (point)) p)))))
+;; FIXME da: these next two functions slightly different, why?
+;; (unprocessed-begin vs proof-locked-end)
(defun proof-goto-end-of-locked-interactive ()
"Jump to the end of the locked region."
(interactive)
@@ -472,6 +471,10 @@ The argument KBL is a list of tuples (k . f) where `k' is a keybinding
"Jump to the end of the locked region."
(goto-char (proof-unprocessed-begin)))
+(defun proof-in-locked-region-p ()
+ "Non-nil if point is in locked region. Assumes proof script buffer current."
+ (< (point) (proof-locked-end)))
+
(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."
(interactive)
@@ -640,6 +643,14 @@ The argument KBL is a list of tuples (k . f) where `k' is a keybinding
;; Turning annotated output into pbp goal set ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+
+
+
+
+
+
(defvar proof-shell-first-special-char nil "where the specials start")
(defvar proof-shell-goal-char nil "goal mark")
(defvar proof-shell-start-char nil "annotation start")
@@ -697,12 +708,17 @@ The default value is \"$\" to match up to the end of the line.")
;; Output from the proof process is handled lazily, so that only
;; the output from the last of multiple commands is actually
-;; processed (assuming they're all successful)
+;; processed (assuming they're all successful)
+
+
(defvar proof-shell-delayed-output nil
"The last interesting output the proof process output, and what to do
with it.")
+(defvar proof-shell-proof-completed nil
+ "Flag indicating that a completed proof has just been observed.")
+
(defvar proof-analyse-using-stack nil
"Are annotations sent by proof assistant local or global")
@@ -815,6 +831,27 @@ Returns the string (with faces) in the specified region."
(run-hooks 'proof-shell-handle-delayed-output-hook)
(setq proof-shell-delayed-output (cons 'insert "done")))
+;; 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:
+;;
+;; 'vanilla Initialised in proof-semis-to-vanillas, for
+;; 'goalsave
+;; 'comment A comment outside a command.
+;;
+;; 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.
+;;
+;;
+
(defun proof-shell-handle-error (cmd string)
"React on an error message triggered by the prover.
We display the process buffer, scroll to the end, beep and fontify the
@@ -897,10 +934,12 @@ error message. At the end it calls `proof-shell-handle-error-hook'. "
())
((string-match proof-shell-proof-completed-regexp string)
+ (setq proof-shell-proof-completed t)
(setq proof-shell-delayed-output
(cons 'insert (concat "\n" (match-string 0 string)))))
((string-match proof-shell-start-goals-regexp string)
+ (setq proof-shell-proof-completed nil)
(let (start end)
(while (progn (setq start (match-end 0))
(string-match proof-shell-start-goals-regexp
@@ -910,6 +949,7 @@ error message. At the end it calls `proof-shell-handle-error-hook'. "
(cons 'analyse (substring string start end)))))
((string-match proof-shell-result-start string)
+ (setq proof-shell-proof-completed nil)
(let (start end)
(setq start (+ 1 (match-end 0)))
(string-match proof-shell-result-end string)
@@ -1004,7 +1044,7 @@ queue is running."
(let (item)
(while (and alist (string=
(nth 1 (setq item (car alist)))
- "COMMENT"))
+ proof-no-command))
(funcall (nth 2 item) (car item))
(setq alist (cdr alist)))
(if alist
@@ -1026,7 +1066,7 @@ queue is running."
(while (and proof-action-list
(string=
(nth 1 (setq item (car proof-action-list)))
- "COMMENT"))
+ proof-no-command))
(funcall (nth 2 item) (car item))
(setq proof-action-list (cdr proof-action-list)))
(if (null proof-action-list)
@@ -1100,7 +1140,7 @@ how far we've got."
(and proof-shell-wakeup-char
(string-match (char-to-string proof-shell-wakeup-char) str))
;; Others rely on a standard top-level (e.g. SML) whose prompt can't
- ;; be hacked. For those we use the prompt regexp.
+ ;; be hacked. For those we use the annotated prompt regexp.
(string-match proof-shell-annotated-prompt-regexp str))
(if (null (marker-position proof-marker))
;; Set marker to first prompt in output buffer, and sleep again.
@@ -1121,6 +1161,11 @@ how far we've got."
(setq cmd (nth 1 (car proof-action-list)))
(save-excursion
(setq res (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 (car-safe res) 'error)
(proof-shell-handle-error cmd (cdr res)))
@@ -1147,7 +1192,7 @@ how far we've got."
;; doesn't apply to Coq at all. (Never mind Isabelle!)
(defun proof-steal-process ()
"This allows us to steal the process if we want to change the buffer
- in which script management is running."
+in which script management is running."
(proof-start-shell)
(if proof-shell-busy (error "Proof Process Busy!"))
(if (not (eq proof-buffer-type 'script))
@@ -1365,7 +1410,7 @@ the next command end."
(aset str i c)
(incf i)))
- (if (looking-at "\"") ; da: should this be more generic?
+ (if (looking-at "\"") ; FIXME da: should this be more generic?
(setq quote-parity (not quote-parity)))
(forward-char)
@@ -1396,7 +1441,7 @@ function) to a set of vanilla extents."
(or callback-fn 'proof-done-advancing))
alist)))
(set-span-property span 'type 'comment)
- (setq alist (cons (list span "COMMENT" 'proof-done-advancing) alist)))
+ (setq alist (cons (list span proof-no-command 'proof-done-advancing) alist)))
(setq semis (cdr semis)))
(nreverse alist)))
@@ -1439,15 +1484,13 @@ function) to a set of vanilla extents."
;; I find it more convenient to assert up to the current command (command
;; point is inside), and move to the character past the terminator.
;; This means proofs can be easily replayed with point at the start
-;; of lines. Above function gives "nothing to do error."
-(defun proof-assert-next-command (&optional dont-move-forward)
+;; of lines. Above function gives stupid "nothing to do error." when
+;; point is on the start of line or in the locked region.
+(defun proof-assert-next-command ()
"Experimental variant of proof-assert-until-point.
-Works in locked region and at start of commands. Moves point
-forward unless optional arg DONT-MOVE-FORWARD is true."
- (interactive "p")
- (let ((pt (point))
- (crowbar (proof-steal-process))
- semis)
+Works in locked region and at start of commands."
+ (interactive)
+ (let ((crowbar (proof-steal-process)) semis)
(save-excursion
;; CHANGE from proof-assert-until-point: don't bother check
;; for non-whitespace between locked region and point.
@@ -1462,9 +1505,7 @@ forward unless optional arg DONT-MOVE-FORWARD is true."
(skip-chars-forward (if proof-one-command-per-line " \t" " \t\n"))
(let ((vanillas (proof-semis-to-vanillas (nreverse semis))))
(if crowbar (setq vanillas (cons crowbar vanillas)))
- (proof-start-queue (proof-locked-end) (point) vanillas))
- ;; FIXME: why is move-forward non-nil when called from keymap???
- (and dont-move-forward (goto-char pt))))
+ (proof-start-queue (proof-locked-end) (point) vanillas))))
;; insert-pbp-command - an advancing command, for use when ;;
;; PbpHyp or Pbp has executed in LEGO, and returned a ;;
@@ -1521,7 +1562,7 @@ deletes the region corresponding to the proof sequence."
(setq span (next-span span 'type)))
(setq actions (proof-setup-retract-action
start end
- (if (null span) "COMMENT"
+ (if (null span) proof-no-command
(funcall proof-count-undos-fn span))
delete-region)
end start))
@@ -1637,6 +1678,18 @@ the proof script."
(and (re-search-forward "\\S-" nil t)
(proof-assert-until-point nil 'ignore-proof-process)))))
+(defun proof-goto-command-start ()
+ "Move point to start of current command."
+ (interactive)
+ (let ((cmd (span-at (point) 'type)))
+ (if cmd (goto-char (span-start cmd)) ; BUG: only works for unclosed proofs.
+ (let ((semis (proof-segment-up-to (point) t)))
+ (if (eq 'unclosed-comment (car semis)) (setq semis (cdr semis)))
+ (if (and semis (car semis) (car (car semis)))
+ (progn
+ (goto-char (nth 2 (car (car semis))))
+ (skip-chars-forward " \t\n")))))))
+
(defun proof-process-buffer ()
"Process the current buffer and set point at the end of the buffer."
(interactive)
@@ -1657,6 +1710,7 @@ script buffer."
(delete-spans (point-min) (point-max) 'type)
(proof-detach-segments)))
(setq proof-shell-busy nil
+ proof-shell-proof-completed nil
proof-script-buffer nil)
(if (buffer-live-p proof-shell-buffer)
(kill-buffer proof-shell-buffer))
@@ -1694,7 +1748,7 @@ Only for use by consenting adults."
(delete-spans (proof-locked-end) (point-max) 'type))))
(defvar proof-minibuffer-history nil
- "The last command read from the minibuffer")
+ "History of proof commands read from the minibuffer")
(defun proof-execute-minibuffer-cmd ()
(interactive)
@@ -1702,9 +1756,33 @@ Only for use by consenting adults."
(proof-check-process-available 'relaxed)
(setq cmd (read-string "Command: " nil 'proof-minibuffer-history))
(proof-invisible-command cmd 'relaxed)))
-
+;; 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)))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Popup and Pulldown Menu ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1728,9 +1806,17 @@ Only for use by consenting adults."
:type 'string
:group 'proof-general)
-(defvar proof-goal-command-string nil
- "Command to set a goal in the proof assistant.
-The format character %s will be replaced by the goal string.")
+(defvar 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, should return a command string to
+insert when called interactively.")
+
+(defvar 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, should return a command string to
+insert when called interactively.")
;;; Functions using the above
@@ -1756,24 +1842,82 @@ The format character %s will be replaced by the goal string.")
;; a choice of minibuffer prompting (hated by power users, perfect
;; for novices).
;; Add named goals.
-(defun proof-issue-goal (goal)
- "Insert a goal command into the script buffer, issue it to the proof assistant."
- (interactive
- (if proof-goal-command-string
- '("sGoal: ")
- (error "Proof General not configured for goals: set proof-goal-command-string.")))
+;; 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.
+
+(defvar proof-issue-goal-history nil
+ "History of goals for proof-issue-goal.")
+
+(defun proof-issue-goal (goal-cmd)
+ "Insert a goal command into the script buffer, issue it to prover."
+ (interactive
+ (if proof-goal-command
+ (if (stringp proof-goal-command)
+ (list (format proof-goal-command-string
+ (read-string "Goal: " ""
+ proof-issue-goal-history)))
+ (proof-goal-command))
+ (error
+ "Proof General not configured for goals: set proof-goal-command.")))
+ (let ((proof-one-command-per-line t)) ; Goals always start at a new line
+ (proof-issue-new-command goal-cmd)))
+
+(defvar proof-issue-save-history nil
+ "History of theorem names for proof-issue-save.")
+
+(defun proof-issue-save (thmsave-cmd)
+ "Insert a save theorem command into the script buffer, issue it."
+ (interactive
+ (if proof-save-command
+ (if (stringp proof-save-command)
+ (list (format proof-save-command-string
+ (read-string "Save as: " ""
+ proof-issue-save-history)))
+ (proof-save-command))
+ (error
+ "Proof General not configured for save theorem: set proof-save-command.")))
+ (let ((proof-one-command-per-line t)) ; Goals always start at a new line
+ (proof-issue-new-command thmsave-cmd)))
+
+(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)
+ (if proof-one-command-per-line
+ ;; One command per line: move to next new line,
+ ;; creating one if at end of buffer.
+ (if (forward-line)
+ (newline))
+ ;; Multiple commands per line: skip spaces at point,
+ ;; if no spaces there already, add one.
+ (if (skip-chars-forward " \t")
+ (insert " "))))
+
+(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."
;; FIXME: da: I think we need a (proof-script-switch-to-buffer)
- ;; function.
+ ;; function (so there is some control over display).
(switch-to-buffer proof-script-buffer)
- ;; Assume point is the right place to insert a new goal.
- ;; An alternative would be to move to end of buffer
- ;; (or end of locked region, at least)
- (let ((goal-string (format proof-goal-command-string goal)))
- ;; FIXME: fixup behaviour of undo here. Really want
- ;; to temporarily disable undo for insertion.
- ;; (buffer-disable-undo) this trashes whole undo list!
- (insert goal-string)
- (proof-assert-until-point)))
+ (if (proof-in-locked-region-p)
+ (proof-goto-end-of-locked-interactive))
+ (proof-script-new-command-advance)
+ ;; FIXME: fixup behaviour of undo here. Really want
+ ;; to temporarily disable undo for insertion.
+ ;; (buffer-disable-undo) this 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))
+
+
;;; To be called from menu
@@ -1909,9 +2053,10 @@ where `k' is a keybinding (vector) and `f' the designated function.")
;; Fixed definitions in proof-mode-map, which don't depend on
;; prover configuration.
+;;; INDENT HACK: font-lock only recognizes define-key at start of line
(let ((map proof-mode-map))
- ;; Funny indentation below is for font-lock to recognize define-key.
(define-key map [(control c) (control e)] 'proof-find-next-terminator)
+(define-key map [(control c) (control a)] 'proof-goto-command-start)
(define-key map [(control c) (control return)] 'proof-assert-next-command)
(define-key map [(control c) (return)] 'proof-assert-until-point)
(define-key map [(control c) (control t)] 'proof-try-command)
@@ -1924,8 +2069,10 @@ where `k' is a keybinding (vector) and `f' the designated function.")
(define-key map [(control c) (control p)] 'proof-prf)
(define-key map [(control c) ?c] 'proof-ctxt)
(define-key map [(control c) ?h] 'proof-help)
+(define-key map [(meta p)] 'proof-previous-matching-command)
+(define-key map [(meta n)] 'proof-next-matching-command)
;; FIXME da: this shouldn't need setting, because it works
-;; via indent-line-function which is set below.
+;; via indent-line-function which is set below. Check this.
(define-key map [tab] 'proof-indent-line)
(proof-define-keys map proof-universal-keys))
@@ -1946,6 +2093,7 @@ finish setup which depends on specific proof assistant configuration."
;; calculate some strings and regexps for searching
(setq proof-terminal-string (char-to-string proof-terminal-char))
+ ;; FIXME da: surely these are LEGO (Coq?) specific!
(setq pbp-goal-command (concat "Pbp %s" proof-terminal-string))
(setq pbp-hyp-command (concat "PbpHyp %s" proof-terminal-string))
@@ -2020,6 +2168,7 @@ finish setup which depends on specific proof assistant configuration."
(setq proof-buffer-type 'shell)
(setq proof-shell-busy nil)
(setq proof-shell-delayed-output (cons 'insert "done"))
+ (setq proof-shell-proof-completed nil)
;;; COMINT customisation
(setq comint-prompt-regexp proof-shell-prompt-pattern)