aboutsummaryrefslogtreecommitdiff
path: root/isar
diff options
context:
space:
mode:
Diffstat (limited to 'isar')
-rw-r--r--isar/BUGS21
-rw-r--r--isar/Example.thy43
-rw-r--r--isar/README33
-rw-r--r--isar/interface236
-rw-r--r--isar/isar-keywords.el403
-rw-r--r--isar/isar-syntax.el425
-rw-r--r--isar/isar.el613
-rw-r--r--isar/isartags86
-rw-r--r--isar/todo17
9 files changed, 1877 insertions, 0 deletions
diff --git a/isar/BUGS b/isar/BUGS
new file mode 100644
index 00000000..11564906
--- /dev/null
+++ b/isar/BUGS
@@ -0,0 +1,21 @@
+-*- mode:outline -*-
+
+* Isabelle/Isar Proof General Bugs
+
+See also ../BUGS for generic bugs.
+
+** Issues with tracing mode
+
+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.
+
diff --git a/isar/Example.thy b/isar/Example.thy
new file mode 100644
index 00000000..fc72c2f7
--- /dev/null
+++ b/isar/Example.thy
@@ -0,0 +1,43 @@
+(*
+ Example proof document for Isabelle/Isar Proof General.
+
+ $Id$
+*)
+
+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
diff --git a/isar/README b/isar/README
new file mode 100644
index 00000000..7f63c136
--- /dev/null
+++ b/isar/README
@@ -0,0 +1,33 @@
+Isabelle/Isar Proof General
+
+Written by Markus Wenzel
+
+Status: supported
+Maintainer: David Aspinall
+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.
+
+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..7a3742bd
--- /dev/null
+++ b/isar/isar-keywords.el
@@ -0,0 +1,403 @@
+;;
+;; Keyword classification tables for Isabelle/Isar.
+;; This file generated by Isabelle99-2 -- DO NOT EDIT!
+;;
+;; NB: This version is for Isabelle99.
+;;
+;; Isabelle2002 is supplied with a different version of this file
+;; which should be loaded instead. See also the "-k" option
+;; to the Isabelle script.
+;;
+;; $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..849cb243
--- /dev/null
+++ b/isar/isar-syntax.el
@@ -0,0 +1,425 @@
+;; isar-syntax.el Syntax expressions for Isabelle/Isar
+;; Copyright (C) 1994-1998 LFCS Edinburgh.
+;; License: GPL (GNU GENERAL PUBLIC LICENSE)
+;;
+;; 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 ?\( "()1")
+ (modify-syntax-entry ?\) ")(4")
+ (cond
+ (proof-running-on-XEmacs
+ ;; We classify {* sequences *} as comments, although
+ ;; they need to be passed as command args as text.
+ ;; NB: adding a comment sequence b seems to break
+ ;; buffer-syntactic-context, best to use emulated
+ ;; version.
+ (modify-syntax-entry ?\{ "(}5")
+ (modify-syntax-entry ?\} "){8")
+ (modify-syntax-entry ?\* ". 2367"))
+ ;; previous version confuses the two comment sequences,
+ ;; but works with buffer-syntactic-context.
+ ;;(modify-syntax-entry ?\{ "(}1")
+ ;;(modify-syntax-entry ?\} "){4")
+ ;;(modify-syntax-entry ?\* ". 23"))
+ (proof-running-on-Emacs21
+ (modify-syntax-entry ?\{ "(}1b")
+ (modify-syntax-entry ?\} "){4b")
+ (modify-syntax-entry ?\* ". 23n"))))
+
+
+(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. { })
+;; FIXME FIXME FIXME
+;; DA: this goes wrong for { and } in fact, because plain { and } in
+;; `proof-script-command-start-regexp' also match with {* and *}, which
+;; should not be considered as commands (breaks new parser).
+
+(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)
+ ;; was just s
+ (cond
+ ;; FIXME: what we really want here is to match { or }
+ ;; _except_ when followed/preceded by *, but not to
+ ;; consider * as part of match. (Exclude punctuation??)
+ ;; That kind of construct is only allowed for whitespace,
+ ;; though.
+ ((string-equal s "{") "{[^\*]")
+ ((string-equal s "}") "[^\*]}") ;; FIXME wrong
+ (t s)) ; what else?
+ (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..8902ad49
--- /dev/null
+++ b/isar/isar.el
@@ -0,0 +1,613 @@
+;; isar.el Major mode for Isabelle/Isar proof assistant
+;; Copyright (C) 1994-1998 LFCS Edinburgh.
+;; License: GPL (GNU GENERAL PUBLIC LICENSE)
+;;
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Author / Maintainer: Markus Wenzel <wenzelm@in.tum.de>
+;;
+;; $Id$
+;;
+
+(require 'proof)
+
+;;
+;; Add generic code for Isabelle and Isabelle/Isar
+;;
+(setq load-path (cons (concat proof-home-directory "isa/") load-path))
+(require 'isabelle-system)
+
+;;
+;; Load syntax
+;;
+(defcustom isar-keywords-name nil
+ "Specifies a theory-specific keywords setting to use with Isar.
+See -k option for Isabelle interface script."
+ :type 'string
+ :group 'isabelle-isar)
+
+(or (featurep 'isar-keywords)
+ ;; Pickup isar-keywords file from somewhere appropriate,
+ ;; giving user chance to set name of file, or based on
+ ;; name of logic.
+ (isabelle-load-isar-keywords
+ (or isar-keywords-name
+ isabelle-chosen-logic)))
+(require 'isar-syntax)
+
+
+;; Completion table for Isabelle/Isar identifiers
+(defpgdefault completion-table isar-keywords-major)
+
+(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-script-comment-end))
+ (cmt-start-regexp (regexp-quote proof-script-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))
+ (progn
+ (delete-backward-char 1)
+ (or (proof-looking-at ";\\|\\s-\\|$")
+ (insert " ")))))))
+
+
+(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
+ ;; FIXME: this gets { and } wrong: they must _not_ appear as {* *}
+ ;; because that's lexically a kind of comment.
+ isar-any-command-regexp
+ (regexp-quote ";"))
+ proof-script-integral-proofs t
+ ;; FIXME: use old parser for now to avoid { } problem
+ proof-script-use-old-parser t
+ proof-script-comment-start isar-comment-start
+ proof-script-comment-end isar-comment-end
+ proof-script-comment-start-regexp isar-comment-start-regexp
+ proof-script-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
+ proof-state-preserving-p 'isar-state-preserving-p
+ proof-shell-compute-new-files-list 'isar-shell-compute-new-files-list
+ ;; span menu
+ proof-script-span-context-menu-extensions 'isabelle-create-span-menu))
+
+
+(defun isar-shell-mode-config-set-variables ()
+ "Configure generic proof shell mode variables for Isabelle/Isar."
+ (setq
+ pg-subterm-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.
+
+ pg-next-error-regexp "\\((line \\([0-9]+\\) of \"[^\"]+\")\\)"
+ pg-next-error-filename-regexp "\\((line [0-9]+ of \"\\([^\"]+\\)\")\\)"
+
+ ;; matches names of assumptions
+ proof-shell-assumption-regexp isar-id
+ ;; matches subgoal name
+ ;; da: not used at the moment, maybe after 4.0 used for
+ ;; proof-generic-goal-hyp-fn to get pg-goals-like features.
+ ;; proof-shell-goal-regexp "\370[ \t]*\\([0-9]+\\)\\."
+
+ proof-shell-start-goals-regexp "\366\n"
+ proof-shell-end-goals-regexp "\367"
+ pg-topterm-char ?\370
+
+ ;; FIXME: next one is needed for backward compatibility.
+ ;; Would be nice to remove this somehow else, it's only used for
+ ;; Isar. One way would be to hack the (now obsolete) defpacustom calls.
+ ;;
+ ;; 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
+
+ ;; Isabelle is learning to talk PGIP...
+ proof-shell-match-pgip-cmd "<pgip"
+ proof-shell-issue-pgip-cmd 'isabelle-process-pgip
+
+ ;; 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."
+
+ ;; Theorem dependencies. NB: next regex anchored at end with eager annot end
+ proof-shell-theorem-dependency-list-regexp "Proof General, theorem dependencies of \\(.*\\) are \"\\(.*\\)\"\361"
+ proof-shell-theorem-dependency-list-split "\" \""
+ proof-shell-show-dependency-cmd "thm %s;"
+
+ ;; Allow font-locking for output based on hidden annotations, see
+ ;; isar-output-font-lock-keywords-1
+ pg-use-specials-for-fontify t
+
+ ;; === ANNOTATIONS === these ones are not implemented in Isabelle
+ proof-shell-result-start "\372 Pbp result \373"
+ proof-shell-result-end "\372 End Pbp result \373"
+ pg-subterm-anns-use-stack t
+ pg-subterm-start-char ?\372
+ pg-subterm-sep-char ?\373
+ pg-subterm-end-char ?\374
+ pg-after-fontify-output-hook
+ (if proof-experimental-features
+ 'isabelle-convert-idmarkup-to-subterm 'pg-remove-specials)
+ pg-subterm-help-cmd "term %s"
+
+ 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
+ "Isar shell" nil
+ (isar-shell-mode-config)))
+
+(eval-and-compile
+(define-derived-mode isar-response-mode proof-response-mode
+ "response" nil
+ (isar-response-mode-config)))
+
+(eval-and-compile ; to define vars for byte comp.
+(define-derived-mode isar-goals-mode proof-goals-mode
+ "proofstate" nil
+ (isar-goals-mode-config)))
+
+(eval-and-compile ; to define vars for byte comp.
+(define-derived-mode isar-mode proof-mode
+ "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, diagnostic, nested proof command: skip
+ ;; (da: adding new span types may break this code,
+ ;; ought to test for type 'cmd before looking at
+ ;; str below)
+ ;; FIXME: should adjust proof-nesting-depth here.
+ ((or (eq (span-property span 'type) 'comment)
+ (eq (span-property span 'type) 'proof); da: needed?
+ (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 output buffer
+;;
+
+(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
+ (append
+ isar-output-font-lock-keywords-1
+ (if (boundp 'x-symbol-isabelle-font-lock-keywords)
+ x-symbol-isabelle-font-lock-keywords)))
+ (isar-shell-mode-config-set-variables)
+ (proof-shell-config-done))
+
+(defun isar-response-mode-config ()
+ (isar-init-output-syntax-table)
+ (setq font-lock-keywords
+ (append
+ isar-output-font-lock-keywords-1
+ (if (proof-ass x-symbol-enable)
+ x-symbol-isabelle-font-lock-keywords)))
+ (proof-response-config-done))
+
+(defun isar-goals-mode-config ()
+ ;; FIXME: next two broken, of course, as is PBP everywhere except LEGO.
+ (setq pg-goals-change-goal "show %s.")
+ (setq pg-goals-error-regexp proof-shell-error-regexp)
+ (isar-init-output-syntax-table)
+ (setq font-lock-keywords
+ (append
+ isar-goals-font-lock-keywords
+ (if (proof-ass x-symbol-enable)
+ x-symbol-isabelle-font-lock-keywords)))
+ (proof-goals-config-done))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; x-symbol support
+;;
+;; The following settings configure the generic PG package.
+;; The token language "Isabelle Symbols" is in file 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/isartags b/isar/isartags
new file mode 100644
index 00000000..0d65f8e6
--- /dev/null
+++ b/isar/isartags
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+#
+# Or perhaps: /usr/local/bin/perl
+#
+# FIXME: this code is just borrowed from legotags program,
+# it isn't yet working! Please send us fixes.
+#
+# $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 or
+# ---- inside commands. Could do better.
+
+# print "----- (",$lp,",",$cp,")\n", $stmt, "\n";
+
+ if($stmt=~/^([ \t]*\$?theory\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) }
+
+# ---- 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/isar/todo b/isar/todo
new file mode 100644
index 00000000..3b76d39a
--- /dev/null
+++ b/isar/todo
@@ -0,0 +1,17 @@
+-*- mode:outline -*-
+
+* Things to do for Isabelle/Isar
+
+See also ../todo for generic things to do, priority codes.
+
+** B visualise dependencies: sometimes not applicable.
+
+** 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);