pax_global_header00006660000000000000000000000064121456230750014517gustar00rootroot0000000000000052 comment=54ecd752711363d2bcae40dd41ad12e6e43e9e00 proofgeneral-4.3~pre130510/000077500000000000000000000000001214562307500154275ustar00rootroot00000000000000proofgeneral-4.3~pre130510/.cvsignore000066400000000000000000000000521214562307500174240ustar00rootroot00000000000000.byte-compile nohup.out TAGS ChangeLog proofgeneral-4.3~pre130510/AUTHORS000066400000000000000000000012401214562307500164740ustar00rootroot00000000000000Current Authors/Maintainers: David Aspinall (all) Pierre Courtieu (coq) Christoph Raffalli (phox) Makarius Wenzel (isar) Previous Authors: Stefan Berghofer (isar) Paul Callaghan (plastic,lego) Healfdene Goguen (coq, generic, doc) Thomas Kleymann (lego, doc, generic) Patrick Loiseleur (coq) David von Oheimb (x-symbol) Dilip Sequeira (lego) Graham Dutton (web support) These are the main "official" authors of Proof General, but many more people have contributed, some very significantly. We're grateful to everyone who has! Please see the CREDITS section in the manual for a more complete list. proofgeneral-4.3~pre130510/BUGS000066400000000000000000000077771214562307500161340ustar00rootroot00000000000000-*- outline -*- * Known Bugs and Workarounds for Proof General. For latest, see: http://proofgeneral.inf.ed.ac.uk/trac See also FAQ: http://proofgeneral.inf.ed.ac.uk/FAQ The bugs here are split into problems which are generic, and those which only apply to particular provers. The FAQ mentions other issues which are not necessarily PG bugs. This list is incomplete and only occasionally updated, please search on Trac for current issues. * Reporting bugs If you have a problem that is not mentioned here, please visit the Trac at the address above to add a ticket. Please describe your problem carefully, include a short demonstration file and tell us the exact version of Emacs and Proof General that you are using. * General issues ** 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 '. 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. ** Glitches in display handling, esp with multiple frames Unfortunately the handling of the display is very difficult to manage because the API provided by Emacs is quirky and varies between versions. If the eager display/tear-down of frames is annoying you, you may customize the variable `proof-shell-fiddle-frames' to nil to reduce it a bit. To prevent eagerly displaying new frames at on starting the shell, you can also add a mode hook to set `proof-eagerly-raise' e.g.: (add-hook 'proof-goals-mode-hook (lambda () (setq proof-eagerly-raise nil))) (add-hook 'proof-response-mode-hook (lambda () (setq proof-eagerly-raise nil))) Generally, the best way of working with multiple frames is to try not to stop/start the proof assistant too much (this involves killing buffers, which spoils the frame/buffer correspondence). ** Using C-g can leave script management in a mess (rare). 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 to be sure of synchronizing. ** 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. ** Prover does not lock/may not notice dirty files 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. * Problems with Isabelle ** Issues with tracing mode 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. * Problems with Coq ** Multiple file handling and auto-compilation is incomplete ** C-c C-a C-i on long intro lines breaks line the wrong way. ** 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. * LEGO Proof General Bugs See lego/BUGS proofgeneral-4.3~pre130510/CHANGES000066400000000000000000000315451214562307500164320ustar00rootroot00000000000000-*- outline -*- This is a summary of main changes. For details, please see the CVS ChangeLog and PG Trac, http://proofgeneral.inf.ed.ac.uk/trac. * Changes of Proof General 4.3 from Proof General 4.2 ** Prooftree changes *** Require Prooftree version 0.11 Check the Prooftree website to see which other versions of Prooftree are compatible with Proof General 4.3. *** New features One can now trigger an retraction (undo) by selecting the appropriate sequent in Prooftree. One can further send proof commands or proof scripts from whole proof subtrees to Proof General, which will insert them in the current buffer. Prooftree also supports some recent Coq features, see below. ** Coq changes *** Asynchronous parallel compilation of required modules Proof General has now a second implementation for compiling required Coq modules. Check menu Coq -> Settings -> Compile Parallel In Background to compile modules in parallel in the background while Proof General stays responsive. *** Support for bullets, braces and Grab Existential Variables for Prooftree. * Changes of Proof General 4.2 from Proof General 4.1 ** Generic/misc changes *** Added user option: `proof-next-command-insert-space' Allows the user to turn off the electric behaviour of generating newlines or spaces in the buffer. Turned on by default, set to nil to revert to PG 3.7 behaviour. *** Support proof-tree visualization via the external Prooftree program Currently only Coq (using Coq version 8.4beta or newer) supports proof-tree visualization. If Prooftree is installed, the proof-tree display can be started via the toolbar, the Proof-General menu or by C-c C-d. To get Prooftree, visit http://askra.de/software/prooftree *** Compilation fixes for Emacs 24. *** Fix "pgshell" mode for shell/CLI prover interaction Also add some quick hacks for scripting OCaml and Haskell ** Coq changes *** Smarter three windows mode: In three pane mode, there are three display modes, depending where the three useful buffers are displayed: scripting buffer, goals buffer and response buffer. Here are the three modes: - vertical: the 3 buffers are displayed in one column. - hybrid: 2 columns mode, left column displays scripting buffer and right column displays the 2 others. - horizontal: 3 columns mode, one for each buffer (script, goals, response). By default, the display mode is automatically chosen by considering the current emacs frame width: if it is smaller than `split-width-threshold' then vertical mode is chosen, otherwise if it is smaller than 1.5 * `split-width-threshold' then hybrid mode is chosen, finally if the frame is larger than 1.5 * `split-width-threshold' then the horizontal mode is chosen. You can change the value of `split-width-threshold' at your will (by default it is 160). If you want to force one of the layouts, you can set variable `proof-three-window-mode-policy' to 'vertical, 'horizontal or 'hybrid. The default value is 'smart which sets the automatic behaviour described above. example: (setq proof-three-window-mode-policy 'hybrid). Or via customization menus. *** Multiple file handling for Coq Feature. No more experimental. Set coq-load-path to the list of directories for libraries (you can attach it to the file using menu "coq prog args"). Many thanks to Hendrik Tews for that great peace of code! *** Support proof-tree visualization Many thanks to Hendrik Tews for that too! *** New commands for Print/Check/About/Show with "Printing All" flag Avoids typing "Printing All" in the buffer. See the menu Coq > Other queries. Thanks to Assia Mahboubi and Frederic Chyzak for the suggestion. Shortcut: add C-u before the usual shortcut (example: C-u C-c C-a C-c for: Set Printing All. Check. Unset Printing All. ) *** Coq menus and shortcut in response and goals buffers. Check, Print etc available in these buffers. *** Tooltips hidden by default Flickering when hovering commands is off by default! *** "Insert Requires" now uses completion based on coq-load-path *** New setting for hiding additional goals from the *goals* buffer Coq > Settings > Hide additional subgoals *** Double hit terminator Experimental: Same as electric terminator except you have to type "." twice quickly. Electric terminator will stop getting in the way all the time with module.notations. Coq > Double Hit Electric Terminator. Note 1: Mutually exclusive with usual electric terminator. Note 2: For french keyboard it may be convenient to map ";" instead of ".": (add-hook 'proof-mode-hook (lambda () (define-key coq-mode-map (kbd ";") 'coq-terminator-insert))) *** Indentation improvements using SMIE. Supporting bullets and { }. Still experimental. Please submit bugs. IMPORTANT: Limitations of indentation: - hard-wired precedence between bullets: - < + < * example: Proof. - split. + split. * auto. * auto. + intros. auto. - auto. Qed. - Always use "Proof." when proving an "Instance" (wrong indentation and slow downs otherwise). As a general rule, try to always introduce a proof with "Proof." (or "Next Obligation" with Program). *** "Show" shows the (cached) state of the proof at point. If Show goals (C-c C-a C-s) is performed when point is on a locked region, then it shows the prover state as stored by proofgeneral at this point. This works only when the command at point has been processed by "next step" (otherwise coq was silent at this point and nothing were cached). *** Minor parsing fixes *** Windows resizing fixed ** HOL Light [WORK IN PROGRESS] *** Basic support now works, see hol-light directory [WORK IN PROGRESS] * Changes of Proof General 4.1 from Proof General 4.0 ** Generic changes *** Parsing now uses cache by default (proof-use-parser-cache=t). Speeds up undo/redo in long buffers if no edits are made. ** Isabelle changes *** Unicode tokens enabled by default ** Coq changes *** A new indentation algorithm, using SMIE. This works when SMIE is available (Emacs >= 23.3), but must be enabled by the variable `coq-use-smie'. It also provides improved navigation facilities for things like C-M-t, C-M-f and C-M-b. Addition by Stefan Monnier. *** Experimental multiple file handling for Coq. Proof General is now able to automatically compile files while scripting Require commands, either internally or externally (by running Make). Additionally, it will automatically retract buffers when switching to new files, to model separate compilation properly. For details, see the Coq chapter in the Proof General manual. Addition by Hendrik Tews. *** Fixes for Coq 8.3 * Main Changes for Proof General 4.0 from 3.7.1 ** Install/support changes *** XEmacs is no longer supported; PG only works with GNU Emacs 23.1+ Older GNU Emacs versions after 22.3 may work but are unsupported. *** Primary distribution formats changed The RPM and zip file formats have been removed. We are very grateful to third-party packagers for Debian and Fedora for distributing packaged versions of PG. ** Generic changes *** Font-lock based Unicode Tokens mode replaces X-Symbol Unicode Tokens has been significantly improved since PG 3.7.1, and now works purely at a "presentation" level without changing buffer contents. See Tokens menu for many useful commands. *** Document-centred mechanisms added: - auto raise of prover output buffers can be disabled - output retained for script buffer popups - background colouring for locked region can be disabled - ...but "sticky" colouring for errors can be used - edit on processed region can automatically undo Depending on the prover language and interaction output, this may enable a useful "document centred" way of working, when output buffers can be ignored and hidden. Use "full annotation" to keep output when several steps are taken. Standard values for the options can be set in one go with: Quick Options -> Display -> Document Centred and the defaults set back with Quick Options -> Display -> Default. See the manual for more details. *** Automatic processing mode Quick Options -> Processing -> Send Automatically Sends commands to the prover when Emacs is idle for a while. This only sends commands when the last processing action has been an action moving forward through the buffer. Interrupt by making a keyboard/mouse action. See the manual for more details. *** Fast buffer processing option Quick Options -> Processing -> Fast Process Buffer This affects 'proof-process-buffer' (C-c C-b, toolbar down). It causes commands to be sent to the prover in a tight loop, without updating the display or processing other input. This speeds up processing dramatically on some Emacs implementations. To interrupt, use C-g, which reverts to normal processing mode. (To stop that, use C-c C-c as usual). *** Improved prevention of Undo in locked region With thanks to Erik Martin-Dorel and Stefan Monnier. Undo in read only region follows `proof-strict-read-only' and gives the user the chance to allow edits by retracting first. *** Proof General -> Options menu extended and rearranged - new menu for useful minor modes indicates modes that PG supports *** New query identifier info button and command (C-c C-i, C-M-mouse1) These are convenience commands for looking up identifiers in the running prover. *** New user configuration options (also on Proof General -> Options) proof-colour-locked (use background colour for checked text) proof-auto-raise-buffers (set to nil for manual window control) proof-full-decoration (add full decoration to input text) proof-sticky-errors (add highlighting for commands that caused error) proof-shell-quiet-errors (non-nil to disable beep on error; default=nil) proof-minibuffer-messages (non-nil to show prover messages; default=nil) *** Removed user configuration options proof-toolbar-use-button-enablers (now always used) proof-output-fontify-enable (now always enabled) *** "Movie" output: export an annotated buffer in XML Basic movie output for Proviola, see http://mws.cs.ru.nl/proviola ** Isabelle/Isar changes *** Support undo back into completed proofs (linear_undo). *** Electric terminator works without inserting terminator Hit ; to process the last command. Easier than C-RET. *** Line numbers reported during script management *** Sync problems with bad input prevented by command wrapping *** Isabelle Settings now organised in sub-menus ** Coq changes *** Only supports Coq 8.1+, support for earlier versions dropped. *** Holes mode can be turned on/off and has its own minor mode *** Some keyboard shortcuts are now available in goals buffer C-c C-a C- are now available in goal buffer. *** Experimental storing buffer To store the content of response or goals buffer in a dedicated persistent buffer (for later use), use Coq/Store response or Coq/Store goal. *** bug fixes, bugs - Three panes mode: "window would be too small" error fixed. - Indentation: several error fixed. If you want to indent tactics inside "Instance" or "Add Parametric Relation" etc, please put "Proof." before the tactics, there is no way for emacs to guess wether these commands initiate new goals or not. - coq prog args permanent settings is working again - when a proof is completed, the goals buffer is cleared again. ** Notable internal changes *** Altered prover configuration settings (internal) proof-terminal-char replaced by proof-terminal-string urgent message matching is now anchored; configurations for `proof-shell-clear-response-regexp', etc, must match strings which begin with `proof-shell-eager-annotation-start'. proof-shell-strip-output-markup: added for cut-and-paste proof-electric-terminator-noterminator: allows non-insert of terminator pg-insert-output-as-comment-fn: removed (use p-s-last-output) proof-shell-wakeup-char: removed (special chars deprecated) pg-use-specials-for-fontify: removed (ditto) proof-shell-prompt-pattern: removed (was only for shell UI) proof-shell-abort-goal-regexp: removed (ordinary response) proof-shell-error-or-interrupt-seen: removed, use p-s-last-output-kind proof-script-next-entity-regexps,next-entity-fn: removed (func-menu dead) proof-script-command-separator: removed (always a space) *** Simplified version of comint now used for proof shell (internal) To improve efficiency, a cut-down version of comint is now used. Editing, history and decoration in the shell (*coq*, *isabelle*, etc) are impoverished compared with PG 3.X. proofgeneral-4.3~pre130510/COMPATIBILITY000066400000000000000000000040211214562307500173600ustar00rootroot00000000000000Compatibility of Proof General ============================== This version of Proof General has been tested with these Emacs versions on recent Linux systems: Emacs 23.4 -- recommended and supported Emacs 23.3,23.2 -- previous versions, should work Emacs 24 (development) -- next version, should work Emacs 23.1, earlier -- obsolete versions, do NOT work and (main) prover versions: Coq 8.3, Isabelle2011[-1] See below for notes about other operating systems. Maintaining compatibility across proof assistant versions, Emacs versions and operating systems is virtually impossible. In the major 4.0 release ** XEmacs compatibility was dropped ** Running on Mac OS X ------------------- For tips, please see here: http://proofgeneral.inf.ed.ac.uk/wiki/PGEmacsOnMacOSX We recommend the 23.2 build of GNU Emacs, which builds natively on Mac OS X (based on the NextStep port). Binaries are available at various websites (e.g., http://emacsformacosx.com), or you can build your own by compiling from the FSF CVS. See the Emacs Wiki at http://www.emacswiki.org/emacs/EmacsForMacOS for more. Note that Mac compatibility isn't thoroughly tested. If you discover problems, please send a report and/or fix to the PG trac. Please add tips to the wiki page above. Running on Windows ------------------ For tips, please see here: http://proofgeneral.inf.ed.ac.uk/wiki/PGEmacsOnWindows We recommend EmacsW32 available at: http://www.ourcomments.org/Emacs/EmacsW32.html 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 Emacs in, e.g. c:\Program Files\Emacs\.emacs Note that Windows compatibility isn't tested by the maintainers. If you discover problems, please add notes on the Wiki page above, and submit patches to http://proofgeneral.inf.ed.ac.uk/trac proofgeneral-4.3~pre130510/COPYING000066400000000000000000000431101214562307500164610ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. proofgeneral-4.3~pre130510/FAQ000066400000000000000000000241601214562307500157640ustar00rootroot00000000000000FAQs for using Proof General ============================ With thanks to the anonymous authors of questions/answers below. For latest version, see http://proofgeneral.inf.ed.ac.uk/FAQ Please also check the BUGS file. ----------------------------------------------------------------- Q. Proof General fails to load with an error message on start-up, containing text like this: Proof General was compiled for GNU Emacs 23.1 but is running on Emacs 22.3: please run "make clean; make" What's wrong? A. We distribute compiled .elcs for one version of Emacs, but other versions use different bytecode formats. You will have to delete the compiled files and (optionally) recompile for your preferred Emacs version. Using the Makefile: make clean # removes all .elc files. and then a command like this: make EMACS=emacs-22.3 (without the EMACS setting just uses 'emacs'). ----------------------------------------------------------------- Q. I have just installed Emacs, ProofGeneral and a proof assistant. It works but Tokens (e.g. \) are not being displayed as symbols. A. You need to enable Unicode Tokens by the menu item: Proof-General -> Options -> Unicode Tokens To enable it automatically every time you use Proof General, use Proof-General -> Options -> Save Options after doing this. Note that we don't do this by default, because from the system's perspective it is difficult to determine if this will succeed --- or just produce funny characters that confuse new users even more. If you are using Isabelle, the wrapper script will load Tokens from any location, and you can enable it by passing the option "-x true". ----------------------------------------------------------------- Q. With Unicode symbols enabled, the symbols look a mess, e.g. compressed and overlap one another. A. Unfortunately this is a bug in the display engine inside certain versions of Emacs, for example the default version of emacs, Emacs 23.3.1 on Ubuntu 11.10, suffers. The solution is to switch to another version (e.g. Emacs 23.2). (See Trac#409: http://proofgeneral.inf.ed.ac.uk/trac/ticket/409) You may be able to get better results with different fonts, even without upgrading Emacs. Proof General uses Deja Vu Sans Mono by default because this often works out-of-the-box. But STIX is better if you install it. See http://www.stixfonts.org/. On Ubuntu try: sudo apt-get install fonts-stix To change to STIX, either M-x customize face RET unicode-tokens-symbol-font-face RET and edit to set the family name to "STIXGeneral", or edit the line beginning "(defface unicode-tokens-symbol-font-face" in lib/unicode-tokens.el. ----------------------------------------------------------------- Q. Help, I'm stuck!! Emacs keeps telling me "Cannot switch buffers in a dedicated window" A. This can happen if you enabled "Use Three Panes" and then change the panes (window) layout manually, typically by deleting another window or frame so you only have a "dedicated" window on the display. Don't kill Emacs! There are many ways of getting out, e.g. -- In single window mode, C-c C-l (proof-layout-windows) refreshes the display -- In multiple window mode, if you have accidently deleted the main window, get a new one with M-x new-frame RET ----------------------------------------------------------------- Q. I have a problem installing/using Proof General, what can I do? A. Please check the documentation carefully, particularly the requirements for a full-featured and recent Emacs version, as mentioned in INSTALL (see "Dependency on Other Emacs Packages"). If you still cannot solve your problem, try to contact someone else who is using Proof General with a similar setup. The best way to do this may be through the user mailing list for your proof assistant. If you think the problem is Proof General related, consult the PG Wiki and Trac pages. ----------------------------------------------------------------- Q. I'm using Proof General for prover X, then I load a file for prover Y. I get an error. Why? 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. 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 because of the missing parenthesis, but Proof General doesn't realise this and waits for a response. You should type something in the proof shell buffer (*isabelle*), 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. For options set in the Proof General -> Options menu use the "Save Options" menu item (Proof General -> Options -> Save Options). For other options set via customize (Proof General -> Advanced -> Customize), use the customize buttons, or M-x customize-save-customized. ----------------------------------------------------------------- Q. The "Favourites" feature to insert/send fixed strings is great, but I'd like to define a command which takes arguments. A. You can do that in Elisp with a command like this: (proof-definvisible isar-theorem '(format "thm %s" (read-string "theorem: ")) [(control t)]) (NB: it binds the key C-c C-a C-t). See the documentation for `proof-definvisible' and `proof-defshortcut`. ----------------------------------------------------------------- Q. Why do I get a warning "Bad version of xml.el found, ..."? A. Your Emacs distribution includes a version of xml.el which has fundamental bugs. The patched version of xml.el, in lib/xml-fixed.el has been loaded instead. This works for Proof General because it fixes the basic bugs, but it may cause compatibility issues in other packages (e.g. it is quite different from the latest xml.el with GNU Emacs development versions). This message is probably nothing to worry about unless you are using the same Emacs session for other packages that heavily use xml.el (e.g. GNUS). ----------------------------------------------------------------- Q. Undo behaviour in Coq seems to stop working with very long sequences of commands. A. Coq has a limited history for Undo. Change Coq -> Settings -> Undo Depth to something higher. Default is 200 (100 outside PG). ----------------------------------------------------------------- Q. Can I join any mailing lists for Proof General? A. Of course, email "proofgeneral-request@informatics.ed.ac.uk" with the line "subscribe" in the message body, to join the users' and announcements list. There is also a list for developers, proofgeneral-devel: http://proofgeneral.inf.ed.ac.uk/mailinglist for more details. ----------------------------------------------------------------- Q. Emacs appears to hang when the prover process is started. A. One thing is to check the variable 'comint-process-echoes' which might be non-nil for the *coq* (or other prover) buffer. It should be nil. The default value of comint-process-echoes is nil. Move any modifications of this variable away from the top level (e.g., .emacs file, which affects the *coq*-buffer), and down to the mode-hooks which require them (e.g. shell-mode-hook). The variable might also have been set by Customize, it can be reset with M-x customize-variable RET comint-process-echoes RET. A reason with older versions of Isabelle and Coq (before 2007) was the emergence of UTF-8 support in linuxes with Glibc 2.2 and later, enabled with UTF8 encoded output in your default locale. Proof General used on 8-bit characters which are UTF8 prefixes in the output of proof assistants. These prefix characters were not flushed to stdout individually. As a workaround we can disable interpretation of UTF8 in the C libraries. Doing this inside Proof General is unreliable; locale settings are set/inherited in strange ways. One solution is to run the Emacs process itself with an altered locale setting, e.g., $ LC_CTYPE=en_GB xemacs & (where $ is the shell prompt; this example is for my locale which by default is "en_GB.UTF-8": I see this by typing "locale" at the prompt). (This fix is attempted in the supplied "proofgeneral" script, as well as making an adjustment in Proof General when the string UTF appears in the current value of LC_CTYPE. Alternatively you can set LC_CTYPE inside a file ~/.i18n, which will be read the shell. Put a line such as "LC_CTYPE=en_GB" into this file. However, this action will affect all applications. NB: a related issue is warnings from X-Symbol: "Emacs language environment and system locale specify different encoding, I'll assume `iso-8859-1'". This warning appears to be mostly harmless. Notice that the variable `buffer-file-coding-system' may determine the format that files are saved in. Another way to affect this which has been suggested is to add a line like this to the init.el file on XEmacs: (prefer-coding-system 'ctext) but I haven't tried this. The above fixes should not be necessary with most recent prover versions. Isabelle 2007 has a "Unicode-safe" interaction mode, enabled by default (to disable, customise `proof-shell-unicode'). This is also used by the Isabelle startup scripts. Coq 8.1 and later do not use non-ASCII characters in output. $Id: FAQ,v 12.2 2012/04/30 13:17:13 da Exp $ proofgeneral-4.3~pre130510/INSTALL000066400000000000000000000124161214562307500164640ustar00rootroot00000000000000Short Instructions for installing Proof General (details below) =============================================================== Proof General runs on a variety of platforms and with a variety of Emacs versions; see COMPATIBILITY for further notes. To install, unpack the distribution somewhere. It will create a top-level directory containing Proof General, called Proof-General-. Put this line in your .emacs file: (load-file "/generic/proof-site.el") Where is replaced by the full path name to Proof-General-. 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 proof assistants, for example, visiting a file ending in .v will start Coq Proof General, and a file ending in .thy will start Isabelle Proof General. See the manual for a full list of file extensions and proof assistants, and the note below for how to disable those you don't need. 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 help, then contact me via the address below. David Aspinall, LFCS, School Of Informatics, University of Edinburgh. Edinburgh. http://proofgeneral.inf.ed.ac.uk/trac Detailed installation Notes for Proof General ============================================= Supported Emacs Versions. ------------------------- Please see COMPATIBILTY. If you're not sure of your version of Emacs, inspect the variable `emacs-version' by doing: C-h C-v emacs-version RET Other *recent* versions of either Emacs may also work, but please do not send bug reports for any version of Emacs which is more than a year older than the most recent stable release of that Emacs, unless you are reasonably sure that the bug has something to do with Proof General rather than Emacs. Unfortunately, compatibility across different Emacs versions is very difficult to maintain as APIs change frequently and bugs come and go between Emacs releases. Byte Compilation. ----------------- Compilation of the Emacs lisp files improves efficiency but can sometimes cause compatibility problems. In particular, byte compiled files are generally not compatible between different Emacs versions. We distribute .elcs for GNU Emacs 23.1, so you will have to delete them and (optionally) recompile for GNU Emacs 22. Use 'make clean' to remove all .elc files. Use 'make compile' to recompile .elc files. Check that the Makefile sets EMACS to your Emacs executable, or run 'make EMACS=/path/to/your/emacs' 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. These are the packages that you need to use Proof General: ESSENTIAL: * cl * custom * font-lock OPTIONAL: * outline * imenu * speedbar Included scripts ---------------- There are some included scripts which have hardwired paths. To try to edit these automatically to point to the right place, run make scripts 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-directory' 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, or using an automatically loaded file stored under site-start.d, if your distribution provides that. The provided Makefile will install everything in default locations: make install Will copy elisp, compiled elisp, documentation, and the "proofgeneral" shell script into perhaps sensible places. Try with "-n" or examine the Makefile carefully before use. Removing support for unwanted provers ------------------------------------- You cannot run more than one instance of Proof General at a time in the same Emacs process: 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 -> and the manual for more details. -------------------------------------------------------------------------- $Id: INSTALL,v 12.0 2011/10/13 10:54:47 da Exp $ proofgeneral-4.3~pre130510/Makefile000066400000000000000000000216421214562307500170740ustar00rootroot00000000000000## ## Makefile for Proof General. ## ## Author: David Aspinall ## ## make - do "compile" targets ## make compile - make .elc's ## make scripts - edit paths to bash/perl/PGHOME in scripts ## make install - install into system directories ## make clean - return to clean source ## ## Edit the EMACS setting below or call with an explicit one, like this: ## ## make EMACS=emacs-23.0.60 ## or ## make EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs ## ## $Id: Makefile,v 12.5 2013/01/15 21:48:49 tews Exp $ ## ########################################################################### # Set this according to your version of Emacs. # NB: this is also used to set default install path names below. EMACS=$(shell if [ -z "`which emacs`" ]; then echo "Emacs executable not found"; exit 1; else echo emacs; fi) # EMACS=/Applications/Emacs\ 23.4.app/Contents/MacOS/Emacs # We default to /usr rather than /usr/local because installs of # desktop and doc files under /usr/local are unlikely to work with # rest of the system. If that's no good for you, edit the paths # individually before the install section. # NB: DEST_PREFIX is used for final destination prefix, in case we're # packaging into a build prefix rather than live root (e.g. in rpmbuild). # NBB: DESTDIR provides for staged installs, for instance when building # Debian packages, see http://www.gnu.org/prep/standards/html_node/DESTDIR.html PREFIX=$(DESTDIR)/usr DEST_PREFIX=$(DESTDIR)/usr PWD=$(shell pwd) PROVERS=acl2 ccc coq hol98 isar lego hol-light phox pgshell pgocaml pghaskell OTHER_ELISP=generic lib contrib/mmm ELISP_DIRS=${PROVERS} ${OTHER_ELISP} ELISP_EXTRAS=isar/interface isar/isartags EXTRA_DIRS = images DOC_FILES=AUTHORS BUGS COMPATIBILITY CHANGES COPYING INSTALL README REGISTER doc/*.pdf DOC_EXAMPLES=acl2/*.acl2 hol98/*.sml isar/*.thy lclam/*.lcm lego/*.l pgshell/*.pgsh phox/*.phx plastic/*.lf twelf/*.elf DOC_SUBDIRS=${DOC_EXAMPLES} */README* */CHANGES */BUGS BATCHEMACS=${EMACS} --batch --no-site-file -q # Scripts to edit paths to shells BASH_SCRIPTS = isar/interface bin/proofgeneral PERL_SCRIPTS = lego/legotags coq/coqtags isar/isartags # Scripts to edit path to PG PG_SCRIPTS = bin/proofgeneral # Scripts to install to bin directory BIN_SCRIPTS = bin/proofgeneral lego/legotags coq/coqtags isar/isartags # Setting load path might be better 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 (mapcar (lambda (d) (concat "${PWD}/" (symbol-name d))) (quote (${ELISP_DIRS}))) load-path))' -eval '(progn (require (quote bytecomp)) (require (quote mouse)) (require (quote tool-bar)) (require (quote fontset)) (setq byte-compile-warnings (remove (quote cl-functions) (remove (quote noruntime) byte-compile-warning-types))) (setq byte-compile-error-on-warn t))' -f batch-byte-compile EL=$(shell for f in $(ELISP_DIRS); do ls $$f/*.el; done) ELC=$(EL:.el=.elc) .SUFFIXES: .el .elc default: all FORCE: ## ## compile : byte compile all lisp files ## ## Compiling can show up errors in the code, but be wary of fixing obsoletion ## or argument call warnings unless they're valid for all supported Emacsen. ## compile: $(EL) @echo "****************************************************************" @echo " Byte compiling... " @echo "****************************************************************" $(MAKE) elc @echo "****************************************************************" @echo " Finished." @echo "****************************************************************" ## ## Make an individual .elc. Building separately means we need to be ## careful to add proper requires in source files and prevent ## evaluating/optimising top-level forms too early. Using a separate ## emacs process for each file is slower but avoids any chance of ## accidently polluting the compilation environment, it also should ## work with make -j n. ## .el.elc: $(BYTECOMP) $*.el elc: $(ELC) ## ## Default targets ## all: compile ## ## Remove generated targets ## clean: cleanpgscripts rm -f $(ELC) .\#* */.\#* */.autotest.log */.profile.log (cd doc; $(MAKE) clean) distclean: clean ## ## Install files ## DESKTOP_PREFIX=${PREFIX} # Set Elisp directories according to paths used in Red Hat RPMs # (which may or may not be official Emacs policy). We generate # a pg-init.el file which loads the appropriate proof-site.el. ELISPP=share/${EMACS}/site-lisp/ProofGeneral ELISP_START=${PREFIX}/share/${EMACS}/site-lisp/site-start.d ELISP=${PREFIX}/${ELISPP} DEST_ELISP=${DEST_PREFIX}/${ELISPP} BINDIR=${PREFIX}/bin DESKTOP=${PREFIX}/share DOCDIR=${PREFIX}/share/doc/ProofGeneral MANDIR=${PREFIX}/share/man/man1 INFODIR=${PREFIX}/share/info install: install-desktop install-elisp install-bin install-init install-desktop: mkdir -p ${DESKTOP}/icons/hicolor/16x16 cp etc/desktop/icons/16x16/proofgeneral.png ${DESKTOP}/icons/hicolor/16x16 mkdir -p ${DESKTOP}/icons/hicolor/32x32 cp etc/desktop/icons/32x32/proofgeneral.png ${DESKTOP}/icons/hicolor/32x32 mkdir -p ${DESKTOP}/icons/hicolor/48x48 cp etc/desktop/icons/48x48/proofgeneral.png ${DESKTOP}/icons/hicolor/48x48 mkdir -p ${DESKTOP}/pixmaps cp etc/desktop/icons/48x48/proofgeneral.png ${DESKTOP}/pixmaps mkdir -p ${DESKTOP}/applications cp etc/desktop/proofgeneral.desktop ${DESKTOP}/applications mkdir -p ${DESKTOP}/mime-info cp etc/desktop/mime-info/proofgeneral.mime ${DESKTOP}/mime-info cp etc/desktop/mime-info/proofgeneral.keys ${DESKTOP}/mime-info # backwards compatibility with old linuxes mkdir -p ${DESKTOP}/application-registry cp etc/desktop/application-registry/proofgeneral.applications ${DESKTOP}/application-registry # NB: .el files are not strictly necessary, but we package/install them # for the time being to help with debugging, or for users to recompile. install-elisp: install-el install-elc # NB: "elisp" directory actually includes the extra subdirs in EXTRA_DIRS, # i.e. images. FIXME: we could put these elsewhere, but # then we would need to adjust paths in proof-site.el. # FIMXE 3: Michaël Cadilhac pointed out that 'cp -p' when used with # sudo to install will give users ownership instead of root. # Should use install program or fix ownerships afterwards here. install-el: mkdir -p ${ELISP} for f in ${ELISP_DIRS} ${EXTRA_DIRS}; do mkdir -p ${ELISP}/$$f; done for f in ${ELISP_DIRS}; do cp -pf $$f/*.el ${ELISP}/$$f; done for f in ${EXTRA_DIRS}; do cp -prf $$f/* ${ELISP}/$$f; done for f in ${ELISP_EXTRAS}; do cp -pf $$f ${ELISP}/$$f; done install-elc: compile mkdir -p ${ELISP} for f in ${ELISP_DIRS} ${EXTRA_DIRS}; do mkdir -p ${ELISP}/$$f; done for f in ${ELISP_DIRS}; do cp -pf $$f/*.elc ${ELISP}/$$f; done for f in ${ELISP_EXTRAS}; do cp -pf $$f ${ELISP}/$$f; done install-init: mkdir -p ${ELISP_START} echo ';;; pg-init.el --- setup for Proof General' > ${ELISP_START}/pg-init.el echo "(setq load-path (append load-path '(\"${DEST_ELISP}/generic\")))" >> ${ELISP_START}/pg-init.el echo "(require 'proof-site)" >> ${ELISP_START}/pg-init.el install-bin: scripts mkdir -p ${BINDIR} cp -pf ${BIN_SCRIPTS} ${BINDIR} install-doc: doc.info doc.pdf mkdir -p ${MANDIR} cp -pf doc/proofgeneral.1 ${MANDIR} mkdir -p ${INFODIR} cp -pf doc/*.info ${INFODIR} /sbin/install-info ${INFODIR}/ProofGeneral.info* ${INFODIR}/dir /sbin/install-info ${INFODIR}/PG-adapting.info* ${INFODIR}/dir mkdir -p ${DOCDIR} for f in ${DOC_FILES}; do cp -pf $$f ${DOCDIR}; done for f in ${DOC_EXAMPLES}; do mkdir -p ${DOCDIR}/`dirname $$f`; cp -pf $$f ${DOCDIR}/$$f; done doc: FORCE (cd doc; $(MAKE) EMACS=$(EMACS) $*) doc.%: FORCE (cd doc; $(MAKE) EMACS=$(EMACS) $*) ## ## scripts: try to patch bash and perl scripts with correct paths ## scripts: bashscripts perlscripts pgscripts 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) # FIXME: this next edit is really for install case, shouldn't be made # just when user types 'make' pgscripts: @(for i in $(PG_SCRIPTS); do \ sed "s|PGHOMEDEFAULT=.*$$|PGHOMEDEFAULT=${DEST_ELISP}|" < $$i > .tmp \ && cat .tmp > $$i; \ done; \ rm -f .tmp) # Set PGHOME path in scripts back to default location. cleanpgscripts: @(for i in $(PG_SCRIPTS); do \ sed "s|PGHOMEDEFAULT=.*$$|PGHOMEDEFAULT=\$$HOME/ProofGeneral|" < $$i > .tmp \ && cat .tmp > $$i; \ done; \ rm -f .tmp) ## ## Include developer's makefile if it exists here. ## -include Makefile.devel proofgeneral-4.3~pre130510/Makefile.devel000066400000000000000000000504171214562307500201740ustar00rootroot00000000000000## -*- makefile -*- ## ## Makefile for Proof General development. ## ## Author: David Aspinall ## ## Maintainer: Proof General maintainer ## ## Developer use only, not part of user distribution. ## ## make clean - remove intermediate files ## make distclean - remove all generated files ## ## make elisptidy - tidy up elisp files (run whitespace-cleanup) ## ## 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 pkg - make Emacs tar file packages (Tromey's package.el) ## ## 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 golive - publish previously built distribution ## ## make links - add some links which help testing web pages ## from the html directory. ## ## make releaseclean - clean up after 'make dist' 'make rpmrelease'. ## ## make testall.emacs23- run all autotest files in Emacs named "emacs23" ## ## ## Notes: ## ## Use 'make releaseclean' if giving up, to remove temp dirs. ## ## NB: no facility to edit html to make a full release in this Makefile. ## Edit download.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 ## ## ## $Id: Makefile.devel,v 12.3 2012/10/19 16:23:42 da Exp $ ## ########################################################################### ## TODO: could include prerel tag in web pages, and link using -latest ## sym links. Would avoid needing to edit html below. # Names and real mail addresses of developers # Arguments for rcs2log for ChangeLog target # NB: must use TAB as separator in list below. DEVELOPERS=\ -u "da David Aspinall da@inf.ed.ac.uk" \ -u "gkein Gerwin Klein gklein@in.tum.de" \ -u "sberghof Stefan Berghofer berghofe@in.tum.de" \ -u "markus Makarius makarius@sketis.net" \ -u "makarius Makarius makarius@sketis.net" \ -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 da+pg-patrl@inf.ed.ac.uk" \ -u "tms Thomas Kleymann da+pg-tms@inf.ed.ac.uk" \ -u "djs Dilip Sequiera da+pg-djs@inf.ed.ac.uk" \ -u "hhg Healfdene Goguen da+pg-hhg@inf.ed.ac.uk" \ -u "gklein Gerwin Klein gerwin.klein@nicta.com.au" \ -u "assia Assia Mahboubi assia.mahboubi@inria.fr" \ -u "monnier Stefan Monnier monnier@iro.umontreal.ca" \ -u "tews Hendrik Tews hendrik@askra.de" # PRERELEASE_PREFIX is used to match PRERELEASE_TAG in sed # line in tag target below, which edits $(DOWNLOADHTML) # The prereltag.txt is kept as a record in the distrib area # of the current pre-release version (currently not used explicitly # anywhere for web pages/whatever). PRERELEASE_PREFIX=4\.3pre PRERELEASE_TAG=4.3pre$(shell date "+%y%m%d") PREREL_TAG_FILE=prereltag.txt # Path to web pages in repository, used for automatically # updating with release information. HTMLDIR=../web DOWNLOADHTMLS=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) # devel just means developer's package, with more files. # bit ambiguous: "development version" means latest version, # in development. # LATESTNAME is linked to the development version. # NAME is linked to the current release. NAME = ProofGeneral LATESTNAME = $(NAME)-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) CVS_RELEASENAME = Release-$(CVS_VERSION) # Where to release (i.e. copy) a new distribution to. # This may be the final directory (local) or temporary directory. # was: RELEASEDIR = /home/proofgen/www RELEASEDIR = /tmp/proofgeneral-www # How to make the release "live". (Could be "true" to do nothing). GOLIVE=rsync -e ssh -auv $(RELEASEDIR)/* ssh.inf.ed.ac.uk:/group/project/proofgeneral/web/releases/ CVSNAME = ProofGeneral # Remote commands to use CVS in server mode and install files. # With these settings the build can be done remotely. # CVSROOT = :pserver:da@cvs.inf.ed.ac.uk:/disk/cvs/proofgen # FIXME: this command causes an error on some recursive calls, e.g. to do # make clean in a non cvs directory. CVSROOT=$(shell cat CVS/Root) # Emacs for batch compiling BATCHEMACS=$(EMACS) -batch -q -no-site-file # Emacs for interactive use in testing EMACSFLAGS=-q -no-site-file # GNU version of tar, please TAR=tar # Files not to include the distribution area or tarball UNFINISHED_ELISP= ETC_FILES=etc/lego etc/coq etc/demoisa etc/isa etc/isar etc/lego etc/patches etc/*.txt NONDISTFILES=.cvsignore */.cvsignore Makefile.devel doc/ProofGeneral.jpg etc/trac etc/testsuite $(UNFINISHED_ELISP) $(ETC_FILES) DOCDISTFILES=ProofGeneral.info PG-adapting.info # 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! IGNOREDFILES=ProofGeneral*/TAGS ProofGeneral*/doc/ProofGeneral.pdf ProofGeneral*/doc/PG-adapting.pdf ProofGeneral*/doc/docstring-magic.el ProofGeneral*/etc/TESTS # Temporary directory to to build a distribution in DISTBUILDIR = /tmp/ProofGeneralRelease # Temporary dmg root for building Mac OS X disk image files. DMGTOPDIR=/tmp/$(NAME)-dmg RELEASENAMETGZ = $(RELEASENAME).tgz RELEASENAMERPM = $(RELEASENAME)-1.noarch.rpm RELEASENAMEDMG = $(RELEASENAME).dmg # Where to install a distribution DISTINSTALLDIR=/usr/local/share/elisp/proofgeneral SUBDIRS=$(ELISP_DIRS) etc doc images PWD=$(shell pwd) FORCE: # Targets to pre-compile for distribution # Warning: elisp files are incompatible across emacs versions! alldist: distcompile distdocs ############################################################ # # Make tags file # TAGS_EXTRAS= ETAGS=etags tags: $(EL) $(TAGS_EXTRAS) $(ETAGS) $(EL) $(TAGS_EXTRAS) doc/ProofGeneral.texi doc/PG-adapting.texi > TAGS ############################################################ # # Run tests for a particular prover and particular Emacs # run.%: $(EMACS) $(EMACSFLAGS) -l generic/proof-site.el -eval '(proof-visit-example-file "$*")' test.%: if [ -f "$*/$*-autotest.el" ]; then if $(EMACS) $(EMACSFLAGS) -l generic/proof-site.el $*/$*-autotest.el -f eval-current-buffer; then echo "Autotests for $* run successfully on `date`"; else cat $*/.autotest.log; echo "Autotests for $* ran with failures on `date`"; exit 1; fi; fi profile.%: if [ -f "$*/$*-profiling.el" ]; then if $(EMACS) $(EMACSFLAGS) -l generic/proof-site.el $*/$*-profiling.el -f eval-current-buffer; then echo "Profiling for $* run successfully on `date`"; else echo "Profiling for $* ran with failures on `date`"; exit 1; fi; cat $*/.profile.log; fi testall.%: for prover in ${PROVERS}; do $(MAKE) test.$$prover EMACS=$*; done ############################################################ # # Add recent messages to ChangeLog. CVSROOT must be set correctly. # # FIXME: this duplicates entries made on the same day: we could do # with a way of cleaning the last day from the ChangeLog. # # Debian default path RCS2LOG=/usr/share/cvs/contrib/rcs2log ChangeLog: FORCE $(RCS2LOG) -h "inf.ed.ac.uk" $(DEVELOPERS) -r -b -i 4 | sed 's|/home/proofgen/src/ProofGeneral/||g' > ChangeLog.prefix if [ -f ChangeLog ]; then mv ChangeLog ChangeLog.old; else echo > ChangeLog.old; fi cat ChangeLog.prefix ChangeLog.old | sed 's|/disk/cvs/proofgen/ProofGeneral/||g' > ChangeLog rm ChangeLog.prefix ChangeLog.old logupdate: ChangeLog.gz cvs commit -m"Updated" ChangeLog.gz ############################################################ # # Clean up intermediate files # devclean: FORCE @echo "***** CLEANING UP INTERMEDIATE FILES ****" rm -f doc/ProofGeneralPortrait.eps.gz rm -f $(HTMLDIR)/ProofGeneral ############################################################ # # Clean up intermediate files, all generated files # and Emacs backups, CVS temps # distclean: devclean clean @echo "***** CLEANING UP ALL JUNK FILES ****" find . \( -name '*~' -o -name '#*#' -o -name '\.\#*' -o -name '\.*\.log' \) -print | xargs rm -f (cd doc; $(MAKE) distclean) ############################################################ # # Clean up all non-cvs files. # cvsclean: clean @echo "***** CLEANING UP ALL NON-CVS FILES ****" # rm -rf $(FILES_NONCVS) (cd doc; $(MAKE) distclean) ############################################################ # # autoloads in generic/ # autoloads: $(EL) @echo "***** MAKING AUTOGENERATED AUTOLOADS ****" $(BATCHEMACS) -eval '(setq autoload-package-name "proof" generated-autoload-file "$(PWD)/generic/proof-autoloads.el")' -f batch-update-autoloads generic/ lib/ ############################################################ # # Elisp tidy # tidy: $(EL) @echo "***** CLEANUP ELISP FILES ****" for f in $(EL); do echo "Cleaning $$f"; $(BATCHEMACS) -eval "(progn (find-file \"$$f\") (whitespace-cleanup) (save-buffer))"; done ############################################################ # # Documentation # distdocs: FORCE @echo "***** MAKING DISTRIBUTION DOCS ****" (cd doc; ln -s $(HTMLDIR)/ProofGeneralPortrait.eps.gz .; $(MAKE) dist) ############################################################ # # Compilation # distcompile: FORCE @echo "***** MAKING ELC FILES ****" $(MAKE) compile ############################################################ ## ## 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 $(DOWNLOADHTMLS) ## if VERSION matches PRERELEASE_TAG. ## tag: @echo "*************************************************" @echo " Tagging sources... (you must 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 -Pd | grep '^[MC] '`" ]; then cvs update -Pd; exit 1; fi # Update version in proof-site.el (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) # Tag ProofGeneral.spec (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 $(DOWNLOADHTMLS) only for prereleases. # Careful: the sed command below relies on previous value of PRERELEASE_TAG. if [ $(PRERELEASE_TAG) = $(VERSION) ]; then \ (cd $(HTMLDIR); \ for f in $(DOWNLOADHTMLS); do \ mv $$f $$f.old; \ sed -e 's|ProofGeneral\([emacselc-]*\)-$(PRERELEASE_PREFIX)......|ProofGeneral\1-$(PRERELEASE_TAG)|g' $$f.old > $$f; \ rm $$f.old; \ done) \ fi if [ -z "$(NOCVS)" ]; then cvs commit -m"Set version tag for new release." generic/$(VERSIONFILE) etc/ProofGeneral.spec; (cd $(HTMLDIR); cvs commit -m"Set version tag for new release." $(DOWNLOADHTMLS)); fi if [ -z "$(NOCVS)" ]; then cvs tag -cF "$(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. ## (NB: lines in subshells here inherit CVSROOT settings from above) ## cvsexport: @echo "*************************************************" @echo " Cleaning build directory and running cvs export..." @echo "*************************************************" rm -rf $(DISTBUILDIR) mkdir -p $(DISTBUILDIR) if [ -z "$(NOCVS)" ]; then \ (cd $(DISTBUILDIR); \ cvs -d $(CVSROOT) export -kv -r "${CVS_RELEASENAME}" -d ${RELEASENAME} ${CVSNAME}) \ else \ mkdir -p $(DISTBUILDIR)/$(RELEASENAME); \ cp -pr . $(DISTBUILDIR)/$(RELEASENAME); \ fi dist: cvsexport @echo "*************************************************" @echo " Running 'make alldist' for new release .." @echo "*************************************************" (cd $(DISTBUILDIR)/$(RELEASENAME); $(MAKE) alldist) @echo "*************************************************" @echo " Cleaning and copying doc files .." @echo "*************************************************" (cd $(DISTBUILDIR)/$(RELEASENAME)/doc; cp -pr $(DOCDISTFILES) $(DISTBUILDIR)) (cd $(DISTBUILDIR)/$(RELEASENAME)/doc; $(MAKE) clean) (cd $(DISTBUILDIR); cp -pr $(DOCDISTFILES) $(RELEASENAME)/doc) @echo "*************************************************" @echo " Cleaning non-distributed files .." @echo "*************************************************" (cd $(DISTBUILDIR)/$(RELEASENAME); rm -rf $(NONDISTFILES)) @echo "*************************************************" @echo " Making compressed tar file..." @echo "*************************************************" -(cd $(DISTBUILDIR); ls $(IGNOREDFILES) > ignoredfiles; echo ignoredfiles >> ignoredfiles) # link the long name to short name for convenience of user (cd $(DISTBUILDIR); ln -sf $(RELEASENAME) $(NAME)) $(TAR) cvzf $(DISTBUILDIR)/$(RELEASENAMETGZ) --directory $(DISTBUILDIR) --exclude-from $(DISTBUILDIR)/ignoredfiles $(RELEASENAME) $(NAME) # remove temporary files made for tar/zip only (cd $(DISTBUILDIR); rm -f ignoredfiles $(NAME)) @echo "*************************************************" @echo " Finished making dist." @echo "*************************************************" ############################################################ ## ## release: ## tag the CVS sources, and make a distribution. ## Then install the distribution in RELEASEDIR ## WARNING: RELEASEDIR is not cleaned except to remove ## links, but files there with same names will be overwritten. ## release: distclean tag dist @echo "*************************************************" @echo " Making release (installing tarball distributions)." @echo "*************************************************" mkdir -p $(RELEASEDIR) (cd $(DISTBUILDIR); rm -f $(NAME)) (cd $(RELEASEDIR); rm -rf $(RELEASENAME)) cp -pfdR $(DISTBUILDIR)/* $(RELEASEDIR) (cd $(RELEASEDIR); rm -f $(LATESTNAME); ln -s $(RELEASENAME) $(LATESTNAME)) (cd $(RELEASEDIR); ln -sf $(RELEASENAMETGZ) $(LATESTNAME).tgz) (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) ## ## # Temporary RPM topdir for building packages as non-root user. RPMTOPDIR=/tmp/$(NAME)-rpm RPMBUILD=rpmbuild --define '_topdir $(RPMTOPDIR)' rpm: rm -rf $(RPMTOPDIR) mkdir -p $(RPMTOPDIR)/RPMS mkdir -p $(RPMTOPDIR)/SPECS mkdir -p $(RPMTOPDIR)/SOURCES mkdir -p $(RPMTOPDIR)/BUILD $(RPMBUILD) -tb $(DISTBUILDIR)/$(RELEASENAMETGZ) ############################################################ ## ## pkg: ## Build an Emacs .tar file package ## PKGMOVES=doc/dir doc/ProofGeneral.info doc/PG-adapting.info PKGDELETES=obsolete etc doc # Emacs package version is fussy about non-numbers in version, have to make version # from date. PKG_VERSION=$(shell echo $(FULLVERSION) | sed 's/$(PRERELEASE_PREFIX)/20/g' | sed 's/RC/\.0/g') PKG_RELEASENAME=$(NAME)-$(PKG_VERSION) pkg: cvsexport (cd $(DISTBUILDIR); if [ "$(RELEASENAME)" != "$(PKG_RELEASENAME)" ]; then mv $(RELEASENAME) $(PKG_RELEASENAME); fi) (cd $(DISTBUILDIR)/$(PKG_RELEASENAME)/doc; make info) (cd $(DISTBUILDIR)/$(PKG_RELEASENAME); mv $(PKGMOVES) .; rm -rf $(PKGDELETES)) (cd $(DISTBUILDIR)/$(PKG_RELEASENAME); echo '(define-package "ProofGeneral" "$(PKG_VERSION)" "Proof General theorem prover interface")' > ProofGeneral-pkg.el) (cd $(DISTBUILDIR); tar -cf $(PKG_RELEASENAME).tar $(PKG_RELEASENAME)) ############################################################ ## ## rpmrelease: ## Build and install RPM package into RELEASEDIR. ## rpmrelease: rpm cp -pf $(RPMTOPDIR)/RPMS/noarch/* $(RELEASEDIR) ############################################################ ## ## dmg: [experimental] ## Build (on Linux) a Mac OS X dmg disk image file ## This requires sudo powers for mounting, and ## (on Ubuntu), packages hfsplus and hfsprogs ## DMGBUILD=$(DISTBUILDIR)/dmg dmg: rm -rf $(DMGBUILD) mkdir -p $(DMGBUILD) dd if=/dev/zero of=$(DISTBUILDIR)/$(RELEASENAMEDMG) bs=1 count=0 seek=16M /sbin/mkfs.hfsplus -v $(RELEASENAME) -s $(DISTBUILDIR)/$(RELEASENAMEDMG) (cd $(DMGBUILD); mkdir dmgfs; \ sudo mount -t hfsplus -o loop,user $(DISTBUILDIR)/$(RELEASENAMEDMG) dmgfs; \ sudo chown $(LOGNAME) dmgfs; \ $(TAR) -xpzf $(DISTBUILDIR)/$(RELEASENAMETGZ); \ mkdir -p Contents/Resources; \ mkdir -p Contents/MacOS; \ mv $(NAME)/bin/proofgeneral Contents/MacOS; \ mv $(NAME)/* Contents/Resources; \ rm -rf $(NAME) $(RELEASENAME); \ mkdir $(NAME).app; \ mv Contents $(NAME).app;\ sudo umount dmgfs) # on mac: # hdiutil create -srcfolder $(DISTBUILDIR) ############################################################ ## ## 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 releaseclean NOCVS="no" ############################################################ ## ## releaseall: ## Do everything! (EXCEPT: ChangeLog.gz update) ## releaseall: release releaseclean golive ############################################################ ## ## golive: ## Execute golive command. ## golive: $(GOLIVE) cd $(HTMLDIR); for f in $(DOWNLOADHTMLS); do $(MAKE) pub.$$f; done; rm -rf $(RELEASEDIR) ############################################################ ## ## releasefinal: ## Do everything for a final release based on a pre-release. ## Except editing download file. ## releasefinal: release releaseclean # Link the latest version (cd $(DISTBUILDIR); rm -f $(NAME); ln -sf $(RELEASENAME) $(NAME)) ############################################################ ## ## 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)/$(RELEASENAMETGZ); \ mv $(RELEASENAME) $(NAME)) ############################################################ # # links: # # Make some handy links for developers. # links: ln -sf $(HTMLDIR)/ProofGeneralPortrait.eps.gz doc ln -sf ../../ProofGeneral $(HTMLDIR) ################################################################# ## ## Reporting Makefile settings. ## ## Useful for debugging Makefile show.%: @echo $($*) proofgeneral-4.3~pre130510/README000066400000000000000000000036201214562307500163100ustar00rootroot00000000000000 Proof General --- Organize your proofs! Proof General is a generic Emacs interface for proof assistants. The aim of the Proof General project is to provide a powerful, generic environment for using interactive proof assistants. This is version 4.2 (prerelease) of Proof General. See About for exact version. It is built for Emacs 23.3. The code *may* also work with previous emacs versions, back as far as Emacs 22.3. But you will need to regenerated the byte-compiled files with "make clean; make compile". Backward compatibility cannot be guaranteed. See INSTALL for installation details. COPYING for license details. COMPATIBILITY for version compatibility information. REGISTER for registration information (please register). FAQ, doc/ for documentation of Proof General. /README for additional prover-specific notes Links: Bug/feature reports: http://proofgeneral.inf.ed.ac.uk/trac Wiki: http://proofgeneral.inf.ed.ac.uk/wiki Lists: http://proofgeneral.inf.ed.ac.uk/mailinglist Supported proof assistants: Coq, Isabelle, LEGO, PhoX Experimental (less useful): CCC,ACL2,HOL98,Hol-Light,Lambda-Clam,Shell,Twelf Obsolete instances: Demoisa,Lambda-Clam,Plastic A few example proofs are included in each prover subdirectory. The "root2" proofs of the irrationality of the square root of 2 were proofs written for Freek Wiedijk's challenge in his comparison of different theorem provers, see http://www.cs.kun.nl/~freek/comparison/. Those proof scripts are copyright by their named authors. (NB: most of these have rusted) Check BUGS files for some static problems and issues. Please report new bugs on the Trac site at http://proofgeneral.inf.ed.ac.uk/trac. For the latest news and downloads, visit Proof General on the web at: http://proofgeneral.inf.ed.ac.uk David Aspinall October 2011. proofgeneral-4.3~pre130510/REGISTER000066400000000000000000000006261214562307500166020ustar00rootroot00000000000000Please register your use of Proof General on the web at: http://proofgeneral.inf.ed.ac.uk/register The information provided will only be used to help 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://proofgeneral.inf.ed.ac.uk/mailinglist proofgeneral-4.3~pre130510/TAGS000066400000000000000000003772271214562307500161320ustar00rootroot00000000000000 ccc/ccc.el,87 (defvar ccc-keywords 17,587 (defvar ccc-tactics 18,613 (defvar ccc-tacticals 19,638 coq/coq-abbrev.el,590 (defun holes-show-doc 12,313 (defun coq-local-vars-list-show-doc 16,390 (defconst coq-tactics-menu21,490 (defconst coq-tactics-abbrev-table26,746 (defconst coq-tacticals-menu29,863 (defconst coq-tacticals-abbrev-table33,972 (defconst coq-commands-menu36,1063 (defconst coq-commands-abbrev-table43,1286 (defconst coq-terms-menu46,1375 (defconst coq-terms-abbrev-table51,1513 (defun coq-install-abbrevs 58,1707 (defconst coq-menu-common-entries81,2663 (defpgdefault menu-entries179,7146 (defpgdefault help-menu-entries213,8253 (defpgdefault other-buffers-menu-entries 217,8383 coq/coq-compile-common.el,2047 (defun get-coq-library-directory 31,821 (defconst coq-library-directory 37,1008 (defcustom coq-dependency-analyzer40,1135 (defcustom coq-compiler46,1275 (defun coq-par-enable 60,1800 (defun coq-par-disable 70,2161 (defun coq-seq-enable 80,2541 (defun coq-seq-disable 86,2747 (defun coq-load-path-safep 95,2998 (defun coq-switch-compilation-method 115,3594 (defun number-of-cpus 124,3829 (defvar coq-internal-max-jobs 138,4170 (defun coq-max-jobs-setter 141,4279 (defgroup coq-auto-compile 157,4741 (defpacustom compile-before-require 162,4892 (defpacustom compile-parallel-in-background 174,5384 (defcustom coq-max-background-compilation-jobs 195,6275 (defcustom coq-compile-command 209,6964 (defconst coq-compile-substitution-list239,8243 (defcustom coq-load-path 259,9164 (defcustom coq-compile-auto-save 296,10909 (defcustom coq-lock-ancestors 321,11966 (defpacustom confirm-external-compilation 330,12287 (defcustom coq-load-path-include-current 339,12594 (defcustom coq-compile-ignored-directories 348,12912 (defcustom coq-compile-ignore-library-directory 361,13544 (defcustom coq-coqdep-error-regexp373,14032 (defconst coq-require-command-regexp390,14811 (defconst coq-require-id-regexp397,15168 (defvar coq-compile-history 405,15602 (defvar coq-compile-response-buffer 408,15686 (defvar coq-debug-auto-compilation 412,15821 (defun time-less-or-equal 418,15930 (defun coq-max-dep-mod-time 426,16268 (defun coq-option-of-load-path-entry 449,17073 (defun coq-include-options 463,17588 (defun coq-prog-args 487,18607 (defun coq-compile-ignore-file 496,18880 (defun coq-library-src-of-obj-file 522,19802 (defun coq-unlock-ancestor 531,20126 (defun coq-unlock-all-ancestors-of-span 538,20421 (defun coq-init-compile-response-buffer 546,20706 (defun coq-display-compile-response-buffer 569,21778 (defvar coq-compile-buffer-with-current-require582,22297 (defun coq-compile-save-buffer-filter 588,22533 (defun coq-compile-save-some-buffers 599,22959 (defun coq-switch-buffer-kill-proof-shell 624,23913 coq/coq-db.el,678 (defconst coq-syntax-db 24,596 (defun coq-insert-from-db 70,2319 (defun coq-build-regexp-list-from-db 88,3050 (defun coq-build-opt-regexp-from-db 107,3856 (defun max-length-db 126,4677 (defun coq-build-menu-from-db-internal 138,4952 (defun coq-build-title-menu 175,6493 (defun coq-sort-menu-entries 184,6861 (defun coq-build-menu-from-db 190,6991 (defcustom coq-holes-minor-mode 212,7830 (defun coq-build-abbrev-table-from-db 218,7974 (defun filter-state-preserving 237,8600 (defun filter-state-changing 242,8754 (defface coq-solve-tactics-face249,8975 (defface coq-cheat-face258,9266 (defconst coq-solve-tactics-face 266,9515 (defconst coq-cheat-face 270,9679 coq/coq.el,8939 (defcustom coq-prog-name61,2049 (defcustom coq-translate-to-v8 80,2900 (defun coq-build-prog-args 85,3015 (defcustom coq-use-makefile 95,3338 (defcustom coq-default-undo-limit 101,3510 (defconst coq-shell-init-cmd106,3638 (defcustom coq-prog-env 115,3965 (defconst coq-shell-restart-cmd 123,4214 (defvar coq-shell-prompt-pattern125,4268 (defvar coq-shell-cd 133,4571 (defvar coq-shell-proof-completed-regexp 137,4731 (defvar coq-goal-regexp140,4946 (defcustom coq-tags 144,5037 (defconst coq-interrupt-regexp 149,5185 (defcustom coq-www-home-page 152,5278 (defcustom coq-end-goals-regexp-show-subgoals 157,5385 (defcustom coq-end-goals-regexp-hide-subgoals164,5669 (defgroup coq-proof-tree 175,6001 (defcustom coq-proof-tree-ignored-commands-regexp183,6364 (defcustom coq-navigation-command-regexp192,6758 (defcustom coq-proof-tree-cheating-regexp199,7012 (defcustom coq-proof-tree-new-layer-command-regexp205,7152 (defcustom coq-proof-tree-current-goal-regexp211,7358 (defcustom coq-proof-tree-update-goal-regexp219,7694 (defcustom coq-proof-tree-additional-subgoal-ID-regexp226,7928 (defcustom coq-proof-tree-existential-regexp 232,8126 (defcustom coq-proof-tree-instantiated-existential-regexp237,8280 (defcustom coq-proof-tree-existentials-state-start-regexp243,8500 (defcustom coq-proof-tree-existentials-state-end-regexp 249,8690 (defcustom coq-proof-tree-branch-finished-regexp254,8859 (defvar coq-outline-regexp270,9360 (defvar coq-outline-heading-end-regexp 279,9634 (defvar coq-shell-outline-regexp 281,9688 (defvar coq-shell-outline-heading-end-regexp 282,9738 (defconst coq-state-preserving-tactics-regexp285,9802 (defconst coq-state-changing-commands-regexp287,9904 (defconst coq-state-preserving-commands-regexp289,10013 (defconst coq-commands-regexp291,10126 (defvar coq-retractable-instruct-regexp293,10205 (defvar coq-non-retractable-instruct-regexp295,10297 (defcustom coq-use-smie 327,10993 (defconst coq-script-command-end-regexp 352,11831 (defun coq-script-parse-function 361,12260 (defun coq-set-undo-limit 368,12486 (defun build-list-id-from-string 374,12618 (defun coq-last-prompt-info 383,13093 (defun coq-last-prompt-info-safe 401,13987 (defvar coq-last-but-one-statenum 409,14340 (defvar coq-last-but-one-proofnum 416,14637 (defvar coq-last-but-one-proofstack 419,14735 (defsubst coq-get-span-statenum 422,14845 (defsubst coq-get-span-proofnum 426,14960 (defsubst coq-get-span-proofstack 430,15075 (defsubst coq-set-span-statenum 434,15219 (defsubst coq-get-span-goalcmd 438,15350 (defsubst coq-set-span-goalcmd 442,15464 (defsubst coq-set-span-proofnum 446,15594 (defsubst coq-set-span-proofstack 450,15725 (defsubst proof-last-locked-span 454,15885 (defun proof-clone-buffer 458,16019 (defun proof-store-buffer-win 472,16556 (defun proof-store-response-win 483,17049 (defun proof-store-goals-win 487,17176 (defun coq-set-state-infos 499,17708 (defun count-not-intersection 537,19798 (defun coq-find-and-forget 567,21050 (defvar coq-current-goal 594,22355 (defun coq-goal-hyp 597,22420 (defun coq-state-preserving-p 610,22900 (defun coq-hide-additional-subgoals-switch 620,23194 (defconst notation-print-kinds-table632,23535 (defun coq-PrintScope 636,23702 (defun coq-remove-trailing-dot 654,24251 (defun coq-id-at-point 662,24488 (defun coq-guess-or-ask-for-string 676,25051 (defun coq-ask-do 695,25666 (defun coq-flag-is-on-p 704,26049 (defun coq-command-with-set-unset 710,26256 (defun coq-ask-do-set-unset 721,26906 (defun coq-ask-do-show-implicits 731,27436 (defun coq-ask-do-show-all 739,27796 (defsubst coq-put-into-brackets 760,28477 (defsubst coq-put-into-quotes 763,28538 (defun coq-SearchIsos 766,28597 (defun coq-SearchConstant 774,28836 (defun coq-Searchregexp 778,28929 (defun coq-SearchRewrite 784,29070 (defun coq-SearchAbout 788,29167 (defun coq-Print 794,29310 (defun coq-Print-with-implicits 802,29580 (defun coq-Print-with-all 807,29734 (defun coq-About 812,29876 (defun coq-About-with-implicits 819,30083 (defun coq-About-with-all 824,30232 (defun coq-LocateConstant 830,30370 (defun coq-LocateLibrary 835,30473 (defun coq-LocateNotation 840,30590 (defun coq-Pwd 848,30821 (defun coq-Inspect 853,30945 (defun coq-PrintSection(857,31045 (defun coq-Print-implicit 861,31138 (defun coq-Check 866,31289 (defun coq-Check-show-implicits 874,31543 (defun coq-Check-show-all 879,31681 (defun coq-get-response-string-at 884,31807 (defun coq-Show 898,32397 (defun coq-Show-with-implicits 928,33805 (defun coq-Show-with-all 933,33961 (defun coq-Compile 960,35338 (defun coq-guess-command-line 972,35663 (defun coq-mode-config 1030,38015 (defun coq-shell-mode-config 1141,42123 (defun coq-goals-mode-config 1234,46070 (defun coq-response-config 1241,46314 (defpacustom hide-additional-subgoals 1264,47031 (defpacustom printing-depth 1285,47694 (defpacustom undo-depth 1290,47855 (defpacustom time-commands 1295,48021 (defun coq-proof-tree-get-proof-info 1305,48226 (defun coq-extract-instantiated-existentials 1315,48614 (defun coq-show-sequent-command 1324,49006 (defun coq-proof-tree-get-new-subgoals 1328,49160 (defun coq-find-begin-of-unfinished-proof 1372,51285 (defun coq-proof-tree-find-undo-position 1390,52119 (defun coq-preprocessing 1410,52860 (defun coq-fake-constant-markup 1424,53315 (defun coq-create-span-menu 1440,53920 (defconst module-kinds-table1458,54433 (defconst modtype-kinds-table1462,54582 (defun coq-postfix-.v-p 1466,54711 (defun coq-directories-files 1469,54772 (defun coq-remove-dot-v-extension 1475,55000 (defun coq-load-path-to-paths 1478,55061 (defun coq-build-accessible-modules-list 1481,55140 (defun coq-insert-section-or-module 1488,55457 (defconst reqkinds-kinds-table1510,56337 (defun coq-insert-requires 1514,56494 (defun coq-end-Section 1528,57047 (defun coq-insert-intros 1546,57625 (defvar coq-commands-accepting-as 1559,58157 (defvar coq-last-input-action 1561,58256 (defun coq-insert-infoH 1567,58472 (defun coq-auto-insert-as 1581,59137 (defpacustom auto-insert-as 1591,59551 (defun coq-tactic-already-has-an-as-close(1598,59786 (defun coq-insert-as 1613,60551 (defun coq-insert-as-in-region 1652,62647 (defun coq-insert-match 1664,62920 (defun coq-insert-solve-tactic 1693,64089 (defun coq-insert-tactic 1699,64340 (defun coq-insert-tactical 1705,64542 (defun coq-insert-command 1711,64773 (defun coq-insert-term 1716,64938 (define-key coq-keymap 1722,65121 (define-key coq-keymap 1723,65179 (define-key coq-keymap 1724,65236 (define-key coq-keymap 1725,65305 (define-key coq-keymap 1726,65361 (define-key coq-keymap 1727,65419 (define-key coq-keymap 1728,65469 (define-key coq-keymap 1729,65542 (define-key coq-keymap 1730,65599 (define-key coq-keymap 1731,65662 (define-key coq-keymap 1734,65740 (define-key coq-keymap 1735,65789 (define-key coq-keymap 1736,65844 (define-key coq-keymap 1737,65896 (define-key coq-keymap 1738,65951 (define-key coq-keymap 1739,66001 (define-key coq-keymap 1740,66051 (define-key coq-keymap 1741,66107 (define-key coq-keymap 1742,66157 (define-key coq-keymap 1743,66201 (define-key coq-keymap 1744,66260 (define-key coq-goals-mode-map 1752,66528 (define-key coq-goals-mode-map 1753,66610 (define-key coq-goals-mode-map 1754,66692 (define-key coq-goals-mode-map 1755,66779 (define-key coq-goals-mode-map 1756,66861 (define-key coq-goals-mode-map 1757,66949 (define-key coq-goals-mode-map 1758,67030 (define-key coq-goals-mode-map 1759,67117 (define-key coq-goals-mode-map 1760,67201 (define-key coq-response-mode-map 1763,67279 (define-key coq-response-mode-map 1764,67364 (define-key coq-response-mode-map 1765,67449 (define-key coq-response-mode-map 1766,67539 (define-key coq-response-mode-map 1767,67624 (define-key coq-response-mode-map 1768,67715 (define-key coq-response-mode-map 1769,67799 (define-key coq-response-mode-map 1770,67899 (define-key coq-response-mode-map 1771,67996 (defvar last-coq-error-location 1778,68146 (defun coq-get-last-error-location 1786,68530 (defun coq-highlight-error 1836,71093 (defun coq-highlight-error-hook 1864,72174 (defun coq-first-word-before 1874,72391 (defun coq-get-from-to-paren 1884,72722 (defun coq-show-first-goal 1897,73128 (defvar coq-modeline-string2 1913,73793 (defvar coq-modeline-string1 1914,73827 (defvar coq-modeline-string0 1915,73861 (defun coq-build-subgoals-string 1916,73902 (defun coq-update-minor-mode-alist 1922,74086 (defun is-not-split-vertic 1956,75655 (defun coq-optimise-resp-windows 1970,76448 (defcustom coq-double-hit-enable 2010,78275 (defadvice proof-electric-terminator-enable 2029,79061 (defvar coq-double-hit-delay 2037,79439 (defvar coq-double-hit-timer 2040,79554 (defvar coq-double-hit-hot 2043,79634 (defun coq-unset-double-hit-hot 2047,79730 (defun coq-colon-self-insert 2055,80061 (defun coq-terminator-insert 2069,80617 coq/coq-indent.el,2698 (defconst coq-any-command-regexp20,368 (defconst coq-indent-inner-regexp23,442 (defconst coq-comment-start-regexp 33,799 (defconst coq-comment-end-regexp 34,842 (defconst coq-comment-start-or-end-regexp35,883 (defconst coq-indent-open-regexp37,991 (defconst coq-indent-close-regexp42,1188 (defconst coq-indent-closepar-regexp 48,1387 (defconst coq-indent-closematch-regexp 49,1432 (defconst coq-indent-openpar-regexp 50,1503 (defconst coq-indent-openmatch-regexp 51,1547 (defconst coq-tacticals-tactics-regex52,1627 (defconst coq-indent-any-regexp54,1746 (defconst coq-indent-kw58,1962 (defconst coq-indent-pattern-regexp 68,2428 (defun coq-indent-goal-command-p 72,2531 (defconst coq-period-end-command93,3549 (defconst coq-curlybracket-end-command99,3831 (defconst coq-bullet-end-command104,4060 (defconst coq-end-command-regexp117,4515 (defun coq-search-comment-delimiter-forward 133,5240 (defun coq-search-comment-delimiter-backward 142,5570 (defun coq-skip-until-one-comment-backward 149,5844 (defun coq-skip-until-one-comment-forward 164,6551 (defun coq-looking-at-comment 175,7069 (defun coq-find-comment-start 180,7234 (defun coq-find-comment-end 192,7711 (defun coq-looking-at-syntactic-context 204,8204 (defconst coq-end-command-or-comment-regexp210,8426 (defconst coq-end-command-or-comment-start-regexp213,8535 (defun coq-find-not-in-comment-backward 216,8652 (defun coq-find-not-in-comment-forward 235,9531 (defun coq-is-on-ending-context 261,10723 (defun coq-empty-command-p 270,10936 (defun coq-script-parse-cmdend-forward 285,11677 (defun coq-script-parse-cmdend-backward 337,14178 (defun coq-find-current-start 378,16099 (defun coq-find-real-start 387,16425 (defun same-line 393,16643 (defun coq-command-at-point 396,16730 (defun coq-commands-at-line 411,17341 (defun coq-indent-only-spaces-on-line 435,18307 (defun coq-indent-find-reg 441,18584 (defun coq-find-no-syntactic-on-line 455,19120 (defun coq-back-to-indentation-prevline 468,19593 (defun coq-find-unclosed 514,21660 (defun coq-find-at-same-level-zero 544,22970 (defun coq-find-unopened 573,24236 (defun coq-find-last-unopened 616,25670 (defun coq-end-offset 627,26067 (defun coq-add-iter 652,26837 (defun coq-goal-count 655,26943 (defun coq-save-count 657,27015 (defun coq-proof-count 662,27214 (defun coq-goal-save-diff-maybe-proof 668,27500 (defun coq-indent-command-offset 678,27794 (defun coq-indent-expr-offset 744,30975 (defun coq-indent-comment-offset 863,35857 (defun coq-indent-offset 895,37309 (defun coq-indent-calculate 914,38183 (defun coq-indent-line 917,38271 (defun coq-indent-line-not-comments 927,38637 (defun coq-indent-region 937,39026 coq/coq-local-vars.el,229 (defconst coq-local-vars-doc 23,470 (defun coq-insert-coq-prog-name 86,2815 (defun coq-read-directory 99,3383 (defun coq-ask-load-path 116,4198 (defun coq-ask-prog-name 135,5165 (defun coq-ask-insert-coq-prog-name 152,5876 coq/coq-par-compile.el,1962 (defvar coq-par-ancestor-files 221,9942 (defvar coq-current-background-jobs 237,10591 (defvar coq-compilation-object-hash 240,10680 (defvar coq-last-compilation-job 248,11053 (defvar coq-par-next-id 252,11196 (defun split-list-at-predicate 259,11353 (defun coq-par-time-less 283,12205 (defun coq-par-init-compilation-hash 293,12553 (defun coq-par-init-ancestor-hash 297,12714 (defconst coq-par-empty-compilation-queue 308,12999 (defvar coq-par-compilation-queue311,13108 (defun coq-par-enqueue 316,13294 (defun coq-par-dequeue 322,13528 (defun coq-par-coq-arguments 370,15079 (defun coq-par-analyse-coq-dep-exit 378,15448 (defun coq-par-get-library-dependencies 397,16231 (defun coq-par-map-module-id-to-obj-file 441,18201 (defun coq-par-kill-all-processes 500,21030 (defun coq-par-unlock-ancestors-on-error 523,21906 (defun coq-par-emergency-cleanup 533,22249 (defun coq-par-process-filter 549,22870 (defun coq-par-start-process 554,23079 (defun coq-par-process-sentinel 588,24693 (defun coq-par-job-is-ready 632,26382 (defun coq-par-dependencies-ready 636,26488 (defun coq-par-add-coqc-dependency 640,26632 (defun coq-par-add-queue-dependency 649,27045 (defun coq-par-get-obj-mod-time 659,27511 (defun coq-par-job-needs-compilation 673,28041 (defun coq-par-kickoff-queue-maybe 702,29272 (defun coq-par-compile-job-maybe 767,32097 (defun coq-par-decrease-coqc-dependency 781,32768 (defun coq-par-kickoff-coqc-dependants 816,34538 (defun coq-par-start-coqdep 858,36468 (defun coq-par-start-task 875,37155 (defun coq-par-start-jobs-until-full 891,37716 (defun coq-par-start-or-enqueue 900,38013 (defun coq-par-create-library-job 909,38400 (defun coq-par-process-coqdep-result 981,41558 (defun coq-par-coqc-continuation 1038,44003 (defun coq-par-handle-module 1061,44849 (defun coq-par-handle-require-list 1089,46049 (defun coq-par-item-require-predicate 1135,48107 (defun coq-par-preprocess-require-commands 1144,48430 coq/coq-seq-compile.el,422 (defun coq-seq-lock-ancestor 38,1174 (defun coq-seq-get-library-dependencies 56,2005 (defun coq-seq-compile-library 109,4420 (defun coq-seq-compile-library-if-necessary 136,5649 (defun coq-seq-make-lib-up-to-date 182,7533 (defun coq-seq-auto-compile-externally 240,10027 (defun coq-seq-map-module-id-to-obj-file 284,12191 (defun coq-seq-check-module 337,14809 (defun coq-seq-preprocess-require-commands 365,16275 coq/coq-smie-lexer.el,862 (defconst coq-smie-dot-friends 21,987 (defun coq-time-indent 26,1163 (defun coq-time-indent-region 32,1304 (defun coq-smie-is-tactic 41,1475 (defun coq-smie-.-deambiguate 51,1708 (defun coq-smie-complete-qualid-backward 80,2425 (defun coq-smie-find-unclosed-match-backward 88,2645 (defun coq-smie-with-deambiguate(98,2973 (defun coq-smie-search-token-forward 116,3538 (defun coq-smie-search-token-backward 161,5463 (defun coq-lonely-:=205,7371 (defun coq-smie-detect-goal-command 222,8132 (defun coq-smie-module-deambiguate 236,8795 (defconst coq-smie-proof-end-tokens255,9691 (defun coq-smie-forward-token 259,9842 (defun coq-is-at-command-real-start(334,12771 (defun coq-smie-:=339,12871 (defun coq-smie-backward-token 375,14320 (defcustom coq-indent-box-style 565,20606 (defconst coq-smie-grammar583,21035 (defun coq-smie-rules 705,26030 coq/coq-syntax.el,2786 (defcustom coq-user-tactics-db 21,586 (defcustom coq-user-commands-db 38,1099 (defcustom coq-user-tacticals-db 54,1618 (defcustom coq-user-solve-tactics-db 70,2139 (defcustom coq-user-cheat-tactics-db 86,2658 (defcustom coq-user-reserved-db 105,3204 (defvar coq-tactics-db123,3735 (defvar coq-solve-tactics-db296,12869 (defvar coq-solve-cheat-tactics-db323,13892 (defvar develock-coq-font-lock-keywords331,14098 (defvar coq-tacticals-db342,14405 (defvar coq-decl-db366,15291 (defvar coq-defn-db391,16747 (defvar coq-goal-starters-db456,21469 (defvar coq-other-commands-db486,23272 (defvar coq-commands-db621,33257 (defvar coq-terms-db628,33477 (defun coq-count-match 690,36092 (defun coq-module-opening-p 706,36821 (defun coq-section-command-p 716,37255 (defun coq-goal-command-str-p 720,37352 (defun coq-goal-command-p 746,38677 (defvar coq-keywords-save-strict755,39021 (defvar coq-keywords-save762,39262 (defun coq-save-command-p 767,39341 (defvar coq-keywords-kill-goal778,39669 (defvar coq-keywords-state-changing-misc-commands782,39759 (defvar coq-keywords-goal785,39884 (defvar coq-keywords-decl788,39967 (defvar coq-keywords-defn791,40041 (defvar coq-keywords-state-changing-commands795,40116 (defvar coq-keywords-state-preserving-commands804,40376 (defvar coq-keywords-commands809,40592 (defvar coq-solve-tactics814,40740 (defvar coq-solve-tactics-regexp818,40861 (defvar coq-solve-cheat-tactics822,40995 (defvar coq-solve-cheat-tactics-regexp826,41140 (defvar coq-tacticals830,41298 (defvar coq-reserved836,41437 (defvar coq-reserved-regexp 846,41772 (defvar coq-state-changing-tactics850,41883 (defvar coq-state-preserving-tactics853,41992 (defvar coq-tactics857,42106 (defvar coq-tactics-regexp 860,42195 (defvar coq-retractable-instruct863,42350 (defvar coq-non-retractable-instruct866,42460 (defvar coq-keywords870,42588 (defun proof-regexp-alt-list-symb 876,42812 (defvar coq-keywords-regexp 879,42917 (defvar coq-symbols882,42990 (defvar coq-error-regexp 904,43231 (defvar coq-id 907,43459 (defvar coq-id-shy 908,43484 (defvar coq-ids 911,43577 (defun coq-first-abstr-regexp 913,43643 (defcustom coq-variable-highlight-enable 916,43738 (defvar coq-font-lock-terms922,43865 (defconst coq-save-command-regexp-strict944,44948 (defconst coq-save-command-regexp950,45116 (defconst coq-save-with-hole-regexp955,45269 (defconst coq-goal-command-regexp959,45429 (defconst coq-goal-with-hole-regexp962,45531 (defconst coq-decl-with-hole-regexp966,45665 (defconst coq-defn-with-hole-regexp973,45915 (defconst coq-with-with-hole-regexp983,46205 (defvar coq-font-lock-keywords-1998,46735 (defvar coq-font-lock-keywords 1026,48070 (defun coq-init-syntax-table 1028,48128 (defconst coq-generic-expression1053,48855 coq/coq-unicode-tokens.el,454 (defconst coq-token-format 39,1427 (defconst coq-token-match 40,1475 (defconst coq-hexcode-match 41,1506 (defun coq-unicode-tokens-set 43,1540 (defcustom coq-token-symbol-map49,1768 (defcustom coq-shortcut-alist165,4719 (defconst coq-control-char-format-regexp254,6808 (defconst coq-control-char-format 258,6933 (defconst coq-control-characters260,6976 (defconst coq-control-region-format-regexp 264,7068 (defconst coq-control-regions266,7151 hol98/hol98.el,121 (defvar hol98-keywords 17,419 (defvar hol98-rules 18,447 (defvar hol98-tactics 19,472 (defvar hol98-tacticals 20,499 isar/isabelle-system.el,1255 (defgroup isabelle 31,882 (defcustom isabelle-web-page35,1010 (defcustom isa-isabelle-command44,1227 (defvar isabelle-not-found 62,1909 (defun isa-set-isabelle-command 65,2024 (defun isa-shell-command-to-string 88,3042 (defun isa-getenv 94,3266 (defcustom isabelle-program-name-override 114,3965 (defun isa-tool-list-logics 125,4311 (defcustom isabelle-logics-available 132,4557 (defcustom isabelle-chosen-logic 142,4894 (defvar isabelle-chosen-logic-prev 158,5478 (defun isabelle-hack-local-variables-function 161,5598 (defun isabelle-set-prog-name 173,6037 (defun isabelle-choose-logic 197,7157 (defun isa-view-doc 216,7919 (defun isa-tool-list-docs 223,8145 (defconst isabelle-verbatim-regexp 241,8875 (defun isabelle-verbatim 244,9017 (defcustom isabelle-refresh-logics 251,9178 (defvar isabelle-docs-menu259,9506 (defvar isabelle-logics-menu-entries 266,9809 (defun isabelle-logics-menu-calculate 269,9882 (defvar isabelle-time-to-refresh-logics 290,10524 (defun isabelle-logics-menu-refresh 294,10619 (defun isabelle-menu-bar-update-logics 309,11266 (defun isabelle-load-isar-keywords 325,11895 (defun isabelle-create-span-menu 346,12623 (defun isabelle-xml-sml-escapes 362,13054 (defun isabelle-process-pgip 365,13155 isar/isar-autotest.el,31 (defvar isar-long-tests 8,186 isar/isar.el,1595 (defcustom isar-keywords-name 41,939 (defpgdefault completion-table 57,1450 (defcustom isar-web-page59,1503 (defun isar-strip-terminators 73,1853 (defun isar-markup-ml 85,2209 (defun isar-mode-config-set-variables 90,2344 (defun isar-shell-mode-config-set-variables 155,5143 (defun isar-set-proof-find-theorems-command 237,8333 (defpacustom use-find-theorems-form 243,8517 (defun isar-set-undo-commands 248,8683 (defpacustom use-linear-undo 263,9316 (defun isar-configure-from-settings 268,9474 (defun isar-remove-file 276,9624 (defun isar-shell-compute-new-files-list 288,9928 (define-derived-mode isar-shell-mode 307,10498 (define-derived-mode isar-response-mode 312,10625 (define-derived-mode isar-goals-mode 317,10758 (define-derived-mode isar-mode 322,10884 (defpgdefault menu-entries374,12599 (defun isar-set-command 405,13793 (defpgdefault help-menu-entries 410,13923 (defun isar-count-undos 413,13999 (defun isar-find-and-forget 439,14965 (defun isar-goal-command-p 475,16308 (defun isar-global-save-command-p 480,16485 (defvar isar-current-goal 501,17269 (defun isar-state-preserving-p 504,17335 (defvar isar-shell-current-line-width 529,18184 (defun isar-shell-adjust-line-width 534,18376 (defsubst isar-string-wrapping 557,19141 (defsubst isar-positions-of 566,19335 (defcustom isar-wrap-commands-singly 572,19540 (defun isar-command-wrapping 578,19736 (defun isar-preprocessing 586,20050 (defun isar-mode-config 604,20601 (defun isar-shell-mode-config 618,21254 (defun isar-response-mode-config 628,21603 (defun isar-goals-mode-config 638,21938 isar/isar-find-theorems.el,779 (defvar isar-find-theorems-data 19,565 (defun isar-find-theorems-minibuffer 35,1039 (defun isar-find-theorems-form 49,1658 (defvar isar-find-theorems-widget-number 92,3532 (defvar isar-find-theorems-widget-pattern 95,3630 (defvar isar-find-theorems-widget-intro 98,3722 (defvar isar-find-theorems-widget-elim 101,3808 (defvar isar-find-theorems-widget-dest 104,3892 (defvar isar-find-theorems-widget-name 107,3976 (defvar isar-find-theorems-widget-simp 110,4063 (defun isar-find-theorems-create-searchform115,4209 (defun isar-find-theorems-create-help 255,8752 (defun isar-find-theorems-submit-searchform298,10924 (defun isar-find-theorems-parse-criteria 376,13294 (defun isar-find-theorems-parse-number 469,16275 (defun isar-find-theorems-filter-empty 479,16552 isar/isar-keywords.el,1064 (defconst isar-keywords-major7,222 (defconst isar-keywords-minor280,4856 (defconst isar-keywords-control339,5659 (defconst isar-keywords-diag360,6153 (defconst isar-keywords-theory-begin434,7438 (defconst isar-keywords-theory-switch437,7491 (defconst isar-keywords-theory-end440,7537 (defconst isar-keywords-theory-heading443,7585 (defconst isar-keywords-theory-decl449,7692 (defconst isar-keywords-theory-script552,9481 (defconst isar-keywords-theory-goal555,9544 (defconst isar-keywords-qed583,10059 (defconst isar-keywords-qed-block590,10145 (defconst isar-keywords-qed-global593,10192 (defconst isar-keywords-proof-heading596,10241 (defconst isar-keywords-proof-goal601,10324 (defconst isar-keywords-proof-block606,10401 (defconst isar-keywords-proof-open610,10463 (defconst isar-keywords-proof-close613,10509 (defconst isar-keywords-proof-chain616,10556 (defconst isar-keywords-proof-decl623,10659 (defconst isar-keywords-proof-asm635,10821 (defconst isar-keywords-proof-asm-goal642,10916 (defconst isar-keywords-proof-script648,11005 isar/isar-mmm.el,81 (defconst isar-start-latex-regexp24,744 (defconst isar-start-sml-regexp36,1172 isar/isar-syntax.el,4005 (defconst isar-script-syntax-table-entries18,483 (defconst isar-script-syntax-table-alist42,885 (defun isar-init-syntax-table 51,1168 (defun isar-init-output-syntax-table 59,1415 (defconst isar-keyword-begin 74,1857 (defconst isar-keyword-end 75,1895 (defconst isar-keywords-theory-enclose77,1930 (defconst isar-keywords-theory82,2068 (defconst isar-keywords-save87,2199 (defconst isar-keywords-proof-enclose92,2314 (defconst isar-keywords-proof98,2475 (defconst isar-keywords-proof-context105,2652 (defconst isar-keywords-local-goal109,2759 (defconst isar-keywords-proper113,2864 (defconst isar-keywords-improper118,2983 (defconst isar-keyword-level-alist123,3115 (defconst isar-keywords-outline 138,3586 (defconst isar-keywords-indent-open141,3662 (defconst isar-keywords-indent-close148,3848 (defconst isar-keywords-indent-enclose153,3981 (defconst isar-ext-first 163,4210 (defconst isar-ext-rest 164,4277 (defconst isar-text 166,4349 (defconst isar-long-id-stuff 167,4382 (defconst isar-id 168,4456 (defconst isar-idx 169,4526 (defconst isar-string 171,4585 (defun isar-ids-to-regexp 173,4645 (defconst isar-any-command-regexp205,6437 (defconst isar-name-regexp212,6810 (defconst isar-improper-regexp218,7105 (defconst isar-save-command-regexp222,7239 (defconst isar-global-save-command-regexp225,7340 (defconst isar-goal-command-regexp228,7454 (defconst isar-local-goal-command-regexp231,7562 (defconst isar-comment-start 234,7675 (defconst isar-comment-end 235,7710 (defconst isar-comment-start-regexp 236,7743 (defconst isar-comment-end-regexp 237,7814 (defconst isar-string-start-regexp 239,7882 (defconst isar-string-end-regexp 240,7934 (defun isar-syntactic-context 242,7985 (defconst isar-antiq-regexp257,8380 (defconst isar-nesting-regexp263,8531 (defun isar-nesting 266,8629 (defun isar-match-nesting 278,9022 (defface isabelle-string-face 290,9356 (defface isabelle-quote-face 298,9556 (defface isabelle-class-name-face306,9752 (defface isabelle-tfree-name-face314,9939 (defface isabelle-tvar-name-face322,10132 (defface isabelle-free-name-face330,10324 (defface isabelle-bound-name-face338,10512 (defface isabelle-var-name-face346,10703 (defconst isabelle-string-face 354,10894 (defconst isabelle-quote-face 355,10948 (defconst isabelle-class-name-face 356,11001 (defconst isabelle-tfree-name-face 357,11063 (defconst isabelle-tvar-name-face 358,11125 (defconst isabelle-free-name-face 359,11186 (defconst isabelle-bound-name-face 360,11247 (defconst isabelle-var-name-face 361,11309 (defun isar-font-lock-fontify-syntactically-region 367,11458 (defvar isar-font-lock-keywords-1402,12736 (defun isar-output-flkprops 420,13744 (defun isar-output-flk 426,13996 (defvar isar-output-font-lock-keywords-1429,14105 (defun isar-strip-output-markup 453,15104 (defconst isar-shell-font-lock-keywords457,15240 (defvar isar-goals-font-lock-keywords460,15324 (defconst isar-linear-undo 494,16003 (defconst isar-undo 496,16046 (defconst isar-pr498,16089 (defun isar-remove 505,16247 (defun isar-undos 508,16322 (defun isar-cannot-undo 518,16556 (defconst isar-undo-commands521,16626 (defconst isar-theory-start-regexp529,16763 (defconst isar-end-regexp535,16921 (defconst isar-undo-fail-regexp539,17022 (defconst isar-undo-skip-regexp543,17126 (defconst isar-undo-ignore-regexp546,17247 (defconst isar-undo-remove-regexp549,17312 (defconst isar-keywords-imenu557,17469 (defconst isar-entity-regexp 564,17660 (defconst isar-named-entity-regexp567,17756 (defconst isar-named-entity-name-match-number572,17886 (defconst isar-generic-expression575,17987 (defconst isar-indent-any-regexp586,18221 (defconst isar-indent-inner-regexp588,18314 (defconst isar-indent-enclose-regexp590,18380 (defconst isar-indent-open-regexp592,18496 (defconst isar-indent-close-regexp594,18606 (defconst isar-outline-regexp600,18743 (defconst isar-outline-heading-end-regexp 604,18896 (defconst isar-outline-heading-alist 606,18945 isar/isar-unicode-tokens.el,1363 (defgroup isabelle-tokens 25,672 (defun isar-set-and-restart-tokens 30,812 (defconst isar-control-region-format-regexp43,1165 (defconst isar-control-char-format-regexp46,1259 (defconst isar-control-char-format 52,1406 (defconst isar-control-region-format-start 53,1455 (defconst isar-control-region-format-end 54,1509 (defcustom isar-control-characters57,1565 (defcustom isar-control-regions71,1978 (defconst isar-token-format 97,2790 (defconst isar-token-variant-format-regexp101,2941 (defcustom isar-greek-letters-tokens104,3055 (defcustom isar-misc-letters-tokens144,3913 (defcustom isar-symbols-tokens156,4231 (defcustom isar-extended-symbols-tokens362,9042 (defun isar-try-char 431,10697 (defcustom isar-symbols-tokens-fallbacks435,10841 (defcustom isar-bold-nums-tokens462,11771 (defun isar-map-letters 478,12160 (defconst isar-script-letters-tokens 484,12308 (defconst isar-roman-letters-tokens 489,12462 (defconst isar-fraktur-uppercase-letters-tokens 494,12636 (defconst isar-fraktur-lowercase-letters-tokens 499,12805 (defcustom isar-token-symbol-map 504,12996 (defcustom isar-user-tokens 521,13537 (defun isar-init-token-symbol-map 535,13977 (defcustom isar-symbol-shortcuts560,14626 (defcustom isar-shortcut-alist 632,16825 (defun isar-init-shortcut-alists 640,17084 (defconst isar-tokens-customizable-variables661,17747 lego/lego.el,1636 (defcustom lego-tags 21,539 (defcustom lego-test-all-name 26,675 (defpgdefault help-menu-entries32,833 (defpgdefault menu-entries36,993 (defvar lego-shell-handle-output47,1294 (defconst lego-process-config55,1604 (defconst lego-pretty-set-width 66,2035 (defconst lego-interrupt-regexp 70,2177 (defcustom lego-www-home-page 75,2294 (defcustom lego-www-latest-release80,2418 (defcustom lego-www-refcard86,2593 (defcustom lego-library-www-page92,2742 (defvar lego-prog-name 101,2958 (defvar lego-shell-cd 104,3027 (defvar lego-shell-proof-completed-regexp 107,3126 (defvar lego-save-command-regexp110,3266 (defvar lego-goal-command-regexp112,3356 (defvar lego-kill-goal-command 115,3447 (defvar lego-forget-id-command 116,3490 (defvar lego-undoable-commands-regexp118,3536 (defvar lego-goal-regexp 127,3910 (defvar lego-outline-regexp129,3955 (defvar lego-outline-heading-end-regexp 135,4130 (defvar lego-shell-outline-regexp 137,4183 (defvar lego-shell-outline-heading-end-regexp 138,4235 (define-derived-mode lego-shell-mode 144,4514 (define-derived-mode lego-mode 151,4675 (define-derived-mode lego-goals-mode 162,4985 (defun lego-count-undos 173,5411 (defun lego-goal-command-p 192,6148 (defun lego-find-and-forget 197,6319 (defun lego-goal-hyp 239,8155 (defun lego-state-preserving-p 248,8352 (defvar lego-shell-current-line-width 264,9055 (defun lego-shell-adjust-line-width 272,9362 (defun lego-mode-config 289,10063 (defun lego-equal-module-filename 357,12114 (defun lego-shell-compute-new-files-list 363,12389 (defun lego-shell-mode-config 373,12772 (defun lego-goals-mode-config 420,14439 lego/lego-syntax.el,600 (defconst lego-keywords-goal 15,358 (defconst lego-keywords-save 17,401 (defconst lego-commands19,472 (defconst lego-keywords31,1030 (defconst lego-tacticals 36,1207 (defconst lego-error-regexp 39,1315 (defvar lego-id 42,1473 (defvar lego-ids 44,1500 (defconst lego-arg-list-regexp 48,1696 (defun lego-decl-defn-regexp 51,1812 (defconst lego-definiendum-alternative-regexp59,2184 (defvar lego-font-lock-terms63,2368 (defconst lego-goal-with-hole-regexp89,3221 (defconst lego-save-with-hole-regexp94,3443 (defvar lego-font-lock-keywords-199,3660 (defun lego-init-syntax-table 110,4122 hol-light/hol-light.el,1930 (defcustom hol-light-home 23,678 (defcustom hol-light-prog-name 30,879 (defcustom hol-light-use-custom-toplevel 38,1075 (defconst hol-light-pre-sync-cmd52,1571 (defcustom hol-light-init-cmd 56,1745 (defconst hol-light-plain-start-goals-regexp78,2476 (defconst hol-light-annotated-start-goals-regexp 85,2722 (defconst hol-light-plain-interrupt-regexp89,2881 (defconst hol-light-annotated-interrupt-regexp93,3012 (defconst hol-light-plain-prompt-regexp97,3174 (defconst hol-light-annotated-prompt-regexp101,3328 (defconst hol-light-plain-error-regexp105,3500 (defconst hol-light-annotated-error-regexp 116,3825 (defconst hol-light-plain-proof-completed-regexp121,4046 (defconst hol-light-annotated-proof-completed-regexp125,4199 (defconst hol-light-plain-message-start 129,4380 (defconst hol-light-annotated-message-start133,4524 (defconst hol-light-plain-message-end137,4678 (defconst hol-light-annotated-message-end141,4809 (defvar hol-light-keywords 150,4965 (defvar hol-light-rules 151,4997 (defvar hol-light-tactics 152,5026 (defvar hol-light-tacticals 153,5057 (defvar hol-light-update-goal-regexp 365,13126 (defconst hol-light-current-goal-regexp369,13252 (defconst hol-light-additional-subgoal-regexp 375,13446 (defconst hol-light-statenumber-regexp 379,13602 (defconst hol-light-existential-regexp 386,13906 (defconst hol-light-existentials-state-start-regexp 389,14013 (defconst hol-light-existentials-state-end-regexp 392,14160 (defvar proof-shell-delayed-output-start 424,15452 (defvar proof-shell-delayed-output-end 425,15498 (defvar proof-info 426,15542 (defvar proof-action-list 427,15566 (defun proof-shell-action-list-item 428,15597 (defconst hol-light-show-sequent-command 430,15648 (defun hol-light-get-proof-info 432,15716 (defun hol-light-find-begin-of-unfinished-proof 448,16217 (defun hol-light-proof-tree-get-new-subgoals 459,16665 (defpgdefault menu-entries509,18887 hol-light/hol-light-unicode-tokens.el,516 (defconst hol-light-token-format 23,746 (defconst hol-light-token-match 24,800 (defconst hol-light-hexcode-match 25,837 (defun hol-light-unicode-tokens-set 27,877 (defcustom hol-light-token-symbol-map33,1117 (defcustom hol-light-shortcut-alist128,3379 (defconst hol-light-control-char-format-regexp217,5409 (defconst hol-light-control-char-format 221,5540 (defconst hol-light-control-characters223,5589 (defconst hol-light-control-region-format-regexp 227,5687 (defconst hol-light-control-regions229,5776 phox/phox.el,555 (defcustom phox-prog-name 32,916 (defcustom phox-web-page37,1018 (defcustom phox-doc-dir43,1168 (defcustom phox-lib-dir49,1315 (defcustom phox-tags-program55,1458 (defcustom phox-tags-doc61,1637 (defcustom phox-etags67,1774 (defpgdefault menu-entries88,2224 (defun phox-config 102,2417 (defun phox-shell-config 146,4343 (define-derived-mode phox-mode 170,5205 (define-derived-mode phox-shell-mode 186,5668 (define-derived-mode phox-response-mode 191,5796 (define-derived-mode phox-goals-mode 201,6157 (defpgdefault completion-table224,6943 phox/phox-extraction.el,383 (defvar phox-prog-orig 19,619 (defun phox-prog-flags-modify(21,687 (defun phox-prog-flags-extract(50,1488 (defun phox-prog-flags-erase(61,1778 (defun phox-toggle-extraction(69,1974 (defun phox-compile-theorem(81,2376 (defun phox-compile-theorem-on-cursor(87,2601 (defun phox-output 103,3079 (defun phox-output-theorem 113,3291 (defun phox-output-theorem-on-cursor(120,3590 phox/phox-font.el,231 (defvar phox-sym-lock-enabled 1,0 (defvar phox-sym-lock-color 2,60 (defvar phox-sym-lock-keywords 3,118 (defconst phox-font-lock-keywords11,511 (defconst phox-sym-lock-keywords-table70,2628 (defun phox-sym-lock-start 93,3202 phox/phox-fun.el,1659 (defconst phox-forget-id-command 11,186 (defconst phox-forget-proof-command 12,232 (defconst phox-forget-new-elim-command 13,287 (defconst phox-forget-new-intro-command 14,345 (defconst phox-forget-new-equation-command 15,405 (defconst phox-forget-close-def-command 16,471 (defconst phox-comments-regexp 18,597 (defconst phox-strict-comments-regexp 20,776 (defconst phox-ident-regexp 21,941 (defconst phox-inductive-option 22,1027 (defconst phox-spaces-regexp 23,1079 (defconst phox-sy-definition-regexp 24,1122 (defconst phox-sy-inductive-regexp 28,1309 (defconst phox-inductive-regexp 34,1522 (defconst phox-data-regexp 40,1673 (defconst phox-definition-regexp 46,1827 (defconst phox-prove-claim-regexp 50,1971 (defconst phox-new-elim-regexp 54,2077 (defconst phox-new-intro-regexp 57,2196 (defconst phox-new-rewrite-regexp 60,2317 (defconst phox-new-equation-regexp 63,2442 (defconst phox-close-def-regexp 66,2569 (defun phox-init-syntax-table 71,2706 (defvar phox-top-keywords87,3178 (defvar phox-proof-keywords135,3633 (defun phox-find-and-forget 176,3983 (defalias 'phox-assert-next-command-interactive phox-assert-next-command-interactive255,6399 (defun phox-depend-theorem(274,7365 (defun phox-eshow-extlist(283,7654 (defun phox-flag-name(297,8251 (defun phox-path(308,8553 (defun phox-print-expression(319,8789 (defun phox-print-sort-expression(332,9245 (defun phox-priority-symbols-list(343,9557 (defun phox-search-string(355,9929 (defun phox-constraints(370,10454 (defun phox-goals(381,10710 (defvar phox-state-menu393,10919 (defun phox-delete-symbol(418,11909 (defun phox-delete-symbol-on-cursor(424,12117 phox/phox-lang.el,323 (defvar phox-lang9,306 (defun phox-lang-absurd 21,583 (defun phox-lang-suppress 26,677 (defun phox-lang-opendef 31,874 (defun phox-lang-instance 36,992 (defun phox-lang-open-instance 41,1121 (defun phox-lang-lock 46,1270 (defun phox-lang-unlock 51,1400 (defun phox-lang-prove 56,1536 (defun phox-lang-let 61,1670 phox/phox-outline.el,254 (defconst phox-outline-title-regexp 19,723 (defconst phox-outline-section-regexp 20,788 (defconst phox-outline-save-regexp 21,844 (defconst phox-outline-heading-end-regexp 38,1387 (defun phox-outline-level(44,1566 (defun phox-setup-outline 58,2040 phox/phox-pbrpm.el,513 (defun phox-pbrpm-left-paren-p 39,1671 (defun phox-pbrpm-right-paren-p 46,1874 (defun phox-pbrpm-menu-from-string 54,2078 (defun phox-pbrpm-rename-in-cmd 63,2410 (defun phox-pbrpm-get-region-name 96,3658 (defun phox-pbrpm-escape-string 99,3785 (defun phox-pbrpm-generate-menu 103,3920 (defalias 'proof-pbrpm-generate-menu proof-pbrpm-generate-menu310,11400 (defalias 'proof-pbrpm-left-paren-p proof-pbrpm-left-paren-p311,11464 (defalias 'proof-pbrpm-right-paren-p proof-pbrpm-right-paren-p312,11526 phox/phox-sym-lock.el,1398 (defcustom phox-sym-lock-enabled 19,871 (defvar phox-sym-lock-sym-count 59,2452 (defvar phox-sym-lock-ext-start 62,2522 (defvar phox-sym-lock-ext-end 64,2644 (defvar phox-sym-lock-font-size 67,2763 (defvar phox-sym-lock-keywords 72,2953 (defvar phox-sym-lock-enabled 77,3129 (defvar phox-sym-lock-color 82,3291 (defvar phox-sym-lock-mouse-face 87,3509 (defvar phox-sym-lock-mouse-face-enabled 92,3699 (defconst phox-sym-lock-with-mule 97,3889 (defun phox-sym-lock-gen-symbol 100,3973 (defun phox-sym-lock-make-symbols-atomic 108,4275 (defun phox-sym-lock-compute-font-size 135,5216 (defvar phox-sym-lock-font-name173,6635 (defun phox-sym-lock-set-foreground 216,8233 (defun phox-sym-lock-translate-char 230,8842 (defun phox-sym-lock-translate-char-or-string 239,9159 (defun phox-sym-lock-remap-face 246,9387 (defvar phox-sym-lock-clear-face266,10375 (defun phox-sym-lock 278,10794 (defun phox-sym-lock-rec 287,11198 (defun phox-sym-lock-atom-face 293,11343 (defun phox-sym-lock-pre-idle-hook-first 298,11639 (defun phox-sym-lock-pre-idle-hook-last 308,12044 (defun phox-sym-lock-enable 317,12419 (defun phox-sym-lock-disable 330,12830 (defun phox-sym-lock-mouse-face-enable 343,13246 (defun phox-sym-lock-mouse-face-disable 350,13461 (defun phox-sym-lock-font-lock-hook 357,13680 (defun font-lock-set-defaults 372,14371 (defun phox-sym-lock-patch-keywords 384,14798 phox/phox-tags.el,305 (defun phox-tags-add-table(26,869 (defun phox-tags-reset-table(35,1264 (defun phox-tags-add-doc-table(40,1374 (defun phox-tags-add-lib-table(46,1523 (defun phox-tags-add-local-table(52,1658 (defun phox-tags-create-local-table(58,1841 (defun phox-complete-tag(69,2091 (defvar phox-tags-menu76,2200 generic/pg-assoc.el,81 (defun proof-associated-buffers 33,973 (defun proof-associated-windows 43,1183 generic/pg-autotest.el,908 (defvar pg-autotest-success 29,690 (defvar pg-autotest-log 32,777 (defun pg-autotest-find-file 37,871 (defun pg-autotest-find-file-restart 44,1137 (defmacro pg-autotest-apply 58,1611 (defmacro pg-autotest 72,2026 (defun pg-autotest-log 89,2463 (defun pg-autotest-message 98,2726 (defun pg-autotest-remark 107,3015 (defun pg-autotest-timestart 110,3096 (defun pg-autotest-timetaken 115,3279 (defun pg-autotest-start 129,3667 (defun pg-autotest-exit 140,4121 (defun pg-autotest-test-process-wholefile 160,4904 (defun pg-autotest-test-script-wholefile 168,5191 (defun pg-autotest-test-script-randomjumps 193,6123 (defun pg-autotest-test-retract-file 242,7680 (defun pg-autotest-test-assert-processed 248,7821 (defun pg-autotest-test-assert-full 254,8047 (defun pg-autotest-test-assert-unprocessed 261,8288 (defun pg-autotest-test-eval 268,8553 (defun pg-autotest-test-quit-prover 272,8652 generic/pg-custom.el,635 (defpgcustom script-indent 37,1201 (defconst proof-toolbar-entries-default42,1338 (defpgcustom toolbar-entries 71,3173 (defpgcustom prog-args 90,3906 (defpgcustom prog-env 102,4484 (defpgcustom quit-timeout 111,4913 (defpgcustom favourites 123,5340 (defpgcustom menu-entries 128,5529 (defpgcustom help-menu-entries 135,5765 (defpgcustom keymap 142,6028 (defpgcustom completion-table 147,6199 (defpgcustom tags-program 158,6575 (defpgcustom use-holes 167,6959 (defpgcustom one-command-per-line174,7217 (defpgcustom maths-menu-enable 185,7453 (defpgcustom unicode-tokens-enable 191,7633 (defpgcustom mmm-enable 197,7840 generic/pg-goals.el,285 (define-derived-mode proof-goals-mode 29,736 (define-key proof-goals-mode-map 56,1612 (define-key proof-goals-mode-map 58,1728 (define-key proof-goals-mode-map 59,1796 (defun proof-goals-config-done 68,1943 (defun pg-goals-display 76,2209 (defun pg-goals-button-action 119,3668 generic/pg-movie.el,333 (defconst pg-movie-xml-header 32,923 (defconst pg-movie-stylesheet34,981 (defun pg-movie-stylesheet-location 37,1080 (defvar pg-movie-frame 41,1188 (defun pg-movie-of-span 43,1242 (defun pg-movie-of-region 79,2362 (defun pg-movie-export 86,2550 (defun pg-movie-export-from 108,3154 (defun pg-movie-export-directory 119,3475 generic/pg-pamacs.el,534 (defmacro deflocal 35,1138 (deflocal proof-buffer-type 42,1376 (defmacro proof-ass-sym 50,1512 (defmacro proof-ass-symv 56,1771 (defmacro proof-ass 62,2029 (defun proof-ass-differs-from-default 68,2281 (defun proof-defpgcustom-fn 74,2536 (defun undefpgcustom 98,3420 (defmacro defpgcustom 104,3644 (defun proof-defpgdefault-fn 117,4294 (defmacro defpgdefault 131,4752 (defmacro defpgfun 142,5114 (defun proof-defpacustom-fn 156,5513 (defmacro defpacustom 223,7701 (defmacro proof-eval-when-ready-for-assistant 270,9510 generic/pg-pbrpm.el,1808 (defvar pg-pbrpm-use-buffer-menu 45,1207 (defvar pg-pbrpm-start-goal-regexp 48,1329 (defvar pg-pbrpm-start-goal-regexp-par-num 52,1486 (defvar pg-pbrpm-end-goal-regexp 55,1609 (defvar pg-pbrpm-start-hyp-regexp 59,1761 (defvar pg-pbrpm-start-hyp-regexp-par-num 63,1922 (defvar pg-pbrpm-start-concl-regexp 67,2129 (defvar pg-pbrpm-auto-select-regexp 71,2293 (defvar pg-pbrpm-buffer-menu 78,2454 (defvar pg-pbrpm-spans 79,2488 (defvar pg-pbrpm-goal-description 80,2516 (defvar pg-pbrpm-windows-dialog-bug 81,2555 (defvar pbrpm-menu-desc 82,2596 (defun pg-pbrpm-erase-buffer-menu 84,2626 (defun pg-pbrpm-menu-change-hook 90,2798 (defun pg-pbrpm-create-reset-buffer-menu 108,3373 (defun pg-pbrpm-analyse-goal-buffer 127,4215 (defun pg-pbrpm-button-action 187,6620 (defun pg-pbrpm-exists 194,6846 (defun pg-pbrpm-eliminate-id 198,6958 (defun pg-pbrpm-build-menu 206,7204 (defun pg-pbrpm-setup-span 269,9524 (defun pg-pbrpm-run-command 329,11823 (defun pg-pbrpm-get-pos-info 362,13348 (defun pg-pbrpm-get-region-info 404,14647 (defun pg-pbrpm-auto-select-around-point 415,15059 (defun pg-pbrpm-translate-position 430,15583 (defun pg-pbrpm-process-click 438,15837 (defvar pg-pbrpm-remember-region-selected-region 458,16862 (defvar pg-pbrpm-regions-list 459,16916 (defun pg-pbrpm-erase-regions-list 461,16952 (defun pg-pbrpm-filter-regions-list 470,17260 (defface pg-pbrpm-multiple-selection-face477,17523 (defface pg-pbrpm-menu-input-face485,17725 (defun pg-pbrpm-do-remember-region 493,17915 (defun pg-pbrpm-remember-region-drag-up-hook 514,18763 (defun pg-pbrpm-remember-region-click-hook 518,18934 (defun pg-pbrpm-remember-region 523,19119 (defun pg-pbrpm-process-region 537,19833 (defun pg-pbrpm-process-regions-list 555,20562 (defun pg-pbrpm-region-expression 559,20745 generic/pg-pgip.el,2932 (defalias 'pg-pgip-debug pg-pgip-debug39,1091 (defalias 'pg-pgip-error pg-pgip-error40,1132 (defalias 'pg-pgip-warning pg-pgip-warning41,1167 (defconst pg-pgip-version-supported 43,1217 (defun pg-pgip-process-packet 47,1323 (defvar pg-pgip-last-seen-id 57,1891 (defvar pg-pgip-last-seen-seq 58,1925 (defun pg-pgip-process-pgip 60,1961 (defun pg-pgip-process-msg 79,2901 (defvar pg-pgip-post-process-functions94,3492 (defun pg-pgip-post-process 104,3967 (defun pg-pgip-process-askpgip 121,4582 (defun pg-pgip-process-usespgip 127,4786 (defun pg-pgip-process-usespgml 131,4950 (defun pg-pgip-process-pgmlconfig 135,5114 (defun pg-pgip-process-proverinfo 151,5731 (defun pg-pgip-process-hasprefs 168,6396 (defun pg-pgip-haspref 182,7028 (defun pg-pgip-process-prefval 200,7744 (defun pg-pgip-process-guiconfig 227,8452 (defvar proof-assistant-idtables 234,8569 (defun pg-pgip-process-ids 237,8686 (defun pg-complete-idtable-symbol 263,9758 (defalias 'pg-pgip-process-setids pg-pgip-process-setids268,9850 (defalias 'pg-pgip-process-addids pg-pgip-process-addids269,9906 (defalias 'pg-pgip-process-delids pg-pgip-process-delids270,9962 (defun pg-pgip-process-idvalue 273,10020 (defun pg-pgip-process-menuadd 285,10366 (defun pg-pgip-process-menudel 288,10409 (defun pg-pgip-process-ready 297,10641 (defun pg-pgip-process-cleardisplay 300,10682 (defun pg-pgip-process-proofstate 314,11139 (defun pg-pgip-process-normalresponse 318,11216 (defun pg-pgip-process-errorresponse 322,11346 (defun pg-pgip-process-scriptinsert 326,11475 (defun pg-pgip-process-metainforesponse 331,11609 (defun pg-pgip-file-of-url 340,11849 (defun pg-pgip-process-informfileloaded 345,11984 (defun pg-pgip-process-informfileretracted 351,12216 (defun pg-pgip-process-brokerstatus 364,12663 (defun pg-pgip-process-proveravailmsg 367,12711 (defun pg-pgip-process-newprovermsg 370,12761 (defun pg-pgip-process-proverstatusmsg 373,12809 (defvar pg-pgip-srcids 382,13055 (defun pg-pgip-process-newfile 386,13162 (defun pg-pgip-process-filestatus 402,13744 (defun pg-pgip-process-newobj 422,14398 (defun pg-pgip-process-delobj 425,14440 (defun pg-pgip-process-objectstatus 428,14482 (defun pg-pgip-process-parsescript 442,14834 (defun pg-pgip-get-pgiptype 465,15708 (defun pg-pgip-default-for 486,16571 (defun pg-pgip-subst-for 499,16966 (defun pg-pgip-interpret-value 512,17336 (defun pg-pgip-interpret-choice 531,18061 (defun pg-pgip-string-of-command 562,19078 (defconst pg-pgip-id579,19839 (defvar pg-pgip-refseq 585,20119 (defvar pg-pgip-refid 587,20216 (defvar pg-pgip-seq 590,20308 (defun pg-pgip-assemble-packet 592,20372 (defun pg-pgip-issue 610,21183 (defun pg-pgip-maybe-askpgip 627,21795 (defun pg-pgip-askprefs 633,21986 (defun pg-pgip-askids 637,22100 (defun pg-pgip-reset 650,22388 (defconst pg-pgip-start-element-regexp 681,23086 (defconst pg-pgip-end-element-regexp 682,23138 generic/pg-response.el,1254 (deflocal pg-response-eagerly-raise 32,791 (define-derived-mode proof-response-mode 42,1016 (define-key proof-response-mode-map 69,1971 (define-key proof-response-mode-map 70,2042 (define-key proof-response-mode-map 71,2096 (defun proof-response-config-done 75,2182 (defvar pg-response-special-display-regexp 86,2528 (defconst proof-multiframe-parameters90,2695 (defun proof-multiple-frames-enable 99,2985 (defun proof-three-window-enable 109,3313 (defun proof-select-three-b 112,3376 (defun proof-display-three-b 157,4806 (defvar pg-frame-configuration 167,5174 (defun pg-cache-frame-configuration 171,5321 (defun proof-layout-windows 175,5492 (defun proof-delete-other-frames 241,8163 (defvar pg-response-erase-flag 272,9251 (defun pg-response-maybe-erase276,9380 (defun pg-response-display 320,10843 (defun pg-response-display-with-face 345,11626 (defun pg-response-clear-displays 373,12472 (defun pg-response-message 391,13178 (defun pg-response-warning 397,13413 (defun proof-next-error 412,13819 (defun pg-response-has-error-location 490,16628 (defcustom proof-trace-buffer-max-lines 505,17047 (defun proof-trace-buffer-display 512,17282 (defun proof-trace-buffer-finish 526,17689 (defun pg-thms-buffer-clear 550,18342 generic/pg-user.el,3669 (defvar which-func-modes)28,748 (defun proof-script-new-command-advance 43,1241 (defun proof-maybe-follow-locked-end 69,2268 (defun proof-goto-command-start 95,3104 (defun proof-goto-command-end 118,4051 (defun proof-forward-command 133,4473 (defun proof-backward-command 154,5194 (defun proof-goto-point 165,5408 (defun proof-assert-next-command-interactive 179,5842 (defun proof-assert-until-point-interactive 191,6328 (defun proof-process-buffer 198,6573 (defun proof-undo-last-successful-command 216,7085 (defun proof-undo-and-delete-last-successful-command 221,7247 (defun proof-undo-last-successful-command-1 233,7766 (defun proof-retract-buffer 250,8430 (defun proof-retract-current-goal 265,9038 (defun proof-mouse-goto-point 284,9558 (defvar proof-minibuffer-history 299,9834 (defun proof-minibuffer-cmd 302,9929 (defun proof-frob-locked-end 341,11336 (defmacro proof-if-setting-configured 377,12437 (defmacro proof-define-assistant-command 385,12706 (defmacro proof-define-assistant-command-witharg 398,13161 (defun proof-issue-new-command 418,13983 (defun proof-cd-sync 458,15206 (defun proof-electric-terminator-enable 509,16805 (defun proof-electric-terminator 517,17109 (defun proof-add-completions 545,18079 (defun proof-script-complete 568,18902 (defun pg-copy-span-contents 582,19211 (defun pg-numth-span-higher-or-lower 596,19635 (defun pg-control-span-of 622,20381 (defun pg-move-span-contents 628,20585 (defun pg-fixup-children-spans 679,22703 (defun pg-move-region-down 689,22960 (defun pg-move-region-up 698,23253 (defun pg-pos-for-event 712,23527 (defun pg-span-for-event 718,23748 (defun pg-span-context-menu 722,23892 (defun pg-toggle-visibility 738,24409 (defun pg-create-in-span-context-menu 747,24716 (defun pg-span-undo 772,25744 (defun pg-goals-buffers-hint 785,25982 (defun pg-slow-fontify-tracing-hint 789,26200 (defun pg-response-buffers-hint 793,26389 (defun pg-jump-to-end-hint 805,26804 (defun pg-processing-complete-hint 809,26933 (defun pg-next-error-hint 826,27653 (defun pg-hint 831,27805 (defun pg-identifier-under-mouse-query 842,28154 (defun pg-identifier-near-point-query 853,28478 (defvar proof-query-identifier-history 882,29401 (defun proof-query-identifier 885,29488 (defun pg-identifier-query 896,29844 (defun proof-imenu-enable 929,30992 (defvar pg-input-ring 969,32470 (defvar pg-input-ring-index 972,32527 (defvar pg-stored-incomplete-input 975,32599 (defun pg-previous-input 978,32702 (defun pg-next-input 992,33165 (defun pg-delete-input 997,33287 (defun pg-get-old-input 1010,33625 (defun pg-restore-input 1024,34016 (defun pg-search-start 1035,34306 (defun pg-regexp-arg 1047,34798 (defun pg-search-arg 1059,35246 (defun pg-previous-matching-input-string-position 1073,35663 (defun pg-previous-matching-input 1100,36828 (defun pg-next-matching-input 1119,37678 (defvar pg-matching-input-from-input-string 1127,38061 (defun pg-previous-matching-input-from-input 1131,38175 (defun pg-next-matching-input-from-input 1149,38940 (defun pg-add-to-input-history 1160,39319 (defun pg-remove-from-input-history 1172,39772 (defun pg-clear-input-ring 1183,40152 (define-key proof-mode-map 1200,40622 (define-key proof-mode-map 1201,40682 (defun pg-protected-undo 1203,40754 (defun pg-protected-undo-1 1233,42048 (defun next-undo-elt 1264,43485 (defvar proof-autosend-timer 1291,44441 (deflocal proof-autosend-modified-tick 1293,44502 (defun proof-autosend-enable 1297,44624 (defun proof-autosend-delay 1311,45167 (defun proof-autosend-loop 1315,45300 (defun proof-autosend-loop-all 1329,45860 (defun proof-autosend-loop-next 1353,46640 generic/pg-vars.el,1500 (defvar proof-assistant-cusgrp 22,386 (defvar proof-assistant-internals-cusgrp 28,646 (defvar proof-assistant 34,916 (defvar proof-assistant-symbol 39,1139 (defvar proof-mode-for-shell 52,1681 (defvar proof-mode-for-response 57,1871 (defvar proof-mode-for-goals 62,2097 (defvar proof-mode-for-script 67,2286 (defvar proof-ready-for-assistant-hook 72,2463 (defvar proof-shell-busy 83,2751 (defvar proof-shell-last-queuemode 101,3422 (defvar proof-included-files-list 105,3577 (defvar proof-script-buffer 127,4596 (defvar proof-previous-script-buffer 130,4688 (defvar proof-shell-buffer 134,4861 (defvar proof-goals-buffer 137,4947 (defvar proof-response-buffer 140,5002 (defvar proof-trace-buffer 143,5063 (defvar proof-thms-buffer 147,5217 (defvar proof-shell-error-or-interrupt-seen 151,5372 (defvar pg-response-next-error 156,5596 (defvar proof-shell-proof-completed 159,5703 (defvar proof-shell-silent 173,6088 (defvar proof-shell-last-prompt 176,6176 (defvar proof-shell-last-output 180,6346 (defvar proof-shell-last-output-kind 184,6486 (defvar proof-assistant-settings 204,7250 (defvar pg-tracing-slow-mode 214,7764 (defvar proof-nesting-depth 217,7853 (defvar proof-last-theorem-dependencies 224,8088 (defvar proof-autosend-running 228,8250 (defvar proof-next-command-on-new-line 233,8449 (defcustom proof-general-name 244,8683 (defcustom proof-general-home-page249,8840 (defcustom proof-unnamed-theorem-name255,9000 (defcustom proof-universal-keys261,9184 generic/pg-xml.el,1177 (defalias 'pg-xml-error pg-xml-error18,381 (defun pg-xml-parse-string 41,1023 (defun pg-xml-parse-buffer 51,1335 (defun pg-xml-get-attr 70,1950 (defun pg-xml-child-elts 78,2252 (defun pg-xml-child-elt 83,2457 (defun pg-xml-get-child 91,2739 (defun pg-xml-get-text-content 101,3106 (defmacro pg-xml-attr 112,3456 (defmacro pg-xml-node 114,3518 (defconst pg-xml-header117,3610 (defun pg-xml-string-of 121,3686 (defun pg-xml-output-internal 132,4053 (defun pg-xml-cdata 166,5192 (defsubst pg-pgip-get-area 174,5385 (defun pg-pgip-get-icon 177,5502 (defsubst pg-pgip-get-name 181,5650 (defsubst pg-pgip-get-version 184,5767 (defsubst pg-pgip-get-descr 187,5890 (defsubst pg-pgip-get-thmname 190,6009 (defsubst pg-pgip-get-thyname 193,6132 (defsubst pg-pgip-get-url 196,6255 (defsubst pg-pgip-get-srcid 199,6370 (defsubst pg-pgip-get-proverid 202,6489 (defsubst pg-pgip-get-symname 205,6614 (defsubst pg-pgip-get-prefcat 208,6734 (defsubst pg-pgip-get-default 211,6862 (defsubst pg-pgip-get-objtype 214,6985 (defsubst pg-pgip-get-value 217,7108 (defalias 'pg-pgip-get-displaytext pg-pgip-get-displaytext220,7178 (defun pg-pgip-get-pgmltext 222,7237 generic/proof-autoloads.el,97 (defsubst proof-shell-live-buffer 736,23730 (defsubst proof-replace-regexp-in-string 892,29291 generic/proof-auxmodes.el,149 (defun proof-mmm-support-available 20,495 (defun proof-maths-menu-support-available 42,1096 (defun proof-unicode-tokens-support-available 56,1513 generic/proof-config.el,7902 (defgroup prover-config 80,2634 (defcustom proof-guess-command-line 98,3484 (defcustom proof-assistant-home-page 113,3979 (defcustom proof-context-command 119,4149 (defcustom proof-info-command 124,4283 (defcustom proof-showproof-command 131,4554 (defcustom proof-goal-command 136,4690 (defcustom proof-save-command 144,4987 (defcustom proof-find-theorems-command 152,5296 (defcustom proof-query-identifier-command 159,5604 (defcustom proof-assistant-true-value 173,6293 (defcustom proof-assistant-false-value 179,6483 (defcustom proof-assistant-format-int-fn 185,6677 (defcustom proof-assistant-format-float-fn 192,6926 (defcustom proof-assistant-format-string-fn 199,7181 (defcustom proof-assistant-setting-format 206,7448 (defcustom proof-tree-configured 216,7931 (defgroup proof-script 234,8397 (defcustom proof-terminal-string 239,8527 (defcustom proof-electric-terminator-noterminator 249,8915 (defcustom proof-script-sexp-commands 254,9087 (defcustom proof-script-command-end-regexp 265,9546 (defcustom proof-script-command-start-regexp 283,10367 (defcustom proof-script-integral-proofs 294,10830 (defcustom proof-script-fly-past-comments 309,11486 (defcustom proof-script-parse-function 314,11657 (defcustom proof-script-comment-start 332,12302 (defcustom proof-script-comment-start-regexp 343,12739 (defcustom proof-script-comment-end 351,13058 (defcustom proof-script-comment-end-regexp 363,13480 (defcustom proof-string-start-regexp 371,13793 (defcustom proof-string-end-regexp 376,13958 (defcustom proof-case-fold-search 381,14119 (defcustom proof-save-command-regexp 390,14531 (defcustom proof-save-with-hole-regexp 395,14641 (defcustom proof-save-with-hole-result 406,15016 (defcustom proof-goal-command-regexp 416,15460 (defcustom proof-goal-with-hole-regexp 424,15747 (defcustom proof-goal-with-hole-result 436,16190 (defcustom proof-non-undoables-regexp 445,16568 (defcustom proof-nested-undo-regexp 456,17031 (defcustom proof-ignore-for-undo-count 472,17751 (defcustom proof-script-imenu-generic-expression 480,18062 (defcustom proof-goal-command-p 488,18401 (defcustom proof-really-save-command-p 499,18892 (defcustom proof-completed-proof-behaviour 508,19199 (defcustom proof-count-undos-fn 536,20548 (defcustom proof-find-and-forget-fn 548,21099 (defcustom proof-forget-id-command 565,21808 (defcustom pg-topterm-goalhyplit-fn 575,22166 (defcustom proof-kill-goal-command 587,22709 (defcustom proof-undo-n-times-cmd 601,23213 (defcustom proof-nested-goals-history-p 615,23750 (defcustom proof-arbitrary-undo-positions 624,24087 (defcustom proof-state-preserving-p 638,24668 (defcustom proof-activate-scripting-hook 648,25140 (defcustom proof-deactivate-scripting-hook 667,25921 (defcustom proof-no-fully-processed-buffer 676,26251 (defcustom proof-script-evaluate-elisp-comment-regexp 687,26749 (defcustom proof-indent 705,27335 (defcustom proof-indent-hang 710,27442 (defcustom proof-indent-enclose-offset 715,27568 (defcustom proof-indent-open-offset 720,27710 (defcustom proof-indent-close-offset 725,27847 (defcustom proof-indent-any-regexp 730,27985 (defcustom proof-indent-inner-regexp 735,28145 (defcustom proof-indent-enclose-regexp 740,28299 (defcustom proof-indent-open-regexp 745,28453 (defcustom proof-indent-close-regexp 750,28605 (defcustom proof-script-font-lock-keywords 756,28759 (defcustom proof-script-syntax-table-entries 764,29111 (defcustom proof-script-span-context-menu-extensions 782,29507 (defgroup proof-shell 808,30267 (defcustom proof-prog-name 818,30437 (defcustom proof-shell-auto-terminate-commands 830,30904 (defcustom proof-shell-pre-sync-init-cmd 839,31309 (defcustom proof-shell-init-cmd 853,31867 (defcustom proof-shell-init-hook 865,32413 (defcustom proof-shell-restart-cmd 870,32552 (defcustom proof-shell-quit-cmd 875,32707 (defcustom proof-shell-cd-cmd 880,32874 (defcustom proof-shell-start-silent-cmd 897,33545 (defcustom proof-shell-stop-silent-cmd 906,33921 (defcustom proof-shell-silent-threshold 915,34256 (defcustom proof-shell-inform-file-processed-cmd 923,34590 (defcustom proof-shell-inform-file-retracted-cmd 944,35518 (defcustom proof-auto-multiple-files 972,36790 (defcustom proof-cannot-reopen-processed-files 987,37511 (defcustom proof-shell-annotated-prompt-regexp 1007,38302 (defcustom proof-shell-error-regexp 1022,38867 (defcustom proof-shell-truncate-before-error 1042,39677 (defcustom pg-next-error-regexp 1056,40216 (defcustom pg-next-error-filename-regexp 1071,40825 (defcustom pg-next-error-extract-filename 1095,41858 (defcustom proof-shell-interrupt-regexp 1102,42101 (defcustom proof-shell-proof-completed-regexp 1116,42704 (defcustom proof-shell-clear-response-regexp 1129,43220 (defcustom proof-shell-clear-goals-regexp 1141,43680 (defcustom proof-shell-start-goals-regexp 1153,44134 (defcustom proof-shell-end-goals-regexp 1166,44709 (defcustom proof-shell-eager-annotation-start 1180,45299 (defcustom proof-shell-eager-annotation-start-length 1203,46318 (defcustom proof-shell-eager-annotation-end 1214,46744 (defcustom proof-shell-strip-output-markup 1230,47419 (defcustom proof-shell-assumption-regexp 1239,47804 (defcustom proof-shell-process-file 1249,48208 (defcustom proof-shell-retract-files-regexp 1275,49284 (defcustom proof-shell-compute-new-files-list 1288,49772 (defcustom pg-special-char-regexp 1303,50339 (defcustom proof-shell-set-elisp-variable-regexp 1308,50483 (defcustom proof-shell-match-pgip-cmd 1346,52157 (defcustom proof-shell-issue-pgip-cmd 1360,52647 (defcustom proof-use-pgip-askprefs 1365,52820 (defcustom proof-shell-query-dependencies-cmd 1373,53167 (defcustom proof-shell-theorem-dependency-list-regexp 1380,53427 (defcustom proof-shell-theorem-dependency-list-split 1396,54095 (defcustom proof-shell-show-dependency-cmd 1405,54526 (defcustom proof-shell-trace-output-regexp 1427,55432 (defcustom proof-shell-thms-output-regexp 1445,56034 (defcustom proof-shell-interactive-prompt-regexp 1453,56368 (defcustom proof-tokens-activate-command 1472,57021 (defcustom proof-tokens-deactivate-command 1479,57261 (defcustom proof-tokens-extra-modes 1486,57506 (defcustom proof-shell-unicode 1501,58011 (defcustom proof-shell-filename-escapes 1510,58401 (defcustom proof-shell-process-connection-type 1527,59081 (defcustom proof-shell-strip-crs-from-input 1533,59308 (defcustom proof-shell-strip-crs-from-output 1545,59791 (defcustom proof-shell-extend-queue-hook 1553,60159 (defcustom proof-shell-insert-hook 1563,60589 (defcustom proof-script-preprocess 1606,62687 (defcustom proof-shell-handle-delayed-output-hook1612,62838 (defcustom proof-shell-handle-error-or-interrupt-hook1618,63053 (defcustom proof-shell-signal-interrupt-hook 1636,63799 (defcustom proof-shell-pre-interrupt-hook1647,64268 (defcustom proof-shell-handle-output-system-specific 1655,64539 (defcustom proof-state-change-hook 1678,65512 (defcustom proof-shell-syntax-table-entries 1688,65905 (defgroup proof-goals 1706,66276 (defcustom pg-subterm-first-special-char 1711,66397 (defcustom pg-subterm-anns-use-stack 1719,66709 (defcustom pg-goals-change-goal 1728,67008 (defcustom pbp-goal-command 1733,67124 (defcustom pbp-hyp-command 1738,67288 (defcustom pg-subterm-help-cmd 1743,67458 (defcustom pg-goals-error-regexp 1750,67702 (defcustom proof-shell-result-start 1755,67870 (defcustom proof-shell-result-end 1761,68112 (defcustom pg-subterm-start-char 1767,68325 (defcustom pg-subterm-sep-char 1778,68799 (defcustom pg-subterm-end-char 1784,68978 (defcustom pg-topterm-regexp 1790,69135 (defcustom proof-goals-font-lock-keywords 1805,69735 (defcustom proof-response-font-lock-keywords 1813,70094 (defcustom proof-shell-font-lock-keywords 1821,70456 (defcustom pg-before-fontify-output-hook 1832,70970 (defcustom pg-after-fontify-output-hook 1840,71331 generic/proof-depends.el,917 (defvar proof-thm-names-of-files 25,639 (defvar proof-def-names-of-files 31,923 (defun proof-depends-module-name-for-buffer 42,1238 (defun proof-depends-module-of 52,1679 (defun proof-depends-names-in-same-file 60,1970 (defun proof-depends-process-dependencies 79,2578 (defun proof-dependency-in-span-context-menu 132,4313 (defun proof-dep-alldeps-menu 155,5203 (defun proof-dep-make-alldeps-menu 161,5429 (defun proof-dep-split-deps 179,5924 (defun proof-dep-make-submenu 198,6590 (defun proof-make-highlight-depts-menu 209,7001 (defun proof-goto-dependency 220,7309 (defun proof-show-dependency 227,7561 (defconst pg-dep-span-priority 234,7850 (defconst pg-ordinary-span-priority 235,7886 (defun proof-highlight-depcs 237,7928 (defun proof-highlight-depts 248,8394 (defun proof-depends-save-old-face 260,8904 (defun proof-depends-restore-old-face 265,9081 (defun proof-dep-unhighlight 271,9310 generic/proof-easy-config.el,193 (defconst proof-easy-config-derived-modes-table17,605 (defun proof-easy-config-define-derived-modes 24,1011 (defun proof-easy-config-check-setup 53,2196 (defmacro proof-easy-config 85,3526 generic/proof-faces.el,1809 (defgroup proof-faces 29,809 (defconst pg-defface-window-systems36,989 (defmacro proof-face-specs 49,1551 (defface proof-queue-face64,2003 (defface proof-locked-face72,2278 (defface proof-declaration-name-face82,2604 (defface proof-tacticals-name-face91,2890 (defface proof-tactics-name-face100,3152 (defface proof-error-face109,3417 (defface proof-warning-face117,3638 (defface proof-eager-annotation-face126,3895 (defface proof-debug-message-face134,4113 (defface proof-boring-face142,4312 (defface proof-mouse-highlight-face150,4504 (defface proof-command-mouse-highlight-face158,4722 (defface proof-region-mouse-highlight-face166,4961 (defface proof-highlight-dependent-face174,5203 (defface proof-highlight-dependency-face182,5410 (defface proof-active-area-face190,5607 (defface proof-script-sticky-error-face198,5919 (defface proof-script-highlight-error-face206,6148 (defconst proof-face-compat-doc 218,6493 (defconst proof-queue-face 219,6573 (defconst proof-locked-face 220,6641 (defconst proof-declaration-name-face 221,6711 (defconst proof-tacticals-name-face 222,6801 (defconst proof-tactics-name-face 223,6887 (defconst proof-error-face 224,6969 (defconst proof-script-sticky-error-face 225,7037 (defconst proof-script-highlight-error-face 226,7133 (defconst proof-warning-face 227,7235 (defconst proof-eager-annotation-face 228,7307 (defconst proof-debug-message-face 229,7397 (defconst proof-boring-face 230,7481 (defconst proof-mouse-highlight-face 231,7551 (defconst proof-command-mouse-highlight-face 232,7639 (defconst proof-region-mouse-highlight-face 233,7743 (defconst proof-highlight-dependent-face 234,7845 (defconst proof-highlight-dependency-face 235,7941 (defconst proof-active-area-face 236,8039 (defconst proof-script-error-face 237,8119 generic/proof-indent.el,219 (defun proof-indent-indent 19,449 (defun proof-indent-offset 28,715 (defun proof-indent-inner-p 45,1316 (defun proof-indent-goto-prev 54,1616 (defun proof-indent-calculate 61,1949 (defun proof-indent-line 82,2708 generic/proof-maths-menu.el,83 (defun proof-maths-menu-set-global 32,906 (defun proof-maths-menu-enable 46,1357 generic/proof-menu.el,2215 (defvar proof-display-some-buffers-count 36,820 (defun proof-display-some-buffers 38,865 (defun proof-menu-define-keys 95,3006 (defun proof-menu-define-main 154,5912 (defvar proof-menu-favourites 163,6097 (defvar proof-menu-settings 166,6204 (defun proof-menu-define-specific 170,6293 (defun proof-assistant-menu-update 213,7555 (defvar proof-help-menu227,7988 (defvar proof-show-hide-menu235,8252 (defvar proof-buffer-menu246,8676 (defun proof-keep-response-history 312,11125 (defconst proof-quick-opts-menu320,11435 (defun proof-quick-opts-vars 546,20709 (defun proof-quick-opts-changed-from-defaults-p 578,21649 (defun proof-quick-opts-changed-from-saved-p 582,21754 (defun proof-set-document-centred 590,21910 (defun proof-set-non-document-centred 603,22336 (defun proof-quick-opts-save 622,23047 (defun proof-quick-opts-reset 627,23215 (defconst proof-config-menu639,23483 (defconst proof-advanced-menu646,23662 (defvar proof-menu664,24346 (defun proof-main-menu 673,24628 (defun proof-aux-menu 685,24967 (defun proof-menu-define-favourites-menu 701,25313 (defun proof-def-favourite 721,25962 (defvar proof-make-favourite-cmd-history 748,26955 (defvar proof-make-favourite-menu-history 751,27040 (defun proof-save-favourites 754,27126 (defun proof-del-favourite 759,27274 (defun proof-read-favourite 776,27830 (defun proof-add-favourite 800,28604 (defun proof-menu-define-settings-menu 827,29649 (defun proof-menu-entry-name 856,30641 (defun proof-menu-entry-for-setting 866,30991 (defun proof-settings-vars 889,31629 (defun proof-settings-changed-from-defaults-p 894,31806 (defun proof-settings-changed-from-saved-p 898,31912 (defun proof-settings-save 902,32015 (defun proof-settings-reset 907,32182 (defun proof-assistant-invisible-command-ifposs 912,32345 (defun proof-maybe-askprefs 934,33315 (defun proof-assistant-settings-cmd 950,33932 (defun proof-assistant-settings-cmds 958,34215 (defvar proof-assistant-format-table973,34657 (defun proof-assistant-format-bool 982,35083 (defun proof-assistant-format-int 985,35196 (defun proof-assistant-format-float 988,35288 (defun proof-assistant-format-string 991,35384 (defun proof-assistant-format 994,35482 generic/proof-mmm.el,70 (defun proof-mmm-set-global 43,1439 (defun proof-mmm-enable 58,1978 generic/proof-script.el,5814 (deflocal proof-active-buffer-fake-minor-mode 48,1552 (deflocal proof-script-buffer-file-name 51,1678 (deflocal pg-script-portions 58,2088 (defalias 'proof-active-buffer-fake-minor-modeproof-active-buffer-fake-minor-mode61,2194 (defun proof-next-element-count 70,2389 (defun proof-element-id 76,2631 (defun proof-next-element-id 80,2800 (deflocal proof-locked-span 116,4104 (deflocal proof-queue-span 123,4370 (deflocal proof-overlay-arrow 132,4856 (defun proof-span-give-warning 138,4983 (defun proof-span-read-only 144,5163 (defun proof-strict-read-only 153,5536 (defsubst proof-set-queue-endpoints 163,5914 (defun proof-set-overlay-arrow 167,6055 (defsubst proof-set-locked-endpoints 178,6393 (defsubst proof-detach-queue 183,6569 (defsubst proof-detach-locked 188,6708 (defsubst proof-set-queue-start 195,6933 (defsubst proof-set-locked-end 199,7059 (defsubst proof-set-queue-end 211,7529 (defun proof-init-segmentation 222,7826 (defun proof-colour-locked 252,9077 (defun proof-colour-locked-span 259,9350 (defun proof-sticky-errors 265,9623 (defun proof-restart-buffers 278,10039 (defun proof-script-buffers-with-spans 302,10972 (defun proof-script-remove-all-spans-and-deactivate 312,11328 (defun proof-script-clear-queue-spans-on-error 316,11518 (defun proof-script-delete-spans 342,12535 (defun proof-script-delete-secondary-spans 347,12734 (defun proof-unprocessed-begin 360,13023 (defun proof-script-end 368,13277 (defun proof-queue-or-locked-end 377,13587 (defun proof-locked-region-full-p 396,14180 (defun proof-locked-region-empty-p 405,14452 (defun proof-only-whitespace-to-locked-region-p 409,14602 (defun proof-in-locked-region-p 419,14951 (defun proof-goto-end-of-locked 431,15208 (defun proof-goto-end-of-locked-if-pos-not-visible-in-window 448,15995 (defun proof-goto-end-of-locked-on-error-if-pos-not-visible-in-window 459,16476 (defun proof-end-of-locked-visible-p 471,17016 (defconst pg-idioms 490,17609 (defconst pg-all-idioms 493,17705 (defun pg-clear-script-portions 497,17826 (defun pg-remove-element 503,18061 (defun pg-get-element 511,18364 (defun pg-add-element 521,18679 (defun pg-invisible-prop 569,20641 (defun pg-set-element-span-invisible 574,20842 (defun pg-toggle-element-span-visibility 587,21408 (defun pg-open-invisible-span 592,21569 (defun pg-make-element-invisible 597,21740 (defun pg-make-element-visible 602,21951 (defun pg-toggle-element-visibility 607,22145 (defun pg-show-all-portions 613,22408 (defun pg-show-all-proofs 635,23152 (defun pg-hide-all-proofs 640,23280 (defun pg-add-proof-element 645,23411 (defun pg-span-name 660,24198 (defvar pg-span-context-menu-keymap693,25405 (defun pg-last-output-displayform 700,25643 (defun pg-set-span-helphighlights 723,26534 (defun proof-complete-buffer-atomic 786,28681 (defun proof-register-possibly-new-processed-file815,29951 (defun proof-query-save-this-buffer-p 861,31825 (defun proof-inform-prover-file-retracted 866,32050 (defun proof-auto-retract-dependencies 886,32901 (defun proof-unregister-buffer-file-name 940,35451 (defsubst proof-action-completed 986,37276 (defun proof-protected-process-or-retract 990,37446 (defun proof-deactivate-scripting-auto 1018,38677 (defun proof-deactivate-scripting-query-user-action 1027,39035 (defun proof-deactivate-scripting-choose-action 1071,40544 (defun proof-deactivate-scripting 1083,40929 (defun proof-activate-scripting 1180,45052 (defun proof-toggle-active-scripting 1280,49591 (defun proof-done-advancing 1319,50836 (defun proof-done-advancing-comment 1387,53333 (defun proof-done-advancing-save 1421,54719 (defun proof-make-goalsave1509,58083 (defun proof-get-name-from-goal 1527,58948 (defun proof-done-advancing-autosave 1547,59973 (defun proof-done-advancing-other 1611,62469 (defun proof-segment-up-to-parser 1640,63433 (defun proof-script-generic-parse-find-comment-end 1710,65714 (defun proof-script-generic-parse-cmdend 1719,66128 (defun proof-script-generic-parse-cmdstart 1770,68024 (defun proof-script-generic-parse-sexp 1809,69624 (defun proof-semis-to-vanillas 1821,70090 (defun proof-next-command-new-line 1874,71763 (defun proof-script-next-command-advance 1879,71969 (defun proof-assert-until-point 1898,72469 (defun proof-assert-electric-terminator 1914,73140 (defun proof-assert-semis 1958,74820 (defun proof-retract-before-change 1972,75581 (defun proof-insert-pbp-command 1995,76237 (defun proof-insert-sendback-command 2010,76740 (defun proof-done-retracting 2036,77643 (defun proof-setup-retract-action 2071,79097 (defun proof-last-goal-or-goalsave 2083,79702 (defun proof-retract-target 2107,80614 (defun proof-retract-until-point-interactive 2186,83867 (defun proof-retract-until-point 2195,84274 (define-derived-mode proof-mode 2253,86415 (defun proof-script-set-visited-file-name 2289,87797 (defun proof-script-set-buffer-hooks 2311,88810 (defun proof-script-kill-buffer-fn 2319,89228 (defun proof-config-done-related 2351,90545 (defun proof-generic-goal-command-p 2422,93402 (defun proof-generic-state-preserving-p 2427,93615 (defun proof-generic-count-undos 2436,94132 (defun proof-generic-find-and-forget 2467,95260 (defconst proof-script-important-settings2518,97032 (defun proof-config-done 2533,97578 (defun proof-setup-parsing-mechanism 2605,99856 (defun proof-setup-imenu 2629,100928 (deflocal proof-segment-up-to-cache 2666,102210 (deflocal proof-segment-up-to-cache-start 2670,102353 (deflocal proof-segment-up-to-cache-end 2671,102398 (deflocal proof-last-edited-low-watermark 2672,102441 (defun proof-segment-up-to-using-cache 2674,102489 (defun proof-segment-cache-contents-for 2702,103609 (defun proof-script-after-change-function 2719,104191 (defun proof-script-set-after-change-functions 2731,104698 generic/proof-shell.el,4011 (defvar proof-marker 35,775 (defvar proof-action-list 38,871 (defsubst proof-shell-invoke-callback 80,2584 (defvar proof-second-action-list-active 86,2794 (defvar proof-shell-last-goals-output 108,3747 (defvar proof-shell-last-response-output 111,3827 (defvar proof-shell-delayed-output-start 114,3914 (defvar proof-shell-delayed-output-end 118,4096 (defvar proof-shell-delayed-output-flags 122,4276 (defvar proof-shell-interrupt-pending 125,4401 (defvar proof-shell-exit-in-progress 130,4625 (defcustom proof-shell-active-scripting-indicator142,4970 (defun proof-shell-ready-prover 194,6554 (defsubst proof-shell-live-buffer 208,7093 (defun proof-shell-available-p 215,7313 (defun proof-grab-lock 221,7535 (defun proof-release-lock 231,7964 (defcustom proof-shell-fiddle-frames 241,8138 (defvar proof-shell-filter-active 246,8296 (defvar proof-shell-filter-was-blocked 249,8380 (defun proof-shell-set-text-representation 253,8564 (defun proof-shell-make-associated-buffers 260,8891 (defun proof-shell-start 276,9557 (defvar proof-shell-kill-function-hooks 439,15123 (defun proof-shell-kill-function 442,15221 (defun proof-shell-clear-state 507,17520 (defun proof-shell-exit 523,17995 (defun proof-shell-bail-out 547,18929 (defun proof-shell-restart 557,19451 (defvar proof-shell-urgent-message-marker 598,20823 (defvar proof-shell-urgent-message-scanner 601,20944 (defun proof-shell-handle-error-output 605,21129 (defun proof-shell-handle-error-or-interrupt 631,21991 (defun proof-shell-error-or-interrupt-action 674,23740 (defun proof-goals-pos 704,25018 (defun proof-pbp-focus-on-first-goal 709,25229 (defsubst proof-shell-string-match-safe 721,25645 (defun proof-shell-handle-immediate-output 725,25806 (defun proof-interrupt-process 792,28413 (defun proof-shell-insert 827,29695 (defun proof-shell-action-list-item 884,31677 (defun proof-shell-set-silent 889,31919 (defun proof-shell-start-silent-item 895,32138 (defun proof-shell-clear-silent 901,32327 (defun proof-shell-stop-silent-item 907,32549 (defsubst proof-shell-should-be-silent 913,32738 (defsubst proof-shell-insert-action-item 925,33311 (defsubst proof-shell-slurp-comments 929,33486 (defun proof-add-to-queue 940,33891 (defun proof-start-queue 996,35997 (defun proof-extend-queue 1008,36392 (defun proof-shell-exec-loop 1027,37011 (defun proof-shell-insert-loopback-cmd 1111,40037 (defun proof-shell-process-urgent-message 1136,41201 (defun proof-shell-process-urgent-message-default 1192,43226 (defun proof-shell-process-urgent-message-trace 1208,43810 (defun proof-shell-process-urgent-message-retract 1220,44333 (defun proof-shell-process-urgent-message-elisp 1246,45463 (defun proof-shell-process-urgent-message-thmdeps 1261,45958 (defun proof-shell-process-interactive-prompt-regexp 1271,46302 (defun proof-shell-strip-eager-annotations 1283,46658 (defun proof-shell-filter-wrapper 1299,47158 (defun proof-shell-filter 1331,48402 (defun proof-shell-filter-first-command 1437,52153 (defun proof-shell-process-urgent-messages 1452,52696 (defun proof-shell-filter-manage-output 1502,54262 (defsubst proof-shell-display-output-as-response 1539,55753 (defun proof-shell-handle-delayed-output 1545,56048 (defvar pg-last-tracing-output-time 1649,59620 (defvar pg-last-trace-output-count 1652,59733 (defconst pg-slow-mode-trigger-count 1655,59818 (defconst pg-slow-mode-duration 1658,59923 (defconst pg-fast-tracing-mode-threshold 1661,60005 (defun pg-tracing-tight-loop 1664,60134 (defun pg-finish-tracing-display 1688,61166 (defun proof-shell-wait 1708,61662 (defun proof-done-invisible 1738,62873 (defun proof-shell-invisible-command 1744,63043 (defun proof-shell-invisible-cmd-get-result 1791,64635 (defun proof-shell-invisible-command-invisible-result 1803,65071 (defun pg-insert-last-output-as-comment 1823,65572 (define-derived-mode proof-shell-mode 1842,66044 (defconst proof-shell-important-settings1879,67079 (defun proof-shell-config-done 1885,67194 generic/proof-site.el,708 (defconst proof-assistant-table-default36,1211 (defconst proof-general-short-version78,2415 (defconst proof-general-version-year 84,2602 (defgroup proof-general 91,2755 (defgroup proof-general-internals 96,2863 (defun proof-home-directory-fn 109,3251 (defcustom proof-home-directory120,3623 (defcustom proof-images-directory129,3989 (defcustom proof-info-directory135,4191 (defun proof-add-to-load-path 150,4667 (defcustom proof-assistant-table177,5517 (defcustom proof-assistants 218,6959 (defun proof-ready-for-assistant 247,8113 (defvar proof-general-configured-provers 298,10348 (defun proof-chose-prover 371,12961 (defun proofgeneral 376,13093 (defun proof-visit-example-file 385,13411 generic/proof-splash.el,991 (defcustom proof-splash-enable 34,1009 (defcustom proof-splash-time 39,1161 (defcustom proof-splash-contents47,1445 (defconst proof-splash-startup-msg91,3010 (defconst proof-splash-welcome 100,3388 (define-derived-mode proof-splash-mode 103,3492 (define-key proof-splash-mode-map 109,3666 (define-key proof-splash-mode-map 110,3718 (defsubst proof-emacs-imagep 115,3845 (defun proof-get-image 120,3970 (defvar proof-splash-timeout-conf 142,4770 (defun proof-splash-centre-spaces 145,4883 (defun proof-splash-remove-screen 172,6039 (defun proof-splash-remove-buffer 189,6695 (defvar proof-splash-seen 200,7083 (defun proof-splash-insert-contents 203,7185 (defun proof-splash-display-screen 243,8315 (defalias 'pg-about pg-about279,9837 (defun proof-splash-message 282,9903 (defun proof-splash-timeout-waiter 295,10361 (defvar proof-splash-old-frame-title-format 308,10921 (defun proof-splash-set-frame-titles 310,10971 (defun proof-splash-unset-frame-titles 319,11286 generic/proof-syntax.el,1278 (defsubst proof-ids-to-regexp 22,516 (defsubst proof-anchor-regexp 29,754 (defconst proof-no-regexp 33,859 (defsubst proof-regexp-alt 36,950 (defsubst proof-regexp-alt-list 45,1262 (defsubst proof-re-search-forward-region 49,1397 (defsubst proof-search-forward 62,1895 (defsubst proof-replace-regexp-in-string 69,2165 (defsubst proof-re-search-forward 74,2416 (defsubst proof-re-search-backward 79,2674 (defsubst proof-re-search-forward-safe 84,2935 (defsubst proof-string-match 90,3216 (defsubst proof-string-match-safe 95,3445 (defsubst proof-stringfn-match 99,3649 (defsubst proof-looking-at 106,3912 (defsubst proof-looking-at-safe 111,4099 (defun proof-buffer-syntactic-context 120,4312 (defsubst proof-looking-at-syntactic-context-default 141,5174 (defun proof-looking-at-syntactic-context 150,5529 (defun proof-inside-comment 159,5991 (defun proof-inside-string 165,6164 (defsubst proof-replace-string 175,6363 (defsubst proof-replace-regexp 180,6567 (defsubst proof-replace-regexp-nocasefold 185,6776 (defvar proof-id 195,7064 (defsubst proof-ids 201,7284 (defun proof-zap-commas 208,7536 (defadvice font-lock-fontify-keywords-region234,8422 (defun proof-format 250,9018 (defun proof-format-filename 269,9657 (defun proof-insert 316,11059 generic/proof-toolbar.el,2402 (defun proof-toolbar-function 34,872 (defun proof-toolbar-icon 38,1019 (defun proof-toolbar-enabler 42,1166 (defun proof-toolbar-make-icon 51,1368 (defun proof-toolbar-make-toolbar-items 60,1676 (defvar proof-toolbar-map 86,2537 (defun proof-toolbar-available-p 89,2636 (defun proof-toolbar-setup 99,2942 (defun proof-toolbar-enable 121,3833 (defalias 'proof-toolbar-undo proof-toolbar-undo154,4891 (defun proof-toolbar-undo-enable-p 156,4959 (defalias 'proof-toolbar-delete proof-toolbar-delete163,5117 (defun proof-toolbar-delete-enable-p 165,5198 (defalias 'proof-toolbar-home proof-toolbar-home173,5380 (defalias 'proof-toolbar-next proof-toolbar-next177,5447 (defun proof-toolbar-next-enable-p 179,5518 (defalias 'proof-toolbar-goto proof-toolbar-goto185,5634 (defun proof-toolbar-goto-enable-p 187,5684 (defalias 'proof-toolbar-retract proof-toolbar-retract192,5769 (defun proof-toolbar-retract-enable-p 194,5826 (defalias 'proof-toolbar-use proof-toolbar-use200,5945 (defalias 'proof-toolbar-use-enable-p proof-toolbar-use-enable-p201,5997 (defalias 'proof-toolbar-prooftree proof-toolbar-prooftree205,6080 (defalias 'proof-toolbar-restart proof-toolbar-restart209,6165 (defalias 'proof-toolbar-goal proof-toolbar-goal213,6230 (defalias 'proof-toolbar-qed proof-toolbar-qed217,6288 (defun proof-toolbar-qed-enable-p 219,6337 (defalias 'proof-toolbar-state proof-toolbar-state227,6499 (defalias 'proof-toolbar-state-enable-p proof-toolbar-state-enable-p228,6542 (defalias 'proof-toolbar-context proof-toolbar-context232,6621 (defalias 'proof-toolbar-context-enable-p proof-toolbar-context-enable-p233,6667 (defalias 'proof-toolbar-command proof-toolbar-command237,6748 (defalias 'proof-toolbar-command-enable-p proof-toolbar-command-enable-p238,6804 (defun proof-toolbar-help 242,6909 (defalias 'proof-toolbar-find proof-toolbar-find248,6989 (defalias 'proof-toolbar-find-enable-p proof-toolbar-find-enable-p249,7041 (defalias 'proof-toolbar-info proof-toolbar-info253,7116 (defalias 'proof-toolbar-info-enable-p proof-toolbar-info-enable-p254,7171 (defalias 'proof-toolbar-visibility proof-toolbar-visibility258,7269 (defun proof-toolbar-visibility-enable-p 260,7329 (defalias 'proof-toolbar-interrupt proof-toolbar-interrupt265,7443 (defun proof-toolbar-interrupt-enable-p 266,7504 (defun proof-toolbar-scripting-menu 274,7657 generic/proof-tree.el,3683 (defgroup proof-tree 99,4376 (defcustom proof-tree-program 104,4517 (defcustom proof-tree-arguments 109,4663 (defgroup proof-tree-internals 119,4823 (defcustom proof-tree-ignored-commands-regexp 127,5092 (defcustom proof-tree-navigation-command-regexp 139,5591 (defcustom proof-tree-cheating-regexp 147,5910 (defcustom proof-tree-new-layer-command-regexp 156,6307 (defcustom proof-tree-current-goal-regexp 165,6699 (defcustom proof-tree-update-goal-regexp 175,7101 (defcustom proof-tree-additional-subgoal-ID-regexp 187,7670 (defcustom proof-tree-existential-regexp 195,7989 (defcustom proof-tree-existentials-state-start-regexp 209,8609 (defcustom proof-tree-existentials-state-end-regexp 220,9160 (defcustom proof-tree-branch-finished-regexp 232,9803 (defcustom proof-tree-get-proof-info 242,10194 (defcustom proof-tree-extract-instantiated-existentials 266,11235 (defcustom proof-tree-show-sequent-command 283,11953 (defcustom proof-tree-find-begin-of-unfinished-proof 297,12575 (defcustom proof-tree-find-undo-position 308,13138 (defcustom proof-tree-urgent-action-hook 318,13586 (defvar proof-tree-external-display 342,14441 (defvar proof-tree-process 353,14946 (defconst proof-tree-process-name 356,15035 (defconst proof-tree-process-buffer-name359,15134 (defvar proof-tree-process-buffer 363,15291 (defconst proof-tree-emacs-exec-regexp366,15390 (defvar proof-tree-last-state 370,15557 (defvar proof-tree-current-proof 374,15661 (defvar proof-tree-sequent-hash 379,15842 (defvar proof-tree-existentials-alist 394,16549 (defvar proof-tree-existentials-alist-history 405,17048 (defvar proof-tree-output-marker 414,17267 (defvar proof-tree-filter-continuation 418,17448 (defun proof-tree-stop-external-display 425,17802 (defun proof-tree-handle-proof-tree-undo 432,18065 (defun proof-tree-insert-script 444,18537 (defun proof-tree-insert-output 470,19488 (defun proof-tree-process-filter 487,20174 (defun proof-tree-process-sentinel 547,22505 (defun proof-tree-start-process 555,22833 (defun proof-tree-is-running 592,24292 (defun proof-tree-ensure-running 597,24453 (defconst proof-tree-protocol-version 607,24657 (defun proof-tree-send-message 612,24857 (defun proof-tree-send-configure 626,25343 (defun proof-tree-send-goal-state 634,25560 (defun proof-tree-send-update-sequent 662,26678 (defun proof-tree-send-switch-goal 675,27115 (defun proof-tree-send-branch-finished 684,27441 (defun proof-tree-send-proof-complete 698,27956 (defun proof-tree-send-undo 706,28205 (defun proof-tree-send-quit-proof 711,28387 (defun proof-tree-record-existentials-state 722,28722 (defun proof-tree-undo-state-var 735,29272 (defun proof-tree-undo-existentials 754,30053 (defun proof-tree-delete-existential-assoc 762,30368 (defun proof-tree-add-existential-assoc 768,30631 (defun proof-tree-clear-existentials 781,31246 (defun proof-tree-show-goal-callback 791,31514 (defun proof-tree-make-show-goal-callback 812,32501 (defun proof-tree-urgent-action 816,32662 (defun proof-tree-quit-proof 881,35198 (defun proof-tree-register-existentials 891,35617 (defun proof-tree-extract-goals 904,36161 (defun proof-tree-extract-list 926,37106 (defun proof-tree-extract-existential-info 949,38076 (defun proof-tree-handle-proof-progress 970,38967 (defun proof-tree-handle-navigation 1027,41464 (defun proof-tree-handle-proof-command 1045,42190 (defun proof-tree-handle-undo 1061,42893 (defun proof-tree-update-sequent 1093,44192 (defun proof-tree-handle-delayed-output 1134,45960 (defun proof-tree-leave-buffer 1194,48408 (defun proof-tree-display-current-proof 1206,48691 (defun proof-tree-external-display-toggle 1238,50032 generic/proof-unicode-tokens.el,497 (defvar proof-unicode-tokens-initialised 31,827 (defun proof-unicode-tokens-init 34,934 (defun proof-unicode-tokens-configure 48,1436 (defun proof-unicode-tokens-mode-if-enabled 60,1882 (defun proof-unicode-tokens-set-global 66,2081 (defun proof-unicode-tokens-enable 82,2651 (defun proof-unicode-tokens-reconfigure 102,3504 (defun proof-unicode-tokens-configure-prover 128,4392 (defun proof-unicode-tokens-activate-prover 133,4573 (defun proof-unicode-tokens-deactivate-prover 140,4819 generic/proof-useropts.el,1785 (defgroup proof-user-options 21,566 (defun proof-set-value 29,745 (defcustom proof-electric-terminator-enable 62,1868 (defcustom proof-next-command-insert-space 74,2400 (defcustom proof-toolbar-enable 82,2730 (defcustom proof-imenu-enable 88,2903 (defcustom pg-show-hints 94,3074 (defcustom proof-shell-quiet-errors 99,3207 (defcustom proof-trace-output-slow-catchup 106,3478 (defcustom proof-strict-state-preserving 116,3975 (defcustom proof-strict-read-only 129,4584 (defcustom proof-three-window-enable 142,5163 (defcustom proof-multiple-frames-enable 161,5911 (defcustom proof-layout-windows-on-visit-file 171,6306 (defcustom proof-three-window-mode-policy 180,6690 (defcustom proof-delete-empty-windows 199,7405 (defcustom proof-shrink-windows-tofit 210,7936 (defcustom proof-auto-raise-buffers 217,8208 (defcustom proof-colour-locked 224,8443 (defcustom proof-sticky-errors 232,8693 (defcustom proof-query-file-save-when-activating-scripting239,8910 (defcustom proof-prog-name-ask255,9630 (defcustom proof-prog-name-guess261,9790 (defcustom proof-tidy-response269,10055 (defcustom proof-keep-response-history283,10518 (defcustom pg-input-ring-size 293,10906 (defcustom proof-general-debug 298,11058 (defcustom proof-use-parser-cache 307,11429 (defcustom proof-follow-mode 314,11683 (defcustom proof-auto-action-when-deactivating-scripting 338,12860 (defcustom proof-rsh-command 366,14042 (defcustom proof-disappearing-proofs 382,14600 (defcustom proof-full-annotation 387,14761 (defcustom proof-output-tooltips 397,15224 (defcustom proof-minibuffer-messages 408,15731 (defcustom proof-autosend-enable 416,16040 (defcustom proof-autosend-delay 422,16220 (defcustom proof-autosend-all 428,16378 (defcustom proof-fast-process-buffer 433,16547 generic/proof-utils.el,1645 (defmacro proof-with-current-buffer-if-exists 61,1737 (defmacro proof-with-script-buffer 70,2114 (defmacro proof-map-buffers 81,2495 (defmacro proof-sym 86,2680 (defsubst proof-try-require 91,2841 (defun proof-save-some-buffers 104,3172 (defun proof-save-this-buffer 124,3768 (defun proof-file-truename 137,4132 (defun proof-files-to-buffers 141,4314 (defun proof-buffers-in-mode 149,4553 (defun pg-save-from-death 163,5003 (defun proof-define-keys 182,5619 (defun pg-remove-specials 193,5904 (defun pg-remove-specials-in-string 203,6240 (defun proof-safe-split-window-vertically 213,6465 (defun proof-warn-if-unset 218,6645 (defun proof-get-window-for-buffer 223,6863 (defun proof-display-and-keep-buffer 260,8497 (defun proof-clean-buffer 302,10220 (defun pg-internal-warning 318,10876 (defun proof-debug 326,11158 (defun proof-switch-to-buffer 341,11709 (defun proof-resize-window-tofit 363,12833 (defun proof-submit-bug-report 458,16681 (defun proof-deftoggle-fn 493,18038 (defmacro proof-deftoggle 508,18704 (defun proof-defintset-fn 519,19217 (defmacro proof-defintset 538,20041 (defun proof-deffloatset-fn 545,20420 (defmacro proof-deffloatset 561,21134 (defun proof-defstringset-fn 568,21519 (defmacro proof-defstringset 581,22145 (defun proof-escape-keymap-doc 594,22601 (defmacro proof-defshortcut 598,22755 (defmacro proof-definvisible 613,23353 (defun pg-custom-save-vars 640,24282 (defun pg-custom-reset-vars 656,24926 (defun proof-locate-executable 669,25263 (defun pg-current-word-pos 684,25813 (defsubst proof-shell-strip-output-markup 729,27468 (defun proof-minibuffer-message 735,27732 lib/bufhist.el,1257 (defun bufhist-ring-update 38,1391 (defgroup bufhist 47,1713 (defcustom bufhist-ring-size 51,1794 (defvar bufhist-ring 56,1905 (defvar bufhist-ring-pos 59,1979 (defvar bufhist-lastswitch-modified-tick 62,2058 (defvar bufhist-read-only-history 65,2164 (defvar bufhist-saved-mode-line-format 68,2235 (defvar bufhist-normal-read-only 71,2338 (defvar bufhist-top-point 74,2432 (defun bufhist-mode-line-format-entry 77,2522 (defconst bufhist-minor-mode-map106,3596 (define-minor-mode bufhist-mode119,4073 (defun bufhist-get-buffer-contents 141,4954 (defun bufhist-restore-buffer-contents 150,5296 (defun bufhist-checkpoint 159,5610 (defun bufhist-erase-buffer 167,5979 (defun bufhist-checkpoint-and-erase 178,6350 (defun bufhist-switch-to-index 184,6536 (defun bufhist-first 223,8135 (defun bufhist-last 228,8294 (defun bufhist-prev 233,8438 (defun bufhist-next 241,8661 (defun bufhist-delete 246,8801 (defun bufhist-clear 258,9342 (defun bufhist-init 273,9737 (defun bufhist-exit 301,10746 (defun bufhist-set-readwrite 311,11010 (defun bufhist-before-change-function 326,11630 (define-button-type 'bufhist-nextbufhist-next340,12053 (define-button-type 'bufhist-prevbufhist-prev344,12150 (defun bufhist-insert-buttons 351,12362 lib/holes.el,2465 (defvar holes-default-hole 44,1123 (defvar holes-active-hole 50,1301 (defgroup holes 60,1498 (defcustom holes-empty-hole-string 65,1597 (defcustom holes-empty-hole-regexp 70,1740 (defface active-hole-face92,2442 (defface inactive-hole-face102,2858 (defvar hole-map116,3299 (defvar holes-mode-map126,3690 (defun holes-region-beginning-or-nil 172,5427 (defun holes-region-end-or-nil 176,5563 (defun holes-copy-active-region 180,5681 (defun holes-is-hole-p 186,5891 (defun holes-hole-start-position 190,5983 (defun holes-hole-end-position 196,6166 (defun holes-hole-buffer 201,6337 (defun holes-hole-at 207,6511 (defun holes-active-hole-exist-p 212,6681 (defun holes-active-hole-start-position 219,6934 (defun holes-active-hole-end-position 227,7302 (defun holes-active-hole-buffer 236,7665 (defun holes-goto-active-hole 244,7966 (defun holes-highlight-hole-as-active 253,8225 (defun holes-highlight-hole 261,8533 (defun holes-disable-active-hole 269,8820 (defun holes-set-active-hole 282,9352 (defun holes-is-in-hole-p 292,9697 (defun holes-make-hole 296,9835 (defun holes-make-hole-at 314,10491 (defun holes-clear-hole 328,10944 (defun holes-clear-hole-at 337,11202 (defun holes-map-holes 345,11458 (defun holes-clear-all-buffer-holes 349,11612 (defun holes-next 359,11912 (defun holes-next-after-active-hole 366,12163 (defun holes-set-active-hole-next 373,12379 (defun holes-replace-segment 392,12916 (defun holes-replace 401,13269 (defun holes-replace-active-hole 429,14447 (defun holes-replace-update-active-hole 436,14738 (defun holes-delete-update-active-hole 454,15385 (defun holes-set-make-active-hole 462,15612 (defalias 'holes-track-mouse-selection holes-track-mouse-selection477,16166 (defsubst holes-track-mouse-clicks 478,16224 (defun holes-mouse-replace-active-hole 482,16334 (defun holes-destroy-hole 496,16805 (defsubst holes-hole-at-event 510,17187 (defun holes-mouse-destroy-hole 514,17287 (defun holes-mouse-forget-hole 521,17508 (defun holes-mouse-set-make-active-hole 531,17800 (defun holes-mouse-set-active-hole 547,18299 (defun holes-set-point-next-hole-destroy 556,18550 (defun holes-replace-string-by-holes-backward 582,19531 (defun holes-skeleton-end-hook 600,20231 (defconst holes-jump-doc609,20669 (defun holes-replace-string-by-holes-backward-jump 616,20875 (define-minor-mode holes-mode 634,21632 (defun holes-abbrev-complete 729,25114 (defun holes-insert-and-expand 739,25457 lib/local-vars-list.el,276 (defconst local-vars-list-doc 28,827 (defun local-vars-list-find 43,1276 (defun local-vars-list-goto-var 62,2047 (defun local-vars-list-get-current 88,3094 (defun local-vars-list-get 109,3944 (defun local-vars-list-get-safe 130,4653 (defun local-vars-list-set 135,4847 lib/maths-menu.el,242 (defvar maths-menu-filter-predicate 56,2328 (defvar maths-menu-tokenise-insert 59,2436 (defun maths-menu-build-menu 62,2551 (defvar maths-menu-menu84,3312 (defvar maths-menu-mode-map344,12870 (define-minor-mode maths-menu-mode352,13089 lib/pg-dev.el,199 (defconst pg-dev-lisp-font-lock-keywords58,1742 (defun pg-loadpath 84,2444 (defun unload-pg 94,2615 (defun profile-pg 125,3509 (defun elp-pack-number 155,4616 (defun pg-bug-references 164,4816 lib/pg-fontsets.el,210 (defcustom pg-fontsets-default-fontset 27,803 (defvar pg-fontsets-names 32,949 (defun pg-fontsets-make-fontsetsizes 35,1030 (defconst pg-fontsets-base-fonts54,1791 (defun pg-fontsets-make-fontsets 60,1921 lib/proof-compat.el,123 (defvar proof-running-on-win32 32,975 (defun pg-custom-undeclare-variable 53,1777 (defmacro save-selected-frame 86,2602 lib/scomint.el,788 (defvar scomint-buffer-maximum-size 19,493 (defvar scomint-output-filter-functions 24,684 (defvar scomint-mode-map27,794 (defvar scomint-last-input-start 33,973 (defvar scomint-last-input-end 34,1011 (defvar scomint-last-output-start 35,1047 (defvar scomint-exec-hook 37,1087 (define-derived-mode scomint-mode 46,1430 (defsubst scomint-check-proc 65,2345 (defun scomint-make-in-buffer 73,2685 (defun scomint-make 97,3952 (defun scomint-exec 110,4663 (defun scomint-exec-1 147,6256 (defalias 'scomint-send-string scomint-send-string197,8386 (defun scomint-send-eof 199,8440 (defun scomint-send-input 208,8673 (defun scomint-truncate-buffer 234,9569 (defun scomint-strip-ctrl-m 247,9963 (defun scomint-output-filter 261,10540 (defun scomint-interrupt-process 284,11295 lib/span.el,1553 (defalias 'span-start span-start22,609 (defalias 'span-end span-end23,647 (defalias 'span-set-property span-set-property24,681 (defalias 'span-property span-property25,724 (defalias 'span-make span-make26,763 (defalias 'span-detach span-detach27,799 (defalias 'span-set-endpoints span-set-endpoints28,839 (defalias 'span-buffer span-buffer29,884 (defun span-read-only-hook 31,925 (defsubst span-read-only 36,1115 (defsubst span-read-write 43,1425 (defsubst span-write-warning 48,1595 (defsubst span-lt 59,2119 (defsubst spans-at-point-prop 64,2263 (defsubst spans-at-region-prop 73,2454 (defsubst span-at 83,2720 (defsubst span-delete 87,2846 (defsubst span-add-delete-action 93,3042 (defsubst span-mapcar-spans 99,3321 (defsubst span-mapc-spans 103,3496 (defsubst span-mapcar-spans-inorder 107,3667 (defun span-at-before 113,3872 (defsubst prev-span 130,4596 (defsubst next-span 136,4749 (defsubst span-live-p 142,4963 (defsubst span-raise 148,5129 (defsubst span-string 152,5262 (defsubst set-span-properties 157,5422 (defsubst span-find-span 163,5616 (defsubst span-at-event 171,5928 (defun fold-spans 177,6125 (defsubst span-detached-p 191,6658 (defsubst set-span-face 195,6774 (defsubst set-span-keymap 199,6872 (defsubst span-delete-spans 207,7041 (defsubst span-property-safe 211,7203 (defsubst span-set-start 215,7340 (defsubst span-set-end 219,7472 (defun span-make-self-removing-span 227,7632 (defun span-delete-self-modification-hook 237,8000 (defun span-make-modifying-removing-span 242,8174 lib/texi-docstring-magic.el,584 (defun texi-docstring-magic-find-face 88,3032 (defun texi-docstring-magic-splice-sep 93,3197 (defconst texi-docstring-magic-munge-table103,3502 (defun texi-docstring-magic-untabify 193,7265 (defun texi-docstring-magic-munge-docstring 200,7463 (defun texi-docstring-magic-texi 239,8744 (defun texi-docstring-magic-format-default 252,9184 (defun texi-docstring-magic-texi-for 268,9817 (defconst texi-docstring-magic-comment326,11776 (defun texi-docstring-magic 332,11930 (defun texi-docstring-magic-face-at-point 366,13009 (defun texi-docstring-magic-insert-magic 381,13532 lib/unicode-chars.el,80 (defvar unicode-chars-alist12,348 (defun unicode-chars-list-chars 5051,245975 lib/unicode-tokens.el,5902 (defgroup unicode-tokens-options 58,1844 (defcustom unicode-tokens-add-help-echo 63,1969 (defun unicode-tokens-toggle-add-help-echo 68,2136 (defvar unicode-tokens-token-symbol-map 82,2542 (defvar unicode-tokens-token-format 101,3201 (defvar unicode-tokens-token-variant-format-regexp 107,3450 (defvar unicode-tokens-shortcut-alist 121,3983 (defvar unicode-tokens-shortcut-replacement-alist 127,4260 (defvar unicode-tokens-control-region-format-regexp 135,4466 (defvar unicode-tokens-control-char-format-regexp 142,4834 (defvar unicode-tokens-control-regions 149,5195 (defvar unicode-tokens-control-characters 152,5271 (defvar unicode-tokens-control-char-format 155,5353 (defvar unicode-tokens-control-region-format-start 158,5466 (defvar unicode-tokens-control-region-format-end 161,5583 (defvar unicode-tokens-tokens-customizable-variables 164,5696 (defconst unicode-tokens-configuration-variables171,5864 (defun unicode-tokens-config 186,6263 (defun unicode-tokens-config-var 190,6408 (defun unicode-tokens-copy-configuration-variables 202,6848 (defvar unicode-tokens-token-list 230,8064 (defvar unicode-tokens-hash-table 233,8184 (defvar unicode-tokens-token-match-regexp 236,8300 (defvar unicode-tokens-uchar-hash-table 242,8583 (defvar unicode-tokens-uchar-regexp 246,8770 (defgroup unicode-tokens-faces 254,8955 (defconst unicode-tokens-font-family-alternatives264,9257 (defface unicode-tokens-symbol-font-face279,9776 (defface unicode-tokens-script-font-face290,10249 (defface unicode-tokens-fraktur-font-face295,10393 (defface unicode-tokens-serif-font-face300,10518 (defface unicode-tokens-sans-font-face305,10655 (defface unicode-tokens-highlight-face310,10777 (defconst unicode-tokens-fonts319,11139 (defconst unicode-tokens-fontsymb-properties328,11356 (define-widget 'unicode-tokens-token-symbol-map unicode-tokens-token-symbol-map356,12977 (define-widget 'unicode-tokens-shortcut-alist unicode-tokens-shortcut-alist374,13529 (defconst unicode-tokens-font-lock-extra-managed-props387,13860 (defun unicode-tokens-font-lock-keywords 391,14014 (defun unicode-tokens-calculate-token-match 424,15385 (defun unicode-tokens-usable-composition 454,16421 (defun unicode-tokens-help-echo 467,16800 (defvar unicode-tokens-show-symbols 472,17002 (defun unicode-tokens-interpret-composition 475,17116 (defun unicode-tokens-font-lock-compose-symbol 493,17628 (defun unicode-tokens-prepend-text-properties-in-match 531,19160 (defun unicode-tokens-prepend-text-property 545,19738 (defun unicode-tokens-show-symbols 570,20883 (defun unicode-tokens-symbs-to-props 578,21193 (defvar unicode-tokens-show-controls 598,21892 (defun unicode-tokens-show-controls 601,21983 (defun unicode-tokens-control-char 613,22496 (defun unicode-tokens-control-region 622,22935 (defun unicode-tokens-control-font-lock-keywords 633,23482 (defvar unicode-tokens-use-shortcuts 644,23806 (defun unicode-tokens-use-shortcuts 647,23909 (defun unicode-tokens-map-ordering 663,24505 (defun unicode-tokens-quail-define-rules 672,24858 (defun unicode-tokens-insert-token 695,25535 (defun unicode-tokens-annotate-region 704,25839 (defun unicode-tokens-insert-control 728,26677 (defun unicode-tokens-insert-uchar-as-token 738,27126 (defun unicode-tokens-delete-token-near-point 744,27347 (defun unicode-tokens-delete-backward-char 756,27788 (defun unicode-tokens-delete-char 767,28169 (defun unicode-tokens-delete-backward-1 778,28523 (defun unicode-tokens-delete-1 795,29119 (defun unicode-tokens-prev-token 811,29663 (defun unicode-tokens-rotate-token-forward 819,29960 (defun unicode-tokens-rotate-token-backward 846,30850 (defun unicode-tokens-replace-shortcut-match 851,31052 (defun unicode-tokens-replace-shortcuts 860,31422 (defun unicode-tokens-replace-unicode-match 874,32021 (defun unicode-tokens-replace-unicode 881,32322 (defun unicode-tokens-copy-token 898,32924 (define-button-type 'unicode-tokens-listunicode-tokens-list905,33145 (defun unicode-tokens-list-tokens 911,33349 (defun unicode-tokens-list-shortcuts 950,34533 (defalias 'unicode-tokens-list-unicode-chars unicode-tokens-list-unicode-chars968,35171 (defun unicode-tokens-encode-in-temp-buffer 970,35244 (defun unicode-tokens-encode 988,35900 (defun unicode-tokens-encode-str 994,36136 (defun unicode-tokens-copy 998,36298 (defun unicode-tokens-paste 1007,36704 (defvar unicode-tokens-highlight-unicode 1026,37425 (defconst unicode-tokens-unicode-highlight-patterns1029,37517 (defun unicode-tokens-highlight-unicode 1033,37686 (defun unicode-tokens-highlight-unicode-setkeywords 1045,38149 (defun unicode-tokens-initialise 1057,38518 (defvar unicode-tokens-mode-map 1077,39189 (defvar unicode-tokens-display-table1080,39286 (define-minor-mode unicode-tokens-mode1087,39537 (defun unicode-tokens-set-font-var 1223,44112 (defun unicode-tokens-set-font-var-aux 1239,44601 (defun unicode-tokens-mouse-set-font 1270,45762 (defsubst unicode-tokens-face-font-sym 1283,46276 (defun unicode-tokens-set-font-restart 1287,46456 (defun unicode-tokens-save-fonts 1298,46766 (defun unicode-tokens-custom-save-faces 1306,47022 (define-key unicode-tokens-mode-map1323,47478 (define-key unicode-tokens-mode-map1326,47585 (defvar unicode-tokens-quail-translation-keymap1334,47844 (define-key unicode-tokens-quail-translation-keymap1341,48034 (defun unicode-tokens-quail-delete-last-char 1345,48168 (define-key unicode-tokens-mode-map 1360,48595 (define-key unicode-tokens-mode-map 1362,48687 (define-key unicode-tokens-mode-map1364,48778 (define-key unicode-tokens-mode-map1366,48884 (define-key unicode-tokens-mode-map1369,48999 (define-key unicode-tokens-mode-map1371,49108 (define-key unicode-tokens-mode-map1373,49216 (define-key unicode-tokens-mode-map1375,49322 (defun unicode-tokens-customize-submenu 1383,49446 (defun unicode-tokens-define-menu 1390,49669 contrib/mmm/mmm-auto.el,343 (defvar mmm-autoloaded-classes67,2676 (defun mmm-autoload-class 89,3439 (defvar mmm-changed-buffers-list 129,4992 (defun mmm-major-mode-change 132,5099 (defun mmm-check-changed-buffers 145,5620 (defun mmm-mode-on-maybe 154,5970 (defalias 'mmm-add-find-file-hooks mmm-add-find-file-hooks166,6374 (defun mmm-add-find-file-hook 167,6434 contrib/mmm/mmm-class.el,415 (defun mmm-get-class-spec 42,1296 (defun mmm-get-class-parameter 59,1939 (defun mmm-set-class-parameter 63,2105 (defun* mmm-apply-class75,2455 (defun* mmm-apply-classes90,3072 (defun* mmm-apply-all 110,3803 (defun* mmm-ify124,4250 (defun* mmm-match-region206,7095 (defun mmm-match->point 269,9480 (defun mmm-match-and-verify 284,10050 (defun mmm-get-form 310,11101 (defun mmm-default-get-form 321,11576 contrib/mmm/mmm-cmds.el,712 (defun mmm-ify-by-class 41,1210 (defun mmm-ify-region 63,1822 (defun mmm-ify-by-regexp75,2243 (defun mmm-parse-buffer 97,2886 (defun mmm-parse-region 106,3222 (defun mmm-parse-block 115,3601 (defun mmm-get-block 132,4352 (defun mmm-reparse-current-region 146,4634 (defun mmm-clear-current-region 167,5210 (defun mmm-clear-regions 172,5374 (defun mmm-clear-all-regions 177,5520 (defun* mmm-end-current-region 185,5680 (defun mmm-narrow-to-submode-region 220,6928 (defun mmm-insert-region 239,7542 (defun mmm-insert-by-key 258,8348 (defun mmm-get-insertion-spec 342,11613 (defun mmm-insertion-help 369,12573 (defun mmm-display-insertion-key 379,12936 (defun mmm-get-all-insertion-keys 401,13723 contrib/mmm/mmm-compat.el,418 (defvar mmm-xemacs 40,1313 (defvar mmm-keywords-used49,1616 (defmacro mmm-regexp-opt 91,2632 (defvar mmm-evaporate-property110,3281 (defmacro mmm-set-keymap-default 128,4047 (defmacro mmm-event-key 137,4489 (defvar skeleton-positions 146,4708 (defun mmm-fixup-skeleton 147,4739 (defmacro mmm-make-temp-buffer 159,5162 (defvar mmm-font-lock-available-p 172,5558 (defmacro mmm-set-font-lock-defaults 179,5772 contrib/mmm/mmm-cweb.el,228 (defvar mmm-cweb-section-tags38,1117 (defvar mmm-cweb-section-regexp41,1164 (defvar mmm-cweb-c-part-tags44,1254 (defvar mmm-cweb-c-part-regexp47,1313 (defun mmm-cweb-in-limbo 50,1397 (defun mmm-cweb-verify-brief-c 57,1622 contrib/mmm/mmm-mason.el,410 (defvar mmm-mason-perl-tags41,1236 (defvar mmm-mason-pseudo-perl-tags45,1377 (defvar mmm-mason-non-perl-tags48,1453 (defvar mmm-mason-perl-tags-regexp51,1554 (defvar mmm-mason-pseudo-perl-tags-regexp56,1749 (defvar mmm-mason-tag-names-regexp61,1966 (defun mmm-mason-verify-inline 66,2186 (defun mmm-mason-start-line 156,4838 (defun mmm-mason-end-line 161,4903 (defun mmm-mason-set-mode-line 168,4997 contrib/mmm/mmm-mode.el,1025 (defun mmm-mode 101,3867 (defun mmm-mode-on 140,5372 (defun mmm-mode-off 183,7156 (defvar mmm-mode-map 209,7897 (defvar mmm-mode-prefix-map 212,7972 (defvar mmm-mode-menu-map 215,8082 (defun mmm-define-key 218,8173 (define-key mmm-mode-prefix-map 242,8928 (define-key mmm-mode-prefix-map 249,9186 (define-key mmm-mode-map 252,9297 (define-key mmm-mode-menu-map 255,9399 (define-key mmm-mode-menu-map 257,9471 (define-key mmm-mode-menu-map 259,9530 (define-key mmm-mode-menu-map 261,9611 (define-key mmm-mode-menu-map 263,9692 (define-key mmm-mode-menu-map 265,9779 (define-key mmm-mode-menu-map 268,9873 (define-key mmm-mode-menu-map 270,9933 (define-key mmm-mode-menu-map 273,10024 (define-key mmm-mode-menu-map 275,10084 (define-key mmm-mode-menu-map 277,10191 (define-key mmm-mode-menu-map 279,10276 (define-key mmm-mode-menu-map 282,10362 (define-key mmm-mode-menu-map 284,10422 (define-key mmm-mode-menu-map 286,10535 (define-key mmm-mode-menu-map 288,10620 (define-key mmm-mode-map 291,10703 contrib/mmm/mmm-region.el,1643 (defsubst mmm-overlay-at 54,1749 (defun mmm-overlays-at 59,1934 (defun mmm-included-p 72,2387 (defun mmm-overlays-containing 112,3876 (defun mmm-overlays-contained-in 125,4314 (defun mmm-overlays-overlapping 138,4754 (defun mmm-sort-overlays 149,5117 (defvar mmm-current-overlay 158,5359 (defvar mmm-previous-overlay 163,5574 (defvar mmm-current-submode 168,5762 (defvar mmm-previous-submode 173,5962 (defun mmm-update-current-submode 178,6135 (defun mmm-set-current-submode 199,6930 (defun mmm-submode-at 210,7373 (defun mmm-match-front 219,7648 (defun mmm-match-back 238,8409 (defun mmm-front-start 257,9154 (defun mmm-back-end 265,9458 (defun mmm-valid-submode-region 278,9805 (defun* mmm-make-region305,10961 (defun mmm-make-overlay 431,16311 (defun mmm-get-face 459,17444 (defun mmm-clear-overlays 470,17736 (defun mmm-update-mode-info 486,18201 (defun mmm-update-submode-region 572,21874 (defun mmm-add-hooks 589,22604 (defun mmm-remove-hooks 592,22701 (defun mmm-get-local-variables-list 598,22828 (defun mmm-get-locals 618,23524 (defun mmm-get-saved-local 631,24021 (defun mmm-set-local-variables 635,24186 (defun mmm-get-saved-local-variables 646,24564 (defun mmm-save-changed-local-variables 654,24839 (defun mmm-clear-local-variables 673,25543 (defun mmm-enable-font-lock 684,25808 (defun mmm-update-font-lock-buffer 692,26068 (defun mmm-refontify-maybe 705,26479 (defun mmm-submode-changes-in 720,26959 (defun mmm-regions-in 731,27316 (defun mmm-regions-alist 745,27794 (defun mmm-fontify-region 762,28321 (defun mmm-fontify-region-list 783,29343 (defun mmm-beginning-of-syntax 805,30091 contrib/mmm/mmm-rpm.el,154 (defconst mmm-rpm-sh-start-tags48,1618 (defvar mmm-rpm-sh-end-tags53,1842 (defvar mmm-rpm-sh-start-regexp57,2016 (defvar mmm-rpm-sh-end-regexp61,2194 contrib/mmm/mmm-sample.el,168 (defvar mmm-here-doc-mode-alist 84,2601 (defun mmm-here-doc-get-mode 93,3086 (defun mmm-file-variables-verify 208,6343 (defun mmm-file-variables-find-back 232,7148 contrib/mmm/mmm-univ.el,34 (defun mmm-univ-get-mode 38,1205 contrib/mmm/mmm-utils.el,282 (defmacro mmm-valid-buffer 42,1332 (defmacro mmm-save-all 61,1941 (defun mmm-format-string 74,2223 (defun mmm-format-matches 85,2661 (defmacro mmm-save-keyword 108,3419 (defmacro mmm-save-keywords 116,3746 (defun mmm-looking-back-at 129,4244 (defun mmm-make-marker 146,4784 contrib/mmm/mmm-vars.el,2668 (defgroup mmm 104,3283 (defvar mmm-c-derived-modes111,3393 (defvar mmm-save-local-variables115,3512 (defvar mmm-buffer-saved-locals 341,10293 (defvar mmm-region-saved-locals-defaults 346,10493 (defvar mmm-region-saved-locals-for-dominant 352,10753 (defgroup mmm-faces 362,11130 (defcustom mmm-submode-decoration-level 368,11301 (defface mmm-init-submode-face 386,12145 (defface mmm-cleanup-submode-face 390,12285 (defface mmm-declaration-submode-face 394,12422 (defface mmm-comment-submode-face 398,12568 (defface mmm-output-submode-face 402,12721 (defface mmm-special-submode-face 406,12870 (defface mmm-code-submode-face 410,13034 (defface mmm-default-submode-face 414,13173 (defface mmm-delimiter-face 419,13381 (defcustom mmm-mode-string 426,13507 (defcustom mmm-submode-mode-line-format 431,13638 (defvar mmm-primary-mode-display-name 448,14293 (defvar mmm-buffer-mode-display-name 453,14507 (defun mmm-set-mode-line 459,14806 (defvar mmm-classes 483,15614 (defvar mmm-global-classes 489,15859 (defcustom mmm-mode-ext-classes-alist 496,16041 (defun mmm-add-mode-ext-class 515,16831 (defcustom mmm-major-mode-preferences524,17156 (defun mmm-add-to-major-mode-preferences 542,17884 (defun mmm-ensure-modename 558,18642 (defun mmm-modename->function 567,18945 (defcustom mmm-delimiter-mode 581,19394 (defcustom mmm-mode-prefix-key 591,19663 (defcustom mmm-command-modifiers 596,19790 (defcustom mmm-insert-modifiers 610,20423 (defcustom mmm-use-old-command-keys 625,21101 (defun mmm-use-old-command-keys 635,21565 (defcustom mmm-mode-hook 643,21757 (defun mmm-run-constructed-hook 663,22564 (defun mmm-run-major-hook 671,22908 (defun mmm-run-submode-hook 674,22985 (defvar mmm-class-hooks-run 677,23072 (defun mmm-run-class-hook 682,23244 (defvar mmm-primary-mode-entry-hook 687,23416 (defcustom mmm-major-mode-hook 702,24063 (defun mmm-run-major-mode-hook 716,24694 (defcustom mmm-global-mode 729,25235 (defcustom mmm-never-modes745,25902 (defvar mmm-set-file-name-for-modes 763,26202 (defvar mmm-mode 774,26561 (defvar mmm-primary-mode 782,26769 (defvar mmm-classes-alist 793,27135 (defun mmm-add-classes 948,35342 (defun mmm-add-group 953,35507 (defun mmm-add-to-group 963,35880 (defconst mmm-version 977,36307 (defun mmm-version 980,36372 (defvar mmm-temp-buffer-name 987,36515 (defvar mmm-interactive-history 993,36645 (defun mmm-add-to-history 999,36914 (defun mmm-clear-history 1002,36997 (defvar mmm-mode-ext-classes 1010,37182 (defun mmm-get-mode-ext-classes 1015,37393 (defun mmm-clear-mode-ext-classes 1024,37720 (defun mmm-mode-ext-applies 1028,37845 (defun mmm-get-all-classes 1042,38224 doc/ProofGeneral.texi,7116 @node Top145,4236 @node Preface184,5435 @node News for Version 4.2News for Version 4.2209,6074 @node News for Version 4.1News for Version 4.1222,6530 @node News for Version 4.0News for Version 4.0233,6837 @node Future254,7688 @node Credits283,9023 @node Introducing Proof GeneralIntroducing Proof General405,13132 @node Installing Proof GeneralInstalling Proof General460,15106 @node Quick start guideQuick start guide474,15555 @node Features of Proof GeneralFeatures of Proof General519,17749 @node Supported proof assistantsSupported proof assistants625,22293 @node Prerequisites for this manualPrerequisites for this manual677,24283 @node Organization of this manualOrganization of this manual721,25902 @node Basic Script ManagementBasic Script Management747,26730 @node Walkthrough example in IsabelleWalkthrough example in Isabelle766,27330 @node Proof scriptsProof scripts1051,38725 @node Script buffersScript buffers1094,40845 @node Locked queue and editing regionsLocked queue and editing regions1116,41422 @node Goal-save sequencesGoal-save sequences1172,43569 @node Active scripting bufferActive scripting buffer1209,45053 @node Summary of Proof General buffersSummary of Proof General buffers1282,48686 @node Script editing commandsScript editing commands1331,50943 @node Script processing commandsScript processing commands1411,53902 @node Proof assistant commandsProof assistant commands1540,59332 @node Toolbar commandsToolbar commands1733,66260 @node Interrupting during trace outputInterrupting during trace output1758,67219 @node Advanced Script Management and EditingAdvanced Script Management and Editing1798,69149 @node Document centred workingDocument centred working1819,69770 @node Automatic processingAutomatic processing1931,74448 @node Visibility of completed proofsVisibility of completed proofs1986,76496 @node Switching between proof scriptsSwitching between proof scripts2041,78436 @node View of processed files View of processed files 2078,80408 @node Retracting across filesRetracting across files2138,83459 @node Asserting across filesAsserting across files2151,84090 @node Automatic multiple file handlingAutomatic multiple file handling2164,84656 @node Escaping script managementEscaping script management2189,85690 @node Editing featuresEditing features2246,87802 @node Unicode symbols and special layout supportUnicode symbols and special layout support2316,90581 @node Maths menuMaths menu2358,92139 @node Unicode Tokens modeUnicode Tokens mode2375,92830 @node Configuring tokens symbols and shortcutsConfiguring tokens symbols and shortcuts2425,95253 @node Special layout Special layout 2455,96214 @node Moving between Unicode and tokensMoving between Unicode and tokens2565,100332 @node Finding available tokens shortcuts and symbolsFinding available tokens shortcuts and symbols2620,102443 @node Selecting suitable fontsSelecting suitable fonts2659,103617 @node Support for other PackagesSupport for other Packages2724,106605 @node Syntax highlightingSyntax highlighting2754,107441 @node Imenu and SpeedbarImenu and Speedbar2782,108444 @node Support for outline modeSupport for outline mode2828,110115 @node Support for completionSupport for completion2853,111244 @node Support for tagsSupport for tags2910,113406 @node Subterm Activation and Proof by PointingSubterm Activation and Proof by Pointing2962,115754 @node Goals buffer commandsGoals buffer commands2978,116349 @node Graphical Proof-Tree VisualizationGraphical Proof-Tree Visualization3077,120502 @node Starting and Stopping Proof-Tree VisualizationStarting and Stopping Proof-Tree Visualization3109,121702 @node Features of ProoftreeFeatures of Prooftree3137,122859 @node Prooftree CustomizationProoftree Customization3172,124216 @node Customizing Proof GeneralCustomizing Proof General3196,125095 @node Basic optionsBasic options3236,126765 @node How to customizeHow to customize3260,127535 @node Display customizationDisplay customization3307,129502 @node User optionsUser options3506,137458 @node Changing facesChanging faces3751,146473 @node Script buffer facesScript buffer faces3773,147348 @node Goals and response facesGoals and response faces3819,148948 @node Tweaking configuration settingsTweaking configuration settings3864,150480 @node Hints and TipsHints and Tips3921,153006 @node Adding your own keybindingsAdding your own keybindings3940,153607 @node Using file variablesUsing file variables4004,156221 @node Using abbreviationsUsing abbreviations4081,158949 @node LEGO Proof GeneralLEGO Proof General4120,160364 @node LEGO specific commandsLEGO specific commands4161,161733 @node LEGO tagsLEGO tags4181,162188 @node LEGO customizationsLEGO customizations4191,162435 @node Coq Proof GeneralCoq Proof General4221,163275 @node Coq-specific commandsCoq-specific commands4237,163641 @node Multiple File SupportMultiple File Support4260,164149 @node Automatic Compilation in DetailAutomatic Compilation in Detail4348,167481 @node Locking AncestorsLocking Ancestors4456,172391 @node Customizing Coq Multiple File SupportCustomizing Coq Multiple File Support4494,173909 @node Current LimitationsCurrent Limitations4754,184912 @node Editing multiple proofsEditing multiple proofs4776,185665 @node User-loaded tacticsUser-loaded tactics4800,186773 @node Holes featureHoles feature4864,189247 @node Proof-Tree VisualizationProof-Tree Visualization4889,190466 @node Isabelle Proof GeneralIsabelle Proof General4913,191413 @node Choosing logic and starting isabelleChoosing logic and starting isabelle4939,192289 @node Isabelle commandsIsabelle commands5008,195090 @node Isabelle settingsIsabelle settings5151,199282 @node Isabelle customizationsIsabelle customizations5165,199864 @node HOL Light Proof GeneralHOL Light Proof General5188,200357 @node Shell Proof GeneralShell Proof General5235,202336 @node Obtaining and InstallingObtaining and Installing5271,203795 @node Obtaining Proof GeneralObtaining Proof General5286,204160 @node Installing Proof General from tarballInstalling Proof General from tarball5312,205042 @node Setting the names of binariesSetting the names of binaries5336,205832 @node Notes for syssiesNotes for syssies5364,206772 @node Bugs and EnhancementsBugs and Enhancements5440,209769 @node References5461,210584 @node History of Proof GeneralHistory of Proof General5501,211607 @node Old News for 3.0Old News for 3.05595,215772 @node Old News for 3.1Old News for 3.15665,219466 @node Old News for 3.2Old News for 3.25691,220638 @node Old News for 3.3Old News for 3.35752,223641 @node Old News for 3.4Old News for 3.45771,224538 @node Old News for 3.5Old News for 3.55793,225593 @node Old News for 3.6Old News for 3.65797,225650 @node Old News for 3.7Old News for 3.75802,225750 @node Function IndexFunction Index5832,227204 @node Variable IndexVariable Index5836,227280 @node Keystroke IndexKeystroke Index5840,227360 @node Concept IndexConcept Index5844,227426 doc/PG-adapting.texi,4617 @node Top137,3997 @node Introduction175,5147 @node Future216,6800 @node Credits252,8396 @node Beginning with a New ProverBeginning with a New Prover262,8688 @node Overview of adding a new proverOverview of adding a new prover302,10630 @node Demonstration instance and easy configurationDemonstration instance and easy configuration384,14250 @node Major modes used by Proof GeneralMajor modes used by Proof General453,17641 @node Menus and Toolbar and User-level CommandsMenus and Toolbar and User-level Commands496,19351 @node Settings for generic user-level commandsSettings for generic user-level commands511,19897 @node Menu configurationMenu configuration556,21629 @node Toolbar configurationToolbar configuration580,22546 @node Proof Script SettingsProof Script Settings639,24783 @node Recognizing commands and commentsRecognizing commands and comments662,25395 @node Recognizing proofsRecognizing proofs799,31848 @node Recognizing other elementsRecognizing other elements903,36152 @node Configuring undo behaviourConfiguring undo behaviour966,38631 @node Nested proofsNested proofs1103,44018 @node Safe (state-preserving) commandsSafe (state-preserving) commands1143,45644 @node Activate scripting hookActivate scripting hook1166,46597 @node Automatic multiple filesAutomatic multiple files1190,47467 @node Completely asserted buffersCompletely asserted buffers1211,48313 @node Completions1244,49778 @node Proof Shell SettingsProof Shell Settings1285,51268 @node Proof shell commandsProof shell commands1316,52550 @node Script input to the shellScript input to the shell1493,60314 @node Settings for matching various output from proof processSettings for matching various output from proof process1563,63518 @node Settings for matching urgent messages from proof processSettings for matching urgent messages from proof process1690,69074 @node Hooks and other settingsHooks and other settings1950,80364 @node Goals Buffer SettingsGoals Buffer Settings2029,83508 @node Splash Screen SettingsSplash Screen Settings2103,86498 @node Global ConstantsGlobal Constants2129,87253 @node Handling Multiple FilesHandling Multiple Files2155,88082 @node Configuring Editing SyntaxConfiguring Editing Syntax2324,96751 @node Configuring Font LockConfiguring Font Lock2381,98868 @node Configuring TokensConfiguring Tokens2457,102580 @node Configuring Proof-Tree VisualizationConfiguring Proof-Tree Visualization2507,104700 @node A layered set of proof treesA layered set of proof trees2525,105273 @node Prerequisites2557,106624 @node Proof-Tree Display InternalsProof-Tree Display Internals2620,109275 @node Organization of the CodeOrganization of the Code2638,109765 @node Communication2734,114028 @node Guards2763,115292 @node Urgent and Delayed ActionsUrgent and Delayed Actions2817,117437 @node Full AnnotationFull Annotation2884,120285 @node Configuring Prooftree for a New Proof AssistantConfiguring Prooftree for a New Proof Assistant2898,120859 @node Proof Tree Elisp configurationProof Tree Elisp configuration2910,121191 @node Prooftree AdaptionProoftree Adaption2931,122021 @node Writing More Lisp CodeWriting More Lisp Code2951,122700 @node Default values for generic settingsDefault values for generic settings2968,123345 @node Adding prover-specific configurationsAdding prover-specific configurations2998,124428 @node Useful variablesUseful variables3041,125710 @node Useful functions and macrosUseful functions and macros3056,126209 @node Internals of Proof GeneralInternals of Proof General3166,130521 @node Spans3196,131451 @node Proof General site configurationProof General site configuration3211,131824 @node Configuration variable mechanismsConfiguration variable mechanisms3294,134942 @node Global variablesGlobal variables3424,140658 @node Proof script modeProof script mode3499,143282 @node Proof shell modeProof shell mode3763,155239 @node Debugging4373,180807 @node Plans and IdeasPlans and Ideas4416,181683 @node Proof by pointing and similar featuresProof by pointing and similar features4437,182405 @node Granularity of atomic command sequencesGranularity of atomic command sequences4475,184063 @node Browser mode for script files and theoriesBrowser mode for script files and theories4520,186288 @node Demonstration InstantiationsDemonstration Instantiations4550,187319 @node demoisa-easy.el4566,187750 @node demoisa.el4628,189942 @node Function IndexFunction Index4782,194862 @node Variable IndexVariable Index4786,194938 @node Concept IndexConcept Index4795,195117 generic/proof.el,0 pghaskell/pghaskell.el,0 pghaskell/pghashell.el,0 pgocaml/pgocaml.el,0 pgshell/pgshell.el,0 hol-light/hol-light-autotest.el,0 isar/isar-profiling.el,0 isar/interface-setup.el,0 coq/coq-mmm.el,0 coq/coq-autotest.el,0 acl2/acl2.el,0 proofgeneral-4.3~pre130510/acl2/000077500000000000000000000000001214562307500162505ustar00rootroot00000000000000proofgeneral-4.3~pre130510/acl2/README000066400000000000000000000011521214562307500171270ustar00rootroot00000000000000ACL2 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: README,v 12.0 2011/10/13 10:54:47 da Exp $ proofgeneral-4.3~pre130510/acl2/acl2.el000066400000000000000000000054531214562307500174220ustar00rootroot00000000000000;; acl2.el Basic Proof General instance for ACL2 ;; ;; Copyright (C) 2000 LFCS Edinburgh. ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; Author: David Aspinall ;; ;; $Id: acl2.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;; ;; 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-script-comment-start ";" proof-shell-annotated-prompt-regexp "ACL2[ !]*>+" proof-save-command-regexp "(def\\w+\\s " proof-goal-command-regexp "(def\\w+\\s " proof-save-with-hole-regexp "(def\\w+[ \t\n]+\\(\\w+\\)" proof-save-with-hole-result 1 proof-shell-error-regexp "^Error: \\|Error in TOP-LEVEL: \\|\\*\\*\\*\\* FAILED \\*\\*\\*" proof-shell-interrupt-regexp "Correctable error: Console interrupt." proof-shell-quit-cmd ":q" ;; FIXME: followed by C-d. proof-shell-restart-cmd ":q\n:q\n:q\n(lp)\n" ;; FIXME: maybe not? proof-info-command ":help" proof-undo-n-times-cmd ":ubt %s" ;; shouldn't give errors proof-forget-id-command ":ubt %s" ;; so use ubt not ubt! proof-context-command ":pbt :max" ;; proof-showproof-cmd ":pbt :here" proof-shell-truncate-before-error nil ;; ;; Syntax table entries for proof scripts (FIXME: incomplete) ;; proof-script-syntax-table-entries '(?\[ "(] " ?\] "([ " ?\( "() " ?\) ")( " ?. "w " ?_ "w " ?- "w " ?> "w " ;; things treated as names can have > in them ?# "' " ?\' "' " ?` "' " ?, "' " ?\| "." ?\; "< " ?\n "> " ) ;; A tiny bit of syntax highlighting ;; proof-script-font-lock-keywords (append (list (proof-ids-to-regexp '("defthm" "defabbrev" "defaxiom" "defchoose" "defcong" "defconst" "defdoc" "defequiv" "defevaluator" "defpackage" "deflabel" "deftheory" "implies" "equal" "and"))) (if (boundp 'lisp-font-lock-keywords) ;; wins if font-lock is loaded lisp-font-lock-keywords)) ;; End of easy config. ) ;; Interrupts and errors enter another loop; break out of it (add-hook 'proof-shell-handle-error-or-interrupt-hook (lambda () (if (eq proof-shell-error-or-interrupt-seen 'interrupt) (proof-shell-insert ":q" nil)))) (warn "ACL2 Proof General is incomplete! Please help improve it! Please add improvements at http://proofgeneral.inf.ed.ac.uk/trac") (provide 'acl2) proofgeneral-4.3~pre130510/acl2/example.acl2000066400000000000000000000002761214562307500204530ustar00rootroot00000000000000;; Example proof script for ACL2 Proof General. ;; ;; $Id: example.acl2,v 12.0 2011/10/13 10:54:47 da Exp $ ;; (defthm assoc->assoc-equal (equal (assoc x a) (assoc-equal x a))) proofgeneral-4.3~pre130510/acl2/root2.acl2000066400000000000000000000260311214562307500200620ustar00rootroot00000000000000(* Example proof by Ruben Gamboa. See http://www.cs.kun.nl/~freek/comparison/ *) (in-package "ACL2") ;; This book presents the proof that sqrt(2) is an irrational number. ;; The proof proceeds by observing that p^2 is even precisely when p ;; is even. Thus, if p^2 = 2 q^2, p must be even. But then, p^2 ;; isn't just even, it's a multiple of 4, so q^2 = p^2 / 2 must also ;; be even. But since q^2 is even, so is q. Now, letting p be the ;; numerator of 2 and q the denominator of 2, we find that both the ;; numerator and denominator are even -- but this is an ;; impossibility. Hence, we can conclude that 2 is not rational. ;; The proof is completed by observing that sqrt(2) is not complex. ;; The reason is that if x is complex, x^2 is real only when x is a ;; pure imaginary number. But in those cases, x^2 is negative (include-book "../arithmetic/top" :load-compiled-file nil) ;; Step 1: We begin by proving that p^2 is even precisely when p is ;; even. (encapsulate () ;; Since ACL2 is so strong in induction, it is common to use ;; induction to prove simple number theoretic results. But to induce ;; over the even numbers requires that each time through the ;; induction we "step" by 2, not the usual 1. So we start by ;; introducing the induction scheme for the even numbers. (local (defun even-induction (x) "Induct by going two steps at a time" (if (or (zp x) (equal x 1)) x (1+ (even-induction (1- (1- x))))))) ;; Now we can prove that if p^2 is even, so is p. Because we're ;; doing this inductively, we only consider the even naturals to ;; begin with. (local (defthm lemma-1 (implies (and (integerp p) (<= 0 p) (evenp (* p p))) (evenp p)) :hints (("Goal" :induct (even-induction p))) :rule-classes nil)) ;; Technically, we do not need to worry about the negative integers ;; in this proof, since both the numerator and denominator of 2 (if ;; they existed) are positive. But it's easy enough to prove this, ;; and it gets rid of the "non-negative" hypothesis. In general, it ;; is good to get rid of hypothesis in ACL2 rewrite rules. (local (defthm lemma-2 (implies (and (integerp p) (<= p 0) (evenp (* p p))) (evenp p)) :hints (("Goal" :use (:instance lemma-1 (p (- p))))) :rule-classes nil)) ;; Now, we can prove that if p^2 is even, so is p. But the converse ;; is trivial, so we could show that p^2 is even iff p is even. ;; Because equalities are more powerful rewrite rules than ;; implications, we prefer to do so, even though we don't really need ;; the stronger equality for this proof. So we prove the converse ;; here: if p is even, so is p^2. (local (defthm lemma-3 (implies (and (integerp p) (evenp p)) (evenp (* p p))) :rule-classes nil)) ;; Now, we simply collect the results above to find that p^2 is even ;; if and only if p is even. This is the only theorem that is ;; exported from this event. (defthm even-square-implies-even (implies (integerp p) (equal (evenp (* p p)) (evenp p))) :hints (("Goal" :use ((:instance lemma-1) (:instance lemma-2) (:instance lemma-3))))) ) ;; Step 2. Suppose p^2 is even. Then, p is even, so p^2 is more than ;; even -- it is a multiple of 4. We prove this here, since it is the ;; key fact allowing us to conclude that q^2 is even when we know that ;; p^2 = 2 * q^2. (defthm even-square-implies-even-square-multiple-of-4 (implies (and (integerp p) (evenp (* p p))) (evenp (* 1/2 p p))) :hints (("Goal" :use ((:instance even-square-implies-even) (:instance (:theorem (implies (integerp x) (integerp (* x x)))) (x (* 1/2 p)))) :in-theory (disable even-square-implies-even)))) ;; In the proofs below, we disable ACL2's definition of even, but we ;; need to remember that 2*n is always even. So we prove that rewrite ;; rule here. (defthm evenp-2x (implies (integerp x) (evenp (* 2 x)))) ;; Step 3. Suppose p^2 = 2 * q^2. Then we can conclude that p is ;; even, since p^2 is even. (defthm numerator-sqrt-2-is-even (implies (and (integerp p) (integerp q) (equal (* p p) (* 2 (* q q)))) (evenp p)) :hints (("Goal" :use ((:instance even-square-implies-even) (:instance evenp-2x (x (* q q)))) :in-theory (disable even-square-implies-even evenp-2x evenp)))) ;; Step 4. Suppose p^2 = 2 * q^2. Then we can conclude that q is ;; even, since p^2 is a multiple of 4, so q^2 is even. (defthm denominator-sqrt-2-is-even (implies (and (integerp p) (integerp q) (equal (* p p) (* 2 (* q q)))) (evenp q)) :hints (("Goal" :use ((:instance even-square-implies-even-square-multiple-of-4) (:instance even-square-implies-even (p q)) (:instance evenp-2x (x (* q q))) (:instance equal-*-/-1 (x 2) (y (* p p)) (z (* q q)))) :in-theory (disable even-square-implies-even-square-multiple-of-4 even-square-implies-even evenp-2x evenp equal-*-/-1)))) ;; Step 5. Those are all the pieces we need to prove that sqrt(2) is ;; not rational. For we observe that if p=numerator(sqrt(2)) and ;; q=denominator(sqrt(2)), the theorems above show that both p and q ;; are even, and that's an absurdity. (encapsulate () ;; ACL2's algebraic prowess is modest. In the proof of the main ;; theorem below, it builds the expression p^2/q^2 where x=p/q, but ;; it does not reduce the expression further to x^2. We add a ;; rewrite rule to take care of that. (local (defthm lemma-1 (implies (rationalp x) (equal (* (/ (denominator x)) (/ (denominator x)) (numerator x) (numerator x)) (* x x))) :hints (("Goal" :use ((:instance Rational-implies2) (:instance *-r-denominator-r (r x))) :in-theory (disable Rational-implies2 *-r-denominator-r))))) ;; Now we can prove that the square root of 2 is not rational. This ;; involves using the theorems defined above, as well as some ;; algebraic lemmas to help reduce the terms. The most important ;; hint, however, is the inclusion of the axiom Lowest-Terms, because ;; it is not enabled in the ACL2 world. (defthm sqrt-2-not-rational (implies (equal (* x x) 2) (not (rationalp x))) :hints (("Goal" :use ((:instance numerator-sqrt-2-is-even (p (numerator x)) (q (denominator x))) (:instance denominator-sqrt-2-is-even (p (numerator x)) (q (denominator x))) (:instance Lowest-Terms (n 2) (r (/ (numerator x) 2)) (q (/ (denominator x) 2))) (:instance equal-*-/-1 (x (/ (* (denominator x) (denominator x)))) (y 2) (z (* (numerator x) (numerator x))))) :in-theory (disable equal-*-/-1 numerator-sqrt-2-is-even denominator-sqrt-2-is-even)))) ) ;; Step 6. Now that the rationals are ruled out, we need to weed out ;; the remaining sqrt(2) suspects. One possibility is that sqrt(2) is ;; a complex number. We explore that here. Because ACL2 has very ;; little knowledge of the complex numbers, we have to start with some ;; basic facts. First, we show that (a+bi)^2 = (a^2-b^2)+(ab+ab)i. (encapsulate () ;; We start out with the desired theorem when the complex number is ;; written as a+bi instead of (complex a b). Here, the result ;; follows from simple algebra and the fact that i^2=-1. (local (defthm lemma-1 (equal (* (+ x (* #c(0 1) y)) (+ x (* #c(0 1) y))) (+ (- (* x x) (* y y)) (* #c(0 1) (+ (* x y) (* x y))))) :rule-classes nil)) ;; Now we rewrite the right-hand side of the rewrite rule into the ;; final form of (complex (a^2-b^2) (ab+ab)) (local (defthm lemma-2 (implies (and (realp x) (realp y)) (equal (* (+ x (* #c(0 1) y)) (+ x (* #c(0 1) y))) (complex (- (* x x) (* y y)) (+ (* x y) (* x y))))) :hints (("Goal" :use ((:instance lemma-1) (:instance complex-definition (x (- (* x x) (* y y))) (y (+ (* x y) (* x y))))))) :rule-classes nil)) ;; And finally we rewrite the left-hand side of the rewrite rule into ;; the final form of (complex a b)^2. (defthm complex-square-definition (implies (and (realp x) (realp y)) (equal (* (complex x y) (complex x y)) (complex (- (* x x) (* y y)) (+ (* x y) (* x y))))) :hints (("Goal" :use ((:instance complex-definition) (:instance lemma-2)))) :rule-classes nil) ) ;; Step 7. Since (a+bi)^2 = (a^2-b^2)+(ab+ab)i, it follows that it is ;; real if and only if a or b is zero, i.e., if and only if the number ;; is real or pure imaginary. Since we're interested only in the ;; non-real complex numbers (the ones for which complexp is true), we ;; can conlude that only pure imaginaries have real squares. (encapsulate () ;; First we show that (a+bi)^2 = (a^2-b^2)+(ab+ab)i is real if and ;; only ab+ab is zero. (local (defthm lemma-1 (implies (and (complexp x) (realp (* x x))) (equal (+ (* (realpart x) (imagpart x)) (* (realpart x) (imagpart x))) 0)) :hints (("Goal" :use (:instance complex-square-definition (x (realpart x)) (y (imagpart x))))) :rule-classes nil)) ;; The following rewrite rule allows us to conclude that a real ;; number x is zero whenever x+x is zero. (local (defthm lemma-2 (implies (and (realp x) (equal (+ x x) 0)) (= x 0)))) ;; The two lemmas above conclude that ab is zero whenever (a+bi)^2 is ;; zero, and since b is assumed non-zero (because a+bi is complex), ;; we have that a must be zero, and a+bi=bi is a pure imaginary ;; number. (defthm complex-squares-real-iff-imaginary (implies (and (complexp x) (realp (* x x))) (equal (realpart x) 0)) :hints (("Goal" :use ((:instance lemma-1) (:instance lemma-2 (x (* (realpart x) (imagpart x)))))))) ) ;; Step 7. Trivially, the square of a pure imaginary number bi is a ;; negative real, since bi^2 = -b^2. (defthm imaginary-squares-are-negative (implies (and (complexp x) (equal (realpart x) 0)) (< (* x x) 0)) :hints (("Goal" :use (:instance complex-square-definition (x 0) (y (imagpart x)))))) ;; Step 8. From the theorems above, we can conclude that sqrt(2) is ;; not a complex number, because the only candidates are the pure ;; imaginary numbers, and their squares are all negative. (defthm sqrt-2-not-complexp (implies (complexp x) (not (equal (* x x) 2))) :hints (("Goal" :use ((:instance complex-squares-real-iff-imaginary) (:instance imaginary-squares-are-negative))))) ;; Step 9. That means sqrt(2) is not rational, and neither is it a ;; complex number. The only remaining candidates (in ACL2's universe) ;; are the non-rational reals, so we can prove the main result: the ;; square root of two (if it exists) is irrational. (defthm irrational-sqrt-2 (implies (equal (* x x) 2) (and (realp x) (not (rationalp x)))) :hints (("Goal" :cases ((rationalp x) (complexp x))))) ;; Step 10. Next, it would be nice to show that sqrt(2) actually ;; exists! See the book nonstd/nsa/sqrt.lisp for a proof of that, ;; using non-standard analysis. proofgeneral-4.3~pre130510/bin/000077500000000000000000000000001214562307500161775ustar00rootroot00000000000000proofgeneral-4.3~pre130510/bin/proofgeneral000077500000000000000000000060671214562307500206210ustar00rootroot00000000000000#!/bin/sh # # Simple shell script for launching Proof General. # # Set EMACS to override choice of Emacs version # # PGHOME must be set to the directory where the lisp files of Proof # General are installed. Script checks standard locations in # /usr/share/emacs/site-lisp, or uses PGHOMEDEFAULT defined at top. # # We load ~/.proofgeneral instead of ~/.emacs if it exists. # # Thanks to Achim Brucker for suggestions. # # $Id: proofgeneral,v 12.0 2011/10/13 10:54:47 da Exp $ # # The default path should work if you are using the Proof General RPM # or unpack Proof General in your home directory. Otherwise edit below. # NB: no trailing backslash here! # On Mac, maybe: # /Applications/Emacs.app/Contents/MacOS/Emacs/site-lisp/ProofGeneral PGHOMEDEFAULT=$HOME/ProofGeneral NAME=`basename $0` HELP="Usage: proofgeneral [OPTION] [FILE]... Launches Emacs Proof General, editing the proof script FILE. Options: --emacs startup Proof General with emacs binary --pghome startup Proof General from directory PGDIR -h, --help show this help and exit -v, --version output version information and exit Unrecognized options are passed to Emacs, along with file names. Examples: $NAME Example.thy Load Proof General editing Isar file Example.thy $NAME example.v Load Proof General editing Coq file Example.v For documentation and latest versions, visit http://proofgeneral.inf.ed.ac.uk Report bugs at http://proofgeneral.inf.ed.ac.uk/trac" VERSIONBLURB='David Aspinall. Copyright (C) 1998-2009 LFCS, University of Edinburgh, UK. This is free software; see the source for copying conditions.' while case $1 in -h) echo "$HELP" exit 0;; --help) echo "$HELP" exit 0;; --emacs) EMACS="$2" shift;; --pghome) PGHOME="$2" shift;; --version|-v) VERSION=`grep proof-general-version $PGHOME/generic/proof-site.el | head -1 | sed -e 's/.*Version //g' | sed -e 's/\. .*//g'` echo "$NAME" "--- script to launch Proof General $VERSION" echo "$VERSIONBLURB" exit 0;; *) break;; esac do shift; done # Try to find Proof General directory if [ -z "$PGHOME" ] || [ ! -d "$PGHOME" ]; then # default relative to this script, otherwise PGHOMEDEFAULT MYDIR="`readlink --canonicalize "$0" | sed -ne 's,/bin/proofgeneral$,,p'`" if [ -d "$MYDIR" ]; then PGHOME="$MYDIR" elif [ -d "$PGHOMEDEFAULT" ]; then PGHOME="$PGHOMEDEFAULT" else echo "Cannot find the Proof General lisp files: Set PGHOME or use --pghome." exit 1 fi fi # Try to find an Emacs executable if [ -z "$EMACS" ] || [ ! -x "$EMACS" ]; then if which emacs > /dev/null; then EMACS=`which emacs` else echo "$NAME: cannot find an Emacs executable. Change PATH, set EMACS, use --emacs to specify." 1>&2 exit 1 fi fi # User may use .proofgeneral in preference to .emacs or .xemacs/init.el if [ -f $HOME/.proofgeneral ]; then STARTUP="-q -l $HOME/.proofgeneral" else STARTUP="" fi exec $EMACS $STARTUP -eval "(or (featurep (quote proof-site)) (load \"$PGHOME/generic/proof-site.el\"))" -f proof-splash-display-screen "$@" proofgeneral-4.3~pre130510/ccc/000077500000000000000000000000001214562307500161575ustar00rootroot00000000000000proofgeneral-4.3~pre130510/ccc/README000066400000000000000000000007621214562307500170440ustar00rootroot00000000000000Proof General for the Casl Consistency Checker Author: Christoph Lüth ================================================================= This is a fairly straightforward instantiation of Proof General for the Casl Consistency Checker, CCC. CASL is the standard algebraic specification language, and CCC is a tool to check consistency of CASL specifications. For more information, hasten thee browser yonder: http://www.informatik.uni-bremen.de/cofi/ccc proofgeneral-4.3~pre130510/ccc/ccc.el000066400000000000000000000057711214562307500172430ustar00rootroot00000000000000;; ccc.el - Proof General for the Casl Consistency Checker ;; ;; Author: Christoph Lüth ;; ;; This is a fairly straightforward instantiation of Proof General for ;; the Casl Consistency Checker, CCC. ;; ;; CASL is the standard algebraic specification language, and CCC is a ;; tool to check consistency of CASL specifications. ;; ;; For more information, hasten thee browser yonder: ;; http://www.informatik.uni-bremen.de/cofi/ccc (require 'proof-easy-config) ; nice and easy does it (require 'proof-syntax) ; functions for making regexps (defvar ccc-keywords nil) (defvar ccc-tactics nil) (defvar ccc-tacticals nil) (proof-easy-config 'ccc "CASL Consistency Checker" proof-prog-name "ccc" ;; must be in your path. proof-terminal-string ";" proof-script-comment-start "(*" proof-script-comment-end "*)" proof-goal-command-regexp "\\(ccc\\|holcasl\\) \".*\";" proof-save-command-regexp "^qeccc" proof-goal-with-hole-regexp "\\(ccc\\|holcasl\\) \"\\(\\(.*\\)\\)\"" proof-save-with-hole-regexp "qeccc \"\\(\\(.*\\)\\)\"" proof-non-undoables-regexp "undo\\|back" proof-goal-command "ccc \"%s\";" proof-save-command "qeccc \"%s\";" proof-kill-goal-command "abort ();" proof-showproof-command "prt()" proof-undo-n-times-cmd "undo_steps %s;" proof-auto-multiple-files nil proof-shell-cd-cmd "cd \"%s\"" proof-shell-interrupt-regexp "Interrupt" proof-shell-start-goals-regexp "^No subgoals\\|^[0-9]* subgoals\\|^Wts:" proof-shell-end-goals-regexp "val it" proof-shell-quit-cmd "quit();" proof-assistant-home-page "http://www.informatik.uni-bremen.de/cofi/tools/ccc" proof-shell-annotated-prompt-regexp "^\\(val it = () : unit\n\\)?\\(CCC\\|^HOL-CASL\\)> " ;; "^\\(val it = () : unit\n\\)?ML>? " proof-shell-error-regexp "\\*\\*\\*\\|^.*Error:\\|^uncaught exception \\|^Exception- " proof-shell-proof-completed-regexp "^Consistency proof successfully finished." proof-shell-eager-annotation-start "^\\[opening \\|^###\\|^Reading" ;;; ??? ;; ;; Some basic fontlocking and syntax table entries, as taken from the ;; hol98 instance (it's all SML anyway :-) ;; proof-script-syntax-table-entries '(?\` "\"" ?\$ "." ?\/ "." ?\\ "." ?+ "." ?- "." ?= "." ?% "." ?< "." ?> "." ?\& "." ?. "w" ?_ "w" ?\' "w" ?\| "." ?\[ "(]" ?\] ")[" ?\* ". 23" ?\( "()1" ?\) ")(4") ccc-keywords '("use" "ap" "holcasl" "ccc" "load_lib" "qeccc") ccc-tactics '("compose" "compose'" "prove" "prove_free_type") ccc-tacticals '("Repeat" "Orelse" "Then" "ThenList" "OrelseList") proof-script-font-lock-keywords (list (cons (proof-ids-to-regexp ccc-keywords) 'font-lock-keyword-face) (cons (proof-ids-to-regexp ccc-tactics) 'font-lock-keyword-face) ; (cons (proof-ids-to-regexp hol98-rules) 'font-lock-keyword-face) (cons (proof-ids-to-regexp ccc-tacticals) 'proof-tacticals-name-face)) ) proofgeneral-4.3~pre130510/contrib/000077500000000000000000000000001214562307500170675ustar00rootroot00000000000000proofgeneral-4.3~pre130510/contrib/mmm/000077500000000000000000000000001214562307500176555ustar00rootroot00000000000000proofgeneral-4.3~pre130510/contrib/mmm/AUTHORS000066400000000000000000000007321214562307500207270ustar00rootroot00000000000000MMM Mode was originally designed and written by Michael Shulman . It was inspired by mmm.el for XEmacs by Gongquan Chen . Recent contributors have included: bishop Joe Kelsey Alan Shutko Michael Alan Dorman Brian P Templeton Yann Dirson Marcus Harnisch and others... proofgeneral-4.3~pre130510/contrib/mmm/COPYING000066400000000000000000000431101214562307500207070ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. proofgeneral-4.3~pre130510/contrib/mmm/FAQ000066400000000000000000000172201214562307500202110ustar00rootroot00000000000000-*-outline-*- Frequently Asked Questions about MMM Mode ========================================= * How do I write/capitalize the name of this package/mode? However you want. The author says `MMM Mode' (and occasionally `MMM') when discussing the entire package, and `mmm-mode' when discussing the emacs mode or function. He does think, however, that `Mmm' looks rather ugly, although that is how SourceForge insists on capitalizing the name of the mailing list. * How do I get rid of that ugly gray background color? Put the following line in your Emacs initialization file: (setq mmm-submode-decoration-level 0) You may want to try using MMM Mode for a while with the background highlight, however, or merely changing it to a different color. There are two reasons it's there by default: 1. MMM Mode isn't as smart as you might hope it would be about recognizing new submode regions, so the presence or absence of the highlight can let you know at a glance where it thinks they are. 2. Just like the rest of font-lock, it helps you mentally organize the code; you can see at a glance that THIS code is executed as Perl, but THAT code is straight HTML (or whatever). You can get even more help by setting the above variable to 2, in which case regions will get a background color according to their function. * I typed `<%' (or other delimiter) but I'm still in the wrong mode. MMM Mode isn't that smart yet. You have to tell it explicitly to reparse (`C-c % C-5' or `C-c % C-b') when you add new submode regions, and both delimiters have to be present. Hopefully a future version will be able to automatically recognize new regions an you type them, but that version is not yet here. However, most submode classes provide insertion commands that remove the need to type the delimiters as well as the need to reparse the block: type `C-c % h' for a list of available insertion commands for current submode class(es). * Why is the first character of the end delimiter in the submode region? It isn't. When your cursor looks like it is over that character, it is actually *before* that character and therefore inside the submode region. You can check that the offending character does not have the background highlight--that is, if you haven't set the decoration level to 0. For example, in the following text (where -!- represents the cursor position) print <, there is a link to the subscription page for the MMM Mode mailing list. When asking a question on the list, be sure to give the versions of emacs and MMM Mode you are using, and any other relevant information. proofgeneral-4.3~pre130510/contrib/mmm/INSTALL000066400000000000000000000172271214562307500207170ustar00rootroot00000000000000Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. proofgeneral-4.3~pre130510/contrib/mmm/NEWS000066400000000000000000000213551214562307500203620ustar00rootroot00000000000000MMM Mode NEWS -- history of user-visible changes. -*-outline-*- Copyright (C) 2003, 2004 Michael Abraham Shulman See the file COPYING for copying conditions. Please submit bug reports at http://sourceforge.net/projects/mmm-mode/ * Changes in MMM Mode 0.4.8 ** Delimiter Regions The delimiters which mark off submode regions now have their own overlays. They can be highlighted if you so desire using appropriate class arguments and/or the variable mmm-delimiter-face. They are also in an appropriate major mode, or non-mode as the case may be. ** Nested Submodes Nested submodes are now vaguely supported. ** RPM Spec File An RPM spec file, contributed by , is now included for people who wish to build their own SRPM to install from. ** New Submode Classes Many thanks to Joe Kelsey for writing a very intelligent class for editing Noweb files, and to Alan Shutko for one for CWeb files. We also have a mode for SGML DTD definitions from Yann Dirson. ** Numerous bugfixes and small improvements * Changes in MMM Mode 0.4.7 ** Multiple Decoration Levels You now have finer control over how colorful your submode regions are, via `mmm-submode-decoration-level'. Level 0 turns coloring off--no messing around with faces required. Level 1 (default) is the same as in previous versions. Level 2 colors regions according to function: initialization, cleanup, output, declaration, comment, etc. ** Preferred Major Modes The variable `mmm-major-mode-preferences' lets you tell MMM what modes you prefer for different programming languages and they will be used by all submode classes. ** New Submode Classes New submode classes for JSP and ePerl are included. A major bug in the handling of embedded Java (and other C-type languages) was fixed, so the JSP class should work consistently. * MMM Mode 0.4.6 is a bug-fix release with one user-visible change: ** New Submode Class for RPM Spec Files Contributed by Marcus Harnisch, the `rpm' submode class allows editing appropriate parts of RPM spec files in shell-script mode. * Changes in MMM Mode 0.4.5 ** Font-Lock works again in XEmacs The MMM code to handle font-locking broke in XEmacs several versions back due to differences in the font-lock implementation between Emacs and XEmacs. It appears to be working once again. ** Here-Document submode class improved Here-document names such as <', rather than `C-c % ' as in previous versions. Key sequences of the form `C-c % ' are now reserved for submode region insertion. The old behavior can be restored by setting the variable `mmm-use-old-command-keys' to a non-nil value before MMM Mode is loaded--then insertion commands are bound to `C-c % C-' sequences. ** New Global Mode added MMM Global Mode can now turn MMM Mode on automatically in all buffers, or only in buffers that have associated submode classes. It replaces the previous function `mmm-add-find-file-hook', which still works for now. A side effect of this change is that it is no longer necessary to use `mmm-add-mode-ext-class': `mmm-mode-ext-classes-alist' can be modified directly. The hack used by MMM Global Mode to insinuate itself into all buffers is different from, but vaguely similar to, the one used by FSF Emacs' Global Font Lock Mode. In order that future writers of global modes don't have to reinvent the wheel, MMM Global Mode provides the hook `mmm-major-mode-hook' which is run (in theory) whenever a major mode starts up. Perhaps in future this will be provided in a separate package. ** Automatic submode region insertion commands Submode classes can now define skeletons for automatic insertion of submode regions with delimiters. For example, when using the Mason class, the key sequence `C-c % %' will (by default) insert the text `<% -!- %>' with point where indicated and submode region already present. These commands also wrap around words as described in the documentation of `skeleton-insert'. ** Info Documentation File MMM Mode now has an (admittedly incomplete) manual in Texinfo format. It can be found in the files `mmm.info' or `mmm.texinfo' in the distribution. ** Automatic Installation MMM Mode now uses GNU automake/autoconf for ease of installation. See the files README and INSTALL for more information. ** Changed submode class specification format This change affects only people who define their own submode classes. The format for defining submode classes has changed; it now uses keyword arguments for clarity and has a few more possible arguments, including skeletons for submode region insertion. proofgeneral-4.3~pre130510/contrib/mmm/README000066400000000000000000000104601214562307500205360ustar00rootroot00000000000000 MMM Mode for Emacs ================== OVERVIEW MMM Mode is a minor mode for Emacs that allows Multiple Major Modes to coexist in one buffer. It is well-suited to editing: * Preprocessed code, such as server-side Perl or PHP embedded in HTML * Code generating code, such as HTML output by CGI scripts * Embedded code, such as Javascript in HTML * Literate programming: code interspersed with documentation, e.g. Noweb INSTALLATION MMM Mode has a standard GNU configure-driven installation. (See the file INSTALL for generic instructions, most of which don't apply.) To install in the standard locations, unpack the archive, `cd' to the mmm-mode-X.X.X directory created, and run these commands: ./configure make make install Alternately, since currently MMM Mode is written in pure Emacs Lisp, you could just copy all the *.el files in the distribution to a directory in your `load-path', and optionally byte-compile them manually (see the Emacs Manual). The configure installation also installs the MMM Mode info manual in your site info directory, so if you're installing manually, you might want to do that too. If you're installing from the CVS version, you won't have the configure script. If you have the automake/autoconf tools installed, you can run the script `autogen.sh' first, and then proceed as above. Otherwise, you'll have to copy the *.el files manually as described above. If you have more than one version of emacs installed and want to use MMM in a version other than /usr/bin/emacs, you must set the environment variable EMACS before running `configure', e.g. EMACS=/usr/bin/xemacs ./configure make make install If you want to use MMM in more than one version of emacs, you must either have separate site-lisp directories (such as Debian does), or load it from source every time; byte-compiled files are not portable between emacsen. CONFIGURATION Once MMM Mode is installed, it has to be configured correctly. This can be done in a site-start file or in user's initialization files; usually the latter is preferable, except possibly for autoloads. First the package needs to be loaded, with either (require 'mmm-mode) or instead, to save time during emacs startup, (require 'mmm-auto) Then you will probably want to set something like this: (setq mmm-global-mode 'maybe) (mmm-add-mode-ext-class 'html-mode "\\.php\\'" 'html-php) The first line tells MMM Mode to load itself whenever you open an appropriate file, and the second is an example which says to notice PHP regions in html-mode files having a `.php' extension. Both lines are necessary. You will, of course, want to change and duplicate the second line according to your needs. either of the first two parameters can be `nil', meaning not to consider that criterion. For example, if all your html files, regardless of extension, are Mason components, you will want something like: (mmm-add-mode-ext-class 'html-mode nil 'mason) whereas if all your files with a `.nw' extension, regardless of primary mode (some may be LaTeX, others HTML, say) are Noweb, you will prefer (mmm-add-mode-ext-class nil "\\.nw\\'" 'noweb) See the info file for more extensive documentation, and for other configuration options. DOCUMENTATION For further information, see (in order) the accompanying info file, the documentation strings of functions and variables, the comments in the source code, and the source code itself. UPDATES The latest version of MMM Mode should always be available from http://sourceforge.net/projects/mmm-mode BUG REPORTS Bug reports and suggestions can be submitted at , or through email to . CONTACT INFO MMM Mode is written and maintained by Michael Shulman, , and others; a list of some contributors can be found on the Sourceforge project. MAILING LIST To subscribe to the MMM Mode mailing list, visit . The mailing list receives announcements of new releases and provides a forum for discussion of bugs and features. Thanks for using MMM Mode! proofgeneral-4.3~pre130510/contrib/mmm/README.mmm-for-ProofGeneral000066400000000000000000000012341214562307500244670ustar00rootroot00000000000000The code in this directory is taken from http://mmm-mode.sourceforge.net/ This is version 0.4.8. Some minor changes have been made for Proof General to remove compilation warnings. Some files have not be included here. ================================================================= MMM Mode for Emacs MMM Mode is an emacs add-on package providing a minor mode that allows Multiple Major Modes to coexist in one buffer. It is particularly well-suited to editing embedded code or code that generates other code, such as Mason or Embperl server-side Perl code, or HTML output by CGI scripts. It is written and maintained by Michael Abraham Shulman . proofgeneral-4.3~pre130510/contrib/mmm/TODO000066400000000000000000000060741214562307500203540ustar00rootroot00000000000000Hey Emacs, this is a -*-text-*- file! To Do List for MMM Mode ======================= It would be nice to have a "split region" command which would insert a _back_ delimiter followed by a _front_ delimiter at point and split the current region into two regions. Say for PHP. Custom mode functions like `mason-mode'. Make Mason work a little better with PSGML. The fix I've found works, but it would be nifty if MMM could do it automatically. Maybe the custom-mode thing could set the variables, or a hook somewhere. Apostrophes mess up Perl parsing in XEmacs but not Emacs. I thought it was because XEmacs sets `font-lock-beginning-of-syntax-function' after MMM does, but changing that that didn't fix it. Improve re-parsing current region to use inclusion/offsets/etc. Support for: ASP, PHP DEB and/or RPM packages would be nice. The local-variables improvements can probably be used to set minor modes locally to submode regions. This could replace tmmofl, especially if we search for regions other than by regexps, say by syntax properties. Trap paragraph motion commands to stop at submode boundaries? On text insertion (in `after-change-functions'), do two things. First, if inside in a region, or after a hanging one, scan for its back and adjust if necessary. Second, scan both for complete regions and for hanging fronts. In the latter case, we may insert the back or start a hanging region; user option. Don't just scan the inserted text, but backwards, using `mmm-looking-back-at'. Remember to handle delimiter inclusion and offsets as best possible. It would be nice if C-j ended a Mason one-liner and began a new one on the next line. This is a rather Mason-specific thing, but other classes might have similar single-line regions. Add a new submode class argument, such as KEYMAP, or even ONE-LINE? Allow a submode class to specify its allowable "parent" submode classes. This could also be used to implement htp.p, by first scanning for the function calls as a major-mode submode region, then requiring that parent type for the HTML mode class. Nested submodes alternate highlight colors, say with `mmm-secondary-submode-face'. Ought %text in Mason to be a non-submode, since any Mason tags inside it will probably be /edited/ as Perl (being, say, code examples)? Only problem is it might confuse the programmer into thinking that code will get executed. Maybe use a different face. Could do that with another grouping class, say uneval-mason, that overrides the faces of mason and has :parent mason-text, and allow a mode to specify what about it changes depending on its parent, or a parent to specify changes to its children, or a group to specify changes to its members. If font-locking needs more help, try narrowing the region before fontifying, or even advising `parse-partial-sexp' and friends. At present, it seems good enough, though. It'd be nice if submode regions could preserve the indentation of the dominant major mode code around them. For example, Perl code embedded in HTML where the HTML is indented such as for a table. proofgeneral-4.3~pre130510/contrib/mmm/mmm-auto.el000066400000000000000000000151051214562307500217350ustar00rootroot00000000000000;;; mmm-auto.el --- loading and enabling MMM Mode automatically ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;; Version: $Id: mmm-auto.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains functions and hooks to load and enable MMM Mode ;; automatically. It sets up autoloads for the main MMM Mode functions ;; and interactive commands, and also sets up MMM Global Mode. ;;{{{ Comments on MMM Global Mode ;; This is a kludge borrowed from `global-font-lock-mode'. The idea ;; is the same: we have a function (here `mmm-mode-on-maybe') that we ;; want to be run whenever a major mode starts. Unfortunately, there ;; is no hook (like, say `major-mode-hook') that all major modes run ;; when they are finished. `post-command-hook', however, is run after ;; *every* command, so we do our work in there. (Actually, using ;; `post-command-hook' is even better than being run by major mode ;; functions, since it is run after all local variables and text are ;; loaded, which may not be true in certain cases for the other.) ;; In order to do this magic, we rely on the fact that there *is* a ;; hook that all major modes run when *beginning* their work. They ;; call `kill-all-local-variables' (unless they are broken), which in ;; turn runs `change-major-mode-hook'. So we add a function to *that* ;; hook which saves the current buffer and temporarily adds a function ;; to `post-command-hook' which processes that buffer. ;; Actually, in the interests of generality, what that function does ;; is run the hook `mmm-major-mode-hook'. Our desired function ;; `mmm-mode-on-maybe' is then added to that hook. This way, if the ;; user wants to run something else on every major mode, they can just ;; add it to `mmm-major-mode-hook' and take advantage of this hack. ;;}}} ;;; Code: (require 'cl) (require 'mmm-vars) ;;{{{ Autoload Submode Classes (defvar mmm-autoloaded-classes '((mason "mmm-mason" nil) (embedded-css "mmm-sample" nil) (html-js "mmm-sample" nil) (here-doc "mmm-sample" nil) (embperl "mmm-sample" nil) (eperl "mmm-sample" nil) (jsp "mmm-sample" nil) (file-variables "mmm-sample" nil) (rpm-sh "mmm-rpm" t) (rpm "mmm-rpm" nil) (cweb "mmm-cweb" nil) (sgml-dtd "mmm-sample" nil) (noweb "mmm-noweb" nil) (html-php "mmm-sample" nil) ) "Alist of submode classes autoloaded from files. Elements look like \(CLASS FILE PRIVATE) where CLASS is a submode class symbol, FILE is a string suitable for passing to `load', and PRIVATE is non-nil if the class is invisible to the user. Classes can be added to this list with `mmm-autoload-class'.") (defun mmm-autoload-class (class file &optional private) "Autoload submode class CLASS from file FILE. PRIVATE, if non-nil, means the class is user-invisible. In general, private classes need not be autoloaded, since they will usually be invoked by a public class in the same file." ;; Don't autoload already defined classes (unless (assq class mmm-classes-alist) (add-to-list 'mmm-autoloaded-classes (list class file private)))) ;;}}} ;;{{{ Autoload Functions ;; To shut up the byte compiler. (eval-and-compile (autoload 'mmm-mode-on "mmm-mode" "Turn on MMM Mode. See `mmm-mode'.") (autoload 'mmm-mode-off "mmm-mode" "Turn off MMM Mode. See `mmm-mode'.") (autoload 'mmm-update-font-lock-buffer "mmm-region") (autoload 'mmm-ensure-fboundp "mmm-utils") (autoload 'mmm-mode "mmm-mode" "Minor mode to allow multiple major modes in one buffer. Without ARG, toggle MMM Mode. With ARG, turn MMM Mode on iff ARG is positive and off otherwise." t)) ;; These may actually be used. (autoload 'mmm-ify-by-class "mmm-cmds" "" t) (autoload 'mmm-ify-by-regexp "mmm-cmds" "" t) (autoload 'mmm-ify-region "mmm-cmds" "" t) (autoload 'mmm-parse-buffer "mmm-cmds" "" t) (autoload 'mmm-parse-region "mmm-cmds" "" t) (autoload 'mmm-parse-block "mmm-cmds" "" t) (autoload 'mmm-clear-current-region "mmm-cmds" "" t) (autoload 'mmm-reparse-current-region "mmm-cmds" "" t) (autoload 'mmm-end-current-region "mmm-cmds" "" t) (autoload 'mmm-insertion-help "mmm-cmds" "" t) (autoload 'mmm-insert-region "mmm-cmds" "" t) ;;}}} ;;{{{ MMM Global Mode (defvar mmm-changed-buffers-list () "Buffers that need to be checked for running the major mode hook.") (defun mmm-major-mode-change () "Add this buffer to `mmm-changed-buffers-list' for checking. When the current command is over, MMM Mode will be turned on in this buffer depending on the value of `mmm-global-mode'. Actually, everything in `mmm-major-mode-hook' will be run." (and (boundp 'mmm-mode) mmm-mode (mmm-mode-off)) (add-to-list 'mmm-changed-buffers-list (current-buffer)) (add-hook 'post-command-hook 'mmm-check-changed-buffers)) (add-hook 'change-major-mode-hook 'mmm-major-mode-change) (defun mmm-check-changed-buffers () "Run major mode hook for the buffers in `mmm-changed-buffers-list'." (remove-hook 'post-command-hook 'mmm-check-changed-buffers) (dolist (buffer mmm-changed-buffers-list) (when (buffer-live-p buffer) (with-current-buffer buffer (mmm-run-major-mode-hook)))) (setq mmm-changed-buffers-list '())) (defun mmm-mode-on-maybe () "Conditionally turn on MMM Mode. Turn on MMM Mode if `global-mmm-mode' is non-nil and there are classes to apply, or always if `global-mmm-mode' is t." (cond ((eq mmm-global-mode t) (mmm-mode-on)) ((not mmm-global-mode)) ((mmm-get-all-classes nil) (mmm-mode-on))) (when mmm-mode (mmm-update-font-lock-buffer))) (add-hook 'mmm-major-mode-hook 'mmm-mode-on-maybe) (defalias 'mmm-add-find-file-hooks 'mmm-add-find-file-hook) (defun mmm-add-find-file-hook () "Equivalent to \(setq mmm-global-mode 'maybe). This function is deprecated and may be removed in future." (message "Warning: `mmm-add-find-file-hook' is deprecated.") (setq mmm-global-mode 'maybe)) ;;}}} (provide 'mmm-auto) ;;; mmm-auto.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-class.el000066400000000000000000000266621214562307500221040ustar00rootroot00000000000000;;; mmm-class.el --- MMM submode class variables and functions ;; Copyright (C) 2000, 2004 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;; Version: $Id: mmm-class.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains variable and function definitions for ;; manipulating and applying MMM submode classes. See `mmm-vars.el' ;; for variables that list classes. ;;; Code: (require 'cl) (require 'mmm-vars) (require 'mmm-region) ;;; CLASS SPECIFICATIONS ;;{{{ Get Class Specifications (defun mmm-get-class-spec (class) "Get the class specification for CLASS. CLASS can be either a symbol to look up in `mmm-classes-alist' or a class specifier itself." (cond ((symbolp class) ; A symbol must be looked up (or (cdr (assq class mmm-classes-alist)) (and (cadr (assq class mmm-autoloaded-classes)) (load (cadr (assq class mmm-autoloaded-classes))) (cdr (assq class mmm-classes-alist))) (signal 'mmm-invalid-submode-class (list class)))) ((listp class) ; A list must be a class spec class) (t (signal 'mmm-invalid-submode-class (list class))))) ;;}}} ;;{{{ Get and Set Class Parameters (defun mmm-get-class-parameter (class param) "Get the value of the parameter PARAM for CLASS, or nil if none." (cadr (member param (mmm-get-class-spec class)))) (defun mmm-set-class-parameter (class param value) "Set the value of the parameter PARAM for CLASS to VALUE. Creates a new parameter if one is not present." (let* ((spec (mmm-get-class-spec class)) (current (member param spec))) (if current (setcar (cdr current) value) (nconc spec (list param value))))) ;;}}} ;;{{{ Apply Classes (defun* mmm-apply-class (class &optional (start (point-min)) (stop (point-max)) face) "Apply the submode class CLASS from START to STOP in FACE. If FACE is nil, the face for CLASS is used, or the default face if none is specified by CLASS." ;; The "special" class t means do nothing. It is used to turn on ;; MMM Mode without applying any classes. (unless (eq class t) (apply #'mmm-ify :start start :stop stop (append (mmm-get-class-spec class) (list :face face))) (mmm-run-class-hook class) ;; Hack in case class hook sets mmm-buffer-mode-display-name etc. (mmm-set-mode-line))) (defun* mmm-apply-classes (classes &key (start (point-min)) (stop (point-max)) face) "Apply all submode classes in CLASSES, in order. All classes are applied regardless of any errors that may occur in other classes. If any errors occur, `mmm-apply-classes' exits with an error once all classes have been applied." (let (invalid-classes) (dolist (class classes) (condition-case err (mmm-apply-class class start stop face) (mmm-invalid-submode-class ;; Save the name of the invalid class, so we can report them ;; all together at the end. (add-to-list 'invalid-classes (second err))))) (when invalid-classes (signal 'mmm-invalid-submode-class invalid-classes)))) ;;}}} ;;{{{ Apply All Classes (defun* mmm-apply-all (&key (start (point-min)) (stop (point-max))) "MMM-ify from START to STOP by all submode classes. The classes come from mode/ext, `mmm-classes', `mmm-global-classes', and interactive history." (mmm-clear-overlays start stop 'strict) (mmm-apply-classes (mmm-get-all-classes t) :start start :stop stop) (mmm-update-submode-region) (mmm-refontify-maybe start stop)) ;;}}} ;;; BUFFER SCANNING ;;{{{ Scan for Regions (defun* mmm-ify (&rest all &key classes handler submode match-submode (start (point-min)) (stop (point-max)) front back save-matches (case-fold-search t) (beg-sticky (not (number-or-marker-p front))) (end-sticky (not (number-or-marker-p back))) include-front include-back (front-offset 0) (back-offset 0) (front-delim nil) (back-delim nil) (delimiter-mode mmm-delimiter-mode) front-face back-face front-verify back-verify front-form back-form creation-hook face match-face save-name match-name (front-match 0) (back-match 0) end-not-begin ;insert private &allow-other-keys ) "Create submode regions from START to STOP according to arguments. If CLASSES is supplied, it must be a list of valid CLASSes. Otherwise, the rest of the arguments are for an actual class being applied. See `mmm-classes-alist' for information on what they all mean." ;; Make sure we get the default values in the `all' list. (setq all (append all (list :start start :stop stop :beg-sticky beg-sticky :end-sticky end-sticky :front-offset front-offset :back-offset back-offset :front-delim front-delim :back-delim back-delim :front-match 0 :back-match 0 ))) (cond ;; If we have a class list, apply them all. (classes (mmm-apply-classes classes :start start :stop stop :face face)) ;; Otherwise, apply this class. ;; If we have a handler, call it. (handler (apply handler all)) ;; Otherwise, we search from START to STOP for submode regions, ;; continuining over errors, until we don't find any more. If FRONT ;; and BACK are number-or-markers, this should only execute once. (t (mmm-save-all (goto-char start) (loop for (beg end front-pos back-pos matched-front matched-back matched-submode matched-face matched-name invalid-resume ok-resume) = (apply #'mmm-match-region :start (point) all) while beg if end ; match-submode, if present, succeeded. do (condition-case nil (progn (mmm-make-region (or matched-submode submode) beg end :face (or matched-face face) :front front-pos :back back-pos :evaporation 'front :match-front matched-front :match-back matched-back :beg-sticky beg-sticky :end-sticky end-sticky :name matched-name :delimiter-mode delimiter-mode :front-face front-face :back-face back-face :creation-hook creation-hook ) (goto-char ok-resume)) ;; If our region is invalid, go back to the end of the ;; front match and continue on. (mmm-error (goto-char invalid-resume))) ;; If match-submode was unable to find a match, go back to ;; the end of the front match and continue on. else do (goto-char invalid-resume) ))))) ;;}}} ;;{{{ Match Regions (defun* mmm-match-region (&key start stop front back front-verify back-verify include-front include-back front-offset back-offset front-form back-form save-matches match-submode match-face front-match back-match end-not-begin save-name match-name &allow-other-keys) "Find the first valid region between point and STOP. Return \(BEG END FRONT-POS BACK-POS FRONT-FORM BACK-FORM SUBMODE FACE NAME INVALID-RESUME OK-RESUME) specifying the region. See `mmm-match-and-verify' for the valid values of FRONT and BACK \(markers, regexps, or functions). A nil value for END means that MATCH-SUBMODE failed to find a valid submode. INVALID-RESUME is the point at which the search should continue if the region is invalid, and OK-RESUME if the region is valid." (when (mmm-match-and-verify front start stop front-verify) (let ((beg (mmm-match->point include-front front-offset front-match)) (front-pos (with-no-warnings ; da: front-delim dyn scope? (if front-delim (mmm-match->point t front-delim front-match) nil))) (invalid-resume (match-end front-match)) (front-form (mmm-get-form front-form))) (let ((submode (if match-submode (condition-case nil (mmm-save-all (funcall match-submode front-form)) (mmm-no-matching-submode (return-from mmm-match-region (values beg nil nil nil nil nil nil nil nil invalid-resume nil)))) nil)) (name (cond ((functionp match-name) (mmm-save-all (funcall match-name front-form))) ((stringp match-name) (if save-name (mmm-format-matches match-name) match-name)))) (face (cond ((functionp match-face) (mmm-save-all (funcall match-face front-form))) (match-face (cdr (assoc front-form match-face)))))) (when (mmm-match-and-verify (if save-matches (mmm-format-matches back) back) beg stop back-verify) (let* ((end (mmm-match->point (not include-back) back-offset back-match)) (back-pos (with-no-warnings ; da: as above (if back-delim (mmm-match->point nil back-delim back-match) nil))) (back-form (mmm-get-form back-form)) (ok-resume (if end-not-begin (match-end back-match) end))) (values beg end front-pos back-pos front-form back-form submode face name invalid-resume ok-resume))))))) (defun mmm-match->point (beginp offset match) "Find a point of starting or stopping from the match data. If BEGINP, start at \(match-beginning MATCH), else \(match-end MATCH), and move OFFSET. Handles all values of OFFSET--see `mmm-classes-alist'." (save-excursion (goto-char (with-no-warnings ; da: front/back-match dyn binding? (if beginp (match-beginning front-match) (match-end back-match)))) (dolist (spec (if (listp offset) offset (list offset))) (if (numberp spec) (forward-char (or spec 0)) (funcall spec))) (point))) (defun mmm-match-and-verify (pos start stop &optional verify) "Find first match for POS between point and STOP satisfying VERIFY. Return non-nil if a match was found, and set match data. POS can be a number-or-marker, a regexp, or a function. If POS is a number-or-marker, it is used as-is. If it is a string, it is searched for as a regexp until VERIFY returns non-nil. If it is a function, it is called with argument STOP and must return non-nil iff a match is found, and set the match data. Note that VERIFY is ignored unless POS is a regexp." (cond ;; A marker can be used as-is, but only if it's in bounds. ((and (number-or-marker-p pos) (>= pos start) (<= pos stop)) (goto-char pos) (looking-at "")) ; Set the match data ;; Strings are searched for as regexps. ((stringp pos) (loop always (re-search-forward pos stop 'limit) until (or (not verify) (mmm-save-all (funcall verify))))) ;; Otherwise it must be a function. ((functionp pos) (funcall pos stop)))) ;;}}} ;;{{{ Get Delimiter Forms (defun mmm-get-form (form) "Return the delimiter form specified by FORM. If FORM is nil, call `mmm-default-get-form'. If FORM is a string, return it. If FORM is a function, call it. If FORM is a list, return its `car' \(usually in this case, FORM is a one-element list containing a function to be used as the delimiter form." (cond ((stringp form) form) ((not form) (mmm-default-get-form)) ((functionp form) (mmm-save-all (funcall form))) ((listp form) (car form)))) (defun mmm-default-get-form () (regexp-quote (match-string 0))) ;;}}} (provide 'mmm-class) ;;; mmm-class.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-cmds.el000066400000000000000000000361271214562307500217220ustar00rootroot00000000000000;;; mmm-cmds.el --- MMM Mode interactive commands and keymap ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;; Version: $Id: mmm-cmds.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains the interactive commands for MMM Mode. ;;; Code: (require 'font-lock) (require 'mmm-compat) (require 'mmm-vars) (require 'mmm-class) ;; APPLYING CLASSES ;;{{{ Applying Predefined Classes (defun mmm-ify-by-class (class) "Add submode regions according to an existing submode class." (interactive (list (intern (completing-read "Submode Class: " (remove-duplicates (mapcar #'(lambda (spec) (list (symbol-name (car spec)))) (append (remove-if #'(lambda (spec) (plist-get (cdr spec) :private)) mmm-classes-alist) (remove-if #'caddr mmm-autoloaded-classes))) :test #'equal) nil t)))) (unless (eq class (intern "")) (mmm-apply-class class) (mmm-add-to-history class) (mmm-update-font-lock-buffer))) ;;}}} ;;{{{ Applying by the Region (defun mmm-ify-region (submode front back) "Add a submode region for SUBMODE coinciding with current region." (interactive "aSubmode: \nr") (mmm-ify :submode submode :front front :back back) (setq front (mmm-make-marker front t nil) back (mmm-make-marker back nil nil)) (mmm-add-to-history `(:submode ,submode :front ,front :back ,back)) (mmm-enable-font-lock submode)) ;;}}} ;;{{{ Applying Simple Regexps (defun mmm-ify-by-regexp (submode front front-offset back back-offset save-matches) "Add SUBMODE regions to the buffer delimited by FRONT and BACK. With prefix argument, prompts for all additional keywords arguments. See `mmm-classes-alist'." (interactive "aSubmode: sFront Regexp: nOffset from Front Regexp: sBack Regexp: nOffset from Back Regexp: nNumber of matched substrings to save: ") (let ((args (mmm-save-keywords submode front back front-offset back-offset save-matches))) (apply #'mmm-ify args) (mmm-add-to-history args)) (mmm-enable-font-lock submode)) ;;}}} ;; EDITING WITH REGIONS ;;{{{ Re-parsing Areas (defun mmm-parse-buffer () "Re-apply all applicable submode classes to current buffer. Clears all current submode regions, reapplies all past interactive mmm-ification, and applies `mmm-classes' and mode-extension classes." (interactive) (message "MMM-ifying buffer...") (mmm-apply-all) (message "MMM-ifying buffer...done")) (defun mmm-parse-region (start stop) "Re-apply all applicable submode classes between START and STOP. Clears all current submode regions, reapplies all past interactive mmm-ification, and applies `mmm-classes' and mode-extension classes." (interactive "r") (message "MMM-ifying region...") (mmm-apply-all :start start :stop stop) (message "MMM-ifying region...done")) (defun mmm-parse-block (&optional lines) "Re-parse LINES lines before and after point \(default 1). Clears all current submode regions, reapplies all past interactive mmm-ification, and applies `mmm-classes' and mode-extension classes. This command is intended for use when you have just typed what should be the delimiters of a submode region and you want to create the region. However, you may want to look into the various types of delimiter auto-insertion that MMM Mode provides. See, for example, `mmm-insert-region'." (interactive "p") (message "MMM-ifying block...") (destructuring-bind (start stop) (mmm-get-block lines) (when (< start stop) (mmm-apply-all :start start :stop stop))) (message "MMM-ifying block...done")) (defun mmm-get-block (lines) (let ((inhibit-point-motion-hooks t)) (list (save-excursion (forward-line (- lines)) (beginning-of-line) (point)) (save-excursion (forward-line lines) (end-of-line) (point))))) ;;}}} ;;{{{ Reparse Current Region (defun mmm-reparse-current-region () "Clear and reparse the area of the current submode region. Use this command if a submode region's boundaries have become wrong." (interactive) (let ((ovl (mmm-overlay-at (point) 'all))) (when ovl (let ((beg (save-excursion (goto-char (mmm-front-start ovl)) (forward-line -1) (point))) (end (save-excursion (goto-char (mmm-back-end ovl)) (forward-line 1) (point)))) (mmm-parse-region beg end))))) ;;}}} ;;{{{ Clear Submode Regions ;; See also `mmm-clear-history' which is interactive. (defun mmm-clear-current-region () "Deletes the submode region point is currently in, if any." (interactive) (delete-overlay (mmm-overlay-at (point) 'all))) (defun mmm-clear-regions (start stop) "Deletes all submode regions from START to STOP." (interactive "r") (mmm-clear-overlays start stop)) (defun mmm-clear-all-regions () "Deletes all submode regions in the current buffer." (interactive) (mmm-clear-overlays)) ;;}}} ;;{{{ End Current Region (defun* mmm-end-current-region (&optional arg) "End current submode region. If ARG is nil, end it at the most appropriate place, usually its current back boundary. If ARG is non-nil, end it at point. If the current region is correctly bounded, the first does nothing, but the second deletes that delimiter as well. If the region's BACK property is a string, it is inserted as above and the overlay moved if necessary. If it is a function, it is called with two arguments--the overlay, and \(if ARG 'middle t)--and must do the entire job of this function." (interactive "P") (let ((ovl (mmm-overlay-at))) (when ovl (combine-after-change-calls (save-match-data (save-excursion (when (mmm-match-back ovl) (if arg (replace-match "") (return-from mmm-end-current-region))))) (let ((back (overlay-get ovl 'back))) (cond ((stringp back) (save-excursion (unless arg (goto-char (overlay-end ovl))) (save-excursion (insert back)) (move-overlay ovl (overlay-start ovl) (point)))) ((functionp back) (funcall back ovl (if arg 'middle t)))))) (mmm-refontify-maybe (save-excursion (forward-line -1) (point)) (save-excursion (forward-line 1) (point)))))) ;;}}} ;;{{{ Narrow to Region (defun mmm-narrow-to-submode-region (&optional pos) "Narrow to the submode region at point." (interactive) ;; Probably don't use mmm-current-overlay here, because this is ;; sometimes called from inside messy functions. (let ((ovl (mmm-overlay-at pos))) (when ovl (narrow-to-region (overlay-start ovl) (overlay-end ovl))))) ;; The inverse command is `widen', usually on `C-x n w' ;;}}} ;; INSERTING REGIONS ;;{{{ Insert regions by keystroke ;; This is the "default" binding in the MMM Mode keymap. Keys defined ;; by classes should be control keys, to avoid conflicts with MMM ;; commands. (defun mmm-insert-region (arg) "Insert a submode region based on last character in invoking keys. Keystrokes after `mmm-mode-prefix-key' which are not bound to an MMM Mode command \(see `mmm-command-modifiers') are passed on to this function. If they have the modifiers `mmm-insert-modifiers', then they are looked up, sans those modifiers, in all current submode classes to find an insert skeleton. For example, in Mason, `p' \(with appropriate prefix and modifiers) will insert a <%perl>... region." (interactive "P") (let* ((seq (this-command-keys)) (event (aref seq (1- (length seq)))) (mods (event-modifiers event)) (key (mmm-event-key event))) (if (subsetp mmm-insert-modifiers mods) (mmm-insert-by-key (append (set-difference mods mmm-insert-modifiers) key) arg)))) (defun mmm-insert-by-key (key &optional arg) "Insert a submode region based on event KEY. Inspects all the classes of the current buffer to find a matching :insert key sequence. See `mmm-classes-alist'. ARG, if present, is passed on to `skeleton-proxy-new' to control wrapping. KEY must be a list \(MODIFIERS... . BASIC-KEY) where MODIFIERS are symbols such as shift, control, etc. and BASIC-KEY is a character code or a symbol such as tab, return, etc. Note that if there are no MODIFIERS, the dotted list becomes simply BASIC-KEY." (multiple-value-bind (class skel str) (mmm-get-insertion-spec key) (when skel (let ((after-change-functions nil) (old-undo buffer-undo-list) undo ;; da: Proof General patch for compatibility with holes.el, ;; bind this variable to prevent inserting holes here. mmm-inside-insert-by-key) ;; XEmacs' skeleton doesn't manage positions by itself, so we ;; have to do it. (if mmm-xemacs (setq skeleton-positions nil)) (skeleton-proxy-new skel str arg) (destructuring-bind (back end beg front) skeleton-positions ;; TODO: Find a way to trap invalid-parent signals from ;; make-region and undo the skeleton insertion. (let ((match-submode (plist-get class :match-submode)) (match-face (plist-get class :match-face)) (match-name (plist-get class :match-name)) (front-form (regexp-quote (buffer-substring front beg))) (back-form (regexp-quote (buffer-substring end back))) submode face name) (setq submode (mmm-modename->function (if match-submode (mmm-save-all (funcall match-submode front-form)) (plist-get class :submode)))) (setq face (cond ((functionp match-face) (mmm-save-all (funcall match-face front-form))) (match-face (cdr (assoc front-form match-face))) (t (plist-get class :face)))) (setq name (cond ((plist-get class :skel-name) ;; Optimize the name to the user-supplied str ;; if we are so instructed. str) ;; Call it if it is a function ((functionp match-name) (mmm-save-all (funcall match-name front-form))) ;; Now we know it's a string, does it need to ;; be formatted? ((plist-get class :save-name) ;; Yes. Haven't done a match before, so ;; match the front regexp against the given ;; form to format the string (string-match (plist-get class :front) front-form) (mmm-format-matches match-name front-form)) (t ;; No, just use it as-is match-name))) (mmm-make-region submode beg end :face face :name name :front front :back back :match-front front-form :match-back back-form :evaporation 'front ;;; :beg-sticky (plist-get class :beg-sticky) ;;; :end-sticky (plist-get class :end-sticky) :beg-sticky t :end-sticky t :creation-hook (plist-get class :creation-hook)) (mmm-enable-font-lock submode))) ;; Now get rid of intermediate undo boundaries, so that the entire ;; insertion can be undone as one action. This should really be ;; skeleton's job, but it doesn't do it. (setq undo buffer-undo-list) (while (not (eq (cdr undo) old-undo)) (when (eq (cadr undo) nil) (setcdr undo (cddr undo))) (setq undo (cdr undo))))))) (defun mmm-get-insertion-spec (key &optional classlist) "Get the insertion info for KEY from all classes in CLASSLIST. Return \(CLASS SKEL STR) where CLASS is the class spec a match was found in, SKEL is the skeleton to insert, and STR is the argument. CLASSLIST defaults to the return value of `mmm-get-all-classes', including global classes." (loop for classname in (or classlist (mmm-get-all-classes t)) for class = (mmm-get-class-spec classname) for inserts = (plist-get class :insert) for skel = (cddr (assoc key inserts)) with str ;; If SKEL is a dotted pair, it means call another key's ;; insertion spec with an argument. unless (consp (cdr skel)) do (setq str (cdr skel) skel (cddr (assoc (car skel) inserts))) if skel return (list class skel str) ;; If we have a group class, recurse. if (plist-get class :classes) if (mmm-get-insertion-spec key it) return it else return nil)) ;;}}} ;;{{{ Help on Insertion (defun mmm-insertion-help () "Display help on currently available MMM insertion commands." (interactive) (with-output-to-temp-buffer "*Help*" (princ "Available MMM Mode Insertion Commands:\n") (princ "Key Inserts\n") (princ "--- -------\n\n") (mapcar #'mmm-display-insertion-key (mmm-get-all-insertion-keys)))) (defun mmm-display-insertion-key (spec) "Print an insertion binding to standard output. SPEC should be \(KEY NAME ...) where KEY is an insertion key and NAME is a symbol naming the insertion." (let* ((str (make-string 16 ?\ )) ;; This gets us a dotted list, because of the way insertion ;; keys are specified. (key (append mmm-insert-modifiers (car spec))) (lastkey (nthcdr (max (1- (safe-length key)) 0) key))) ;; Now we make it a true list (if (consp key) (setcdr lastkey (list (cdr lastkey))) (setq key (list key))) ;; Get the spacing right (store-substring str 0 (key-description (apply #'vector (append mmm-mode-prefix-key (list key))))) (princ str) ;; Now print the binding symbol (princ (cadr spec)) (princ "\n"))) (defun mmm-get-all-insertion-keys (&optional classlist) "Return an alist of all currently available insertion keys. Elements look like \(KEY NAME ...) where KEY is an insertion key and NAME is a symbol naming the insertion." (remove-duplicates (loop for classname in (or classlist (mmm-get-all-classes t)) for class = (mmm-get-class-spec classname) append (plist-get class :insert) into keys ;; If we have a group class, recurse. if (plist-get class :classes) do (setq keys (append keys (mmm-get-all-insertion-keys it))) finally return keys) :test #'equal :key #'(lambda (x) (cons (car x) (cadr x))) :from-end t)) ;;}}} ;;{{{ Auto Insertion (copied from interactive session);-COM- ;-COM- ;-COM-;; Don't use `mmm-ify-region' of course. And rather than having ;-COM-;; classes define their own functions, we should have them pass a ;-COM-;; skeleton as an attribute. Then our insert function can turn off ;-COM-;; after-change hooks and add the submode region afterward. ;-COM- ;-COM-(define-skeleton mmm-see-inline ;-COM- "" nil ;-COM- -1 @ " " _ " " @ "%>" ;-COM- '(apply #'mmm-ify-region 'cperl-mode (reverse skeleton-positions))) ;-COM- ;-COM-(define-skeleton mmm-see-other ;-COM- "" nil ;-COM- @ ";\n" _ "\n" @ "<%/" str ">" ;-COM- '(apply #'mmm-ify-region 'cperl-mode (reverse skeleton-positions))) ;-COM- ;-COM-(make-local-hook 'after-change-functions) ;-COM-(add-hook 'after-change-functions 'mmm-detect t) ;-COM- ;-COM-(defun mmm-detect (beg end length) ;-COM- (when (mmm-looking-back-at "<% ") ;-COM- (mmm-see-inline)) ;-COM- (when (mmm-looking-back-at "<%\\(\\w+\\)>") ;-COM- (mmm-see-other (match-string 1)))) ;-COM- ;;}}} (provide 'mmm-cmds) ;;; mmm-cmds.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-compat.el000066400000000000000000000142641214562307500222550ustar00rootroot00000000000000;;; mmm-compat.el --- MMM Hacks for compatibility with other Emacsen ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;; Version: $Id: mmm-compat.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file provides a number of hacks that are necessary for MMM ;; Mode to function in different Emacsen. MMM Mode is designed for ;; FSF Emacs 20 and 21, but these hacks usually enable it to work ;; almost perfectly in Emacs 19 and XEmacs 20 or 21. ;;; Code: (require 'cl) ;;{{{ Emacsen Detection (defvar mmm-xemacs (featurep 'xemacs) "Whether we are running XEmacs.") ;;}}} ;;{{{ Keywords (Emacs 19) ;; Emacs 19 doesn't automatically set keyword variables to themselves. ;; We shouldn't have to do any more than these, since CL automatically ;; defines all keywords used for function arguments. (defvar mmm-keywords-used '(:group :regexp :region :function :insert :classes :private) "List of extra keywords used by MMM Mode.") (dolist (keyword mmm-keywords-used) (set keyword keyword)) ;;}}} ;;{{{ Customization (Emacs 19) (condition-case () (require 'custom) (error nil)) (unless (and (featurep 'custom) (fboundp 'custom-declare-variable)) (defmacro defgroup (&rest args) nil) ;; da: backquote syntax updated, so not Emacs <19.29 compatible (defmacro defface (var values doc &rest args) `(make-face (quote ,var))) (defmacro defcustom (var value doc &rest args) `(defvar ,var ,value ,doc))) ;;}}} ;;{{{ Regexp-Opt (Emacs 19) (condition-case () (require 'regexp-opt) (error nil)) (unless (and (featurep 'regexp-opt) (fboundp 'regexp-opt)) ;; No regexp-opt; create one (defun regexp-opt (strings &optional paren) (concat (if paren "\\(" "") (mapconcat 'regexp-quote strings "\\|") (if paren "\\)" "")))) ;;}}} ;;{{{ Regexp-Opt (XEmacs) (defmacro mmm-regexp-opt (strings paren) "Act like FSF Emacs' `regexp-opt', whichever Emacs we're in. XEmacs' `regexp-opt' requires an extra parameter to do grouping." (if (featurep 'xemacs) `(regexp-opt ,strings ,paren t) `(regexp-opt ,strings ,paren))) ;;}}} ;;{{{ Overlays (XEmacs) ;; The main thing we use from FSF Emacs that XEmacs doesn't support ;; are overlays. XEmacs uses extents instead, but comes with a package ;; to emulate overlays. (when mmm-xemacs ;; This does almost everything we need. (require 'overlay)) ;; We also use a couple "special" overlay properties which have ;; different names for XEmacs extents. (defvar mmm-evaporate-property (if (featurep 'xemacs) 'detachable 'evaporate) "The name of the overlay property controlling evaporation.") ;; We don't use this any more, since its behavior is different in FSF ;; and XEmacs: in the one it replaces the buffer's local map, but in ;; the other it gets stacked on top of it. Instead we just set the ;; buffer's local map temporarily. ;;;(defvar mmm-keymap-property ;;; (if (featurep 'xemacs) 'keymap 'local-map) ;;; "The name of the overlay property controlling keymaps.") ;;}}} ;;{{{ Keymaps and Events (XEmacs) ;; In XEmacs, keymaps are a primitive type, while in FSF Emacs, they ;; are a list whose car is the symbol `keymap'. Among other things, ;; this means that they handle default bindings differently. (defmacro mmm-set-keymap-default (keymap binding) (if (featurep 'xemacs) `(set-keymap-default-binding ,keymap ,binding) `(define-key ,keymap [t] ,binding))) ;; In XEmacs, events are a primitive type, while in FSF Emacs, they ;; are represented by characters or vectors. We treat them as vectors. ;; We can use `event-modifiers' in both Emacsen to extract the ;; modifiers, but the function to extract the basic key is different. (defmacro mmm-event-key (event) (if (featurep 'xemacs) `(event-key ,event) `(event-basic-type ,event))) ;;}}} ;;{{{ Skeleton (XEmacs) ;; XEmacs' `skeleton' package doesn't provide `@' to record positions. (defvar skeleton-positions ()) (defun mmm-fixup-skeleton () "Add `@' to `skeleton-further-elements' if XEmacs and not there. This makes `@' in skeletons act approximately like it does in FSF." (and (featurep 'xemacs) (defvar skeleton-further-elements ()) (not (assoc '@ skeleton-further-elements)) (add-to-list 'skeleton-further-elements '(@ ''(push (point) skeleton-positions))))) ;;}}} ;;{{{ Make Temp Buffers (XEmacs) (defmacro mmm-make-temp-buffer (buffer name) "Return a buffer called NAME including the text of BUFFER. This text should not be modified." (if (fboundp 'make-indirect-buffer) `(make-indirect-buffer ,buffer ,name) `(save-excursion (set-buffer (get-buffer-create ,name)) (insert-buffer ,buffer) (current-buffer)))) ;;}}} ;;{{{ Font Lock Available (Emacs w/o X) (defvar mmm-font-lock-available-p (or window-system mmm-xemacs) "Whether font-locking is available. Emacs 19 and 20 only provide font-lock with a window system in use.") ;;}}} ;;{{{ Font Lock Defaults (XEmacs) (defmacro mmm-set-font-lock-defaults () "Set font-lock defaults without trying to turn font-lock on. In XEmacs, `font-lock-set-defaults' calls `font-lock-set-defaults-1' to do the real work but then `turn-on-font-lock', which in turn calls `font-lock-mode', which unsets the defaults if running in a hidden buffer \(name begins with a space). So in XEmacs, we just call `font-lock-set-defaults-1' directly." (if mmm-xemacs `(font-lock-set-defaults-1) `(font-lock-set-defaults))) ;;}}} (provide 'mmm-compat) ;;; mmm-compat.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-cweb.el000066400000000000000000000053271214562307500217120ustar00rootroot00000000000000;;; mmm-cweb.el --- MMM submode class for CWeb programs ;; Copyright (C) 2001 by Alan Shutko ;; Author: Alan Shutko ;; Version: $Id: mmm-cweb.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains the definition of an MMM Mode submode class for ;; editing CWeb programs. ;;; Code: (require 'mmm-compat) (require 'mmm-vars) (require 'mmm-auto) (defvar mmm-cweb-section-tags '("@ " "@*")) (defvar mmm-cweb-section-regexp (concat "^" (mmm-regexp-opt mmm-cweb-section-tags t))) (defvar mmm-cweb-c-part-tags '("@c" "@>=" "@>+=" "@p")) (defvar mmm-cweb-c-part-regexp (concat (mmm-regexp-opt mmm-cweb-c-part-tags t))) (defun mmm-cweb-in-limbo (pos) "Check to see if POS is in limbo, ie before any cweb sections." (save-match-data (save-excursion (goto-char pos) (not (re-search-backward mmm-cweb-section-regexp nil t))))) (defun mmm-cweb-verify-brief-c () "Verify function for cweb-brief-c class. Checks whether the match is in limbo." (not (mmm-cweb-in-limbo (match-beginning 0)))) (mmm-add-group 'cweb `( (cweb-c-part :submode c-mode :front ,mmm-cweb-c-part-regexp :back ,mmm-cweb-section-regexp) (cweb-label :submode tex-mode :front "@<" :back "@>" :face mmm-comment-submode-face :insert ((?l cweb-label nil @ "@<" @ "@>"))) (cweb-brief-c :submode c-mode :front "[^\\|]\\(|\\)[^|]" :front-match 1 :front-verify mmm-cweb-verify-brief-c ; :front-offset -1 :back "[^\\|]\\(|\\)" :back-match 1 ; :back-offset 1 :end-not-begin t :insert ((?| cweb-c-in-tex nil "|" @ "|"))) (cweb-comment :submode tex-mode :front "/[*]" :back "[*]/" :face mmm-comment-submode-face) )) ;; (add-to-list 'mmm-mode-ext-classes-alist ;; '(plain-tex-mode "\\.w\\'" cweb)) ;; (add-to-list 'mmm-mode-ext-classes-alist ;; '(latex-mode "\\.w\\'" cweb)) ;; (add-to-list 'auto-mode-alist '("\\.w\\'" . tex-mode)) (provide 'mmm-cweb) ;;; mmm-cweb.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-mason.el000066400000000000000000000121101214562307500220730ustar00rootroot00000000000000;;; mmm-mason.el --- MMM submode class for Mason components ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;; Version: $Id: mmm-mason.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains the definition of an MMM Mode submode class for ;; editing Mason components. See the file README.Mason for more ;; details. ;;; Code: (require 'mmm-compat) (require 'mmm-vars) (require 'mmm-auto) ;;{{{ Perl Tags (defvar mmm-mason-perl-tags '("perl" "init" "cleanup" "once" "filter" "shared" "perl_init" "perl_cleanup" "perl_once" "perl_filter")) (defvar mmm-mason-pseudo-perl-tags '("args" "perl_args" "attr" "flags")) (defvar mmm-mason-non-perl-tags '("doc" "perl_doc" "text" "perl_text" "def" "perl_def" "method")) (defvar mmm-mason-perl-tags-regexp (concat "<%" (mmm-regexp-opt mmm-mason-perl-tags t) ">") "Matches tags beginning Mason sections containing Perl code. Saves the name of the tag matched.") (defvar mmm-mason-pseudo-perl-tags-regexp (concat "<%" (mmm-regexp-opt mmm-mason-pseudo-perl-tags t) ">") "Match tags beginning Mason sections that look like Perl but aren't. Saves the name of the tag matched.") (defvar mmm-mason-tag-names-regexp (regexp-opt (append mmm-mason-perl-tags mmm-mason-non-perl-tags) t) "Matches any Mason tag name after the \"<%\". Used to verify that a \"<%\" sequence starts an inline section.") (defun mmm-mason-verify-inline () (not (looking-at mmm-mason-tag-names-regexp))) ;;}}} ;;{{{ Add Classes (mmm-add-group 'mason `((mason-text :submode nil :front "<%text>" :back "" :insert ((?t mason-<%text> nil @ "<%text>" @ "\n" _ "\n" @ "" @))) (mason-doc :submode text-mode :face mmm-comment-submode-face :front "<%doc>" :back "" :face nil :insert ((?d mason-<%doc> nil @ "<%doc>" @ "\n" _ "\n" @ "" @))) (mason-perl :submode perl :match-face (("<%perl>" . mmm-code-submode-face) ("<%init>" . mmm-init-submode-face) ("<%cleanup>" . mmm-cleanup-submode-face) ("<%once>" . mmm-init-submode-face) ("<%filter>" . mmm-special-submode-face) ("<%shared>" . mmm-init-submode-face)) :front ,mmm-mason-perl-tags-regexp :back "" :save-matches 1 :match-name "~1" :save-name 1 :insert ((?, mason-<%TAG> "Perl section: " @ "<%" str ">" @ ";\n" _ "\n" @ "" @) (?< mason-<%TAG> ?, . nil) (?p mason-<%perl> ?, . "perl") (?i mason-<%init> ?, . "init") (?c mason-<%cleanup> ?, . "cleanup") (?o mason-<%once> ?, . "once") (?l mason-<%filter> ?, . "filter") (?s mason-<%shared> ?, . "shared"))) (mason-pseudo-perl :submode perl :face mmm-declaration-submode-face :front ,mmm-mason-pseudo-perl-tags-regexp :back "" :save-matches 1 :insert ((?. mason-pseudo-<%TAG> "Pseudo-perl section: " @ "<%" str ">" @ "\n" _ "\n" @ "" @) (?> mason-pseudo-<%TAG> ?, . nil) (?a mason-<%args> ?. . "args") (?f mason-<%flags> ?. . "flags") (?r mason-<%attr> ?. . "attr"))) (mason-inline :submode perl :face mmm-output-submode-face :front "<%" :front-verify mmm-mason-verify-inline :back "%>" :insert ((?% mason-<%-%> nil @ "<%" @ " " _ " " @ "%>" @) (?5 mason-<%-%> ?% . nil))) (mason-call :submode perl :face mmm-special-submode-face :front "<&" :back "&>" :insert ((?& mason-<&-&> nil @ "<&" @ " " _ " " @ "&>" @) (?7 mason-<&-&> ?% . nil))) (mason-one-line-comment :submode text-mode :face mmm-comment-submode-face :front "^%#" :back "\n" :insert ((?# mason-%-comment nil (mmm-mason-start-line) @ "%" @ "# " _ @ '(mmm-mason-end-line) "\n" @) (?3 mason-%-comment ?# . nil))) (mason-one-line :submode perl :face mmm-code-submode-face :front "^%" :back "\n" :insert ((return mason-%-line nil (mmm-mason-start-line) @ "%" @ " " _ @ '(mmm-mason-end-line) "\n" @))))) ;;}}} ;;{{{ One-line Sections (defun mmm-mason-start-line () (if (bolp) "" "\n")) (defun mmm-mason-end-line () (if (eolp) (delete-char 1))) ;;}}} ;;{{{ Set Mode Line (defun mmm-mason-set-mode-line () (setq mmm-buffer-mode-display-name "Mason")) (add-hook 'mmm-mason-class-hook 'mmm-mason-set-mode-line) ;;}}} (provide 'mmm-mason) ;;; mmm-mason.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-mode.el000066400000000000000000000252201214562307500217100ustar00rootroot00000000000000;;; mmm-mode.el --- Allow Multiple Major Modes in a buffer ;; Copyright (C) 1999, 2004 by Michael Abraham Shulman ;; Emacs Lisp Archive Entry ;; Package: mmm-mode ;; Author: Michael Abraham Shulman ;; Keywords: convenience, faces, languages, tools ;; Version: 0.4.8 ;; Revision: $Id: mmm-mode.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, but ;; WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;;; MMM Mode is a minor mode that allows multiple major modes to ;;; coexist in a single buffer. Refer to the documentation of the ;;; function `mmm-mode' for more detailed information. This file ;;; contains mode on/off functions and the mode keymap, but mostly ;;; just loads all the subsidiary files. ;;{{{ Parameter Naming ;;; Since version 0.3.7, I've tried to use a uniform scheme for naming ;;; parameters. Here's a brief summary. ;;; BEG and END refer to the beginning and end of a region. ;;; FRONT and BACK refer to the respective delimiters of a region. ;;; FRONT- and BACK-OFFSET are the offsets from delimiter matches. ;;; FRONT-BEG through BACK-END are the endings of the delimiters. ;;; START and STOP bound actions, like searching, fontification, etc. ;;}}} ;;{{{ CL and Parameters ;;; Keyword parameters can be nice because it makes it easier to see ;;; what's getting passed as what. But I try not to use them in user ;;; functions, because CL doesn't make good documentation strings. ;;; Similarly, any hook or callback function can't take keywords, ;;; since Emacs as a whole doesn't use them. And for small parameter ;;; lists, they are overkill. So I use them only for a large number of ;;; optional parameters, such as `mmm-make-region'. ;;; An exception is the various submode class application functions, ;;; which all take all their arguments as keywords, for consistency ;;; and so the classes alist looks nice. ;;; When using keyword arguments, defaults should *always* be supplied ;;; in all arglists. (This pertains mostly to :start and :stop ;;; arguments, usually defaulting to (point-min) and (point-max) ;;; respectively.) `mmm-save-keywords' should only be used for lists ;;; with more than four arguments, such as in `mmm-ify-by-regexp'. ;;; In general, while I have no qualms about using things from CL like ;;; `mapl', `loop' and `destructuring-bind', I try not to use `defun*' ;;; more than I have to. For one, it sometimes makes bad documentation ;;; strings. Furthermore, to a `defun'ned function, a nil argument is ;;; the same as no argument, so it will use its (manual) default, but ;;; to a `defun*'ned function, a nil argument *is* the argument, so ;;; any default specified in the arglist will be ignored. Confusion of ;;; this type should be avoided when at all possible. ;;}}} ;;; Code: (require 'cl) ;; If we don't load font-lock now, but it is loaded later, the ;; necessary mmm-font-lock-* properties may not be there. (require 'font-lock) (require 'mmm-compat) (require 'mmm-utils) (require 'mmm-vars) (require 'mmm-auto) (require 'mmm-region) (require 'mmm-class) ;; This file is set up to autoload by `mmm-auto.el'. ;; (require 'mmm-cmds) (require 'mmm-univ) ;;{{{ Toggle Function (defun mmm-mode (&optional arg) "Minor mode to allow multiple major modes in one buffer. Without ARG, toggle MMM Mode. With ARG, turn MMM Mode on iff ARG is positive and off otherwise. Commands Available: \\ \\{mmm-mode-map} BASIC CONCEPTS The idea of MMM Mode is to allow multiple major modes to coexist in the same buffer. There is one \"primary\" major mode that controls most of the buffer, and a number of \"submodes\" that each hold sway over certain regions. The submode regions are usually highlighted by a background color for ease of recognition. While the point is in a submode region, the following changes \(are supposed to) occur: 1. The local keymap is that of the submode. 2. The mode line changes to show what submode region is active. 3. The major mode menu and mouse popup menu are that of the submode. 4. Some local variables of the submode shadow the default mode's. 5. The syntax table and indentation are those of the submode. 6. Font-lock fontifies correctly for the submode. For further information, including installation and configuration instructions, see the Info file mmm.info which is included with the distribution of MMM Mode. Many of MMM's configuration variables are available through M-x customize under Programming | Tools | Mmm." (interactive "P") (if (if arg (> (prefix-numeric-value arg) 0) (not mmm-mode)) (mmm-mode-on) (mmm-mode-off))) (add-to-list 'minor-mode-alist (list 'mmm-mode mmm-mode-string)) ;;}}} ;;{{{ Mode On (defun mmm-mode-on () "Turn on MMM Mode. See `mmm-mode'." (interactive) ;; This function is called from mode hooks, so we need to make sure ;; we're not in a temporary buffer. We don't need to worry about ;; recursively ending up in ourself, however, since by that time the ;; variable `mmm-mode' will already be set. (mmm-valid-buffer (unless mmm-mode (setq mmm-primary-mode major-mode) (when (fboundp 'c-make-styles-buffer-local) (c-make-styles-buffer-local t)) (mmm-update-mode-info major-mode) (setq mmm-region-saved-locals-for-dominant (list* (list 'font-lock-cache-state nil) (list 'font-lock-cache-position (make-marker)) (copy-tree (cdr (assq major-mode mmm-region-saved-locals-defaults))))) ;; Without the next line, the (make-marker) above gets replaced ;; with the starting value of nil, and all comes to naught. (mmm-set-local-variables major-mode) (mmm-add-hooks) (mmm-fixup-skeleton) (make-local-variable 'font-lock-fontify-region-function) ;(make-local-variable 'font-lock-beginning-of-syntax-function) (make-local-variable 'syntax-beginning-function) (setq font-lock-fontify-region-function 'mmm-fontify-region ; font-lock-beginning-of-syntax-function 'mmm-beginning-of-syntax syntax-begin-function 'mmm-beginning-of-syntax) (setq mmm-mode t) (condition-case err (mmm-apply-all) (mmm-error ;; Complain, but don't die, since we want files to go ahead ;; and be opened anyway, and the mode to go ahead and be ;; turned on. Should we delete all previously made submode ;; regions when we find an invalid one? (message "%s" (error-message-string err)))) (run-hooks 'mmm-mode-hook) (mmm-run-major-hook)))) ;;}}} ;;{{{ Mode Off (defun mmm-mode-off () "Turn off MMM Mode. See `mmm-mode'." (interactive) (when mmm-mode (mmm-remove-hooks) (mmm-clear-overlays) (mmm-clear-history) (mmm-clear-mode-ext-classes) (mmm-clear-local-variables) (mmm-update-submode-region) (setq font-lock-fontify-region-function (get mmm-primary-mode 'mmm-fontify-region-function) ; font-lock-beginning-of-syntax-function syntax-begin-function (get mmm-primary-mode 'mmm-beginning-of-syntax-function)) (mmm-update-font-lock-buffer) (mmm-refontify-maybe) (setq mmm-mode nil) ;; Restore the mode line (setq mmm-primary-mode-display-name nil mmm-buffer-mode-display-name nil) (mmm-set-mode-line))) ;;}}} ;;{{{ Mode Keymap (defvar mmm-mode-map (make-sparse-keymap) "Keymap for MMM Minor Mode.") (defvar mmm-mode-prefix-map (make-sparse-keymap) "Keymap for MMM Minor Mode after `mmm-mode-prefix-key'.") (defvar mmm-mode-menu-map (make-sparse-keymap "MMM") "Keymap for MMM Minor Mode menu.") (defun mmm-define-key (key binding &optional keymap) (define-key (or keymap mmm-mode-prefix-map) (vector (append mmm-command-modifiers (list key))) binding)) (when mmm-use-old-command-keys (mmm-use-old-command-keys)) (mmm-define-key ?c 'mmm-ify-by-class) (mmm-define-key ?x 'mmm-ify-by-regexp) (mmm-define-key ?r 'mmm-ify-region) (mmm-define-key ?b 'mmm-parse-buffer) (mmm-define-key ?g 'mmm-parse-region) (mmm-define-key ?% 'mmm-parse-block) (mmm-define-key ?5 'mmm-parse-block) (mmm-define-key ?k 'mmm-clear-current-region) (mmm-define-key ?\ 'mmm-reparse-current-region) (mmm-define-key ?e 'mmm-end-current-region) (mmm-define-key ?z 'mmm-narrow-to-submode-region) ;; This one is exact, since C-h is (usually) already used for help. (define-key mmm-mode-prefix-map [?h] 'mmm-insertion-help) ;; Default bindings to do insertion (dynamic) (mmm-set-keymap-default mmm-mode-prefix-map 'mmm-insert-region) ;; Set up the prefix help command, since otherwise the default binding ;; overrides it. (define-key mmm-mode-prefix-map (vector help-char) prefix-help-command) ;; And put it all onto the prefix key (define-key mmm-mode-map mmm-mode-prefix-key mmm-mode-prefix-map) ;; Order matters for the menu bar. (define-key mmm-mode-menu-map [off] '("MMM Mode Off" . mmm-mode-off)) (define-key mmm-mode-menu-map [sep0] '(menu-item "----")) (define-key mmm-mode-menu-map [clhist] '("Clear History" . mmm-clear-history)) (define-key mmm-mode-menu-map [end] '("End Current" . mmm-end-current-region)) (define-key mmm-mode-menu-map [clear] '("Clear Current" . mmm-clear-current-region)) (define-key mmm-mode-menu-map [reparse] '("Reparse Current" . mmm-reparse-current-region)) (define-key mmm-mode-menu-map [sep10] '(menu-item "----")) (define-key mmm-mode-menu-map [ins-help] '("List Insertion Keys" . mmm-insertion-help)) (define-key mmm-mode-menu-map [sep20] '(menu-item "----")) (define-key mmm-mode-menu-map [region] '(menu-item "MMM-ify Region" mmm-ify-region :enable mark-active)) (define-key mmm-mode-menu-map [regexp] '("MMM-ify by Regexp" . mmm-ify-by-regexp)) (define-key mmm-mode-menu-map [class] '("Apply Submode Class" . mmm-ify-by-class)) (define-key mmm-mode-menu-map [sep30] '(menu-item "----")) (define-key mmm-mode-menu-map [parse-region] '(menu-item "Parse Region" mmm-parse-region :enable mark-active)) (define-key mmm-mode-menu-map [parse-buffer] '("Parse Buffer" . mmm-parse-buffer)) (define-key mmm-mode-menu-map [parse-block] '("Parse Block" . mmm-parse-block)) (define-key mmm-mode-map [menu-bar mmm] (cons "MMM" mmm-mode-menu-map)) (add-to-list 'minor-mode-map-alist (cons 'mmm-mode mmm-mode-map)) ;;}}} (provide 'mmm-mode) ;;; mmm-mode.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-region.el000066400000000000000000000733741214562307500222640ustar00rootroot00000000000000;;; mmm-region.el --- Manipulating and behavior of MMM submode regions ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;; Version: $Id: mmm-region.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file provides the functions and variables to create, delete, ;; and inspect submode regions, as well as functions that make them ;; behave like the submode with respect to syntax tables, local maps, ;; font lock, etc. ;; See mmm-class.el for functions which scan the buffer and decide ;; where to create regions. ;;; Code: (require 'cl) (require 'font-lock) (require 'mmm-compat) (require 'mmm-utils) (require 'mmm-auto) (require 'mmm-vars) ;; INSPECTION ;;{{{ Current Overlays ;; Emacs counts an overlay starting at POS as "at" POS, but not an ;; overlay ending at POS. XEmacs is more sensible and uses beg- and ;; end-stickiness to determine whether an endpoint is within an ;; extent. Here we want to act like XEmacs does. (defsubst mmm-overlay-at (&optional pos type) "Return the highest-priority MMM Mode overlay at POS. See `mmm-included-p' for the values of TYPE." (car (mmm-overlays-at pos type))) (defun mmm-overlays-at (&optional pos type) "Return a list of the MMM overlays at POS, in decreasing priority. See `mmm-included-p' for the values of TYPE." (or pos (setq pos (point))) (mmm-sort-overlays (remove-if-not #'(lambda (ovl) (and (overlay-get ovl 'mmm) (mmm-included-p ovl pos type))) ;; XEmacs complains about positions outside the buffer (overlays-in (max (1- pos) (point-min)) (min (1+ pos) (point-max)))))) (defun mmm-included-p (ovl pos &optional type) "Return true if the overlay OVL contains POS. If OVL strictly contains POS, always return true. If OVL starts or ends at POS, return true or false based on the value of TYPE, which should be one of nil, `beg', `end', `none', or `all'. * If TYPE is nil, return true for an overlay starting at POS only if it is beg-sticky, and for one ending at POS only if it is end-sticky. * If TYPE is `beg', return true for any overlay starting at POS but false for any ending at POS. * If TYPE is `end', return true for any overlay ending at POS but false for any starting at POS. * If TYPE is `all', return true for any overlay starting or ending at POS. * If TYPE is `none' \(or any other value), return false for any overlay starting or ending at POS." (let ((beg (overlay-start ovl)) (end (overlay-end ovl))) (cond ((and (= beg pos) (= end pos)) ;; Do the Right Thing for zero-width overlays (case type ((nil) (and (overlay-get ovl 'beg-sticky) (overlay-get ovl 'end-sticky))) ((none) nil) (t t))) ((= beg pos) (case type ((nil) (overlay-get ovl 'beg-sticky)) ((beg all) t) (t nil))) ((= end pos) (case type ((nil) (overlay-get ovl 'end-sticky)) ((end all) t) (t nil))) ((and (> end pos) (< beg pos)) t)))) ;;; `mmm-overlays-in' has been retired as altogether too confusing a ;;; name, when what is really meant is one of the following three: (defun mmm-overlays-containing (start stop) "Return all MMM overlays containing the region START to STOP. The overlays are returned in order of decreasing priority. No attention is paid to stickiness." (mmm-sort-overlays (remove-if-not #'(lambda (ovl) (and (overlay-get ovl 'mmm) (<= (overlay-start ovl) start) (>= (overlay-end ovl) stop))) (overlays-in (max start (point-min)) (min stop (point-max)))))) (defun mmm-overlays-contained-in (start stop) "Return all MMM overlays entirely contained in START to STOP. The overlays are returned in order of decreasing priority. No attention is paid to stickiness." (mmm-sort-overlays (remove-if-not #'(lambda (ovl) (and (overlay-get ovl 'mmm) (>= (overlay-start ovl) start) (<= (overlay-end ovl) stop))) (overlays-in (max start (point-min)) (min stop (point-max)))))) (defun mmm-overlays-overlapping (start stop) "Return all MMM overlays overlapping the region START to STOP. The overlays are returned in order of decreasing priority. No attention is paid to stickiness." (mmm-sort-overlays (remove-if-not #'(lambda (ovl) (overlay-get ovl 'mmm)) (overlays-in (max start (point-min)) (min stop (point-max)))))) (defun mmm-sort-overlays (overlays) "Sort OVERLAYS in order of decreasing priority." (sort (copy-list overlays) #'(lambda (x y) (> (or (overlay-get x 'priority) 0) (or (overlay-get y 'priority) 0))))) ;;}}} ;;{{{ Current Submode (defvar mmm-current-overlay nil "What submode region overlay we think we are currently in. May be out of date; call `mmm-update-current-submode' to correct it.") (make-variable-buffer-local 'mmm-current-overlay) (defvar mmm-previous-overlay nil "What submode region overlay we were in just before this one. Set by `mmm-update-current-submode'.") (make-variable-buffer-local 'mmm-previous-overlay) (defvar mmm-current-submode nil "What submode we think we are currently in. May be out of date; call `mmm-update-current-submode' to correct it.") (make-variable-buffer-local 'mmm-current-submode) (defvar mmm-previous-submode nil "What submode we were in just before this one. Set by `mmm-update-current-submode'.") (make-variable-buffer-local 'mmm-previous-submode) (defun mmm-update-current-submode (&optional pos) "Update current and previous position variables to POS, or point. Return non-nil if the current region changed. Also deletes overlays that ought to evaporate because their delimiters have disappeared." (mapc #'delete-overlay (remove-if #'(lambda (ovl) (or (not (eq (overlay-get ovl 'mmm-evap) 'front)) (overlay-buffer (overlay-get ovl 'front)))) (mmm-overlays-at pos))) (let ((ovl (mmm-overlay-at pos))) (if (eq ovl mmm-current-overlay) nil (setq mmm-previous-overlay mmm-current-overlay mmm-previous-submode mmm-current-submode) (setq mmm-current-overlay ovl mmm-current-submode (if ovl (overlay-get ovl 'mmm-mode))) t))) ;; This function is, I think, mostly for hacking font-lock. (defun mmm-set-current-submode (mode &optional pos) "Set the current submode to MODE and the current region to whatever region of that mode is present at POS, or nil if none." (setq mmm-previous-overlay mmm-current-overlay mmm-previous-submode mmm-current-submode) (setq mmm-current-submode mode mmm-current-overlay (find-if #'(lambda (ovl) (eq (overlay-get ovl 'mmm-mode) mode)) (mmm-overlays-at (or pos (point)) 'all)))) (defun mmm-submode-at (&optional pos type) "Return the submode at POS \(or point), or NIL if none. See `mmm-included-p' for values of TYPE." (let ((ovl (mmm-overlay-at pos type))) (if ovl (overlay-get ovl 'mmm-mode)))) ;;}}} ;;{{{ Delimiter Matching and Boundaries (defun mmm-match-front (ovl) "Return non-nil if the front delimiter of OVL matches as it should. Sets the match data to the front delimiter, if it is a regexp. Otherwise, calls it as a function with point at the beginning of the front delimiter overlay \(i.e. where the front delimiter ought to start) and one argument being the region overlay. The function should return non-nil if the front delimiter matches correctly, and set the match data appropriately." (let* ((front-ovl (overlay-get ovl 'front)) (front (if front-ovl (overlay-get front-ovl 'match)))) (when front (save-excursion (goto-char (overlay-start front-ovl)) (if (stringp front) ;; It's a regexp (looking-at front) ;; It's a function (funcall front ovl)))))) (defun mmm-match-back (ovl) "Return non-nil if the back delimiter of OVL matches as it should. Sets the match data to the back delimiter, if it is a regexp. Otherwise, calls it as a function with point at the beginning of the back delimiter overlay \(i.e. where the back delimiter ought to start) and one argument being the region overlay. The function should return non-nil if the back delimiter matches correctly, and set the match data appropriately." (let* ((back-ovl (overlay-get ovl 'back)) (back (if back-ovl (overlay-get back-ovl 'match)))) (when back (save-excursion (goto-char (overlay-start back-ovl)) (if (stringp back) ;; It's a regexp (looking-at back) ;; It's a function (funcall back ovl)))))) (defun mmm-front-start (ovl) "Return the position at which the front delimiter of OVL starts." (let ((front (overlay-get ovl 'front))) ;; Overlays which have evaporated become "overlays in no buffer" (if (and front (overlay-buffer front)) (overlay-start front) (overlay-start ovl)))) (defun mmm-back-end (ovl) "Return the position at which the back delimiter of OVL ends." (let ((back (overlay-get ovl 'back))) ;; Overlays which have evaporated become "overlays in no buffer" (if (and back (overlay-buffer back)) (overlay-end back) (overlay-end ovl)))) ;;}}} ;; CREATION & DELETION ;;{{{ Make Submode Regions (defun mmm-valid-submode-region (submode beg end) "Check if the region between BEG and END is valid for SUBMODE. This region must be entirely contained within zero or more existing submode regions, none of which start or end inside it, and it must be a valid child of the highest-priority of those regions, if any. Signals errors, returns `t' if no error." ;; First check if the placement is valid. Every existing region ;; that overlaps this one must contain it in its entirety. (let ((violators (set-difference (mmm-overlays-overlapping beg end) (mmm-overlays-containing beg end)))) (if violators (signal 'mmm-subregion-invalid-placement violators))) ;; Now check if it is inside a valid parent (let ((parent-mode (mmm-submode-at beg 'beg))) (and parent-mode ;; TODO: Actually check parents here. For present purposes, ;; we just make sure we aren't putting a submode inside one ;; of the same type. Actually, what we should really be ;; doing is checking classes/names of regions, not just the ;; submodes. (eq submode parent-mode) (signal 'mmm-subregion-invalid-parent (list parent-mode)))) t) (defun* mmm-make-region (submode beg end &key face front back (evaporation 'front) delimiter-mode front-face back-face display-name (match-front "") (match-back "") (beg-sticky t) (end-sticky t) name creation-hook ) "Make a submode region from BEG to END of SUBMODE. BEG and END are buffer positions or markers with BEG <= END \(although see EVAPORATION below). SUBMODE is a major mode function or a valid argument to `mmm-modename->function'. FACE is a valid display face. FRONT and BACK specify the positions of the front and back delimiters for this region, if any. If FRONT is a buffer position or marker, the front delimiter runs from it to BEG. FRONT can also be a two-element list \(FRONT-BEG FRONT-END) specifying the exact position of the front delimiter. One must have FRONT-BEG < FRONT-END <= BEG. Similarly, BACK may be a buffer position or marker, in which case the back delimiter runs from END to BACK. BACK can also be a two-element list \(BACK-BEG BACK-END) specifying the exact position, in which case we must have END <= BACK-BEG < BACK-END. EVAPORATION specifies under what conditions this submode region should disappear. * If `nil', the region never disappears. This can cause serious problems when using cut-and-paste and is not recommended. * If the value is t, the region disappears whenever it has zero length. This is recommended for manually created regions used for temporary editing convenience. * If the value is `front', the region will disappear whenever the text in its front delimiter disappears, that is, whenever the overlay which marks its front delimiter has zero width. The default value is `front'. However, if the parameter FRONT is nil, then this makes no sense, so the default becomes `t'. Note that if EVAPORATION is `t', then an error is signalled if BEG = END. MATCH-FRONT \(resp. MATCH-BACK) is a regexp or function to match the correct delimiters, see `mmm-match-front' \(resp. `mmm-match-back'). It is ignored if FRONT \(resp. BACK) is nil. At present these are not used much. DELIMITER-MODE specifies the major mode to use for delimiter regions. A `nil' value means they remain in the primary mode. FACE, FRONT-FACE, and BACK-FACE, are faces to use for the region, the front delimiter, and the back delimiter, respectively, under high decoration \(see `mmm-submode-decoration-level'). BEG-STICKY and END-STICKY determine whether the front and back of the region, respectively, are sticky with respect to new insertion. The default is yes. NAME is a string giving the \"name\" of this submode region. Submode regions with the same name are considered part of the same code fragment and formatted accordingly. DISPLAY-NAME is a string to display in the mode line when point is in this submode region. If nil or not given, the name associated with SUBMODE is used. In delimiter regions, \"--\" is shown. CREATION-HOOK should be a function to run after the region is created, with point at the start of the new region." ;; Check placement of region and delimiters (unless (if (eq evaporation t) (< beg end) (<= beg end)) (signal 'mmm-subregion-invalid-placement (list beg end))) (when front (unless (listp front) (setq front (list front beg))) (unless (and (< (car front) (cadr front)) (<= (cadr front) beg)) (signal 'mmm-subregion-invalid-placement front))) (when back (unless (listp back) (setq back (list end back))) (unless (and (< (car back) (cadr back)) (<= end (car back))) (signal 'mmm-subregion-invalid-placement back))) (setq submode (mmm-modename->function submode)) ;; Check embedding in existing regions (mmm-valid-submode-region submode beg end) (mmm-mode-on) (when submode (mmm-update-mode-info submode)) (and (not front) (eq evaporation 'front) (setq evaporation t)) (let ((region-ovl (mmm-make-overlay submode beg end name face beg-sticky end-sticky (or (eq evaporation t) nil) display-name))) ;; Save evaporation type for checking later (overlay-put region-ovl 'mmm-evap evaporation) ;; Calculate priority to supersede anything already there. (overlay-put region-ovl 'priority (length (mmm-overlays-at beg))) ;; Make overlays for the delimiters, with appropriate pointers. (when front (let ((front-ovl (mmm-make-overlay delimiter-mode (car front) (cadr front) nil front-face nil nil t "--" t))) (overlay-put region-ovl 'front front-ovl) (overlay-put front-ovl 'region region-ovl) (overlay-put front-ovl 'match match-front))) (when back (let ((back-ovl (mmm-make-overlay delimiter-mode (car back) (cadr back) nil back-face nil nil t "--" t))) (overlay-put region-ovl 'back back-ovl) (overlay-put back-ovl 'region region-ovl) (overlay-put back-ovl 'match match-back))) ;; Update everything and run all the hooks (mmm-save-all (goto-char (overlay-start region-ovl)) (mmm-set-current-submode submode) (mmm-set-local-variables submode) (mmm-run-submode-hook submode) (when creation-hook (funcall creation-hook)) (mmm-save-changed-local-variables region-ovl submode)) (setq mmm-previous-submode submode mmm-previous-overlay region-ovl) (mmm-update-submode-region) region-ovl)) (defun mmm-make-overlay (submode beg end name face beg-sticky end-sticky evap &optional display-name delim) "Internal function to make submode overlays. Does not handle delimiters. Use `mmm-make-region'." (let ((ovl (make-overlay beg end nil (not beg-sticky) end-sticky))) (mapc #'(lambda (pair) (overlay-put ovl (car pair) (cadr pair))) `((mmm t) ; Mark all submode overlays (mmm-mode ,submode) ,@(if delim '((delim t)) nil) (mmm-local-variables ;; Have to be careful to make new list structure here ,(list* (list 'font-lock-cache-state nil) (list 'font-lock-cache-position (make-marker)) (copy-tree (cdr (assq submode mmm-region-saved-locals-defaults))))) (name ,name) (display-name ,display-name) ;; Need to save these, because there's no way of accessing an ;; overlay's official "front-advance" parameter once it's created. (beg-sticky ,beg-sticky) (end-sticky ,end-sticky) ;; These have special meaning to Emacs (,mmm-evaporate-property ,evap) (face ,(mmm-get-face face submode delim)) )) ovl)) (defun mmm-get-face (face submode &optional delim) (cond ((= mmm-submode-decoration-level 0) nil) ((and (= mmm-submode-decoration-level 2) face) face) (delim 'mmm-delimiter-face) (submode 'mmm-default-submode-face))) ;;}}} ;;{{{ Clear Overlays ;; See also `mmm-clear-current-region'. (defun mmm-clear-overlays (&optional start stop strict) "Clears all MMM overlays overlapping START and STOP. If STRICT, only clear those entirely included in that region." (mapc #'delete-overlay (if strict (mmm-overlays-contained-in (or start (point-min)) (or stop (point-max))) (mmm-overlays-overlapping (or start (point-min)) (or stop (point-max))))) (mmm-update-submode-region)) ;;}}} ;; BASIC UPDATING ;;{{{ Submode Info (defun mmm-update-mode-info (mode &optional force) "Save the global-saved and buffer-saved variables for MODE. Global saving is done on properties of the symbol MODE and buffer saving in `mmm-buffer-saved-locals'. This function must be called for both the dominant mode and all submodes, in each file. Region-saved variables are initialized from `mmm-region-saved-locals-defaults', which is set here as well. See `mmm-save-local-variables'. If FORCE is non-nil, don't quit if the info is already there." (let ((buffer-entry (assq mode mmm-buffer-saved-locals)) (region-entry (assq mode mmm-region-saved-locals-defaults)) global-vars buffer-vars region-vars ;; kludge for XEmacs 20 (html-helper-build-new-buffer nil)) (unless (and (not force) (get mode 'mmm-local-variables) buffer-entry region-entry) (save-excursion (let ((filename (buffer-file-name))) ;; On errors, the temporary buffers don't get deleted, so here ;; we get rid of any old ones that may be hanging around. (when (buffer-live-p (get-buffer mmm-temp-buffer-name)) (with-current-buffer (get-buffer mmm-temp-buffer-name) (set-buffer-modified-p nil) (kill-buffer (current-buffer)))) ;; Now make a new temporary buffer. (set-buffer (mmm-make-temp-buffer (current-buffer) mmm-temp-buffer-name)) ;; Handle stupid modes that need the file name set (if (memq mode mmm-set-file-name-for-modes) (setq buffer-file-name filename))) (funcall mode) (when (featurep 'font-lock) ;; XEmacs doesn't have global-font-lock-mode (or rather, it ;; has nothing but global-font-lock-mode). (when (or mmm-xemacs ;; Code copied from font-lock.el to detect when font-lock ;; should be on via global-font-lock-mode. (and (or font-lock-defaults (with-no-warnings (assq major-mode font-lock-defaults-alist)) (assq major-mode font-lock-keywords-alist)) (or (eq font-lock-global-modes t) (if (eq (car-safe font-lock-global-modes) 'not) (not (memq major-mode (cdr font-lock-global-modes))) (memq major-mode font-lock-global-modes))))) ;; Don't actually fontify in the temp buffer, but note ;; that we should fontify when we use this mode. (put mode 'mmm-font-lock-mode t)) ;; Get the font-lock variables (when mmm-font-lock-available-p ;; To fool `font-lock-add-keywords' (let ((font-lock-mode t)) (mmm-set-font-lock-defaults))) ;; These can't be in the local variables list, because we ;; replace their actual values, but we want to use their ;; original values elsewhere. (unless (and mmm-xemacs (= emacs-major-version 20)) ;; XEmacs 20 doesn't have this variable. This effectively ;; prevents the MMM font-lock support from working, but we ;; just ignore it and go on, to prevent an error message. (put mode 'mmm-fontify-region-function font-lock-fontify-region-function)) (put mode 'mmm-beginning-of-syntax-function ;font-lock-beginning-of-syntax-function)) syntax-begin-function)) ;; Get variables (setq global-vars (mmm-get-locals 'global) buffer-vars (mmm-get-locals 'buffer) region-vars (mmm-get-locals 'region)) (put mode 'mmm-mode-name mode-name) (set-buffer-modified-p nil) (kill-buffer (current-buffer))) (put mode 'mmm-local-variables global-vars) (if buffer-entry (setcdr buffer-entry buffer-vars) (push (cons mode buffer-vars) mmm-buffer-saved-locals)) (if region-entry (setcdr region-entry region-vars) (push (cons mode region-vars) mmm-region-saved-locals-defaults))))) ;;}}} ;;{{{ Updating Hooks (defun mmm-update-submode-region () "Update all MMM properties correctly for the current position. This function and those it calls do the actual work of setting the different keymaps, syntax tables, local variables, etc. for submodes." (when (mmm-update-current-submode) (mmm-save-changed-local-variables mmm-previous-overlay mmm-previous-submode) (let ((mode (or mmm-current-submode mmm-primary-mode))) (mmm-update-mode-info mode) (mmm-set-local-variables mode) (mmm-enable-font-lock mode)) (mmm-set-mode-line) (dolist (func (if mmm-current-overlay (overlay-get mmm-current-overlay 'entry-hook) mmm-primary-mode-entry-hook)) (ignore-errors (funcall func))))) (defun mmm-add-hooks () (add-hook 'post-command-hook 'mmm-update-submode-region nil 'local)) (defun mmm-remove-hooks () (remove-hook 'post-command-hook 'mmm-update-submode-region 'local)) ;;}}} ;;{{{ Local Variables (defun mmm-get-local-variables-list (type mode) "Filter `mmm-save-local-variables' to match TYPE and MODE. Return a list \(VAR ...). In some cases, VAR will be a cons cell \(GETTER . SETTER) -- see `mmm-save-local-variables'." (mapcan #'(lambda (element) (and (if (and (consp element) (cdr element) (cadr element)) (eq (cadr element) type) (eq type 'global)) (if (and (consp element) (cddr element) (not (eq (caddr element) t))) (if (functionp (caddr element)) (funcall (caddr element)) (member mode (caddr element))) t) (list (if (consp element) (car element) element)))) mmm-save-local-variables)) (defun mmm-get-locals (type) "Get the local variables and values for TYPE from this buffer. Return \((VAR VALUE) ...). In some cases, VAR will be of the form \(GETTER . SETTER) -- see `mmm-save-local-variables'." (mapcan #'(lambda (var) (if (consp var) `((,var ,(funcall (car var)))) (and (boundp var) ;; This seems logical, but screws things up. ;;(local-variable-p var) `((,var ,(symbol-value var)))))) (mmm-get-local-variables-list type major-mode))) (defun mmm-get-saved-local (mode var) "Get the value of the local variable VAR saved for MODE, if any." (cadr (assq var (mmm-get-saved-local-variables mode)))) (defun mmm-set-local-variables (mode) "Set all the local variables saved for MODE. Looks up both global, buffer, and region saves." (mapcar #'(lambda (var) ;; (car VAR) may be (GETTER . SETTER) (if (consp (car var)) (funcall (cdar var) (cadr var)) (make-local-variable (car var)) (set (car var) (cadr var)))) (mmm-get-saved-local-variables mode))) (defun mmm-get-saved-local-variables (mode) (append (get mode 'mmm-local-variables) (cdr (assq mode mmm-buffer-saved-locals)) (let ((ovl (mmm-overlay-at (point)))) (if ovl (overlay-get ovl 'mmm-local-variables) mmm-region-saved-locals-for-dominant)))) (defun mmm-save-changed-local-variables (ovl mode) "Save by-buffer and by-region variables for OVL and MODE. Called when we move to a new submode region, with OVL and MODE the region and mode for the previous position." (let ((buffer-vars (cdr (assq (or mode mmm-primary-mode) mmm-buffer-saved-locals))) (region-vars (if ovl (overlay-get ovl 'mmm-local-variables) mmm-region-saved-locals-for-dominant)) (set-local-value #'(lambda (var) (setcar (cdr var) ;; (car VAR) may be (GETTER . SETTER) (if (consp (car var)) (funcall (caar var)) (symbol-value (car var))))))) (mapc set-local-value buffer-vars) (mapc set-local-value region-vars))) (defun mmm-clear-local-variables () "Clear all buffer- and region-saved variables for current buffer." (setq mmm-buffer-saved-locals () mmm-region-saved-locals-defaults () mmm-region-saved-locals-for-dominant ())) ;;}}} ;; FONT LOCK ;;{{{ Enable Font Lock (defun mmm-enable-font-lock (mode) "Turn on font lock if it is not already on and MODE enables it." (mmm-update-mode-info mode) (and mmm-font-lock-available-p (not font-lock-mode) (get mode 'mmm-font-lock-mode) (font-lock-mode 1))) (defun mmm-update-font-lock-buffer () "Turn on font lock iff any mode in the buffer enables it." (when mmm-font-lock-available-p (if (some #'(lambda (mode) (get mode 'mmm-font-lock-mode)) (cons mmm-primary-mode (mapcar #'(lambda (ovl) (overlay-get ovl 'mmm-mode)) (mmm-overlays-overlapping (point-min) (point-max))))) (font-lock-mode 1) (font-lock-mode 0)))) (defun mmm-refontify-maybe (&optional start stop) "Re-fontify from START to STOP, or entire buffer, if enabled." (and font-lock-mode (if (or start stop) (font-lock-fontify-region (or start (point-min)) (or stop (point-max))) (font-lock-fontify-buffer)))) ;;}}} ;;{{{ Get Submode Regions ;;; In theory, these are general functions that have nothing to do ;;; with font-lock, but they aren't used anywhere else, so we might as ;;; well have them close. (defun mmm-submode-changes-in (start stop) "Return a list of all submode-change positions from START to STOP. The list is sorted in order of increasing buffer position." (sort (remove-duplicates (list* start stop (mapcan #'(lambda (ovl) `(,(overlay-start ovl) ,(overlay-end ovl))) (mmm-overlays-overlapping start stop)))) #'<)) (defun mmm-regions-in (start stop &optional flag delim) "Return a list of regions of the form (MODE BEG END) whose disjoint union covers the region from START to STOP, including delimiters." (let ((regions (maplist #'(lambda (pos-list) (if (cdr pos-list) (list (or (mmm-submode-at (car pos-list) 'beg) mmm-primary-mode) (car pos-list) (cadr pos-list)))) (mmm-submode-changes-in start stop)))) (setcdr (last regions 2) nil) regions)) (defun mmm-regions-alist (start stop) "Return a list of lists of the form \(MODE . REGIONS) where REGIONS is a list of elements of the form \(BEG END). The disjoint union all of the REGIONS covers START to STOP." (let ((regions (mmm-regions-in start stop))) (mapcar #'(lambda (mode) (cons mode (mapcan #'(lambda (region) (if (eq mode (car region)) (list (cdr region)))) regions))) ;; All the modes (remove-duplicates (mapcar #'car regions))))) ;;}}} ;;{{{ Fontify Regions (defun mmm-fontify-region (start stop &optional loudly) "Fontify from START to STOP keeping track of submodes correctly." (when loudly (message "Fontifying %s with submode regions..." (buffer-name))) ;; Necessary to catch changes in font-lock cache state and position. (mmm-save-changed-local-variables mmm-current-overlay mmm-current-submode) ;; For some reason `font-lock-fontify-block' binds this to nil, thus ;; preventing `mmm-beginning-of-syntax' from doing The Right Thing. ;; I don't know why it does this, but let's undo it here. (let ((;font-lock-beginning-of-syntax-function syntax-begin-function 'mmm-beginning-of-syntax)) (mapc #'(lambda (elt) (when (get (car elt) 'mmm-font-lock-mode) (mmm-fontify-region-list (car elt) (cdr elt)))) (mmm-regions-alist start stop))) ;; With jit-lock, this causes blips in the mode line and menus. ;; Shouldn't be necessary here, since it's in post-command-hook too. ;;(mmm-update-submode-region) (when loudly (message nil))) (defun mmm-fontify-region-list (mode regions) "Fontify REGIONS, each like \(BEG END), in mode MODE." (save-excursion (let (;(major-mode mode) (func (get mode 'mmm-fontify-region-function))) (mapc #'(lambda (reg) (goto-char (car reg)) ;; Here we do the same sort of thing that ;; `mmm-update-submode-region' does, but we force it ;; to use a specific mode, and don't save anything, ;; fontify, or change the mode line. (mmm-set-current-submode mode) (mmm-set-local-variables mode) (funcall func (car reg) (cadr reg) nil) ;; Catch changes in font-lock cache. (mmm-save-changed-local-variables mmm-current-overlay mmm-current-submode)) regions)))) ;;}}} ;;{{{ Beginning of Syntax (defun mmm-beginning-of-syntax () (goto-char (let ((ovl (mmm-overlay-at (point))) (func (get (or mmm-current-submode mmm-primary-mode) 'mmm-beginning-of-syntax-function))) (max (if ovl (overlay-start ovl) (point-min)) (if func (progn (funcall func) (point)) (point-min)) (point-min))))) ;;}}} (provide 'mmm-region) ;;; mmm-region.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-rpm.el000066400000000000000000000052771214562307500215740ustar00rootroot00000000000000;;; mmm-rpm.el --- MMM submode class for RPM spec files ;; Copyright (C) 2000 by Marcus Harnisch ;; Author: Marcus Harnisch ;; Version: $Id: mmm-rpm.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains the definition of an MMM Mode submode class for ;; editing shell script sections within RPM (Redhat Package Manager) ;; spec files. I recommend to use it in combination with ;; rpm-spec-mode.el by Stig Bjørlykke and Steve ;; Sanbeg (http://www.xemacs.org/~stigb/rpm-spec-mode.el) ;;; Installation: ;; 1. Copy this file where Emacs can find it. ;; ;; 2. Add the following lines to one of your startup files (e.g. ~/.emacs): ;; ;; (add-to-list 'mmm-mode-ext-classes-alist ;; '(rpm-spec-mode "\\.spec\\'" rpm-sh)) ;;; Code: (require 'mmm-auto) (defconst mmm-rpm-sh-start-tags '("prep" "build" "install" "clean" "preun" "postun" "pre" "post" "triggerin" "triggerun" "triggerpostun") "List containing RPM tags that start a shell-script section in a spec file") (defvar mmm-rpm-sh-end-tags (append '("files" "description" "package") mmm-rpm-sh-start-tags) "List containing RPM tags that end a shell-script section in a spec file") (defvar mmm-rpm-sh-start-regexp (concat "^%" (mmm-regexp-opt mmm-rpm-sh-start-tags t) "\\b.*$") "Regexp matching RPM tags that start a shell-script section in a spec file") (defvar mmm-rpm-sh-end-regexp (concat "\\'\\|^%" (mmm-regexp-opt mmm-rpm-sh-end-tags t) "\\b.*$") "Regexp matching RPM tags that end a shell-script section in a spec file") (mmm-add-group 'rpm `((rpm-sh :submode sh-mode :face mmm-code-submode-face ;; match tags that starts sh-script region :front ,mmm-rpm-sh-start-regexp ;; match end of buffer or next tag that ends sh-script region :back ,mmm-rpm-sh-end-regexp :front-offset 1 :back-offset 0 :save-matches 0 ))) (provide 'mmm-rpm) ;;; mmm-rpm.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-sample.el000066400000000000000000000257431214562307500222570ustar00rootroot00000000000000;;; mmm-sample.el --- Sample MMM submode classes ;; Copyright (C) 2003, 2004 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;; Version: $Id: mmm-sample.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains several sample submode classes for use with MMM ;; Mode. For a more detailed and useful example, see `mmm-mason.el'. ;;; Code: (require 'mmm-auto) (require 'mmm-vars) ;;{{{ CSS embedded in HTML ;; This is the simplest example. Many applications will need no more ;; than a simple regexp. (mmm-add-classes '((embedded-css :submode css :face mmm-declaration-submode-face :delimiter-mode nil :front "]*>" :back ""))) ;;}}} ;;{{{ Javascript in HTML ;; We use two classes here, one for code in a " :insert ((?j js-tag nil @ "" @)) ) (js-inline :submode javascript :face mmm-code-submode-face :delimiter-mode nil :front "on\\w+=\"" :back "\""))) ;;}}} ;;{{{ Here-documents ;; Here we match the here-document syntax used by Perl and shell ;; scripts. We try to be automagic about recognizing what mode the ;; here-document should be in. To make sure that it is recognized ;; correctly, the name of the mode, perhaps minus `-mode', in upper ;; case, and/or with hyphens converted to underscores, should be ;; separated from the rest of the here-document name by hyphens or ;; underscores. (defvar mmm-here-doc-mode-alist '() "Alist associating here-document name regexps to submodes. Normally, this variable is unnecessary, as the `here-doc' submode class tries to automagically recognize the right submode. If you use here-document names that it doesn't recognize, however, then you can add elements to this alist. Each element is \(REGEXP . MODE) where REGEXP is a regular expression matched against the here-document name and MODE is a major mode function symbol.") (defun mmm-here-doc-get-mode (string) (string-match "[a-zA-Z_-]+" string) (setq string (match-string 0 string)) (or (mmm-ensure-modename ;; First try the user override variable. (some #'(lambda (pair) (if (string-match (car pair) string) (cdr pair) nil)) mmm-here-doc-mode-alist)) (let ((words (split-string (downcase string) "[_-]+"))) (or (mmm-ensure-modename ;; Try the whole name, stopping at "mode" if present. (intern (mapconcat #'identity (nconc (ldiff words (member "mode" words)) (list "mode")) "-"))) ;; Try each word by itself (preference list) (some #'(lambda (word) (mmm-ensure-modename (intern word))) words) ;; Try each word with -mode tacked on (some #'(lambda (word) (mmm-ensure-modename (intern (concat word "-mode")))) words) ;; Try each pair of words with -mode tacked on (loop for (one two) on words if (mmm-ensure-modename (intern (concat one two "-mode"))) return it) ;; I'm unaware of any modes whose names, minus `-mode', ;; are more than two words long, and if the entire mode ;; name (perhaps minus `-mode') doesn't occur in the ;; here-document name, we can give up. (signal 'mmm-no-matching-submode nil))))) (mmm-add-classes '((here-doc :front "<<[\"\'\`]?\\([a-zA-Z0-9_-]+\\)" :front-offset (end-of-line 1) :back "^~1$" :save-matches 1 :delimiter-mode nil :match-submode mmm-here-doc-get-mode :insert ((?d here-doc "Here-document Name: " @ "<<" str _ "\n" @ "\n" @ str "\n" @)) ))) ;;}}} ;;{{{ Embperl (mmm-add-group 'embperl '((embperl-perl :submode perl :front "\\[\\([-\\+!\\*\\$]\\)" :back "~1\\]" :save-matches 1 :match-name "embperl" :match-face (("[+" . mmm-output-submode-face) ("[-" . mmm-code-submode-face) ("[!" . mmm-init-submode-face) ("[*" . mmm-code-submode-face) ("[$" . mmm-special-submode-face)) :insert ((?p embperl "Region Type (Character): " @ "[" str @ " " _ " " @ str "]" @) (?+ embperl+ ?p . "+") (?- embperl- ?p . "-") (?! embperl! ?p . "!") (?* embperl* ?p . "*") (?$ embperl$ ?p . "$") ) ) (embperl-comment :submode text-mode :face mmm-comment-submode-face :front "\\[#" :back "#\\]" :insert ((?# embperl-comment nil @ "[#" @ " " _ " " @ "#]" @)) ))) ;;}}} ;;{{{ ePerl (mmm-add-group 'eperl '((eperl-expr :submode perl :face mmm-output-submode-face :front "<:=" :back ":>" :insert ((?= eperl-expr nil @ "<:=" @ " " _ " " @ ":>" @))) (eperl-code :submode perl :face mmm-code-submode-face :front "<:" :back "_?:>" :match-name "eperl" :insert ((?p eperl-code nil @ "<:" @ " " _ " " @ ":>" @) (?: eperl-code ?p . nil) (?_ eperl-code_ nil @ "<:" @ " " _ " " @ "_:>" @))) (eperl-comment :submode text :face mmm-comment-submode-face :front ":>//" :back "\n") )) ;;}}} ;;{{{ File Variables ;; This submode class puts file local variable values, specified with ;; a `Local Variables:' line as in (emacs)File Variables, into Emacs ;; Lisp Mode. It is a good candidate to put in `mmm-global-classes'. (defun mmm-file-variables-verify () ;; It would be nice to cache this somehow, which could be done in a ;; buffer-local variable with markers for positions, but the trick ;; is knowing when to expire the cache. (let ((bounds (save-excursion (save-match-data (goto-char (point-max)) (backward-page) (and (re-search-forward "^\\(.*\\)Local Variables:" nil t) (list (match-string 1) (progn (end-of-line) (point)) (and (search-forward (format "%sEnd:" (match-string 1)) nil t) (progn (beginning-of-line) (point))))))))) (and bounds (caddr bounds) (save-match-data (string-match (format "^%s" (regexp-quote (car bounds))) (match-string 0))) (> (match-beginning 0) (cadr bounds)) (< (match-end 0) (caddr bounds))))) (defun mmm-file-variables-find-back (bound) (forward-sexp) (if (> (point) bound) nil (looking-at ""))) (mmm-add-classes '((file-variables :front ".+:" :front-verify mmm-file-variables-verify :back mmm-file-variables-find-back :submode emacs-lisp-mode :delimiter-mode nil ))) ;;}}} ;;{{{ JSP Pages (mmm-add-group 'jsp `((jsp-comment :submode text-mode :face mmm-comment-submode-face :front "<%--" :back "--%>" :insert ((?- jsp-comment nil @ "<%--" @ " " _ " " @ "--%>" @)) ) (jsp-code :submode java :match-face (("<%!" . mmm-declaration-submode-face) ("<%=" . mmm-output-submode-face) ("<%" . mmm-code-submode-face)) :front "<%[!=]?" :back "%>" :match-name "jsp" :insert ((?% jsp-code nil @ "<%" @ " " _ " " @ "%>" @) (?! jsp-declaration nil @ "<%!" @ " " _ " " @ "%>" @) (?= jsp-expression nil @ "<%=" @ " " _ " " @ "%>" @)) ) (jsp-directive :submode text-mode :face mmm-special-submode-face :front "<%@" :back "%>" :insert ((?@ jsp-directive nil @ "<%@" @ " " _ " " @ "%>" @)) ))) ;;}}} ;;{{{ SGML DTD ;; Thanks to Yann Dirson for writing and ;; contributing this submode class. (mmm-add-classes '((sgml-dtd :submode dtd-mode :face mmm-declaration-submode-face :delimiter-mode nil :front "[]*\\[" :back "]>"))) ;;}}} ;;{{{ in httpd.conf (mmm-add-classes '((httpd-conf-perl :submode perl :delimiter-mode nil :front "" :back ""))) ;; Suggested Use: ;; (mmm-add-mode-ext-class 'apache-generic-mode nil 'httpd-conf-perl) ;;}}} ;;{{{ PHP in HTML (mmm-add-group 'html-php '((html-php-output :submode php-mode :face mmm-output-submode-face :front "<\\?php *echo " :back "\\?>" :include-front t :front-offset 5 :insert ((?e php-echo nil @ "" @)) ) (html-php-code :submode php-mode :face mmm-code-submode-face :front "<\\?\\(php\\)?" :back "\\?>" :insert ((?p php-section nil @ "" @) (?b php-block nil @ "" @)) ))) ;;}}} ;; NOT YET UPDATED ;;{{{ HTML in PL/SQL;-COM- ;-COM- ;-COM-;; This one is the most complex example. In PL/SQL, HTML is generally ;-COM-;; output as a (single quote delimited) string inside a call to htp.p or ;-COM-;; its brethren. The problem is that there may be strings outside of ;-COM-;; htp.p calls that should not be HTML, so we need to only look inside ;-COM-;; these calls. The situation is complicated by PL/SQL's rule that two ;-COM-;; sequential single quotes in a string mean to put a single quote ;-COM-;; inside the string. ;-COM- ;-COM-;; These functions have not been thoroughly tested, and always search ;-COM-;; the entire buffer, ignoring START and END. ;-COM- ;-COM-(defun mmm-html-in-plsql (start end) ;-COM- (save-match-data ;-COM- (let ((case-fold-search t)) ;-COM- (and (re-search-forward "htp.p\\(\\|rn\\|rint\\)1?(" nil t) ;-COM- (mmm-html-in-plsql-in-htp ;-COM- ;; Find the end of the procedure call ;-COM- (save-excursion (forward-char -1) (forward-sexp) (point)) ;-COM- start end))))) ;-COM- ;-COM-(defun mmm-html-in-plsql-in-htp (htp-end start end) ;-COM- (let (beg end) ;-COM- (or (and (re-search-forward "'" htp-end 'limit) ;-COM- (setf beg (match-end 0)) ;-COM- ;; Find an odd number of 's to end the string. ;-COM- (do ((lgth 0 (length (match-string 0)))) ;-COM- ((oddp lgth) t) ;-COM- (re-search-forward "'+" nil t)) ;-COM- (setf end (1- (match-end 0))) ;-COM- (cons (cons beg end) ;-COM- (mmm-html-in-plsql-in-htp htp-end start end))) ;-COM- ;; No more strings in the procedure call; look for another. ;-COM- (and (eql (point) htp-end) ;-COM- (mmm-html-in-plsql start end))))) ;-COM- ;-COM-(add-to-list 'mmm-classes-alist ;-COM- '(htp-p (:function html-mode mmm-html-in-plsql))) ;-COM- ;;}}} (provide 'mmm-sample) ;;; mmm-sample.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-univ.el000066400000000000000000000035021214562307500217440ustar00rootroot00000000000000;;; mmm-univ.el --- The "Universal" Submode Class ;; Copyright (C) 2000 by Free Software Foundation, Inc. ;; Author: Michael Abraham Shulman ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file defines the "universal" submode class, the default value ;; of `mmm-global-classes', which specifies a standard way to indicate ;; that part of a buffer should be in a different mode--for example, ;; in an email message. ;;; Code: (require 'mmm-auto) (require 'mmm-vars) (defun mmm-univ-get-mode (string) (string-match "[a-zA-Z-]+" string) (setq string (match-string 0 string)) (let ((modestr (intern (if (string-match "mode\\'" string) string (concat string "-mode"))))) (or (mmm-ensure-modename modestr) (signal 'mmm-no-matching-submode nil)))) (mmm-add-classes `((universal :front "{%\\([a-zA-Z-]+\\)%}" :back "{%/~1%}" :insert ((?/ universal "Submode: " @ "{%" str "%}" @ "\n" _ "\n" @ "{%/" str "%}" @)) :match-submode mmm-univ-get-mode :save-matches 1 ))) (provide 'mmm-univ) ;;; Local Variables: ;;; mmm-global-classes: nil ;;; End: ;;; mmm-univ.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-utils.el000066400000000000000000000122351214562307500221260ustar00rootroot00000000000000;;; mmm-utils.el --- Coding Utilities for MMM Mode ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;; Version: $Id: mmm-utils.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file provides a number of macros and other coding utilities ;; for MMM Mode. ;;; Code: (eval-when-compile (require 'cl)) ;;{{{ Valid Buffer ;; We used to wrap almost everything in this, but I realized that ;; only `mmm-mode-on' really needs it. Kept it as a macro, though, ;; for modularity and in case we need it somewhere else. (defmacro mmm-valid-buffer (&rest body) "Execute BODY if in a valid buffer for MMM Mode to be enabled. This means not hidden, not a minibuffer, not in batch mode, and not in of `mmm-never-modes'." `(unless (or (eq (aref (buffer-name) 0) ?\ ) (window-minibuffer-p (selected-window)) (memq major-mode mmm-never-modes) noninteractive ;; Unnecessary as now hidden ;;; (equal (buffer-name) mmm-temp-buffer-name) ) ,@body)) ;;;(def-edebug-spec mmm-valid-buffer t) ;;}}} ;;{{{ Save Everything ;; Never trust callback functions to preserve anything. (defmacro mmm-save-all (&rest body) "Execute BODY forms, then restoring point, mark, current buffer, restrictions, and match data." `(save-excursion (save-restriction (save-match-data ,@body)))) ;;;(def-edebug-spec mmm-save-all t) ;;}}} ;;{{{ String Formatting (defun mmm-format-string (string arg-pairs) "Format STRING by replacing arguments as specified by ARG-PAIRS. Each element of ARG-PAIRS is \(REGEXP . STR) where each STR is to be substituted for the corresponding REGEXP wherever it matches." (let ((case-fold-search nil)) (save-match-data (dolist (pair arg-pairs) (while (string-match (car pair) string) (setq string (replace-match (cdr pair) t t string)))))) string) (defun mmm-format-matches (string &optional on-string) "Format STRING by matches from the current match data. Strings like ~N are replaced by the Nth subexpression from the last global match. Does nothing if STRING is not a string. ON-STRING, if supplied, means to use the match data from a `string-match' on that string, rather than the global match data." (when (stringp string) (let ((old-data (match-data)) subexp) (save-match-data (while (string-match "~\\([0-9]\\)" string) (setq subexp (string-to-number (match-string-no-properties 1 string)) string (replace-match (save-match-data (set-match-data old-data) (match-string-no-properties subexp on-string)) t t string)))))) string) ;;}}} ;;{{{ Save Keywords (defmacro mmm-save-keyword (param) "If the value of PARAM as a variable is non-nil, return the list \(:PARAM (symbol-value PARAM)), otherwise NIL. Best used only when it is important that nil values disappear." `(if (and (boundp ',param) ,param) (list (intern (concat ":" (symbol-name ',param))) ,param) nil)) (defmacro mmm-save-keywords (&rest params) "Return a list saving the non-nil elements of PARAMS. E.g. \(let \(\(a 1) \(c 2)) \(mmm-save-keywords a b c)) ==> \(:a 1 :c 2) Use of this macro can make code more readable when there are a lot of PARAMS, but less readable when there are only a few. Also best used only when it is important that nil values disappear." `(append ,@(mapcar #'(lambda (param) (macroexpand `(mmm-save-keyword ,param))) params))) ;;}}} ;;{{{ Looking Back At (defun mmm-looking-back-at (regexp &optional bound) "Return t if text before point matches REGEXP. Modifies the match data. If supplied, BOUND means not to look farther back that that many characters before point. Otherwise, it defaults to \(length REGEXP), which is good enough when REGEXP is a simple string." (eq (point) (save-excursion (and (re-search-backward regexp (- (point) (or bound (length regexp))) t) (match-end 0))))) ;;}}} ;;{{{ Markers ;; Mostly for remembering interactively made regions (defun mmm-make-marker (pos beg-p sticky-p) "Make, and return, a marker at POS that is or isn't sticky. BEG-P represents whether the marker delimits the beginning of a region \(or the end of it). STICKY-P is whether it should be sticky, i.e. whether text inserted at the marker should be inside the region." (let ((mkr (set-marker (make-marker) pos))) (set-marker-insertion-type mkr (if beg-p (not sticky-p) sticky-p)) mkr)) ;;}}} (provide 'mmm-utils) ;;; mmm-utils.el ends hereproofgeneral-4.3~pre130510/contrib/mmm/mmm-vars.el000066400000000000000000001134251214562307500217440ustar00rootroot00000000000000;;; mmm-vars.el --- Variables for MMM Mode ;; Copyright (C) 2000, 2004 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;; Version: $Id: mmm-vars.el,v 12.0 2011/10/13 10:54:47 da Exp $ ;;{{{ GPL ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file provides the definitions for the variables used by MMM ;; Mode, as well as several functions to manipulate them. It also ;; defines the errors that MMM Mode can signal. ;;; Code: (require 'cl) (require 'mmm-compat) (require 'mmm-utils) ;; MISCELLANEOUS ;;{{{ Shut up the Byte Compiler ;; Otherwise it complains about undefined variables. (eval-when-compile (defvar mmm-current-submode) (defvar mmm-current-overlay) (defvar mmm-save-local-variables) (defvar mmm-mode-string) (defvar mmm-submode-mode-line-format) (defvar mmm-mode-ext-classes-alist) (defvar mmm-mode-prefix-key) (defvar mmm-global-mode) (defvar mmm-primary-mode) (defvar mmm-classes-alist) (defvar mmm-current-submode)) (declare-function mmm-set-class-parameter "mmm-class") (declare-function mmm-get-class-parameter "mmm-class") ;;}}} ;;{{{ Error Conditions ;; Most of these should be caught internally and never seen by the ;; user, except when the user is creating submode regions manually. ;; Signalled when we try to put a submode region inside one where it ;; isn't meant to go. (put 'mmm-subregion-invalid-parent 'error-conditions '(mmm-subregion-invalid-parent mmm-error error)) (put 'mmm-subregion-invalid-parent 'error-message "Invalid submode region parent") ;; Signalled when we try to put a submode region overlapping others in ;; an invalid way. (put 'mmm-subregion-invalid-placement 'error-conditions '(mmm-subregion-invalid-placement mmm-error error)) (put 'mmm-subregion-invalid-placement 'error-message "Submode region placement invalid") ;; Signalled when we try to apply a submode class that doesn't exist. (put 'mmm-invalid-submode-class 'error-conditions '(mmm-invalid-submode-class mmm-error error)) (put 'mmm-invalid-submode-class 'error-message "Invalid or undefined submode class") ;; Signalled by :match-submode functions when they are unable to ;; resolve a submode. This error should *always* be caught internally ;; and never seen by the user. (put 'mmm-no-matching-submode 'error-conditions '(mmm-no-matching-submode mmm-error error)) (put 'mmm-no-matching-submode 'error-message "Internal error: no matching submode.") ;;}}} ;; USER VARIABLES ;;{{{ Customization Group (defgroup mmm nil "Multiple Major Modes in one buffer." :group 'tools) ;;}}} ;;{{{ Save Local Variables (defvar mmm-c-derived-modes '(c-mode c++-mode objc-mode pike-mode java-mode jde-mode javascript-mode php-mode)) (defvar mmm-save-local-variables `(;; Don't use `function' (#') here!! We're already inside `quote'! major-mode comment-start comment-end (comment-line-start-skip buffer (fortran-mode)) comment-start-skip (comment-column buffer) comment-indent-function comment-line-break-function sentence-end ,@(when mmm-xemacs '(mode-popup-menu (((lambda () current-menubar) . set-buffer-menubar)) )) font-lock-keywords font-lock-keywords-only font-lock-keywords-case-fold-search font-lock-syntax-table font-lock-mark-block-function ; Override this? font-lock-syntactic-keywords indent-line-function parse-sexp-ignore-comments ; Fixes indentation in PHP-mode? ;; Can be different in different buffers (c-basic-offset buffer (c-mode c++-mode objc-mode pike-mode java-mode jde-mode)) ;; These are necessary for C syntax parsing (c-class-key nil ,mmm-c-derived-modes) (c-extra-toplevel-key nil ,mmm-c-derived-modes) (c-inexpr-class-key nil ,mmm-c-derived-modes) (c-conditional-key nil ,mmm-c-derived-modes) semantic-bovinate-toplevel-override semantic-toplevel-bovine-table ;; Indentation style control variables. ;; These have to be localized in Emacs: see `mmm-mode-on'. ,@(mapcar #'(lambda (var) (list var nil mmm-c-derived-modes)) '(c++-template-syntax-table c-<-op-cont-regexp c->-op-cont-regexp c-after-suffixed-type-decl-key c-after-suffixed-type-maybe-decl-key c-any-class-key c-any-class-key c-asm-stmt-kwds c-assignment-op-regexp c-backslash-column c-basic-offset c-bitfield-kwds c-block-comment-prefix c-block-decls-with-vars c-block-stmt-1-key c-block-stmt-1-key c-block-stmt-1-kwds c-block-stmt-2-key c-block-stmt-2-key c-block-stmt-2-kwds c-brace-list-key c-cast-parens c-class-key c-class-key c-class-kwds c-cleanup-list c-colon-type-list-re c-comment-only-line-offset c-comment-prefix-regexp c-comment-start-regexp c-comment-start-regexp c-cpp-defined-fns c-current-comment-prefix c-decl-block-key c-decl-block-key c-decl-prefix-re c-decl-spec-kwds c-doc-comment-start-regexp c-expr-kwds c-file-offsets c-file-style c-hanging-braces-alist c-hanging-colons-alist c-hanging-comment-ender-p c-hanging-comment-starter-p c-hanging-semi\&comma-criteria c-identifier-key c-identifier-last-sym-match c-identifier-start c-identifier-syntax-modifications c-identifier-syntax-table c-in-comment-lc-prefix c-indent-comment-alist c-indent-comments-syntactically-p c-indentation-style c-inexpr-block-kwds c-inexpr-class-kwds c-keywords c-keywords-obarray c-keywords-regexp c-keywords-regexp c-known-type-key c-label-key c-label-key c-label-kwds c-label-kwds-regexp c-label-kwds-regexp c-label-minimum-indentation c-lambda-kwds c-literal-start-regexp c-nonsymbol-chars c-nonsymbol-token-regexp c-not-decl-init-keywords c-offsets-alist c-opt-<>-arglist-start c-opt-<>-arglist-start-in-paren c-opt-<>-sexp-key c-opt-access-key c-opt-access-key c-opt-asm-stmt-key c-opt-asm-stmt-key c-opt-bitfield-key c-opt-bitfield-key c-opt-block-decls-with-vars-key c-opt-block-stmt-key c-opt-block-stmt-key c-opt-cpp-prefix c-opt-cpp-start c-opt-decl-spec-key c-opt-friend-key c-opt-friend-key c-opt-identifier-concat-key c-opt-inexpr-block-key c-opt-inexpr-block-key c-opt-inexpr-brace-list-key c-opt-inexpr-class-key c-opt-inexpr-class-key c-opt-lambda-key c-opt-lambda-key c-opt-method-key c-opt-method-key c-opt-postfix-decl-spec-key c-opt-type-component-key c-opt-type-concat-key c-opt-type-modifier-key c-opt-type-suffix-key c-other-decl-block-key c-other-decl-block-key c-other-decl-block-kwds c-other-decl-kwds c-overloadable-operators-regexp c-paragraph-separate c-paragraph-start c-paren-stmt-key c-primary-expr-regexp c-primitive-type-key c-primitive-type-kwds c-protection-kwds c-recognize-<>-arglists c-recognize-knr-p c-recognize-knr-p c-recognize-paren-inits c-recognize-typeless-decls c-regular-keywords-regexp c-simple-stmt-key c-simple-stmt-kwds c-special-brace-lists c-special-brace-lists c-specifier-key c-specifier-kwds c-stmt-delim-chars c-stmt-delim-chars-with-comma c-symbol-key c-symbol-key c-symbol-start c-syntactic-eol c-syntactic-ws-end c-syntactic-ws-start c-type-decl-prefix-key c-type-decl-suffix-key c-type-prefix-key comment-end comment-start comment-start-skip)) ;; Skeleton insertion skeleton-transformation ;; Abbrev mode abbrev-mode local-abbrev-table ;; And finally the syntax table and local map. ((syntax-table . set-syntax-table)) ((current-local-map . use-local-map) buffer) paragraph-separate paragraph-start ) "Which local variables to save for major mode regions. Each element has the form \(VARIABLE [TYPE [MODES]]), causing VARIABLE to be saved for all major modes in the list MODES. If MODES is t or absent, the variable is saved for all major modes. MODES can also be a function of no arguments which returns non-nil whenever the variable should be saved. TYPE should be either the symbol `global', meaning to save the variable globally, the symbol `buffer', meaning to save it per buffer, or the symbol `region', meaning to save it for each submode region. If TYPE has any other value, such as nil, or is absent, the variable is saved globally. If all optional parameters are omitted, the element may be simply VARIABLE instead of \(VARIABLE). It is possible for VARIABLE to be not a symbol but a cons cell of the form \(GETTER . SETTER), thus specifying special functions to set and get the value of the \"variable\". This is used for objects like local maps, syntax tables, etc. which need to be installed in a special way. GETTER should be a function of no arguments, and SETTER a function of one. In this case, even if TYPE and MODES are omitted, the list cannot be flattened--it must be \((GETTER . SETTER)). \"Variables\" of this type cannot be seen with `mmm-get-saved-local'. A single variable may appear more than once in this list, with different modes and/or types. If the same mode appears more than once for the same variable with different types, the behavior is undefined. Changing the value of this variable after MMM Mode has been activated in some buffer may produce unpredictable results. Globally saved variables are saved in the mmm-local-variables property of the mode symbol. Buffer saved variables are saved in the alist `mmm-buffer-saved-locals'. Region saved variables are saved in the mmm-local-variables property of the overlay.") (defvar mmm-buffer-saved-locals () "Stores saved local variables for this buffer, by mode. Each element looks like \(MODE \(VAR VALUE) ...).") (make-variable-buffer-local 'mmm-buffer-saved-locals) (defvar mmm-region-saved-locals-defaults () "Stores saved defaults for region-saved locals, by mode. Each element looks like \(MODE \(VAR VALUE) ...). Used to initialize new submode regions.") (make-variable-buffer-local 'mmm-region-saved-locals-defaults) (defvar mmm-region-saved-locals-for-dominant () "Stores saved region locals for the dominant major mode. The dominant major mode is considered to be one region for purposes of saving region variables. Region-saved variables for submode regions are saved as overlay properties.") (make-variable-buffer-local 'mmm-region-saved-locals-for-dominant) ;;}}} ;;{{{ Submode Faces (defgroup mmm-faces nil "Faces and coloring for submode regions. In general, only background colors should be set, to avoid interfering with font-lock." :group 'mmm) (defcustom mmm-submode-decoration-level 1 "*Amount of coloring to use in submode regions. Should be either 0, 1, or 2, representing None, Low, and High amounts of coloring respectively. * None (0) means to use no coloring at all. * Low (1) means to use `mmm-default-submode-face' for all submode regions \(except for \"non-submode\" regions, i.e. those that are of the primary mode) and `mmm-delimiter-face' for region delimiters. * High (2) means to use different faces for different types of submode regions and delimiters, such as initialization code, expressions that are output, declarations, and so on, as specified by the submode class. The default faces are still used for regions that do not specify a face." :group 'mmm-faces :type '(choice (const :tag "None" 0) (const :tag "Low" 1) (const :tag "High" 2))) (defface mmm-init-submode-face '((t (:background "Pink"))) "Face used for submodes containing initialization code." :group 'mmm-faces) (defface mmm-cleanup-submode-face '((t (:background "Wheat"))) "Face used for submodes containing cleanup code." :group 'mmm-faces) (defface mmm-declaration-submode-face '((t (:background "Aquamarine"))) "Face used for submodes containing declarations." :group 'mmm-faces) (defface mmm-comment-submode-face '((t (:background "SkyBlue"))) "Face used for submodes containing comments and documentation." :group 'mmm-faces) (defface mmm-output-submode-face '((t (:background "Plum"))) "Face used for submodes containing expression that are output." :group 'mmm-faces) (defface mmm-special-submode-face '((t (:background "MediumSpringGreen"))) "Face used for special submodes not fitting any other category." :group 'mmm-faces) (defface mmm-code-submode-face '((t (:background "LightGray"))) "Face used for submodes containing ordinary code." :group 'mmm-faces) (defface mmm-default-submode-face '((t (:background "gray85"))) "Face used for all submodes at decoration level 1. Also used at decoration level 2 for submodes not specifying a type." :group 'mmm-faces) (defface mmm-delimiter-face nil "Face used to mark submode delimiters." :group 'mmm-faces) ;;}}} ;;{{{ Mode Line Format (defcustom mmm-mode-string " MMM" "*String to display in mode line as MMM minor mode indicator." :group 'mmm :type 'string) (defcustom mmm-submode-mode-line-format "~M[~m]" "*Format of the mode-line display when point is in a submode region. ~M is replaced by the name of the primary major mode \(which may be replaced by a combined-mode function, see the info documentation). ~m is replaced by the submode region overlay's `display-name' property, if it has one. Otherwise it is replaced by the mode name of the submode region. If `mmm-primary-mode-display-name' is non-nil, then this variable is used even when point is not in a submode region \(i.e. it is in a primary mode region), with ~m being replaced by the value of that variable." :group 'mmm :type 'string) (defvar mmm-primary-mode-display-name nil "If non-nil, displayed as the primary mode name in the mode line. See also `mmm-buffer-mode-display-name'.") (make-variable-buffer-local 'mmm-primary-mode-display-name) (defvar mmm-buffer-mode-display-name nil "If non-nil, displayed in the mode line instead of the primary mode name, which is then shown next to it as if it were a submode when in a primary mode region, i.e. outside all submode regions.") (make-variable-buffer-local 'mmm-buffer-mode-display-name) (defun mmm-set-mode-line () "Set the mode line display correctly for the current submode, according to `mmm-submode-mode-line-format'." (let ((primary (or mmm-primary-mode-display-name (get mmm-primary-mode 'mmm-mode-name))) (submode (and mmm-current-overlay (or (overlay-get mmm-current-overlay 'display-name) (get mmm-current-submode 'mmm-mode-name))))) (if mmm-buffer-mode-display-name (setq mode-name (mmm-format-string mmm-submode-mode-line-format `(("~M" . ,mmm-buffer-mode-display-name) ("~m" . ,(or submode primary))))) (if submode (setq mode-name (mmm-format-string mmm-submode-mode-line-format `(("~M" . ,primary) ("~m" . ,submode)))) (setq mode-name primary)))) (force-mode-line-update)) ;;}}} ;;{{{ Submode Classes (defvar mmm-classes nil "*List of submode classes that apply to a buffer. Generally set in a file local variables list. Can either be one symbol, or a list of symbols. Automatically buffer-local.") (make-variable-buffer-local 'mmm-classes) (defvar mmm-global-classes '(universal) "*List of submode classes that apply to all buffers. Can be overridden in a file local variables list.") ;;}}} ;;{{{ Modes and Extensions (defcustom mmm-mode-ext-classes-alist nil "Alist of submode classes for major modes and/or file extensions. This variable can now be directly modified. Elements look like \(MODE EXT CLASS), where MODE is a major mode, EXT is a regexp to match a filename such as in `auto-mode-alist', and CLASS is a submode class. CLASS is activated in all buffers in mode MODE \(if non-nil) and whose filenames match EXT \(if non-nil). If both MODE and EXT are nil, CLASS is activated in all buffers. If CLASS is the symbol t, MMM Mode is turned on in all buffers matching MODE and EXT, but no classes are activated. See `mmm-global-mode'." :group 'mmm :type '(repeat (list (symbol :tag "Major Mode") (string :tag "Filename Regexp") (symbol :tag "Class"))) :require 'mmm-mode) (defun mmm-add-mode-ext-class (mode ext class) "Add an element to `mmm-mode-ext-classes-alist', which see. That variable can now be directly modified, so this function is unnecessary. It probably won't go away, though." (add-to-list 'mmm-mode-ext-classes-alist (list mode ext class))) ;;}}} ;;{{{ Preferred Major Modes (defcustom mmm-major-mode-preferences '((perl cperl-mode perl-mode) (javascript javascript-mode c++-mode) (java jde-mode java-mode c++-mode) (css css-mode c++-mode)) "User preferences about what major modes to use. Each element has the form \(LANGUAGE . MODES) where LANGUAGE is the name of a programming language such as `perl' as a symbol, and MODES is a list of possible major modes to use, such as `cperl-mode' or `perl-mode'. The first element of MODES which is `fboundp' is used for submodes of LANGUAGE. The last element of MODES should be a mode which will always be available." :group 'mmm :type '(repeat (cons symbol (repeat (restricted-sexp :match-alternatives (fboundp)))))) (defun mmm-add-to-major-mode-preferences (language mode &optional default) "Set the preferred major mode for LANGUAGE to MODE. This sets the value of `mmm-major-mode-preferences'. If DEFAULT is nil or unsupplied, MODE is added at the front of the list of modes for LANGUAGE. If DEFAULT is non-nil, then it is added at the end. This may be used by packages to ensure that some mode is present, but not override any user-specified mode." (let ((pair (assq language mmm-major-mode-preferences))) (if pair ;; Existing mode preferences (if default (setcdr pair (cons mode (cdr pair))) (setcdr pair (append (cdr pair) (list mode)))) ;; No existing mode preference (add-to-list 'mmm-major-mode-preferences (list language mode))))) (defun mmm-ensure-modename (symbol) "Return SYMBOL if it is a valid submode name, else nil. Valid submode names are either `fboundp' or present as the `car' of an element in `mmm-major-mode-preferences'." (if (or (fboundp symbol) (assq symbol mmm-major-mode-preferences)) symbol nil)) (defun mmm-modename->function (mode) "Convert MODE to a mode function, nil if impossible. Valid submode names are either `fboundp' or present as the `car' of an element in `mmm-major-mode-preferences'. In the latter case, the first `fboundp' element of the `cdr' is returned, or nil if none." (if (fboundp mode) mode (car (remove-if-not #'fboundp (cdr (assq mode mmm-major-mode-preferences)))))) ;;}}} ;;{{{ Delimiter Regions (defcustom mmm-delimiter-mode 'fundamental-mode "Major mode used by default for delimiter regions. Classes are encouraged to override this by providing a delimiter-mode parameter-- see `mmm-classes-alist'." :group 'mmm :type 'function) ;;}}} ;;{{{ Key Bindings (defcustom mmm-mode-prefix-key [(control ?c) ?%] "Prefix key for the MMM Minor Mode Keymap." :group 'mmm :type 'vector) (defcustom mmm-command-modifiers '(control) "List of key modifiers for MMM command keys. The MMM commands in the MMM Mode map, after `mmm-mode-prefix-key', are bound to default keys with these modifiers added. This variable must be set before MMM Mode is loaded to have an effect. It is suggested that the value of this variable be either nil or \(control), as the default keys are either plain keys or have only a meta modifier. The shift modifier is not particularly portable between Emacsen. The values of this variable and `mmm-insert-modifiers' should be disjoint." :group 'mmm :type '(repeat (symbol :tag "Modifier"))) (defcustom mmm-insert-modifiers '() "List of key modifiers for MMM submode insertion keys. When a key pressed after `mmm-mode-prefix-key' has no MMM Mode command binding, and its modifiers include these, then its basic type, plus any modifiers in addition to these, is looked up in classes' :insert specifications. It is suggested that the value of this variable be either nil or \(control), allowing submode classes to specify the presence or absence of the meta modifier. The shift modifier is not particularly portable between Emacsen. The values of `mmm-command-modifiers' and this variable should be disjoint." :group 'mmm :type '(repeat (symbol :tag "Modifier"))) (defcustom mmm-use-old-command-keys nil "Non-nil means to Use the old command keys for MMM Mode. MMM Mode commands then have no modifier while insertion commands have a control modifier, i.e. `mmm-command-modifiers' is set to nil and `mmm-insert-modifiers' is set to \(control). If nil, the values of these variables are as the default, or whatever the user has set them to. This variable must be set before MMM Mode is loaded." :group 'mmm :type 'boolean) (defun mmm-use-old-command-keys () "Use the old command keys \(no control modifer) in MMM Mode." (setq mmm-command-modifiers '() mmm-insert-modifiers '(control))) ;;}}} ;;{{{ MMM Hooks (defcustom mmm-mode-hook () "Hook run when MMM Mode is enabled in a buffer. A hook named mmm--hook is also run, if it exists. For example, `mmm-html-mode-hook' is run whenever MMM Mode is entered with HTML mode the dominant mode. A hook named mmm--submode-hook is run when a submode region of a given mode is created. For example, `mmm-cperl-mode-submode-hook' is run whenever a CPerl mode submode region is created, in any buffer. When this hooks are run, point is guaranteed to be at the start of the newly created submode region. Finally, a hook named mmm--class-hook is run whenever a buffer is first mmm-ified with a given submode class. For example, `mmm-mason-class-hook' is run whenever the `mason' class is first applied in a buffer." :group 'mmm :type 'hook) (defun mmm-run-constructed-hook (body &optional suffix) "Run the hook named `mmm---hook', if it exists. If SUFFIX is nil or unsupplied, run `mmm--hook' instead." (let ((hook (intern-soft (if suffix (format "mmm-%s-%s-hook" body suffix) (format "mmm-%s-hook" body))))) (if hook (run-hooks hook)))) (defun mmm-run-major-hook () (mmm-run-constructed-hook mmm-primary-mode)) (defun mmm-run-submode-hook (submode) (mmm-run-constructed-hook submode "submode")) (defvar mmm-class-hooks-run () "List of submode classes for which hooks have already been run in the current buffer.") (make-variable-buffer-local 'mmm-class-hooks-run) (defun mmm-run-class-hook (class) (unless (member class mmm-class-hooks-run) (mmm-run-constructed-hook class "class") (add-to-list 'mmm-class-hooks-run class))) (defvar mmm-primary-mode-entry-hook nil "Hook run when point moves into a region of the primary mode. Each submode region can have an `entry-hook' property which is run when they are entered, but since primary mode regions have no overlay to store properties, this is a buffer-local variable. N.B. This variable is not a standard Emacs hook. Unlike Emacs' \"local hooks\" it has *no* global value, only a local one. Its value should always be a list of functions \(possibly empty) and never a single function. It may be used with `add-hook', however.") (make-variable-buffer-local 'mmm-primary-mode-entry-hook) ;;}}} ;;{{{ Major Mode Hook (defcustom mmm-major-mode-hook () "Hook run whenever a new major mode is finished starting up. MMM Mode implements this with a hack \(see comments in the source) so that `mmm-global-mode' will function correctly, but makes this hook available so that others can take advantage of the hack as well. Note that file local variables have *not* been processed by the time this hook is run. If a function needs to inspect them, it should also be added to `find-file-hooks'. However, `find-file-hooks' is not run when creating a non-file-based buffer, or when changing major modes in an existing buffer." :group 'mmm :type 'hook) (defun mmm-run-major-mode-hook () (dolist (func mmm-major-mode-hook) (ignore-errors (funcall func)))) ;;}}} ;;{{{ MMM Global Mode ;;; There's a point to be made that this variable should default to ;;; `maybe' (i.e. not nil and not t), because that's what practically ;;; everyone wants. I subscribe, however, to the view that simply ;;; *loading* a lisp extension should not change the (user-visible) ;;; behavior of Emacs, until it is configured or turned on in some ;;; way, which dictates that the default for this must be nil. (defcustom mmm-global-mode nil "*Specify in which buffers to turn on MMM Mode automatically. - If nil, MMM Mode is never enabled automatically. - If t, MMM Mode is enabled automatically in all buffers. - If any other symbol, MMM mode is enabled only in those buffers that have submode classes associated with them. See `mmm-classes' and `mmm-mode-ext-classes-alist' for more information." :group 'mmm :type '(choice (const :tag "Always" t) (const :tag "Never" nil) (other :tag "Maybe" maybe)) :require 'mmm-mode) ;; These are not traditional editing modes, so mmm makes no sense, and ;; can mess things up seriously if it doesn't know not to try. (defcustom mmm-never-modes '( help-mode Info-mode dired-mode comint-mode telnet-mode shell-mode eshell-mode forms-mode ) "List of modes in which MMM Mode is never activated." :group 'mmm :type '(repeat (symbol :tag "Mode"))) ;;}}} ;;{{{ Buffer File Name (defvar mmm-set-file-name-for-modes '(mew-draft-mode) "List of modes for which the temporary buffers MMM creates have a file name. In these modes, this file name is the same as that of the parent buffer. In general, this has been found to cause more problems than it solves, but some modes require it.") ;;}}} ;; NON-USER VARIABLES ;;{{{ Mode Variable (defvar mmm-mode nil "Non-nil means MMM Mode is turned on in this buffer. Do not set this variable directly; use the function `mmm-mode'.") (make-variable-buffer-local 'mmm-mode) ;;}}} ;;{{{ Primary Mode (defvar mmm-primary-mode nil "The primary major mode in the current buffer.") (make-variable-buffer-local 'mmm-primary-mode) ;;}}} ;;{{{ Classes Alist ;; Notes: ;; 1. :parent could be an all-class argument. Same with :keymap. ;; 2. :match-submode really does have to be distinct from :submode, ;; because 'functionp' isn't enough to distinguish which is meant. (defvar mmm-classes-alist nil "Alist containing all defined mmm submode classes. A submode class is a named recipe for parsing a document into submode regions, and sometimes for inserting new ones while editing. Each element of this alist looks like \(CLASS . ARGS) where CLASS is a symbol naming the submode class and ARGS is a list of keyword arguments, called a \"class specifier\". There are a large number of accepted keyword arguments in the class specifier. The argument CLASSES, if supplied, must be a list of other submode class names, or class specifiers, representing other classes to call recursively. The FACE arguments of these classes are overridden by the FACE argument of this class. If the argument CLASSES is supplied, all other arguments to this class are ignored. That is, \"grouping\" classes can do nothing but group other classes. The argument HANDLER, if supplied, also overrides any other processing. It must be a function, and all the arguments are passed to it as keywords, and it must do everything. See `mmm-ify' for what sorts of things it must do. This back-door interface should be cleaned up. The optional argument FACE gives the display face of the submode regions under high decoration (see `mmm-submode-decoration-level'). It must be a valid face. The standard faces used for submode regions are `mmm-*-submode-face' where * is one of `init', `cleanup', `declaration', `comment', `output', `special', or `code'. A more flexible alternative is the argument MATCH-FACE. MATCH-FACE can be a function, which is called with one argument, the form of the front delimiter \(found from FRONT-FORM, below), and should return the face to use. It can also be an alist, with each element of the form \(DELIM . FACE). If neither CLASSES nor HANDLER are supplied, either SUBMODE or MATCH-SUBMODE must be. SUBMODE specifies the submode to use for the submode regions, a symbol such as `cperl-mode' or `emacs-lisp-mode', while MATCH-SUBMODE must be a function to be called immediately after a match is found for FRONT, which is passed one argument, the form of the front delimiter \(found from FRONT-FORM, below), and return a symbol such as SUBMODE would be set to. If MATCH-SUBMODE detects an invalid match--for example a specified mode which is not `fboundp'--it should \(signal 'mmm-no-matching-submode nil). FRONT and BACK are the means to find the submode regions, and can be either buffer positions \(number-or-markers), regular expressions, or functions. If they are absolute buffer positions, only one submode region is created, from FRONT to BACK. This is generally not used in named classes. \(Unnamed classes are created by interactive commands in `mmm-interactive-history'). If FRONT is a regexp, then that regexp is searched for, and the end of its FRONT-MATCH'th match \(or the beginning thereof, if INCLUDE-FRONT is non-nil), plus FRONT-OFFSET, becomes the beginning of the submode region. If FRONT is a function, that function is called instead, and must act somewhat like a search, in that it should start at point, take one argument as a search bound, and set the match data. A similar pattern is followed for BACK \(the search starts at the beginning of the submode region), save that the beginning of its BACK-MATCH'th match \(or the end, if INCLUDE-BACK is non-nil) becomes the end of the submode region, plus BACK-OFFSET. If SAVE-MATCHES is non-nil, then BACK, if it is a regexp, is formatted by replacing strings of the form \"~N\" by the corresponding value of \(match-string n) after matching FRONT. FRONT-MATCH and BACK-MATCH default to zero. They specify which sub-match of the FRONT and BACK regexps to treat as the delimiter. This number will be passed to any calls to `match-beginning' and company. FRONT- and BACK-OFFSET default to 0. In addition to numbers, they can also be functions to call which should move point to the correct position for the beginning or end of the submode region. Common choices include `beginning-of-line' and `end-of-line', and new functions can of course be written. They can also be lists which will be applied in sequence, such as \(end-of-line 1) meaning move to end of line and then forward one character. FRONT-VERIFY and BACK-VERIFY, if supplied, must be functions that inspect the match data to see if a match found by FRONT or BACK respectively is valid. FRONT-DELIM \(resp. BACK-DELIM), if supplied, can take values like those of FRONT-OFFSET \(resp. BACK-OFFSET), specifying the offset from the start \(resp. end) of the match for FRONT \(resp. BACK) to use as the starting \(resp. ending) point for the front \(resp. back) delimiter. If nil, it means not to make a region for the respective delimiter at all. DELIMITER-MODE, if supplied, specifies what submode to use for the delimiter regions, if any. If `nil', the primary mode is used. If not supplied, `mmm-delimiter-mode' is used. FRONT-FACE and BACK-FACE specify faces to use for displaying the delimiter regions, under high decoration. FRONT-FORM and BACK-FORM, if given, must supply a regexp used to match the *actual* delimiter. If they are strings, they are used as-is. If they are functions, they are called and must inspect the match data. If they are lists, their `car' is taken as the delimiter. The default for both is \(regexp-quote \(match-string 0)). The last case--them being a list--is usually used to set the delimiter to a function. Such a function must take 1-2 arguments, the first being the overlay in question, and the second meaning to insert the delimiter and adjust the overlay rather than just matching the delimiter. See `mmm-match-front', `mmm-match-back', and `mmm-end-current-region'. CASE-FOLD-SEARCH, if specified, controls whether the search is case-insensitive. See `case-fold-search'. It defaults to `t'. CREATION-HOOK, if specified, should be a function which is run whenever a submode region is created, with point at the beginning of the new region. One use for it is to set region-saved local variables \(see `mmm-save-local-variables'). INSERT specifies the keypress insertion spec for such submode regions. INSERT's value should be list of elements of the form \(KEY NAME . SPEC). Each KEY should be either a character, a function key symbol, or a dotted list \(MOD . KEY) where MOD is a symbol for a modifier key. The use of any other modifier than meta is discouraged, as `mmm-insert-modifiers' is sometimes set to \(control), and other modifiers are not very portable. Each NAME should be a symbol representing the insertion for that key. Each SPEC can be either a skeleton, suitable for passing to `skeleton-insert' to create a submode region, or a dotted pair \(OTHER-KEY . ARG) meaning to use the skeleton defined for OTHER-KEY but pass it the argument ARG as the `str' variable, possible replacing a prompt string. Skeletons for insertion should have the symbol `_' where point \(or wrapped text) should go, and the symbol `@' in four different places: at the beginning of the front delimiter, the beginning of the submode region, the end of the submode region, and the end of the back delimiter. If END-NOT-BEGIN is non-nil, it specifies that a BACK delimiter cannot begin a new submode region. MATCH-NAME, if supplied, specifies how to determine the \"name\" for each submode region. It must be a string or a function. If it is a function, it is passed the value of FRONT-FORM and must return the name to use. If it is a string, it is used as-is unless SAVE-NAME has a non-nil value, in which case, the string is interpreted the same as BACK when SAVE-MATCHES is non-nil. If MATCH-NAME is not specified, the regions are unnamed. Regions with the same name are considered part of the same chunk of code, and formatted as such, while unnamed regions are not grouped with any others. As a special optimization for insertion, if SKEL-NAME is non-nil, the insertion code will use the user-prompted string value as the region name, instead of going through the normal matching procedure. PRIVATE, if supplied and non-nil, means that this class is a private or internal class, usually one invoked by another class via :classes, and is not for the user to see.") (defun mmm-add-classes (classes) "Add the submode classes CLASSES to `mmm-classes-alist'." (dolist (class classes) (add-to-list 'mmm-classes-alist class))) (defun mmm-add-group (group classes) "Add CLASSES and a \"grouping class\" named GROUP which calls them all. The CLASSES are all made private, i.e. non-user-visible." (mmm-add-classes (mapcar #'(lambda (class) (append class '(:private t))) classes)) (add-to-list 'mmm-classes-alist (list group :classes (mapcar #'first classes)))) (defun mmm-add-to-group (group classes) "Add CLASSES to the \"grouping class\" named GROUP. The CLASSES are all made private, i.e. non-user-visible." (mmm-add-classes (mapcar #'(lambda (class) (append class '(:private t))) classes)) (mmm-set-class-parameter group :classes (append (mmm-get-class-parameter group :classes) (mapcar #'first classes)))) ;;}}} ;;{{{ Version Number (defconst mmm-version "0.4.8" "Current version of MMM Mode.") (defun mmm-version () (interactive) (message "MMM Mode version %s by Michael Abraham Shulman" mmm-version)) ;;}}} ;;{{{ Temp Buffer Name (defvar mmm-temp-buffer-name " *mmm-temp*" "Name for temporary buffers created by MMM Mode.") ;;}}} ;;{{{ Interactive History (defvar mmm-interactive-history nil "History of interactive mmm-ification in the current buffer. Elements are either submode class symbols or class specifications. See `mmm-classes-alist' for more information.") (make-variable-buffer-local 'mmm-interactive-history) (defun mmm-add-to-history (class) (add-to-list 'mmm-interactive-history class)) (defun mmm-clear-history () "Clears history of interactive mmm-ification in current buffer." (interactive) (setq mmm-interactive-history nil)) ;;}}} ;;{{{ Mode/Ext Manipulation (defvar mmm-mode-ext-classes () "List of classes associated with current buffer by mode and filename. Set automatically from `mmm-mode-ext-classes-alist'.") (make-variable-buffer-local 'mmm-mode-ext-classes) (defun mmm-get-mode-ext-classes () "Return classes for current buffer from major mode and filename. Uses `mmm-mode-ext-classes-alist' to find submode classes." (or mmm-mode-ext-classes (setq mmm-mode-ext-classes (mapcar #'third (remove-if-not #'mmm-mode-ext-applies mmm-mode-ext-classes-alist))))) (defun mmm-clear-mode-ext-classes () "Clear classes added by major mode and filename." (setq mmm-mode-ext-classes nil)) (defun mmm-mode-ext-applies (element) (destructuring-bind (mode ext class) element (and (if mode (eq mode ;; If MMM is on in this buffer, use the primary mode, ;; otherwise use the normal indicator. (or mmm-primary-mode major-mode)) t) (if ext (and (buffer-file-name) (save-match-data (string-match ext (buffer-file-name)))) t)))) (defun mmm-get-all-classes (global) "Return a list of all classes applicable to the current buffer. These come from mode/ext associations, `mmm-classes', and interactive history, as well as `mmm-global-classes' if GLOBAL is non-nil." (append mmm-interactive-history (if (listp mmm-classes) mmm-classes (list mmm-classes)) (if global mmm-global-classes ()) (mmm-get-mode-ext-classes))) ;;}}} (provide 'mmm-vars) ;;; mmm-vars.el ends here proofgeneral-4.3~pre130510/contrib/mmm/mmm.texinfo000066400000000000000000002566451214562307500220630ustar00rootroot00000000000000\input texinfo @c %**start of header @setfilename mmm.info @settitle MMM Mode Manual @c %**end of header @syncodeindex vr fn @set MASON_VERSION 0.896 @dircategory GNU Emacs Lisp @direntry * MMM-Mode: (mmm). Multiple Major Modes for Emacs @end direntry @include version.texi @ifinfo This is edition @value{EDITION} of the MMM Mode Manual, last updated @value{UPDATED}. It documents version @value{VERSION} of MMM Mode. Copyright 2000 Michael Abraham Shulman. 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. @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries a 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 Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled ``Copying'' and ``GNU General Public License'' are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end ifinfo @titlepage @title MMM Mode Manual @subtitle Multiple Major Modes for Emacs @subtitle Edition @value{EDITION} @subtitle @value{UPDATED} @author Michael Abraham Shulman @page @vskip 0pt plus 1filll Copyright @copyright{} 2000 Michael Abraham Shulman. 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. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled ``Copying'' and ``GNU General Public License'' are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end titlepage @ifinfo @node Top, Overview, (dir), (dir) @top MMM Mode MMM Mode is a minor mode for Emacs which allows Multiple Major Modes to coexist in a single buffer. This is edition @value{EDITION} of the MMM Mode Manual, last updated @value{UPDATED}, which documents version @value{VERSION} of MMM Mode. @end ifinfo @menu * Overview:: An overview and introduction to MMM Mode. * Basics:: The basics of how to use it. * Customizing:: Customizing how it works to your needs. * Supplied Classes:: The supplied submode classes. * Writing Classes:: Writing your own submode classes. * Indices:: Just that. @detailmenu --- The Detailed Node Listing --- Overview of MMM Mode * Basic Concepts:: A simple explanation of how it works. * Installation:: How to install MMM Mode. * Quick Start:: Getting started using MMM Mode quickly. MMM Mode Basics * MMM Minor Mode:: The Emacs minor mode that manages it all. * Submode Classes:: What they are and how to use them. * Selecting Classes:: How MMM Mode knows what classes to use. * Insertion:: Inserting new submode regions automatically. * Re-parsing:: Re-scanning for submode regions. * Interactive:: Adding submode regions manually. * Global Mode:: Turning MMM Mode on automatically. The MMM Minor Mode * Enabling MMM Mode:: Turning MMM Mode on and off. * MMM Mode Keys:: Default key bindings in MMM Mode. How MMM Mode selects submode classes * File Classes:: Classes for a single file. * Mode-Ext Classes:: Classes for a given mode or extension. * Global Classes:: Classes for all MMM Mode buffers. MMM Global Mode * Major Mode Hook:: Using MMM's Major Mode Hook Customizing MMM Mode * Region Coloring:: Changing or removing background colors. * Preferred Modes:: Choosing which major modes to use. * Mode Line:: What is displayed in the mode line. * Key Bindings:: Customizing the MMM Mode key bindings. * Local Variables:: What local variables are saved for submodes. * Changing Classes:: Changing the supplied submode classes. * Hooks:: How to make MMM Mode run your code. Supplied Submode Classes * Mason:: Mason server-side Perl in HTML. * File Variables:: Elisp code in File Variables. * Here-documents:: Code in shell and Perl here-documents. * Javascript:: Javascript embedded in HTML. * Embedded CSS:: CSS Styles embedded in HTML. * Embperl:: Another syntax for Perl in HTML. * ePerl:: A general Perl-embedding syntax. * JSP:: Java code embedded in HTML. * RPM:: Shell scripts in RPM Spec Files. * Noweb:: Noweb literate programs. Writing Submode Classes * Basic Classes:: Writing a simple submode class. * Paired Delimiters:: Matching paired delimiters. * Region Placement:: Placing the region more accurately. * Submode Groups:: Grouping several classes together. * Calculated Submodes:: Deciding the submode at run-time. * Calculated Faces:: Deciding the display face at run-time. * Insertion Commands:: Inserting regions automatically. * Region Names:: Naming regions for syntax grouping. * Other Hooks:: Running code at arbitrary points. * Delimiters:: Controlling delimiter overlays. * Misc Keywords:: Other miscellaneous options. Indices * Concept Index:: Index of MMM Mode Concepts. * Function Index:: Index of functions and variables. * Keystroke Index:: Index of key bindings in MMM Mode. @end detailmenu @end menu @node Overview, Basics, Top, Top @comment node-name, next, previous, up @chapter Overview of MMM Mode @cindex overview of mmm-mode @cindex mmm-mode, overview of MMM Mode is a minor mode for Emacs which allows Multiple Major Modes to coexist in a single buffer. The name is an abbreviation of `Multiple Major Modes'@footnote{The name is derived from @file{mmm.el} for XEmacs by Gongquan Chen , from which MMM Mode was adapted.}. A major mode is a customization of Emacs for editing a certain type of text, such as code for a specific programming language. @xref{Major Modes, , , emacs, The Emacs Manual}, for details. MMM Mode is a general extension to Emacs which is useful whenever one file contains text in two or more programming languages, or that should be in two or more different modes. For example: @itemize @bullet @item CGI scripts written in any language, from Perl to PL/SQL, may want to output verbatim HTML, and the writer of such scripts may want to use Emacs' html-mode or sgml-mode to edit this HTML code, while remaining in the appropriate programming language mode for the rest of the file. @xref{Here-documents}, for example. @item There are now many ``content delivery systems'' which turn the CGI script idea around and simply add extra commands to an HTML file, often in some programming language, which are interpreted on the server. @xref{Mason}, @xref{Embperl}, @xref{ePerl}, @xref{JSP}. @item HTML itself can also contain embedded languages such as Javascript and CSS styles, for which Emacs has different major modes. @xref{Javascript}, and @xref{Embedded CSS}, for example. @item The idea of ``literate programming'' requires the same file to contain documentation (written as text, html, latex, etc.) and code (in an appropriate programming language). @xref{Noweb}, for example. @item Emacs allows files of any type to contain `local variables', which can include Emacs Lisp code to be evaluated. @xref{File Variables, , , emacs, The Emacs Manual}. It may be easier to edit this code in Emacs Lisp mode than in whatever mode is used for the rest of the file. @xref{File Variables}. @item There are many more possible uses for MMM Mode. RPM spec files can contain shell scripts (@pxref{RPM}). Email or newsgroup messages may contain sample code. And so on. We encourage you to experiment. @end itemize @menu * Basic Concepts:: A simple explanation of how it works. * Installation:: How to install MMM Mode. * Quick Start:: Getting started using MMM Mode quickly. @end menu @node Basic Concepts, Installation, Overview, Overview @comment node-name, next, previous, up @section Basic Concepts @cindex dominant major mode @cindex major mode, dominant @cindex default major mode @cindex major mode, default @cindex submode regions @cindex regions, submode @cindex overlays, submode @cindex submode overlays @cindex mmm-ification The way MMM Mode works is as follows. Each buffer has a @dfn{dominant} or @dfn{default} major mode, which is chosen as major modes normally are: the user can set it interactively, or it can be chosen automatically with `auto-mode-alist' (@pxref{Choosing Modes, , , emacs, The Emacs Manual}). Within the file, MMM Mode creates @dfn{submode regions} within which other major modes are in effect. While the point is in a submode region, the following changes occur: @enumerate @item The local keymap is that of the submode. This means the key bindings for the submode are available, while those of the dominant mode are not. @item The mode line (@pxref{Mode Line, , , emacs, The Emacs Manual}) changes to show which submode region is active. This can be configured; see @ref{Mode Line}. @item The major mode menu, both on the menu bar and the mouse popup, are that of the submode. @item Some local variables of the submode shadow those of the default mode (@pxref{Local Variables}). For the user, this serves to help make Emacs behave as if the submode were the major mode. @item The syntax table and indentation are those of the submode. @item Font-lock (@pxref{Font Lock, , , emacs, The Emacs Manual}) fontifies correctly for the submode. @item The submode regions are highlighted by a background color; see @ref{Region Coloring}. @end enumerate The submode regions are represented internally by Emacs Lisp objects known as @dfn{overlays}. Some of the above are implemented by overlay properties, and others are updated by an MMM Mode function in `post-command-hook'. You don't need to know this to use MMM Mode, but it may make any error messages you come across more understandable. @xref{Overlays, , , elisp, The GNU Emacs Lisp Reference Manual}, for more information on overlays. Because overlays are not saved with a file, every time a file is opened, they must be created. Creating submode regions is occasionally referred to as @dfn{mmm-ification}. (I've never had occasion to pronounce this, but if I did I would probably say `mummification'. Like what they did in ancient Egypt.) You can mmm-ify a buffer interactively, but most often MMM Mode will find and create submode regions automatically based on a buffer's file extension, dominant mode, or local variables. @node Installation, Quick Start, Basic Concepts, Overview @comment node-name, next, previous, up @section Installing MMM Mode MMM Mode has a standard installation process. See the file INSTALL for generic information on this process. To summarize, unpack the archive, @command{cd} to the created MMM Mode directory, type @samp{./configure}, then @samp{make}, then @samp{make install}. If all goes correctly, this will compile the MMM Mode elisp files, install them in your local site-lisp directory, and install the MMM Mode info file @file{mmm.info} in your local info directory. Now you need to configure your Emacs initialization file (usually @file{~/.emacs}) to use MMM Mode. First, Emacs has to know where to find MMM Mode. In other words, the MMM Mode directory has to be in @code{load-path}. This can be done in the parent directory's @file{subdirs.el} file, or in the init file with a line such as: @lisp (add-to-list 'load-path "/path/to/site-lisp/mmm/") @end lisp Once @code{load-path} is configured, MMM Mode must be loaded. You can load all of MMM Mode with the line @lisp (require 'mmm-mode) @end lisp @noindent but if you use MMM Mode only rarely, it may not be desirable to load all of it at the beginning of every editing session. You can load just enough of MMM Mode so it will turn itself on when necessary and load the rest of itself, by using instead the line @lisp (require 'mmm-auto) @end lisp @noindent in your initialization file. One more thing you may want to do right now is to set the variable @code{mmm-global-mode}. If this variable is @code{nil} (the default), MMM Mode will never turn itself on. If it is @code{t}, MMM Mode will turn itself on in every buffer. Probably the most useful value for it, however, is the symbol @code{maybe} (actually, anything that is not @code{nil} and not @code{t}), which causes MMM Mode to turn itself on in precisely those buffers where it would be useful. You can do this with a line such as: @lisp (setq mmm-global-mode 'maybe) @end lisp @noindent in your initialization file. @xref{Global Mode}, for more detailed information. @node Quick Start, , Installation, Overview @comment node-name, next, previous, up @section Getting Started Quickly Perhaps the simplest way to create submode regions is to do it interactively by specifying a region. First you must turn MMM Mode on---say, with @kbd{M-x mmm-mode}---then place point and mark around the area you want to make into a submode region, type @kbd{C-c % C-r}, and enter the desired major mode. @xref{Interactive}, for more details. A better way to add submode regions is by using submode classes, which store a lot of useful information for MMM Mode about how to add and manipulate the regions created. @xref{Submode Classes}, for more details. There are several sample submode classes that come with MMM Mode, which are documented later in this manual. Look through these and determine if one of them fits your needs. If so, I suggest reading the comments on that mode. Then come back here to find out to use it. To apply a submode class to a buffer interactively, turn MMM Mode on as above, then type @kbd{C-c % C-c} and enter the name of the class. Submode regions should be added automatically, if there are any regions in the buffer appropriate to the submode class. If you want a given file to always use a given submode class, you can express this in a file variable: add a line containing the string @samp{-*- mmm-classes: @var{class} -*-} at the top of the file. @xref{File Variables, , , emacs, The Emacs Manual}, for more information and other methods. Now whenever MMM Mode is turned on in that file, it will be mmm-ified according to @var{class}. If @code{mmm-global-mode} is non-nil, then MMM Mode will turn itself on whenever a file with a @code{mmm-classes} local variable is opened. @xref{Global Mode}, for more information. If you want a submode class to apply to @emph{all} files in a certain major mode or with a certain extension, add a line such as this to your initialization file: @lisp (mmm-add-mode-ext-class @var{mode} @var{extension} @var{class}) @end lisp @noindent After this call, any file opened whose name matches the regular expression @var{extension} @emph{and} whose default mode is @var{mode} will be automatically mmm-ified according to @var{class} (assuming @code{mmm-global-mode} is non-nil). If one of @var{extension} or @var{mode} is @code{nil}, a file need only satisfy the other one to be mmm-ified. You can now read the rest of this manual to learn more about how MMM Mode works and how to configure it to your preferences. If none of the supplied submode classes fit your needs, then you can try to write your own. @xref{Writing Classes}, for more information. @node Basics, Customizing, Overview, Top @comment node-name, next, previous, up @chapter MMM Mode Basics This chapter explains the most important parts of how to use MMM Mode. @menu * MMM Minor Mode:: The Emacs minor mode that manages it all. * Submode Classes:: What they are and how to use them. * Selecting Classes:: How MMM Mode knows what classes to use. * Insertion:: Inserting new submode regions automatically. * Re-parsing:: Re-scanning for submode regions. * Interactive:: Adding submode regions manually. * Global Mode:: Turning MMM Mode on automatically. @end menu @node MMM Minor Mode, Submode Classes, Basics, Basics @comment node-name, next, previous, up @section The MMM Minor Mode @cindex mode, mmm minor @cindex minor mode, mmm @cindex mmm minor mode An Emacs minor mode is an optional feature which can be turned on or off in a given buffer, independently of the major mode. @xref{Minor Modes, , , emacs, The Emacs Manual}. MMM Mode is implemented as a minor mode which manages the submode regions. This minor mode must be turned on in a buffer for submode regions to be effective. When activated, the MMM Minor mode is denoted by @samp{MMM} in the mode line (@pxref{Mode Line}). @menu * Enabling MMM Mode:: Turning MMM Mode on and off. * MMM Mode Keys:: Default key bindings in MMM Mode. @end menu @node Enabling MMM Mode, MMM Mode Keys, MMM Minor Mode, MMM Minor Mode @comment node-name, next, previous, up @subsection Enabling MMM Mode @cindex mmm mode, turning on @cindex mmm mode, turning off @cindex turning on mmm mode @cindex turning off mmm mode @cindex mmm mode, enabling @cindex mmm mode, disabling @cindex enabling mmm mode @cindex disabling mmm mode If @code{mmm-global-mode} is non-@code{nil} (@pxref{Global Mode}), then the MMM minor mode will be turned on automatically whenever a file with associated submode classes is opened (@pxref{Selecting Classes}). It is also turned on by interactive mmm-ification (@pxref{Interactive}), although the interactive commands do not have key bindings when it is not on and must be invoked via @kbd{M-x}. You can also turn it on (or off) manually with @kbd{M-x mmm-mode}, in which case it applies all submode classes associated with the buffer. Turning MMM Mode off automatically removes all submode regions from the buffer. @deffn Command mmm-mode @var{arg} Toggle the state of MMM Mode in the current buffer. If @var{arg} is supplied, turn MMM Mode on if and only if @var{arg} is positive. @end deffn @defun mmm-mode-on Turn MMM Mode on unconditionally in the current buffer. @end defun @defun mmm-mode-off Turn MMM Mode off unconditionally in the current buffer. @end defun @defvar mmm-mode This variable represents whether MMM Mode is on in the current buffer. Do not set this variable directly; use one of the above functions. @end defvar @node MMM Mode Keys, , Enabling MMM Mode, MMM Minor Mode @comment node-name, next, previous, up @subsection Key Bindings in MMM Mode @cindex mmm mode key bindings @cindex key bindings in mmm mode @findex mmm-insertion-help @kindex C-c % h When MMM Mode is on, it defines a number of key bindings. By default, these are bound after the prefix sequence @kbd{C-c %}. Minor mode keymaps are supposed to use @kbd{C-c @var{punctuation}} sequences, and I find this one to be a good mnemonic because @samp{%} is used by Mason to denote special tags. This prefix key can be customized; @ref{Key Bindings}. There are two types of key bindings in MMM Mode: @dfn{commands} and @dfn{insertions}. Command bindings run MMM Mode interactive functions to do things like re-parse the buffer or end the current submode region, and are defined statically as normal Emacs key-bindings. Insertion bindings insert submode region skeletons with delimiters into the buffer, and are defined dynamically, according to which submode classes (@pxref{Submode Classes}) are in effect, via a keymap default binding. To distinguish between the two, MMM Mode uses distinct modifier keys for each. By default, command bindings use the control key (e.g. @kbd{C-c % C-b} re-parses the buffer), and insertion bindings do not (e.g. @kbd{C-c % p}, when the Mason class is in effect, inserts a @samp{<%perl>...} region). This makes the command bindings different from in previous versions, however, so the variable @code{mmm-use-old-bindings} is provided. If this variable is set to `t' before MMM Mode is loaded, the bindings will be reversed: insertion bindings will use the control key and command bindings will not. Normally, Emacs gives help on a prefix command if you type @kbd{C-h} after that command (e.g. @kbd{C-x C-h} displays all key bindings starting with @kbd{C-x}). Because of how insertion bindings are implemented dynamically with a default binding, they do not show up when you hit @kbd{C-c % C-h}. For this reason, MMM Mode defines the command @kbd{C-c % h} which displays a list of all currently valid insertion key sequences. If you use the defaults for command and insertion bindings, the @kbd{C-h} and @kbd{h} should be mnemonic. In the rest of this manual, I will assume you are using the defaults for the mode prefix (@kbd{C-c %}) and the command and insertion modifiers. You can customize them, however; @ref{Key Bindings}. @node Submode Classes, Selecting Classes, MMM Minor Mode, Basics @comment node-name, next, previous, up @section Understanding Submode Classes @cindex submode classes @cindex classes, submode A submode class represents a ``type'' of submode region. It specifies how to find the regions, what their delimiters look like, what submode they should be, how to insert them, and how they behave in other ways. It is represented by a symbol, such as @code{mason} or @code{eval-elisp}. For example, in the Mason set of classes, there is one class representing all @samp{<%...%>} inline Perl regions, and one representing regions such as @samp{<%perl>...}, @samp{<%init>...}, and so on. These are different to Mason, but to Emacs they are all just Perl sections, so they are covered by the same submode class. But it would be tedious if whenever we wanted to use the Mason classes, we had to specify both of these. (Actually, this is a simplification: there are some half a dozen Mason submode classes.) So submode classes can also ``group'' others together, and we can refer to the @code{mason} class and mean all of them. The way a submode class is used is to @dfn{apply} it to a buffer. This scans the buffer for regions which should be submode regions according to that class, and also remembers the class for later, so that new submode regions can be inserted and scanned for later. @node Selecting Classes, Insertion, Submode Classes, Basics @comment node-name, next, previous, up @section How MMM Mode selects submode classes Submode classes that apply to a buffer come from three sources: mode/extension-associated classes, file-local classes, and interactive MMM-ification (@pxref{Interactive}). Whenever MMM Mode is turned on in a buffer (@pxref{MMM Minor Mode}, and @ref{Global Mode}), it inspects the value of two variables to determine which classes to automatically apply to the buffer. This covers the first two sources; the latter is covered in a later chapter. @menu * File Classes:: Classes for a single file. * Mode-Ext Classes:: Classes for a given mode or extension. * Global Classes:: Classes for all MMM Mode buffers. @end menu @node File Classes, Mode-Ext Classes, Selecting Classes, Selecting Classes @comment node-name, next, previous, up @subsection File-Local Submode Classes @defvar mmm-classes This variable is always buffer-local when set. Its value should be either a single symbol or a list of symbols. Each symbol represents a submode class that is applied to the buffer. @end defvar @code{mmm-classes} is usually set in a file local variables list. @xref{File Variables, , , emacs, The Emacs Manual}. The easiest way to do this is for the first line of the file to contain the string @samp{-*- mmm-classes: @var{classes} -*-}, where @var{classes} is the desired value of @code{mmm-classes} for the file in question. It can also be done with a local variables list at the end of the file. @node Mode-Ext Classes, Global Classes, File Classes, Selecting Classes @comment node-name, next, previous, up @subsection Submode Classes Associated with Modes and Extensions @defopt mmm-mode-ext-classes-alist This global variable associates certain submode classes with major modes and/or file extensions. Its value is a list of elements of the form @code{(@var{mode} @var{ext} @var{class})}. Any buffer whose major mode is @var{mode} (a symbol) @emph{and} whose file name matches @var{ext} (a regular expression) will automatically have the submode class @var{class} applied to it. If @var{mode} is @code{nil}, then only @var{ext} is considered to determine if a buffer fits the criteria, and vice versa. Thus if both @var{mode} and @var{ext} are nil, then @var{class} is applied to @emph{all} buffers in which MMM Mode is on. Note that @var{ext} can be any regular expression, although its name indicates that it most often refers to the file extension. If @var{class} is the symbol @code{t}, then no submode class is actually applied for this association. However, if @code{mmm-global-mode} is non-@code{nil} and non-@code{t}, MMM Mode will be turned on in matching buffers even if there are no actual submode classes being applied. @xref{Global Mode}. @end defopt @defun mmm-add-mode-ext-class @var{mode} @var{ext} @var{class} This function adds an element to @code{mmm-mode-ext-classes-alist}, associating the submode class @var{class} with the major mode @var{mode} and extension @var{ext}. Older versions of MMM Mode required this function to be used to control the value of @code{mmm-mode-ext-classes-alist}, rather than setting it directly. In this version it is provided purely for convenience and backward compatibility. @end defun @node Global Classes, , Mode-Ext Classes, Selecting Classes @comment node-name, next, previous, up @subsection Globally Applied Classes and the Universal Class In addition to file-local and mode-ext-associated submode classes, MMM Mode also allows you to specify that certain submode classes apply to @emph{all} buffers in which MMM Mode is enabled. @defopt mmm-global-classes This variable's value should be a list of submode classes that apply to all buffers with MMM Mode on. It can be overriden in a file local variables list, such as to disable global class for a specific file. Its default value is @code{(universal)}. @end defopt The default global class is the ``universal class'', which is defined in the file @file{mmm-univ.el} (loaded automatically), and allows the author of text to specify that a certain section of it be in a specific major mode. Thus, for example, when writing an email message that includes sample code, the author can allow readers of the message (who use emacs and MMM) to view the code in the appropriate major mode. The syntax used is @samp{@{%@var{mode}%@} ... @{%/@var{mode}%@}}, where @var{mode} should be the name of the major mode, with or without the customary @samp{-mode} suffix: for example, both @samp{cperl} and @samp{cperl-mode} are acceptable. The universal class also defines an insertion key, @samp{/}, which prompts for the submode to use. @xref{Insertion}. The universal class is most useful when @code{mmm-global-mode} is set to @code{t}; @ref{Global Mode}. @node Insertion, Re-parsing, Selecting Classes, Basics @comment node-name, next, previous, up @section Inserting new submode regions So much for noticing submode regions already present when you open a file. When editing a file with MMM Mode on, you will often want to add a new submode region. MMM Mode provides several facilities to help you. The simplest is to just hit a few keys and have the region and its delimiters inserted for you. Each submode class can define an association of keystrokes with ``skeletons'' to insert a submode region. If there are several submode classes enabled in a buffer, it is conceivable that the keys they use for insertion might conflict, but unlikely as most buffers will not use more than one or two submode classes groups. As an example of how insertion works, consider the Mason classes. In a buffer with MMM Mode enabled and Mason associated, the key sequence @kbd{C-c % p} inserts the following perl section (the semicolon is to prevent CPerl Mode from getting confused---@pxref{Mason}): @example <%perl>-<-; -!- ->- @end example In this schematic representation, the string @samp{-!-} represents the position of point (the cursor), @samp{-<-} represents the beginning of the submode region, and @samp{->-} its end. All insertion keys come after the MMM Mode prefix keys (by default @kbd{C-c %}; @pxref{Key Bindings}) and are by default single characters such as @kbd{p}, @kbd{%}, and @kbd{i}. To avoid confusion, all the MMM Mode commands are bound by default to control characters (after the same prefix keys), such as @kbd{C-b}, @kbd{C-%} and @kbd{C-r}. This is a change from earlier versions of MMM Mode, and can be customized; see @ref{Key Bindings}. To find out what insertion keys are available, consult the documentation for the submode class you are using. If it is one of the classes supplied with MMM Mode, you can find it in this Info file. Because insertion keys are implemented with a ``default binding'' for flexibility, they do not show up in the output of @kbd{C-h m} and cannot be found with @kbd{C-h k}. For this reason, MMM Mode supplies the command @kbd{C-c % h} (@code{mmm-insertion-help} to view the available insertion keys. @node Re-parsing, Interactive, Insertion, Basics @comment node-name, next, previous, up @section Re-Parsing Submode Regions @cindex re-parsing submode regions @cindex parsing submode regions @cindex submode regions, re-parsing @cindex regions, submode, re-parsing @cindex submode regions, clearing @cindex clearing submode regions @cindex regions, submode, clearing @kindex C-c % C-b @kindex C-c % C-g @kindex C-c % C-% @kindex C-c % C-5 @kindex C-c % C-k Describe @code{mmm-parse-buffer}, @code{mmm-parse-region}, @code{mmm-parse-block}, and @code{mmm-clear-current-region}. @node Interactive, Global Mode, Re-parsing, Basics @comment node-name, next, previous, up @section Interactive MMM-ification Functions @cindex interactive mmm-ification @cindex mmm-ification, interactive @cindex mmm-ification by region @cindex mmm-ification by regexp @cindex mmm-ification by class @cindex region, mmm-ification by @cindex regexp, mmm-ification by @cindex class, mmm-ification by @kindex C-c % C-r @kindex C-c % C-c @kindex C-c % C-x @cindex mmm-ification, interactive history @cindex history of interactive mmm-ification @cindex interactive mmm-ification, history of There are several commands you can use to create submode regions interactively, rather than by applying a submode class to a buffer. These commands (in particular, @code{mmm-ify-region}), can be useful when editing a file or email message containing a snippet of code in some other language. Also see @ref{Global Classes}, for an alternate approach to the same problem. @table @kbd @item C-c % C-r Creates a submode region between point and mark. Prompts for the submode to use, which must be a valid Emacs major mode name, such as @code{emacs-lisp-mode} or @code{cperl-mode}. Adds markers to the interactive history. (@code{mmm-ify-region}) @item C-c % C-c Applies an already-defined submode class to the buffer, which it prompts for. Adds this class to the interactive history. (@code{mmm-ify-by-class}) @item C-c % C-x Scans the buffer for submode regions (prompts for the submode) using front and back regular expressions that it also prompts for. Briefly, it starts at the beginning of the buffer and searches for the front regexp. If it finds a match, it searches for the back regexp. If it finds a match for that as well, it makes a submode region between the two matches and continues searching until no more matches are found. Adds the regexps to the interactive history. (@code{mmm-ify-by-regexp}) @end table These commands are also useful when designing a new submode class (@pxref{Submode Classes}). Working with the regexps interactively can make it easier to debug and tune the class before starting to use it on automatic. All these commands also add to value of the following variable. @defvar mmm-interactive-history Stores a history of all interactive mmm-ification that has been performed in the current buffer. This way, for example, the re-parsing functions (@pxref{Re-parsing}) will respect interactively added regions, and the insertion keys for classes that were added interactively are available. @end defvar If for any reason you want to ``wipe the slate clean'', this command should help you. By default, it has no key binding, so you must invoke it with @kbd{M-x mmm-clear-history @key{RET}}. @deffn Command mmm-clear-history Clears all history of interactive mmm-ification in the current buffer. This command does not affect existing submode regions; to remove them, you may want to re-parse the buffer with @kbd{C-c % C-b} (@code{mmm-parse-buffer}). @end deffn @node Global Mode, , Interactive, Basics @comment node-name, next, previous, up @section MMM Global Mode @cindex mode, mmm global @cindex global mmm mode @cindex mmm global mode @vindex mmm-never-modes When a file has associated submode classes (@pxref{Selecting Classes}), you may want MMM Mode to turn itself on and parse that file for submode regions automatically whenever it is opened in an Emacs buffer. The value of the following variable controls when MMM Mode turns itself on automatically. @defopt mmm-global-mode Do not be misled by the fact that this variable's name ends in @samp{-mode}: it is not a simple on/off switch. There are three possible (meanings of) values for it: @code{t}, @code{nil}, and anything else. When this variable is @code{nil}, MMM Mode is never enabled automatically. If it is enabled manually, such as by typing @kbd{M-x mmm-mode}, any submode classes associated with the buffer will still be used, however. When this variable is @code{t}, MMM Mode is enabled automatically in @emph{all} buffers, including those not visiting files, except those whose major mode is an element of @code{mmm-never-modes}. The default value of this variable contains modes such as @code{help-mode} and @code{dired-mode} in which most users would never want MMM Mode, and in which MMM might cause problems. When this variable is neither @code{nil} nor @code{t}, MMM Mode is enabled automatically in all buffers that would have associated submode classes; i.e. only if there would be something for it to do. The value of @code{mmm-never-modes} is still respected, however. Note that this can include buffers not visiting files, if that buffer's major mode is present in @code{mmm-mode-ext-classes-alist} with a @code{nil} value for @var{ext} (@pxref{Mode-Ext Classes}). Submode class values of @code{t} in @code{mmm-mode-ext-classes-alist} cause MMM Mode to be enabled in matching buffers, but supply no submode classes to be applied. @end defopt @menu * Major Mode Hook:: Using MMM's Major Mode Hook @end menu @node Major Mode Hook, , Global Mode, Global Mode @comment node-name, next, previous, up @subsection The Major Mode Hook @cindex hook, major mode @cindex major mode hook @vindex mmm-major-mode-hook This section is intended for users who understand Emacs Lisp and want to know how MMM Global Mode is implemented, and perhaps use the same technique. In fact, MMM Mode exports a hook variable that you can use easily, without understanding any of the details---see below. In order to enable itself in @emph{all} buffers, however, MMM Mode has to hook itself into all major modes. Global Font Lock Mode from the standard Emacs distribution (@pxref{Font Lock, , , emacs, The Emacs Manual}) has a similar problem, and solves it by adding a function to @code{change-major-mode-hook}, which is run by @code{kill-all-local-variables}, which is run in turn by all major mode functions at the @emph{beginning}. This function stores a list of which buffers need fontification. It then adds a different function to @code{post-command-hook}, which checks if the current buffer needs fontification, and if so performs it. MMM Global Mode uses the same technique. In the interests of generality, and for your use, the function that MMM Mode runs in @code{post-command-hook} (@code{mmm-run-major-mode-hook}) is not specific to MMM Mode, but rather runs the hook variable @code{mmm-major-mode-hook}, which by default contains a function (@code{mmm-mode-on-maybe}) which possibly turns MMM Mode on, depending on the value of @code{mmm-global-mode}. Thus, to run another function in all major modes, all you need to do is add it to this hook. For example, the following line in an initialization file will turn on Auto Fill Mode (@pxref{Auto Fill, , , emacs, The Emacs Manual}) in all buffers: @lisp (add-hook 'mmm-major-mode-hook 'turn-on-auto-fill) @end lisp @node Customizing, Supplied Classes, Basics, Top @comment node-name, next, previous, up @chapter Customizing MMM Mode This chapter explains how to customize the appearance and functioning of MMM Mode however you want. @menu * Region Coloring:: Changing or removing background colors. * Preferred Modes:: Choosing which major modes to use. * Mode Line:: What is displayed in the mode line. * Key Bindings:: Customizing the MMM Mode key bindings. * Local Variables:: What local variables are saved for submodes. * Changing Classes:: Changing the supplied submode classes. * Hooks:: How to make MMM Mode run your code. @end menu @node Region Coloring, Preferred Modes, Customizing, Customizing @comment node-name, next, previous, up @section Customizing Region Coloring @cindex faces, submode @cindex submode faces @cindex customizing submode faces @cindex default submode face By default, MMM Mode highlights all submode regions with a background color. There are three levels of this decoration, controlled by the following variable: @defopt mmm-submode-decoration-level This variable controls the level of coloring of submode regions. It should be one of the integers 0, 1, or 2, representing (respectively) none, low, and high coloring. @end defopt No coloring means exactly that. Submode regions have the same background as the rest of the text. This produces the minimal interference with font-lock coloration. In particular, if you want to use background colors for font-lock, this may be a good idea, because the submode highlight, if present, overrides any font-lock background coloring. Low coloring uses the same background color for all submode regions. This color is specified with the face @code{mmm-default-submode-face} (@pxref{Faces, , , emacs, The Emacs Manual}) which can be customized, either through the Emacs ``customize'' interface or using direct Lisp commands such as @code{set-face-background}. Of course, other aspects of the face can also be set, such as the foreground color, bold, underline, etc. These are more likely to conflict with font-lock, however, so only a background color is recommended. High coloring uses multiple background colors, depending on the function of the submode region. The recognized functions and their meanings are as follows: @table @samp @item init Code that is executed at the beginning of (something), as initialization of some sort. @item cleanup Code that is executed at the end of (something), as some sort of clean up facility. @item declaration Code that provides declarations of some sort, perhaps global or local arguments, variables, or methods. @item comment Text that is not executed as code, but instead serves to document the code around it. Submode regions of this function often use a mode such as Text Mode rather than a programming language mode. @item output An expression that is evaluated and its value interpolated into the output produced. @item code Executed code not falling under any other category. @item special Submode regions not falling under any other category, such as component calls. @end table The different background colors are provided by the faces @code{mmm-@var{function}-submode-face}, which can be customized in the same way as @code{mmm-default-submode-face}. @node Preferred Modes, Mode Line, Region Coloring, Customizing @comment node-name, next, previous, up @section Preferred Major Modes Certain of the supplied submode classes know only the language that certain sections are written in, but not what major mode you prefer to use to edit such code. For example, many people prefer CPerl mode over Perl mode; you may have a special mode for Javascript or just use C++ mode. This variable allows you to tell submodes such as Mason (@pxref{Mason}) and Embedded Javascript (@pxref{Javascript}) what major mode to use for the submodes: @defopt mmm-major-mode-preferences The elements of this list are cons cells of the form @code{(@var{language} . @var{mode})}. @var{language} should be a symbol such as @code{perl}, @code{html-js}, or @code{java}, while @var{mode} should be the name of a major mode such as @code{perl-mode}, @code{cperl-mode}, @code{javascript-mode}, or @code{c++-mode}. You probably won't have to set this variable at all; MMM tries to make intelligent guesses about what modes you prefer. For example, if a function called @code{javascript-mode} exists, it is chosen, otherwise @code{c++-mode} is used. Similarly for @code{jde-mode} and @code{java-mode}. @end defopt If you do need to change the defaults, you may find the following function convenient. @defun mmm-set-major-mode-preferences @var{language} @var{mode} &optional @var{default} Set the preferred major mode for LANGUAGE to MODE. If there is already a mode specified for LANGUAGE, and DEFAULT is nil or unsupplied, then it is changed. If DEFAULT is non-nil, then any existing mode is unchanged. This is used by packages to ensure that some mode is present, but not override any user-specified mode. If you are not writing a submode class, you should ignore the third argument. @end defun Thus, for example, to use @code{my-java-mode} for Java code, you would use the following line: @lisp (mmm-set-major-mode-preferences 'java 'my-java-mode) @end lisp @node Mode Line, Key Bindings, Preferred Modes, Customizing @comment node-name, next, previous, up @section Customizing the Mode Line Display By default, when in a submode region, MMM Mode changes the section of the mode line (@pxref{Mode Line, , , emacs, The Emacs Manual}) that normally displays the major mode name---for example, @samp{HTML}---to instead show both the dominant major mode and the currently active submode---for example, @samp{HTML[CPerl]}. You can change this format, however. @defopt mmm-submode-mode-line-format The value of this variable should be a string containing one or both of the escape sequences @samp{~M} and @samp{~m}. The string displayed in the major mode section of the mode line when in a submode is obtained by replacing all occurrences of @samp{~M} with the dominant major mode name and @samp{~m} with the currently active submode name. For example, to display only the currently active submode, set this variable to @samp{~m}. The default value is @samp{~M[~m]}. @end defopt The MMM minor mode also normally displays the string @samp{MMM} in the minor mode section of the mode line to indicate when it is active. You can customize or disable this as well. @defopt mmm-mode-string This string is displayed in the minor mode section of the mode line when the MMM minor mode is active. If nonempty, it should begin with a space to separate the MMM indicator from that of other minor modes. To eliminate the indicator entirely, set this variable to the empty string. @end defopt @node Key Bindings, Local Variables, Mode Line, Customizing @comment node-name, next, previous, up @section Customizing the MMM Mode Key Bindings The default MMM Mode key bindings are explained in @ref{MMM Mode Keys}, and in @ref{Insertion}. There are a couple of ways to customize these bindings. @defopt mmm-mode-prefix-key The value of this variable (default is @kbd{C-c %}) should be a key sequence to use as the prefix for the MMM Mode keymap. Minor modes typically use @kbd{C-c} followed by a punctuation character, but you can change it to any user-available key sequence. To have an effect, this variable should be set before MMM Mode is loaded. @end defopt @defopt mmm-use-old-command-keys When this variable is @code{nil}, MMM Mode commands use the control modifier and insertion keys no modifier. Any other value switches the two, so that @code{mmm-parse-buffer}, for example, is bound to @kbd{C-c % b}, while perl-section insertion in the Mason class is bound to @kbd{C-c % C-p}. This variable should be set before MMM Mode is loaded to have an effect. @end defopt When MMM is loaded, it uses the value of @code{mmm-use-old-command-keys} to set the values of the variables @code{mmm-command-modifiers} and @code{mmm-insert-modifiers}, so if you prefer you can set these variables instead. They should each be a list of key modifiers, such as @code{(control)} or @code{()}. The Meta modifier is used in some of the command and insertion keys, so it should not be used, and the Shift modifier is not particularly portable between Emacsen---if it works for you, feel free to use it. Other modifiers, such as Hyper and Super, are not universally available, but are valid when present. @node Local Variables, Changing Classes, Key Bindings, Customizing @comment node-name, next, previous, up @section Changing Saved Local Variables A lot of the functionality of MMM Mode---that which makes the major mode appear to change---is implemented by saving and restoring the values of local variables, or pseudo-variables. You can customize what variables are saved, and how, with the following variable. @defvar mmm-save-local-variables At its simplest, this is a list each of whose elements is a buffer-local variable whose value is saved and restored for each major mode. Each elements can also, however, be a list whose first element is the variable symbol and whose subsequent elements specify how and where the variable is to be saved. The second element of the list, if present, should be one of the symbols @code{global}, @code{buffer}, or @code{region}. If not present, the default value is @code{global}. The third element, if present, should be a list of major mode symbols in which to save the variable. In the list form, the variable symbol itself can be replaced with a cons cell of two functions, one to get the value and one to set the value. This is called a ``pseudo-variable''. @end defvar Globally saved variables are the same in all (MMM-controlled) buffers and submode regions of each major mode listed in the third argument, or all major modes if it is @code{t} or not present. Buffer-saved variables are the same in all submode regions of a given major mode in each buffer, and region-saved variables can be different for each submode region. Pseudo-variables are used, for example, to save and restore the syntax table (@pxref{Syntax, , , emacs, The Emacs Manual}) and mode keymaps (@pxref{Keymaps, , , emacs, The Emacs Manual}). @node Changing Classes, Hooks, Local Variables, Customizing @comment node-name, next, previous, up @section Changing the Supplied Submode Classes If you need to use MMM with a syntax for which a submode class is not supplied, and you have some facility with Emacs Lisp, you can write your own; see @ref{Writing Classes}. However, sometimes you will only want to make a slight change to one of the supplied submode classes. You can do this, after that class is loaded, with the following functions. @defun mmm-set-class-parameter @var{class} @var{param} @var{value} Set the value of the keyword parameter @var{param} of the submode class @var{class} to @var{value}. @xref{Writing Classes}, for an explanation of the meaning of each keyword parameter. This creates a new parameter if one is not already present in the class. @end defun @defun mmm-get-class-parameter @var{class} @var{param} Get the value of the keyword parameter @var{param} for the submode class @var{class}. Returns @code{nil} if there is no such parameter. @end defun @node Hooks, , Changing Classes, Customizing @comment node-name, next, previous, up @section Hooks Provided by MMM Mode MMM Mode defines several hook variables (@pxref{Hooks, , , emacs, The Emacs Manual}) which are run at different times. The most often used is @code{mmm-major-mode-hook} which is described in @ref{Major Mode Hook}, but there are a couple others. @defvar mmm-mode-hook This normal hook is run whenever MMM Mode is enabled in a buffer. @end defvar @defvar mmm-@var{major-mode}-hook This is actually a whole set of hook variables, a different one for every major mode. Whenever MMM Mode is enabled in a buffer, the corresponding hook variable for the dominant major mode is run. @end defvar @defvar mmm-@var{submode}-submode-hook Again, this is a set of one hook variable per major mode. These hooks are run whenever a submode region of the corresponding major mode is created in any buffer, with point at the start of the new submode region. @end defvar @defvar mmm-@var{class}-class-hook This is a set of one hook variable per submode class. These hooks are run when a submode class is first applied to a given buffer. @end defvar Submode classes also have a @code{:creation-hook} parameter which should be a function to run whenever a submode region is created with that class, with point at the beginning of the submode region. This can be set for supplied submode classes with @code{mmm-set-class-parameter}; @ref{Changing Classes}. @node Supplied Classes, Writing Classes, Customizing, Top @comment node-name, next, previous, up @chapter Supplied Submode Classes This chapter describes the submode classes that are supplied with MMM Mode. @menu * Mason:: Mason server-side Perl in HTML. * File Variables:: Elisp code in File Variables. * Here-documents:: Code in shell and Perl here-documents. * Javascript:: Javascript embedded in HTML. * Embedded CSS:: CSS Styles embedded in HTML. * Embperl:: Another syntax for Perl in HTML. * ePerl:: A general Perl-embedding syntax. * JSP:: Java code embedded in HTML. * RPM:: Shell scripts in RPM Spec Files. * Noweb:: Noweb literate programs. @end menu @node Mason, File Variables, Supplied Classes, Supplied Classes @comment node-name, next, previous, up @section Mason: Perl in HTML Mason is a syntax to embed Perl code in HTML and other documents. See @uref{http://www.masonhq.com} for more information. The submode class for Mason components is called `mason' and is loaded on demand from `mmm-mason.el'. The current Mason class is intended to correctly recognize all syntax valid in Mason @value{MASON_VERSION}. There are insertion keys for most of the available syntax; use @code{mmm-insertion-help} (@kbd{C-c % h} by default) with Mason on to get a list. If you want to have mason submodes automatically in all Mason files, you can use automatic mode and filename associations; the details depend on what you call your Mason components and what major mode you use. @xref{Mode-Ext Classes}. If you use an extension for your Mason files that emacs does not automatically place in your preferred HTML Mode, you will probably want to associate that extension with your HTML Mode as well; @ref{Choosing Modes, , , emacs, The Emacs Manual}. This also goes for ``special'' Mason files such as autohandlers and dhandlers. The Perl mode used is controlled by the user: @xref{Preferred Modes}. The default is to use CPerl mode, if present. Unfortunately, there are also certain problems with CPerl mode in submode regions. (Not to say that the original perl-mode would do any better---it hasn't been much tried.) First of all, the first line of a Perl section is usually indented as if it were a continuation line. A fix for this is to start with a semicolon on the first line. The insertion key commands do this whenever the Mason syntax allows it. @example <%perl>; print $var; @end example In addition, some users have reported that the CPerl indentation sometimes does not work. This problem has not yet been tracked down, however, and more data about when it happens would be helpful. Some people have reported problems using PSGML with Mason. Adding the following line to a @file{.emacs} file should suffice to turn PSGML off and cause emacs to use a simpler HTML mode: @lisp (autoload 'html-mode "sgml-mode" "HTML Mode" t) @end lisp Earlier versions of PSGML may require instead the following fix: @lisp (delete '("\\.html$" . sgml-html-mode) auto-mode-alist) (delete '("\\.shtml$" . sgml-html-mode) auto-mode-alist) @end lisp Other users report using PSGML with Mason and MMM Mode without difficulty. If you don't have problems and want to use PSGML, you may need to replace @code{html-mode} in the suggested code with @code{sgml-html-mode}. (Depending on your version of PSGML, this may not be necessary.) Similarly, if you are using XEmacs and want to use the alternate HTML mode @code{hm--html-mode}, replace @code{html-mode} with that symbol. One problem that crops up when using PSGML with Mason is that even ignoring the special tags and Perl code (which, as I've said, haven't caused me any problems), Mason components often are not a complete SGML document. For instance, my autohandlers often say @example <% $m->call_next %> @end example in which case the actual components contain no doctype declaration, @code{}, @code{}, or @code{}, confusing PSGML. One solution I've found is to use the variable @code{sgml-parent-document} in such incomplete components; try, for example, these lines at the end of a component. @example %# Local Variables: %# sgml-parent-document: ("autohandler" "body" nil ("body")) %# sgml-doctype: "/top/level/autohandler" %# End: @end example This tells PSGML that the current file is a sub-document of the file @file{autohandler} and is included inside a @code{} tag, thus alleviating its confusion. @node File Variables, Here-documents, Mason, Supplied Classes @comment node-name, next, previous, up @section Elisp in a Local Variables List Emacs allows the author of a file to specify major and minor modes to be used while editing that file, as well as specifying values for other local Elisp variables, with a File Variables list. @xref{File Variables, , , emacs, The Emacs Manual}. Since file variables values are Elisp objects (and with the @code{eval} special ``variable'', they are forms to be evaluated), one might want to edit them in @code{emacs-lisp-mode}. The submode class @code{file-variables} allows this, and is suitable for turning on in a given file with @code{mmm-classes}, or in all files with @code{mmm-global-classes}. @node Here-documents, Javascript, File Variables, Supplied Classes @comment node-name, next, previous, up @section Here-documents One of the long-time standard syntaxes for outputting large amounts of code (or text, or HTML, or whatever) from a script (notably shell scripts and Perl scripts) is the here-document syntax: @example print < Test Page END_HTML @end example The @code{here-doc} submode class recognizes this syntax, and can even guess the correct submode to use in many cases. For instance, it would put the above example in @code{html-mode}, noticing the string @samp{HTML} in the name of the here-document. If you use less than evocative here-document names, or if the submode is recognized incorrectly for any other reason, you can tell it explicitly what submode to use. @defopt mmm-here-doc-mode-alist The value of this variable should be an alist, each element a cons pair associating a regular expression to a submode symbol. Whenever a here-document name matches one of these regexps, the corresponding submode is applied. For example, if this variable contains the element @code{("CODE" . cc-mode)}, then any here-document whose name contains the string @samp{CODE} will be put in @code{cc-mode}. The value of this variable overrides any guessing that the @code{here-doc} submode class would do otherwise. @end defopt @node Javascript, Embedded CSS, Here-documents, Supplied Classes @comment node-name, next, previous, up @section Javascript in HTML The submode class @code{html-js} allows for embedding Javascript code in HTML documents. It recognizes both this syntax: @example @end example and this syntax: @example @end example The mode used for Javascript regions is controlled by the user; @xref{Preferred Modes}. @node Embedded CSS, Embperl, Javascript, Supplied Classes @comment node-name, next, previous, up @section CSS embedded in HTML CSS (Cascading Style Sheets) can also be embedded in HTML. The @code{embedded-css} submode class recognizes this syntax: @example @end example It uses @code{css-mode} if present, @code{c++-mode} otherwise. This can be customized: @xref{Preferred Modes}. @node Embperl, ePerl, Embedded CSS, Supplied Classes @comment node-name, next, previous, up @section Embperl: More Perl in HTML Embperl is another syntax for embedding Perl in HTML. See @uref{http://perl.apache.org/embperl} for more information. The @code{embperl} submode class recognizes most if not all of the Embperl embedding syntax. Its Perl mode is also controllable by the user; @xref{Preferred Modes}. @node ePerl, JSP, Embperl, Supplied Classes @comment node-name, next, previous, up @section ePerl: General Perl Embedding Yet another syntax for embedding Perl is called ePerl. See @uref{http://www.engelschall.com/sw/eperl/} for more information. The @code{eperl} submode class handles this syntax, using the Perl mode specified by the user; @xref{Preferred Modes}. @node JSP, RPM, ePerl, Supplied Classes @comment node-name, next, previous, up @section JSP: Java Embedded in HTML JSP (Java Server Pages) is a syntax for embedding Java code in HTML. The submode class @code{jsp} handles this syntax, using a Java mode specified by the user; @xref{Preferred Modes}. The default is @code{jde-mode} if present, otherwise @code{java-mode}. @node RPM, Noweb, JSP, Supplied Classes @comment node-name, next, previous, up @section RPM Spec Files @file{mmm-rpm.el} contains the definition of an MMM Mode submode class for editing shell script sections within RPM (Redhat Package Manager) spec files. It is recommended for use in combination with @file{rpm-spec-mode.el} by Stig Bjørlykke and Steve Sanbeg (@uref{http://www.xemacs.org/~stigb/rpm-spec-mode.el}). Suggested setup code: @lisp (add-to-list 'mmm-mode-ext-classes-alist '(rpm-spec-mode "\\.spec\\'" rpm-sh)) @end lisp Thanks to Marcus Harnisch for contributing this submode class. @node Noweb, , RPM, Supplied Classes @comment node-name, next, previous, up @section Noweb literate programming @file{mmm-noweb.el} contains the definition of an MMM Mode submode class for editing Noweb documents. Most Noweb documents use \LaTeX for the documentation chunks. Code chunks in Noweb are document-specific, and the mode may be set with a local variable setting in the document. The variable @var{mmm-noweb-code-mode} controls the global code chunk mode. Since Noweb files may have many languages in their code chunks, this mode also allows setting the mode by specifying a mode in the first line or two of a code chunk, using the normal Emacs first-line mode setting syntax. Note that this first-line mode setting only matches a single word for the mode name, and does not support the variable name setting of the generalized first file line syntax. @verbatim % -*- mode: latex; mmm-noweb-code-mode: c++; -*- % First chunk delimiter! @ \noweboptions{smallcode} \title{Sample Noweb File} \author{Joe Kelsey\\ \nwanchorto{mailto:bozo@bozo.bozo}{\tt bozo@bozo.bozo}} \maketitle @ \section{Introduction} Normal noweb documentation for the required [[*]] chunk. <<*>>= // C++ mode here! // We might list the program here, or simply included chunks. <> @ %def myfile.cc @ \section{[[myfile.cc]]} This is [[myfile.cc]]. MMM noweb-mode understands code quotes in documentation. <>= // This section is indented separately from previous. @ @ \section{A Perl Chunk} We need a Perl chunk. <>= #!/usr/bin/perl # -*- perl -*- # Each differently named chunk is flowed separately. @ \section{Finish [[myfile.cc]]} When we resume a previously defined chunk, they are indented together. <>= // Pick up where we left off... @ @end verbatim The quoted code chunks inside documentation chunks are given the mode found in the variable @var{mmm-noweb-quote-mode}, if set, or the value in @var{mmm-noweb-code-mode} otherwise. Also, each quoted chunk is set to have a unique name to prevent them from being indented as a unit. Suggested setup code: @lisp (mmm-add-mode-ext-class 'latex-mode "\\.nw\\'" 'noweb) (add-to-list 'auto-mode-alist '("\\.nw\\'" . latex-mode)) @end lisp In mmm-noweb buffers, each differently-named code chunk has a different @code{:name}, allowing all chunks with the same name to get indented together. This mode also supplies special paragraph filling operations for use in documentation areas of the buffer. From a primary-mode (@code{latex-mode, , emacs}) region, pressing @kbd{C-c % C-q} will mark all submode regions with word syntax (@code{mmm-word-other-regions}), fill the current paragraph (@code{(fill-paragraph justify)}), and remove the syntax markings (@code{mmm-undo-syntax-other-regions}). Thanks to Joe Kelsey for contributing this class. @node Writing Classes, Indices, Supplied Classes, Top @comment node-name, next, previous, up @chapter Writing Submode Classes Sometimes (perhaps often) you may want to use MMM with a syntax for which it is suited, but for which no submode is supplied. In such cases you may have to write your own submode class. This chapter briefly describes how to write a submode class, from the basic to the advanced, with examples. @menu * Basic Classes:: Writing a simple submode class. * Paired Delimiters:: Matching paired delimiters. * Region Placement:: Placing the region more accurately. * Submode Groups:: Grouping several classes together. * Calculated Submodes:: Deciding the submode at run-time. * Calculated Faces:: Deciding the display face at run-time. * Insertion Commands:: Inserting regions automatically. * Region Names:: Naming regions for syntax grouping. * Other Hooks:: Running code at arbitrary points. * Delimiters:: Controlling delimiter overlays. * Misc Keywords:: Other miscellaneous options. @end menu @node Basic Classes, Paired Delimiters, Writing Classes, Writing Classes @comment node-name, next, previous, up @section Writing Basic Submode Classes @cindex simple submode classes @cindex submode classes, simple Writing a submode class can become rather complex, if the syntax to match is complicated and you want to take advantage of some of MMM Mode's extra features. But a simple submode class is not particularly difficult to write. This section describes the basics of writing submode classes. Submode classes are stored in the variable @code{mmm-classes-alist}. Each element of this list represents a single submode class. For convenience, the function @code{mmm-add-classes} takes a list of submode classes and adds them all to this alist. Each class is represented by a list containing the class name---a symbol such as @code{mason} or @code{html-js}---followed by pairs of keywords and arguments called a @dfn{class specifier}. For example, consider the specifier for the submode class @code{embedded-css}: @lisp (mmm-add-classes '((embedded-css :submode css :face mmm-declaration-submode-face :front "]*>" :back ""))) @end lisp The name of the submode is @code{embedded-css}, the first element of the list. The rest of the list consists of pairs of keywords (symbols beginning with a colon) such as @code{:submode} and @code{:front}, and arguments, such as @code{css} and @code{"]*>"}. It is the keywords and arguments that specify how the submode works. The order of keywords is not important; all that matters is the arguments that follow them. The three most important keywords are @code{:submode}, @code{:front}, and @code{:back}. The argument following @code{:submode} names the major mode to use in submode regions. It can be either a symbol naming a major mode, such as @code{text-mode} or @code{c++-mode}, or a symbol to look up in @code{mmm-major-mode-preferences} (@pxref{Preferred Modes}) such as @code{css}, as in this case. The arguments following @code{:front} and @code{:back} are regular expressions (@pxref{Regexps, , , emacs, The Emacs Manual}) that should match the delimiter strings which begin and end the submode regions. In our example, CSS regions begin with a @samp{} tag. The argument following @code{:face} specifies the face (background color) to use when @code{mmm-submode-decoration-level} is 2 (high coloring). @xref{Region Coloring}, for a list of canonical available faces. There are many more possible keywords arguments. In the following sections, we will examine each of them and their uses in writing submode classes. @node Paired Delimiters, Region Placement, Basic Classes, Writing Classes @comment node-name, next, previous, up @section Matching Paired Delimiters A simple pair of regular expressions does not always suffice to exactly specify the beginning and end of submode regions correctly. For this reason, there are several other possible keyword/argument pairs which influence the matching process. Many submode regions are marked by paired delimiters. For example, the tags used by Mason (@pxref{Mason}) include @samp{<%init>...} and @samp{<%args>...}. It would be possible to write a separate submode class for each type of region, but there is an easier way: the keyword argument @code{:save-matches}. If supplied and non-nil, it causes the regular expression @code{:back}, before being searched for, to be formatted by replacing all strings of the form @samp{~@var{N}} (where @var{N} is an integer) with the corresponding numbered subexpression of the match for @code{:front}. As an example, here is an excerpt from the @code{here-doc} submode class. @xref{Here-documents}, for more information about this submode. @lisp :front "<<\\([a-zA-Z0-9_-]+\\)" :back "^~1$" :save-matches 1 @end lisp The regular expression for @code{:front} matches @samp{<<} followed by a string of one or more alphanumeric characters, underscores, and dashes. The latter string, which happens to be the name of the here-document, is saved as the first subexpression, since it is surrounded by @samp{\(...\)}. Then, because the value of @code{:save-matches} is present and non-nil, the string @samp{~1} is replaced in the value of @code{:back} by the name of the here-document, thus creating a regular expression to match the correct ending delimiter. @node Region Placement, Submode Groups, Paired Delimiters, Writing Classes @comment node-name, next, previous, up @section Placing Submode Regions Precisely Normally, a submode region begins immediately after the end of the string matching the @code{:front} regular expression and ends immediately before the beginning of the string matching the @code{:back} regular expression. This can be changed with the keywords @code{:include-front} and @code{:include-back}. If their arguments are @code{nil}, or they do not appear, the default behavior is unchanged. But if the argument of @code{:include-front} (respectively, @code{:include-back}) is non-nil, the submode region will begin (respectively, end) immediately before (respectively, after) the string matching the @code{:front} (respectively, @code{:back}) regular expression. In other words, these keywords specify whether or not the delimiter strings are @emph{included} in the submode region. When @code{:front} and @code{:back} are regexps, the delimiter is normally considered to be the entire matched region. This can be changed using the @code{:front-match} and @code{:back-match} keywords. The values of the keywords is a number specifying the submatch. This defaults to zero (specifying the whole regexp). Two more keywords which affect the placement of the region @code{:front-offset} and @code{:back-offset}, which both take integers as arguments. The argument of @code{:front-offset} (respectively, @code{:back-offset}) gives the distance in characters from the beginning (respectively, ending) location specified so far, to the actual point where the submode region begins (respectively, ends). For example, if @code{:include-front} is nil or unsupplied and @code{:front-offset} is 2, the submode region will begin two characters after the end of the match for @code{:front}, and if @code{:include-back} is non-nil and @code{:back-offset} is -1, the region will end one character before the end of the match for @code{:back}. In addition to integers, the arguments of @code{:front-offset} and @code{:back-offset} can be functions which are invoked to move the point from the position specified by the matches and inclusions to the correct beginning or end of the submode region, or lists whose elements are either functions or numbers and whose effects are applied in sequence. To help disentangle these options, here is another excerpt from the @code{here-doc} submode class: @lisp :front "<<\\([a-zA-Z0-9_-]+\\)" :front-offset (end-of-line 1) :back "^~1$" :save-matches 1 @end lisp Here the value of @code{:front-offset} is the list @code{(end-of-line 1)}, meaning that from the end of the match for @code{:front}, go to the end of the line, and then one more character forward (thus to the beginning of the next line), and begin the submode region there. This coincides with the normal behavior of here-documents: they begin on the following line and go until the ending flag. If the @code{:back} should not be able to start a new submode region, set the @code{:end-not-begin} keyword to non-nil. @node Submode Groups, Calculated Submodes, Region Placement, Writing Classes @comment node-name, next, previous, up @section Defining Groups of Submodes Sometimes more than one submode class is required to accurately reflect the behavior of a single type of syntax. For example, Mason has three very different types of Perl regions: blocks bounded by matched tags such as @samp{<%perl>...}, inline output expressions bounded by @samp{<%...%>}, and single lines of code which simply begin with a @samp{%} character. In cases like these, it is possible to specify an ``umbrella'' class, to turn all these classes on or off together. @defun mmm-add-group @var{group} @var{classes} The submode classes @var{classes}, which should be a list of lists, similar to what might be passed to @code{mmm-add-classes}, are added just as by that function. Furthermore, another class named @var{group} is added, which encompasses all the classes in @var{classes}. @end defun Technically, an group class is specified with a @code{:classes} keyword argument, and the subsidiary classes are given a non-nil @code{:private} keyword argument to make them invisible. But in general, all you should ever need to know is how to invoke the function above. @defun mmm-add-to-group @var{group} @var{classes} Adds a list of classes to an already existing group. This can be used, for instance, to add a new quoting definition to @var{html-js} using this example to add the quote characters ``%=%'': @lisp (mmm-add-to-group 'html-js '((js-html :submode javascript :face mmm-code-submode-face :front "%=%" :back "%=%" :end-not-begin t))) @end lisp @end defun @node Calculated Submodes, Calculated Faces, Submode Groups, Writing Classes @comment node-name, next, previous, up @section Calculating the Correct Submode In most cases, the author of a submode class will know in advance what major mode to use, such as @code{text-mode} or @code{c++-mode}. If there are multiple possible modes that the user might desire, then @code{mmm-major-mode-preferences} should be used (@pxref{Preferred Modes}). The function @code{mmm-set-major-mode-preferences} can be used, with a third argument, to ensure than the mode is present. In some cases, however, the author has no way of knowing in advance even what language the submode region will be in. The @code{here-doc} class is one of these. In such cases, instead of the @code{:submode} keyword, the @code{:match-submode} keyword must be used. Its argument should be a function, probably written by the author of the submode class, which calculates what major mode each region should use. It is invoked immediately after a match is found for @code{:front}, and is passed one argument: a string representing the front delimiter. Normally this string is simply whatever was matched by @code{:front}, but this can be changed with the keyword @code{:front-form} (@pxref{Delimiters}). The function should then return a symbol that would be a valid argument to @code{:submode}: either the name of a mode, or that of a language to look up a preferred mode. If it detects an invalid match---for example, the user has specified a mode which is not available---it should @code{(signal 'mmm-no-matching-submode nil)}. Since here-documents can contain code in any language, the @code{here-doc} submode class uses @code{:match-submode} rather than @code{:submode}. The function it uses is @code{mmm-here-doc-get-mode}, defined in @file{mmm-sample.el}, which inspects the name of the here-document for flags indicating the proper mode. For example, this code should probably be in @code{perl-mode} (or @code{cperl-mode}): @example print <} and @code{
    
      
        
        mouseover(
          
        )
        
        
        
          
          
            
          
          
          
        
          
      
    
    
        
        
        
        
      
proofgeneral-4.3~pre130510/etc/proviola/proviola-spp.xsl000066400000000000000000000070231214562307500232220ustar00rootroot00000000000000
    
      
        
        mouseover(
          
        )
        
        
          
	    
          
          
	
      
    
    
        
        
      
proofgeneral-4.3~pre130510/etc/proviola/proviola.xsl000066400000000000000000000064551214562307500224320ustar00rootroot00000000000000
    
      
        
        mouseover(
          
        )
        
        
      
    
    
        
        
      
proofgeneral-4.3~pre130510/etc/testsuite/000077500000000000000000000000001214562307500202335ustar00rootroot00000000000000proofgeneral-4.3~pre130510/etc/testsuite/pg-pgip-test.el000066400000000000000000000010461214562307500230760ustar00rootroot00000000000000;; Tests for pg-pgip.el ;; ;; $Id: pg-pgip-test.el,v 12.0 2011/10/13 10:54:49 da Exp $ (pg-clear-test-suite "pg-pgip") (pg-set-test-suite "pg-pgip") (pg-test-eval (pg-pgip-interpret-value "true" 'boolean) t) (pg-test-eval (pg-pgip-interpret-value "false" 'boolean) nil) (pg-test-eval (pg-pgip-interpret-value "27" 'integer) 27) (pg-test-eval (pg-pgip-interpret-value "true" (list 'choice 'boolean 'integer)) t) (pg-test-eval (pg-pgip-interpret-value "27" (list 'choice 'boolean 'integer)) 27) (provide 'pg-pgip-test) ;; End of `pg-pgip-test.el'proofgeneral-4.3~pre130510/etc/testsuite/pg-test.el000066400000000000000000000063371214562307500221510ustar00rootroot00000000000000;; pg-test.el -- Simple test framework for Proof General. ;; ;; $Id: pg-test.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; (defconst pg-test-buffer "** PG test output **") (defvar pg-test-total-success-count 0) (defvar pg-test-total-fail-count 0) (defvar pg-test-suite-success-count 0) (defvar pg-test-suite-fail-count 0) ;; A test suite is a list of tests. (defvar pg-test-suite-table nil) (defvar pg-current-test-suite nil) (defun pg-set-test-suite (name) (setq pg-current-test-suite name) (unless (assoc name pg-test-suite-table) (setq pg-test-suite-table ;; Add an empty subtable (cons (cons name nil) pg-test-suite-table)))) (defun pg-clear-test-suite (name) (setq pg-test-suite-table (remassoc name pg-test-suite-table))) (defmacro pg-test-eval (expr result) "Add test (equal (eval EXPR) RESULT) to current test suite." (let* ((suite (assoc pg-current-test-suite pg-test-suite-table)) (testnum (length suite)) (name (concat pg-current-test-suite "." (int-to-string testnum)))) (setcdr suite (cons (list name 'eval expr result) (cdr suite))) ;; Result is number of this test in suite testnum)) (defun pg-execute-test (test) (let ((name (car test)) (type (cadr test))) (cond ((eq type 'eval) (let ((expr (nth 2 test)) (goodresult (nth 3 test)) result errorresult exn) (condition-case exn (setq result (eval expr)) ;; FIXME: add negative tests here, that exns _are_ raised. (t (setq errorresult (format " %s failed: error signalled: %s %s\n" name (car exn) (cdr exn))))) (or errorresult (unless (equal goodresult result) (setq errorresult (format " %s failed: exprected result %s, got %s\n" name goodresult result)))) (if errorresult (incf pg-test-suite-fail-count) (incf pg-test-suite-success-count) (setq errorresult (format " %s succeeded.\n" name))) ;; Return string errorresult)) ;; No other types at the moment (t (error "Eek! unrecognized test type.")) ))) (defun pg-execute-test-suite (name) (interactive (list (completing-read "Run test suite: " pg-test-suite-table))) (setq pg-test-suite-success-count 0) (setq pg-test-suite-fail-count 0) (save-excursion (set-buffer (get-buffer-create pg-test-buffer)) (insert "=================================================================\n") (insert "TEST SUITE: " name "\n") (insert "=================================================================\n") (apply 'insert (mapcar 'pg-execute-test (reverse (cdr-safe (assoc name pg-test-suite-table))))) (insert (format "\nTotal successful tests: %s, failed tests: %s\n\n" pg-test-suite-success-count pg-test-suite-fail-count))) (setq pg-test-total-success-count (+ pg-test-suite-success-count pg-test-total-success-count)) (setq pg-test-total-fail-count (+ pg-test-suite-fail-count pg-test-total-fail-count))) (defun pg-execute-all-tests () (interactive) (pop-to-buffer (get-buffer-create pg-test-buffer)) (erase-buffer) (sit-for 0) (setq pg-test-total-success-count 0) (setq pg-test-total-fail-count 0) (mapcar 'pg-execute-test-suite (mapcar 'car pg-test-suite-table))) (provide 'pg-test) ;; End of `pg-test.el' proofgeneral-4.3~pre130510/etc/trac/000077500000000000000000000000001214562307500171335ustar00rootroot00000000000000proofgeneral-4.3~pre130510/etc/trac/README000066400000000000000000000000721214562307500200120ustar00rootroot00000000000000Small tests for regressions. Indexed by trac bug number. proofgeneral-4.3~pre130510/etc/trac/Trac140.v000066400000000000000000000011161214562307500204370ustar00rootroot00000000000000(* Follow example shows bad behaviour in low-level regexp matching for output font locking. See http://proofgeneral.inf.ed.ac.uk/trac/ticket/140. *) (* Note: the bad behaviour seems to be triggered when the pretty-printed output starts to print parameters on a separate line and then gets successively worse. p5 does this for me *) Module Type T. Parameter p1 : nat. Parameter p2 : nat. Parameter p3 : nat. Parameter p4 : nat. Parameter p5 : nat. (* Parameter p6 : nat. Parameter p7 : nat. Parameter p8 : nat. Parameter p9 : nat. *) End T. Time Print Module Type T. proofgeneral-4.3~pre130510/etc/trac/Trac345.thy000066400000000000000000000001711214562307500210050ustar00rootroot00000000000000theory Trac345 imports Main begin (* "a comment" *) -- a comment (* "another comment that PG does not get to" *) end proofgeneral-4.3~pre130510/etc/trac/trac-200.thy000066400000000000000000000004241214562307500211110ustar00rootroot00000000000000(* See trac #200 *) theory Trac200 imports Main begin (* Test simulating sledgehammer asynchronous output *) ML {* Thread.fork (fn () => (OS.Process.sleep (Time.fromSeconds 3); priority "urgent message"), []) *} (* Want to preserve correct term output *) term "x" end proofgeneral-4.3~pre130510/etc/trac/trac-206.thy000066400000000000000000000005531214562307500211220ustar00rootroot00000000000000(* see trac #206 *) theory Trac206 imports Main begin (* The special markup (for terms etc.) is not processed in minibuffer messages. For example: *) ML_command {* warning (Syntax.string_of_typ @{context} @{typ 'a}) *} term "\ x. x" (* Here the decoration for 'a shows up as funny control characters, instead of proper font-lock colouring. *) end proofgeneral-4.3~pre130510/etc/trac/trac-296.v000066400000000000000000000002631214562307500205720ustar00rootroot00000000000000(* PG accepts this as valid though it isn't; see http://proofgeneral.inf.ed.ac.uk/trac/ticket/296 *) Check nat.&!&*\:,.:<*&!)@)$. (* How should this one parse? *) Check 0.99. proofgeneral-4.3~pre130510/etc/trac/trac-307.thy000066400000000000000000000004021214562307500211150ustar00rootroot00000000000000 theory trac307 imports Main begin lemma foo: "Suc x = Suc x" .. (* 2. Go to the simp-command that does not terminate 3. Perform the following actions: Undo, Interrupt, Undo, Next Sync is lost. *) lemma "P (Suc x)" apply (simp add: foo) end proofgeneral-4.3~pre130510/etc/trac/trac-345.thy000066400000000000000000000001501214562307500211170ustar00rootroot00000000000000theory Scratch imports Main begin -- "a comment" ; -- "another comment that PG does not get to" end proofgeneral-4.3~pre130510/etc/trac/trac-346.v000066400000000000000000000002631214562307500205660ustar00rootroot00000000000000Open Scope ... (* is not colorized at all, *) Reserved Notation ... (* has only "Notation" colorized, *) Set Implicit Arguments. (* has only "Set" colorized, in a wrong way. *) proofgeneral-4.3~pre130510/etc/trac/trac109.v000066400000000000000000000001221214562307500205000ustar00rootroot00000000000000(* http://proofgeneral.inf.ed.ac.uk/trac/ticket/109 *) Goal True. idtac "Hello!". proofgeneral-4.3~pre130510/generic/000077500000000000000000000000001214562307500170435ustar00rootroot00000000000000proofgeneral-4.3~pre130510/generic/README000066400000000000000000000006641214562307500177310ustar00rootroot00000000000000Proof 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: README,v 12.0 2011/10/13 10:54:49 da Exp $ proofgeneral-4.3~pre130510/generic/pg-assoc.el000066400000000000000000000031051214562307500211000ustar00rootroot00000000000000;;; pg-assoc.el --- Functions for associated buffers ;; ;; Copyright (C) 1994-2008, 2010 LFCS Edinburgh. ;; Authors: David Aspinall, Yves Bertot, Healfdene Goguen, ;; Thomas Kleymann and Dilip Sequeira ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-assoc.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; ;;; Commentary: ;; ;; Defines an empty mode inherited by modes of the associated buffers. ;; ;;; Code: (require 'proof-utils) (eval-and-compile ; defines proof-universal-keys-only-mode-map at compile time (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))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Return a list of associated buffers ;; ;;;###autoload (defun proof-associated-buffers () "Return a list of the associated buffers. Some may be dead/nil." (list proof-goals-buffer proof-response-buffer proof-trace-buffer proof-thms-buffer)) ;;;###autoload (defun proof-associated-windows () "Return a list of the associated buffers windows. Dead or nil buffers are not represented in the list." (let ((bufs (proof-associated-buffers)) buf wins) (while bufs (setq buf (car bufs)) (if (and buf (get-buffer-window buf)) (setq wins (cons (get-buffer-window buf) wins))) (setq bufs (cdr bufs))) wins)) (provide 'pg-assoc) ;;; pg-assoc.el ends here proofgeneral-4.3~pre130510/generic/pg-autotest.el000066400000000000000000000213571214562307500216510ustar00rootroot00000000000000;;; pg-autotest.el --- Simple testing framework for Proof General ;; ;; Copyright (C) 2005, 2009-11 LFCS Edinburgh, David Aspinall. ;; Authors: David Aspinall ;; ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;;; Commentary: ;; ;; Support for running a series of scripted UI tests. ;; ;; TODO: ;; -- fix failure handling for scriptfile ;; -- add macros for defining test suites ;; -- add more precise functional tests to check results ;; -- add negative tests ;; ;; $Id: pg-autotest.el,v 12.0 2011/10/13 10:54:49 da Exp $ (require 'proof-splash) (setq proof-splash-enable nil) ; prevent splash when testing (require 'proof) (require 'proof-shell) (require 'proof-utils) ;;; Code: (defvar pg-autotest-success t "Flag indicating overall successful state of tests.") (defvar pg-autotest-log t "Value for 'standard-output' during tests.") ;;; Some utilities (defun pg-autotest-find-file (file) "Find FILE (relative to `proof-home-directory')." (let* ((name (concat proof-home-directory file))) (if (file-exists-p name) (find-file name) (error (format "autotest: requested file %s does not exist" name))))) (defun pg-autotest-find-file-restart (file) "Find FILE and make ready to script there." ;; Ensure scripting off; if completely full, will register, otherwise retract (proof-deactivate-scripting-auto) (pg-autotest-find-file file) (goto-char (point-min)) (unless (proof-locked-region-empty-p) ;; Should retract and unregister if was completely full (proof-goto-point)) (proof-shell-wait) (pg-autotest-test-assert-unprocessed file)) ;;; Invoke a test (defmacro pg-autotest-apply (fn &rest args) `(let ((scaffoldfn (intern (concat "pg-autotest-" (symbol-name (quote ,fn)))))) (if (fboundp scaffoldfn) (apply scaffoldfn (list ,@args)) (pg-autotest-message "TEST: %s" (prin1-to-string (cons (quote ,fn) (quote ,args)))) (apply (intern (concat "pg-autotest-test-" (symbol-name (quote ,fn)))) (list ,@args))))) (defmacro pg-autotest (fn &rest args) `(if debug-on-error (pg-autotest-apply ,fn ,@args) (unwind-protect (progn (setq standard-output pg-autotest-log) (condition-case err (pg-autotest-apply ,fn ,@args) (error (progn (setq pg-autotest-success nil) (pg-autotest-message "ERROR %s: %s" (quote ,fn) (prin1-to-string err)))))) (setq standard-output t)))) ;;; Test output and timing (defun pg-autotest-log (file) (save-excursion (find-file file) (setq buffer-save-without-query t) (erase-buffer) (setq pg-autotest-log (current-buffer)) (pg-autotest-message (concat "Tests started " (format-time-string "%D %H:%M"))))) (defun pg-autotest-message (msg &rest args) "Give message MSG in log file output and on display." (let ((fmsg (if args (apply 'format msg args) msg))) (proof-with-current-buffer-if-exists pg-autotest-log (insert fmsg "\n")) (message "%s" fmsg) (redisplay t))) (defun pg-autotest-remark (msg) (pg-autotest-message "\n\nREMARK: %s\n" msg)) (defun pg-autotest-timestart (&optional clockname) "Make a note of current time, named 'local or CLOCKNAME." (put 'pg-autotest-time (or clockname 'local) (current-time))) (defun pg-autotest-timetaken (&optional clockname) "Report time since (startclock CLOCKNAME)." (let* ((timestart (get 'pg-autotest-time (or clockname 'local))) (timetaken (time-subtract (current-time) timestart))) (pg-autotest-message "TIME: %f (%s)" (float-time timetaken) (if clockname (symbol-name clockname) "this test")))) ;;; Start up and exit (defun pg-autotest-start (&optional debug) "Start a session of tests. DEBUG indicates to capture debug output." (when debug (setq debug-on-error t) ; enable in case a test goes wrong (setq proof-general-debug t) ; debug messages from PG (defadvice proof-debug (before proof-debug-to-log (msg &rest args)) "Output the debug message to the test log." (apply 'pg-autotest-message msg args)) (ad-activate 'proof-debug))) (defun pg-autotest-exit () "Exit Emacs returning Unix success 0 if all tests succeeded." (pg-autotest-message (concat "\nTests completed " (format-time-string "%D %H:%M"))) (proof-with-current-buffer-if-exists pg-autotest-log (goto-char (point-max)) (insert "\n\nContents of *Messages*:\n\n") (with-current-buffer (get-buffer "*Messages*") (append-to-buffer pg-autotest-log (point-min) (point-max))) (goto-char (point-max)) (when (get-buffer "*PG Debug*") (insert "\n\nContents of *PG Debug*:\n\n") (proof-with-current-buffer-if-exists (get-buffer "*PG Debug*")) (append-to-buffer pg-autotest-log (point-min) (point-max))) (save-buffer 0)) (kill-emacs (if pg-autotest-success 0 1))) ;;; The test script functions proper (defun pg-autotest-test-process-wholefile (file) "Load FILE and script in one go. An error is signalled if scripting doesn't completely the whole buffer." (pg-autotest-find-file-restart file) (proof-process-buffer) (proof-shell-wait) (pg-autotest-test-assert-processed file)) (defun pg-autotest-test-script-wholefile (file) "Process FILE line-by-line, using `proof-shell-wait'. An error is signalled if scripting doesn't complete." (pg-autotest-find-file-restart file) (save-excursion (let ((making-progress t) last-locked-end) (while making-progress (setq last-locked-end (proof-unprocessed-begin)) (goto-char last-locked-end) (save-current-buffer (condition-case err (proof-assert-next-command-interactive) (error (let ((msg (car-safe (cdr-safe err)))) (unless (string-equal msg ;; normal user error message at end of buffer "At end of the locked region, nothing to do to!") (pg-autotest-message "proof-assert-next-command-interactive hit an error: %s" msg))))) (proof-shell-wait)) (goto-char (proof-queue-or-locked-end)) (setq making-progress (> (point) last-locked-end))))) (pg-autotest-test-assert-processed file)) (defun pg-autotest-test-script-randomjumps (file jumps) "Load FILE and process in it by jumping around randomly JUMPS times. This should be robust against synchronization errors; we test this by completely processing the buffer as the last step." ;; TODO: Additionally some edits are made but undone. (pg-autotest-find-file-restart file) (while (> jumps 0) (let* ((random-point (random (point-max))) (random-edit nil) ; (< 20 (random 100))) (random-thing (random 10))) (cond ((and (eq random-thing 0) (not (proof-locked-region-full-p))) (pg-autotest-message " random jump: processing whole buffer") (proof-process-buffer) (proof-shell-wait) (decf jumps)) ((and (eq random-thing 1) (not (proof-locked-region-empty-p))) (pg-autotest-message " random jump: retracting whole buffer") (proof-retract-buffer) (proof-shell-wait) (decf jumps)) (t (pg-autotest-message " random jump: going to point: %d" random-point)) (goto-char random-point) (unless (if (>= (point) (proof-unprocessed-begin)) (proof-only-whitespace-to-locked-region-p)) (proof-goto-point) (if (eq random-thing 2) (progn ;; interrupt after 2 secs (sit-for 1) (sit-for 1) (when proof-shell-busy (pg-autotest-message " random jump: interrupting prover") (proof-interrupt-process))) (proof-shell-wait)) (decf jumps))))) (unless (proof-locked-region-full-p) (proof-process-buffer) (proof-shell-wait)) (pg-autotest-test-assert-processed file)) (defun pg-autotest-test-retract-file (file) (save-excursion (pg-autotest-find-file file) (proof-retract-buffer) (sit-for 1))) (defun pg-autotest-test-assert-processed (file) "Check that FILE has been fully processed." (save-excursion ;; TODO: also check on included files list (pg-autotest-find-file file) (pg-autotest-test-assert-full))) (defun pg-autotest-test-assert-full () "Check that current buffer has been fully processed." (proof-shell-wait) (unless (proof-locked-region-full-p) (error (format "Locked region in buffer `%s' is not full" (buffer-name))))) (defun pg-autotest-test-assert-unprocessed (file) "Check that FILE has been fully unprocessed." (save-excursion (pg-autotest-find-file file) (unless (proof-locked-region-empty-p) (error (format "Locked region in file `%s' is not empty" file))))) (defun pg-autotest-test-eval (body) "Evaluate given expression for side effect." (eval body)) (defun pg-autotest-test-quit-prover () "Exit prover process." (if (buffer-live-p proof-shell-buffer) (let ((kill-buffer-query-functions nil)) (kill-buffer proof-shell-buffer)) (error "No proof shell buffer to kill"))) (provide 'pg-autotest) ;;; pg-autotest.el ends here proofgeneral-4.3~pre130510/generic/pg-custom.el000066400000000000000000000200651214562307500213060ustar00rootroot00000000000000;;; pg-custom.el --- Proof General per-prover settings ;; ;; Copyright (C) 2008, 2010 LFCS Edinburgh. ;; Author: David Aspinall and others ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-custom.el,v 12.1 2012/01/03 09:36:05 tews Exp $ ;; ;;; Commentary: ;; ;; Prover specific settings and user options. ;; ;; The settings defined here automatically use the current proof ;; assistant symbol as a prefix, i.e. isar-favourites, coq-favourites, ;; or whatever will be defined on evaluation. ;; ;; This file is loaded only by mode stubs defined in `proof-site.el', ;; immediately after `proof-assistant' and similar settings have been ;; configured. ;; ;; WARNING: loading this file without these variables being set will ;; give errors, because defpgcustom calls are expanded to top-level ;; forms that refer to `proof-assistant', which is only properly set ;; when the mode for a proof assistant is started (see mode stub). ;; ;; See also: ;; ;; proof-useropts.el ;; pg-vars.el ;;; Code: (require 'pg-pamacs) ; defpgcustom (require 'pg-vars) ; for proof-next-command-on-new-line (require 'proof-config) ; for proof-toolbar-entries-default (defpgcustom script-indent t "*If non-nil, enable indentation code for proof scripts." :type 'boolean :group 'proof-user-options) (defconst proof-toolbar-entries-default `((state "Display Proof State" "Display the current proof state" t proof-showproof-command) (context "Display Context" "Display the current context" t proof-context-command) (goal "Start a New Proof" "Start a new proof" t nil) (retract "Retract Buffer" "Retract (undo) whole buffer" t t) (undo "Undo Step" "Undo the previous proof command" t t) (delete "Delete Step" "Delete the last proof command" nil t) (next "Next Step" "Process the next proof command" t t) (use "Use Buffer" "Process whole buffer" t t) (goto "Goto Point" "Process or undo to the cursor position" t t) (qed "Finish Proof" "Close/save proved theorem" t nil) (home "Goto Locked End" "Goto end of the last command processed" t t) (find "Find Theorems" "Find theorems" t proof-find-theorems-command) (info "Identifier Info" "Information about identifier" t proof-query-identifier-command) (command "Issue Command" "Issue a non-scripting command" t t) (prooftree "Start/Stop Prooftree" "Start/Stop external proof-tree display" t proof-tree-configured) (interrupt "Interrupt Prover" "Interrupt the proof assistant" t t) (restart "Restart Scripting" "Restart scripting (clear all locked regions)" t t) (visibility "Toggle Visibility" "Show or hide hidden proofs" nil t) (help nil "Proof General manual" t 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 `-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 TOOLBAR-P [VISIBLE-P]). For each TOKEN, we expect an icon with base filename TOKEN, a function proof-toolbar-, and (optionally) a dynamic enabler proof-toolbar--enable-p. If VISIBLE-P is absent, or evaluates to non-nil, the item will appear on the toolbar or menu. If it evaluates to nil, the item is not shown. If MENUNAME is nil, item will not appear on the scripting menu. If TOOLBAR-P is nil, item will not appear on the toolbar. The default value is `proof-toolbar-entries-default' which contains the standard Proof General buttons.") (defpgcustom prog-args nil "Arguments to be passed to `proof-prog-name' to run the proof assistant. If non-nil, will be treated as a list of arguments for `proof-prog-name'. Otherwise `proof-prog-name' will be split on spaces to form arguments. Remark: Arguments are interpreted strictly: each one must contain only one word, with no space (unless it is the same word). For example if the arguments are -x foo -y bar, then the list should be '(\"-x\" \"foo\" \"-y\" \"bar\"), notice that '(\"-x foo\" \"-y bar\") is *wrong*." :type '(repeat string) :group 'proof-shell) (defpgcustom prog-env nil "Modifications to `process-environment' made before running `proof-prog-name'. Each element should be a string of the form ENVVARNAME=VALUE. They will be added to the environment before launching the prover (but not pervasively). For example for coq on Windows you might need something like: \(setq coq-prog-env '(\"HOME=C:\\Program Files\\Coq\\\"))" :type '(repeat string) :group 'proof-shell) (defpgcustom quit-timeout (cond ((eq proof-assistant-symbol 'isar) 45) (t 5)) "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 'number :group 'proof-shell) (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 post suggestions at http://proofgeneral.inf.ed.ac.uk/trac" :type '(repeat string) :group 'prover-config) ;; TODO: not used yet. (defpgcustom tags-program nil "Program to run to generate TAGS table for proof assistant. Currently this setting is UNIMPLEMENTED, changes have no effect." :type 'file :group 'prover-config) ;; TODO: not used yet. Want to move specific enabling of holes modes ;; to generic code (coq.el enables it in script and shell). ;; See http://proofgeneral.inf.ed.ac.uk/trac/ticket/211 (defpgcustom use-holes (eq proof-assistant-symbol 'coq) "Whether or not to use the holes (editing template) mechanism. Enabled by default for Coq. Currently this setting is UNIMPLEMENTED, changes have no effect." :type 'boolean :group 'prover-config) (defpgcustom one-command-per-line (cond ((eq proof-assistant-symbol 'isar) nil) (t t)) "*If non-nil, format for newlines after each command in a script." :type 'boolean :group 'proof-user-options) ;; Contributed modes (defpgcustom maths-menu-enable nil "*Non-nil for Unicode maths menu in Proof General for this assistant." :type 'boolean :set 'proof-set-value :group 'proof-user-options) (defpgcustom unicode-tokens-enable (eq proof-assistant-symbol 'isar) "*Non-nil for using Unicode token input mode in Proof General." :type 'boolean :set 'proof-set-value :group 'proof-user-options) (defpgcustom mmm-enable nil "*Whether to use MMM Mode in Proof General for this assistant. MMM Mode allows multiple modes to be used in the same buffer. If you activate this variable, whether or not you really get MMM support depends on whether your proof assistant supports it." :type 'boolean :set 'proof-set-value :group 'proof-user-options) (provide 'pg-custom) ;;; pg-custom.el ends here proofgeneral-4.3~pre130510/generic/pg-goals.el000066400000000000000000000104461214562307500211030ustar00rootroot00000000000000;; pg-goals.el --- Proof General goals buffer mode. ;; ;; Copyright (C) 1994-2009 LFCS, University of Edinburgh. ;; Authors: David Aspinall, Yves Bertot, Healfdene Goguen, ;; Thomas Kleymann and Dilip Sequeira ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-goals.el,v 12.2 2012/06/04 20:16:04 tews Exp $ ;; ;;; Commentary: ;;; Code: (eval-when-compile (require 'easymenu) ; easy-menu-add, etc (require 'cl) ; incf (require 'span) ; span-* (defvar proof-goals-mode-menu) ; defined by macro below (defvar proof-assistant-menu)) ; defined by macro in proof-menu (require 'pg-assoc) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Goals buffer mode ;; ;;;###autload (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}" (setq proof-buffer-type 'goals) (add-hook 'kill-buffer-hook 'pg-save-from-death nil t) (easy-menu-add proof-goals-mode-menu proof-goals-mode-map) (easy-menu-add proof-assistant-menu proof-goals-mode-map) (proof-toolbar-setup) (buffer-disable-undo) (if proof-keep-response-history (bufhist-mode)) ; history for contents (set-buffer-modified-p nil) (setq cursor-in-non-selected-windows nil)) ;; ;; Menu for goals buffer ;; (proof-eval-when-ready-for-assistant ; proof-aux-menu depends on (easy-menu-define proof-goals-mode-menu proof-goals-mode-map "Menu for Proof General goals buffer." (proof-aux-menu))) ;; ;; Keys for goals buffer ;; (define-key proof-goals-mode-map [q] 'bury-buffer) ;; TODO: use standard Emacs button behaviour here (cf Info mode) (define-key proof-goals-mode-map [mouse-1] 'pg-goals-button-action) (define-key proof-goals-mode-map [C-M-mouse-3] 'proof-undo-and-delete-last-successful-command) ;; ;; The completion of init ;; ;;;###autoload (defun proof-goals-config-done () "Initialise the goals buffer after the child has been configured." (setq font-lock-defaults '(proof-goals-font-lock-keywords))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Goals buffer processing ;; (defun pg-goals-display (string keepresponse) "Display STRING in the `proof-goals-buffer', properly marked up. Converts term substructure markup into mouse-highlighted extents. The response buffer may be cleared to avoid confusing the user with output associated with a previous goals message. This function tries to do that by calling `pg-response-maybe-erase'. If KEEPRESPONSE is non-nil, we assume that a response message corresponding to this goals message has already been displayed before this goals message (see `proof-shell-handle-delayed-output'), so the response buffer should not be cleared." (save-excursion ;; Response buffer may be out of date. It may contain (error) ;; messages relating to earlier proof states ;; Erase the response buffer if need be, maybe removing the ;; window. Indicate it should be erased before the next output. (pg-response-maybe-erase t t nil keepresponse) ;; Erase the goals buffer and add in the new string (set-buffer proof-goals-buffer) (setq buffer-read-only nil) (unless (eq 0 (buffer-size)) (bufhist-checkpoint-and-erase)) ;; Only display if string is non-empty. (unless (string-equal string "") (insert string)) (setq buffer-read-only t) (set-buffer-modified-p nil) ;; Keep point at the start of the buffer. (proof-display-and-keep-buffer proof-goals-buffer (point-min)))) ;; ;; Actions in the goals buffer ;; (defun pg-goals-button-action (event) "Construct a command based on the mouse-click EVENT." (interactive "e") (let* ((posn (event-start event)) (pos (posn-point posn)) (buf (window-buffer (posn-window posn))) (props (text-properties-at pos buf)) (sendback (plist-get props 'sendback))) (cond (sendback (with-current-buffer buf (let* ((cmdstart (previous-single-property-change pos 'sendback nil (point-min))) (cmdend (next-single-property-change pos 'sendback nil (point-max))) (cmd (buffer-substring-no-properties cmdstart cmdend))) (proof-insert-sendback-command cmd))))))) (provide 'pg-goals) ;;; pg-goals.el ends here proofgeneral-4.3~pre130510/generic/pg-movie.el000066400000000000000000000075201214562307500211140ustar00rootroot00000000000000;;; pg-movie.el --- Export a processed script buffer for external replay ;; ;; Copyright (C) 2010 LFCS Edinburgh. ;; Author: David Aspinall and others ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-movie.el,v 12.1 2011/10/17 09:51:26 da Exp $ ;; ;;; Commentary: ;; ;; Given a processed proof script, write out an XML file that ;; contains the buffer contents and the contents of prover ;; output attached to spans. ;; ;; See etc/proviola and http://mws.cs.ru.nl/proviola/ ;; ;; Much more could be done to dump the prettified output from the ;; prover, but this is probably not the right way of doing things in ;; general (one would rather have prover-integrated batch tools). ;; ;; It does give quick and easy results for provers already supported by ;; Proof General though! ;; ;;; Code: (eval-when-compile (require 'span) (require 'unicode-tokens)) (require 'pg-xml) (defconst pg-movie-xml-header "") (defconst pg-movie-stylesheet "") (defun pg-movie-stylesheet-location () (concat proof-home-directory "etc/proviola/proviola-spp.xsl")) (defvar pg-movie-frame 0 "Frame counter for movie.") (defun pg-movie-of-span (span) "Render annotated SPAN in XML." (let* ((tokens (proof-ass unicode-tokens-enable)) (cmd (buffer-substring-no-properties (span-start span) (span-end span))) (tcmd (if tokens ;; no subscripts of course (unicode-tokens-encode-str cmd) cmd)) (helpspan (span-property span 'pg-helpspan)) (resp (when helpspan (span-property helpspan 'response))) (tresp (if resp (if tokens (unicode-tokens-encode-str resp) resp) "")) (type (span-property span 'type)) (class (cond ((eq type 'comment) "comment") ((eq type 'proof) "lemma") ((eq type 'goalsave) "lemma") (t "command"))) (label (span-property span 'rawname)) (frameid (int-to-string pg-movie-frame))) (incf pg-movie-frame) (pg-xml-node frame (list (pg-xml-attr frameNumber frameid)) (list (pg-xml-node command (append (list (pg-xml-attr class class)) (if label (list (pg-xml-attr label label)))) (list tcmd)) (pg-xml-node response nil (list tresp)))))) (defun pg-movie-of-region (start end) (list (pg-xml-node movie nil (list (pg-xml-node film nil (span-mapcar-spans-inorder 'pg-movie-of-span start end 'type)))))) ;;;###autoload (defun pg-movie-export (&optional force) "Export the movie file from the current script buffer. If FORCE, overwrite existing file without asking." (interactive "DP") (setq pg-movie-frame 0) (let ((movie (pg-movie-of-region (point-min) (point-max))) (movie-file-name (concat (file-name-sans-extension (buffer-file-name)) ".xml"))) (with-current-buffer (get-buffer-create "*pg-movie*") (erase-buffer) (insert pg-movie-xml-header "\n") (insert pg-movie-stylesheet "\n") (xml-print movie) (write-file movie-file-name (not force))))) ;;;###autoload (defun pg-movie-export-from (script &optional force) "Export the movie file that results from processing SCRIPT." (interactive "fFile: P") (let ((proof-full-annotation t) ; dynamic (proof-fast-process-buffer t)) (find-file script) (proof-process-buffer) (pg-movie-export force))) ;;;###autoload (defun pg-movie-export-directory (dir extn) "Export movie files from directory DIR with extension EXTN. Existing XML files are overwritten." (interactive "DDirectory: sFile extension: ") (let ((files (directory-files dir t (concat "\\." extn "$")))) (dolist (f files) (pg-movie-export-from f 'force)) (copy-file (pg-movie-stylesheet-location) dir 'overwrite))) (provide 'pg-movie) ;;; pg-movie.el ends here proofgeneral-4.3~pre130510/generic/pg-pamacs.el000066400000000000000000000231751214562307500212450ustar00rootroot00000000000000;;; pg-pamacs.el --- Macros for per-proof assistant configuration ;; ;; Copyright (C) 2010, 2011 LFCS Edinburgh, David Aspinall. ;; ;; Author: David Aspinall ;; Keywords: internal ;;; Commentary: ;; ;; Macros for defining per-assistant customization settings. ;; ;; This 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 more ;; complicated, and less "object-oriented" than the previous approach. ;; ;; There are two mechanisms for accessing generic vars: ;; ;; (proof-ass name) or (proof-assistant-name) ;; ;; (require 'proof-site) ; proof-assitant-symbol (require 'proof-compat) ; pg-custom-undeclare-variable (require 'proof-autoloads) ; proof-debug ;;; Code: (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))) (deflocal proof-buffer-type nil "Symbol for the type of this buffer: 'script, 'shell, 'goals, or 'response.") ;; ;; Main macros ;; (defmacro proof-ass-sym (sym) "Return the symbol for SYM for the current prover. SYM not evaluated. This macro should only be called once a specific prover is known." `(intern (concat (symbol-name proof-assistant-symbol) "-" (symbol-name ',sym)))) (defmacro proof-ass-symv (sym) "Return the symbol for SYM for the current prover. SYM evaluated. This macro should only be invoked once a specific prover is engaged." `(intern (concat (symbol-name proof-assistant-symbol) "-" (symbol-name ,sym)))) (defmacro proof-ass (sym) "Return the value for SYM for the current prover. This macro should only be invoked once a specific prover is engaged." `(symbol-value (intern (concat (symbol-name proof-assistant-symbol) "-" (symbol-name ',sym))))) (defun proof-ass-differs-from-default (sym) "Return non-nil if SYM for current prover differs from its customize standard value." (let ((pasym (proof-ass-symv sym))) (not (equal (eval (car (get pasym 'standard-value))) (symbol-value pasym))))) (defun proof-defpgcustom-fn (sym args) "Define a new customization variable -sym for current proof assistant. Helper for macro `defpgcustom'." (let ((specific-var (proof-ass-symv sym)) (generic-var (intern (concat "proof-assistant-" (symbol-name sym)))) (newargs (if (member :group args) args (append (list :group proof-assistant-internals-cusgrp) args)))) (eval `(defcustom ,specific-var ,@args)) ;; 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))))) (defun undefpgcustom (sym) (let ((specific-var (proof-ass-symv sym)) (generic-var (intern (concat "proof-assistant-" (symbol-name sym))))) (pg-custom-undeclare-variable specific-var) (fmakunbound generic-var))) (defmacro defpgcustom (sym &rest args) "Define a new customization variable -SYM for the current proof assistant. This is intended for defining settings which are useful for any prover, but which the user may require different values of across provers. The function proof-assistant- is also defined, which can be used in the generic portion of Proof General to access the value for the current prover. Arguments are as for `defcustom', which see. If a :group argument is not supplied, the setting will be added to the internal settings for the current prover (named -config)." `(proof-defpgcustom-fn (quote ,sym) (quote ,args))) (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 -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 -SYM as for defun." `(defun ,(proof-ass-symv name) ,arglist ,@args)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Prover-assistant specific customizations ;; which are recorded in `proof-assistant-settings' ;; ;;; autoload for compiled version: used in macro proof-defpacustom ;;;###autoload (defun proof-defpacustom-fn (name val args) "As for macro `defpacustom' but evaluating arguments." (let (newargs setting evalform type descr) (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) :pgipcmd) ;; Construct a function which yields a PGIP string (setq setting `(lambda (x) (pg-pgip-string-of-command (proof-assistant-format ,(cadr args) x)))) (setq args (cdr args))) ((eq (car args) :pggroup) ;; use the group as a prefix to the name, and set a pggroup property on it (setq name (intern (concat (downcase (cadr args)) ":" (symbol-name name)))) (put name 'pggroup (cadr args)) (setq args (cdr args))) ((eq (car args) :pgdynamic) (put name 'pgdynamic (cadr args)) (setq args (cdr args))) ((eq (car args) :type) (setq type (cadr args)) (if (eq (eval type) 'float) (setq type (quote 'number))) ; widget type for defcustom (setq args (cdr args)) (setq newargs (cons type (cons :type newargs)))) (t ; first element, description (setq newargs (cons (car args) newargs)))) (setq args (cdr args))) (setq newargs (reverse newargs)) (setq descr (car-safe newargs)) (unless (and type (or (eq (eval type) 'boolean) (eq (eval type) 'integer) (eq (eval type) 'number) (eq (eval type) 'string))) (error "defpacustom: missing :type keyword or wrong :type value")) ;; Error in case a defpacustom is repeated. (when (assq name proof-assistant-settings) (error "defpacustom: Proof assistant setting %s re-defined!" name)) (eval `(defpgcustom ,name ,val ,@newargs :set 'proof-set-value :group (quote ,proof-assistant-cusgrp))) (cond (evalform (eval `(defpgfun ,name () ,evalform))) (setting (eval `(defpgfun ,name () (proof-assistant-invisible-command-ifposs (proof-assistant-settings-cmd (quote ,name))))))) (setq proof-assistant-settings (cons (list name setting (eval type) descr) proof-assistant-settings)))) ;;;###autoload (defmacro defpacustom (name val &rest args) "Define a setting NAME for the current proof assistant, default VAL. Mainly intended for configuring settings of running provers, which can be changed by sending commands. In this case, NAME stands for the internal setting, flag, etc, for the proof assistant, and a :setting and :type value should be provided. The :type of NAME should be one of 'integer, 'float, 'boolean, 'string. The function `proof-assistant-format' is used to format VAL. This macro invokes the standard Emacs `defcustom' macro, so this also defines a customizable setting inside Emacs. The customization variable is automatically put into the group named after the prover. If NAME corresponds instead to a PG internal setting, then a form :eval to evaluate can be provided instead. Additional properties in the ARGS prop list may include: pggroup string A grouping name for the setting, in case there are many. For example, \"Timing\", \"Tracing\", etc. Used to generate sub-menus in the UI. pgipgcmd string Alternative to :setting. Send a PGIP formatted command based on given string. pgdynamic flag If flag is non-nil, this setting is a dynamic one that is particular to the running instance of the prover. Automatically set by preferences configured from PGIP askprefs message. This macro also extends the `proof-assistant-settings' list." (eval-when-compile (if (boundp 'proof-assistant-symbol) ;; declare variable to compiler to prevent warnings (eval `(defvar ,(proof-ass-sym name) nil "Dummy for compilation.")))) `(proof-defpacustom-fn (quote ,name) (quote ,val) (quote ,args))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Evaluation once proof assistant is known ;; (defmacro proof-eval-when-ready-for-assistant (&rest body) "Evaluate BODY once the proof assistant is determined (possibly now)." `(if (and (boundp 'proof-assistant-symbol) proof-assistant-symbol) (progn ,@body) (add-hook 'proof-ready-for-assistant-hook (lambda () ,@body)))) (provide 'pg-pamacs) ;;; pg-pamacs.el ends here proofgeneral-4.3~pre130510/generic/pg-pbrpm.el000066400000000000000000000536641214562307500211270ustar00rootroot00000000000000;; pg-pbrpm.el --- Proof General - Proof By Rules Pop-up Menu - mode. ;; ;; Copyright (C) 2004 - Universite de Savoie, France. ;; Authors: Jean-Roch SOTTY, Christophe Raffalli ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-pbrpm.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; ;;; Commentary: ;; ;; Analyse the goal buffer to produce a popup menu. ;; ;; NB: this code is currently XEmacs specific ;; (uses make-gui-button, insert-gui-button, make-dialog-frame) ;; ;; da: can you simply use ;; make-button/make-text-button and something like ;; ;; (make-frame '((minibuffer . nil) (menu-bar-lines . 0) (tool-bar-lines . nil))) (declare-function proof-pbrpm-generate-menu "nofile") (declare-function insert-gui-button "nofile") (declare-function make-gui-button "nofile") (declare-function make-dialog-frame "nofile") (declare-function event-point "nofile") (declare-function event-buffer "nofile") (declare-function default-mouse-track-return-dragged-selection "nofile") (declare-function default-mouse-track-drag-hook "nofile") (declare-function mouse-track "nofile") ;; ;;; Code: (require 'span) (eval-when-compile (require 'proof-utils)) (require 'proof) ;;; ;;; Configuration ;;; (defvar pg-pbrpm-use-buffer-menu t "If t, pbrpm will use a menu displayed in a dialog frame instead of a popup menu.") (defvar pg-pbrpm-start-goal-regexp nil "Regexp to match start of goals. Used to produce a table of goal descriptions in `pg-pbrpm-analyse-goal-buffer'.") (defvar pg-pbrpm-start-goal-regexp-par-num nil "Match number for `pg-pbrpm-start-goal-regexp' to extract goal number.") (defvar pg-pbrpm-end-goal-regexp nil "Regexp to match end of goal. Used to produce a table of goal descriptions in `pg-pbrpm-analyse-goal-buffer'.") (defvar pg-pbrpm-start-hyp-regexp nil "Regexp to match start of hypothesis. Used to produce a table of goal descriptions in `pg-pbrpm-analyse-goal-buffer'.") (defvar pg-pbrpm-start-hyp-regexp-par-num nil "Match number for `pg-pbrpm-start-hyp-regexp' to extract hypothesis number. Used to produce a table of goal descriptions in `pg-pbrpm-analyse-goal-buffer'.") (defvar pg-pbrpm-start-concl-regexp nil "Regexp to match start of conclusions. Used to produce a table of goal descriptions in `pg-pbrpm-analyse-goal-buffer'.") (defvar pg-pbrpm-auto-select-regexp nil "Regexp used to select regions of text around point. Matches the region to be returned.") ;;; ;;; Local variables ;;; (defvar pg-pbrpm-buffer-menu nil) (defvar pg-pbrpm-spans nil) (defvar pg-pbrpm-goal-description nil) (defvar pg-pbrpm-windows-dialog-bug nil) (defvar pbrpm-menu-desc nil) (defun pg-pbrpm-erase-buffer-menu () (with-current-buffer pg-pbrpm-buffer-menu (mapc 'span-delete pg-pbrpm-spans) (setq pg-pbrpm-spans nil) (erase-buffer))) (defun pg-pbrpm-menu-change-hook (start end len) (save-excursion (let ((span (span-at (- start 1) 'editable))) (if (not span) (setq span (span-at start 'editable))) (if span (let ((len (- (span-end span) (span-start span)))) (mapc (lambda (sp) (let* ((p1 (span-start sp)) (p2 (span-end sp)) (spl (span-at p1 'pglock))) (span-read-write spl) (goto-char p1) (insert (span-string span)) (delete-region (+ p1 len) (+ p2 len)) (span-read-only spl))) (span-property span 'occurrences))))))) (defun pg-pbrpm-create-reset-buffer-menu () "Create if necessary and erase all text in the buffer menu." (if (or (not pg-pbrpm-buffer-menu) (not (buffer-live-p pg-pbrpm-buffer-menu))) (progn (setq pg-pbrpm-buffer-menu (generate-new-buffer (generate-new-buffer-name "*proof-menu*"))) (set-buffer pg-pbrpm-buffer-menu) ; needs to be fixed here, the mode could be some other prover ; (phox-mode) ; da: proof-mode-for-script should do it ; cr: proof-mode-for-script is not defined in 3.7 ; (if (functionp 'proof-mode-for-script) ; (funcall 'proof-mode-for-shell) (funcall 'proof-mode)) ; da: it's the name of a function, not fn itself. See pg-vars (funcall proof-mode-for-script) (add-hook 'after-change-functions 'pg-pbrpm-menu-change-hook nil t) (pg-pbrpm-erase-buffer-menu))) (set-buffer pg-pbrpm-buffer-menu)) (defun pg-pbrpm-analyse-goal-buffer () "This function analyses the goal buffer and produces a table to find goals and hypothesis. If stores, in the variable pg-pbrpm-goal-description, a list with shape (start-goal end-goal goal-name start-concl hyps ...) with 5 elements for each goal: start-goal: the position of the first char of the goal end-goal: the position of the last char of the goal goal-name: the goal name (or number) start-concl: the position of first char of the conclusion of the goal hyps: the list of hypothesis with the shape: (start-hyp start-hyp-text end-hyp hyp-name ...) with 4 elemets per hypothesis: start-hyp: the position of the first char of the hypothesis (including its name) start-hyp-text: the position of the first char of the hypothesis formula (no name) end-hyp: the position of the last char of the hypothesis hyp-name: then name of the hypothesis." (with-current-buffer proof-goals-buffer (save-excursion (goto-char 0) (let ((goals nil)) (progn (while (search-forward-regexp pg-pbrpm-start-goal-regexp nil t) (let ((hyps nil) (start-goal (match-end 0)) (goal-num (match-string pg-pbrpm-start-goal-regexp-par-num)) (end-goal (search-forward-regexp pg-pbrpm-end-goal-regexp nil t))) (goto-char start-goal) (while (search-forward-regexp pg-pbrpm-start-hyp-regexp end-goal t) (let ((start-hyp (match-beginning 0)) (start-hyp-text (match-end 0)) (hyp-name (match-string pg-pbrpm-start-hyp-regexp-par-num)) (end-hyp (- (if (search-forward-regexp pg-pbrpm-start-hyp-regexp end-goal t) (match-beginning 0) (search-forward-regexp pg-pbrpm-start-concl-regexp end-goal t) (match-beginning 0)) 1))) (goto-char start-hyp-text) (setq hyps (append (list start-hyp start-hyp-text end-hyp hyp-name) hyps)))) (setq goals (append (list start-goal end-goal goal-num (search-forward-regexp pg-pbrpm-start-concl-regexp nil t) hyps) goals)))) (setq pg-pbrpm-goal-description goals)))))) (add-hook 'proof-shell-handle-delayed-output-hook 'pg-pbrpm-analyse-goal-buffer) ;;--------------------------------------------------------------------------;; ;; the Rules Popup Menu functions ;;--------------------------------------------------------------------------;; (defun pg-pbrpm-button-action (event) "This function is bound to a CTRL-RightClick in the Proof General goals buffer." (interactive "e") (save-excursion (pg-pbrpm-build-menu event (point-marker) (mark-marker)) ) ) (defun pg-pbrpm-exists (f l0) (if (null l0) nil (or (funcall f (car l0)) (pg-pbrpm-exists f (cdr l0))))) (defun pg-pbrpm-eliminate-id (acc l) (if (null l) (reverse acc) (if (pg-pbrpm-exists (lambda (x) (string= (car x) (car (car l)))) acc) (pg-pbrpm-eliminate-id acc (cdr l)) (pg-pbrpm-eliminate-id (cons (car l) acc) (cdr l))))) (defun pg-pbrpm-build-menu (event start end) "Build a Proof By Rules pop-up menu according to the state of the proof, the event and a selected region (between the start and end markers). The prover command is processed via pg-pbrpm-run-command." ;; first, run the prover specific (name, rule)'s list generator (let ((click-info (pg-pbrpm-process-click event start end))) ; retrieve click informations (if click-info (let ((pbrpm-list (pg-pbrpm-eliminate-id nil (mapcar 'cdr (sort (proof-pbrpm-generate-menu click-info (pg-pbrpm-process-regions-list)) (lambda (l1 l2) (< (car l1) (car l2))))))) (count 0)) ;; retrieve selected region informations ;; then make that list a menu description (if pbrpm-list (if (not pg-pbrpm-use-buffer-menu) (progn (setq pbrpm-menu-desc '("PBRPM-menu")) (while pbrpm-list (let* ((pbrpm-list-car (pop pbrpm-list)) (description (pop pbrpm-list-car)) (command (concat "(*" description "*)\n" (pop pbrpm-list-car)))) (setq pbrpm-menu-desc (append pbrpm-menu-desc (list (vector description (list 'pg-pbrpm-run-command (list command nil nil)))))))) ;; finally display the pop-up-menu (popup-menu pbrpm-menu-desc)) (pg-pbrpm-create-reset-buffer-menu) (while pbrpm-list (let* ((pbrpm-list-car (pop pbrpm-list)) (description (pop pbrpm-list-car)) (command (pop pbrpm-list-car)) (act (pop pbrpm-list-car)) (pos (point))) (setq count (+ 1 count)) (insert " ") (insert description) (insert " ") ; hack for renaming of last name (let ((spans (pg-pbrpm-setup-span pos (point)))) (insert-gui-button (make-gui-button (concat (int-to-string count) ")") 'pg-pbrpm-run-command (list command act spans)) pos)) (insert "\n"))) (insert-gui-button (make-gui-button "Cancel" (lambda (n) (pg-pbrpm-erase-buffer-menu) (delete-frame)) nil)) ;; needs to be fixed for other prover than phox ;; da: I've removed code here, we should simply keep this ;; buffer with font lock on. (mapc 'span-read-only pg-pbrpm-spans) (make-dialog-frame '(width 80 height 30))) (beep)))))) (defun pg-pbrpm-setup-span (start end) "Set up the span in the menu buffer." (save-excursion (let ((rank 0) (spans nil) (allspan (span-make start end))) (while (< start end) (goto-char start) (let ((pos (search-forward "\\[" end 0)) (goalnum 0)) (if pos (progn (delete-char -2) (setq end (- end 2)) (setq pos (- pos 2)))) ; (message "make l span %d %d" start (if pos pos end)) (let ((span (span-make start (if pos pos end)))) (span-set-property span 'pglock t) (setq pg-pbrpm-spans (cons span pg-pbrpm-spans))) (if pos (progn (search-forward "\\]" end) (delete-char -2) (setq end (- end 2)) (setq start (point)) (save-excursion (goto-char pos) (if (search-forward-regexp "\\\\|\\([0-9]\\)" start t) (progn (setq goalnum (string-to-number (match-string 1))) (let ((len (- (match-end 0) (match-beginning 0)))) (setq end (- end len)) (setq start (- start len))) (delete-region (match-beginning 0) (match-end 0))))) (let* ((span (span-make pos start)) (str (concat "\\{" (span-string span) (if (= goalnum 0) "" (concat "\\|" (int-to-string goalnum))) "\\}")) (len (- start pos)) (occurrences nil)) (save-excursion (goto-char pos) (while (search-forward str end t) (setq end (+ (- end (- (match-end 0) (match-beginning 0))) len)) (delete-region (match-beginning 0) (match-end 0)) (insert (span-string span)) ; (message "span o %d %d" (match-beginning 0) (+ (match-beginning 0) len)) (setq occurrences (cons (span-make (match-beginning 0) (+ (match-beginning 0) len)) occurrences)))) ; (message "make w span %d %d %s %d" pos start (span-string span) goalnum) (setq spans (cons span spans)) (setq rank (+ rank 1)) (span-set-property span 'editable t) (span-set-property span 'rank rank) (span-set-property span 'goalnum goalnum) (span-set-property span 'occurrences occurrences) (span-set-property span 'original-text (span-string span)) (span-set-property span 'face 'pg-pbrpm-menu-input-face))) (setq start (if pos pos end))))) (cons allspan (sort (reverse spans) (lambda (sp1 sp2) (< (span-property sp1 'goalnum) (span-property sp1 'goalnum)))))))) (defun pg-pbrpm-run-command (args) "Insert COMMAND into the proof queue and then run it. -- adapted from proof-insert-pbp-command --" (let* ((command (pop args)) (act (pop args)) (spans (pop args)) (allspan (pop spans))) (if act (setq command (apply act command spans nil))) (if allspan (setq command (concat "(* " (span-string allspan) " *)\n" command "."))) ; delete buffer (and its span) after applying "act" (pg-pbrpm-erase-regions-list) (if pg-pbrpm-use-buffer-menu (progn (pg-pbrpm-erase-buffer-menu) (delete-frame))) ;; da: why not just this? (pop-to-buffer proof-script-buffer) (let ((proof-next-command-on-new-line t)) (proof-insert-pbp-command command)))) ;; (let (span) ;; (pop-to-buffer proof-script-buffer) ;; (proof-goto-end-of-locked) ;; (proof-activate-scripting nil 'advancing) ;; (insert (concat "\n" command)) ;; (setq span (span-make (proof-unprocessed-begin) (point))) ;; ; TODO : define the following properties for PBRPM, I don't understand their use ... ;; (span-set-property span 'type 'pbp) ;; (span-set-property span 'cmd command) ;; (proof-start-queue (proof-unprocessed-begin) (point) ;; (list (list span (list command) ;; 'proof-done-advancing)))))) ;;--------------------------------------------------------------------------;; ;; Click Informations extractors ;;--------------------------------------------------------------------------;; (defun pg-pbrpm-get-pos-info (pos) "Get position information for POS. Returns (n . s) where n is the goal name s if either the hypothesis name, \"none\" (for the conclusion), or \"whole\" in strange cases." (let ((l pg-pbrpm-goal-description) (found nil) start-goal end-goal goal-name start-concl hyps the-goal-name the-click-info start-hyp end-hyp start-hyp-text hyp-name) (while (and pos l (not found)) (setq start-goal (car l)) (setq end-goal (cadr l)) (setq goal-name (caddr l)) (setq start-concl (cadddr l)) (setq hyps (car (cddddr l))) (setq l (cdr (cddddr l))) (if (and (<= start-goal pos) (<= pos end-goal)) (progn (setq found t) (setq the-goal-name goal-name)))) (if found (progn (if (<= start-concl pos) (setq the-click-info "none") (setq found nil) (while (and hyps (not found)) (setq start-hyp (car hyps)) (setq start-hyp-text (cadr hyps)) (setq end-hyp (caddr hyps)) (setq hyp-name (cadddr hyps)) (setq hyps (cddddr hyps)) (if (and (<= start-hyp pos) (<= pos end-hyp)) (progn (setq found t) (setq the-click-info hyp-name)))) (if (not found) (setq the-click-info "whole"))) (cons the-goal-name the-click-info))))) (defun pg-pbrpm-get-region-info (start end) "Get position info for a region, if region is within a single position. See `pg-pbrpm-get-pos-info'." (let ((r1 (pg-pbrpm-get-pos-info start)) (r2 (pg-pbrpm-get-pos-info end))) ;; da: this said start, surely wrong? (if (and r1 r2 (string-equal (car r1) (car r2))) (if (string-equal (cdr r1) (cdr r2)) r1 (cons (car r1) "whole")) nil))) (defun pg-pbrpm-auto-select-around-point () "Extract some text arround point, according to `pg-pbrpm-auto-select-regexp'. If no match found, return the empty string." (save-excursion (let ((pos (point))) (beginning-of-line) (block 'loop (while (< (point) pos) (unless (search-forward-regexp pg-pbrpm-auto-select-regexp nil t) (return-from 'loop "")) (if (and (<= (match-beginning 0) pos) (<= pos (match-end 0))) (return-from 'loop (match-string 0)))) (return-from 'loop ""))))) (defun pg-pbrpm-translate-position (buffer pos) "return pos if buffer is goals-buffer otherwise, return the point position in the goal buffer" (if (eq proof-goals-buffer buffer) pos (with-current-buffer proof-goals-buffer (point)))) (defun pg-pbrpm-process-click (event start end) "Returns the list of informations about the click needed to call generate-menu. EVENT is an event." (save-excursion (save-window-excursion (mouse-set-point event) (let* ((pos (event-point event)) (buffer (event-buffer event)) (r (pg-pbrpm-get-pos-info (pg-pbrpm-translate-position buffer pos)))) (if r (list (string-to-number (car r)) ; should not be an int for other prover (if (eq proof-goals-buffer buffer) (cdr r) (pg-pbrpm-auto-select-around-point)) (if (and start end (eq proof-goals-buffer buffer) (<= (marker-position start) pos) (<= pos (marker-position end))) (pg-pbrpm-region-expression buffer (marker-position start) (marker-position end)) (pg-pbrpm-auto-select-around-point)))))))) ;;--------------------------------------------------------------------------;; ;; Selected Region informations extractors ;;--------------------------------------------------------------------------;; (defvar pg-pbrpm-remember-region-selected-region nil) (defvar pg-pbrpm-regions-list nil) (defun pg-pbrpm-erase-regions-list () (mapc (lambda (span) (span-delete span)) pg-pbrpm-regions-list) (setq pg-pbrpm-regions-list nil) nil) (add-hook 'mouse-track-drag-up-hook (lambda (event count) (if (not (member 'control (event-modifiers event))) (pg-pbrpm-erase-regions-list)))) (defun pg-pbrpm-filter-regions-list () (let ((l pg-pbrpm-regions-list)) (setq pg-pbrpm-regions-list nil) (mapc (lambda (span) (if (span-live-p span) (setq pg-pbrpm-regions-list (cons span pg-pbrpm-regions-list)) (span-delete span))) l))) (defface pg-pbrpm-multiple-selection-face (proof-face-specs (:background "orange") (:background "darkorange") (:italic t)) "*Face for showing (multiple) selection." :group 'proof-faces) (defface pg-pbrpm-menu-input-face (proof-face-specs (:background "Gray80") (:background "Gray65") (:italic t)) "*Face for showing (multiple) selection." :group 'proof-faces) (defun pg-pbrpm-do-remember-region (start end) (pg-pbrpm-filter-regions-list) (if (and start end (not (eq start end))) ; if a region is selected (let ((span (span-make start end)) (found nil)) (setq pg-pbrpm-regions-list (reverse (mapcar (lambda (oldspan) (let ((oldstart (span-start oldspan)) (oldend (span-end oldspan))) (if (and (eq (current-buffer) (span-buffer oldspan)) (or (and (<= start oldstart) (<= oldstart end)) (and (<= start oldend) (<= oldend end)))) (progn (setq found t) (span-delete oldspan) span) oldspan))) pg-pbrpm-regions-list))) (if (not found) (setq pg-pbrpm-regions-list (cons span pg-pbrpm-regions-list))) (span-set-property span 'face 'pg-pbrpm-multiple-selection-face)))) ; the follwing are adapted from mouse-track-insert from mouse.el (defun pg-pbrpm-remember-region-drag-up-hook (event click-count) (setq pg-pbrpm-remember-region-selected-region (default-mouse-track-return-dragged-selection event))) (defun pg-pbrpm-remember-region-click-hook (event click-count) (default-mouse-track-drag-hook event click-count nil) (pg-pbrpm-remember-region-drag-up-hook event click-count) t) (defun pg-pbrpm-remember-region (event &optional delete) "Allow multiple selection as a list of spam stored in ???. The current (standard) selection in the same buffer is also stored" (interactive "*e") (setq pg-pbrpm-remember-region-selected-region nil) (let ((mouse-track-drag-up-hook 'pg-pbrpm-remember-region-drag-up-hook) (mouse-track-click-hook 'pg-pbrpm-remember-region-click-hook) (start (point)) (end (mark))) (if (and start end) (pg-pbrpm-do-remember-region start end)) (mouse-track event) (if (consp pg-pbrpm-remember-region-selected-region) (let ((pair pg-pbrpm-remember-region-selected-region)) (pg-pbrpm-do-remember-region (car pair) (cdr pair)))))) (defun pg-pbrpm-process-region (span) "Returns the list of informations about the the selected region needed to call generate-menu. span is a span covering the selected region" (let ((start (span-start span)) (end (span-end span)) (buffer (span-buffer span)) r) (if (and start end) ; if a region is selected (if (eq proof-goals-buffer buffer) (progn (setq r (pg-pbrpm-get-region-info start end)) (if r (list (string-to-number (car r)) ; should not be an int for other prover (cdr r) (pg-pbrpm-region-expression buffer start end)) (list 0 "none" (pg-pbrpm-region-expression buffer start end)))) (list 0 "none" (pg-pbrpm-region-expression buffer start end)))))) (defun pg-pbrpm-process-regions-list () (pg-pbrpm-do-remember-region (point-marker) (mark-marker)) (mapcar (lambda (span) (pg-pbrpm-process-region span)) pg-pbrpm-regions-list)) (defun pg-pbrpm-region-expression (buffer start end) "Valid parenthesis'd expression." ;; an expression is valid if it has as many left paren' as right paren' (with-current-buffer buffer (buffer-substring start end))) ; (let ; ((pbrpm-left-pars 0) ; (pbrpm-right-pars 0) ; (pos start)) ; (while (< pos end) ; (if (proof-pbrpm-left-paren-p (char-after pos)) ; (setq pbrpm-left-pars (+ pbrpm-left-pars 1))) ; (if (proof-pbrpm-right-paren-p (char-after pos)) ; (setq pbrpm-right-pars (+ pbrpm-right-pars 1))) ; (setq pos (+ pos 1))) ; (if (= pbrpm-left-pars pbrpm-right-pars) ; (buffer-substring start end buffer) ; (progn ; nil ; TODO : define how to manage this error case ; ;we could call (pg-pbrpm-dialog "Selected region is not valid), then what about the state of the process ? ; )))) ;;--------------------------------------------------------------------------;; (eval-after-load "pg-goals" '(progn (define-key proof-goals-mode-map [(button3)] 'pg-pbrpm-button-action) (define-key proof-goals-mode-map [(control button3)] 'pg-goals-yank-subterm) (define-key proof-goals-mode-map [(control button1)] 'pg-pbrpm-remember-region) (define-key proof-mode-map [(button3)] 'pg-pbrpm-button-action) (define-key proof-mode-map [(control button3)] 'pg-goals-yank-subterm) (define-key proof-mode-map [(control button1)] 'pg-pbrpm-remember-region))) (eval-after-load "proof-script" '(progn (define-key pg-span-context-menu-keymap [(button3)] 'pg-pbrpm-button-action) (define-key pg-span-context-menu-keymap [(control button3)] 'pg-span-context-menu))) (provide 'pg-pbrpm) ;;; pg-pbrpm ends here proofgeneral-4.3~pre130510/generic/pg-pgip.el000066400000000000000000000553031214562307500207360ustar00rootroot00000000000000;; pg-pgip.el --- PGIP manipulation for Proof General ;; ;; Copyright (C) 2000-2002, 2010 LFCS Edinburgh. ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-pgip.el,v 12.1 2011/10/17 10:11:45 da Exp $ ;; ;; STATUS: Experimental ;; ;; 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 ;; and to construct PGIP commands to send out. ;; ;; TESTING NOTES: turn on `proof-general-debug' for ;; useful tracing messages: (setq proof-general-debug t). ;; ;; TODO NEXT: ;; -- completion command for completion tables ;; -- parsescript input/outputs ;; -- guiconfig, some parts of ;; -- support fully native PGIP mode ;; ;;; Commentary: ;; (require 'cl) ; incf (require 'pg-xml) ; (declare-function pg-response-warning "pg-response") (declare-function pg-response-message "pg-response") (declare-function proof-segment-up-to "proof-script") (declare-function proof-insert-pbp-command "proof-script") ;;; Code: (defalias 'pg-pgip-debug 'proof-debug) (defalias 'pg-pgip-error 'error) (defalias 'pg-pgip-warning 'pg-internal-warning) (defconst pg-pgip-version-supported "2.0" "Version of PGIP supported by this library.") ;;;###autoload (defun pg-pgip-process-packet (pgips) "Process the command packet PGIP, which is parsed XML according to pg-xml-parse-*. The list PGIPS may contain one or more PGIP packets, whose contents are processed." ;; PGIP processing is split into two steps: ;; (1) process each command, altering internal data structures ;; (2) post-process for each command type, affecting external interface (menus, etc). (mapc 'pg-pgip-post-process (reduce 'union (mapcar 'pg-pgip-process-pgip pgips)))) ;; TODO: use id's and sequence numbers to reconstruct streams of messages. (defvar pg-pgip-last-seen-id nil) (defvar pg-pgip-last-seen-seq nil) (defun pg-pgip-process-pgip (pgip) "Process the commands in the PGIP XML-node PGIP." ;; NB: appearances of 'notreallyoptional below should be removed, ;; but they are needed for compatibility with Isabelle at the moment, ;; whose PGIP follows an older schema. (let* ((name (xml-node-name pgip)) (tag (pg-xml-get-attr 'tag pgip 'optional)) (id (pg-xml-get-attr 'id pgip 'optional)) (class (pg-xml-get-attr 'messageclass pgip 'notreallyoptional)) (refseq (pg-xml-get-attr 'refseq pgip 'optional)) (refid (pg-xml-get-attr 'refid pgip 'optional)) (seq (pg-xml-get-attr 'seq pgip 'notreallyoptional))) (setq pg-pgip-last-seen-id id) (setq pg-pgip-last-seen-seq seq) (if (eq name 'pgip) ;; NB: schema currently allows only one message here (mapcar 'pg-pgip-process-msg (xml-node-children pgip)) (pg-internal-warning "pg-pgip-process-pgip: expected PGIP element, got %s" name)))) (defun pg-pgip-process-msg (pgipmsg) "Process the PGIP message in the XML node PGIPMSG. Return a symbol representing the PGIP command processed, or nil." (let* ((name (xml-node-name pgipmsg)) (fname (intern (concat "pg-pgip-process-" (symbol-name name))))) (if (fboundp fname) (progn (pg-pgip-debug "Processing PGIP message seq %s, type %s" (or (pg-xml-get-attr 'seq pgipmsg 'notreallyoptional) "") name) (funcall fname pgipmsg) name) (pg-internal-warning "!!! unrecognized/unimplemented PGIP message element `%s'" name) nil))) (defvar pg-pgip-post-process-functions '((hasprefs . proof-assistant-menu-update) (oldhaspref . proof-assistant-menu-update) ;; NB: Isabelle compatibility (menuadd . proof-assistant-menu-update) (menudel . proof-assistant-menu-update) (idtable . pg-pgip-update-idtables) ;; TODO: not yet implemented (addid . pg-pgip-update-idtables) (delid . pg-pgip-update-idtables)) "Table of functions to call after processing PGIP commands.") (defun pg-pgip-post-process (cmdname) "Perform post-processing for a PGIP command type CMDNAME (a symbol)." (let ((ppfn (cdr-safe (assoc cmdname pg-pgip-post-process-functions)))) (if (fboundp ppfn) (progn (pg-pgip-debug "Post-processing for PGIP message type `%s' with function `%s'" cmdname ppfn) (funcall ppfn)) (pg-pgip-debug "[No post-processing defined for PGIP message type `%s']" cmdname)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Message processing: fromprovermsg/kitconfig ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun pg-pgip-process-askpgip (node) (pg-pgip-debug "Received message with version `%s'" (pg-xml-get-attr 'version node 'notreallyoptional)) ;; TODO: send a uses PGIP message back? ) (defun pg-pgip-process-usespgip (node) (let ((version (pg-pgip-get-version node))) (pg-pgip-debug "Received message with version `%s'" version))) (defun pg-pgip-process-usespgml (node) (let ((version (pg-pgip-get-version node))) (pg-pgip-debug "Received message with version `%s'" version))) (defun pg-pgip-process-pgmlconfig (node) ;; symconfig specify an ascii alternative string for a named symbol; ;; we process it by storing a property 'pgml-alt on the elisp symbol. (let ((pgmlconfigures (xml-get-children node 'symconfig))) (dolist (config pgmlconfigures) (cond ((and (not (stringp config)) (eq (xml-node-name config) "symconfig")) (let ((symname (pg-pgip-get-symname node)) (asciialt (pg-xml-get-attr 'alt node t))) (put (intern symname) 'pgml-alt asciialt))) (t (pg-pgip-warning "Unexpected child of node: %s" config)))))) (defun pg-pgip-process-proverinfo (node) (let* ((name (pg-pgip-get-name node)) (descr (pg-pgip-get-descr node t "")) (version (pg-pgip-get-version node t "")) (url (pg-pgip-get-url node t)) (welcomeelt (pg-xml-get-child 'welcomemsg node)) (welcomemsg (if welcomeelt (pg-xml-get-text-content welcomeelt))) (icon (xml-get-children node 'icon)) (helpdocs (xml-get-children node 'helpdocs))) ;; TODO: enter the data into a table of provers (see proof-site.el). ;; Seems little point doing this while we have the single-prover limitation. )) ;; ;; Preferences ;; (defun pg-pgip-process-hasprefs (node) (let* ((prefcat (pg-pgip-get-prefcat node)) (hasprefnodes (xml-get-children node 'haspref))) (dolist (node hasprefnodes) (let* ((name (pg-pgip-get-name node)) (descr (pg-pgip-get-descr node 'optional)) (pgiptype (pg-pgip-get-pgiptype (pg-xml-child-elt node))) (default (pg-pgip-get-default node 'optional)) (defaultlsp (if default (pg-pgip-interpret-value default pgiptype) (pg-pgip-default-for pgiptype))) (icon (pg-pgip-get-icon node 'optional))) ;; TODO; ignored (pg-pgip-haspref name pgiptype prefcat descr defaultlsp))))) (defun pg-pgip-haspref (name type prefcat descr default) "Call `defpacustom' with values from a element." (let* ((subst (pg-pgip-subst-for type)) ;; FIXME: this substitution mechanism is not really good enough, we ;; want to escape XML characters, etc. Should be possible: turn this ;; into a function. (pgipcmd (concat "" subst "")) (symname (intern name))) (pg-pgip-debug "haspref calling defpacustom: name:%s default:%s type:%s pgipcmd:%s" symname default type pgipcmd) (eval `(defpacustom ,symname ,default ,descr :type (quote ,type) :pggroup ,prefcat :pgipcmd ,pgipcmd :pgdynamic t)))) (defun pg-pgip-process-prefval (node) ;; ;; value ;; ;; Proof assistant advises that preference n has been updated. ;; ;; Protocol is that sent on a PGIP channel is assumed to ;; succeed, so is not required to be acknowledged with a ;; message from prover. But no harm will result if it is --- and that ;; might be appropriate if some canonicalisation occurs. ; in progress [FIXME: Isabelle can send this as reply to getpref now] ;(defun pg-pgip-prefval (attrs value) ; "Process a element, by setting interface's copy of preference." ; (let* ; ((name (pg-xml-get-attr 'haspref 'name attrs t)) ; (type ( ) ;; ;; guiconfig ;; (defun pg-pgip-process-guiconfig (node) ) ;; ;; Identifiers: managing obarrays of symbols used for completion ;; (defvar proof-assistant-idtables nil "List of idtables (objtype symbols) for currently running proof assistant.") (defun pg-pgip-process-ids (node) "Manipulate identifier tables, according to setids/addids/delids in NODE." (let ((idtables (pg-xml-child-elts node)) (opn (xml-node-name node))) (dolist (idtable idtables) (let* ((context (pg-xml-get-attr 'context idtable 'optional)) (objtype (intern (pg-pgip-get-objtype idtable))) (idents (mapcar 'pg-xml-get-text-content (xml-get-children idtable 'identifier))) (obarray (or (and (not (eq opn 'setids)) (get objtype 'pgsymbols)) ;; new empty obarray for setids or if unset (put objtype 'pg-symbols (make-vector 31 0))))) (setq proof-assistant-idtables (if (and (null idents) (eq opn 'setids)) (delete objtype proof-assistant-idtables) (adjoin objtype proof-assistant-idtables))) (cond ((or (eq opn 'setids) (eq opn 'addids)) (mapc (lambda (i) (intern i obarray)) idents)) ((eq opn 'delids) (mapc (lambda (i) (unintern i obarray)) idents)) (t (pg-pgip-error "Pg-pgip-process-ids: called on wrong node %s" (xml-node-name node)))))))) (defun pg-complete-idtable-symbol () (interactive) ;; TODO: complete based on blah ) (defalias 'pg-pgip-process-setids 'pg-pgip-process-ids) (defalias 'pg-pgip-process-addids 'pg-pgip-process-ids) (defalias 'pg-pgip-process-delids 'pg-pgip-process-ids) (defun pg-pgip-process-idvalue (node) (let ((name (pg-pgip-get-name node)) (objtype (pg-pgip-get-objtype node)) (text (pg-pgip-get-displaytext node))) ;; TODO: display and cache the value in a dedicated buffer ;; FIXME: should idvalue have a context? (pg-response-message text))) ;; ;; Menu configuration [TODO] ;; (defun pg-pgip-process-menuadd (node) ) (defun pg-pgip-process-menudel (node) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Message processing: fromprovermsg/proveroutput ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun pg-pgip-process-ready (node) ) (defun pg-pgip-process-cleardisplay (node) (let ((area (pg-pgip-get-area node))) (cond ((equal area "message") (pg-response-maybe-erase nil t t)) ((equal area "display") (proof-clean-buffer proof-goals-buffer)) ((equal area "all") (pg-response-maybe-erase nil t t) (proof-clean-buffer proof-goals-buffer) ;; TODO: could also erase trace here. ;; [PGIP: Should trace have a separate cat?] )))) (defun pg-pgip-process-proofstate (node) ;(let ((pgml (pg-xml-child ) ) (defun pg-pgip-process-normalresponse (node) (let ((text (pg-pgip-get-displaytext node))) (pg-response-message text))) (defun pg-pgip-process-errorresponse (node) (let ((text (pg-pgip-get-displaytext node))) (pg-response-warning text))) (defun pg-pgip-process-scriptinsert (node) (let ((text (pg-pgip-get-displaytext node))) (proof-insert-pbp-command text))) (defun pg-pgip-process-metainforesponse (node) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Message processing: fromprovermsg/fileinfomsg ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun pg-pgip-file-of-url (urlstr) (save-match-data (if (string-match "^file:///\\(.*\\)$" urlstr) (match-string 1 urlstr)))) (defun pg-pgip-process-informfileloaded (node) (let* ((thyname (pg-pgip-get-thyname node)) (url (pg-pgip-get-url node)) (filename (pg-pgip-file-of-url url))) (proof-register-possibly-new-processed-file filename))) (defun pg-pgip-process-informfileretracted (node) (let* ((thyname (pg-pgip-get-thyname node)) (url (pg-pgip-get-url node)) (filename (pg-pgip-file-of-url url))) ;(proof-unregister-possibly-processed-file filename))) ;; unimplemented! )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Message processing: todisplaymsg/brokermsg ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun pg-pgip-process-brokerstatus (node) ) (defun pg-pgip-process-proveravailmsg (node) ) (defun pg-pgip-process-newprovermsg (node) ) (defun pg-pgip-process-proverstatusmsg (node) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Message processing: todisplaymsg/dispmsg/dispfilemsg ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar pg-pgip-srcids nil "Association list of srcrds to (buffer file) lists") ;; FIXME: right action? (defun pg-pgip-process-newfile (node) "Process message from broker by displaying file. Also sets local proverid and srcid variables for buffer." (let* ((srcid (pg-pgip-get-srcid node)) (proverid (pg-pgip-get-proverid node)) (url (pg-pgip-get-url node)) (file (pg-pgip-file-of-url url))) (find-file file) (let ((buffer (get-file-buffer file))) (with-current-buffer buffer (make-local-variable 'proverid) (setq proverid proverid)) (set pg-pgip-srcids (acons srcid (list buffer file) pg-pgip-srcids))))) ;; FIXME: right action? (defun pg-pgip-process-filestatus (node) "Process flag by adjusting buffer's modified flag." (let* ((srcid (pg-pgip-get-srcid node)) (filestat (pg-xml-get-attr 'filestat node)) (buffer (car-safe (cdr-safe (assoc srcid pg-pgip-srcids))))) (proof-with-current-buffer-if-exists buffer (cond ((equal filestat "changed") (set-buffer-modified-p t)) ((equal filestat "saved") (set-buffer-modified-p nil)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Message processing: todisplaymsg/dispmsg/dispobjmsg ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun pg-pgip-process-newobj (node) ) (defun pg-pgip-process-delobj (node) ) (defun pg-pgip-process-objectstatus (node) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Message processing: parsescript [incomplete] ;; ;; NB: pgip.rnc v 2.18 only has parsescript sent to prover, ;; so if we get here we have a invalid document. ;; ;; Provide parsing functionality for other interfaces (sacrilege!) ;; (defun pg-pgip-process-parsescript (node) ;; Text ought to be cdata or something. We'll stick it into a buffer ;; and run the proof-script code on it. (save-excursion (let* ((text (pg-xml-get-text-content node)) (buf (get-buffer-create " *pgip-parsescript*"))) (delete-region (point-min) (point-max)) ; wipe previous contents (insert text) (let ((semis (proof-segment-up-to (point)))) ;; semis is now a list of (type, string, int) tuples (in reverse order). ;; we'll turn it into XML and send it back to the prover ;; FIXME: todo: make parseresult element according to types, ;; properscriptcmd = properproofcmd | properfilecmd | bindid )))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PGIP types and values <-> Elisp types and values ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun pg-pgip-get-pgiptype (node) "Return internal (custom format) representation for element in NODE." (let ((tyname (and node (xml-node-name node)))) (cond ((eq tyname 'pgipbool) 'boolean) ((eq tyname 'pgipint) 'integer) ;; TODO: implement range limits ((eq tyname 'pgipfloat) 'float) ;; TODO: implement range limits ((eq tyname 'pgipstring) 'string) ((eq tyname 'pgipconst) (let ((name (pg-pgip-get-name node 'optional)) (val (pg-pgip-get-value node))) (if name (list 'const :tag name val) (list 'const val)))) ((eq tyname 'pgipchoice) (let* ((choicesnodes (pg-xml-child-elts node)) (choices (mapcar 'pg-pgip-get-pgiptype choicesnodes))) (list 'choice choices))) (t (pg-pgip-warning "pg-pgip-get-pgiptype: unrecognized/missing typename \"%s\"" tyname))))) (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) 'const) (car (last type))) ((eq (car-safe type) 'choice) (pg-pgip-default-for (car-safe (cdr-safe type)))) (t (pg-pgip-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") ((eq type 'float) "%f") (t "%s"))) ;; Converting PGIP representations to elisp representations. This is ;; the inverse of proof-assistant-format translations in ;; proof-menu.el, although we fix PGIP value syntax. (defun pg-pgip-interpret-value (value type) "Interpret the PGIP value VALUE at (lisp-representation for) TYPE." (cond ((eq type 'boolean) (cond ((or (string-equal value "true") (string-equal value "1")) t) ((or (string-equal value "false") (string-equal value "0")) nil) (t (progn (pg-pgip-warning "pg-pgip-interpret-value: received non-bool value %s" value) nil)))) ((eq type 'integer) (string-to-number value)) ((eq type 'float) (string-to-number value)) ((eq type 'string) value) ((eq (car-safe type) 'const) value) ((eq (car-safe type) 'choice) (pg-pgip-interpret-choice (cdr type) value)) (t (pg-pgip-error "pg-pgip-interpret-value: unkown type %s" type)))) (defun pg-pgip-interpret-choice (choices value) ;; Untagged union types: test for value in each type in turn. (let (res) (while (and choices (not res)) (let ((type (car choices))) (cond ((and (eq (car-safe type) 'const) (string-equal value (cadr type))) (setq res (pg-pgip-interpret-value value 'const))) ((and (eq type 'integer) (string-match "[+-]?[0-9]+$" value)) (setq res (pg-pgip-interpret-value value 'integer))) ((and (eq type 'boolean) (or (string-equal value "true") (string-equal value "false") (string-equal value "0") (string-equal value "1"))) (setq res (pg-pgip-interpret-value value 'boolean))) ((eq type 'string) (setq res (pg-pgip-interpret-value value 'string))))) (setq choices (cdr choices))) (or res (pg-pgip-error "pg-pgip-interpret-choice: mismatching value %s for choices %s" value choices)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Sending PGIP commands to prover ;; (defun pg-pgip-string-of-command (pgip &optional refseq refid otherclass) "Convert XML node PGIP or string into a command string to send to the prover. This wraps the node in a packet with appropriate attributes. See `pg-pgip-assemble-packet' " (let ((wrappedpgip (pg-xml-string-of (list (pg-pgip-assemble-packet (list pgip) refseq refid otherclass))))) (cond ((stringp proof-shell-issue-pgip-cmd) (format proof-shell-issue-pgip-cmd wrappedpgip)) ((functionp proof-shell-issue-pgip-cmd) (funcall proof-shell-issue-pgip-cmd wrappedpgip)) (t ;; FIXME: Empty setting: might be better to send a comment (pg-pgip-warning "pg-prover-interpret-pgip-command: `proof-shell-issue-pgip' is unset!") "")))) (defconst pg-pgip-id ;; Identifier based on hostname, user, time, and (FIXME: possible?) ppid (concat (getenv "HOSTNAME") "/" (getenv "USER") "/" (let ((tm (current-time))) (format "%d.%d" (car tm) (cadr tm)))) "PGIP Identifier for this Emacs Proof General component.") (defvar pg-pgip-refseq nil "The sequence number of the received message this reply refers to") (defvar pg-pgip-refid nil "The identity of the component this message is being sent to") (defvar pg-pgip-seq 0 "Sequence number of messages sent out.") (defun pg-pgip-assemble-packet (body &optional refseq refid otherclass) "Construct a PGIP node with body list BODY. REFSEQ and REFID are used for the corresponding attributes, if present. By default, the class of the message is \"pa\" (destined for prover). OTHERCLASS overrides this." (let* ((tag (pg-xml-attr tag (concat "EmacsPG/" proof-general-short-version "/" proof-assistant))) (id (pg-xml-attr id pg-pgip-id)) (class (pg-xml-attr class (or otherclass "pa"))) (seq (pg-xml-attr seq (int-to-string (incf pg-pgip-seq)))) (refseq (if refseq (list (pg-xml-attr refseq refseq)))) (refid (if refid (list (pg-xml-attr refid refid)))) (pgip_attrs (append (list tag id class seq) refseq refid))) (pg-xml-node pgip pgip_attrs body))) (defun pg-pgip-issue (pgip &optional block refseq refid otherclass) "Issue a PGIP command via `proof-shell-issue-pgip-cmd' and `proof-shell-invisible-command'. This expects a single XML node/string in PGIP, which will have a PGIP header attached. If BLOCK is non-nil, we wait for the response from the prover. For remaining optional args, see doc of `pgip-assemble-packet'." (proof-shell-invisible-command (pg-pgip-string-of-command pgip refseq refid otherclass) block)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Functions to send particular commands ;; ;;;###autoload (defun pg-pgip-maybe-askpgip () "Send an message to the prover if PGIP is supported." (if proof-shell-issue-pgip-cmd (pg-pgip-issue "" 'block))) ;;;###autoload (defun pg-pgip-askprefs () "Send an message to the prover." (pg-pgip-issue "" 'block)) (defun pg-pgip-askids (&optional objtype thyname) "Send an message to the prover." (pg-pgip-issue (pg-xml-node askids (append (if thyname (list (pg-xml-attr 'thyname objtype))) (if objtype (list (pg-xml-attr 'objtype objtype)))) nil) 'block)) (defun pg-pgip-reset () "Reset state of the PGIP module" (setq pg-pgip-refseq nil pg-pgip-refid nil pg-pgip-last-seen-id nil pg-pgip-last-seen-seq nil pg-pgip-seq 0 proof-assistant-settings nil ;; optional proof-assistant-idtables nil)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Standalone PGIP processing -- Emacs in batch mode, yuk! ;; ;; TODO: output PGIP on stdout, read in on stdin. ;; standard-input ;; standard-output ;; (defun pg-pgip-filter () ;; (let (instuff outstuff) ;; (while (setq (read-char standard-input)) ;; reads lisp!!! ;; ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Constants for export ;; (defconst pg-pgip-start-element-regexp "") (provide 'pg-pgip) ;;; pg-pgip.el ends here proofgeneral-4.3~pre130510/generic/pg-response.el000066400000000000000000000443711214562307500216400ustar00rootroot00000000000000;; pg-response.el --- Proof General response buffer mode. ;; ;; Copyright (C) 1994-2010 LFCS Edinburgh. ;; Authors: David Aspinall, Healfdene Goguen, ;; Thomas Kleymann and Dilip Sequeira ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-response.el,v 12.10 2012/09/25 09:44:18 pier Exp $ ;; ;;; Commentary: ;; ;; This mode is used for the response buffer proper, and ;; also the trace and theorems buffer. A sub-module of proof-shell. ;; ;;; Code: (eval-when-compile (require 'easymenu) ; easy-menu-add (require 'proof-utils) ; deflocal, proof-eval-when-ready-for-assistant (defvar proof-response-mode-menu nil) (defvar proof-assistant-menu nil)) (require 'pg-assoc) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Local variables ;; (deflocal pg-response-eagerly-raise t "Non-nil if this buffer will be eagerly raised/displayed on startup.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Response buffer mode ;; ;;;###autoload (define-derived-mode proof-response-mode proof-universal-keys-only-mode "PGResp" "Responses from Proof Assistant" (setq proof-buffer-type 'response) (add-hook 'kill-buffer-hook 'pg-save-from-death nil t) (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 pg-response-next-error nil) (buffer-disable-undo) (if proof-keep-response-history (bufhist-mode)) ; history for contents (set-buffer-modified-p nil) (setq buffer-read-only t) (setq cursor-in-non-selected-windows nil)) ;; ;; Menu for response buffer ;; (proof-eval-when-ready-for-assistant ; proof-aux-menu depends on (easy-menu-define proof-response-mode-menu proof-response-mode-map "Menu for Proof General response buffer." (proof-aux-menu))) ;; ;; Keys for response buffer ;; ;; TODO: use standard Emacs button behaviour here (cf Info mode) (define-key proof-response-mode-map [mouse-1] 'pg-goals-button-action) (define-key proof-response-mode-map [q] 'bury-buffer) (define-key proof-response-mode-map [c] 'pg-response-clear-displays) ;;;###autoload (defun proof-response-config-done () "Complete initialisation of a response-mode derived buffer." (setq font-lock-defaults '(proof-response-font-lock-keywords))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Window configuration ;; -- multiple frames for goals and response buffers, ;; -- three window mode ;; (defvar pg-response-special-display-regexp nil "Regexp for `special-display-regexps' for multiple frame use. Internal variable, setting this will have no effect!") (defconst proof-multiframe-parameters '((minibuffer . nil) (modeline . nil) ; ignored? (unsplittable . t) (menu-bar-lines . 0) (tool-bar-lines . nil) (proofgeneral . t)) ;; indicates generated for/by PG "List of GNU Emacs frame parameters for secondary frames.") (defun proof-multiple-frames-enable () (let ((spdres (cons pg-response-special-display-regexp proof-multiframe-parameters))) (if proof-multiple-frames-enable (add-to-list 'special-display-regexps spdres) (setq special-display-regexps (delete spdres special-display-regexps)))) (proof-layout-windows)) (defun proof-three-window-enable () (proof-layout-windows)) (defun proof-select-three-b (b1 b2 b3 &optional policy) "Put the given three buffers into three windows. Following POLICY, which can be one of 'smart, 'horizontal, 'vertical or 'hybrid." (interactive "bBuffer1:\nbBuffer2:\nbBuffer3:") (delete-other-windows) (switch-to-buffer b1) (let ((pol)) (if (eq policy 'smart) (cond ((>= (frame-width) (* 1.5 split-width-threshold)) (setq pol 'horizontal)) ((>= (frame-width) split-width-threshold) (setq pol 'hybrid)) (t (setq pol 'vertical))) (setq pol policy)) (message "policy = %S , pol = %S" policy pol) (save-selected-window (cond ((eq pol 'hybrid) (split-window-horizontally) (other-window 1) (switch-to-buffer b2) (proof-safe-split-window-vertically) ; enlarge vertically if necessary (other-window 1) (switch-to-buffer b3)) ((eq pol 'vertical) (split-window-vertically) (other-window 1) (switch-to-buffer b2) (proof-safe-split-window-vertically) ; enlarge vertically if necessary (other-window 1) (switch-to-buffer b3)) ((eq pol 'horizontal) (split-window-horizontally) ; horizontally again (other-window 1) (switch-to-buffer b2) (enlarge-window (/ (frame-width) 6) t) ; take 2/3 of width before splitting again (split-window-horizontally) ; horizontally again (other-window 1) (switch-to-buffer b3)))))) (defun proof-display-three-b (&optional policy) "Layout three buffers in a single frame. Only do this if buffers exist." (interactive) (when (and (buffer-live-p proof-goals-buffer) (buffer-live-p proof-response-buffer)) (save-excursion (proof-select-three-b proof-script-buffer proof-goals-buffer proof-response-buffer policy)))) (defvar pg-frame-configuration nil "Variable storing last used frame configuration.") ;; FIXME: would be nice to try storing this persistently. (defun pg-cache-frame-configuration () "Cache the current frame configuration, between prover restarts." (setq pg-frame-configuration (current-frame-configuration))) (defun proof-layout-windows () "Refresh the display of windows according to current display mode. For multiple frame mode, this function obeys the setting of `pg-response-eagerly-raise', which see. For single frame mode: - In two panes mode, this uses a canonical layout made by splitting Emacs windows in equal proportions. The splitting is vertical if emacs width is smaller than `split-width-threshold' and horizontal otherwise. You can then adjust the proportions by dragging the separating bars. - In three pane mode, there are three display modes, depending where the three useful buffers are displayed: scripting buffer, goals buffer and response buffer. Here are the three modes: - vertical: the 3 buffers are displayed in one column. - hybrid: 2 columns mode, left column displays scripting buffer and right column displays the 2 others. - horizontal: 3 columns mode, one for each buffer (script, goals, response). By default, the display mode is automatically chosen by considering the current emacs frame width: if it is smaller than `split-width-threshold' then vertical mode is chosen, otherwise if it is smaller than 1.5 * `split-width-threshold' then hybrid mode is chosen, finally if the frame is larger than 1.5 * `split-width-threshold' then the horizontal mode is chosen. You can change the value of `split-width-threshold' at your will. If you want to force one of the layouts, you can set variable `proof-three-window-mode-policy' to 'vertical, 'horizontal or 'hybrid. The default value is 'smart which sets the automatic behaviour described above." (interactive) (cond (proof-multiple-frames-enable (delete-other-windows) ;; hope we're on the right frame/window (if proof-script-buffer (switch-to-buffer proof-script-buffer)) (proof-map-buffers (proof-associated-buffers) (if pg-response-eagerly-raise (proof-display-and-keep-buffer (current-buffer) nil 'force))) ;; Restore an existing frame configuration (seems buggy, typical) (if pg-frame-configuration (set-frame-configuration pg-frame-configuration 'nodelete))) (proof-three-window-enable (proof-delete-other-frames) (set-window-dedicated-p (selected-window) nil) (proof-display-three-b proof-three-window-mode-policy)) ;; Two-of-three window mode. ;; Show the response buffer as first in preference order. (t (proof-delete-other-frames) (set-window-dedicated-p (selected-window) nil) (delete-other-windows) (if (buffer-live-p proof-response-buffer) (proof-display-and-keep-buffer proof-response-buffer nil 'force)))) (pg-hint (pg-response-buffers-hint))) (defun proof-delete-other-frames () "Delete frames showing associated buffers." (save-selected-window ;; FIXME: this is a bit too brutal. If there is no ;; frame for the associated buffer, we may delete ;; the main frame!! (let ((mainframe (window-frame (if proof-script-buffer (proof-get-window-for-buffer proof-script-buffer) ;; We may lose with just selected window (selected-window))))) (proof-map-buffers (proof-associated-buffers) (let* ((win ;; NB: g-w-f-b will re-display in new frame if ;; the buffer isn't selected/visible. This causes ;; new frame to flash up and be deleted if already ;; deleted! ;; (proof-get-window-for-buffer (current-buffer)) ;; This next choice is probably better: (get-buffer-window (current-buffer) 'visible)) (fm (and win (window-frame win)))) (unless (equal mainframe fm) (if fm (delete-frame fm)))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Displaying in the response buffer ;; ;; Flag and function to keep response buffer tidy. (defvar pg-response-erase-flag nil "Non-nil means the response buffer should be cleared before next message.") ;;;###autoload (defun pg-response-maybe-erase (&optional erase-next-time clean-windows force keep) "Erase the response buffer, according to confusing flag combinations. Mainly, we look at `pg-response-erase-flag' and clear the response buffer if this is non-nil, but NOT the special symbol 'invisible. ERASE-NEXT-TIME is the new value for the flag. FORCE overrides the flag to force cleaning. KEEP overrides the flag to prevent cleaning. FORCE takes precedent over KEEP. If CLEAN-WINDOWS is set, use `proof-clean-buffer' to do the erasing, otherwise we use `bufhist-checkpoint-and-erase' to record an undo history entry for the current buffer contents. If the user option `proof-tidy-response' is nil, the buffer will never be cleared unless 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 ((inhibit-read-only t) (doit (or (and proof-tidy-response (not keep) (not (eq pg-response-erase-flag 'invisible)) pg-response-erase-flag) force))) (if doit (if clean-windows (proof-clean-buffer proof-response-buffer) (with-current-buffer proof-response-buffer (setq pg-response-next-error nil) ; all error msgs lost! (if (> (buffer-size) 0) (bufhist-checkpoint-and-erase)) (set-buffer-modified-p nil)))) (setq pg-response-erase-flag erase-next-time) doit))) (defun pg-response-display (str) "Show STR as a response in the response buffer." (pg-response-maybe-erase t nil) (pg-response-display-with-face str) ;; NB: this displays an empty buffer sometimes when it's not ;; so useful. It _is_ useful if the user has requested to ;; see the proof state and there is none ;; (Isabelle/Isar displays nothing: might be better if it did). (proof-display-and-keep-buffer proof-response-buffer)) ;; ;; Images for the response buffer ;; ;(defimage pg-response-error-image ; ((:type xpm :file "/home/da/PG/images/epg-interrupt.xpm"))) ;(defimage pg-response-warning-image ; ((:type xpm :file "/home/da/PG/images/epg-abort.xpm"))) ;; TODO: this function should be combined with ;; pg-response-maybe-erase-buffer. ;;;###autoload (defun pg-response-display-with-face (str &optional face) "Display STR with FACE in response buffer." (cond ((string-equal str "")) ((string-equal str "\n")) ; quick exit, no display. (t (let (start end) (with-current-buffer proof-response-buffer (setq buffer-read-only nil) ;; 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). (goto-char (point-max)) ;; insert a newline before the new message unless the ;; buffer is empty (unless (eq (point-min) (point-max)) (newline)) (setq start (point)) (insert str) (unless (bolp) (newline)) (when face (overlay-put (make-overlay start (point-max)) 'face face)) (setq buffer-read-only t) (set-buffer-modified-p nil)))))) (defun pg-response-clear-displays () "Clear Proof General response and tracing buffers. You can use this command to clear the output from these buffers when it becomes overly long. Particularly useful when `proof-tidy-response' is set to nil, so responses are not cleared automatically." (interactive) (proof-with-current-buffer-if-exists proof-response-buffer (if (> (buffer-size) 0) (let ((inhibit-read-only t)) (bufhist-checkpoint-and-erase) (set-buffer-modified-p nil)))) (proof-with-current-buffer-if-exists proof-trace-buffer (let ((inhibit-read-only t)) (erase-buffer) (set-buffer-modified-p nil))) (message "Response buffers cleared.")) ;;;###autoload (defun pg-response-message (&rest args) "Issue the message ARGS in the response buffer and display it." (pg-response-display-with-face (apply 'concat args)) (proof-display-and-keep-buffer proof-response-buffer)) ;;;####autoload (defun pg-response-warning (&rest args) "Issue the warning ARGS in the response buffer and display it. The warning is coloured with `proof-warning-face'." (pg-response-display-with-face (apply 'concat args) 'proof-warning-face) (proof-display-and-keep-buffer proof-response-buffer)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Next error function. ;; ;;;###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. Optional argument ARGP means reparse the error message buffer and start at the first error." (interactive "P") (if (and pg-next-error-regexp (or (buffer-live-p proof-response-buffer) (error "Next error: no response buffer to parse!"))) (let ((wanted-error (or (and (not (consp argp)) (+ (prefix-numeric-value argp) (or pg-response-next-error 0))) (and (consp argp) 1) (or pg-response-next-error 1))) line column file errpos) (set-buffer proof-response-buffer) (goto-char (point-min)) (if (re-search-forward pg-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-number line))) (setq column (match-string 3)) ; may be unset (if column (setq column (string-to-number column))) (setq pg-response-next-error wanted-error) (if (and pg-next-error-filename-regexp ;; Look for the most recently mentioned filename (re-search-backward pg-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 pg-next-error-extract-filename (format pg-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 ;; Could make guesses, e.g. last active script (error "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 (with-no-warnings ; "interactive only" (goto-line line)) (if (and column (> column 1)) (move-to-column (1- column))))) (setq pg-response-next-error nil) (error "Next error: couldn't find a next error"))))) ;;;###autoload (defun pg-response-has-error-location () "Return non-nil if the response buffer has an error location. See `pg-next-error-regexp'." (if pg-next-error-regexp (proof-with-current-buffer-if-exists proof-response-buffer (save-excursion (goto-char (point-min)) (re-search-forward pg-next-error-regexp nil t))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Tracing buffers ;; (defcustom proof-trace-buffer-max-lines 10000 "The maximum size in lines for Proof General *trace* buffers. A value of 0 stands for unbounded." :type 'integer :group 'proof-shell) ;; An analogue of pg-response-display-with-face (defun proof-trace-buffer-display (start end) "Copy region START END from current buffer to end of the trace buffer." (let ((cbuf (current-buffer)) (nbuf proof-trace-buffer)) (set-buffer nbuf) (save-excursion (goto-char (point-max)) (let ((inhibit-read-only t)) (insert ?\n) (insert-buffer-substring cbuf start end) (unless (bolp) (insert ?\n)))) (set-buffer cbuf))) (defun proof-trace-buffer-finish () "Call to complete a batch of tracing output. The buffer is truncated if its size is greater than `proof-trace-buffer-max-lines'." (if (> proof-trace-buffer-max-lines 0) (proof-with-current-buffer-if-exists proof-trace-buffer (save-excursion (goto-char (point-max)) (forward-line (- proof-trace-buffer-max-lines)) (let ((inhibit-read-only t)) (delete-region (point-min) (point))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Theorems buffer ;; ;; [ INCOMPLETE ] ;; ;; Revives an old idea from Isamode: a buffer displaying a bunch ;; of theorem names. ;; ;; (defun pg-thms-buffer-clear () "Clear the theorems buffer." (with-current-buffer proof-thms-buffer (let (start str) (goto-char (point-max)) (newline) (setq start (point)) (insert str) (unless (bolp) (newline)) (set-buffer-modified-p nil)))) (provide 'pg-response) ;;; pg-response.el ends here proofgeneral-4.3~pre130510/generic/pg-user.el000066400000000000000000001356401214562307500207600ustar00rootroot00000000000000 ;;; pg-user.el --- User level commands for Proof General ;; ;; Copyright (C) 2000-2010 LFCS Edinburgh. ;; Copyright (c) 2010 Erik Martin-Dorel, ENS de Lyon (pg-protected-undo). ;; Author: David Aspinall and others ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-user.el,v 12.5 2012/08/14 10:37:25 da Exp $ ;; ;; ;;; Commentary: ;; ;; This file defines some user-level commands. Most of them ;; are script-based operations. Exported user-level commands ;; are defined here as autoloads to avoid circular requires. ;;; Code: (require 'span) (require 'scomint) (require 'proof-script) ; we build on proof-script (require 'cl) (eval-when-compile (require 'completion)) ; Loaded dynamically at runtime. (defvar which-func-modes) ; Defined by which-func. (declare-function proof-segment-up-to "proof-script") (declare-function proof-interrupt-process "proof-shell") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Utilities: moving point in proof script buffer ;; ;; First: 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. ;;;###autoload (defun proof-script-new-command-advance () "Move point to a nice position for a new command, possibly inserting spaces. Assumes that point is at the end of a command. No effect if `proof-next-command-insert-space' is nil." (interactive) (when proof-next-command-insert-space (let (sps) (if (and (proof-next-command-new-line) (setq sps (skip-chars-forward " \t")) ;; don't break existing lines (eolp)) (progn (newline) (unless proof-next-command-on-new-line (indent-relative)))) (unless (proof-next-command-new-line) ;; 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. ; ;; ; Tab columns don't work properly, however. (let ((newspace (max (or sps 1) (skip-chars-forward " \t"))) (p (point))) (insert-char ?\040 newspace) (goto-char p)))))) (defun proof-maybe-follow-locked-end (&optional pos) "Move point according to `proof-follow-mode'. If optional POS is set, use that position, else `proof-queue-or-locked-end'. Assumes script buffer is current." (unless (or proof-autosend-running (eq proof-follow-mode 'ignore)) (let ((dest (or pos (proof-queue-or-locked-end)))) (cond ((eq proof-follow-mode 'locked) (goto-char dest) (or pos (proof-script-next-command-advance))) ((eq proof-follow-mode 'follow) (unless (pos-visible-in-window-p dest) (let ((win (get-buffer-window (current-buffer) t))) (if win (set-window-point win dest))))) ((and (eq proof-follow-mode 'followdown) (> dest (point))) (goto-char dest)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Further movement commands ;; (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-unprocessed-begin))))) ;; 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)) (let ((semis (save-excursion (proof-segment-up-to-using-cache (point))))) (if semis (progn (goto-char (nth 2 (car semis))) (skip-chars-backward " \t\n") (unless (eq (point) (point-min)) (backward-char)))))))) (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))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Processing commands ;; ;;;###autoload (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) (save-excursion (if (> (proof-queue-or-locked-end) (point)) (proof-retract-until-point) (if (proof-only-whitespace-to-locked-region-p) (progn (skip-chars-forward " \t\n") (forward-char 1))) (proof-assert-until-point)))) (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 ; for toolbar/other buffers (save-excursion (goto-char (proof-queue-or-locked-end)) (skip-chars-forward " \t\n") (proof-assert-until-point)) (proof-maybe-follow-locked-end))) ;; NB: "interactive" variant merely for a simple docstring. (defun proof-assert-until-point-interactive () "Process the region from the end of the locked-region until point. If inside a comment, just process until the start of the comment." (interactive) (proof-assert-until-point)) ;;;###autoload (defun proof-process-buffer () "Process the current (or script) buffer, and maybe move point to the end." (interactive) (proof-with-script-buffer (save-excursion (goto-char (point-max)) (proof-assert-until-point-interactive)) (proof-maybe-follow-locked-end)) (when proof-fast-process-buffer (message "Processing buffer...") (proof-shell-wait) (message "Processing buffer...done"))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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 'kill-region)) (defun proof-undo-last-successful-command-1 (&optional undo-action) "Undo last successful command at end of locked region. If optional UNDO-ACTION is non-nil, that function is called on the text region in the proof script after undoing." (interactive "P") (proof-with-script-buffer (let (lastspan) (save-excursion (unless (proof-locked-region-empty-p) (if (setq lastspan (span-at-before (proof-unprocessed-begin) 'type)) (progn (goto-char (span-start lastspan)) (proof-retract-until-point undo-action)) (error "Nothing to undo!")))) (if lastspan (proof-maybe-follow-locked-end (span-start lastspan)))))) (defun proof-retract-buffer (&optional called-interactively) "Retract the current buffer, and maybe move point to the start. Point is only moved according to `proof-follow-mode', if CALLED-INTERACTIVELY is non-nil, which is the case for all interactive calls." ;; The numeric prefix argument "p" is never nil, ;; see Section "Distinguish Interactive Calls" in the Elisp manual. (interactive "p") (proof-with-script-buffer (save-excursion (goto-char (point-min)) (proof-retract-until-point-interactive)) (if called-interactively (proof-maybe-follow-locked-end (point-min))))) (defun proof-retract-current-goal () "Retract the current proof, and move point to its start." (interactive) (let ((span (proof-last-goal-or-goalsave))) (save-excursion (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)) (error "Not proving"))) (if span (proof-maybe-follow-locked-end (span-start span))))) ;; ;; Mouse functions ;; (defun proof-mouse-goto-point (event) "Call `proof-goto-point' on the click position EVENT." (interactive "e") (proof-with-script-buffer (mouse-set-point event) (proof-goto-point) (proof-maybe-follow-locked-end))) ;; ;; Minibuffer non-scripting command ;; (defvar proof-minibuffer-history nil "History of proof commands read from the minibuffer.") (defun proof-minibuffer-cmd (cmd) "Send CMD to proof assistant. Interactively, read from minibuffer. 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-active-p)) (replace-regexp-in-string "[ \t\n]+" " " (buffer-substring (region-beginning) (region-end)))) '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 ;; ;; In fact, it's so risky, we'll disable it by default (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")) (t (proof-set-locked-end (point)) (span-delete-spans (proof-unprocessed-begin) (point-max) 'type)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Non-scripting proof assistant commands. ;;; ;; These are based on defcustom'd settings so that users may ;; re-configure the system to their liking. ;; ;; 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)))) ;;;###autoload (defmacro proof-define-assistant-command (fn doc cmdvar &optional body) "Define FN (docstring DOC) to send BODY to prover, 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))))) ;;;###autoload (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 variable holding 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) (insert cmd) (proof-assert-until-point-interactive) (proof-script-new-command-advance))) ;; ;; 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 (progn (pg-goals-buffers-hint) 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 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. (when proof-shell-cd-cmd (proof-cd) (proof-shell-wait))) ;; ;; Commands which require an argument, and maybe affect the script. ;; (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" ; Goals always start at a new line (let ((proof-next-command-on-new-line t)) (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" ; Saves always start at a new line (let ((proof-next-command-on-new-line t)) (proof-issue-new-command arg))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Electric terminator mode ;; ;; Register proof-electric-terminator as a minor mode. (or (assq 'proof-electric-terminator-enable minor-mode-alist) (setq minor-mode-alist (append minor-mode-alist (list '(proof-electric-terminator-enable (:eval (if (eq major-mode proof-mode-for-script) proof-terminal-string))))))) ;;;###autoload (defun proof-electric-terminator-enable () "Ensure modeline update to display new value for electric terminator. This a function is called by the custom-set property 'proof-set-value." (force-mode-line-update)) (proof-deftoggle proof-electric-terminator-enable proof-electric-terminator-toggle) (defun proof-electric-terminator (&optional count) "Insert terminator char, maybe sending the command to the assistant. If we are inside a comment or string, insert the terminator. Otherwise, if the variable `proof-electric-terminator-enable' is non-nil, the command will be sent to the assistant. To side-step the electric action and possibly insert multiple characters, use a numeric prefix arg, like M-3 ." (interactive "P") (if (and (not count) proof-electric-terminator-enable (not (proof-inside-comment (point))) (not (proof-inside-string (point)))) (proof-assert-electric-terminator) (self-insert-command (prefix-numeric-value count)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Completion based on -completion-table ;; ;; Requires completion.el package. Completion is usually a hand-wavy ;; thing, so we don't attempt to maintain a precise completion table. ;; (defun proof-add-completions () "Add completions from -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; trapping is tricky so test again (if (>= (length cmpl) completion-min-length) (add-completion cmpl -1000 0))) (proof-ass completion-table))) ;; completion not autoloaded in GNU Emacs (or (fboundp 'complete) (autoload 'complete "completion")) ;; NB: completion table is expected to be set when proof-script ;; is loaded! Call `proof-script-add-completions' to update. (unless noninteractive ; during compilation (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))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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))) (if (fboundp 'own-clipboard) ;; XEmacs function (own-clipboard (car kill-ring)))) (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"))))) (defun pg-control-span-of (span) "Return the controlling span of SPAN, or SPAN itself." (or (span-property span 'controlspan) span)) ;; Really a drag-and-drop interface for this would be nice. (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." (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 (span-set-property nextspan 'end-open t) (span-set-property nextspan 'start-open t)) ;; When we delete the span, we want to duplicate it ;; to recreate in the new position. (span-set-property span 'duplicable 't) ;; TODO: this is faulty: moving span up gives children ;; list with single nil element. Hence liveness test (mapc (lambda (s) (if (span-live-p s) (span-set-property s 'duplicable 't))) (span-property span 'children)) (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)) ;; TODO: 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. (span-set-property new-span 'children (pg-fixup-children-spans new-span insertpos (point))) (span-set-end proof-locked-span lockedend) (undo-boundary) new-span))))))) (defun pg-fixup-children-spans (new-parent start end) (append (span-mapcar-spans (lambda (span) (if (span-property span 'controlspan) (progn (span-set-property span 'controlspan new-parent) (list span)))) start end 'type))) (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))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Context menus inside spans ;; (defun pg-pos-for-event (event) "Return position corresponding to position of a mouse click EVENT." (with-current-buffer (window-buffer (posn-window (event-start event))) (posn-point (event-start event)))) (defun pg-span-for-event (event) "Return span corresponding to position of a mouse click EVENT." (span-at (pg-pos-for-event event) 'type)) (defun pg-span-context-menu (event) "Display a context sensitive menu for proof script, around EVENT." (interactive "e") (let* ((span (pg-span-for-event event)) cspan) (when span ;; Find controlling span (while (setq cspan (span-property span 'controlspan)) (setq span cspan)) (let* ((idiom (and span (span-property span 'idiom))) (id (and span (span-property span 'id)))) (popup-menu (pg-create-in-span-context-menu span idiom (if id (symbol-name id)))))))) (defun pg-toggle-visibility () "Toggle visibility of region under point." (interactive) (let* ((span (span-at (point) 'type)) (idiom (and span (span-property span 'idiom))) (id (and span (span-property span 'id)))) (and idiom id (pg-toggle-element-visibility idiom (symbol-name id))))) (defun pg-create-in-span-context-menu (span idiom name) "Create the dynamic context-sensitive menu for a span." (append (list (pg-span-name span)) (list (vector "Show/hide" (if idiom (list 'pg-toggle-element-visibility (quote idiom) name)) (not (not idiom)))) (list (vector "Copy" (list 'pg-copy-span-contents span) t)) (list (vector "Undo" (list 'pg-span-undo span) t)) ;; PG 4.1: these commands are neither very useful nor reliable ;; (list (vector ;; "Move up" (list 'pg-move-span-contents span -1) ;; (pg-numth-span-higher-or-lower (pg-control-span-of span) -1 'noerr))) ;; (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 proof-script-span-context-menu-extensions (funcall proof-script-span-context-menu-extensions span idiom name)) (if proof-shell-theorem-dependency-list-regexp (proof-dependency-in-span-context-menu span)))) (defun pg-span-undo (span) "Undo to the start of the given SPAN." (interactive) (goto-char (span-start span)) (proof-retract-until-point)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Message buffer hints ;; (defun pg-goals-buffers-hint () (pg-hint "Use \\\\[proof-display-some-buffers] to rotate output buffers; \\\\[pg-response-clear-displays] to clear response & trace.")) ;;;###autoload (defun pg-slow-fontify-tracing-hint () (pg-hint "Large tracing output; refreshing intermittently. Use \\\\[pg-response-clear-displays] to clear trace.")) ;;;###autoload (defun pg-response-buffers-hint (&optional nextbuf) (unless (not (buffer-live-p proof-goals-buffer)) (pg-hint (format "\\[proof-prf] for goals;%s \\[proof-layout-windows] refreshes" (if (or proof-three-window-enable proof-multiple-frames-enable) "" (format " \\[proof-display-some-buffers] rotates output%s;" (if nextbuf (concat " (next:" nextbuf ")") ""))))))) ;;;###autoload (defun pg-jump-to-end-hint () (pg-hint "Use \\[proof-goto-end-of-locked] to jump to end of processed region")) ;;;###autoload (defun pg-processing-complete-hint () "Display hint for showing end of locked region or processing complete." (if (buffer-live-p proof-script-buffer) (let ((win (get-buffer-window proof-script-buffer))) (unless ;; end of locked already displayed (and win (pos-visible-in-window-p (proof-unprocessed-begin))) (with-current-buffer proof-script-buffer (cond ((proof-locked-region-empty-p)) ;; nothing if empty ((proof-locked-region-full-p) (pg-hint (concat "Processing complete in " (buffer-name proof-script-buffer)))) ((not proof-autosend-running) ;; partly complete: hint about displaying the locked end (pg-jump-to-end-hint)))))))) ;;;###autoload (defun pg-next-error-hint () "Display hint for locating error." (pg-hint "Use \\[proof-next-error] to go to next error location.")) ;;;###autoload (defun pg-hint (hintmsg) "Display a hint HINTMSG in the minibuffer, if `pg-show-hints' is non-nil. The function `substitute-command-keys' is called on the argument." (if pg-show-hints (message (substitute-command-keys hintmsg)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Symbol near point/identifier under mouse query ;; (defun pg-identifier-under-mouse-query (event) "Query the prover about the identifier near mouse click EVENT." (interactive "e") (if proof-query-identifier-command (save-selected-window (save-selected-frame (save-excursion (mouse-set-point event) (pg-identifier-near-point-query)))))) ;;;###autoload (defun pg-identifier-near-point-query () "Query the prover about the identifier near point. If the result is successful, we add a span to the buffer which has a popup with the information in it." (interactive) (let* ((stend (if (region-active-p) (cons (region-beginning) (region-end)) (pg-current-word-pos))) (start (car-safe stend)) (end (cdr-safe stend)) (identifier (if start (buffer-substring-no-properties start end))) (ctxt (if start (save-excursion (goto-char start) (proof-buffer-syntactic-context))))) (if start (pg-identifier-query identifier ctxt ;; the callback (lexical-let ((s start) (e end)) (lambda (x) (save-excursion (let ((idspan (span-make s e))) (span-set-property idspan 'priority 90) ; highest (span-set-property idspan 'help-echo (pg-last-output-displayform)))))))))) (defvar proof-query-identifier-history nil "History for `proof-query-identifier'.") (defun proof-query-identifier (string) "Query the prover about the identifier STRING. If called interactively, STRING defaults to the current word near point." (interactive (list (completing-read "Query identifier: " nil nil nil (current-word) 'proof-query-identifier-history))) (if string (pg-identifier-query string))) (defun pg-identifier-query (identifier &optional ctxt callback) "Query the proof assisstant about the given IDENTIFIER. This uses `proof-query-identifier-command'. Parameter CTXT allows to give a context for the identifier (which allows for multiple name spaces). If CALLBACK is set, we invoke that when the command completes." (unless (or (null identifier) (string-equal identifier "")) ;; or whitespace? (proof-shell-invisible-command (cond ((stringp proof-query-identifier-command) ;; simple customization (format proof-query-identifier-command identifier)) (t ;; buffer-syntactic context dependent, as an alist ;; (handy for Isabelle: not a true replacement for parsing) (format (nth 1 (assq ctxt proof-query-identifier-command)) identifier))) nil ; no wait callback))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Imenu and Speedbar ;; (eval-after-load "speedbar" '(and proof-assistant-symbol ;; *should* be set by now (speedbar-add-supported-extension (nth 2 (assoc proof-assistant-symbol proof-assistant-table))))) ;;;###autoload (defun proof-imenu-enable () "Add or remove index menu." ;; NB: next two a bit interferring, but we suppose use-case is PG. (which-function-mode (if proof-imenu-enable 1 0)) (when (listp which-func-modes) ;; FIXME: It's not PG's business to decide whether to use ;; which-function-mode. (add-to-list 'which-func-modes proof-mode-for-script)) (if proof-imenu-enable (imenu-add-to-menubar "Index") (progn (when (listp which-func-modes) (setq which-func-modes (remove proof-mode-for-script which-func-modes))) (let ((oldkeymap (keymap-parent (current-local-map)))) (if ;; sanity checks in case someone else set local keymap (and oldkeymap (lookup-key (current-local-map) [menu-bar index]) (not (lookup-key oldkeymap [menu-bar index]))) (use-local-map oldkeymap))) (remove-hook 'menu-bar-update-hook 'imenu-update-menubar)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Command history ;; ;; This implements a history ring for commands in the locked region. ;; Inspired by (and code heavily copied from) comint. ;; ;; The current behaviour is not ideal: we only extend the input ring as ;; we process (so history does not browse pink text while the ;; prover is busy). Moreover, instead of using a history, we might ;; simply parse commands backwards (or forwards) in the buffer. ;; (i.e, more like the copying behaviour implemented in Bibtex mode). ;; (defvar pg-input-ring nil "Ring of previous inputs.") (defvar pg-input-ring-index nil "Position of last matched command.") (defvar pg-stored-incomplete-input nil "Stored incomplete input: string between point and locked.") (defun pg-previous-input (arg) "Cycle backwards through input history, saving input." (interactive "*p") (if (and pg-input-ring-index (or ; leaving the "end" of the ring (and (< arg 0) ; going down (eq pg-input-ring-index 0)) (and (> arg 0) ; going up (eq pg-input-ring-index (1- (ring-length pg-input-ring))))) pg-stored-incomplete-input) (pg-restore-input) (pg-previous-matching-input "." arg))) (defun pg-next-input (arg) "Cycle forwards through input history." (interactive "*p") (pg-previous-input (- arg))) (defun pg-delete-input () (let* ((unproc (proof-unprocessed-begin)) (start (save-excursion (goto-char unproc) (skip-chars-forward " \t\n") (point))) (end (point-at-eol))) (cond ((< start end) (delete-region start end)) ((< start (point-at-eol)) (delete-region start (point-at-eol)))))) (defun pg-get-old-input () "Return text between end of locked region and point, up to EOL. If there is no text, return the empty string." (let* ((unproc (proof-unprocessed-begin)) (start (save-excursion (goto-char unproc) (skip-chars-forward " \t\n") (point))) (end (point-at-eol))) (if (< start end) (buffer-substring-no-properties start end) nil))) (defun pg-restore-input () "Restore unfinished input." (interactive) (when pg-input-ring-index (pg-delete-input) (when (> (length pg-stored-incomplete-input) 0) (insert pg-stored-incomplete-input) (message "Input restored")) (setq pg-input-ring-index nil))) (defun pg-search-start (arg) "Index to start a directional search, starting at `pg-input-ring-index'." (if pg-input-ring-index ;; If a search is running, offset by 1 in direction of arg (mod (+ pg-input-ring-index (if (> arg 0) 1 -1)) (ring-length pg-input-ring)) ;; For a new search, start from beginning or end, as appropriate (if (>= arg 0) 0 ; First elt for forward search (1- (ring-length pg-input-ring))))) ; Last elt for backward search (defun pg-regexp-arg (prompt) "Return list of regexp and prefix arg using PROMPT." (let* (;; Don't clobber this. (last-command last-command) (regexp (read-from-minibuffer prompt nil nil nil 'minibuffer-history-search-history))) (list (if (string-equal regexp "") (setcar minibuffer-history-search-history (nth 1 minibuffer-history-search-history)) regexp) (prefix-numeric-value current-prefix-arg)))) (defun pg-search-arg (arg) ;; First make sure there is a ring and that we are after the process mark (cond ((not (>= (point) (proof-unprocessed-begin))) (error "Not in unlocked region")) ((or (null pg-input-ring) (ring-empty-p pg-input-ring)) (error "Empty input ring")) ((zerop arg) ;; arg of zero resets search from beginning, and uses arg of 1 (setq pg-input-ring-index nil) 1) (t arg))) (defun pg-previous-matching-input-string-position (regexp arg &optional start) "Return the index matching REGEXP ARG places along the input ring. Moves relative to START, or `pg-input-ring-index'." (if (or (not (ring-p pg-input-ring)) (ring-empty-p pg-input-ring)) (error "No history")) (let* ((len (ring-length pg-input-ring)) (motion (if (> arg 0) 1 -1)) (n (mod (- (or start (pg-search-start arg)) motion) len)) (tried-each-ring-item nil) (prev nil)) ;; Do the whole search as many times as the argument says. (while (and (/= arg 0) (not tried-each-ring-item)) ;; Step once. (setq prev n n (mod (+ n motion) len)) ;; If we haven't reached a match, step some more. (while (and (< n len) (not tried-each-ring-item) (not (string-match regexp (ring-ref pg-input-ring n)))) (setq n (mod (+ n motion) len) ;; If we have gone all the way around in this search. tried-each-ring-item (= n prev))) (setq arg (if (> arg 0) (1- arg) (1+ arg)))) ;; Now that we know which ring element to use, if we found it, return that. (if (string-match regexp (ring-ref pg-input-ring n)) n))) (defun pg-previous-matching-input (regexp n) "Search backwards through input history for match for REGEXP. \(Previous history elements are earlier commands.) With prefix argument N, search for Nth previous match. If N is negative, find the next or Nth next match." (interactive (pg-regexp-arg "Previous input matching (regexp): ")) (setq n (pg-search-arg n)) (let ((pos (pg-previous-matching-input-string-position regexp n))) ;; Has a match been found? (if (null pos) (error "Match not found for regexp %s" regexp) ;; If leaving the edit line, save partial input (if (null pg-input-ring-index) ;not yet on ring (setq pg-stored-incomplete-input (pg-get-old-input))) (setq pg-input-ring-index pos) (message "History item: %d" (1+ pos)) (pg-delete-input) (insert (ring-ref pg-input-ring pos))))) (defun pg-next-matching-input (regexp n) "Search forwards through input history for match for REGEXP. \(Later history elements are more recent commands.) With prefix argument N, search for Nth following match. If N is negative, find the previous or Nth previous match." (interactive (pg-regexp-arg "Next input matching (regexp): ")) (pg-previous-matching-input regexp (- n))) (defvar pg-matching-input-from-input-string "" "Input previously used to match input history.") ;;;###autoload (defun pg-previous-matching-input-from-input (n) "Search backwards through input history for match for current input. \(Previous history elements are earlier commands.) With prefix argument N, search for Nth previous match. If N is negative, search forwards for the -Nth following match." (interactive "p") (if (not (memq last-command '(pg-previous-matching-input-from-input pg-next-matching-input-from-input))) ;; Starting a new search (setq pg-matching-input-from-input-string (pg-get-old-input) pg-input-ring-index nil)) (if pg-matching-input-from-input-string (pg-previous-matching-input (concat "^" (regexp-quote pg-matching-input-from-input-string)) n) (pg-previous-matching-input "." n))) ;;;###autoload (defun pg-next-matching-input-from-input (n) "Search forwards through input history for match for current input. \(Following history elements are more recent commands.) With prefix argument N, search for Nth following match. If N is negative, search backwards for the -Nth previous match." (interactive "p") (pg-previous-matching-input-from-input (- n))) ;;;###autoload (defun pg-add-to-input-history (cmd) "Maybe add CMD to the input history. CMD is only added to the input history if it is not a duplicate of the last item added." (when (or (not (ring-p pg-input-ring)) (ring-empty-p pg-input-ring) (not (string-equal (ring-ref pg-input-ring 0) cmd))) (unless (ring-p pg-input-ring) (setq pg-input-ring (make-ring pg-input-ring-size))) (ring-insert pg-input-ring cmd))) ;;;###autoload (defun pg-remove-from-input-history (cmd) "Maybe remove CMD from the end of the input history. This is called when the command is undone. It's only removed if it matches the last item in the ring." (if (and (ring-p pg-input-ring) (not (ring-empty-p pg-input-ring)) (string-equal (ring-ref pg-input-ring 0) cmd)) (ring-remove pg-input-ring 0))) ;;;###autoload (defun pg-clear-input-ring () (setq pg-input-ring nil)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Protected undo (added in PG 4.0) ;; ;; From a suggestion of Stefan Monnier as an improvement over the ;; previous use of `undo-make-selective-list' to hack ;; `buffer-undo-list' in `proof-set-queue-endpoints'. ;; ;; Improved version due to Erik Martin-Dorel. Uses auxiliary ;; functions `pg-protected-undo-1' and `next-undo-elt' ;; (define-key proof-mode-map [remap undo] 'pg-protected-undo) (define-key proof-mode-map [remap advertised-undo] 'pg-protected-undo) (defun pg-protected-undo (&optional arg) "As `undo' but avoids breaking the locked region. It performs each of the desired undos checking that these operations will not affect the locked region, obeying `proof-strict-read-only' if required. If strict read only behaviour is enforced, the user is queried whether to retract before the undo is allowed. If automatic retraction is enabled, the retract and undo will go ahead without querying the user. Moreover, undo/redo is always allowed in comments located in \ the locked region." (interactive "*P") (if (or (not proof-locked-span) (equal (proof-queue-or-locked-end) (point-min))) (undo arg) (let ((repeat ; Allow the user to perform successive undos at once (if (numberp arg) (prefix-numeric-value arg) ; arg is a raw prefix argument 1)) (newarg ; Allow the user to limit the undo to the current region (and ;; this Boolean expression is necessary to match ;; the behavior of GNU Emacs (23.2) undo function (or (region-active-p) (and arg (not (numberp arg)))) (> (region-end) (region-beginning))))) (while (> repeat 0) (pg-protected-undo-1 newarg) ; do some safe undos step by step (setq last-command 'undo) ; need for this assignment meanwhile (decf repeat))))) (defun pg-protected-undo-1 (arg) "This function is intended to be called by `pg-protected-undo'. The flag ARG is passed to functions `undo' and `next-undo-elt'. It should be a non-numeric value saying whether an undo-in-region behavior is expected." ;; Note that if ARG is non-nil, (> (region-end) (region-beginning)) must hold, ;; at least for the first call from the loop of `pg-protected-undo'. (setq arg (and arg (not (numberp arg)))) ; ensure arg is boolean (if (or (not proof-locked-span) (equal (proof-queue-or-locked-end) (point-min))) ; required test (undo arg) (let* ((next (next-undo-elt arg)) (delta (undo-delta next)) ; can be '(0 . 0) if next is nil (beg (car delta)) (end (max beg (- beg (cdr delta))))) ; Key computation (when (and next (> beg 0) ; the "next undo elt" exists (> (proof-queue-or-locked-end) beg) proof-strict-read-only ; edit freely doesn't retract (not (and ; neither does edit in comments (proof-inside-comment beg) (proof-inside-comment end)))) (if (or (eq proof-strict-read-only 'retract) (y-or-n-p "Next undo will modify read-only region, retract? ")) (proof-retract-before-change beg end) (when (eq last-command 'undo) (setq this-command 'undo)) ;; now we can stop the function without breaking possible undo chains (error "Cannot undo without retracting to the appropriate position."))) (undo arg)))) (defun next-undo-elt (arg) "Returns the undo element that will be processed on next undo/redo, assuming the undo-in-region behavior will apply if ARG is non-nil." (let ((undo-list (if arg ; handle "undo in region" (undo-make-selective-list (region-beginning) (region-end)) ; can be '(nil) buffer-undo-list))) ; can be nil (if (or (null undo-list) (equal undo-list (list nil))) nil ; there is clearly no undo elt (while (eq (car undo-list) nil) (setq undo-list (cdr undo-list))) ; get the last undo record (if (and (eq last-command 'undo) (or (eq pending-undo-list t) (gethash undo-list undo-equiv-table))) ;; then we are within a run of consecutive undo commands (if (eq pending-undo-list t) nil (car pending-undo-list)) (car undo-list))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Automatic processing of buffer ahead of point ;; ;; Added in PG 4.0 ;; (defvar proof-autosend-timer nil "Timer used by autosend.") (deflocal proof-autosend-modified-tick nil "Records 'buffer-chars-modified-tick' since last autosend.") ;;;###autoload (defun proof-autosend-enable (&optional nomsg) "Enable or disable autosend behaviour." (if proof-autosend-timer (cancel-timer proof-autosend-timer)) (when proof-autosend-enable (setq proof-autosend-timer (run-with-idle-timer proof-autosend-delay t 'proof-autosend-loop)) (setq proof-autosend-modified-tick nil) (unless nomsg (message "Automatic sending turned on."))) (when (not proof-autosend-enable) (setq proof-autosend-timer nil) (unless nomsg (message "Automatic sending turned off.")))) (defun proof-autosend-delay () "Adjust autosend timer when variable `proof-autosend-delay' changes." (proof-autosend-enable t)) (defun proof-autosend-loop () (proof-with-current-buffer-if-exists proof-script-buffer (unless (or (proof-locked-region-full-p) proof-shell-busy ;; TODO: re-engage autosend after C-c C-n even if not modified. (eq (buffer-chars-modified-tick) proof-autosend-modified-tick) (and proof-autosend-all (eq proof-shell-last-queuemode 'retracting))) (let ((proof-autosend-running t)) (setq proof-autosend-modified-tick (buffer-chars-modified-tick)) (if proof-autosend-all (proof-autosend-loop-all) (proof-autosend-loop-next)))))) (defun proof-autosend-loop-all () "Send commands from the script until an error, complete, or input appears." (message "Sending commands to prover...") (unwind-protect (progn (save-excursion (goto-char (point-max)) (proof-assert-until-point (if proof-multiple-frames-enable 'no-minibuffer-messages ; nb: not API '(no-response-display no-error-display no-goals-display)))) (proof-shell-wait t) ; interruptible (cond ((eq proof-shell-last-output-kind 'error) (message "Sending commands to prover...error")) ((and (input-pending-p) proof-shell-busy) (proof-interrupt-process) (message "Sending commands to prover...interrupted") (proof-shell-wait)) (t (message "Sending commands to prover...done")))))) (defun proof-autosend-loop-next () "Send the next command from the script and indicate its success/otherwise." (unwind-protect (let ((qol (proof-queue-or-locked-end))) (save-excursion ;(goto-char qol) ;(skip-chars-forward " \t\n") (message "Trying next commands in prover...") (proof-assert-until-point (if proof-multiple-frames-enable 'no-minibuffer-messages ; nb: not API '(no-response-display no-error-display no-goals-display)))) (let ((proof-sticky-errors t)) (proof-shell-wait t)) ; interruptible (cond ((eq proof-shell-last-output-kind 'error) (message "Trying next commands in prover...error")) ((and (input-pending-p) proof-shell-busy) (proof-interrupt-process) (message "Trying next commands in prover...interrupted") (proof-shell-wait)) (t (message "Trying next commands in prover...OK"))) ;; success: now undo in prover, highlight undone spans if OK (unless (eq qol (proof-queue-or-locked-end)) ; no progress (save-excursion (goto-char qol) (proof-retract-until-point (lambda (beg end) (span-make-self-removing-span (save-excursion (goto-char beg) (skip-chars-forward " \t\n") (point)) end 'face 'highlight)) '(no-response-display no-error-display no-goals-display))))))) (provide 'pg-user) ;;; pg-user.el ends here proofgeneral-4.3~pre130510/generic/pg-vars.el000066400000000000000000000240041214562307500207440ustar00rootroot00000000000000;;; pg-vars.el --- Proof General global variables ;; ;; Copyright (C) 2008, 2010 LFCS Edinburgh. ;; Author: David Aspinall and others ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-vars.el,v 12.1 2012/09/02 21:06:35 da Exp $ ;; ;;; Commentary: ;; ;; Global variables used in several files. ;; ;; ;;; Code: ;;; ;;; Early variables ;;; (defvar 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.") (defvar 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.") (defvar 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 names given in `proof-assistant-table'.") (defvar 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. Non-nil indicates PG has been initialised for an assistant. If this is nil, the hook functions in `proof-ready-for-assistant-hook' are yet to be run. 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'.") (defvar proof-mode-for-shell nil "Mode function for proof shell buffers. Do not change this variable! It is set automatically by the mode stub defined in proof-site to -shell-mode.") (defvar proof-mode-for-response nil "Mode function for proof response buffer (and trace buffer, if used). Do not change this variable! It is set automatically by the mode stub defined in proof-site to -response-mode.") (defvar proof-mode-for-goals nil "Mode for proof state display buffers. Do not change this variable! It is set automatically by the mode stub defined in proof-site to -goals-mode.") (defvar proof-mode-for-script nil "Mode for proof script buffers. Do not change this variable! It is set automatically by the mode stub defined in proof-site to -mode.") (defvar proof-ready-for-assistant-hook nil "Hook functions to run after PG is configured for a proof assistant. These functions allow late initialisation, once the choice of prover has been set.") ;;; ;;; Later variables ;;; (could be separated to cut down Emacs env pollution) ;;; (defvar proof-shell-busy nil "A lock indicating that the proof shell is processing. The lock notes that we are processing a queue of commands being sent to the prover, and indicates whether the commands correspond to script management from a buffer (rather than being ad-hoc query commands to the prover). When processing commands from a buffer for script management, this will be set to the queue mode 'advancing or 'retracting to indicate the direction of movement. When this is non-nil, `proof-shell-ready-prover' will give an error if called with a different requested queue mode. See also functions `proof-activate-scripting' and `proof-shell-available-p'.") (defvar proof-shell-last-queuemode nil "Flag indicating last direction of proof queue. This is actually the last non-nil value of `proof-shell-busy'.") (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. This can be used to help multiple file handling.") (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-thms-buffer nil "A buffer for displaying a list of theorems from the proof assistant. See `proof-shell-thm-display-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 pg-response-next-error nil "Error counter in response buffer to count for next error message.") (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).") ;; ;; Internal variables ;; -- usually local to a couple of modules and perhaps inspected ;; by prover modes ;; -- here to avoid compiler warnings and minimise requires. ;; (defvar proof-shell-silent nil "A flag, non-nil if PG thinks the prover is silent.") (defvar proof-shell-last-prompt "" "A raw record of the last prompt seen from the proof system. This is the string matched by `proof-shell-annotated-prompt-regexp'.") (defvar proof-shell-last-output "" "A record of the last string seen from the proof system. This is raw string, for internal use only.") (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 '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-handle-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-assistant-settings nil "Settings kept in Proof General for current proof assistant. A list of lists (SYMBOL SETTING TYPE DESCR) 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 (this is an Emacs widget type) and the DESCR description string is used as a help tooltip in the settings menu. This list is extended by the `defpacustom' macro.") (defvar pg-tracing-slow-mode nil "Non-nil for slow refresh mode for tracing output.") (defvar proof-nesting-depth 0 "Current depth of a nested proof. Zero means outside a proof, 1 means inside a top-level proof, etc. This variable is maintained in `proof-done-advancing'; it is zeroed in `proof-shell-clear-state'.") (defvar proof-last-theorem-dependencies nil "Contains the dependencies of the last theorem. A list of strings. Set in `proof-shell-process-urgent-message'.") (defvar proof-autosend-running nil "Flag indicating we are sending commands to the prover automatically. Used in `proof-autosend-loop' and inspected in other places to inhibit user interaction.") (defvar proof-next-command-on-new-line nil "Indicate that `proof-script-new-command-advance' should make a newline. Internal variable dynamically bound.") ;; ;; Not variables at all: global constants (were in proof-config) ;; (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://proofgeneral.inf.ed.ac.uk" "*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) (defcustom proof-universal-keys '(([(control c) ?`] . proof-next-error) ([(control c) (control c)] . proof-interrupt-process) ([(control c) (control n)] . proof-assert-next-command-interactive) ([(control c) (control u)] . proof-undo-last-successful-command) ([(control c) (control p)] . proof-prf) ([(control c) (control l)] . proof-layout-windows) ([(control c) (control x)] . proof-shell-exit) ([(control c) (control v)] . proof-minibuffer-cmd) ([(control c) (control w)] . pg-response-clear-displays) ([(control c) (control ?.)] . proof-goto-end-of-locked) ([(control c) (control f)] . proof-find-theorems) ([(control c) (control o)] . proof-display-some-buffers) ([(control shift mouse-1)] . pg-identifier-under-mouse-query)) "List of key bindings made for all proof general buffers. 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) (provide 'pg-vars) ;;; pg-vars.el ends here proofgeneral-4.3~pre130510/generic/pg-xml.el000066400000000000000000000163611214562307500206000ustar00rootroot00000000000000;; pg-xml.el --- XML functions for Proof General ;; ;; Copyright (C) 2000-2002 LFCS Edinburgh. ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-xml.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; ;; XML functions for Proof General. ;; (require 'cl) (require 'xml) (require 'proof-utils) ;; for pg-internal-warning (defalias 'pg-xml-error 'error) ;; ;; Elisp format of XML trees (see xml.el) ;; ;; xml-list ::= (node node ...) ;; node ::= (qname attribute-list . child_node_list) ;; child_node_list ::= child_node child_node ... ;; child_node ::= node | string ;; qname ::= (:namespace-uri . "name") | "name" ;; attribute_list ::= ((qname . "value") (qname . "value") ...) ;; | nil ;; string ::= "..." ;; ;; NB [da]: without namespace aware parsing, qnames are symbols. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Parsing function: pg-xml-parse-buffer ;; ;;;###autoload (defun pg-xml-parse-string (arg) "Parse string in ARG, same as pg-xml-parse-buffer." (let ((tempbuffer (get-buffer-create " *xml-parse*"))) (with-current-buffer tempbuffer (delete-region (point-min) (point-max)) (insert arg) (pg-xml-parse-buffer (current-buffer) 'nomessage)))) (defun pg-xml-parse-buffer (&optional buffer nomsg start end) "Parse an XML documment in BUFFER (defaulting to current buffer). Parsing according to `xml-parse-file' of xml.el. Optional START and END bound the parse." (unless nomsg (message "Parsing %s..." (buffer-name buffer))) (let ((xml (xml-parse-region (or start (point-min)) (or end (point-max)) (or buffer (current-buffer)) nil))) (unless nomsg (message "Parsing %s...done" (buffer-name buffer))) xml)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Helper functions for parsing ;; (defun pg-xml-get-attr (attribute node &optional optional defaultval) (let ((val (cdr (assoc attribute (xml-node-attributes node))))) (or val (if optional defaultval (pg-xml-error "pg-xml-get-attr: Didn't find required %s attribute in %s element" attribute (xml-node-name node)))))) (defun pg-xml-child-elts (node) "Return list of *element* children of NODE (ignoring strings)." (let ((children (xml-node-children node))) (mapcan (lambda (x) (if (listp x) (list x))) children))) (defun pg-xml-child-elt (node) "Return unique element child of NODE." (let ((children (pg-xml-child-elts node))) (if (= (length children) 1) (car children) (pg-internal-warning "pg-xml-child-elt: expected single element child of %s" (xml-node-name node))))) (defun pg-xml-get-child (child node) "Return single element CHILD of node, give error if more than one." (let ((children (xml-get-children node child))) (if (> (length children) 1) (progn (pg-internal-warning "pg-xml-get-child: got more than one %s child of %s node, ignoring rest" child (xml-node-name node)) (car children)) children))) (defun pg-xml-get-text-content (node) "Return the concatenation of all the text children of node NODE." (mapconcat (lambda (x) (if (stringp x) x "")) (xml-node-children node) "")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Producing functions: constructing an XML tree in xml.el format ;; and converting to a string (defmacro pg-xml-attr (name val) `(cons (quote ,name) ,val)) (defmacro pg-xml-node (name atts children) `(cons (quote ,name) (cons ,atts ,children))) (defconst pg-xml-header "\n") (defun pg-xml-string-of (xmls) "Convert the XML trees in XMLS into a string (without additional indentation)." (let* (strs (insertfn (lambda (&rest args) (setq strs (cons (reduce 'concat args) strs))))) (dolist (xml xmls) (pg-xml-output-internal xml nil insertfn)) (reduce 'concat (reverse strs)))) ;; based on xml-debug-print from xml.el (defun pg-xml-output-internal (xml indent-string outputfn) "Outputs the XML tree using OUTPUTFN, which should accept a list of args. Output with indentation INDENT-STRING (or none if nil)." (let ((tree xml) attlist) (funcall outputfn (or indent-string "") "<" (symbol-name (xml-node-name tree))) ;; output the attribute list (setq attlist (xml-node-attributes tree)) (while attlist (funcall outputfn " ") (funcall outputfn (symbol-name (caar attlist)) "=\"" (cdar attlist) "\"") (setq attlist (cdr attlist))) (setq tree (xml-node-children tree)) (if tree (progn (funcall outputfn ">") ;; output the children (dolist (node tree) (cond ((listp node) (if indent-string (funcall outputfn "\n")) (pg-xml-output-internal node (if indent-string (concat indent-string " ")) outputfn)) ((stringp node) (funcall outputfn node)) (t (error "pg-xml-output-internal: Invalid XML tree")))) (funcall outputfn (if indent-string (concat "\n" indent-string) "") "")) (funcall outputfn "/>")))) (defun pg-xml-cdata (str) (concat " child of NODE, or nil if none." (pg-xml-get-child 'icon node)) (defsubst pg-pgip-get-name (node &optional optional defaultval) (pg-xml-get-attr 'name node optional defaultval)) (defsubst pg-pgip-get-version (node &optional optional defaultval) (pg-xml-get-attr 'version node optional defaultval)) (defsubst pg-pgip-get-descr (node &optional optional defaultval) (pg-xml-get-attr 'descr node optional defaultval)) (defsubst pg-pgip-get-thmname (node &optional optional defaultval) (pg-xml-get-attr 'thmname node optional defaultval)) (defsubst pg-pgip-get-thyname (node &optional optional defaultval) (pg-xml-get-attr 'thmname node optional defaultval)) (defsubst pg-pgip-get-url (node &optional optional defaultval) (pg-xml-get-attr 'url node optional defaultval)) (defsubst pg-pgip-get-srcid (node &optional optional defaultval) (pg-xml-get-attr 'srcid node optional defaultval)) (defsubst pg-pgip-get-proverid (node &optional optional defaultval) (pg-xml-get-attr 'proverid node optional defaultval)) (defsubst pg-pgip-get-symname (node &optional optional defaultval) (pg-xml-get-attr 'name node optional defaultval)) (defsubst pg-pgip-get-prefcat (node &optional optional defaultval) (pg-xml-get-attr 'prefcategory node optional defaultval)) (defsubst pg-pgip-get-default (node &optional optional defaultval) (pg-xml-get-attr 'default node optional defaultval)) (defsubst pg-pgip-get-objtype (node &optional optional defaultval) (pg-xml-get-attr 'objtype node optional defaultval)) (defsubst pg-pgip-get-value (node) (pg-xml-get-text-content node)) (defalias 'pg-pgip-get-displaytext 'pg-pgip-get-pgmltext) (defun pg-pgip-get-pgmltext (node) ;; TODO: fetch text or markup XML with text properties (pg-xml-get-text-content node)) (provide 'pg-xml) ;;; pg-xml.el ends here proofgeneral-4.3~pre130510/generic/proof-autoloads.el000066400000000000000000001042061214562307500225060ustar00rootroot00000000000000;;; proof-autoloads.el --- automatically extracted autoloads ;; ;;; Code: (if (featurep 'proof-autoloads) (error "Already loaded")) (eval-when-compile (require 'cl)) (eval-when (compile) (require 'pg-vars) (require 'proof-config) (require 'scomint)) (provide 'proof-autoloads) ;;;### (autoloads (bufhist-exit bufhist-init bufhist-mode) "bufhist" ;;;;;; "../lib/bufhist.el" (20118 50210)) ;;; Generated autoloads from ../lib/bufhist.el (autoload 'bufhist-mode "bufhist" "\ Minor mode retaining an in-memory history of the buffer contents. Commands:\\ \\[bufhist-prev] bufhist-prev go back in history \\[bufhist-next] bufhist-next go forward in history \\[bufhist-first] bufhist-first go to first item in history \\[bufhist-last] bufhist-last go to last (current) item in history. \\[bufhist-clear] bufhist-clear clear history. \\[bufhist-delete] bufhist-clear delete current item from history. \(fn &optional ARG)" t nil) (autoload 'bufhist-init "bufhist" "\ Initialise a ring history for the current buffer. The history will be read-only unless READWRITE is non-nil. For read-only histories, edits to the buffer switch to the latest version. The size defaults to `bufhist-ring-size'. \(fn &optional READWRITE RINGSIZE)" t nil) (autoload 'bufhist-exit "bufhist" "\ Stop keeping ring history for current buffer. \(fn)" t nil) ;;;*** ;;;### (autoloads (holes-insert-and-expand holes-abbrev-complete ;;;;;; holes-mode holes-set-make-active-hole) "holes" "../lib/holes.el" ;;;;;; (20118 50210)) ;;; Generated autoloads from ../lib/holes.el (autoload 'holes-set-make-active-hole "holes" "\ Make a new hole between START and END or at point, and make it active. \(fn &optional START END)" t nil) (autoload 'holes-mode "holes" "\ Toggle Holes minor mode. With arg, turn Outline minor mode on if arg is positive, off otherwise. The mode `holes-mode' is meant to help program editing. It is useful to build complicated expressions by copy pasting several peices of text from different parts of a buffer (or even from different buffers). HOLES A hole is a piece of (highlighted) text that may be replaced by another part of text later. There is no information stored on the file for holes, so you can save and modify files containing holes with no harm... You can even insert or delete characters inside holes like any other characters. USE At any time only one particular hole, called \"active\", can be \"filled\". Holes can be in several buffers but there is always one or zero active hole globally. It is highlighted with a different color. Functions described below have default shortcuts when `holes-mode' is on that you can customize. TO DEFINE A HOLE, two methods: o Select a region with keyboard or mouse, then use \\[holes-set-make-active-hole]. If the selected region is empty, then a hole containing # is created at point. o Select text with mouse while pressing ctrl and meta (`C-M-select'). If the selected region is empty (i.e. if you just click while pressing ctrl+meta), then a hole containing # is created. TO ACTIVATE A HOLE, click on it with the button 1 of your mouse. The previous active hole will be deactivated. TO FORGET A HOLE without deleting its text, click on it with the button 2 (middle) of your mouse. TO DESTROY A HOLE and delete its text, click on it with the button 3 of your mouse. TO FILL A HOLE with a text selection, first make sure it is active, then two methods: o Select text with keyboard or mouse and hit \\[holes-replace-update-active-hole] o Select text with mouse while pressing ctrl, meta and shift (`C-M-S-select'). This is a generalization of the `mouse-track-insert' feature of XEmacs. This method allows you to fill different holes faster than with the usual copy-paste method. After replacement the next hole is automatically made active so you can fill it immediately by hitting again \\[holes-replace-update-active-hole] or `C-M-S-select'. TO JUMP TO THE ACTIVE HOLE, just hit \\[holes-set-point-next-hole-destroy]. You must be in the buffer containing the active hole. the point will move to the active hole, and the active hole will be destroyed so you can type something to put at its place. The following hole is automatically made active, so you can hit \\[holes-set-point-next-hole-destroy] again. It is useful in combination with abbreviations. For example in `coq-mode' \"fix\" is an abbreviation for Fixpoint # (# : #) {struct #} : # := #, where each # is a hole. Then hitting \\[holes-set-point-next-hole-destroy] goes from one hole to the following and you can fill-in each hole very quickly. COMBINING HOLES AND SKELETONS `holes' minor mode is made to work with minor mode `skeleton' minor mode. KNOWN BUGS o Don't try to make overlapping holes, it doesn't work. (what would it mean anyway?) o Cutting or pasting a hole will not produce new holes, and undoing on holes cannot make holes re-appear. \(fn &optional ARG)" t nil) (autoload 'holes-abbrev-complete "holes" "\ Complete abbrev by putting holes and indenting. Moves point at beginning of expanded text. Put this function as call-back for your abbrevs, and just expanded \"#\" and \"@{..}\" will become holes. \(fn)" nil nil) (autoload 'holes-insert-and-expand "holes" "\ Insert S, expand it and replace #s and @{]s by holes. \(fn S)" nil nil) ;;;*** ;;;### (autoloads (maths-menu-mode) "maths-menu" "../lib/maths-menu.el" ;;;;;; (20118 50210)) ;;; Generated autoloads from ../lib/maths-menu.el (autoload 'maths-menu-mode "maths-menu" "\ Install a menu for entering mathematical characters. Uses window system menus only when they can display multilingual text. Otherwise the menu-bar item activates the text-mode menu system. This mode is only useful with a font which can display the maths repertoire. \(fn &optional ARG)" t nil) ;;;*** ;;;### (autoloads (proof-associated-windows proof-associated-buffers) ;;;;;; "pg-assoc" "pg-assoc.el" (20118 50210)) ;;; Generated autoloads from pg-assoc.el (autoload 'proof-associated-buffers "pg-assoc" "\ Return a list of the associated buffers. Some may be dead/nil. \(fn)" nil nil) (autoload 'proof-associated-windows "pg-assoc" "\ Return a list of the associated buffers windows. Dead or nil buffers are not represented in the list. \(fn)" nil nil) ;;;*** ;;;### (autoloads (profile-pg) "pg-dev" "../lib/pg-dev.el" (20118 ;;;;;; 50210)) ;;; Generated autoloads from ../lib/pg-dev.el (autoload 'profile-pg "pg-dev" "\ Configure Proof General for profiling. Use M-x elp-results to see results. \(fn)" t nil) ;;;*** ;;;### (autoloads (proof-goals-config-done) "pg-goals" "pg-goals.el" ;;;;;; (20118 50210)) ;;; Generated autoloads from pg-goals.el (autoload 'proof-goals-config-done "pg-goals" "\ Initialise the goals buffer after the child has been configured. \(fn)" nil nil) ;;;*** ;;;### (autoloads (pg-movie-export-directory pg-movie-export-from ;;;;;; pg-movie-export) "pg-movie" "pg-movie.el" (20123 64158)) ;;; Generated autoloads from pg-movie.el (autoload 'pg-movie-export "pg-movie" "\ Export the movie file from the current script buffer. If FORCE, overwrite existing file without asking. \(fn &optional FORCE)" t nil) (autoload 'pg-movie-export-from "pg-movie" "\ Export the movie file that results from processing SCRIPT. \(fn SCRIPT &optional FORCE)" t nil) (autoload 'pg-movie-export-directory "pg-movie" "\ Export movie files from directory DIR with extension EXTN. Existing XML files are overwritten. \(fn DIR EXTN)" t nil) ;;;*** ;;;### (autoloads (defpacustom proof-defpacustom-fn) "pg-pamacs" ;;;;;; "pg-pamacs.el" (20118 50210)) ;;; Generated autoloads from pg-pamacs.el (autoload 'proof-defpacustom-fn "pg-pamacs" "\ As for macro `defpacustom' but evaluating arguments. \(fn NAME VAL ARGS)" nil nil) (autoload 'defpacustom "pg-pamacs" "\ Define a setting NAME for the current proof assistant, default VAL. Mainly intended for configuring settings of running provers, which can be changed by sending commands. In this case, NAME stands for the internal setting, flag, etc, for the proof assistant, and a :setting and :type value should be provided. The :type of NAME should be one of 'integer, 'float, 'boolean, 'string. The function `proof-assistant-format' is used to format VAL. This macro invokes the standard Emacs `defcustom' macro, so this also defines a customizable setting inside Emacs. The customization variable is automatically put into the group named after the prover. If NAME corresponds instead to a PG internal setting, then a form :eval to evaluate can be provided instead. Additional properties in the ARGS prop list may include: pggroup string A grouping name for the setting, in case there are many. For example, \"Timing\", \"Tracing\", etc. Used to generate sub-menus in the UI. pgipgcmd string Alternative to :setting. Send a PGIP formatted command based on given string. pgdynamic flag If flag is non-nil, this setting is a dynamic one that is particular to the running instance of the prover. Automatically set by preferences configured from PGIP askprefs message. This macro also extends the `proof-assistant-settings' list. \(fn NAME VAL &rest ARGS)" nil (quote macro)) ;;;*** ;;;### (autoloads (pg-pgip-askprefs pg-pgip-maybe-askpgip pg-pgip-process-packet) ;;;;;; "pg-pgip" "pg-pgip.el" (20123 64607)) ;;; Generated autoloads from pg-pgip.el (autoload 'pg-pgip-process-packet "pg-pgip" "\ Process the command packet PGIP, which is parsed XML according to pg-xml-parse-*. The list PGIPS may contain one or more PGIP packets, whose contents are processed. \(fn PGIPS)" nil nil) (autoload 'pg-pgip-maybe-askpgip "pg-pgip" "\ Send an message to the prover if PGIP is supported. \(fn)" nil nil) (autoload 'pg-pgip-askprefs "pg-pgip" "\ Send an message to the prover. \(fn)" nil nil) ;;;*** ;;;### (autoloads (pg-response-has-error-location proof-next-error ;;;;;; pg-response-message pg-response-display-with-face pg-response-maybe-erase ;;;;;; proof-response-config-done proof-response-mode) "pg-response" ;;;;;; "pg-response.el" (20118 50210)) ;;; Generated autoloads from pg-response.el (autoload 'proof-response-mode "pg-response" "\ Responses from Proof Assistant \(fn)" t nil) (autoload 'proof-response-config-done "pg-response" "\ Complete initialisation of a response-mode derived buffer. \(fn)" nil nil) (autoload 'pg-response-maybe-erase "pg-response" "\ Erase the response buffer according to `pg-response-erase-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 `pg-response-erase-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. \(fn &optional ERASE-NEXT-TIME CLEAN-WINDOWS FORCE)" nil nil) (autoload 'pg-response-display-with-face "pg-response" "\ Display STR with FACE in response buffer. \(fn STR &optional FACE)" nil nil) (autoload 'pg-response-message "pg-response" "\ Issue the message ARGS in the response buffer and display it. \(fn &rest ARGS)" nil nil) (autoload 'proof-next-error "pg-response" "\ 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. Optional argument ARGP means reparse the error message buffer and start at the first error. \(fn &optional ARGP)" t nil) (autoload 'pg-response-has-error-location "pg-response" "\ Return non-nil if the response buffer has an error location. See `pg-next-error-regexp'. \(fn)" nil nil) ;;;*** ;;;### (autoloads (proof-autosend-enable pg-clear-input-ring pg-remove-from-input-history ;;;;;; pg-add-to-input-history pg-next-matching-input-from-input ;;;;;; pg-previous-matching-input-from-input proof-imenu-enable ;;;;;; pg-identifier-near-point-query pg-hint pg-next-error-hint ;;;;;; pg-processing-complete-hint pg-jump-to-end-hint pg-response-buffers-hint ;;;;;; pg-slow-fontify-tracing-hint proof-electric-terminator-enable ;;;;;; proof-define-assistant-command-witharg proof-define-assistant-command ;;;;;; proof-process-buffer proof-goto-point proof-script-new-command-advance) ;;;;;; "pg-user" "pg-user.el" (20123 64158)) ;;; Generated autoloads from pg-user.el (autoload 'proof-script-new-command-advance "pg-user" "\ Move point to a nice position for a new command. Assumes that point is at the end of a command. \(fn)" t nil) (autoload 'proof-goto-point "pg-user" "\ Assert or retract to the command at current position. Calls `proof-assert-until-point' or `proof-retract-until-point' as appropriate. \(fn)" t nil) (autoload 'proof-process-buffer "pg-user" "\ Process the current (or script) buffer, and maybe move point to the end. \(fn)" t nil) (autoload 'proof-define-assistant-command "pg-user" "\ Define FN (docstring DOC) to send BODY to prover, based on CMDVAR. BODY defaults to CMDVAR, a variable. \(fn FN DOC CMDVAR &optional BODY)" nil (quote macro)) (autoload 'proof-define-assistant-command-witharg "pg-user" "\ Define command FN to prompt for string CMDVAR to proof assistant. CMDVAR is a variable holding a function or string. Automatically has history. \(fn FN DOC CMDVAR PROMPT &rest BODY)" nil (quote macro)) (autoload 'proof-electric-terminator-enable "pg-user" "\ Ensure modeline update to display new value for electric terminator. This a function is called by the custom-set property 'proof-set-value. \(fn)" nil nil) (autoload 'pg-slow-fontify-tracing-hint "pg-user" "\ Not documented \(fn)" nil nil) (autoload 'pg-response-buffers-hint "pg-user" "\ Not documented \(fn &optional NEXTBUF)" nil nil) (autoload 'pg-jump-to-end-hint "pg-user" "\ Not documented \(fn)" nil nil) (autoload 'pg-processing-complete-hint "pg-user" "\ Display hint for showing end of locked region or processing complete. \(fn)" nil nil) (autoload 'pg-next-error-hint "pg-user" "\ Display hint for locating error. \(fn)" nil nil) (autoload 'pg-hint "pg-user" "\ Display a hint HINTMSG in the minibuffer, if `pg-show-hints' is non-nil. The function `substitute-command-keys' is called on the argument. \(fn HINTMSG)" nil nil) (autoload 'pg-identifier-near-point-query "pg-user" "\ Query the prover about the identifier near point. If the result is successful, we add a span to the buffer which has a popup with the information in it. \(fn)" t nil) (autoload 'proof-imenu-enable "pg-user" "\ Add or remove index menu. \(fn)" nil nil) (autoload 'pg-previous-matching-input-from-input "pg-user" "\ Search backwards through input history for match for current input. \(Previous history elements are earlier commands.) With prefix argument N, search for Nth previous match. If N is negative, search forwards for the -Nth following match. \(fn N)" t nil) (autoload 'pg-next-matching-input-from-input "pg-user" "\ Search forwards through input history for match for current input. \(Following history elements are more recent commands.) With prefix argument N, search for Nth following match. If N is negative, search backwards for the -Nth previous match. \(fn N)" t nil) (autoload 'pg-add-to-input-history "pg-user" "\ Maybe add CMD to the input history. CMD is only added to the input history if it is not a duplicate of the last item added. \(fn CMD)" nil nil) (autoload 'pg-remove-from-input-history "pg-user" "\ Maybe remove CMD from the end of the input history. This is called when the command is undone. It's only removed if it matches the last item in the ring. \(fn CMD)" nil nil) (autoload 'pg-clear-input-ring "pg-user" "\ Not documented \(fn)" nil nil) (autoload 'proof-autosend-enable "pg-user" "\ Enable or disable autosend behaviour. \(fn &optional NOMSG)" nil nil) ;;;*** ;;;### (autoloads (pg-xml-parse-string) "pg-xml" "pg-xml.el" (20118 ;;;;;; 50210)) ;;; Generated autoloads from pg-xml.el (autoload 'pg-xml-parse-string "pg-xml" "\ Parse string in ARG, same as pg-xml-parse-buffer. \(fn ARG)" nil nil) ;;;*** ;;;### (autoloads (proof-dependency-in-span-context-menu proof-depends-process-dependencies) ;;;;;; "proof-depends" "proof-depends.el" (20118 50210)) ;;; Generated autoloads from 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. \(fn NAME GSPAN)" nil nil) (autoload 'proof-dependency-in-span-context-menu "proof-depends" "\ Make some menu entries showing proof dependencies of SPAN. \(fn SPAN)" nil nil) ;;;*** ;;;### (autoloads (proof-easy-config) "proof-easy-config" "proof-easy-config.el" ;;;;;; (20118 50210)) ;;; Generated autoloads from proof-easy-config.el (autoload 'proof-easy-config "proof-easy-config" "\ Configure Proof General for proof-assistant using BODY as a setq body. The symbol SYM and string name NAME must match those given in the `proof-assistant-table', which see. \(fn SYM NAME &rest BODY)" nil (quote macro)) ;;;*** ;;;### (autoloads (proof-indent-line) "proof-indent" "proof-indent.el" ;;;;;; (20118 50210)) ;;; Generated autoloads from proof-indent.el (autoload 'proof-indent-line "proof-indent" "\ Indent current line of proof script, if indentation enabled. \(fn)" t nil) ;;;*** ;;;### (autoloads (proof-maths-menu-enable proof-maths-menu-set-global) ;;;;;; "proof-maths-menu" "proof-maths-menu.el" (20118 50210)) ;;; Generated autoloads from proof-maths-menu.el (autoload 'proof-maths-menu-set-global "proof-maths-menu" "\ Set global status of maths-menu mode for PG buffers to be FLAG. Turn on/off menu in all script buffers and ensure new buffers follow suit. \(fn FLAG)" nil nil) (autoload 'proof-maths-menu-enable "proof-maths-menu" "\ Turn on or off maths-menu mode in Proof General script buffer. This invokes `maths-menu-mode' to toggle the setting for the current buffer, and then sets PG's option for default to match. Also we arrange to have maths menu mode turn itself on automatically in future if we have just activated it for this buffer. \(fn)" t nil) ;;;*** ;;;### (autoloads (proof-aux-menu proof-menu-define-specific proof-menu-define-main ;;;;;; proof-menu-define-keys) "proof-menu" "proof-menu.el" (20123 ;;;;;; 63408)) ;;; Generated autoloads from proof-menu.el (autoload 'proof-menu-define-keys "proof-menu" "\ Prover specific keymap under C-c C-a. \(fn MAP)" nil nil) (autoload 'proof-menu-define-main "proof-menu" "\ Not documented \(fn)" nil nil) (autoload 'proof-menu-define-specific "proof-menu" "\ Not documented \(fn)" nil nil) (autoload 'proof-aux-menu "proof-menu" "\ Construct and return PG auxiliary menu used in non-scripting buffers. \(fn)" nil nil) ;;;*** ;;;### (autoloads (proof-mmm-enable proof-mmm-set-global) "proof-mmm" ;;;;;; "proof-mmm.el" (20118 50210)) ;;; Generated autoloads from proof-mmm.el (autoload 'proof-mmm-set-global "proof-mmm" "\ Set global status of MMM mode for PG buffers to be FLAG. \(fn FLAG)" nil nil) (autoload 'proof-mmm-enable "proof-mmm" "\ Turn on or off MMM mode in Proof General script buffer. This invokes `mmm-mode' to toggle the setting for the current buffer, and then sets PG's option for default to match. Also we arrange to have MMM mode turn itself on automatically in future if we have just activated it for this buffer. \(fn)" t nil) ;;;*** ;;;### (autoloads (proof-config-done proof-mode proof-insert-sendback-command ;;;;;; proof-insert-pbp-command proof-script-generic-parse-find-comment-end ;;;;;; proof-register-possibly-new-processed-file pg-set-span-helphighlights ;;;;;; proof-locked-region-empty-p proof-locked-region-full-p proof-unprocessed-begin ;;;;;; proof-colour-locked) "proof-script" "proof-script.el" (20123 ;;;;;; 64988)) ;;; Generated autoloads from proof-script.el (autoload 'proof-colour-locked "proof-script" "\ Alter the colour of all locked regions according to variable `proof-colour-locked'. \(fn)" t nil) (autoload 'proof-unprocessed-begin "proof-script" "\ Return end of locked region in current buffer or (point-min) otherwise. The position is actually one beyond the last locked character. \(fn)" nil nil) (autoload 'proof-locked-region-full-p "proof-script" "\ Non-nil if the locked region covers all the buffer's non-whitespace. Works on any buffer. \(fn)" nil nil) (autoload 'proof-locked-region-empty-p "proof-script" "\ Non-nil if the locked region is empty. Works on any buffer. \(fn)" nil nil) (autoload 'pg-set-span-helphighlights "proof-script" "\ Add a daughter help span for SPAN with help message, highlight, actions. The daughter span covers the non whitespace content of the main span. We add the last output (when non-empty) to the hover display, and also as the 'response property on the span. Optional argument MOUSEFACE means use the given face as a mouse highlight face, if it is a face, otherwise, if it is non-nil but not a face, do not add a mouse highlight. In any case, a mouse highlight and tooltip are only set if `proof-output-tooltips' is non-nil. Argument FACE means add 'face property FACE to the span. \(fn SPAN &optional MOUSEFACE FACE)" nil nil) (autoload 'proof-register-possibly-new-processed-file "proof-script" "\ 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. \(fn FILE &optional INFORMPROVER NOQUESTIONS)" nil nil) (autoload 'proof-script-generic-parse-find-comment-end "proof-script" "\ Find the end of the comment point is at the start of. Nil if not found. \(fn)" nil nil) (autoload 'proof-insert-pbp-command "proof-script" "\ Insert CMD into the proof queue. \(fn CMD)" nil nil) (autoload 'proof-insert-sendback-command "proof-script" "\ Insert CMD into the proof script, execute assert-until-point. \(fn CMD)" nil nil) (autoload 'proof-mode "proof-script" "\ Proof General major mode class for proof scripts. \\{proof-mode-map} \(fn)" t nil) (autoload 'proof-config-done "proof-script" "\ 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. \(fn)" nil nil) ;;;*** ;;;### (autoloads (proof-shell-config-done proof-shell-mode proof-shell-invisible-command-invisible-result ;;;;;; proof-shell-invisible-cmd-get-result proof-shell-invisible-command ;;;;;; proof-shell-wait proof-extend-queue proof-start-queue proof-shell-insert ;;;;;; proof-shell-available-p proof-shell-ready-prover) "proof-shell" ;;;;;; "proof-shell.el" (20118 50320)) ;;; Generated autoloads from 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, which is a symbol or list of symbols. Otherwise, if the shell is busy, give an error. No change to current buffer or point. \(fn &optional QUEUEMODE)" nil nil) (defsubst proof-shell-live-buffer nil "\ Return non-nil if proof-shell-buffer is live." (and proof-shell-buffer (buffer-live-p proof-shell-buffer) (scomint-check-proc proof-shell-buffer))) (autoload 'proof-shell-available-p "proof-shell" "\ Return non-nil if there is a proof shell active and available. No error messages. Useful as menu or toolbar enabler. \(fn)" nil nil) (autoload 'proof-shell-insert "proof-shell" "\ Insert STRINGS at the end of the proof shell, call `scomint-send-input'. STRINGS is a list of strings (which will be concatenated), or a single string. The ACTION argument is a symbol which is typically the name of a callback for when each string has been processed. This calls `proof-shell-insert-hook'. The arguments `action' and `scriptspan' may be examined by the hook to determine how to modify the `string' variable (exploiting dynamic scoping) which will be the command actually sent to the shell. Note that the hook is not called for the empty (null) string or a carriage return. We strip the 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-add-to-queue' when we start processing a queue, and in `proof-shell-exec-loop', to process the next item. \(fn STRINGS ACTION &optional SCRIPTSPAN)" nil nil) (autoload 'proof-start-queue "proof-shell" "\ Begin processing a queue of commands in QUEUEITEMS. If START is non-nil, START and END are buffer positions in the active scripting buffer for the queue region. This function calls `proof-add-to-queue'. \(fn START END QUEUEITEMS &optional QUEUEMODE)" nil nil) (autoload 'proof-extend-queue "proof-shell" "\ Extend the current queue with QUEUEITEMS, 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 \(fn END QUEUEITEMS)" nil nil) (autoload 'proof-shell-wait "proof-shell" "\ Busy wait for `proof-shell-busy' to become nil, reading from prover. Needed between sequences of commands to maintain synchronization, because Proof General does not allow for the action list to be extended in some cases. Also is considerably faster than leaving the Emacs top-level command loop to read from the prover. Called by `proof-shell-invisible-command' and `proof-process-buffer' when setting `proof-fast-process-buffer' is enabled. If INTERRUPT-ON-INPUT is non-nil, return if input is received. If TIMEOUTSECS is a number, time out after that many seconds. \(fn &optional INTERRUPT-ON-INPUT TIMEOUTSECS)" nil nil) (autoload 'proof-shell-invisible-command "proof-shell" "\ Send CMD to the proof process. The CMD is `invisible' in the sense that it is not recorded in buffer. CMD may be a string or a string-yielding expression. Automatically add `proof-terminal-string' 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. In case CMD is (or yields) nil, do nothing. INVISIBLECALLBACK will be invoked after the command has finished, if it is set. It should probably run the hook variables `proof-state-change-hook'. FLAGS are additional flags to put onto the `proof-action-list'. The flag 'invisible is always added to FLAGS. \(fn CMD &optional WAIT INVISIBLECALLBACK &rest FLAGS)" nil nil) (autoload 'proof-shell-invisible-cmd-get-result "proof-shell" "\ Execute CMD and return result as a string. This expects CMD to result in some theorem prover output. Ordinary output (and error handling) is disabled, and the result \(contents of `proof-shell-last-output') is returned as a string. \(fn CMD)" nil nil) (autoload 'proof-shell-invisible-command-invisible-result "proof-shell" "\ Execute CMD for side effect in the theorem prover, waiting before and after. Error messages are displayed as usual. \(fn CMD)" nil nil) (autoload 'proof-shell-mode "proof-shell" "\ Proof General shell mode class for proof assistant processes \(fn)" t nil) (autoload 'proof-shell-config-done "proof-shell" "\ Initialise the specific prover after the child has been configured. Every derived shell mode should call this function at the end of processing. \(fn)" nil nil) ;;;*** ;;;### (autoloads (proof-ready-for-assistant) "proof-site" "proof-site.el" ;;;;;; (20119 3136)) ;;; Generated autoloads from proof-site.el (autoload 'proof-ready-for-assistant "proof-site" "\ Configure PG for symbol ASSISTANTSYM, name ASSISTANT-NAME. If ASSISTANT-NAME is omitted, look up in `proof-assistant-table'. \(fn ASSISTANTSYM &optional ASSISTANT-NAME)" nil nil) ;;;*** ;;;### (autoloads (proof-splash-message proof-splash-display-screen) ;;;;;; "proof-splash" "proof-splash.el" (20123 63408)) ;;; Generated autoloads from 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, make a key binding to remove this buffer. \(fn &optional TIMEOUT)" t nil) (autoload 'proof-splash-message "proof-splash" "\ Make sure the user gets welcomed one way or another. \(fn)" t nil) ;;;*** ;;;### (autoloads (proof-format) "proof-syntax" "proof-syntax.el" ;;;;;; (20118 50210)) ;;; Generated autoloads from proof-syntax.el (defsubst proof-replace-regexp-in-string (regexp rep string) "\ Like replace-regexp-in-string, but set case-fold-search to proof-case-fold-search." (let ((case-fold-search proof-case-fold-search)) (replace-regexp-in-string regexp rep string))) (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. \(fn ALIST STRING)" nil nil) ;;;*** ;;;### (autoloads (proof-toolbar-scripting-menu proof-toolbar-setup) ;;;;;; "proof-toolbar" "proof-toolbar.el" (20118 50210)) ;;; Generated autoloads from proof-toolbar.el (autoload 'proof-toolbar-setup "proof-toolbar" "\ Initialize Proof General toolbar and enable it for all PG buffers. If `proof-toolbar-enable' is nil, change the buffer toolbars back the default toolbar. \(fn)" t nil) (autoload 'proof-toolbar-toggle "proof-toolbar") (autoload 'proof-toolbar-scripting-menu "proof-toolbar" "\ Menu made from the Proof General toolbar commands. \(fn)" nil nil) ;;;*** ;;;### (autoloads (proof-unicode-tokens-enable proof-unicode-tokens-set-global ;;;;;; proof-unicode-tokens-mode-if-enabled) "proof-unicode-tokens" ;;;;;; "proof-unicode-tokens.el" (20118 50210)) ;;; Generated autoloads from proof-unicode-tokens.el (autoload 'proof-unicode-tokens-mode-if-enabled "proof-unicode-tokens" "\ Turn on or off the Unicode Tokens minor mode in this buffer. \(fn)" nil nil) (autoload 'proof-unicode-tokens-set-global "proof-unicode-tokens" "\ Set global status of unicode tokens mode for PG buffers to be FLAG. Turn on/off menu in all script buffers and ensure new buffers follow suit. \(fn FLAG)" nil nil) (autoload 'proof-unicode-tokens-enable "proof-unicode-tokens" "\ Turn on or off Unicode tokens mode in Proof General script buffer. This invokes `unicode-tokens-mode' to toggle the setting for the current buffer, and then sets PG's option for default to match. Also we arrange to have unicode tokens mode turn itself on automatically in future if we have just activated it for this buffer. Note: this function is called when the customize setting for the prover is changed. \(fn)" t nil) ;;;*** ;;;### (autoloads (proof-debug) "proof-utils" "proof-utils.el" (20118 ;;;;;; 50210)) ;;; Generated autoloads from proof-utils.el (autoload 'proof-debug "proof-utils" "\ Issue the debugging message (format MSG ARGS) in the *PG Debug* buffer. If flag `proof-general-debug' is nil, do nothing. \(fn MSG &rest ARGS)" nil nil) ;;;*** ;;;### (autoloads (scomint-make scomint-make-in-buffer) "scomint" ;;;;;; "../lib/scomint.el" (20123 63408)) ;;; Generated autoloads from ../lib/scomint.el (autoload 'scomint-make-in-buffer "scomint" "\ Make a Comint process NAME in BUFFER, running PROGRAM. If BUFFER is nil, it defaults to NAME surrounded by `*'s. PROGRAM should be either a string denoting an executable program to create via `start-file-process', or a cons pair of the form (HOST . SERVICE) denoting a TCP connection to be opened via `open-network-stream'. If there is already a running process in that buffer, it is not restarted. Optional fourth arg STARTFILE is the name of a file to send the contents of to the process. If PROGRAM is a string, any more args are arguments to PROGRAM. \(fn NAME BUFFER PROGRAM &optional STARTFILE &rest SWITCHES)" nil nil) (autoload 'scomint-make "scomint" "\ Make a Comint process NAME in a buffer, running PROGRAM. The name of the buffer is made by surrounding NAME with `*'s. PROGRAM should be either a string denoting an executable program to create via `start-file-process', or a cons pair of the form (HOST . SERVICE) denoting a TCP connection to be opened via `open-network-stream'. If there is already a running process in that buffer, it is not restarted. Optional third arg STARTFILE is the name of a file to send the contents of the process to. If PROGRAM is a string, any more args are arguments to PROGRAM. \(fn NAME PROGRAM &optional STARTFILE &rest SWITCHES)" nil nil) ;;;*** ;;;### (autoloads (texi-docstring-magic) "texi-docstring-magic" "../lib/texi-docstring-magic.el" ;;;;;; (20118 50210)) ;;; Generated autoloads from ../lib/texi-docstring-magic.el (autoload 'texi-docstring-magic "texi-docstring-magic" "\ Update all texi docstring magic annotations in buffer. With prefix arg, no errors on unknown symbols. (This results in @def .. @end being deleted if not known). \(fn &optional NOERROR)" t nil) ;;;*** ;;;### (autoloads (unicode-chars-list-chars) "unicode-chars" "../lib/unicode-chars.el" ;;;;;; (20118 50210)) ;;; Generated autoloads from ../lib/unicode-chars.el (autoload 'unicode-chars-list-chars "unicode-chars" "\ Insert each Unicode character into a buffer. Lets you see which characters are available for literal display in your emacs font. \(fn)" t nil) ;;;*** ;;;### (autoloads (unicode-tokens-encode-str) "unicode-tokens" "../lib/unicode-tokens.el" ;;;;;; (20118 50210)) ;;; Generated autoloads from ../lib/unicode-tokens.el (autoload 'unicode-tokens-encode-str "unicode-tokens" "\ Return a unicode encoded version presentation of STR. \(fn STR)" nil nil) ;;;*** ;;;### (autoloads nil nil ("../lib/local-vars-list.el" "../lib/pg-fontsets.el" ;;;;;; "../lib/proof-compat.el" "../lib/span.el" "pg-autotest.el" ;;;;;; "pg-custom.el" "pg-pbrpm.el" "pg-vars.el" "proof-auxmodes.el" ;;;;;; "proof-config.el" "proof-faces.el" "proof-useropts.el" "proof.el" ;;;;;; "proofgeneral-pkg.el") (20123 65399 608731)) ;;;*** ;; Local Variables: ;; version-control: never ;; no-update-autoloads: t ;; End: ;;; proof-autoloads.el ends here proofgeneral-4.3~pre130510/generic/proof-auxmodes.el000066400000000000000000000037751214562307500223510ustar00rootroot00000000000000;;; proof-auxmodes.el --- Arrange for auxiliary modes to be loaded when required ;; ;; Copyright (C) 2008, 2010 David Aspinall / LFCS Edinburgh ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;;; Commentary: ;; ;; Startup code from auxiliary modes are collected here, allowing late ;; loading of their main defining files and the possibility to disable them. ;; (require 'proof-utils) ; proof-ass, proof-eval... ;;; Code: ;; ;; MMM ;; (defun proof-mmm-support-available () "A test to see whether mmm support is available." (and (or (featurep 'mmm-auto) (progn ;; put bundled version on load path (proof-add-to-load-path (concat proof-home-directory "contrib/mmm/")) ;; *should* always succeed unless bundled version broken (proof-try-require 'mmm-auto))) ;; Load prover-specific config in -mmm.el (proof-try-require (proof-ass-sym mmm)))) (proof-eval-when-ready-for-assistant (if (and (proof-ass mmm-enable) (proof-mmm-support-available)) (proof-mmm-set-global t))) ;; ;; Maths menu ;; (defun proof-maths-menu-support-available () "A test to see whether maths-menu support is available. The test loads optional prover-specific config in -maths-menu.el" (or (proof-try-require (proof-ass-sym maths-menu)) t)) (proof-eval-when-ready-for-assistant (if (and (proof-ass maths-menu-enable) (proof-maths-menu-support-available)) (proof-maths-menu-set-global t))) ;; ;; Unicode tokens ;; (defun proof-unicode-tokens-support-available () "A test to see whether unicode tokens support is available." ;; Requires prover-specific config in -unicode-tokens.el ;; Loaded before unicode-tokens.el to allow load-time config there (proof-try-require (proof-ass-sym unicode-tokens))) (proof-eval-when-ready-for-assistant (if (and (proof-ass unicode-tokens-enable) (proof-unicode-tokens-support-available)) (proof-unicode-tokens-set-global t))) (provide 'proof-auxmodes) ;;; proof-auxmodes.el ends here proofgeneral-4.3~pre130510/generic/proof-config.el000066400000000000000000002136621214562307500217670ustar00rootroot00000000000000;;; proof-config.el --- Proof General configuration for proof assistant ;; ;; Copyright (C) 1998-2010 LFCS Edinburgh. ;; Author: David Aspinall and others ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-config.el,v 12.8 2012/11/13 22:05:11 tews Exp $ ;; ;;; Commentary: ;; ;; This file declares all 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. Menus, user-level commands, toolbar ;; 2. Script mode configuration ;; 3. Shell mode configuration ;; 3a. commands ;; 3b. regexps ;; 3c. tokens ;; 3d. hooks and others ;; 4. Goals buffer configuration ;; ;; The remaining variables in 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 ;; (see proof-useropts.el) ;; : User options for proof assistant ;; (see pg-custom.el) ;; -internals : Internal settings for proof assistant ;; (see pg-custom.el) ;; ;; proof-general-internals : Internal settings of Proof General ;; prover-config : Configuration for proof assistant (1) ;; proof-script : settings for proof script mode (2) ;; proof-shell : settings for proof shell mode (3) ;; proof-goals : settings for goals buffer (4) ;; -config : Specific internal settings for a prover ;; ;; ====================================================================== ;; ;; Developer notes: ;; ;; i. When adding a new configuration variable, please ;; (a) put it in the right customize group, and ;; (b) add a magical comment in ProofGeneral.texi/PG-adapting.texi ;; ;; ii. Presently the customize library seems a bit picky over the ;; :type property and some correct but complex types don't work: ;; 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 ;; ;; ;; See also: ;; ;; pg-custom.el ;; pg-vars.el ;;; Code: (require 'proof-useropts) ; user options (require 'proof-faces) ; user options: faces (eval-when-compile (require 'custom)) ;; ;; 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 ;; -mode-config type functions. This is why prover-config ;; appears under the proof-general-internal group. (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) ;; ;; 1. 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 send." :type '(choice string function) :group 'prover-config) (defcustom proof-query-identifier-command nil "Command sent to the prover to query about a given identifier (or string). This is typically a command used to print a theorem, constant, or whatever. Inside the command the string %s is replaced by the given identifier or string. Value should be a string for a single command, or maybe an association list between values for `proof-buffer-syntactic-context' and strings, which allows different prover commands to be sent based on the syntactic context of the string. If value is an alist, must include a default value for no context (nil)." :type '(or string (list (cons (choice 'nil 'string 'comment) string))) :group 'proof-shell) (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-float-fn 'number-to-string "Function for converting float values to ints in proof assistant. Used for configuring settings in proof assistant. Default is `number-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 (const nil)) :group 'prover-config) (defcustom proof-tree-configured nil "Whether external proof-tree display is configured. This boolean enables the proof-tree menu entry and the function that starts external proof-tree display." :type 'boolean :group 'proof-tree-internals) ;; ;; 2. 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-string nil "String that terminates commands sent to prover; 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-string', or `proof-script-parse-function'." :type 'character :group 'prover-config) (defcustom proof-electric-terminator-noterminator nil "If non-nil, electric terminator does not actually insert a terminator." :type 'boolean :group 'prover-config) (defcustom proof-script-sexp-commands nil "Non-nil if script has LISP-like syntax: 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-string', 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. The end of the command is considered to be the end of the match of this regexp. The regexp may include a nested group, which can be used to recognize the start of the following command \(or white space). If there is a nested group, the end of the command is considered to be the start of the nested group, i.e. (match-beginning 1), rather than (match-end 0). 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-string', 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-string', or `proof-script-parse-function'." :type 'string :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) (defcustom proof-script-fly-past-comments nil "*If non-nil, fly past successive comments, coalescing into single spans." :type 'boolean :group 'proof-user-options) (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-string' and its friends are set." :type 'string :group 'prover-config) (defcustom proof-script-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-script-comment-end'." :type 'string :group 'proof-script) (defcustom proof-script-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-script-comment-start') but you can set this variable to something else more precise if necessary." :type 'string :group 'proof-script) (defcustom proof-script-comment-end "" "String which ends a comment in the proof assistant command language. Should be an empty string if comments are terminated by `end-of-line' The script buffer's `comment-end' is set to a space plus this string, if it is non-empty. See also `proof-script-comment-start'. You should set this variable for reliable working of Proof General." :type 'string :group 'proof-script) (defcustom proof-script-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-script-comment-end') but you can set this variable to something else more precise if necessary." :type 'string :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 built 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. It's safe to leave this setting as nil." :type 'regexp :group 'proof-script) (defcustom proof-save-with-hole-result 2 "How to get theorem name after `proof-save-with-hole-regexp' match. String or Int. If an int N use match-string to recover the value of the Nth parenthesis matched. If it is a string use replace-match. In this case, `proof-save-with-hole-regexp' should match the entire command" :type '(choice string integer) :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 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." :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 built from the variable `proof-goal-with-hole-result' using the same convention as for `query-replace-regexp'. Used for setting names of goal..save regions and for default configuration of other modes (function menu, imenu). It's safe to leave this setting as nil." :type 'regexp :group 'proof-script) (defcustom proof-goal-with-hole-result 2 "How to get theorem name after `proof-goal-with-hole-regexp' match. String or Int. If an int N use match-string to recover the value of the Nth parenthesis matched. If it is a string use replace-match. In this case, proof-save-with-hole-regexp should match the entire command" :type '(choice string integer) :group 'proof-script) (defcustom proof-non-undoables-regexp nil "Regular expression matching commands which are *not* undoable. These are commands which should not appear in proof scripts, for example, undo commands themselves (if the proof assistant cannot \"redo\" an \"undo\"). 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 (const nil) regexp) :group 'proof-script) (defcustom proof-nested-undo-regexp nil "Regexp for commands that must be counted in nested goal-save regions. Used for provers which allow nested atomic goal-saves, but with some nested history that must be undone specially. At the moment, the behaviour is that a goal-save span has a 'nestedundos property which is set to the number of commands within it which match this regexp. The idea is that the prover-specific code can create a customized undo command to retract the goal-save region, based on the 'nestedundos setting. Coq uses this to forget declarations, since declarations in Coq reside in a separate context with its own (flat) history." :type '(choice (const 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 (const nil) regexp function) :group 'proof-script) (defcustom proof-script-imenu-generic-expression nil "Regular expressions to help find definitions and proofs in a script. Value for `imenu-generic-expression', see documentation of Imenu and that variable for details." :type 'sexp :group 'proof-script) ;; FIXME da: unify this with proof-save-command-regexp, to allow fn or regexp (defcustom proof-goal-command-p 'proof-generic-goal-command-p "A function to test: is this really a goal command span? 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 da: unify this with proof-save-command-regexp, to allow fn or regexp (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." :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. NB: 'extend behaviour is not currently compatible with appearance of save commands, so don't use that if your prover has save commands." :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-count-undos-fn 'proof-generic-count-undos "Function to calculate a list of commands to undo 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) (defcustom proof-find-and-forget-fn 'proof-generic-find-and-forget "Function to return list of commands to forget 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-unprocessed-begin). This may involve forgetting a number of definitions, declarations, or whatever. If return value is nil, it means there is nothing to do. 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-forget-id-command nil "Command to forget back to a given named span. A string; `%s' will be replaced by the name of the span. This is only used in the implementation of `proof-generic-find-and-forget', you only need to set if you use that function (by not customizing `proof-find-and-forget-fn'." :type 'string :group 'proof-script) (defcustom pg-topterm-goalhyplit-fn nil "Function to return cons if point is at a goal/hypothesis/literal. This is used to parse the proofstate output to mark it up for proof-by-pointing or literal command insertion. It should return a cons or nil. First element of the cons is a symbol, 'goal', 'hyp' or 'lit'. The second element is a string: the goal, hypothesis, or literal command itself. If you leave this variable unset, no proof-by-pointing markup will be attempted." :type '(choice function (const nil)) :group 'proof-script) (defcustom proof-kill-goal-command nil "Command to kill the currently open goal. If this is set to nil, PG will expect `proof-find-and-forget-fn' to do all the work of retracting to an arbitrary point in a file. Otherwise, the generic split-phase mechanism will be used: 1. If inside an unclosed proof, use `proof-count-undos'. 2. If retracting to before an unclosed proof, use `proof-kill-goal-command', followed by `proof-find-and-forget-fn' if necessary." :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 a list of the appropriate commands (given the number of undo steps). This setting is used for the default `proof-generic-count-undos'. If you set `proof-count-undos-fn' to some other function, there is no need to set this variable." :type '(or string function) :group 'proof-script) (defcustom proof-nested-goals-history-p nil "Whether the prover supports recovery of history for nested proofs. If it does (non-nil), Proof General will retain history inside nested proofs. If it does not, Proof General will amalgamate nested proofs into single steps within the outer proof." :type 'boolean :group 'proof-script) (defcustom proof-arbitrary-undo-positions nil "Non-nil if Proof General may undo to arbitrary positions. The classic behaviour of Proof General is to undo completed proofs in one step: this design arose because older provers discarded nested history once proofs were complete. The proof script engine amalgamates spans for a complete proof (into a single 'goalsave) to give this effect. Newer designs keep more state, and may support arbitrary undo with a file being processed. If this flag is non-nil, amalgamation will not happen." :type 'boolean :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. This is a safety-test 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) (defcustom proof-deactivate-scripting-hook nil "Hook run when a buffer is switched out of scripting mode. The current buffer will be the recently scripting buffer. This hook may be useful for synchronizing with the proof assistant, for example, to compile a completed file." :type '(repeat function) :group 'proof-script) (defcustom proof-no-fully-processed-buffer nil "Set to t if buffers should always retract before scripting elsewhere. Leave at nil if fully processed buffers make sense for the current proof assistant. If nil the user can choose to fully assert a buffer when starting scripting in a different buffer. If t there is only the choice to fully retract the active buffer before starting scripting in a different buffer. This last behavior is needed for Coq." :type 'boolean :group 'proof-script) (defcustom proof-script-evaluate-elisp-comment-regexp "ELISP: -- \\(.*\\) --" "Matches text within a comment telling Proof General to evaluate some code. This allows Emacs Lisp to be executed during scripting. \(It's also a fantastic backdoor security risk). If the regexp matches text inside a comment, there should be one subexpression match string, which will contain elisp code to be evaluated. Elisp errors will be trapped when evaluating; set `proof-general-debug' to be informed when this happens." :type 'regexp :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-script-font-lock-keywords nil "Value of `font-lock-keywords' used to fontify proof scripts. The proof script mode should set this before calling `proof-config-done'. Used also by `proof-easy-config' mechanism. See also `proof-goals-font-lock-keywords' and `proof-response-font-lock-keywords'." :type 'sexp :group 'proof-script) (defcustom proof-script-syntax-table-entries nil "List of syntax table entries for proof script mode. A flat list of the form (CHAR SYNCODE CHAR SYNCODE ...) See doc of `modify-syntax-entry' for details of characters and syntax codes. At present this is used only by the `proof-easy-config' macro." :type 'sexp :group 'proof-script) ;; ;; Proof script context menu customization ;; (defcustom proof-script-span-context-menu-extensions nil "Extensions for the in-span context sensitive menu. This should be a function which accepts three arguments: SPAN IDIOM NAME. See pg-user.el: `pg-create-in-span-context-menu' for more hints." :type 'function :group 'proof-script) ;; ;; 3. 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-") ;; ;; 3a. commands ;; (defcustom proof-prog-name nil "System command to run the proof assistant in the proof shell. May contain arguments separated by spaces, but see also the prover specific settings `-prog-args' and `-prog-env'. Remark: if `-prog-args' is non-nil, then `proof-prog-name' is considered strictly: it must contain *only* the program name with no option, spaces are interpreted literally as part of the program name." :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-string', and add it if not. If `proof-terminal-string' 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(s) 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 (list string) string (const nil)) :group 'proof-shell) ;; TODO: remove proof-shell-init-cmd in favour of this hook (defcustom proof-shell-init-hook nil "Hooks run when the proof process has started up." :type '(list function) :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) (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. It is also possible to set this value to a function which will be invoked on the name of the retracted file, and should remove the ancestor files from `proof-included-files-list' by some other calculation. See also: `proof-shell-inform-file-processed-cmd', `proof-shell-process-file', `proof-shell-compute-new-files-list'." :type '(choice string (const nil)) ;; FIXME: or function :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) ;; not really proof-shell (defcustom proof-cannot-reopen-processed-files nil "Non-nil if the prover allows re-opening of already processed files. If the user has used Proof General to process a file incrementally, then PG will retain the spans recording undo history in the buffer corresponding to that file (provided it remains visited in Emacs). If the prover allows, it will be possible to undo to a position within this file. If the prover does *not* allow this, this variable should be set non-nil, so that when a completed file is activated for scripting (to do undo operations), the whole history is discarded." :type 'boolean :group 'proof-shell) ;; not really proof shell ;; (defcustom proof-shell-adjust-line-width-cmd nil ;; ;; 3b. Regexp variables for matching output from proof process. ;; (defcustom proof-shell-annotated-prompt-regexp nil "Regexp matching a (possibly annotated) prompt pattern. THIS IS THE MOST IMPORTANT SETTING TO CONFIGURE!! Output is grabbed between pairs of lines matching this regexp, and the appearance of this regexp is used by Proof General to recognize when the prover has finished processing a command. To help speed up matching you may be able to annotate the proof assistant prompt with a special character not appearing in ordinary output, which should appear in this regexp." :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 variable `proof-shell-truncate-before-error' controls whether text before the error message is displayed. The engine matches interrupts before errors, see `proof-shell-interrupt-regexp'. It is safe to leave this variable unset (as nil)." :type '(choice (const nil) regexp) :group 'proof-shell) (defcustom proof-shell-truncate-before-error t "Non-nil means truncate output that appears before error messages. If nil, the whole output that the prover generated before the last error message will be shown. NB: the default setting for this is t to be compatible with behaviour in Proof General before version 3.4. The more obvious setting for new instances is probably nil. Interrupt messages are treated in the same way. See `proof-shell-error-regexp' and `proof-shell-interrupt-regexp'." :type 'boolean :group 'proof-shell) (defcustom pg-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 `pg-next-error-filename-regexp', which is assumed to precede pg-next-error-regexp." :type 'string :group 'proof-shell) (defcustom pg-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 `pg-next-error-regexp' \(whether they contain a line number or not). The response buffer is then searched *backwards* for a regexp matching this variable, `pg-next-error-filename-regexp'. (So if the filename appears after the line number, make the first regexp match the whole line). Finally `pg-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 pg-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 (const 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 we may automatically close off the proof region if another goal appears before a save command, depending on whether the prover supports nested proofs or not." :type '(choice (const nil) regexp) :group 'proof-shell) (defcustom proof-shell-clear-response-regexp nil "Regexp matching output telling Proof General to clear the response buffer. More precisely, this should match a string which is bounded by matches on `proof-shell-eager-annotation-start' and `proof-shell-eager-annotation-end'. 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 (const nil) regexp) :group 'proof-shell) (defcustom proof-shell-clear-goals-regexp nil "Regexp matching output telling Proof General to clear the goals buffer. More precisely, this should match a string which is bounded by matches on `proof-shell-eager-annotation-start' and `proof-shell-eager-annotation-end'. 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 (const 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. If it is left as nil, the goals buffer will not be used. The goals display starts at the beginning of the match on this regexp, unless it has a match group, in which case it starts at (match-end 1)." :type '(choice (const nil) regexp) :group 'proof-shell) (defcustom proof-shell-end-goals-regexp nil "Regexp matching the end of the proof state output, or nil. This allows a shorter form of the proof state output to be displayed, in case several messages are combined in a command output. The portion treated as the goals output will be that between the match on `proof-shell-start-goals-regexp' (which see) and the start of the match on `proof-shell-end-goals-regexp'. If nil, use the whole of the output from the match on `proof-shell-start-goals-regexp' up to the next prompt." :type '(choice (const 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. Note that this affects processing of output which is ordinarily accumulated: output which appears before the eager annotation start will be discarded. The start/end annotations can be used to hilight the output, but are stripped from display of the message in the minibuffer. It is useful 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-strip-output-markup 'identity "A function which strips markup from the process output. This should remove any markup which is made invisible by font-lock when displayed in the output buffer. This is used in `pg-insert-last-output-as-comment' to insert output into the proof script, and for cut and paste operations." :type 'function :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. Future use may provide a generic implementation for `pg-topterm-goalhyplit-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. 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. More precisely, REGEXP should match a string which is bounded by matches on `proof-shell-eager-annotation-start' and `proof-shell-eager-annotation-end'. 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. More precisely, this should match a string which is bounded by matches on `proof-shell-eager-annotation-start' and `proof-shell-eager-annotation-end'. 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. The result will be stored in `proof-included-files-list'. This function is called when `proof-shell-retract-files-regexp' has been matched in the prover output. 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 pg-special-char-regexp "[\200-\377]" "Regexp matching any \"special\" character sequence." :type 'string :group 'proof-shell) (defcustom proof-shell-set-elisp-variable-regexp nil "Matches output telling Proof General to set some variable. This allows the proof assistant to configure Proof General directly and dynamically. (It's also a fantastic backdoor security risk). More precisely, this should match a string which is bounded by matches on `proof-shell-eager-annotation-start' and `proof-shell-eager-annotation-end'. 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-general-debug' 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 (const nil) regexp) :group 'proof-shell) (defcustom proof-shell-match-pgip-cmd nil "Regexp used to match PGIP command from proof assistant. More precisely, this should match a string which is bounded by matches on `proof-shell-eager-annotation-start' and `proof-shell-eager-annotation-end'. The matching string will be parsed as XML and then processed by `pg-pgip-process-cmd'." :type '(choice (const nil) regexp) :group 'proof-shell) ;; FIXME: next one needs changing to be a function, or have function ;; built from it. (defcustom proof-shell-issue-pgip-cmd nil "Command sent to prover to process PGIP command in %s placeholder." :type '(choice (const nil) string) :group 'proof-shell) (defcustom proof-use-pgip-askprefs nil "Whether to use the PGIP command to configure prover settings." :type 'boolean :group 'proof-shell) ;; FIXME FIXME: this next one not yet used. It's hard to interleave ;; commands with the ordinary queue anyway: the prover should ;; automatically output this information if it is enabled. (defcustom proof-shell-query-dependencies-cmd nil "Command to query the prover for dependencies of given theorem name. %s is replaced by the name of the theorem. This command will be sent when a proof is completed." :type 'string :group 'proof-shell) (defcustom proof-shell-theorem-dependency-list-regexp nil "Matches output telling Proof General about dependencies. This is to allow navigation and display of dependency information. The output from the prover should be a message with the form DEPENDENCIES OF X Y Z ARE A B C with X Y Z, A B C separated by whitespace or somehow else (see `proof-shell-theorem-dependency-list-split'. This variable should be set to a regexp to match the overall message (which should be an urgent message), with two sub-matches for X Y Z and A B C. This is an experimental feature, currently work-in-progress." :type '(choice (const nil) regexp) :group 'proof-shell) (defcustom proof-shell-theorem-dependency-list-split nil "Splits strings which match `proof-shell-theorem-dependency-list-regexp'. Used as an argument to `split-string'; nil defaults to whitespace. \(This setting is necessary for provers which allow whitespace in the names of theorems/definitions/constants), see setting for Isabelle in isa/isa.el and isar/isar.el." :type '(choice (const nil) regexp) :group 'proof-shell) (defcustom proof-shell-show-dependency-cmd nil "Command sent to the prover to display a dependency. This is typically a command used to print a theorem, constant, or whatever. A string with %s replaced by the dependency name." :type 'string :group 'proof-shell) ;; A feature that could be added to support Isabelle's tracing of ;; tactics. Seems to be little used, so probably not worth adding. ;(defcustom proof-shell-interactive-input-regexp nil ; "Matches special interactive input request prompt from the prover. ;A line which matches this regexp but would otherwise be treated ;as an ordinary response is instead treated as a prompt for ;input to be displayed in the minibuffer. The line which is ;input is delivered directly to the proof assistant. ;This can be used if the proof assistant requires return key ;presses to continue, or similar." ; :type 'string ; :group 'proof-shell) (defcustom proof-shell-trace-output-regexp nil "Matches 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. This should match a string which is bounded by matches on `proof-shell-eager-annotation-start' and `proof-shell-eager-annotation-end'. Set to nil to disable." :type '(choice (const nil) regexp) :group 'proof-shell) (defcustom proof-shell-thms-output-regexp nil "Matches theorem display which should be displayed in theorem buffer. Each line which matches this regexp but would otherwise be treated as an ordinary response, is sent to the theorem buffer as well as the response buffer." :type '(choice (const nil) regexp) :group 'proof-shell) (defcustom proof-shell-interactive-prompt-regexp nil "Matches output from the prover which indicates an interactive prompt. If we match this, we suppose that the prover has switched to an interactive diagnostic mode which requires direct interaction with the shell rather than via script management. In this case, the shell buffer will be displayed and the user left to their own devices. Note: this should match a string which is bounded by matches on `proof-shell-eager-annotation-start' and `proof-shell-eager-annotation-end'." :type '(choice (const nil) regexp) :group 'proof-shell) ;; ;; 3c. tokens mode: turning on/off tokens output ;; (defcustom proof-tokens-activate-command nil "Command to activate token input/output for prover. If non-nil, this command is sent to the proof assistant when Unicode Tokens support is activated." :type 'string :group 'prover-config) (defcustom proof-tokens-deactivate-command nil "Command to deactivate token input/output for prover. If non-nil, this command is sent to the proof assistant when Unicode Tokens support is deactivated." :type 'string :group 'proof-config) (defcustom proof-tokens-extra-modes nil "List of additional mode names to use with Proof General tokens. These modes will have Tokens 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-config) ;; ;; 3d. hooks and other miscellaneous customizations ;; (defcustom proof-shell-unicode t "Whether communication between PG and prover is 8bit clean. If non-nil, no special non-ASCII characters must be used in markup. If so, the process coding system will be set to UTF-8. With old systems that may use unsafe unicode prefix sequences \(i.e., lead to hanging in C-libraries), this should be set to nil." :type 'boolean :group 'proof-shell) (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 (if (= emacs-major-version 24) nil t) "The value of `process-connection-type' for the proof shell. Set non-nil for ptys, nil for pipes." :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 many systems based on human input, because several CR's can result in several prompts, which may mess up the display (or even worse, the synchronization). If the prover can be set to output only one prompt for every chunk of input, then newlines can be retained in the input." :type 'boolean :group 'proof-shell) (defcustom proof-shell-strip-crs-from-output (eq system-type 'cygwin32) ;; Cygwin32 probs with Isabelle noted by Norbert Voelker "If non-nil, remove carriage returns (^M) at the end of lines from output. This is enabled for cygwin32 systems by default. You should turn it off if you don't need it (slight speed penalty)." :type 'boolean :group 'proof-shell) (defcustom proof-shell-extend-queue-hook nil "Hooks run by proof-extend-queue before extending `proof-action-list'. Can be used to run additional actions before items are added to the queue \(such as compiling required modules for Coq) or to modify the items that are going to be added to `proof-action-list'. The items that are about to be added are bound to `queueitems'." :type '(repeat function) :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, the first two are normally the ones of interest: 'proof-done-advancing A \"forward\" scripting command 'proof-done-retracting A \"backward\" scripting command 'proof-done-invisible A non-scripting command 'proof-shell-set-silent Indicates prover output has been surpressed 'proof-shell-clear-silent Indicates prover output has been restored 'init-cmd Early initialization command sent to prover 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'. See also `proof-script-preprocess' which can munge text when it is added to the queue of commands." :type '(repeat function) :group 'proof-shell) (defcustom proof-script-preprocess nil "Function to pre-process (SPAN STRING) taken from proof script." :type '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-on-error-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-last-output-kind' to determine whether the cause was an error or interrupt. Possible values for this hook include: `proof-goto-end-of-locked-on-error-if-pos-not-visible-in-window' `proof-goto-end-of-locked-if-pos-not-visible-in-window' which move the cursor in the scripting buffer on an error or error/interrupt. Remark: This hook is called from shell buffer. If you want to do something in scripting buffer, `save-excursion' and/or `set-buffer'." :type '(repeat function) :group 'proof-shell) (defcustom proof-shell-signal-interrupt-hook nil "Run when the user tries to interrupt the prover. This hook is run inside `proof-interrupt-process' when the user tries to interrupt the proof process. It is therefore run earlier than `proof-shell-handle-error-or-interrupt-hook', which runs when the interrupt is acknowledged inside `proof-shell-exec-loop'. This hook also runs when the proof assistent is killed." :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 systems that query the user before returning to the top level." :type '(repeat function) :group 'proof-shell) (defcustom proof-shell-handle-output-system-specific nil "Set this variable to handle system specific output. Errors and interrupts are recognised in the function `proof-shell-handle-immediate-output'. Later output is handled by `proof-shell-handle-delayed-output', which displays messages to the user in *goals* and *response* buffers. This hook can run between the two stages to take some effect. It should be a function which is passed (cmd string) as arguments, where `cmd' is a string containing the currently processed command and `string' is the response from the proof system. If action is taken and goals/response display should be prevented, the function should update the variable `proof-shell-last-output-kind' to some non-nil symbol. The symbol will be compared against standard ones, see documentation of `proof-shell-last-output-kind'. A suggested canonical non-standard symbol is 'systemspecific." :type '(repeat function) :group 'proof-shell) (defcustom proof-state-change-hook nil "This hook is called when a scripting 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-syntax-table-entries nil "List of syntax table entries for proof script mode. A flat list of the form (CHAR SYNCODE CHAR SYNCODE ...) See doc of `modify-syntax-entry' for details of characters and syntax codes. At present this is used only by the `proof-easy-config' macro." :type 'sexp :group 'proof-shell) ;; ;; 4. Goals buffer ;; (defgroup proof-goals nil "Settings for configuring the goals buffer." :group 'prover-config :prefix "pg-goals-") (defcustom pg-subterm-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-goals) (defcustom pg-subterm-anns-use-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 pg-goals-change-goal nil "Command to change to the goal `%s'." :type 'string :group 'proof-goals) (defcustom pbp-goal-command nil "Command sent when `pg-goals-button-action' is requested on a goal." :type '(choice (const nil) string) :group 'proof-goals) (defcustom pbp-hyp-command nil "Command sent when `pg-goals-button-action' is requested on an assumption." :type '(choice (const nil) string) :group 'proof-goals) (defcustom pg-subterm-help-cmd nil "Command to display mouse help about a subterm. This command is sent to the proof assistant, replacing %s by the subterm that the mouse is over." :type '(choice (const nil) string) :group 'proof-goals) (defcustom pg-goals-error-regexp nil "Regexp indicating that the proof process has identified an error." :type '(choice (const 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 (const 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 pg-subterm-start-char nil "Opening special character for subterm markup. Subsequent special characters with values *below* `pg-subterm-first-special-char' are assumed to be subterm position indicators. Annotations should be finished with `pg-subterm-sep-char'; the end of the concrete syntax is indicated by `pg-subterm-end-char'. If `pg-subterm-start-char' is nil, subterm markup is disabled." :type '(choice character (const nil)) :group 'proof-goals) (defcustom pg-subterm-sep-char nil "Finishing special for a subterm markup. See doc of `pg-subterm-start-char'." :type '(choice character (const nil)) :group 'proof-goals) (defcustom pg-subterm-end-char nil "Closing special character for subterm markup. See `pg-subterm-start-char'." :type 'character :group 'proof-goals) (defcustom pg-topterm-regexp nil "Annotation regexp that indicates the beginning of a \"top\" element. A \"top\" element may be a sub-goal to be proved or a named hypothesis, for example. It could also be a literal command to insert and send back to the prover. The function `pg-topterm-goalhyplit-fn' examines text following this special character, to determine what kind of top element it is. 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-goals-font-lock-keywords nil "Value of `font-lock-keywords' used to fontify the goals output. The goals shell mode should set this before calling `proof-goals-config-done'. Used also by `proof-easy-config' mechanism. See also `proof-script-font-lock-keywords' and `proof-response-font-lock-keywords'." :type 'sexp :group 'proof-goals) (defcustom proof-response-font-lock-keywords nil "Value of `font-lock-keywords' used to fontify the response output. The response mode should set this before calling `proof-response-config-done'. Used also by `proof-easy-config' mechanism. See also `proof-script-font-lock-keywords' and `proof-goals-font-lock-keywords'." :type 'sexp :group 'proof-goals) (defcustom proof-shell-font-lock-keywords nil "Value of `font-lock-keywords' used to fontify the shell buiffer. The shell mode should may this before calling `proof-response-config-done'. Note that by default, font lock is turned *off* in shell buffers to improve performance. If you need to understand some output it may help to turn it on temporarily. See also `proof-script-font-lock-keywords', `proof-goals-font-lock-keywords' and `proof-response-font-lock-keywords'." :type 'sexp :group 'proof-goals) (defcustom pg-before-fontify-output-hook nil "This hook is called before fontifying a region in an output buffer. A function on this hook can alter the region of the buffer within the current restriction, and must return the final value of (point-max). \[This hook is presently only used by phox-sym-lock]." :type '(repeat function) :group 'proof-goals) (defcustom pg-after-fontify-output-hook nil "This hook is called before fonfitying a region in an output buffer. \[This hook is presently only used by Isabelle]." :type '(repeat function) :group 'proof-goals) (provide 'proof-config) ;;; proof-config.el ends here proofgeneral-4.3~pre130510/generic/proof-depends.el000066400000000000000000000232031214562307500221320ustar00rootroot00000000000000;;; proof-depends.el --- Theorem-theorem and theorem-definition dependencies ;; ;; Copyright (C) 2000-2004, 2010 University of Edinburgh. ;; Authors: David Aspinall ;; Earlier version by Fiona McNeil. ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; Status: Experimental code ;; ;; $Id: proof-depends.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; ;;; Commentary: ;; ;; Based on Fiona McNeill's MSc project on analysing dependencies ;; within proofs. Code rewritten by David Aspinall. ;; (require 'cl) (require 'span) (require 'pg-vars) (require 'proof-config) (require 'proof-autoloads) (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)))") ;;; Code: ;; 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 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." (span-set-property gspan 'dependencies ;; Ancestors of NAME are in the second component. ;; FIXME: for now we ignore the first component: ;; NAME may not be enough [Isar allows proof regions ;; with multiple names, which are reported in dep'c'y ;; output]. (cdr proof-last-theorem-dependencies)) (let* ((samefilenames (proof-depends-names-in-same-file (cdr 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 (span-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))) (span-set-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)))) (span-set-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. ;;;###autoload (defun proof-dependency-in-span-context-menu (span) "Make some menu entries showing proof dependencies of SPAN." ;; FIXME: might only activate this for dependency-relevant spans. (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-alldeps-menu span))) (defun proof-dep-alldeps-menu (span) (or (span-property span 'dependencies-menu) ;; cached value (span-set-property span 'dependencies-menu (proof-dep-make-alldeps-menu (span-property span 'dependencies))))) (defun proof-dep-make-alldeps-menu (deps) (let ((menuname "All Dependencies...") (showdep 'proof-show-dependency)) (if deps (let ((nestedtop (proof-dep-split-deps deps))) (cons menuname (append (mapcar (lambda (l) (vector l (list showdep l) t)) (cdr nestedtop)) (mapcar (lambda (sm) (proof-dep-make-submenu (car sm) 'car 'proof-show-dependency (mapcar 'list (cdr sm)))) (car nestedtop))))) (vector menuname nil nil)))) (defun proof-dep-split-deps (deps) "Split dependencies into named nested lists according to dotted prefixes." ;; NB: could handle deeper nesting here, but just do one level for now. (let (nested toplevel) ;; Add each name into a nested list or toplevel list (dolist (name deps) (let* ((period (string-match "\\." name)) (ns (and period (substring name 0 period))) (subitems (and ns (assoc ns nested)))) (cond ((and ns subitems) (setcdr subitems (adjoin name (cdr subitems)))) (ns (setq nested (cons (cons ns (list name)) nested))) (t (setq toplevel (adjoin name toplevel)))))) (cons nested toplevel))) (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. NAMEFN is applied to each element of LIST to make the names." (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) "Go to the start of 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) "Show dependency THM using `proof-show-dependency-cmd'. This is simply to display the dependency somehow." (if proof-shell-show-dependency-cmd ;; robustness (proof-shell-invisible-command (format proof-shell-show-dependency-cmd thm)))) (defconst pg-dep-span-priority 500) (defconst pg-ordinary-span-priority 100) (defun proof-highlight-depcs (name nmspans) (let ((helpmsg (concat "This item is a dependency (ancestor) of " name))) (while nmspans (let ((span (cadar nmspans))) (proof-depends-save-old-face span) (span-set-property span 'face 'proof-highlight-dependency-face) (span-set-property span 'priority pg-dep-span-priority) (span-set-property span 'mouse-highlight nil) (span-set-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))) (proof-depends-save-old-face span) (span-set-property span 'face 'proof-highlight-dependent-face) (span-set-property span 'priority pg-dep-span-priority) (span-set-property span 'mouse-highlight nil) (span-set-property span 'help-echo helpmsg) (span-set-property span 'balloon-help helpmsg)) (setq nmspans (cdr nmspans))))) (defun proof-depends-save-old-face (span) (unless (span-property span 'depends-old-face) (span-set-property span 'depends-old-face (span-property span 'face)))) (defun proof-depends-restore-old-face (span) (when (span-property span 'depends-old-face) (span-set-property span 'face (span-property span 'depends-old-face)) (span-set-property span 'depends-old-face nil))) (defun proof-dep-unhighlight () "Remove additional highlighting on all spans in file to their default." (interactive) (save-excursion (let ((span (span-at (point-min) 'type))) ;; FIXME: covers too many spans! (while span (pg-set-span-helphighlights span 'nohighlight) (proof-depends-restore-old-face span) (span-set-property span 'priority pg-ordinary-span-priority) (setq span (next-span span 'type)))))) (provide 'proof-depends) ;; proof-depends.el ends here (provide 'proof-depends) ;;; proof-depends.el ends here proofgeneral-4.3~pre130510/generic/proof-easy-config.el000066400000000000000000000075151214562307500227240ustar00rootroot00000000000000;; proof-easy-config.el Easy configuration for Proof General ;; ;; Copyright (C) 1999-2002 David Aspinall / LFCS. ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-easy-config.el,v 12.1 2012/01/23 08:59:32 da Exp $ ;; ;; Future versions 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-site) ; proof-assistant, proof-assistant-symbol (require 'proof-auxmodes) ; make sure extra modes available (defconst 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)) ;; FIXME: declare these variables in proof-config: ;; proof-{goals,response,trace}-syntax-table-entries ;; FIXME: in future versions, use these settings in *-config-done ;; to simplify elisp code elsewhere. ;; FIXME: add imenu-generic-expression too ;; (modsyn (intern (concat "proof-" suffixnm "-syntax-table-entries"))) (fullbody (append (if (and (boundp modsyn) (eval 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))))) (defun proof-easy-config-check-setup (sym name) "A number of simple checks." (let ((msg "")) ;; At the moment we just check that the symbol/name used ;; in the macro matches that in `proof-assistant-table' ;; and have the right type. (unless (symbolp sym) (error "Macro proof-easy-config: first argument (%s) should be a symbol" sym)) (unless (stringp name) (error "Macro proof-easy-config: second argument (%s) should be a string" name)) (cond ((or (and (boundp 'proof-assistant) proof-assistant (not (equal proof-assistant "")) (not (equal proof-assistant name)) (setq msg (format "\nproof-assistant name: \"%s\" doesn't match expected \"%s\"" proof-assistant name))) (and (boundp 'proof-assistant-symbol) proof-assistant-symbol (not (eq proof-assistant-symbol sym)) (setq msg (format "\nproof-assistant symbol: '%s doesn't match expected '%s" proof-assistant-symbol sym)))) (error "proof-easy-config: PG already in use or name/symbol mismatch %s" msg)) (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. The symbol SYM and string name NAME must match those given in the `proof-assistant-table', which see." `(progn (proof-easy-config-check-setup ,sym ,name) (setq ,@body) (proof-easy-config-define-derived-modes))) ;; (provide 'proof-easy-config) proofgeneral-4.3~pre130510/generic/proof-faces.el000066400000000000000000000200661214562307500215750ustar00rootroot00000000000000;;; proof-faces.el --- Faces for Proof General ;; ;; Copyright (C) 2009 LFCS Edinburgh. ;; Author: David Aspinall and others ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-faces.el,v 12.1 2012/08/16 14:58:40 da Exp $ ;; ;;; Commentary: ;; ;; In an ideal world, faces should work sensibly: ;; ;; a) with default colours ;; b) with -rv ;; c) on console ;; d) on different Emacsen/architectures (win32, mac, etc) ;; ;; But it's difficult to keep track of all that! ;; Please report any bad/failing colour ;; combinations (with suggested improvements) at ;; http://proofgeneral.inf.ed.ac.uk/trac ;; ;; 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. ;;; Code: (defgroup proof-faces nil "Faces used by Proof General." :group 'proof-general :prefix "proof-") ;; TODO: get rid of this list. Does 'default work widely enough ;; by now? (defconst pg-defface-window-systems '(x ;; bog standard mswindows ;; Windows w32 ;; Windows gtk ;; gtk emacs (obsolete?) mac ;; used by Aquamacs carbon ;; used by Carbon XEmacs ns ;; NeXTstep Emacs (Emacs.app) x-toolkit) ;; possible catch all (but probably not) "A list of possible values for variable `window-system'. If you are on a window system and your value of variable `window-system' is not listed here, you may not get the correct syntax colouring behaviour.") (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)))) pg-defface-window-systems)) (list (list t (quote ,ow))))) (defface proof-queue-face (proof-face-specs (:background "mistyrose") ;; was "darksalmon" in PG 3.4,3.5 (:background "mediumorchid") (:foreground "white" :background "black")) "*Face for commands in proof script waiting to be processed." :group 'proof-faces) (defface proof-locked-face (proof-face-specs ;; This colour is quite subjective and may be best chosen according ;; to the type of display you have. (:background "#eaf8ff") (:background "darkslateblue") (: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) (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) (defface proof-tactics-name-face (proof-face-specs (:foreground "darkblue") (:foreground "mediumpurple") (:underline t)) "*Face for names of tactics in proof scripts. Exactly what uses this face depends on the proof assistant." :group 'proof-faces) (defface proof-error-face (proof-face-specs (:background "rosybrown1") ; a drab version of misty rose (:background "brown") (: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 "palegoldenrod") (: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 "Gray75") (:background "Gray30") (:italic t)) "*Face for boring text in proof assistant output." :group 'proof-faces) (defface proof-mouse-highlight-face (proof-face-specs (:background "lightblue") (:background "darkslateblue") (:italic t)) "*General mouse highlighting face used in script buffer." :group 'proof-faces) (defface proof-command-mouse-highlight-face (proof-face-specs (:background "gold1") (:background "gold4") (:italic t)) "*Mouse highlighting face for atomic regions (usually commands) in script buffer." :group 'proof-faces) (defface proof-region-mouse-highlight-face (proof-face-specs (:background "yellow2") (:background "yellow3") (:italic t)) "*Mouse highlighting face for compound regions (usually proofs) in script buffer." :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) (defface proof-active-area-face (proof-face-specs (:background "lightyellow" :box (:line-width 2 :color "grey75" :style released-button)) (:background "darkyellow" :underline t) (:underline t)) "*Face for showing active areas (clickable regions), outside of subterm markup." :group 'proof-faces) (defface proof-script-sticky-error-face (proof-face-specs (:background "indianred1") (:background "indianred3") (:underline t)) "Proof General face for marking an error in the proof script. " :group 'proof-faces) (defface proof-script-highlight-error-face (proof-face-specs (:background "indianred1" :bold t) (:background "indianred3" :bold t) (:underline t :bold t)) "Proof General face for highlighting an error in the proof script. " :group 'proof-faces) ;;; Compatibility: these are required for use in GNU Emacs/font-lock-keywords (defconst proof-face-compat-doc "Evaluates to a face name, for compatibility.") (defconst proof-queue-face 'proof-queue-face proof-face-compat-doc) (defconst proof-locked-face 'proof-locked-face proof-face-compat-doc) (defconst proof-declaration-name-face 'proof-declaration-name-face proof-face-compat-doc) (defconst proof-tacticals-name-face 'proof-tacticals-name-face proof-face-compat-doc) (defconst proof-tactics-name-face 'proof-tactics-name-face proof-face-compat-doc) (defconst proof-error-face 'proof-error-face proof-face-compat-doc) (defconst proof-script-sticky-error-face 'proof-script-sticky-error-face proof-face-compat-doc) (defconst proof-script-highlight-error-face 'proof-script-highlight-error-face proof-face-compat-doc) (defconst proof-warning-face 'proof-warning-face proof-face-compat-doc) (defconst proof-eager-annotation-face 'proof-eager-annotation-face proof-face-compat-doc) (defconst proof-debug-message-face 'proof-debug-message-face proof-face-compat-doc) (defconst proof-boring-face 'proof-boring-face proof-face-compat-doc) (defconst proof-mouse-highlight-face 'proof-mouse-highlight-face proof-face-compat-doc) (defconst proof-command-mouse-highlight-face 'proof-command-mouse-highlight-face proof-face-compat-doc) (defconst proof-region-mouse-highlight-face 'proof-region-mouse-highlight-face proof-face-compat-doc) (defconst proof-highlight-dependent-face 'proof-highlight-dependent-face proof-face-compat-doc) (defconst proof-highlight-dependency-face 'proof-highlight-dependency-face proof-face-compat-doc) (defconst proof-active-area-face 'proof-active-area-face proof-face-compat-doc) (defconst proof-script-error-face 'proof-script-errror-face-compat-doc) (provide 'proof-faces) ;;; proof-faces.el ends here proofgeneral-4.3~pre130510/generic/proof-indent.el000066400000000000000000000063541214562307500220010ustar00rootroot00000000000000;;; proof-indent.el --- Generic indentation for proof assistants ;; ;; Authors: Markus Wenzel, David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-indent.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; ;;; Commentary: ;; (require 'proof-config) ; config variables (require 'proof-utils) ; proof-ass (require 'proof-syntax) ; p-looking-at-safe, p-re-search (require 'proof-autoloads) ; p-locked-end ;;; Code: (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 indentation level at point. INDENT is current indentation level, INNER a flag for inner indentation." (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-unprocessed-begin)) (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))))) (provide 'proof-indent) ;;; proof-indent.el ends here proofgeneral-4.3~pre130510/generic/proof-maths-menu.el000066400000000000000000000035741214562307500225770ustar00rootroot00000000000000;;; proof-maths-menu.el --- Support for maths menu mode package ;; ;; Copyright (C) 2007, 2009 LFCS Edinburgh / David Aspinall ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; ;; With thanks to Dave Love for the original maths menu code, ;; provided at http://www.loveshack.ukfsn.org/emacs/ ;; ;; $Id: proof-maths-menu.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; ;;; Commentary: ;; ;; Note: maths menu is bundled with Proof General in lib/, and PG will select ;; it's own version before any other version on the Emacs load path. ;; If you want to override this, simply load your version before ;; starting Emacs, with (require 'maths-menu). ;; ;;; Code: (eval-when-compile (require 'cl)) (eval-when (compile) (require 'proof-auxmodes) ; loaded by proof.el (require 'maths-menu)) ; loaded dynamically in proof-auxmodes ;;;###autoload (defun proof-maths-menu-set-global (flag) "Set global status of maths-menu mode for PG buffers to be FLAG. Turn on/off menu in all script buffers and ensure new buffers follow suit." (let ((hook (proof-ass-sym mode-hook))) (if flag (add-hook hook 'maths-menu-mode) (remove-hook hook 'maths-menu-mode)) (proof-map-buffers (proof-buffers-in-mode proof-mode-for-script) (maths-menu-mode (if flag 1 0))))) ;;;###autoload (defun proof-maths-menu-enable () "Turn on or off maths-menu mode in Proof General script buffer. This invokes `maths-menu-mode' to toggle the setting for the current buffer, and then sets PG's option for default to match. Also we arrange to have maths menu mode turn itself on automatically in future if we have just activated it for this buffer." (interactive) (require 'maths-menu) (if (proof-maths-menu-support-available) (proof-maths-menu-set-global (not maths-menu-mode)))) (provide 'proof-maths-menu) ;;; proof-maths-menu.el ends here proofgeneral-4.3~pre130510/generic/proof-menu.el000066400000000000000000001074301214562307500214610ustar00rootroot00000000000000;;; proof-menu.el --- Menus, keymaps, misc commands for Proof General ;; ;; Copyright (C) 2000,2001,2009,2010,2011 LFCS Edinburgh. ;; Authors: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-menu.el,v 12.3 2012/08/16 15:01:05 da Exp $ ;; (require 'cl) ; mapcan ;;; Code: (eval-when (compile) (defvar proof-assistant-menu nil) ; defined by macro in proof-menu-define-specific (defvar proof-mode-map nil)) (require 'proof-utils) ; proof-deftoggle, proof-eval-when-ready-for-assistant (require 'proof-useropts) (require 'proof-config) (eval-when-compile (defvar proof-assistant-menu) ; defined by macro in proof-menu-define-specific (defvar proof-mode-map)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Miscellaneous commands ;;; (defvar proof-display-some-buffers-count 0) (defun proof-display-some-buffers () "Display the reponse, trace, goals, or shell buffer, rotating. A fixed number of repetitions of this command switches back to the same buffer. Also move point to the end of the response buffer if it's selected. If in three window or multiple frame mode, display two buffers. The idea of this function is to change the window->buffer mapping without adjusting window layout." (interactive) ;; Idea: a humane toggle, which allows habituation. ;; E.g. two taps of C-c C-l always shows the goals buffer, three the ;; trace buffer, etc. (Makes less sense from the menu, though, ;; where it seems more natural just to rotate from last position) (cond ((and (called-interactively-p 'any) (eq last-command 'proof-display-some-buffers)) (incf proof-display-some-buffers-count)) (t (setq proof-display-some-buffers-count 0))) (let* ((assocbufs (remove-if-not 'buffer-live-p (list proof-response-buffer proof-thms-buffer proof-trace-buffer proof-goals-buffer ))) ;proof-shell-buffer (numassoc (length assocbufs))) ;; If there's no live other buffers, we don't do anything. (unless (zerop numassoc) (let ((selectedbuf (nth (mod proof-display-some-buffers-count numassoc) assocbufs)) (nextbuf (nth (mod (1+ proof-display-some-buffers-count) numassoc) assocbufs))) (cond ((or proof-three-window-enable proof-multiple-frames-enable) ;; Display two buffers: next in rotation and goals/response ;; FIXME: this doesn't work as well as it might. (proof-switch-to-buffer selectedbuf 'noselect) (proof-switch-to-buffer (if (eq selectedbuf proof-goals-buffer) proof-response-buffer proof-goals-buffer) 'noselect)) (selectedbuf (proof-switch-to-buffer selectedbuf 'noselect))) (if (eq selectedbuf proof-response-buffer) (set-window-point (get-buffer-window proof-response-buffer t) (point-max))) (pg-response-buffers-hint (buffer-name nextbuf)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Key bindings ;;; ;;;###autoload (defun proof-menu-define-keys (map) "Prover specific keymap under C-c C-a." ;; 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 b)] 'proof-process-buffer) ;; C-c C-c is proof-interrupt-process in universal-keys (define-key map [(control c) (control d)] 'proof-tree-external-display-toggle) ;; C-c C-f is proof-find-theorems in universal-keys (define-key map [(control c) (control H)] 'proof-help) ;; C-c C-l is proof-layout-windows in universal-keys ;; C-c C-n is proof-assert-next-command-interactive in universal-keys ;; C-c C-o is proof-display-some-buffers in universal-keys (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 i)] 'proof-query-identifier) ;; C-c C-u is proof-undo-last-successful-command in universal-keys ;; C-c C-w is pg-response-clear-displays in universal-keys (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 ;; C-c C-. is proof-goto-end-of-locked in universal-keys (define-key map [(control c) (control return)] 'proof-goto-point) (define-key map [(control c) ?v] 'pg-toggle-visibility) (define-key map [(control meta mouse-3)] 'proof-mouse-goto-point) ;; NB: next binding overwrites comint-find-source-code. (define-key map [(meta p)] 'pg-previous-matching-input-from-input) (define-key map [(meta n)] 'pg-next-matching-input-from-input) ;; Standard binding for completion (define-key map [(control return)] 'proof-script-complete) (define-key map [(control c) (control ?\;)] 'pg-insert-last-output-as-comment) ;; (define-key map [(control meta up)] 'pg-move-region-up) (define-key map [(control meta down)] 'pg-move-region-down) ;; (define-key map [(control c) ?b] 'proof-toolbar-toggle) (define-key map [(control c) ?>] 'proof-autosend-toggle) ;; Add the universal keys bound in all PG buffers. ;; NB: 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" (proof-main-menu))) ;; The proof assistant specific menu (defvar proof-menu-favourites nil "The Proof General favourites menu for the current proof assistant.") (defvar proof-menu-settings nil "Settings submenu for Proof General.") ;;;###autoload (defun proof-menu-define-specific () (easy-menu-do-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)) ;; TODO: doc -set-command here (vector (concat "Set " proof-assistant " Command") (proof-ass-sym set-command) ':visible '(fboundp (proof-ass-sym set-command)))) '("----") (list (cons "Help" (append (list (vector (concat proof-assistant " Information") 'proof-help :visible proof-info-command) (vector (concat proof-assistant " Web Page") '(browse-url proof-assistant-home-page) :visible proof-assistant-home-page)) (proof-ass help-menu-entries)))))))) (defun proof-assistant-menu-update () "Update proof assistant menu in scripting buffers." (proof-map-buffers (proof-buffers-in-mode proof-mode-for-script) (easy-menu-remove proof-assistant-menu) (proof-menu-define-settings-menu) (proof-menu-define-specific) (easy-menu-add proof-assistant-menu (proof-ass mode-map)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Contents of sub menus ;; (defvar proof-help-menu '("Help" ["About PG" proof-splash-display-screen t] ["Info" (info "ProofGeneral") t] ["Homepage" (browse-url proof-general-home-page) t] ["Send Bug Report" proof-submit-bug-report t]) "Proof General help menu.") (defvar proof-show-hide-menu '(("Show All" ["Proofs" (pg-show-all-portions 'proof) t] ["Commands" (pg-show-all-portions 'command) t] ["Comments" (pg-show-all-portions 'comment) t]) ("Hide All" ["Proofs" (pg-show-all-portions 'proof 'hide) t] ["Commands" (pg-show-all-portions 'command 'hide) t] ["Comments" (pg-show-all-portions 'comment 'hide) t])) "Show/hide submenu.") (defvar proof-buffer-menu (cons "Buffers" '(["Layout Windows" proof-layout-windows] ["Rotate Output Buffers" proof-display-some-buffers :visible (not proof-three-window-enable) :active (buffer-live-p proof-goals-buffer)] ["Clear Responses" pg-response-clear-displays :active (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)] ["Trace" (proof-switch-to-buffer proof-trace-buffer) :active (buffer-live-p proof-trace-buffer) :visible proof-shell-trace-output-regexp] ["Shell" (proof-switch-to-buffer proof-shell-buffer) :active (buffer-live-p proof-shell-buffer)])) "Proof General buffer menu.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; "Quick" (or main) options ;; ;; First, make the togglers used in options menu below (proof-deftoggle proof-script-fly-past-comments) (proof-deftoggle proof-delete-empty-windows) (proof-deftoggle proof-shrink-windows-tofit) (proof-deftoggle proof-multiple-frames-enable proof-multiple-frames-toggle) (proof-deftoggle proof-layout-windows-on-visit-file proof-layout-windows-eagerly-toggle) (proof-deftoggle proof-three-window-enable proof-three-window-toggle) (proof-deftoggle proof-auto-raise-buffers proof-auto-raise-toggle) (proof-deftoggle proof-disappearing-proofs) (proof-deftoggle proof-full-annotation) (proof-deftoggle proof-colour-locked) (proof-deftoggle proof-sticky-errors) (proof-deftoggle proof-shell-quiet-errors) (proof-deftoggle proof-minibuffer-messages) (proof-deftoggle proof-output-tooltips) (proof-deftoggle proof-autosend-enable proof-autosend-toggle) (proof-deftoggle proof-fast-process-buffer) (proof-deftoggle proof-imenu-enable proof-imenu-toggle) (proof-deftoggle proof-keep-response-history) (proof-eval-when-ready-for-assistant ;; togglers for settings separately configurable per-prover (proof-deftoggle-fn (proof-ass-sym unicode-tokens-enable) 'proof-unicode-tokens-toggle) (proof-deftoggle-fn (proof-ass-sym maths-menu-enable) 'proof-maths-menu-toggle) (proof-deftoggle-fn (proof-ass-sym mmm-enable) 'proof-mmm-toggle)) (defun proof-keep-response-history () "Enable associated buffer histories following `proof-keep-response-history'." (if proof-keep-response-history (proof-map-buffers (proof-associated-buffers) (bufhist-init)) (proof-map-buffers (proof-associated-buffers) (bufhist-exit)))) ;; Here is the menu (defconst proof-quick-opts-menu (cons "Quick Options" `( ;;; TODO: Add this in PG 4.0 once bufhist robust; see trac #169 ;;; ["Response history" proof-keep-response-history-toggle ;;; :style toggle ;;; :selected proof-keep-response-history] ("Processing" ["Fast Process Buffer" proof-fast-process-buffer-toggle :style toggle :selected proof-fast-process-buffer :help "Use a fast loop when processing whole buffer (disables input)"] ["Electric Terminator" proof-electric-terminator-toggle :style toggle :selected proof-electric-terminator-enable :help "Automatically send commands when terminator typed"] ["Beep on Errors" proof-shell-quiet-errors-toggle :style toggle :selected (not proof-shell-quiet-errors) :help "Beep on errors or interrupts"] ["Fly Past Comments" proof-script-fly-past-comments-toggle :style toggle :selected proof-script-fly-past-comments :help "Coalesce and skip over successive comments"] ["Full Annotation" proof-full-annotation-toggle :style toggle :selected proof-full-annotation :help "Record full information to decorate scripts (may cause slowdown)"] ["Process Automatically" proof-autosend-toggle :style toggle :selected proof-autosend-enable :help "Automatically send commands when idle"] ("Automatic Processing Mode" ["Next Command" (customize-set-variable 'proof-autosend-all nil) :style radio :selected (eq proof-autosend-all nil) :active proof-autosend-enable :help "Automatically try out the next commmand"] ["Send Whole Buffer" (customize-set-variable 'proof-autosend-all t) :style radio :selected (eq proof-autosend-all t) :active proof-autosend-enable :help "Automatically send the whole buffer"])) ("Display" ["Toolbar" proof-toolbar-toggle :style toggle :visible (featurep 'tool-bar) :selected proof-toolbar-enable :help "Use the Proof General toolbar"] ["Unicode Tokens" (proof-unicode-tokens-toggle (if (boundp 'unicode-tokens-mode) (if unicode-tokens-mode 0 1) 1)) :active (proof-unicode-tokens-support-available) :style toggle :selected (and (boundp 'unicode-tokens-mode) unicode-tokens-mode) :help "Enable display of tokens as Unicode characters"] ["Minibuffer Messages" proof-minibuffer-messages-toggle :style toggle :selected proof-minibuffer-messages :help "Show progress messages in minibuffer"] ["Output Tooltips" proof-output-tooltips-toggle :style toggle :selected proof-output-tooltips :help "Add tooltips for prover output"] ["Auto Raise" proof-auto-raise-toggle :style toggle :selected proof-auto-raise-buffers :help "Automatically raise buffers when output arrives"] ["Use Three Panes" proof-three-window-toggle :style toggle :active (not proof-multiple-frames-enable) :selected proof-three-window-enable :help "Use three panes"] ;; We use non-Emacs terminology "Windows" in this menu to help ;; non-Emacs users. Cf. Gnome usability studies: menus saying ;; "Web Browser" more useful to novices than menus saying "Mozilla"!! ["Layout Eagerly" proof-layout-windows-eagerly-toggle :style toggle :selected proof-layout-windows-on-visit-file :help "Display prover output windows when script file is opened."] ["Multiple Windows" proof-multiple-frames-toggle :active (and window-system t) :style toggle :selected proof-multiple-frames-enable :help "Use multiple windows (Emacs frames) for display"] ["Delete Empty Panes" proof-delete-empty-windows-toggle :active (not proof-multiple-frames-enable) :style toggle :selected proof-delete-empty-windows :help "Dynamically remove empty panes from display"] ["Shrink to Fit" proof-shrink-windows-tofit-toggle :active (not proof-multiple-frames-enable) :style toggle :selected proof-shrink-windows-tofit :help "Dynamically shrink size of output panes to fit contents"] ["Colour Locked" proof-colour-locked-toggle :style toggle :selected proof-colour-locked :help "Add highlighting to locked (checked) text"] ["Sticky Errors" proof-sticky-errors-toggle :style toggle :selected proof-sticky-errors :help "Highlight commands that caused errors"] ["Disppearing Proofs" proof-disappearing-proofs-toggle :style toggle :selected proof-disappearing-proofs :help "Hide proofs as they are completed"] "----" ["Document Centred" proof-set-document-centred :help "Select options for document-centred working"] ["Default" proof-set-non-document-centred :help "Set options for classic Proof General interaction"]) ("Read Only" ["Strict Read Only" (customize-set-variable 'proof-strict-read-only t) :style radio :selected (eq proof-strict-read-only t) :help "Do not allow editing in processed region"] ["Undo On Edit" (customize-set-variable 'proof-strict-read-only 'retract) :style radio :selected (eq proof-strict-read-only 'retract) :help "Automatically retract on edits in processed region"] ["Freely Edit" (customize-set-variable 'proof-strict-read-only nil) :style radio :selected (null proof-strict-read-only) :help "No write protection, edit anywhere. Dangerous!"]) ("Follow Mode" ["Follow Locked Region" (customize-set-variable 'proof-follow-mode 'locked) :style radio :selected (eq proof-follow-mode 'locked) :help "Point follows the locked region"] ;; Not implemented. See Trac #187 ;; ["Follow On Success" ;; (customize-set-variable 'proof-follow-mode 'followsuccess) ;; :style radio ;; :selected (eq proof-follow-mode 'followdown)] ["Follow Locked Region Down" (customize-set-variable 'proof-follow-mode 'followdown) :style radio :selected (eq proof-follow-mode 'followdown) :help "Point follows the locked region when processsing"] ["Keep Locked Region Displayed" (customize-set-variable 'proof-follow-mode 'follow) :style radio :selected (eq proof-follow-mode 'follow) :help "Scroll to ensure end of lock region is visible"] ["Never Move" (customize-set-variable 'proof-follow-mode 'ignore) :style radio :selected (eq proof-follow-mode 'ignore) :help "Do not move cursor during processing"]) ("Deactivate Action" ["Retract" (customize-set-variable 'proof-auto-action-when-deactivating-scripting 'retract) :style radio :selected (eq proof-auto-action-when-deactivating-scripting 'retract)] ["Process" (customize-set-variable 'proof-auto-action-when-deactivating-scripting 'process) :style radio :selected (eq proof-auto-action-when-deactivating-scripting 'process)] ["Query" (customize-set-variable 'proof-auto-action-when-deactivating-scripting nil) :style radio :selected (null proof-auto-action-when-deactivating-scripting)]) ("Minor Modes" ["Unicode Maths Menu" (proof-maths-menu-toggle (if (boundp 'maths-menu-mode) (if maths-menu-mode 0 1) 1)) :active (proof-maths-menu-support-available) :style toggle :selected (and (boundp 'maths-menu-mode) maths-menu-mode) :help "Maths menu for inserting Unicode characters"] ["Multiple Modes" (proof-mmm-toggle (if mmm-mode 0 1)) :active (proof-mmm-support-available) :style toggle :selected (and (boundp 'mmm-mode) mmm-mode) :help "Allow multiple major modes"] ["Index Menu" proof-imenu-toggle :active (stringp (locate-library "imenu")) :style toggle :selected proof-imenu-enable :help "Generate an index menu of definitions, display which function in modeline"] "----" ;; NB: next group not saved, just for convenience here to ;; hint they're defined for PG ["Outline" outline-minor-mode :active (stringp (locate-library "outline")) :style toggle :selected (and (boundp 'outline-minor-mode) outline-minor-mode) :help "Outline mode for folding (note: option not saved)"] ["Hide/Show" hs-minor-mode :active (stringp (locate-library "hideshow")) :style toggle :selected (and (boundp 'hs-minor-mode) hs-minor-mode) :help "Hide/Show mode for folding (note: option not saved)"] ["Speedbar" speedbar :active (stringp (locate-library "speedbar")) :style toggle :selected (and (boundp 'speedbar-frame) speedbar-frame) :help "Speedbar navigation window (note: option not saved)"]) "----" ["Reset Options" (proof-quick-opts-reset) (proof-quick-opts-changed-from-defaults-p)] ["Save Options" (proof-quick-opts-save) (proof-quick-opts-changed-from-saved-p)])) "Proof General quick options.") (defun proof-quick-opts-vars () "Return a list of the quick option variables." (list 'proof-electric-terminator-enable 'proof-autosend-enable 'proof-fast-process-buffer 'proof-script-fly-past-comments 'proof-disappearing-proofs 'proof-full-annotation 'proof-strict-read-only (proof-ass-sym unicode-tokens-enable) (proof-ass-sym maths-menu-enable) (proof-ass-sym mmm-enable) 'proof-toolbar-enable 'proof-keep-response-history 'proof-imenu-enable 'proof-shell-quiet-errors ;; Display sub-menu 'proof-minibuffer-messages 'proof-auto-raise-buffers 'proof-three-window-enable 'proof-delete-empty-windows 'proof-multiple-frames-enable 'proof-shrink-windows-tofit 'proof-multiple-frames-enable 'proof-colour-locked 'proof-sticky-errors ;; Follow mode sub-menu 'proof-follow-mode ;; Deactivate scripting action proof-auto-action-when-deactivating-scripting)) (defun proof-quick-opts-changed-from-defaults-p () ;; NB: would be nice to add. Custom support? t) (defun proof-quick-opts-changed-from-saved-p () ;; NB: would be nice to add. Custom support? t) ;; ;; Changing several options together (ugly UI) ;; (defun proof-set-document-centred () "Select options for document-centred working" (interactive) (proof-full-annotation-toggle 1) (proof-auto-raise-toggle 0) (proof-colour-locked-toggle 0) (proof-sticky-errors-toggle 1) (proof-autosend-toggle 1) (customize-set-variable 'proof-strict-read-only 'retract) (customize-set-variable 'proof-autosend-all t) (customize-set-variable 'proof-follow-mode 'ignore)) (defun proof-set-non-document-centred () "Set options for classic Proof General interaction" (interactive) ;; default: (proof-full-annotation-toggle 1) (proof-auto-raise-toggle 1) (proof-colour-locked-toggle 1) (proof-sticky-errors-toggle 0) (proof-autosend-toggle 0) ;; default: (customize-set-variable 'proof-strict-read-only 'retract) (customize-set-variable 'proof-autosend-all nil) (customize-set-variable 'proof-follow-mode 'ignore)) ;; ;; We have menu items for saving options and reseting them. ;; We could just store the settings automatically (no save), ;; but then the reset option would have to change to restore ;; to manufacturer settings (rather then user-stored ones). ;; (defun proof-quick-opts-save () "Save current values of PG Options menu items using custom." (interactive) (apply 'pg-custom-save-vars (proof-quick-opts-vars))) (defun proof-quick-opts-reset () "Reset PG Options menu to default (or user-set) values, using custom." (interactive) (apply 'pg-custom-reset-vars (proof-quick-opts-vars))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Main menu ;; (defconst proof-config-menu (list "----" ;; buffer menu might better belong in toolbar menu? proof-buffer-menu proof-quick-opts-menu) "Proof General configuration menu.") (defconst proof-advanced-menu (cons "Advanced" (append '(["Complete Identifier" proof-script-complete :help "Complete the identifier at point"] ["Insert Last Output" pg-insert-last-output-as-comment :active proof-shell-last-output :help "Insert the last output into the proof script as a comment"] ["Make Movie" pg-movie-export :help "Export processed portion as Movie XML file (enable Full Annotations first!)"]) (list "-----") proof-show-hide-menu (list "-----") (list (customize-menu-create 'proof-general)) (list (customize-menu-create 'proof-general-internals "Internals")))) "Advanced sub-menu of script functions and customize.") (defvar proof-menu '(["Next Error" proof-next-error :active pg-next-error-regexp] ["Scripting Active" proof-toggle-active-scripting :style toggle :selected (eq proof-script-buffer (current-buffer))]) "The Proof General generic menu for scripting buffers.") (defun proof-main-menu () "Construct and return PG main menu used in scripting buffers." (cons proof-general-name (append (proof-toolbar-scripting-menu) proof-menu proof-config-menu (list (customize-menu-create 'proof-user-options "Customize Options")) (list proof-advanced-menu) (list proof-help-menu)))) ;;;###autoload (defun proof-aux-menu () "Construct and return PG auxiliary menu used in non-scripting buffers." (cons proof-general-name (append (proof-toolbar-scripting-menu) proof-config-menu (list proof-help-menu)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Favourites mechanism for prover-specific menu ;;; (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 ;; (list "----") doesn't work for adding before '(["Add Favourite" (call-interactively 'proof-add-favourite) t] ["Delete Favourite" (call-interactively 'proof-del-favourite) t] ["Save Favourites" (proof-save-favourites) t]))))))) ;;; Define stuff from favourites (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 (mapconcat 'identity 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))) ;;; Commentary: ;; ;;; Code for adding "favourites" to the proof-assistant specific menu (defvar proof-make-favourite-cmd-history nil "History for proof-make-favourite.") (defvar proof-make-favourite-menu-history nil "History for proof-make-favourite.") (defun proof-save-favourites () "Save favourites in customization settings." (interactive) (pg-custom-save-vars (proof-ass-sym favourites))) (defun proof-del-favourite (menuname) "Delete \"favourite\" command recorded at MENUNAME." (interactive (list (completing-read "Menu item to delete: " (mapcar 'cddr (proof-ass favourites)) nil t))) (let* ((favs (proof-ass favourites)) (rmfavs (remove-if (lambda (f) (string-equal menuname (caddr f))) favs))) (unless (equal favs rmfavs) (easy-menu-remove-item proof-assistant-menu '("Favourites") menuname) (customize-set-variable (proof-ass-sym favourites) rmfavs)))) (defun proof-read-favourite () (let* ((guess (buffer-substring (save-excursion (beginning-of-line-text) (point)) (point))) (cmd (read-string (concat "Command to send to " proof-assistant ": ") guess 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 proof-make-favourite-menu-history)) (key (if (y-or-n-p "Set a keybinding for this command? ") ;; FIXME: better validation here would be to check ;; this is a new binding, or remove old binding below. (read-key-sequence "Type the key to use (binding will be C-c C-a ): " nil t)))) ;; result (list cmd ins men key))) (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 (proof-read-favourite)) (let* ((menu-entry (proof-def-favourite command inscript menuname key t)) (favs (proof-ass favourites)) (rmfavs (remove-if (lambda (f) (string-equal menuname (caddr f))) favs)) (newfavs (append rmfavs (list (list command inscript menuname key))))) ;; If def succeeds, add to customize var (customize-set-variable (proof-ass-sym favourites) newfavs) (easy-menu-add-item proof-assistant-menu '("Favourites") menu-entry "Add Favourite"))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Proof assistant settings mechanism. ;;; (defun proof-menu-define-settings-menu () "Return menu generated from `proof-assistant-settings', update `proof-menu-settings'." (if proof-assistant-settings (let ((save (list "----" ["Reset Settings" (proof-settings-reset) (proof-settings-changed-from-defaults-p)] ["Save Settings" (proof-settings-save) (proof-settings-changed-from-saved-p)])) groups ents) (mapc (lambda (stg) (add-to-list 'groups (get (car stg) 'pggroup))) proof-assistant-settings) (dolist (grp (reverse groups)) (let* ((gstgs (mapcan (lambda (stg) (if (eq (get (car stg) 'pggroup) grp) (list stg))) proof-assistant-settings)) (cmds (mapcar (lambda (stg) (apply 'proof-menu-entry-for-setting stg)) (reverse gstgs)))) (setq ents (if grp (cons (cons grp cmds) ents) (append cmds (if (> (length groups) 1) '("----")) ents))))) (setq proof-menu-settings (list (cons "Settings" (nconc ents save))))))) (defun proof-menu-entry-name (symbol) "Return a nice menu entry name for SYMBOL." (let ((grp (get symbol 'pggroup)) (nm (symbol-name symbol))) (upcase-initials (replace-regexp-in-string "-" " " ;; strip the group name from the menu entry name. (if grp (replace-regexp-in-string (concat (downcase grp) ":") "" nm) nm))))) (defun proof-menu-entry-for-setting (symbol setting type descr) (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 :help descr)) ((eq type 'integer) (vector entry-name (proof-defintset-fn pasym) :help descr)) ((eq type 'number) (vector entry-name (proof-deffloatset-fn pasym) :help descr)) ((eq type 'string) (vector entry-name (proof-defstringset-fn pasym) :help descr))))) (defun proof-settings-vars () "Return a list of proof assistant setting variables." (mapcar (lambda (setting) (proof-ass-symv (car setting))) proof-assistant-settings)) (defun proof-settings-changed-from-defaults-p () ;; FIXME: would be nice to add. Custom support? t) (defun proof-settings-changed-from-saved-p () ;; FIXME: would be nice to add. Custom support? t) (defun proof-settings-save () "Save current values of proof assistant settings using Custom." (interactive) (apply 'pg-custom-save-vars (proof-settings-vars))) (defun proof-settings-reset () "Reset proof assistant settings to their default values." (interactive) (apply 'pg-custom-reset-vars (proof-settings-vars))) (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"). ;; PG 3.5 (patch 22.04.04): ;; Let's approximate that by looking at proof-nesting-depth. (if (and proof-showproof-command (> proof-nesting-depth 0)) (proof-shell-invisible-command proof-showproof-command)) ;; Could also repeat last command if non-state destroying. ))) (defun proof-maybe-askprefs () "If `proof-use-pgip-askprefs' is non-nil, try to issue . This will configure dynamic settings used in the current prover session and extend `proof-assistant-settings'. We first clear the dynamic settings from `proof-assistant-settings'." (when (and proof-use-pgip-askprefs proof-shell-issue-pgip-cmd) (let (newsettings) (dolist (setting proof-assistant-settings) (let ((name (car setting))) (if (get name 'pgdynamic) (undefpgcustom name) (push setting newsettings)))) (setq proof-assistant-settings newsettings)) (pg-pgip-askprefs))) (defun proof-assistant-settings-cmd (setting) "Return string for making SETTING in Proof General customization." (let ((expr (assq setting proof-assistant-settings))) (if (and expr (cadr expr)) (proof-assistant-format (cadr expr) (eval (proof-ass-symv (car expr))))))) (defun proof-assistant-settings-cmds () "Return strings for settings kept in Proof General customizations." (let (cmds) (dolist (setting proof-assistant-settings) (let ((sym (car setting)) (pacmd (cadr setting))) (if (and pacmd (or (not (get sym 'pgdynamic)) (proof-ass-differs-from-default sym))) (push (proof-assistant-format pacmd (eval (proof-ass-symv sym))) cmds)))) cmds)) (defvar proof-assistant-format-table (list (cons "%b" '(proof-assistant-format-bool curvalue)) (cons "%i" '(proof-assistant-format-int curvalue)) (cons "%f" '(proof-assistant-format-float 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-float (value) (funcall proof-assistant-format-float-fn value)) (defun proof-assistant-format-string (value) (funcall proof-assistant-format-string-fn value)) (defun proof-assistant-format (string curvalue) "Replace a format characters in STRING by formatted CURVALUE. Format character is one of %b, %i, %f, or %s. Formatting suitable for current proof assistant, controlled by `proof-assistant-format-table' which see. Finally, apply `proof-assistant-setting-format' if non-nil. Alternatively, STRING can be a function which yields a string when applied to the CURVALUE. As another 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." (let ((setting (cond ((stringp string) ;; use % format characters (proof-format proof-assistant-format-table string)) ((functionp string) ;; call the function (funcall string curvalue)) ((consp string) ;; true/false options (if curvalue (car string) (cdr string))) (t ;; no idea what to do (error "proof-assistant-format: called with invalid string arg %s" string))))) (if proof-assistant-setting-format (funcall proof-assistant-setting-format setting) setting))) (provide 'proof-menu) ;;; proof-menu.el ends here proofgeneral-4.3~pre130510/generic/proof-mmm.el000066400000000000000000000053411214562307500213010ustar00rootroot00000000000000;; proof-mmm.el --- Support for MMM mode package ;; ;; Copyright (C) 2003, 2010 LFCS Edinburgh / David Aspinall ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; The MMM package is at http://mmm-mode.sourceforge.net/ ;; ;; $Id: proof-mmm.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; ;;; Commentary: ;; ;; Configuration for the prover is expected to reside in -mmm.el ;; It should define an MMM submode class called . ;; ;; NB: mmm-mode is bundled with Proof General, and PG will select ;; it's own version before any other version on the Emacs load path. ;; If you want to override this, simply load your version before ;; starting Emacs, with (require 'mmm-auto). ;; ;; Credits: thanks to Stefan Monnier for pointing me to this package, ;; and Michael Abraham Shulman for providing it. ;; ;;; Code: (eval-when-compile (require 'cl)) (eval-when (compile) (require 'proof-auxmodes) ; will be loaded (require 'mmm-auto)) ; loaded dynamically by proof-auxmodes ;; The following function is called by the menu item for MMM-Mode. It ;; is an attempt at an intuitive behaviour without confusing the user ;; with extra "in this buffer" and "everywhere" options. We make the ;; global option track the last setting made for any buffer. The menu ;; toggle displays the status of the buffer (as seen in the modeline) ;; rather than the PG setting. ;;;###autoload (defun proof-mmm-set-global (flag) "Set global status of MMM mode for PG buffers to be FLAG." (let ((automode-entry (list (proof-ass-sym mode) nil proof-assistant-symbol))) (if flag (add-to-list 'mmm-mode-ext-classes-alist automode-entry) (setq mmm-mode-ext-classes-alist (delete automode-entry mmm-mode-ext-classes-alist))) ;; make sure MMM obeys the mmm-mode-ext-classes-alist (unless (eq mmm-global-mode t) (setq mmm-global-mode 'pg-use-mode-ext-classes-alist)))) ;;;###autoload (defun proof-mmm-enable () "Turn on or off MMM mode in Proof General script buffer. This invokes `mmm-mode' to toggle the setting for the current buffer, and then sets PG's option for default to match. Also we arrange to have MMM mode turn itself on automatically in future if we have just activated it for this buffer." (interactive) (when (proof-mmm-support-available) ;; Make sure auto mode follows PG's global setting. (NB: might do ;; only if global state changes, but by now (proof-ass mmm-mode) set). (with-no-warnings ; bytecomp gives spurious error ; "proof-mmm-set-global might not be defined" ; because the autoload overrides the definition above(!) (proof-mmm-set-global (not mmm-mode))) (mmm-mode))) (provide 'proof-mmm) ;;; proof-mmm.el ends here proofgeneral-4.3~pre130510/generic/proof-script.el000066400000000000000000003147571214562307500220350ustar00rootroot00000000000000;;; proof-script.el --- Major mode for proof assistant script files. ;; ;; Copyright (C) 1994-2010 LFCS Edinburgh. ;; Authors: David Aspinall, Yves Bertot, Healfdene Goguen, ;; Thomas Kleymann and Dilip Sequeira ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-script.el,v 12.5 2012/08/16 15:01:05 da Exp $ ;; ;;; Commentary: ;; ;; This implements the main mode for script management, including ;; parsing script buffers and setting spans inside them. ;; ;; Compile note: functions used here from proof-shell, pg-user, ;; pg-response, pg-goals auto-loaded to prevent circular dependency. ;;; Code: (require 'cl) ; various (require 'span) ; abstraction of overlays/extents (require 'proof-utils) ; proof-utils macros (require 'proof-syntax) ; utils for manipulating syntax (eval-when-compile (require 'easymenu) (defvar proof-mode-menu nil) (defvar proof-assistant-menu nil)) (declare-function proof-shell-strip-output-markup "proof-shell" (string &optional push)) (declare-function proof-shell-make-associated-buffers "proof-shell" ()) (declare-function proof-layout-windows "pg-response" (&rest args)) (declare-function pg-response-warning "pg-response" (&rest args)) (declare-function proof-segment-up-to "proof-script") (declare-function proof-autosend-enable "pg-user") (declare-function proof-interrupt-process "pg-shell") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PRIVATE VARIABLES ;; ;; Local variables used by proof-script-mode ;; ;; Buffer-local variables (deflocal proof-active-buffer-fake-minor-mode nil "An indication in the modeline that this is the *active* script buffer") (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.") (deflocal pg-script-portions nil "Alist of hash tables for symbols naming processed script portions.") (defalias 'proof-active-buffer-fake-minor-mode 'proof-toggle-active-scripting) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Counting and naming proof elements ;; (defun proof-next-element-count (idiom) "Return count for next element of type IDIOM. This uses the size of the hash table for IDIOM." (let ((tbl (cdr-safe (assq idiom pg-script-portions)))) (if tbl (1+ (hash-table-count tbl)) 1))) (defun proof-element-id (idiom number) "Return a string identifier composed from symbol IDIOM and NUMBER." (concat (symbol-name idiom) "-" (int-to-string number))) (defun proof-next-element-id (idiom) "Return a string suitable for naming the next element of type IDIOM." (proof-element-id idiom (proof-next-element-count idiom))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Basic functions for handling the locked and queue regions ;; ;; -------------------------------------------------------------- ;; ;; Notes on regions in the scripting buffer. (da) ;; ;; The locked region is covered by a collection of non-overlaping ;; spans (spans are our abstraction of extents/overlays). ;; ;; Each 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 ;; ;; 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. ;; ;; A spans corresponding to a command has 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. ;; ;; ** Variables (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.") (deflocal proof-queue-span nil "The queue span of the buffer. May be detached if inactive or empty. Each script buffer has its own queue span, although only the active scripting buffer may have an active queue span.") ;; da: reason for buffer local queue span is because initialisation ;; in proof-init-segmentation 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-overlay-arrow nil "Marker holding the overlay arrow position for this buffer.") ;; ** Getters and setters (defun proof-span-give-warning (&rest args) "Give a warning message. Optional argument ARGS is ignored." (unless inhibit-read-only (message "You should not edit here!"))) (defun proof-span-read-only (span &optional always) "Make SPAN read-only, following variable `proof-strict-read-only' or ALWAYS." (if (or always (not (memq proof-strict-read-only '(nil retract)))) (span-read-only span) (span-write-warning span (if (eq proof-strict-read-only 'retract) 'proof-retract-before-change 'proof-span-give-warning)))) (defun proof-strict-read-only () "Set spans read-only according to variable `proof-strict-read-only'. Action is taken on all script buffers." ;; NB: read-only is synchronized in all script buffers (interactive) (proof-map-buffers (proof-buffers-in-mode proof-mode-for-script) (if (span-live-p proof-locked-span) (proof-span-read-only proof-locked-span)))) (defsubst proof-set-queue-endpoints (start end) "Set the queue span to be START, END." (span-set-endpoints proof-queue-span start end)) (defun proof-set-overlay-arrow (pos) "Set the position of the overlay marker to POS." (and (markerp proof-overlay-arrow) (set-marker proof-overlay-arrow (save-excursion (goto-char pos) (skip-chars-forward " \t\s\n") (unless (eq (point) (point-max)) (beginning-of-line) (point)))))) (defsubst proof-set-locked-endpoints (start end) "Set the locked span to be START, END." (span-set-endpoints proof-locked-span start end) (proof-set-overlay-arrow end)) (defsubst proof-detach-queue () "Remove the span for the queue region." (and proof-queue-span (span-detach proof-queue-span))) (defsubst proof-detach-locked () "Remove the span for the locked region." (and proof-locked-span (span-detach proof-locked-span)) (and (markerp proof-overlay-arrow) (set-marker proof-overlay-arrow nil))) (defsubst proof-set-queue-start (start) "Set the queue span to begin at START." (span-set-start proof-queue-span start)) (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) ;; Detach queue span, otherwise may have read-only character at end. (proof-detach-locked) (proof-set-locked-endpoints (point-min) ;; safety in case called with end>point-max (min (point-max) end)))) (defsubst proof-set-queue-end (end) "Set the queue span to end at END." (if (or (>= (point-min) end) (not (span-live-p proof-queue-span)) (<= end (span-start proof-queue-span))) (proof-detach-queue) (span-set-end proof-queue-span end))) ;; ** Initialise spans for a buffer (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 (span-make 1 1)) (span-raise proof-queue-span)) (span-set-property proof-queue-span 'start-closed t) (span-set-property proof-queue-span 'end-open t) (proof-span-read-only proof-queue-span 'always) (span-set-property proof-queue-span 'face 'proof-queue-face) (span-detach proof-queue-span) ;; Initialise locked span, remove it from buffer (unless proof-locked-span (setq proof-locked-span (span-make 1 1)) (span-raise proof-locked-span)) (span-set-property proof-locked-span 'start-closed t) (span-set-property proof-locked-span 'end-open t) (proof-span-read-only proof-locked-span) (proof-colour-locked-span) (span-detach proof-locked-span) (setq proof-overlay-arrow (make-marker)) (setq overlay-arrow-position proof-overlay-arrow) (setq proof-last-theorem-dependencies nil) (pg-clear-script-portions) (pg-clear-input-ring)) ;;;###autoload (defun proof-colour-locked () "Alter the colour of all locked regions according to variable `proof-colour-locked'." (interactive) (proof-map-buffers (proof-buffers-in-mode proof-mode-for-script) (and (span-live-p proof-locked-span) (proof-colour-locked-span)))) (defun proof-colour-locked-span () "Alter the colour of the locked region according to variable `proof-colour-locked'." (if proof-colour-locked (span-set-property proof-locked-span 'face 'proof-locked-face) (span-set-property proof-locked-span 'face nil))) (defun proof-sticky-errors () "Alter the colour of sticky errors to match `proof-sticky-errors'. This function is not yet implemented, so the colouring will stay in effect until the regions are next cleared, or only be added the next time an error is processed." ;; TODO: we need to tag spans separately as error spans, and ;; map over all spans in all buffers. ) ;; ** Restarting and clearing spans (defun proof-restart-buffers (buffers) "Remove all extents in BUFFERS and maybe reset `proof-script-buffer'. The high-level effect is that all members of BUFFERS are completely unlocked, including all the necessary cleanup. 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)) (proof-script-delete-spans (point-min) (point-max)) (proof-script-delete-secondary-spans (point-min) (point-max)) (setq pg-script-portions nil) (proof-detach-queue) (proof-detach-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-on-error (badspan &optional interruptp) "Remove the queue span from buffer, cleaning spans no longer queued. If BADSPAN is non-nil, assume that this was the span whose command caused the error. Go to the start of it if `proof-follow-mode' is 'locked. If INTERRUPTP is non-nil, do not consider BADSPAN itself as faulty. This is a subroutine used in proof-shell-handle-{error,interrupt}." (let ((start (proof-unprocessed-begin)) (end (proof-queue-or-locked-end)) (infop (span-live-p badspan))) (proof-detach-queue) (when infop (unless proof-autosend-running (when (eq proof-follow-mode 'locked) ;; jump to start of error: should this be configurable? (goto-char (span-start badspan)) (skip-chars-forward " \t\n"))) (unless interruptp (when proof-sticky-errors (pg-set-span-helphighlights badspan 'proof-script-highlight-error-face 'proof-script-sticky-error-face)))) (proof-script-delete-spans start end))) (defun proof-script-delete-spans (beg end) "Delete primary spans between BEG and END. Secondary 'pghelp spans are left." (span-delete-spans beg end 'type) (span-delete-spans beg end 'idiom)) (defun proof-script-delete-secondary-spans (beg end) "Delete secondary spans between BEG and END (currently, 'pghelp spans)." (span-delete-spans beg end 'pghelp)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Buffer position functions ;; ;;;###autoload (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-unprocessed-begin' 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 detached (and proof-queue-span (span-end proof-queue-span)) (and proof-locked-span (span-end proof-locked-span)) (point-min))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Predicates for locked region. ;; ;;;###autoload (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)))) ;;;###autoload (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 from char-after point and end of locked region. Point must be after the locked region or this will signal an error." (save-excursion (or (eq (point) (point-max)) (forward-char 1)) (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 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 called interactively or SWITCH is non-nil, switch to script buffer. If called interactively, a mark is set at the current location with `push-mark'" (interactive) (if (and proof-script-buffer (called-interactively-p 'any)) (push-mark)) (proof-with-script-buffer (if ;; there is an active scripting buffer and it's not displayed (and proof-script-buffer (not (get-buffer-window proof-script-buffer)) (or switch (called-interactively-p 'any))) ;; display it (switch-to-buffer proof-script-buffer)) (goto-char (proof-unprocessed-begin)))) ;; Careful: 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))) (unless (proof-end-of-locked-visible-p) (proof-goto-end-of-locked t)))) (defun proof-goto-end-of-locked-on-error-if-pos-not-visible-in-window () "As `proof-goto-end-of-locked-if-pos-not-visible-in-window', but not for interrupts. Intended as a hook function for `proof-shell-handle-error-or-interrupt-hook'." (interactive) (unless (eq proof-follow-mode 'ignore) (if (eq proof-shell-last-output-kind 'error) (proof-goto-end-of-locked-if-pos-not-visible-in-window))) (proof-with-current-buffer-if-exists proof-script-buffer (unless (proof-end-of-locked-visible-p) (pg-jump-to-end-hint)))) (defun proof-end-of-locked-visible-p () "Return non-nil if end of locked region is visible." (let* ((pos (proof-with-current-buffer-if-exists proof-script-buffer (proof-unprocessed-begin))) (win (and pos (get-buffer-window proof-script-buffer t)))) (and win (pos-visible-in-window-p pos)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Names of proofs (and other parts) in a script. ;; ;; Elements are represented as spans (overlays). ;; ;; Each kind of part ("idiom") in a proof script has its own name ;; space. Idioms are named with symbols. ;; (defconst pg-idioms '(proof) "List of script element kinds PG is aware of for this prover.") (defconst pg-all-idioms (append pg-idioms '(comment command other)) "List of all possible script element kinds.") (defun pg-clear-script-portions () "Clear record of script portion names and types from internal list." (dolist (idtbl pg-script-portions) (maphash (lambda (k span) (span-delete span)) (cdr idtbl)) (clrhash (cdr idtbl)))) (defun pg-remove-element (idiom id) "Remove the identifier ID from the script portion IDIOM." (let* ((elts (cdr-safe (assq idiom pg-script-portions))) (span (and elts (gethash idiom elts)))) (when span (span-detach span) ;; delete overlay, without pre-del fn (remhash id elts)))) (defun pg-get-element (idiomsym id) "Return proof script element of type IDIOM identifier ID. IDIOM is a symbol, ID is a string." (assert (symbolp idiomsym)) (assert (stringp id)) (let ((idsym (intern id)) (elts (cdr-safe (assq idiomsym pg-script-portions)))) (if elts (gethash idsym elts)))) (defun pg-add-element (idiomsym id span &optional name) "Add element of type IDIOMSYM with identifier ID, referred to by SPAN. This records the element in `pg-script-portions' and sets span properties accordingly. IDIOMSYM is a symbol, whereas ID and optional NAME are strings. Identifiers must be unique for a given idiom; the optional NAME will be recorded as a textual name used instead of ID for users; NAME does not need to be unique. NAME is a name that comes from the proof script or prover output. It is recorded in the span with the 'rawname property." (assert (symbolp idiomsym)) (assert (stringp id)) (if name (assert (stringp name))) (let* ((idsym (intern id)) (rawname name) (name (or name id)) (idiom (symbol-name idiomsym)) (delfn `(lambda () (pg-remove-element (quote ,idiomsym) (quote ,idsym)))) (elts (cdr-safe (assq idiomsym pg-script-portions)))) (unless elts (setq pg-script-portions (cons (cons idiomsym (setq elts (make-hash-table))) pg-script-portions))) (if (gethash idsym elts) (proof-debug "Element named %s (type %s) was already in buffer." name idiom)) (puthash idsym span elts) ;; Idiom and ID are stored in the span as symbols; name as a string. (span-set-property span 'idiom idiomsym) (span-set-property span 'id idsym) (span-set-property span 'name name) (span-set-property span 'rawname rawname) (span-add-delete-action span delfn) ;; Ideally: would keep invisible property to be the idiom type ;; (span-set-property span 'invisible idiom) ;; BUT: problems overlapping invisible regions with ;; Unicode Tokens (crucial for hiding control sequences). ;; Nice behaviour in with isearch: open invisible regions temporarily. (span-set-property span 'isearch-open-invisible 'pg-open-invisible-span) (span-set-property span 'isearch-open-invisible-temporary 'pg-open-invisible-span))) (defun pg-invisible-prop (idiom) "Return an invisibility symbol for the given IDIOM. This is a value for the overlay 'invisible property." (intern (concat "pg-" (symbol-name (or idiom 'other))))) (defun pg-set-element-span-invisible (span invisiblep) "Function to adjust visibility of span to INVISIBLEP. We use list values of the 'invisible property which contain private symbols, that should play well with other conforming modes and `buffer-invisibility-spec'." (let* ((invisible-prop (pg-invisible-prop (span-property span 'idiom))) (invisible-rest (remq invisible-prop (span-property span 'invisible)))) (span-set-property span 'invisible (if invisiblep (cons invisible-prop invisible-rest) invisible-rest)))) (defun pg-toggle-element-span-visibility (span) "Toggle visibility of SPAN." (pg-set-element-span-invisible span (not (span-property span 'invisible)))) (defun pg-open-invisible-span (span &optional invisible) "Function for `isearch-open-invisible' property." ;; alias (pg-set-element-span-invisible span invisible)) (defun pg-make-element-invisible (idiomsym id) "Make element ID of type IDIOMSYM invisible, with ellipsis." (let ((span (pg-get-element idiomsym id))) (if span (pg-set-element-span-invisible span t)))) (defun pg-make-element-visible (idiomsym id) "Make element ID of type IDIOMSYM visible." (let ((span (pg-get-element idiomsym id))) (if span (pg-set-element-span-invisible span nil)))) (defun pg-toggle-element-visibility (idiomsym id) "Toggle visibility of script element of type IDIOMSYM, named ID. IDIOMSYM is a symbol and ID is a strings." (let ((span (pg-get-element idiomsym id))) (if span (pg-toggle-element-span-visibility span)))) (defun pg-show-all-portions (idiom &optional hide) "Show or conceal portions of kind IDIOM; if HIDE is non-nil, conceal." (interactive (list (intern (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 idiom pg-script-portions))) (alterfn (if hide (lambda (k span) (pg-set-element-span-invisible span t)) (lambda (k span) (pg-set-element-span-invisible span nil))))) (when elts (proof-with-script-buffer ; may be called from menu (maphash alterfn elts))))) ;; Next two could be in pg-user.el. No key-bindings for these. (defun pg-show-all-proofs () "Display all completed proofs in the buffer." (interactive) (pg-show-all-portions "proof")) (defun pg-hide-all-proofs () "Hide all completed proofs in the buffer." (interactive) (pg-show-all-portions "proof" 'hide)) (defun pg-add-proof-element (name span controlspan) "Add a span proof element to SPAN with name NAME and parent CONTROLSPAN." (let ((proofid (proof-next-element-id 'proof))) (pg-add-element 'proof proofid span name) ;; Set id in controlspan [NB: intern here means symbol-name elsewhere] (span-set-property controlspan 'id (intern proofid)) ;; Make a navigable link between the two spans. (span-set-property span 'controlspan controlspan) (span-set-property controlspan 'children (cons span (span-property controlspan 'children))) (pg-set-span-helphighlights span proof-region-mouse-highlight-face) (span-set-property span 'priority 10) ; lower than default (if proof-disappearing-proofs (pg-make-element-invisible 'proof proofid)))) (defun pg-span-name (span) "Return a user-level name for SPAN. This is based on its name and type. Each 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 " (let ((type (span-property span 'type)) (idiom (span-property span 'idiom)) (name (span-property span 'name)) (rawname (span-property span 'rawname))) (cond (idiom (concat (upcase-initials (symbol-name idiom)) ;; only use rawnames, not internally generated ones (if (and rawname (not (equal rawname proof-unnamed-theorem-name))) (concat " [" rawname "]")))) ((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")))) (defvar pg-span-context-menu-keymap (let ((map (make-sparse-keymap "Keymap for context-sensitive menus on spans"))) (define-key map [down-mouse-3] 'pg-span-context-menu) map) "Keymap for the span context menu.") (defun pg-last-output-displayform () "Return displayable form of `proof-shell-last-output'. This is used to annotate the buffer with the result of proof steps." ;; NOTE: Isabelle/Isar uses urgent messages (sigh) in its ordinary output. ;; ("Successful attempt..."). This loses here. (if (string= proof-shell-last-output "") "" (let* ((text (proof-shell-strip-output-markup (if (and (boundp 'unicode-tokens-mode) unicode-tokens-mode) (unicode-tokens-encode-str proof-shell-last-output) proof-shell-last-output)))) ;; HACK: for Isabelle which puts ugly leading \n's around proofstate. (if (and (> (length text) 0) (string= (substring text 0 1) "\n")) (setq text (substring text 1))) (if (and (> (length text) 0) (string= (substring text -1) "\n")) (setq text (substring text 0 -1))) text))) ;;;###autoload (defun pg-set-span-helphighlights (span &optional mouseface face) "Add a daughter help span for SPAN with help message, highlight, actions. The daughter span covers the non whitespace content of the main span. We add the last output (when non-empty) to the hover display, and also as the 'response property on the span. Optional argument MOUSEFACE means use the given face as a mouse highlight face, if it is a face, otherwise, if it is non-nil but not a face, do not add a mouse highlight. In any case, a mouse highlight and tooltip are only set if `proof-output-tooltips' is non-nil. Argument FACE means add 'face property FACE to the span." (let* ((output (pg-last-output-displayform)) (newstart (save-excursion (goto-char (span-start span)) (skip-chars-forward " \n\t") (point))) (newend (save-excursion (goto-char (span-end span)) (skip-chars-backward " \n\t") (point))) (newspan (span-make-modifying-removing-span newstart newend))) (span-set-property span 'pg-helpspan newspan) ; link from parent (span-set-property newspan 'pghelp t) (span-set-property newspan 'response output) (when proof-output-tooltips (span-set-property newspan 'help-echo (if (<= (length output) 2) (pg-span-name span) output))) ;; Here's the message we used to show in minibuffer ;; when pg-show-hints was on: ;; ;; " (" ;; (substitute-command-keys ;; (if (span-property span 'idiom) ;; "with point in region, \\[pg-toggle-visibility] to show/hide; " ;; "\\\\[pg-span-context-menu]")) ;; " for menu)"))) (span-set-property newspan 'keymap pg-span-context-menu-keymap) (if (or (facep mouseface) (setq mouseface (unless mouseface 'proof-mouse-highlight-face))) (when proof-output-tooltips (span-set-property newspan 'mouse-face mouseface))) (if face (span-set-property newspan 'face face)) (span-set-property newspan 'priority 50))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Multiple file handling ;; (defun proof-complete-buffer-atomic (buffer) "Ensure BUFFER marked completely processed, completing with a single step. If buffer already contains a locked region, only the remainder of the buffer is closed off atomically (although undo for the initial portion is unlikely to work, the decoration may be worth retaining). 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." (with-current-buffer buffer (save-excursion ;; prevent point moving if user viewing file (if (< (proof-unprocessed-begin) (proof-script-end)) (let ((span (span-make (proof-unprocessed-begin) (proof-script-end)))) ;; Reset queue and locked regions. (proof-init-segmentation) ;; End of locked region is always end of buffer (proof-set-locked-end (proof-script-end)) ;; Configure the overlay span (span-set-property span 'type 'proverproc) (pg-set-span-helphighlights span 'nohighlight)))))) ;; Note: desirable to clean 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. ;;;###autoload (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 (find-buffer-visiting 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) (pg-response-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 (if (and proof-query-file-save-when-activating-scripting (not noquestions)) (unwind-protect (save-some-buffers nil #'proof-query-save-this-buffer-p))) ;; Tell the prover (proof-shell-invisible-command (proof-format-filename proof-shell-inform-file-processed-cmd cfile) 'wait)))))) (defun proof-query-save-this-buffer-p () "Predicate testing whether `save-some-buffers' during scripting should query." (and (eq major-mode proof-mode-for-script) (not (eq (current-buffer) proof-script-buffer)))) (defun proof-inform-prover-file-retracted (rfile) "Send a message to the prover to tell it RFILE has been undone." (cond ((stringp proof-shell-inform-file-retracted-cmd) (proof-shell-invisible-command (proof-format-filename proof-shell-inform-file-retracted-cmd rfile) 'wait)) ;; If it's a function it might not actually be informing the prover at all, ;; but merely cleans up proof-included-files-list by its own magic. We ;; do the same thing as in proof-shell.el. ;; FIXME: clean and amalgamate this code. ((functionp proof-shell-inform-file-retracted-cmd) (let ((current-included proof-included-files-list)) (funcall proof-shell-inform-file-retracted-cmd rfile) (proof-restart-buffers (proof-files-to-buffers (set-difference current-included proof-included-files-list))))))) (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 (find-buffer-visiting 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 (pg-response-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)) ;; If we're not allowed to undo into a processed ;; file, we had better remove all the history. (if proof-cannot-reopen-processed-files (proof-restart-buffers (list (current-buffer)))) ;; 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 ;; ;; The notion of "active scripting buffer" clarifies how ;; scripting across multiple files is handled. Only one ;; script buffer is allowed to be active, and actions are ;; taken when scripting is turned off/on. ;; (defsubst proof-action-completed (action) (or (and (eq action 'retract) (proof-locked-region-empty-p)) (and (eq action 'process) (proof-locked-region-full-p)))) (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." (unless (or (eq action 'process) (eq action 'retract)) (error "proof-protected-process-or-retract: invalid argument")) (let ((buf (or buffer (current-buffer)))) (with-current-buffer buf (unless (proof-action-completed action) (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")))) (unwind-protect (progn (message "%s buffer %s..." name buf) (funcall fn) (proof-shell-wait) ; busy wait (message "%s buffer %s...done." name buf) (sit-for 0)) ;; Test to see if action was successful (unless (proof-action-completed action) (error "%s of %s failed!" name buf)))))))) (defun proof-deactivate-scripting-auto () "Deactivate scripting without asking questions or raising errors. If the locked region is full, register the file as processed. Otherwise retract it. Errors are ignored" (ignore-errors (proof-deactivate-scripting (proof-with-script-buffer (if (proof-locked-region-full-p) 'process 'retract))))) (defun proof-deactivate-scripting-query-user-action () "Display the script and query the user for a deactivate action. Returns 'retract, 'process or finally nil if user declined." ;; 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. (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))) (unless (one-window-p) (delete-other-windows)) (switch-to-buffer proof-script-buffer t)) (let ((action (cond ((y-or-n-p (format "Scripting incomplete in buffer %s, retract? " proof-script-buffer)) 'retract) ((and (not proof-no-fully-processed-buffer) (y-or-n-p (format "Completely process buffer %s instead? " proof-script-buffer))) 'process)))) (or action (progn ;; 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))))) (defun proof-deactivate-scripting-choose-action () "Select a deactivation action, 'process, 'retract or nil." (let ((auto-action (if (and proof-no-fully-processed-buffer (eq proof-auto-action-when-deactivating-scripting 'process)) nil proof-auto-action-when-deactivating-scripting))) (or auto-action (proof-deactivate-scripting-query-user-action)))) (defun proof-deactivate-scripting (&optional forcedaction) "Try to deactivate scripting for the active scripting buffer. Aims to set `proof-script-buffer' to nil and turn off the modeline indicator. No action is required 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 `proof-no-fully-processed-buffer' is t there is only the choice to fully retract the active scripting buffer. In this case the active scripting buffer is retracted even if it was fully processed. Setting `proof-auto-action-when-deactivating-scripting' to 'process is ignored in this case. 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) (proof-with-current-buffer-if-exists 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.) (let* ((complete (or (proof-locked-region-empty-p) (and (not proof-no-fully-processed-buffer) (proof-locked-region-full-p)))) (action (unless complete (or forcedaction (proof-deactivate-scripting-choose-action))))) (if action (proof-protected-process-or-retract action)) (unless (and (not complete) (not action)) ;; If we get here, then the locked region is (now) either ;; completely empty or completely full. ;; 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) (force-mode-line-update) ;; Finally, run hooks (run-hooks 'proof-deactivate-scripting-hook))))) (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 is 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) (unless (eq proof-buffer-type 'script) (error "Must be running in a script buffer!")) (unless (equal (current-buffer) proof-script-buffer) ;; TODO: narrow the scope of this save-excursion. ;; Where is it needed? Maybe hook functions. (save-excursion ;; If there's another buffer currently active, we need to ;; deactivate it (also fixing up the included files list). (when proof-script-buffer (proof-deactivate-scripting) ;; Test whether deactivation worked (if proof-script-buffer (error "You cannot have more than one active scripting buffer!"))) ;; Ensure this buffer is off the included files list. If we ;; re-activate scripting in an already completed buffer, the ;; proof assistant may need to retract some 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.") ;; Fire up the prover (or check it's going the right way). (proof-shell-ready-prover queuemode) ;; Set the active scripting buffer, and initialise regions (setq proof-script-buffer (current-buffer)) (if (proof-locked-region-empty-p) ; leave alone if non-empty (proof-init-segmentation)) ;; Turn on the minor mode, make it show up. (setq proof-active-buffer-fake-minor-mode t) (force-mode-line-update) ;; A good time to ask if the user wants to save some buffers ;; (idea being they may be included in imports at top of new buffer). (if (and proof-query-file-save-when-activating-scripting (not nosaves)) (save-some-buffers nil #'proof-query-save-this-buffer-p)) ;; 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 (called-interactively-p 'any))) (setq proof-shell-last-output-kind nil) (run-hooks 'proof-activate-scripting-hook) ;; If activate scripting functions caused an error, ;; prevent switching to another buffer. Might be better ;; to leave to specific instances, or simply run the hooks ;; as the last step before turning on scripting properly. (when (or (eq 'error proof-shell-last-output-kind) (eq 'interrupt proof-shell-last-output-kind)) (proof-deactivate-scripting) ;; turn off again! ;; Give an error to prevent further actions. (error "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") (if (if (null arg) (not (eq proof-script-buffer (current-buffer))) (> (prefix-numeric-value arg) 0)) (progn (if proof-script-buffer ;; deactivate elsewhere first (call-interactively 'proof-deactivate-scripting)) (call-interactively 'proof-activate-scripting)) (call-interactively 'proof-deactivate-scripting))) ;; ;; End of activating and deactivating scripting section ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Processing the script management queue -- PART 1: "advancing" ;; ;; The 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, it is classified as ;; 'comment, 'goalsave, 'vanilla, etc. ;; ;; The main function for dealing with processed spans is ;; `proof-done-advancing' (defun proof-done-advancing (span) "The callback function for `assert-until-point'. Argument SPAN has just been processed." (let ((end (span-end span)) (cmd (span-property span 'cmd))) (proof-set-locked-end end) (if (span-live-p proof-queue-span) (proof-set-queue-start end)) (cond ;; CASE 1: Comments just get highlighted ((eq (span-property span 'type) 'comment) (proof-done-advancing-comment span)) ;; CASE 2: Save command seen, now we may amalgamate spans. ((and (proof-string-match-safe proof-save-command-regexp cmd) (funcall proof-really-save-command-p span cmd) (decf proof-nesting-depth) ;; [always non-nil/true] (if proof-nested-goals-history-p ;; For now, we only support this nesting behaviour: ;; don't amalgamate unless the nesting depth is 0, ;; i.e. we're in a top-level proof. ;; This assumes prover keeps history for nested proofs. ;; (True for Isabelle/Isar). (eq proof-nesting-depth 0) t)) (proof-done-advancing-save span)) ;; 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 allows 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. ((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 span)))) (proof-done-advancing-autosave span)) ;; CASE 4: A "Require" type of command is seen (Coq). ;; Case 4 has been flushed, because its functionality has been ;; superseeded by the new auto-compilation feature for Coq. ;; CASE 5: Some other kind of command (or a nested goal). (t (proof-done-advancing-other span))) ;; Add the processed command to the input ring (unless (or (not (span-live-p span)) (eq (span-property span 'type) 'comment)) (pg-add-to-input-history cmd))) ;; Finally: state of scripting may have changed now, run hooks. (run-hooks 'proof-state-change-hook)) (defun proof-done-advancing-comment (span) "A subroutine of `proof-done-advancing'. Add comment element for SPAN." ;; Add an element for a new span, which should span ;; the text of the comment. ;; FIXME: might be better to use regexps/skip spaces for matching ;; start/end of comments, rather than comment-start and ;; comment-end skip (which assumes comments are nicely formatted). ;; (let ((bodyspan (span-make (+ (length comment-start) (span-start span)) (- (span-end span) (max 1 (length comment-end))))) (id (proof-next-element-id 'comment)) str) (pg-add-element 'comment id bodyspan) (span-set-property span 'id (intern id)) (span-set-property span 'idiom 'comment) (let ((proof-shell-last-output "")) ; comments not sent, no last output (pg-set-span-helphighlights bodyspan)) ;; possibly evaluate some arbitrary Elisp. SECURITY RISK! (save-match-data (setq str (buffer-substring-no-properties (span-start span) (span-end span))) (if (proof-string-match-safe proof-script-evaluate-elisp-comment-regexp str) (condition-case nil (eval (car (read-from-string (match-string-no-properties 1 str)))) (t (proof-debug (concat "lisp error when obeying proof-shell-evaluate-elisp-comment-regexp: \n" (prin1-to-string (match-string-no-properties 1)) "\n")))))))) (defun proof-done-advancing-save (span) "A subroutine of `proof-done-advancing'. Add info for save span SPAN." (unless (or (eq proof-shell-proof-completed 1) (eq proof-assistant-symbol 'isar)) ;; We expect saves to succeed only for recently completed top-level proofs. ;; NB: not true in Isar, because save commands can perform proof. (proof-debug (format "PG: save command with proof-shell-proof-completed=%s, proof-nesting-depth=%s" proof-shell-proof-completed proof-nesting-depth))) (setq proof-shell-proof-completed nil) ;; FIXME: need subroutine here: (let ((gspan span) ; putative goal span (savestart (span-start span)) (saveend (span-end span)) (cmd (span-property span 'cmd)) lev nestedundos nam next) (and proof-save-with-hole-regexp (proof-string-match proof-save-with-hole-regexp cmd) ;; Give a message of a name if one can be determined (proof-minibuffer-message (format "proved %s" (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)))))) ;; Search back for a goal command, deleting spans along the way: ;; they may be amalgamated into a single goal-save region, which ;; corresponds to the prover discarding the proof history. (setq lev 1) (setq nestedundos 0) (while (and gspan (> lev 0)) (setq next (prev-span gspan 'type)) (unless proof-arbitrary-undo-positions (span-delete gspan)) (setq gspan next) (if gspan (progn (setq cmd (span-property gspan 'cmd)) (cond ;; Ignore comments [may have null cmd setting] ((eq (span-property gspan 'type) 'comment)) ;; Nested goal saves: add in any nestedcmds ((eq (span-property gspan 'type) 'goalsave) (setq nestedundos (+ nestedundos 1 (or (span-property gspan 'nestedundos) 0)))) ;; Increment depth for a nested save, in case ;; prover supports history of nested proofs ((and proof-nested-goals-history-p proof-save-command-regexp (proof-string-match proof-save-command-regexp cmd)) (incf lev)) ;; Decrement depth when a goal is hit ((funcall proof-goal-command-p gspan) (decf lev)) ;; Remainder cases: see if command matches something we ;; should count for a global undo ((and proof-nested-undo-regexp (proof-string-match proof-nested-undo-regexp cmd)) (incf nestedundos)) )))) (if (not gspan) ;; No goal span found! Issue a warning and do nothing more. (pg-response-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, or as a ;; final desparate attempt, set the name to ;; proof-unnamed-theorem-name (Coq uses a default name for ;; unnamed theorems, believe it or not, and issues a ;; name-binding error for two unnamed theorems in a row!). (setq nam (or nam (proof-get-name-from-goal gspan) proof-unnamed-theorem-name)) (proof-make-goalsave gspan (span-end gspan) savestart saveend nam nestedundos) ;; *** Theorem dependencies *** (if proof-last-theorem-dependencies (proof-depends-process-dependencies nam gspan))))) (defun proof-make-goalsave (gspan goalend savestart saveend nam &optional nestedundos) "Make new goal-save span, using GSPAN. Subroutine of `proof-done-advancing-save'. Argument GOALEND is the end of the goal;." (unless proof-arbitrary-undo-positions (span-set-end gspan saveend) (span-set-property gspan 'type 'goalsave)) (span-set-property gspan 'idiom 'proof);; links to nested proof element (span-set-property gspan 'name nam) (and nestedundos (span-set-property gspan 'nestedundos nestedundos)) (pg-set-span-helphighlights gspan proof-region-mouse-highlight-face) ;; Now make a nested span covering the purported body of the proof, ;; and add to buffer-local list of elements. (let ((proofbodyspan (span-make goalend (if proof-script-integral-proofs saveend savestart)))) (pg-add-proof-element nam proofbodyspan gspan))) (defun proof-get-name-from-goal (gspan) "Try to return a goal name from GSPAN. Subroutine of `proof-done-advancing-save'." (let ((cmdstr (span-property gspan 'cmd))) (and proof-goal-with-hole-regexp (proof-string-match proof-goal-with-hole-regexp cmdstr) (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))))) ;; FIXME: this next function should be more like proof-done-advancing-save, ;; perhaps simplifying the proof-completed-proof-behaviour functionality, ;; which isn't seriously used in any prover. At the moment the behaviour ;; here is incomplete compared with proof-done-advancing-save. ;; NB: in this function we assume non-nested proofs, which explains ;; some of the logic. There is no attempt to fix up proof-nesting-depth. ;; NB: 'extend behaviour is not currently compatible with appearance of ;; save commands, since proof-done-advancing-save allow for goalspan ;; already existing. (defun proof-done-advancing-autosave (span) "A subroutine of `proof-done-advancing'." ;; In the extend case, the context of proof grows until hit a save ;; or new goal. (if (eq proof-completed-proof-behaviour 'extend) (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))) (cmd (span-property span 'cmd)) (newgoal (funcall proof-goal-command-p 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. ;; FIXME: this should really do the work done in ;; proof-done-advancing-save above, too, with nested undos, etc. (while ;; big ugly condition (and gspan (or (eq (span-property gspan 'type) 'comment) (and (setq ncmd (span-property gspan 'cmd)) (setq cmd ncmd) ; dynamic scope for funcall below (not (funcall proof-goal-command-p gspan)) (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))) (cond ((or hitsave (null gspan)) (proof-debug "Proof General strangeness: unclosed proof completed, but couldn't find its start!") (pg-set-span-helphighlights span)) ((and swallow newgoal) ;; If extending the region, goalsave already there; just highlight new region (setq proof-shell-proof-completed nil) (pg-set-span-helphighlights span)) (t ;; If, search back through spans, 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 (mapc 'span-delete dels) ;; Try to set the name from the goal... [as above] (setq nam (or (proof-get-name-from-goal gspan) proof-unnamed-theorem-name)) ;; NB: if extending an already closed region, ought to delete ;; the body and extend that too: currently we make multiple nested ;; bodies, a bit messy. ;; (NB: savestart used for nested region: here use saveend) (proof-make-goalsave gspan (+ (span-start gspan) (length (or (span-property-safe gspan 'cmd)))) newend newend nam))))) (defun proof-done-advancing-other (span) (let ((bodyspan span) ;; might take subscript after first word/line (id (proof-next-element-id 'command))) ;; Hidable regions for commands: the problem is that they have no ;; natural surrounding region, so makes it difficult to define a ;; region for revealing again. (cond ((funcall proof-goal-command-p span) (pg-add-element 'statement id bodyspan) (incf proof-nesting-depth)) (t (pg-add-element 'command id bodyspan))) (if proof-shell-proof-completed (incf proof-shell-proof-completed)) (pg-set-span-helphighlights span proof-command-mouse-highlight-face))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Parsing functions for parsing commands in script ;; ;; Command parsing is suprisingly subtle with various possibilities of ;; command syntax (terminated, not terminated, or lisp-style), whether ;; or not PG silently ignores comments, etc. (defun proof-segment-up-to-parser (pos &optional next-command-end) "Parse the script buffer from end of queue/locked region to POS. This partitions the script buffer into contiguous regions, classifying them by type. Return a list of lists of the form (TYPE TEXT ENDPOS) where: TYPE is a symbol indicating the type of text found, either 'cmd or 'comment; TEXT is the string content taken from the buffer; ENDPOS is the position of the final character of the text. 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-no-properties 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. (setq segs (cons seg (if (and proof-script-fly-past-comments (eq type 'comment) (eq prevtype 'comment)) (cdr segs) segs))) ;; Update state (setq cur (point)) (setq prevtype type))))) ;; Return segment list segs))) ;;;###autoload (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-script-comment-end-regexp nil 'movetolimit)) (setq notout (proof-buffer-syntactic-context))) (not (proof-buffer-syntactic-context)))) (defun proof-script-generic-parse-cmdend () "For `proof-script-parse-function' if `proof-script-command-end-regexp' set." (if (looking-at proof-script-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 (progn (and (re-search-forward proof-script-command-end-regexp nil t) (or (match-beginning 1) ;; optional start of white space (match-end 0))))) (proof-buffer-syntactic-context)) ;; inside a string or comment before the command end ) (if (and foundend (goto-char foundend) ; move to command end (not (proof-buffer-syntactic-context))) ;; Found command end outside string/comment 'cmd ;; Didn't find command end nil)))) ;; This was added for the fine-grained command structure of Isar ;; ;; It more involved than the case of just scanning for 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). It's needed particularly for Isar's text command (text ;; {* foo *}) so we can define the buffer syntax for text as comment. ;; ;; 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. ;; ;; NB: proof-script-comment-start-regexp doesn't need to be the same ;; as (reqexp-quote comment-start). ;; (defun proof-script-generic-parse-cmdstart () "For `proof-script-parse-function' if `proof-script-command-start-regexp' is set." (let ((case-fold-search proof-case-fold-search)) (if (looking-at proof-script-comment-start-regexp) ;; Find end of comment (if (proof-script-generic-parse-find-comment-end) 'comment) ;; Handle non-comments: assumed to be commands (when (looking-at proof-script-command-start-regexp) ;; We've got at least the beginnings of a command, skip past it (goto-char (match-end 0)) (let (foundstart) ;; Find next command start (while (and (setq foundstart (and (re-search-forward proof-script-command-start-regexp nil 'movetolimit) (and (match-beginning 0) ;; jiggery pokery here is to move outside a ;; comment in case a comment start is considered to ;; be a command start (for non fly-past behaviour) (goto-char (match-beginning 0))))) (proof-buffer-syntactic-context) (goto-char (1+ (point)))) ;; loop while in a string/comment before the next command start ) (unless (proof-buffer-syntactic-context) ; not inside a comment/string (cond (foundstart ; found a second command start (goto-char foundstart) ; beginning of command start (skip-chars-backward " \t\n") ; end of previous command 'cmd) ((eq (point) (point-max)) ; At the end of the buffer (skip-chars-backward " \t\n") ; benefit of the doubt, let 'cmd))) ; the PA moan if it's incomplete ;; Return nil otherwise, 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-script-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))))) (defun proof-semis-to-vanillas (semis &optional queueflags) "Create vanilla spans for SEMIS and a list for the queue. Proof terminator positions SEMIS has the form returned by the function `proof-segment-up-to'. The argument list is destroyed. The callback in each queue element is `proof-done-advancing'. If the variable `proof-script-preprocess' is set (to the name of a function), call that function to construct the first element of each queue item. The optional QUEUEFLAGS are added to each queue item." (let ((start (proof-queue-or-locked-end)) (file (or (buffer-file-name) (buffer-name))) (cb 'proof-done-advancing) span alist semi item end) (setq semis (nreverse semis)) (save-match-data (dolist (semi semis) (setq end (nth 2 semi)) (setq span (span-make start end)) (if (eq (car semi) 'cmd) (progn ;; command span (let* ((cmd (nth 1 semi)) (qcmd (if proof-script-preprocess (funcall proof-script-preprocess file ;; ignore spaces at start of command (+ start (save-excursion (goto-char start) (skip-chars-forward " \t\n"))) end cmd) (list cmd))) (qitem (list span qcmd cb queueflags))) (span-set-property span 'type 'vanilla) (span-set-property span 'cmd cmd) (setq alist (cons qitem alist)))) ;; ignored text (let ((qitem (list span nil cb queueflags))) ; nil was `proof-no-command' (span-set-property span 'type 'comment) (setq alist (cons qitem alist)))) (setq start end))) (nreverse alist))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Moving point in proof script buffer ;; (defun proof-next-command-new-line () "Return non-nil if next command should start a new line." (or proof-next-command-on-new-line ; pg-vars (with-no-warnings (proof-ass one-command-per-line)))) (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-chars-forward " \t") (if (and (eolp) (proof-next-command-new-line)) (forward-line))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Assert-until-point. ;; ;; This function parses some region of the script buffer into ;; commands, and the adds the commands into the queue. ;; (defun proof-assert-until-point (&optional displayflags) "Process the region from the end of the locked-region until point." (if (proof-only-whitespace-to-locked-region-p) (error "At end of the locked region, nothing to do to!")) (proof-activate-scripting nil 'advancing) (let ((semis (save-excursion (skip-chars-backward " \t\n" (proof-queue-or-locked-end)) (proof-segment-up-to-using-cache (point))))) (if (eq 'unclosed-comment (car semis)) (setq semis (cdr semis))) (if (null semis) ; maybe inside a string or something. (error "I can't find any complete commands to process!")) (proof-assert-semis semis displayflags))) (defun proof-assert-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)) (termregexp (regexp-quote proof-terminal-string)) ins incomment nwsp) (if (< mrk (proof-unprocessed-begin)) (insert proof-terminal-string) ; insert immediately in locked region (if (proof-only-whitespace-to-locked-region-p) (error "There's nothing to do!")) (skip-chars-backward " \t\n") (setq nwsp (point)) ; char after first non-whitespace (unless (or proof-electric-terminator-noterminator ;; before the terminal (looking-at termregexp) ;; after the terminal (and (re-search-backward termregexp (proof-unprocessed-begin) t) (goto-char nwsp) (eq (match-end 0) nwsp))) (insert proof-terminal-string) (setq ins t)) (proof-activate-scripting nil 'advancing) (let* ((pos (if proof-electric-terminator-noterminator (1- (point)) (point))) (semis (save-excursion (proof-segment-up-to-using-cache pos)))) (unless semis (error "Can't find a parseable command!")) (when (eq 'unclosed-comment (caar semis)) (setq incomment t) ;; delete spurious char in comment (if ins (backward-delete-char 1)) (goto-char mrk) (insert proof-terminal-string)) ;; assert the region (proof-assert-semis semis) (proof-script-next-command-advance))))) (defun proof-assert-semis (semis &optional displayflags) "Add to the command queue the list SEMIS of command positions. SEMIS must be a non-empty list, in reverse order (last position first). We assume that the list is contiguous and begins at (proof-queue-or-locked-end). We also delete help spans which appear in the same region (in the expectation that these may be overwritten). This function expects the buffer to be activated for advancing." (assert semis nil "proof-assert-semis: argument must be a list") (let ((startpos (proof-queue-or-locked-end)) (lastpos (nth 2 (car semis))) (vanillas (proof-semis-to-vanillas semis displayflags))) (proof-script-delete-secondary-spans startpos lastpos) (proof-extend-queue lastpos vanillas))) (defun proof-retract-before-change (beg end) "For `before-change-functions'. Retract to BEG unless BEG and END in comment. No effect if prover is busy." (when (and (> (proof-queue-or-locked-end) beg) (not (and (proof-inside-comment beg) (proof-inside-comment end)))) (when proof-shell-busy (message "Interrupting prover") (proof-interrupt-process) (proof-shell-wait)) (save-excursion (save-restriction ;; see Trac#403 (widen) (goto-char beg) (proof-retract-until-point) (proof-shell-wait))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PBP call-backs ;; ;;;###autoload (defun proof-insert-pbp-command (cmd) "Insert CMD into the proof queue." (proof-activate-scripting) (let (span) (proof-goto-end-of-locked) (if (proof-next-command-new-line) (insert "\n")) (insert cmd) (setq span (span-make (proof-unprocessed-begin) (point))) (span-set-property span 'type 'pbp) (span-set-property span 'cmd cmd) (proof-start-queue (proof-unprocessed-begin) (point) (list (list span (list cmd) 'proof-done-advancing))))) ;;;###autoload (defun proof-insert-sendback-command (cmd) "Insert CMD into the proof script, execute assert-until-point." (proof-with-script-buffer (proof-goto-end-of-locked) (insert "\n") ;; could be user opt (insert cmd) (proof-assert-until-point))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Processing the script management queue -- PART 2: retracting ;; ;; Most of the hard work (computing the commands to do the retraction) ;; is implemented in the customisation module (lego.el or coq.el), so ;; code here is fairly straightforward. ;; TODO: we need to adjust proof-nesting-depth appropriately here. ;; It would help to know the type of retraction which has just ;; occurred: a kill-proof may be assumed to set nesting depth ;; to zero; an undo sequence may alter it some other way. ;; NB: at the moment, the adjustment is made in the wrong place!! (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)." ;; TODO: need to fixup proof-nesting-depth (setq proof-shell-proof-completed nil) (if (span-live-p span) (let ((start (span-start span)) (end (span-end span)) (killfn (span-property span 'remove-action))) ;; da: check for empty region seems odd here? ;; [prevents regions from being detached in set-locked-end] (unless (proof-locked-region-empty-p) (proof-set-locked-end start) (proof-set-queue-end start)) ;; Try to clean input history (NB: rely on order here) ;; PG 3.7 release: disable this, it's not yet robust. ;; (let ((cmds (spans-at-region-prop start end 'cmd)) ;; (fn (lambda (span) ;; (unless (eq (span-property span 'type) 'comment) ;; (pg-remove-from-input-history ;; (span-property span 'cmd)))))) ;; (mapc fn (reverse cmds))) (proof-script-delete-spans start end) (span-delete span) (if killfn (funcall killfn start end)))) ;; State of scripting may have changed now (run-hooks 'proof-state-change-hook)) (defun proof-setup-retract-action (start end proof-commands remove-action &optional displayflags) "Make span from START to END which corresponds to retraction. Returns retraction action destined for proof shell queue, and make span. Action holds PROOF-COMMANDS and `proof-done-retracting' callback. Span deletion property set to function REMOVE-ACTION. DISPLAYFLAGS control output shown to user, see `proof-action-list'." (let ((span (span-make start end))) (span-set-property span 'remove-action remove-action) (list (list span proof-commands 'proof-done-retracting displayflags)))) (defun proof-last-goal-or-goalsave () "Return the span which is the last goal or save before point." (save-excursion (let ((span (span-at-before (proof-unprocessed-begin) 'type))) (while (and span (not (eq (span-property span 'type) 'goalsave)) (or (eq (span-property span 'type) 'proof) (eq (span-property span 'type) 'comment) (eq (span-property span 'type) 'proverproc) (not (funcall proof-goal-command-p span)))) (setq span (prev-span span 'type))) span))) ;; ;; NB: Should carefully explain/document this behaviour somewhere. ;; The undo is three-phase: ;; undo-cmd - ... - undo-cmd within proof ;; kill proof exit proof ;; forget-to-declaration forget target span ;; ;; It turns out that this behaviour is not quite right for Coq. ;; It might be simpler to just use a single undo/forget ;; command, which is called in all cases. ;; (defun proof-retract-target (target undo-action displayflags) "Retract the span TARGET and apply UNDO-ACTION to undone region if non-nil. Notice that this necessitates retracting any spans following TARGET, up to the end of the locked region. DISPLAYFLAGS control output shown to user, see `proof-action-list'." (let ((end (proof-unprocessed-begin)) (start (span-start target)) (span (if proof-arbitrary-undo-positions target (proof-last-goal-or-goalsave))) actions) ;; NB: first section only entered if proof-kill-goal-command is ;; non-nil. Otherwise we expect proof-find-and-forget-fn to do ;; all relevent work for arbitrary retractions. FIXME: clean up ;; 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 proof-kill-goal-command (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/non-undoable spans at and immediately following target (setq span target) (while (and span (memq (span-property span 'type) '(comment proverproc))) (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) nil ; was: proof-no-command (funcall proof-count-undos-fn span)) undo-action) end start)) ;; Otherwise, start the retraction by killing off the ;; currently active goal. ;; FIXME: and couldn't we move the end upwards? ;; FIXME: hack proof-nesting-depth here. This is ;; in the wrong place: it should be done *after* the ;; retraction has succeeded. (setq proof-nesting-depth (1- proof-nesting-depth)) (setq actions (proof-setup-retract-action (span-start span) end (list proof-kill-goal-command) undo-action displayflags) 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)... ;; But end may have moved backwards above: this just checks whether ;; there is more retraction to be done. (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. (nconc actions (proof-setup-retract-action start end (funcall proof-find-and-forget-fn target) undo-action displayflags)))) (proof-start-queue (min start end) (proof-unprocessed-begin) actions 'retracting))) (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 (if delete-region 'kill-region))) (defun proof-retract-until-point (&optional undo-action displayflags) "Set up the proof process for retracting until point. This calculates the commands to undo to the current point within the locked region. If invoked outside the locked region, undo the last successfully processed command. See `proof-retract-target'. After retraction has succeeded in the prover, the filter will call `proof-done-retracting'. If UNDO-ACTION is non-nil, it will then be invoked on the region in the proof script corresponding to the proof command sequence. DISPLAYFLAGS control output shown to user, see `proof-action-list'. Before the retraction is calculated, we enforce the file-level protocol with `proof-activate-scripting'. This has a couple of effects: 1. If the file is completely processed, we have to re-open it for scripting again which may involve retracting other (dependent) files. 2. We may query the user whether to save some buffers. Step 2 may seem odd -- we're undoing (in) the buffer, after all -- but what may happen is that when scripting starts going forward again, we hit a command that loads other files, but the user hasn't saved the latest edits. Therefore it is right to query saves here." (if (proof-locked-region-empty-p) (error "No locked region") (proof-activate-scripting) ;; enforce not busy to avoid retracting items from the queue region, ;; which is not supported currently, see #443 ;; (future: may allow retracting from queue in progress) (proof-shell-ready-prover) (unless (proof-locked-region-empty-p) ;; re-opening may discard locked region! (let ((span (span-at (point) 'type))) ;; If no span at point, retracts the last span in the buffer. (unless span (proof-goto-end-of-locked) (backward-char) (setq span (span-at (point) 'type))) (if span (proof-retract-target span undo-action displayflags) ;; something wrong (proof-debug "proof-retract-until-point: couldn't find a span!")))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Proof General scripting mode definition, part 1. ;; ;;;###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) ;; Set default indent function (can be overriden in derived modes) (make-local-variable 'indent-line-function) (setq indent-line-function 'proof-indent-line) ;; 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 cause double 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) ;; Set after change functions (proof-script-set-after-change-functions) (add-hook 'after-set-visited-file-name-hooks 'proof-script-set-visited-file-name nil t) (add-hook 'proof-activate-scripting-hook 'proof-cd-sync nil t)) ;; NB: proof-mode-map declared above (proof-menu-define-keys proof-mode-map) (proof-eval-when-ready-for-assistant (define-key proof-mode-map [(control c) (control a)] (proof-ass keymap))) (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 \\[write-file], 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-name buffer-file-name) (if (eq (current-buffer) proof-script-buffer) (pg-response-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'." (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 (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-auto'. 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. (if (eq (current-buffer) proof-script-buffer) (proof-deactivate-scripting-auto)) (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)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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 `proof-script-font-lock-keywords'. 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) (setq font-lock-defaults (list '(proof-script-font-lock-keywords) ;; see defadvice in proof-syntax (fboundp (proof-ass-sym font-lock-fontify-syntactically-region)))) ;; Has buffer already been processed? ;; NB: call to file-truename is needed for GNU 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))) (make-local-variable 'comment-start) (setq comment-start (concat proof-script-comment-start " ")) (make-local-variable 'comment-end) (setq comment-end ;; For end of line terminated comments, stays empty. (if (string-equal "" proof-script-comment-end) "" ;; Otherwise, an extra space before comment delimiter (concat " " proof-script-comment-end))) (unless proof-script-comment-start-regexp (setq proof-script-comment-start-regexp (regexp-quote proof-script-comment-start))) (unless proof-script-comment-end-regexp (setq proof-script-comment-end-regexp (if (string-equal "" proof-script-comment-end) (regexp-quote "\n") ;; end-of-line terminated comments (regexp-quote proof-script-comment-end)))) ;; FIXME: This is clearly bogus: it sets the *start* matcher based on the ;; *end* marker. But I'm not sure what's the right fix: OT1H the code is ;; careful to build a correct end-matcher, but OTOH it's not as careful as ;; the default code in newcomment.el anyway. So I'm tempted to just remove ;; this code altogether. (make-local-variable 'comment-start-skip) (unless comment-start-skip (setq comment-start-skip (if (string-equal "" proof-script-comment-end) (regexp-quote "\n") ;; end-of-line terminated comments (regexp-quote proof-script-comment-end))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Generic defaults for hooks, based on regexps. ;; ;; 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 (span) "Is SPAN a goal? Decide by matching with `proof-goal-command-regexp'." (proof-string-match-safe proof-goal-command-regexp (or (span-property span 'cmd) ""))) (defun proof-generic-state-preserving-p (cmd) "Is CMD state preserving? Match on `proof-non-undoables-regexp'." ;; FIXME: logic here is not quite finished: proof-non-undoables are ;; certainly not state preserving, but so are a bunch more things, ;; i.e. ordinary proof commands which may appear in proof scripts. ;; Might be better to add positive and negative regexps for ;; state-preserving tests (only one of which needs to be set). (not (proof-string-match-safe proof-non-undoables-regexp cmd))) (defun proof-generic-count-undos (span) "Count number of undos in SPAN, return commands 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 (tl (length proof-terminal-string))) (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 (string-equal (substring str i (+ i tl)) proof-terminal-string) (incf ct)) (incf i)))) (setq span (next-span span 'type))) (if (= ct 0) nil ; was proof-no-command (cond ((stringp proof-undo-n-times-cmd) (list (format proof-undo-n-times-cmd ct))) ((functionp proof-undo-n-times-cmd) (list (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. This generic implementation assumes it is enough to find the nearest following span with a `name' property, and retract that using `proof-forget-id-command' with the given name. If this behaviour is not correct, you must customize the function with something different." ;; Modelled on Isar's find-and-forget function, but less ;; general at the moment: will only issue one und command. ;; FIXME: would be much cleaner to wrap up the undo behaviour ;; also within proofs in this function. (cond ((not proof-forget-id-command) (proof-debug "proof-generic-find-and-forget: proof-forget-id-command is unset, no action taken.") "") (t (let (ans typ name answers cmd) (while span (setq ans nil) (setq cmd (span-property span 'cmd)) (setq typ (span-property span 'type)) (cond ;; comment, diagnostic, prover processed, nested proof command: skip ((or (eq typ 'comment) (eq typ 'proverproc) (eq typ 'proof) (and proof-ignore-for-undo-count cmd (proof-string-match proof-ignore-for-undo-count cmd)))) ;; some named element: use generic forget-id function; finish. ((setq name (span-property span 'name)) (setq ans (format proof-forget-id-command name)) (setq span nil))) (if ans (setq answers (cons ans answers))) (if span (setq span (next-span span 'type)))) answers)))) ;; ;; End of new generic functions ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Sanity checks on important settings ;; (defconst proof-script-important-settings '(proof-script-comment-start ; proof-script-comment-end proof-save-command-regexp ; [actually, some provers may not have save command] ; proof-goal-command-regexp ; not needed if proof-goal-command-p is set ; 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 )) ;;;###autoload (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." ;; Common configuration for shared script/other related buffers. (proof-config-done-related) ;; Make mode class "pg-sticky" so renaming doesn't change the mode. (put major-mode 'mode-class 'pg-sticky) (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 def for (first character of) terminal string (if proof-terminal-string (progn (define-key proof-mode-map (vconcat [(control c)] (vector (aref proof-terminal-string 0))) 'proof-electric-terminator-toggle) (define-key proof-mode-map (vector (aref proof-terminal-string 0)) 'proof-electric-terminator))) ;; Toolbar, main menu (loads proof-toolbar,setting p.-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) ;; Define parsing functions (proof-setup-parsing-mechanism) ;; Setup imenu and add it to menu if enabled. (proof-setup-imenu) (proof-imenu-enable) ;; Save file-less script mode buffers in case of accidental exit (or (buffer-file-name) (setq buffer-offer-save t)) ;; Turn on autosend if enabled (proof-autosend-enable 'nomsg) ;; Invisibility management: show ellipsis (mapc (lambda (p) (add-to-invisibility-spec (cons (pg-invisible-prop p) t))) pg-all-idioms) ;; If we're excited to get going straightaway, make and layout windows (when proof-layout-windows-on-visit-file (proof-shell-make-associated-buffers) (proof-layout-windows)) ;; Make sure the user has been welcomed! (proof-splash-message)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Subroutines of proof-config-done ;; (defun proof-setup-parsing-mechanism () "Choose parsing mechanism according to different kinds of script syntax. Choice of function depends on configuration setting." (unless (fboundp 'proof-segment-up-to) (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-string) (setq proof-script-parse-function 'proof-script-generic-parse-cmdend) (unless proof-script-command-end-regexp (proof-warn-if-unset "probof-config-done" 'proof-terminal-string) (setq proof-script-command-end-regexp (if proof-terminal-string (regexp-quote proof-terminal-string) "$")))) (t (error "Configuration error: must set `proof-terminal-string' or one of its friends"))))) (defun proof-setup-imenu () "Setup a default for imenu, perhaps using `proof-script-imenu-generic-expression'." (unless ;; already setup, leave it alone (and (boundp 'imenu-generic-expression) imenu-generic-expression) (set (make-local-variable 'imenu-generic-expression) (or proof-script-imenu-generic-expression (delq nil (list (if proof-goal-with-hole-regexp (list nil proof-goal-with-hole-regexp proof-goal-with-hole-result)) (if proof-save-with-hole-regexp (list "Saves" proof-save-with-hole-regexp proof-save-with-hole-result)))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Caching parse results for unedited portions of the buffer ;; ;; Added in PG 4.1 ;; ;; A simplistic first attempt: we only cache the last region that was ;; parsed. It would be better to maintain a parse cache for the ;; unedited prefix of the buffer or for individual segments like ;; PGIP Emacs PG does. Or to parse during idle like font-lock. ;; ;; We assume that extending the parsed region can only possibly affect ;; the last command in the cache but leaves the rest intact. (NB: in ;; Isabelle/Isar a command can be a proper prefix of a longer one and ;; there are no explicit terminators). (deflocal proof-segment-up-to-cache nil "Cache used to speed up parsing. Stores recent results of `proof-segment-up-to' in reverse order.") (deflocal proof-segment-up-to-cache-start 0) (deflocal proof-segment-up-to-cache-end 0) (deflocal proof-last-edited-low-watermark nil) (defun proof-segment-up-to-using-cache (pos &rest args) "A wrapper for `proof-segment-up-to' which uses a cache to speed things up." (let (res) (if (and proof-use-parser-cache ;; safety off valve proof-segment-up-to-cache (>= (proof-queue-or-locked-end) proof-segment-up-to-cache-start) (setq res (proof-segment-cache-contents-for pos)) ;; only use result if last edit point is >1 segment below (or (not proof-last-edited-low-watermark) (> proof-last-edited-low-watermark (nth 2 (car res))))) (progn (proof-debug "proof-segment-up-to-using-cache: re-using %d parse results" (length res)) res) ;; Cache not useful, perform a fresh parse (let ((semis (proof-segment-up-to pos args))) (setq proof-segment-up-to-cache (reverse semis)) (setq proof-segment-up-to-cache-start (proof-queue-or-locked-end)) (setq proof-segment-up-to-cache-end (if semis (nth 2 (car semis)) 0)) (when proof-last-edited-low-watermark (if (<= proof-last-edited-low-watermark proof-segment-up-to-cache-end) (setq proof-last-edited-low-watermark nil))) semis)))) (defun proof-segment-cache-contents-for (pos) ;; only return result if we have cache for complete region (when (<= pos proof-segment-up-to-cache-end) (let ((semis proof-segment-up-to-cache) (start (proof-queue-or-locked-end)) usedsemis semiend) (while semis (setq semiend (nth 2 (car semis))) (if (> semiend start) (setq usedsemis (cons (car semis) usedsemis))) (setq semis (if (or (< semiend pos) ;; matches parsing-until-find-something behaviour (and (= semiend pos) (not usedsemis))) (cdr semis)))) usedsemis))) (defun proof-script-after-change-function (start end prelength) "Value for `after-change-functions' in proof script buffers." (setq proof-last-edited-low-watermark (min (or proof-last-edited-low-watermark (point-max)) start)) (if (and (markerp proof-overlay-arrow) (marker-position proof-overlay-arrow) ; only move marker up: ;(< start (marker-position proof-overlay-arrow)) (>= start (proof-queue-or-locked-end))) (proof-set-overlay-arrow (proof-queue-or-locked-end)))) (defun proof-script-set-after-change-functions () "Set `after-change-functions' for script buffers." (add-hook 'after-change-functions 'proof-script-after-change-function nil t)) (provide 'proof-script) ;;; proof-script.el ends here proofgeneral-4.3~pre130510/generic/proof-shell.el000066400000000000000000002076451214562307500216350ustar00rootroot00000000000000;;; proof-shell.el --- Proof General shell mode. ;; ;; Copyright (C) 1994-2011 LFCS Edinburgh. ;; Authors: David Aspinall, Yves Bertot, Healfdene Goguen, ;; Thomas Kleymann and Dilip Sequeira ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-shell.el,v 12.17 2013/01/15 14:40:18 tews Exp $ ;; ;;; Commentary: ;; ;; Mode for buffer which interacts with proof assistant. ;; Includes management of a queue of commands waiting to be sent. ;; ;;; Code: (require 'cl) ; set-difference, every (eval-when-compile (require 'span) (require 'proof-utils)) (require 'scomint) (require 'pg-response) (require 'pg-goals) (require 'pg-user) ; proof-script, new-command-advance (require 'proof-tree) ;; ;; 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 "The main queue of things to do: spans, commands and actions. The value is a list of lists of the form (SPAN COMMANDS ACTION [DISPLAYFLAGS]) which is the queue of things to do. SPAN is a region in the sources, where COMMANDS come from. Often, additional properties are recorded as properties of SPAN. COMMANDS is a list of strings, holding the text to be send to the prover. It might be the empty list if nothing needs to be sent to the prover, such as, for comments. Usually COMMANDS contains just 1 string, but it might also contains more elements. The text should be obtained with `(mapconcat 'identity COMMANDS \" \")', where the last argument is a space. ACTION is the callback to be invoked when this item has been processed by the prover. For normal scripting items it is `proof-done-advancing', for retract items `proof-done-retracting', but there are more possibilities (e.g. `proof-done-invisible', `proof-shell-set-silent', `proof-shell-clear-silent' and `proof-tree-show-goal-callback'). The DISPLAYFLAGS are set for non-scripting commands or for when scripting should not bother the user. They may include 'invisible non-script command (`proof-shell-invisible-command') 'no-response-display do not display messages in *response* buffer 'no-error-display do not display errors/take error action 'no-goals-display do not goals in *goals* buffer 'proof-tree-show-subgoal item inserted by the proof-tree package Note that 'invisible does not imply any of the others. If flags are non-empty, interactive cues will be surpressed. (E.g., printing hints). See the functions `proof-start-queue' and `proof-shell-exec-loop'.") (defsubst proof-shell-invoke-callback (listitem) "From `proof-action-list' LISTITEM, invoke the callback on the span." (condition-case nil (funcall (nth 2 listitem) (car listitem)) (error nil))) (defvar proof-second-action-list-active nil "Signals that some items are waiting outside of `proof-action-list'. If this is t it means that some items from the queue region are waiting for being processed in a place different from `proof-action-list'. In this case Proof General must behave as if `proof-action-list' would be non-empty, when it is, in fact, empty. This is used, for instance, for parallel background compilation for Coq: The Require command and the following items are not put into `proof-action-list' and are stored somewhere else until the background compilation finishes. Then those items are put into `proof-action-list' for getting processed.") ;; We record the last output from the prover and a flag indicating its ;; type, as well as a previous ("delayed") version for when the end ;; of the queue is reached or an error or interrupt occurs. ;; ;; See `proof-shell-last-output', `proof-shell-last-prompt' in ;; pg-vars.el (defvar proof-shell-last-goals-output "" "The last displayed goals string.") (defvar proof-shell-last-response-output "" "The last displayed response message.") (defvar proof-shell-delayed-output-start nil "A record of the start of the previous output in the shell buffer. The previous output is held back for processing at end of queue.") (defvar proof-shell-delayed-output-end nil "A record of the start of the previous output in the shell buffer. The previous output is held back for processing at end of queue.") (defvar proof-shell-delayed-output-flags nil "A copy of the `proof-action-list' flags for `proof-shell-delayed-output'.") (defvar proof-shell-interrupt-pending nil "A flag indicating an interrupt is pending. This ensures that the proof queue will be interrupted even if no interrupt message is printed from the prover after the last output.") (defvar proof-shell-exit-in-progress nil "A flag indicating that the current proof process is about to exit. This flag is set for the duration of `proof-shell-kill-function' to tell hooks in `proof-deactivate-scripting-hook' to refrain from calling `proof-shell-exit'.") ;; ;; Indicator and fake minor mode for active scripting buffer ;; (defcustom proof-shell-active-scripting-indicator '(:eval (propertize " Scripting " 'face (cond (proof-shell-busy 'proof-queue-face) ((eq proof-shell-last-output-kind 'error) 'proof-script-sticky-error-face) ((proof-with-current-buffer-if-exists proof-script-buffer (proof-locked-region-full-p)) 'font-lock-type-face) (t 'proof-locked-face)))) "Modeline indicator for active scripting buffer. Changes colour to indicate whether the shell is busy, etc." :type 'sexp :group 'proof-general-internals) (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))))) ;; ;; Implementing the process lock ;; ;; Note that because Emacs Lisp code is single-threaded, there are no ;; concurrency issues here (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). But the ;; lock allows for clear management of the queue. ;; ;; Three relevant 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, an enabler predicate: ;; ;; proof-shell-available-p ;; returns non-nil if a proof shell is active and not locked. ;; ;;;###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, which is a symbol or list of symbols. 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) (and (listp queuemode) (member proof-shell-busy queuemode))) (error "Proof process busy!"))) ;;;###autoload (defsubst proof-shell-live-buffer () "Return non-nil if proof-shell-buffer is live." (and proof-shell-buffer (buffer-live-p proof-shell-buffer) (scomint-check-proc proof-shell-buffer))) ;;;###autoload (defun proof-shell-available-p () "Return 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. If QUEUEMODE is supplied, set the lock to that value." (proof-shell-ready-prover queuemode) (setq proof-shell-interrupt-pending nil proof-shell-busy (or queuemode t) proof-shell-last-queuemode proof-shell-busy) (run-hooks 'proof-state-change-hook)) (defun proof-release-lock () "Release the proof shell lock. Clear `proof-shell-busy'." (setq proof-shell-busy nil)) ;; ;; Starting and stopping the proof shell ;; (defcustom proof-shell-fiddle-frames t "Non-nil if proof-shell functions should fire-up/delete frames like crazy." :type 'boolean :group 'proof-shell) (defvar proof-shell-filter-active nil "t when `proof-shell-filter' is running.") (defvar proof-shell-filter-was-blocked nil "t when a recursive call of `proof-shell-filter' was blocked. In this case `proof-shell-filter' must be called again after it finished.") (defun proof-shell-set-text-representation () "Adjust representation for current buffer, to match `proof-shell-unicode'." (unless proof-shell-unicode ;; Prevent interpretation of multi-byte characters. ;; Otherwise, chars 128-255 get remapped higher, breaking regexps (toggle-enable-multibyte-characters -1))) (defun proof-shell-make-associated-buffers () "Create the associated buffers and set buffer variables holding them." (let ((goals "*goals*") (resp "*response*") (trace "*trace*") (thms "*thms*")) (setq proof-goals-buffer (get-buffer-create goals)) (setq proof-response-buffer (get-buffer-create resp)) (if proof-shell-trace-output-regexp (setq proof-trace-buffer (get-buffer-create trace))) (if proof-shell-thms-output-regexp (setq proof-thms-buffer (get-buffer-create thms))) ;; Set the special-display-regexps now we have the buffer names (setq pg-response-special-display-regexp (proof-regexp-alt goals resp trace thms)))) (defun proof-shell-start () "Initialise a shell-like buffer for a proof assistant. Does nothing if proof assistant is already running. Also generates goal and response buffers. If `proof-prog-name-ask' is set, query the user for the process command." (interactive) (unless (proof-shell-live-buffer) (setq proof-shell-filter-active nil) (setq proof-included-files-list nil) ; clear some state (let ((name (buffer-file-name (current-buffer)))) (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 (setq proof-prog-name (read-shell-command "Run process: " proof-prog-name))) (let ((proc (downcase proof-assistant))) ;; Starting the inferior process (asynchronous) (let* ((prog-name-list1 (if (functionp (proof-ass-sym prog-args)) ;; complex assistants define -prog-args as function ;; that computes the argument list. (cons proof-prog-name (funcall (proof-ass-sym prog-args))) (if (proof-ass prog-args) ;; Intermediate complex assistants set the value ;; of -prog-args to the argument list. (cons proof-prog-name (proof-ass prog-args)) ;; Trivial assistants simply set proof-prog-name (split-string proof-prog-name)))) (prog-name-list ;; Splice in proof-rsh-command if it's non-nil (if (and proof-rsh-command (> (length proof-rsh-command) 0)) (append (split-string proof-rsh-command) prog-name-list1) prog-name-list1)) (prog-command-line (mapconcat 'identity prog-name-list " ")) (process-connection-type proof-shell-process-connection-type) ;; Trac #324, Trac #284: default with Emacs 23 variants ;; is t. nil gives marginally better results with "make ;; profile.isar" on homogenous test input. Top-level ;; Emacs loop causes slow down on Mac and Windows ports. (process-adaptive-read-buffering nil) ;; The next few settings control the proof assistant encoding. ;; See Elisp manual for recommendations for coding systems. ;; Modern versions of proof systems should be Unicode ;; clean, i.e., outputing only ASCII characters or using a ;; representation such as UTF-8. Old versions of PG ;; relied on control sequences using 8-bit characters with ;; codes between 127 and 255, this is now deprecated. ;; Backward compatibility: remove UTF-8 encoding if not ;; wanted; it conflicts with using chars 128-255 for ;; markup and results in blocking in C libraries. (process-environment (append (proof-ass prog-env) ; custom environment (if proof-shell-unicode ; if specials not used, process-environment ; leave it alone (cons (if (getenv "LANG") (format "LANG=%s" (replace-regexp-in-string "\\.UTF-8" "" (getenv "LANG"))) "LANG=C") (delete (concat "LANG=" (getenv "LANG")) process-environment))))) (normal-coding-system-for-read coding-system-for-read) (coding-system-for-read (if proof-shell-unicode (or (condition-case nil (check-coding-system 'utf-8) (error nil)) normal-coding-system-for-read) (if (string-match "Linux" (shell-command-to-string "uname")) 'raw-text normal-coding-system-for-read))) (coding-system-for-write coding-system-for-read)) (message "Starting: %s" prog-command-line) (apply 'scomint-make (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 (process exited) (setq proof-shell-buffer nil) (error "Starting process: %s..failed" prog-command-line))) (proof-shell-make-associated-buffers) (with-current-buffer proof-shell-buffer ;; Clear and set text representation (see CVS history for comments) (erase-buffer) (proof-shell-set-text-representation) ;; Initialise associated buffers (with-current-buffer proof-response-buffer (erase-buffer) (proof-shell-set-text-representation) (funcall proof-mode-for-response)) (with-current-buffer proof-goals-buffer (erase-buffer) (proof-shell-set-text-representation) (funcall proof-mode-for-goals)) (proof-with-current-buffer-if-exists proof-trace-buffer (erase-buffer) (proof-shell-set-text-representation) (funcall proof-mode-for-response) (setq pg-response-eagerly-raise nil)) ;; Initialise shell mode (calls hook function, after process started) (funcall proof-mode-for-shell) ;; Check to see that the process is still going. If not, ;; switch buffer to display the error messages to the user. (unless (proof-shell-live-buffer) (switch-to-buffer proof-shell-buffer) (error "%s process exited!" proc)) ;; Setting modes initialises local variables which ;; may affect frame/buffer appearance: so we fire up frames ;; once this has been done. (if proof-shell-fiddle-frames ;; Call multiple-frames-enable in case we need to fire up ;; new frames (NB: sets specifiers to remove modeline) (save-selected-window (save-selected-frame (proof-multiple-frames-enable))))) (message "Starting %s process... done." proc)))) ;; ;; 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. Try to shut down the proof process nicely and clear locked regions and state variables. Value for `kill-buffer-hook' in shell buffer, called by `proof-shell-bail-out' if process exits." (let* ((alive (scomint-check-proc (current-buffer))) (proc (get-buffer-process (current-buffer))) (bufname (buffer-name))) (message "%s, cleaning up and exiting..." bufname) (run-hooks 'proof-shell-signal-interrupt-hook) (redisplay t) (when (and alive proc) (catch 'exited (setq proof-shell-exit-in-progress t) (set-process-sentinel proc (lambda (p m) (throw 'exited t))) ;; Turn off scripting (ensure buffers completely processed/undone) (proof-deactivate-scripting-auto) (proof-shell-wait (proof-ass quit-timeout)) ;; Try to shut down politely. (if proof-shell-quit-cmd (scomint-send-string proc (concat proof-shell-quit-cmd "\n")) (scomint-send-eof)) ;; Wait for it to die (let ((timecount (proof-ass quit-timeout)) (proc (get-buffer-process proof-shell-buffer))) (while (and (> timecount 0) (scomint-check-proc proof-shell-buffer)) (accept-process-output proc 1 nil 1) (decf timecount))) ;; Still there, kill it rudely. (when (memq (process-status proc) '(open run stop)) (message "%s, cleaning up and exiting...killing process" bufname) (kill-process proc))) (set-process-sentinel proc nil)) ;; Clear all state (proof-script-remove-all-spans-and-deactivate) (proof-shell-clear-state) (run-hooks 'proof-shell-kill-function-hooks) ;; Remove auxiliary windows, trying to stop proliferation of ;; frames (NB: loses if user has switched buffer in special frame) (if (and proof-multiple-frames-enable proof-shell-fiddle-frames) (proof-delete-other-frames)) ;; Kill associated buffer (let ((proof-shell-buffer nil)) ;; fool kill buffer hooks (dolist (buf '(proof-goals-buffer proof-response-buffer proof-trace-buffer)) (when (buffer-live-p (symbol-value buf)) (delete-windows-on (symbol-value buf)) (kill-buffer (symbol-value buf)) (set buf nil)))) (setq proof-shell-exit-in-progress 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-last-queuemode nil proof-shell-proof-completed nil proof-nesting-depth 0 proof-shell-silent nil proof-shell-last-output "" proof-shell-last-prompt "" proof-shell-last-output-kind nil proof-shell-delayed-output-start nil proof-shell-delayed-output-end nil proof-shell-delayed-output-flags nil)) (defun proof-shell-exit (&optional dont-ask) "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. If optional argument DONT-ASK is non-nil, the proof process is terminated without confirmation. The kill function uses `-quit-timeout' as a timeout to wait after sending `proof-shell-quit-cmd' before rudely killing the process. This function should not be called if `proof-shell-exit-in-progress' is t, because a recursive call of `proof-shell-kill-function' will give strange errors." (interactive "P") (if (buffer-live-p proof-shell-buffer) (when (or dont-ask (yes-or-no-p (format "Exit %s process? " proof-assistant))) (let ((kill-buffer-query-functions nil)) ; avoid extra dialog (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. EVENT is the string describing the change." (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) (when proof-shell-busy (proof-interrupt-process) (proof-shell-wait)) (if (not (proof-shell-live-buffer)) (proof-shell-start) ;; start if not running ;; otherwise clear context (proof-script-remove-all-spans-and-deactivate) (proof-shell-clear-state) (with-current-buffer proof-shell-buffer (delete-region (point-min) (point-max))) (if (and (buffer-live-p proof-shell-buffer) proof-shell-restart-cmd) (proof-shell-invisible-command proof-shell-restart-cmd)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Response buffer processing ;; (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. This is only used in `proof-shell-process-urgent-message'.") (defun proof-shell-handle-error-output (start-regexp append-face) "Displays output from process in `proof-response-buffer'. The output is taken from `proof-shell-last-output' and begins the first match for START-REGEXP. If START-REGEXP is nil or no match can be found (which can happen if output has been garbled somehow), begin from the start of the output for this command. This is a subroutine of `proof-shell-handle-error'." (let ((string proof-shell-last-output) pos) (if (and start-regexp (setq pos (string-match start-regexp string))) (setq string (substring string pos))) ;; Erase if need be, and erase next time round too. (pg-response-maybe-erase t nil) (pg-response-display-with-face string append-face))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Processing error output ;; (defun proof-shell-handle-error-or-interrupt (err-or-int flags) "React on an error or interrupt message triggered by the prover. The argument ERR-OR-INT should be set to 'error or 'interrupt which affects the action taken. For errors, we first flush unprocessed output (usually goals). The error message is the (usually) displayed in the response buffer. For interrupts, a warning message is displayed. In both cases we then sound a beep, clear the queue and spans and finally we call `proof-shell-handle-error-or-interrupt-hook'. Commands which are not part of regular script management (with non-empty flags='no-error-display) will not cause any display action. This is called in two places: (1) from the output processing functions, in case we find an error or interrupt message output, and (2) from the exec loop, in case of a pending interrupt which didn't cause prover output." (unless (memq 'no-error-display flags) (cond ((eq err-or-int 'interrupt) (pg-response-maybe-erase t t t) ; force cleaned now & next (proof-shell-handle-error-output (if proof-shell-truncate-before-error proof-shell-interrupt-regexp) 'proof-error-face) (pg-response-warning "Interrupt: script management may be in an inconsistent state (but it's probably okay)")) (t ; error (if proof-shell-delayed-output-start (save-excursion (proof-shell-handle-delayed-output))) (proof-shell-handle-error-output (if proof-shell-truncate-before-error proof-shell-error-regexp) 'proof-error-face) (proof-display-and-keep-buffer proof-response-buffer)))) (proof-with-current-buffer-if-exists proof-shell-buffer (proof-shell-error-or-interrupt-action err-or-int))) (defun proof-shell-error-or-interrupt-action (err-or-int) "Take action on errors or interrupts. ERR-OR-INT is a flag, 'error or 'interrupt. This is a subroutine of `proof-shell-handle-error-or-interrupt'. Must be called with proof shell buffer current. This function invokes `proof-shell-handle-error-or-interrupt-hook' unless the FLAGS for the command are non-nil (see `proof-action-list')." (unless proof-shell-quiet-errors (beep)) (let* ((fatalitem (car-safe proof-action-list)) (badspan (car-safe fatalitem)) (flags (if fatalitem (nth 3 fatalitem)))) (proof-with-current-buffer-if-exists proof-script-buffer (save-excursion (proof-script-clear-queue-spans-on-error badspan (eq err-or-int 'interrupt)))) ;; Note: coq-par-emergency-cleanup, which might be called via ;; proof-shell-handle-error-or-interrupt-hook below, assumes that ;; proof-action-list is empty on error. (setq proof-action-list nil) (proof-release-lock) (unless flags ;; Give a hint about C-c C-`. (NB: approximate test) (if (pg-response-has-error-location) (pg-next-error-hint)) ;; Run hooks for additional effects, e.g. highlight or moving pointer (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." ) ;; PG 4.0 FIXME ; (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-handle-immediate-output (cmd start end flags) "See if the output between START and END must be dealt with immediately. To speed up processing, PG tries to avoid displaying output that the user will not have a chance to see. Some output must be handled immediately, however: these are errors, interrupts, goals and loopbacks (proof step hints/proof by pointing results). In this function we check, in turn: `proof-shell-interrupt-regexp' `proof-shell-error-regexp' `proof-shell-proof-completed-regexp' `proof-shell-result-start' Other kinds of output are essentially display only, so only dealt with if necessary. To extend this, set `proof-shell-handle-output-system-specific', which is a hook to take particular additional actions. This function sets variables: `proof-shell-last-output-kind', and the counter `proof-shell-proof-completed' which counts commands after a completed proof." (setq proof-shell-last-output-kind nil) ; unclassified (goto-char start) (cond ;; TODO: Isabelle has changed (since 2009) and is now amalgamating ;; output between prompts, and does e.g., ;; GOALS ;; ERROR ;; we need to override delayed output from the previous ;; command with delayed output from this command to handle that! ((proof-re-search-forward-safe proof-shell-interrupt-regexp end t) (setq proof-shell-last-output-kind 'interrupt) (proof-shell-handle-error-or-interrupt 'interrupt flags)) ((proof-re-search-forward-safe proof-shell-error-regexp end t) (setq proof-shell-last-output-kind 'error) (proof-shell-handle-error-or-interrupt 'error flags)) ((proof-re-search-forward-safe proof-shell-result-start end t) ;; NB: usually the action list is empty, strange results likely if ;; more commands follow. Therefore, this case might be delayed. (let (pstart pend) (setq pstart (+ 1 (match-end 0))) (re-search-forward proof-shell-result-end end t) (setq pend (- (match-beginning 0) 1)) (proof-shell-insert-loopback-cmd (buffer-substring-no-properties pstart pend))) (setq proof-shell-last-output-kind 'loopback) (proof-shell-exec-loop)) ((proof-re-search-forward-safe proof-shell-proof-completed-regexp end t) (setq proof-shell-proof-completed 0))) ; commands since complete ;; PG4.0 change: simplify and run earlier (if proof-shell-handle-output-system-specific (funcall proof-shell-handle-output-system-specific cmd proof-shell-last-output))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Interrupts ;; (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 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. Some provers may ignore (and lose) interrupt signals, or fail to indicate that they have been acted upon yet stop in the middle of output. In the first case, PG will terminate the queue of commands at the first available point. In the second case, you may need to press enter inside the prover command buffer (e.g., with Isabelle2009 press RET inside *isabelle*)." (interactive) (unless (proof-shell-live-buffer) (error "Proof process not started!")) (unless proof-shell-busy (error "Proof process not active!")) (setq proof-shell-interrupt-pending t) (with-current-buffer proof-shell-buffer (interrupt-process)) (run-hooks 'proof-shell-signal-interrupt-hook)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Low-level commands for shell communication ;; ;;;###autoload (defun proof-shell-insert (strings action &optional scriptspan) "Insert STRINGS at the end of the proof shell, call `scomint-send-input'. STRINGS is a list of strings (which will be concatenated), or a single string. The ACTION argument is a symbol which is typically the name of a callback for when each string has been processed. This calls `proof-shell-insert-hook'. The arguments `action' and `scriptspan' may be examined by the hook to determine how to modify the `string' variable (exploiting dynamic scoping) which will be the command actually sent to the shell. Note that the hook is not called for the empty (null) string or a carriage return. We strip the 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-add-to-queue' when we start processing a queue, and in `proof-shell-exec-loop', to process the next item." (assert (or (stringp strings) (listp strings)) nil "proof-shell-insert: expected string list argument") (with-current-buffer proof-shell-buffer (goto-char (point-max)) ;; TEMP: next step: preprocess list of strings directly (let ((string (if (stringp strings) strings (apply 'concat strings)))) ;; Hook for munging `string' and other dirty hacks. (run-hooks 'proof-shell-insert-hook) ;; Replace CRs from string with spaces to avoid spurious prompts. (if proof-shell-strip-crs-from-input (setq string (subst-char-in-string ?\n ?\ string t))) (insert string) ;; Advance the proof-marker, if synchronization has been gained. ;; Null marker => no yet synced; output is ignored. (unless (null (marker-position proof-marker)) (set-marker proof-marker (point))) (scomint-send-input)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Code for manipulating proof queue ;; (defun proof-shell-action-list-item (cmd callback &optional flags) "Return action list entry run CMD with callback CALLBACK and FLAGS. The queue entry does not refer to a span in the script buffer." (list nil (list cmd) callback flags)) (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-action-list-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-action-list-item proof-shell-stop-silent-cmd 'proof-shell-clear-silent)) (defsubst proof-shell-should-be-silent () "Non-nil if we should switch to silent mode based on size of queue." (if (and proof-shell-start-silent-cmd ; configured (not proof-full-annotation) ; always noisy (not proof-tree-external-display) ; no proof-tree display (not proof-shell-silent)) ; already silent ;; NB: to be more accurate we should only count number ;; of scripting items in the list (not e.g. invisibles). ;; More efficient: keep track of size of queue as modified. (>= (length proof-action-list) proof-shell-silent-threshold))) (defsubst proof-shell-insert-action-item (item) "Insert ITEM from `proof-action-list' into the proof shell." (proof-shell-insert (nth 1 item) (nth 2 item) (nth 0 item))) (defsubst proof-shell-slurp-comments () "Strip comments at front of `proof-action-list', returning items stripped. Comments are not sent to the prover." (let (cbitems nextitem) (while (and proof-action-list (not (nth 1 (setq nextitem (car proof-action-list))))) (setq cbitems (cons nextitem cbitems)) (setq proof-action-list (cdr proof-action-list))) (nreverse cbitems))) (defun proof-add-to-queue (queueitems &optional queuemode) "Chop off the vacuous prefix of the QUEUEITEMS and queue them. For each item with a nil command 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." (when (and queueitems proof-action-list) ;; 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))))) (let ((nothingthere (null proof-action-list))) ;; Now extend or start the queue. (setq proof-action-list (nconc proof-action-list queueitems)) (when nothingthere ; process comments immediately (let ((cbitems (proof-shell-slurp-comments))) (mapc 'proof-shell-invoke-callback cbitems))) (if proof-action-list ;; something to do (progn (if (proof-shell-should-be-silent) ;; do this ASAP, either first or just after current command (setq proof-action-list (if nothingthere ; the first thing (cons (proof-shell-start-silent-item) proof-action-list) (cons (car proof-action-list) ; after current (cons (proof-shell-start-silent-item) (cdr proof-action-list)))))) (when nothingthere ; start sending commands (proof-grab-lock queuemode) (setq proof-shell-last-output-kind nil) (proof-shell-insert-action-item (car proof-action-list)))) (if proof-second-action-list-active ;; primary action list is empty, but there are items waiting ;; somewhere else (proof-grab-lock queuemode) ;; nothing to do: maybe we completed a list of comments without sending them (proof-detach-queue))))) ;;;###autoload (defun proof-start-queue (start end queueitems &optional queuemode) "Begin processing a queue of commands in QUEUEITEMS. If START is non-nil, START and END are buffer positions in the active scripting buffer for the queue region. This function calls `proof-add-to-queue'." (if start (proof-set-queue-endpoints start end)) (proof-add-to-queue queueitems queuemode)) ;;;###autoload (defun proof-extend-queue (end queueitems) "Extend the current queue with QUEUEITEMS, 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) (condition-case err (run-hooks 'proof-shell-extend-queue-hook) ((error quit) (proof-detach-queue) (signal (car err) (cdr err)))) (proof-add-to-queue queueitems 'advancing)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; MAIN LOOP ;; (defun proof-shell-exec-loop () "Main loop processing the `proof-action-list', called from shell filter. `proof-action-list' contains a list of (SPAN COMMAND ACTION [FLAGS]) lists. 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 the callback (ACTION SPAN) on the first item, then (ACTION SPAN) on any following items which have null 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 or contains only invisible elements for Prooftree synchronization." (unless (null proof-action-list) (save-excursion (if proof-script-buffer ; switch to active script (set-buffer proof-script-buffer)) (let* ((item (car proof-action-list)) (flags (nth 3 item)) cbitems) ;; now we should invoke callback on just processed command, ;; but we delay this until sending the next command, attempting ;; to parallelize prover and Emacs somewhat. (PG 4.0 change) (setq proof-action-list (cdr proof-action-list)) (setq cbitems (cons item (proof-shell-slurp-comments))) ;; This is the point where old items have been removed from ;; proof-action-list and where the next item has not yet been ;; sent to the proof assistant. This is therefore one of the ;; few points where it is safe to manipulate ;; proof-action-list. The urgent proof-tree display actions ;; must therefore be called here, because they might add some ;; Show actions at the front of proof-action-list. (if proof-tree-external-display (proof-tree-urgent-action flags)) ;; if action list is (nearly) empty, ensure prover is noisy. (if (and proof-shell-silent (not (eq (nth 2 item) 'proof-shell-clear-silent)) (or (null proof-action-list) (null (cdr proof-action-list)))) ;; Insert the quieten command on head of queue (setq proof-action-list (cons (proof-shell-stop-silent-item) proof-action-list))) ;; pending interrupts: we want to stop the queue here (when proof-shell-interrupt-pending (mapc 'proof-shell-invoke-callback cbitems) (setq cbitems nil) (proof-shell-handle-error-or-interrupt 'interrupt flags)) (if proof-action-list ;; send the next command to the process. (proof-shell-insert-action-item (car proof-action-list))) ;; process the delayed callbacks now (mapc 'proof-shell-invoke-callback cbitems) (unless (or proof-action-list proof-second-action-list-active) ; release lock, cleanup (proof-release-lock) (proof-detach-queue) (unless flags ; hint after a batch of scripting (pg-processing-complete-hint)) (pg-finish-tracing-display)) (and (not proof-second-action-list-active) (or (null proof-action-list) (every (lambda (item) (memq 'proof-tree-show-subgoal (nth 3 item))) proof-action-list))))))) (defun proof-shell-insert-loopback-cmd (cmd) "Insert command string CMD sent from prover into script buffer. String is inserted at the end of locked region, after a newline and indentation. Assumes `proof-script-buffer' is active." (unless (string-match "^\\s-*$" cmd) ; FIXME: assumes cmd is single line (with-current-buffer proof-script-buffer (let (span) (proof-goto-end-of-locked) (let ((proof-one-command-per-line t)) ; because pbp several commands (proof-script-new-command-advance)) (insert cmd) ;; 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 (span-make (proof-unprocessed-begin) (point))) (span-set-property span 'type 'pbp) (span-set-property span 'cmd cmd) (proof-set-queue-endpoints (proof-unprocessed-begin) (point)) (setq proof-action-list (cons (car proof-action-list) (cons (list span cmd 'proof-done-advancing) (cdr proof-action-list)))))))) (defun proof-shell-process-urgent-message (start end) "Analyse urgent message between START and END for various cases. Cases are: *trace* output, included/retracted files, cleared goals/response buffer, variable setting, xml-encoded PGIP response, theorem dependency message or interactive output indicator. If none of these apply, display the text between START and END. The text between START and END should be a string that starts with text matching `proof-shell-eager-annotation-start' and ends with text matching `proof-shell-eager-annotation-end'." (goto-char start) (cond ((proof-looking-at-safe proof-shell-trace-output-regexp) (proof-shell-process-urgent-message-trace start end)) ((proof-looking-at-safe (car-safe proof-shell-process-file)) (let ((file (funcall (cdr proof-shell-process-file)))) (if (and file (not (string= file ""))) (proof-register-possibly-new-processed-file file)))) ((proof-looking-at-safe proof-shell-retract-files-regexp) (proof-shell-process-urgent-message-retract start end)) ((proof-looking-at-safe proof-shell-clear-response-regexp) (pg-response-maybe-erase nil t t)) ((proof-looking-at-safe proof-shell-clear-goals-regexp) (proof-clean-buffer proof-goals-buffer)) ((proof-looking-at-safe proof-shell-set-elisp-variable-regexp) (proof-shell-process-urgent-message-elisp)) ((proof-looking-at-safe proof-shell-match-pgip-cmd) (pg-pgip-process-packet ;; NB: xml-parse-region ignores junk before XML (xml-parse-region start end))) ((proof-looking-at-safe proof-shell-theorem-dependency-list-regexp) (proof-shell-process-urgent-message-thmdeps)) ((proof-looking-at-safe proof-shell-theorem-dependency-list-regexp) (proof-shell-process-urgent-message-thmdeps)) ((proof-looking-at-safe proof-shell-interactive-prompt-regexp) (proof-shell-process-interactive-prompt-regexp)) (t (proof-shell-process-urgent-message-default start end)))) ;; ;; urgent message subroutines ;; (defun proof-shell-process-urgent-message-default (start end) "A subroutine of `proof-shell-process-urgent-message'." ;; Clear the response buffer this time, but not next, leave window. (pg-response-maybe-erase nil nil) (proof-minibuffer-message (buffer-substring-no-properties (save-excursion (re-search-forward proof-shell-eager-annotation-start end nil) (point)) (min end (save-excursion (end-of-line) (point)) (+ start 75)))) (pg-response-display-with-face (proof-shell-strip-eager-annotations start end) 'proof-eager-annotation-face)) (defun proof-shell-process-urgent-message-trace (start end) "Display a message in the tracing buffer. A subroutine of `proof-shell-process-urgent-message'." (proof-trace-buffer-display start end) (unless (and proof-trace-output-slow-catchup (pg-tracing-tight-loop)) (proof-display-and-keep-buffer proof-trace-buffer)) ;; 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))) (defun proof-shell-process-urgent-message-retract (start end) "A subroutine of `proof-shell-process-urgent-message'. Takes files off `proof-included-files-list' and calls `proof-restart-buffers' to do the necessary clean-up on those buffers visting a file that disappears from `proof-included-files-list'. So in some respect this function is inverse to `proof-register-possibly-new-processed-file'." (let ((current-included proof-included-files-list)) (setq proof-included-files-list (funcall proof-shell-compute-new-files-list)) (let ((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 buffer hasn't changed (may be nuked) ((eq scrbuf proof-script-buffer)) ;; Otherwise, active scripting buffer has been retracted. (t (setq proof-script-buffer nil)))))) (defun proof-shell-process-urgent-message-elisp () "A subroutine of `proof-shell-process-urgent-message'." (let ((variable (match-string 1)) (expr (match-string 2))) (condition-case nil (with-temp-buffer (insert expr) ; massive risk from malicious provers!! (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")))))) (defun proof-shell-process-urgent-message-thmdeps () "A subroutine of `proof-shell-process-urgent-message'." (let ((names (match-string 1)) (deps (match-string 2)) (sep proof-shell-theorem-dependency-list-split)) (setq proof-last-theorem-dependencies (cons (split-string names sep) (split-string deps sep))))) (defun proof-shell-process-interactive-prompt-regexp () "Action taken when `proof-shell-interactive-prompt-regexp' is observed." (when (and (proof-shell-live-buffer) ; not already visible t) (switch-to-buffer proof-shell-buffer) (message "Prover expects input in %s buffer" proof-shell-buffer))) ;; ;; urgent message utilities ;; (defun proof-shell-strip-eager-annotations (start end) "Strip `proof-shell-eager-annotation-{start,end}' from region." (goto-char start) (if (re-search-forward proof-shell-eager-annotation-start end nil) (setq start (point))) (if (re-search-forward proof-shell-eager-annotation-end end nil) (setq end (match-beginning 0))) (buffer-substring-no-properties start end)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; The proof shell process filter ;; (defun proof-shell-filter-wrapper (str-do-not-use) "Wrapper for `proof-shell-filter', protecting against parallel calls. In Emacs a process filter function can be called while the same filter is currently running for the same process, for instance, when the filter bocks on I/O. This wrapper protects the main entry point, `proof-shell-filter' against such parallel, overlapping calls. The argument STR-DO-NOT-USE contains the most recent output, but is discarded. `proof-shell-filter' collects the output from `proof-shell-buffer' (where it is inserted by `scomint-output-filter'), relieving this function from the task to buffer the output that arrives during parallel, overlapping calls." (if proof-shell-filter-active (progn (setq proof-shell-filter-was-blocked t)) (let ((call-proof-shell-filter t)) (while call-proof-shell-filter (setq proof-shell-filter-active t proof-shell-filter-was-blocked nil) (condition-case err (progn (proof-shell-filter) (setq proof-shell-filter-active nil)) ((error quit) (setq proof-shell-filter-active nil proof-shell-filter-was-blocked nil) (signal (car err) (cdr err)))) (setq call-proof-shell-filter proof-shell-filter-was-blocked))))) (defun proof-shell-filter () "Master filter for the proof assistant shell-process. A function for `scomint-output-filter-functions'. Deal with output and issue new input from the queue. This is an important internal function. The output must be collected from `proof-shell-buffer' for the following reason. This function might block inside `process-send-string' when sending input to the proof assistant or to prooftree. In this case Emacs might call the process filter again while the previous instance is still running. `proof-shell-filter-wrapper' detects and delays such calls but does not buffer the output. Handle urgent messages first. As many as possible are processed, using the function `proof-shell-process-urgent-messages'. If a prompt is seen, run `proof-shell-filter-manage-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-1 OUTPUT-2 URGENT-MESSAGE-2 OUTPUT-3 PROMPT> `proof-marker' points after INPUT. `proof-shell-urgent-message-marker' points after URGENT-MESSAGE-2, after both urgent messages have been processed by `proof-shell-process-urgent-messages'. Urgent messages always processed; they are intended to correspond to informational notes that the prover makes to inform the user or interface on progress. In this case, the ordinary outputs OUTPUT-1 and OUTPUT-2 are ignored; only OUTPUT-3 will be processed by `proof-shell-filter-manage-output'. Error or interrupt messages are expected to terminate an interactive output and appear last before a prompt and will always be processed. Error messages and interrupt messages are therefore *not* considered as urgent messages. 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. After that, `proof-marker' is only changed when input is sent in `proof-shell-insert'." (save-excursion ;; Process urgent messages. (and proof-shell-eager-annotation-start (proof-shell-process-urgent-messages)) (let ((pos (marker-position proof-marker))) (if (not pos) (proof-shell-filter-first-command) (if proof-action-list ;; We were expecting some output. Wait until output is ;; complete. Only one piece of output is dealt with at a ;; time; we loose sync if there's more than one bit there. (let ((urgnt (marker-position proof-shell-urgent-message-marker)) (prev-prompt pos) (startpos pos) endpos) ;; Ignore any urgent messages that have already been dealt ;; with. This loses in the case mentioned above. Instead ;; might try to delete/filter out old urgent messages. (goto-char pos) (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 (setq endpos (match-beginning 0)) (setq proof-shell-last-prompt (buffer-substring-no-properties endpos (match-end 0))) (goto-char (point-max)) ;; Process output string. (proof-shell-filter-manage-output startpos endpos)))) ;; Not expecting output, ignore it. Busy flag should be clear. (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-first-command () "Deal with initial output. A subroutine of `proof-shell-filter'. This initialises `proof-marker': we set marker to after the first prompt in the output buffer if one can be found now. The first time a prompt is seen we ignore any output that occurred before it, assuming that corresponds to uninteresting startup messages." (goto-char (point-min)) (if (re-search-forward proof-shell-annotated-prompt-regexp nil t) (progn (set-marker proof-marker (point)) (proof-shell-exec-loop)))) (defun proof-shell-process-urgent-messages () "Scan the shell buffer for urgent messages. Scanning starts from `proof-shell-urgent-message-scanner' or `scomint-last-input-end', which ever is later. We deal with strings between regexps `proof-shell-eager-annotation-start' and `proof-shell-eager-annotation-end'. We update `proof-shell-urgent-message-marker' to point to last message found. This is a subroutine of `proof-shell-filter'." (let ((pt (point)) (end t) lastend laststart (initstart (max (marker-position proof-shell-urgent-message-scanner) (marker-position scomint-last-input-end)))) (goto-char initstart) (while (and end (re-search-forward proof-shell-eager-annotation-start nil 'limit)) (setq laststart (match-beginning 0)) (if (setq end (re-search-forward proof-shell-eager-annotation-end nil t)) (save-excursion (setq lastend end) ;; Process the region including the annotations (proof-shell-process-urgent-message laststart lastend)))) (set-marker proof-shell-urgent-message-scanner (if end ;; couldn't find message start; move forward to avoid rescanning (max initstart (- (point) (1+ proof-shell-eager-annotation-start-length))) ;; incomplete message; leave marker at start of message laststart)) ;; Set position of last urgent message found (if lastend (set-marker proof-shell-urgent-message-marker lastend)) (goto-char pt))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Despatching output ;; (defun proof-shell-filter-manage-output (start end) "Subroutine of `proof-shell-filter' for output between START and END. First, we invoke `proof-shell-handle-immediate-output' which classifies and handles output that must be dealt with immediately. Other output (user display) is only displayed when the proof action list becomes empty, to avoid a confusing rapidly changing output that slows down processing. After processing the current output, the last step undertaken by the filter is to send the next command from the queue." (let ((span (caar proof-action-list)) (cmd (nth 1 (car proof-action-list))) (flags (nth 3 (car proof-action-list))) (old-proof-marker (marker-position proof-marker))) ;; A copy of the last message, verbatim, never modified. (setq proof-shell-last-output (buffer-substring-no-properties start end)) ;; sets proof-shell-last-output-kind (proof-shell-handle-immediate-output cmd start end flags) (unless proof-shell-last-output-kind ; dealt with already (setq proof-shell-delayed-output-start start) (setq proof-shell-delayed-output-end end) (setq proof-shell-delayed-output-flags flags) (if (proof-shell-exec-loop) (setq proof-shell-last-output-kind ;; only display result for last output (proof-shell-handle-delayed-output))) ;; send output to the proof tree visualizer (if proof-tree-external-display (proof-tree-handle-delayed-output old-proof-marker cmd flags span))))) (defsubst proof-shell-display-output-as-response (flags str) "If FLAGS permit, display response STR; set `proof-shell-last-response-output'." (setq proof-shell-last-response-output str) ; set even if not displayed (unless (memq 'no-response-display flags) (pg-response-display str))) (defun proof-shell-handle-delayed-output () "Display delayed goals/responses, when queue is stopped or completed. This function handles the cases of `proof-shell-output-kind' which are not dealt with eagerly during script processing, namely 'response and 'goals types. This is useful even with empty delayed output as it will empty the buffers. The delayed output is in the region \[proof-shell-delayed-output-start,proof-shell-delayed-output-end]. If no goals classified output is found, the whole output is displayed in the response buffer. If goals output is found, the last matching instance, possibly bounded by `proof-shell-end-goals-regexp', will be displayed in the goals buffer (and may be further analysed by Proof General). Any output that appears *before* the last goals output (but after messages classified as urgent, see `proof-shell-filter') will also be displayed in the response buffer. For example, if OUTPUT has this form: MESSSAGE-1 GOALS-1 MESSAGE-2 GOALS-2 JUNK then GOALS-2 will be displayed in the goals buffer, and MESSAGE-2 in the response buffer. JUNK will be ignored. Notice that the above alternation (and separation of JUNK) can only be distinguished if both `proof-shell-start-goals-regexp' and `proof-shell-end-goals-regexp' are set. With just the start goals regexp set, GOALS-2 JUNK will appear in the goals buffer and no response output would occur. The goals and response outputs are copied into `proof-shell-last-goals-output' and `proof-shell-last-response-output' respectively. The value returned is the value for `proof-shell-last-output-kind', i.e., 'goals or 'response." (let ((start proof-shell-delayed-output-start) (end proof-shell-delayed-output-end) (flags proof-shell-delayed-output-flags)) (goto-char start) (cond ((and proof-shell-start-goals-regexp (proof-re-search-forward proof-shell-start-goals-regexp end t)) (let* ((gmark (match-beginning 0)) ; start of goals message (gstart (or (match-end 1) ; start of actual display gmark)) (rstart start) ; possible response before goals (gend end) both) ; flag for response+goals (goto-char gstart) (while (re-search-forward proof-shell-start-goals-regexp end t) (setq gmark (match-beginning 0)) (setq gstart (or (match-end 1) gmark)) (setq gend (if (and proof-shell-end-goals-regexp (re-search-forward proof-shell-end-goals-regexp end t)) (progn (setq rstart (match-end 0)) (match-beginning 0)) end))) (setq proof-shell-last-goals-output (buffer-substring-no-properties gstart gend)) ;; FIXME heuristic: 4 allows for annotation in end-goals-regexp [is it needed?] (setq both (> (- gmark rstart) 4)) (if both (proof-shell-display-output-as-response flags (buffer-substring-no-properties rstart gmark))) ;; display goals output second so it persists in 2-pane mode (unless (memq 'no-goals-display flags) (pg-goals-display proof-shell-last-goals-output both)) ;; indicate a goals output has been given 'goals)) (t (proof-shell-display-output-as-response flags proof-shell-last-output) ;; indicate that (only) a response output has been given 'response)) (run-hooks 'proof-shell-handle-delayed-output-hook))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Tracing slow down: prevent Emacs-consumes-all-CPU-displaying phenomenon ;; ;; Possible improvement: add user-controlled flag to turn on/off display (defvar pg-last-tracing-output-time (float-time) "Time of last tracing output, as recorded by (float-time).") (defvar pg-last-trace-output-count 0 "Count up to `pg-slow-mode-trigger-count'.") (defconst pg-slow-mode-trigger-count 20 "Number of fast trace messages before turning on slow mode.") (defconst pg-slow-mode-duration 3 "Maximum duration of slow mode in seconds.") (defconst pg-fast-tracing-mode-threshold 500000 "Minimum microsecond delay between tracing outputs that triggers slow mode.") (defun pg-tracing-tight-loop () "Return non-nil in case it seems like prover is dumping a lot of output. This is a performance hack to avoid Emacs consuming CPU when prover is output tracing information. Only works when system timer has microsecond count available." (let ((tm (float-time)) (dontprint pg-tracing-slow-mode)) (if pg-tracing-slow-mode (when ;; seconds differs by more than slow mode max duration (> (- tm pg-last-tracing-output-time) pg-slow-mode-duration) (setq dontprint nil)) (when ;; time since last tracing output less than threshold (and (< (- tm pg-last-tracing-output-time) (/ pg-fast-tracing-mode-threshold 1000000.0)) (>= (incf pg-last-trace-output-count) pg-slow-mode-trigger-count)) ;; quickly consecutive tracing outputs: go into slow mode (setq dontprint t) (pg-slow-fontify-tracing-hint))) ;; return flag for non-printing is new value of slow mode (setq pg-last-tracing-output-time tm) (setq pg-tracing-slow-mode dontprint))) (defun pg-finish-tracing-display () "Handle the end of possibly voluminous tracing-style output. If the output update was slowed down, show it now." (proof-trace-buffer-finish) (when pg-tracing-slow-mode (proof-display-and-keep-buffer proof-trace-buffer) (setq pg-tracing-slow-mode nil)) (setq pg-last-trace-output-count 0)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; proof-shell-invisible-command: for user-level commands. ;; ;;;###autoload (defun proof-shell-wait (&optional interrupt-on-input timeoutsecs) "Busy wait for `proof-shell-busy' to become nil, reading from prover. Needed between sequences of commands to maintain synchronization, because Proof General does not allow for the action list to be extended in some cases. Also is considerably faster than leaving the Emacs top-level command loop to read from the prover. Called by `proof-shell-invisible-command' and `proof-process-buffer' when setting `proof-fast-process-buffer' is enabled. If INTERRUPT-ON-INPUT is non-nil, return if input is received. If TIMEOUTSECS is a number, time out after that many seconds." (let* ((proverproc (get-buffer-process proof-shell-buffer)) (accepttime 0.01) (timecount (if (numberp timeoutsecs) (/ timeoutsecs accepttime)))) (when proverproc (while (and proof-shell-busy (not quit-flag) (if timecount (> (setq timecount (1- timecount)) 0) t) (not (and interrupt-on-input (input-pending-p)))) ;; TODO: check below OK on GE 22/23.1. See Trac #324 (accept-process-output proverproc accepttime nil 1)) (redisplay) (if quit-flag (error "Proof General: quit in proof-shell-wait"))))) (defun proof-done-invisible (span) "Callback for proof-shell-invisible-command. Calls proof-state-change-hook." (run-hooks 'proof-state-change-hook)) ;;;###autoload (defun proof-shell-invisible-command (cmd &optional wait invisiblecallback &rest flags) "Send CMD to the proof process. The CMD is `invisible' in the sense that it is not recorded in buffer. CMD may be a string or a string-yielding expression. Automatically add `proof-terminal-string' 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. In case CMD is (or yields) nil, do nothing. INVISIBLECALLBACK will be invoked after the command has finished, if it is set. It should probably run the hook variables `proof-state-change-hook'. FLAGS are additional flags to put onto the `proof-action-list'. The flag 'invisible is always added to FLAGS." (unless (stringp cmd) (setq cmd (eval cmd))) (if cmd (progn (unless (or (null proof-terminal-string) (not proof-shell-auto-terminate-commands) (string-match (concat (regexp-quote proof-terminal-string) "[ \t]*$") cmd)) (setq cmd (concat cmd proof-terminal-string))) (if wait (proof-shell-wait)) (proof-shell-ready-prover) ; start proof assistant; set vars. (let* ((callback (if invisiblecallback (lexical-let ((icb invisiblecallback)) (lambda (span) (funcall icb span))) 'proof-done-invisible))) (proof-start-queue nil nil (list (proof-shell-action-list-item cmd callback (cons 'invisible flags))))) (if wait (proof-shell-wait))))) ;;;###autoload (defun proof-shell-invisible-cmd-get-result (cmd) "Execute CMD and return result as a string. This expects CMD to result in some theorem prover output. Ordinary output (and error handling) is disabled, and the result \(contents of `proof-shell-last-output') is returned as a string." (proof-shell-invisible-command cmd 'waitforit nil 'no-response-display 'no-error-display) proof-shell-last-output) ;;;###autoload (defun proof-shell-invisible-command-invisible-result (cmd) "Execute CMD for side effect in the theorem prover, waiting before and after. Error messages are displayed as usual." (proof-shell-invisible-command cmd 'waitforit nil 'no-response-display)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; User-level functions depending on shell commands ;; ;; ;; 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 (let ((beg (point))) (insert (proof-shell-strip-output-markup proof-shell-last-output)) (comment-region beg (point))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Proof General shell mode definition ;; ;(eval-and-compile ; to define vars ;;;###autoload (define-derived-mode proof-shell-mode scomint-mode "proof-shell" "Proof General shell mode class for proof assistant processes" (setq proof-buffer-type 'shell) (proof-shell-clear-state) (buffer-disable-undo) ;; scomint customisation. (setq scomint-output-filter-functions (append (if proof-shell-strip-crs-from-output 'scomint-strip-ctrl-m) (list 'proof-shell-filter-wrapper))) (setq proof-marker ; follows prompt (make-marker) proof-shell-urgent-message-marker (make-marker) ; follows urgent messages proof-shell-urgent-message-scanner (make-marker)) ; last scan point (set-marker proof-shell-urgent-message-scanner (point-min)) ;; Make cut functions work with proof shell output (add-hook 'buffer-substring-filters 'proof-shell-strip-output-markup) ;; Note: before entering proof assistant specific code, we could ;; check that process is up and running. If not, could call the ;; sentinel to display the buffer, and give error. ) ;; ;; Sanity checks on important settings ;; (defconst proof-shell-important-settings '(proof-shell-annotated-prompt-regexp ; crucial )) ;;;###autoload (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." (with-current-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)) ;; Set font lock keywords, but turn off by default to save cycles. (setq font-lock-defaults '(proof-shell-font-lock-keywords)) (set (make-local-variable 'font-lock-global-modes) (list 'not proof-mode-for-shell)) (let ((proc (get-buffer-process proof-shell-buffer))) ;; Add the kill buffer function and process sentinel (add-hook 'kill-buffer-hook 'proof-shell-kill-function t t) (set-process-sentinel proc 'proof-shell-bail-out) ;; Pre-sync initialization command. Necessary for provers which ;; change 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 (memq (process-status proc) '(open run)) (null (marker-position proof-marker))) (accept-process-output proc 1)) (if (memq (process-status proc) '(open run)) (progn ;; Also ensure that proof-action-list is initialised. (setq proof-action-list nil) ;; Send main intitialization command and wait for it to be ;; processed. ;; First, configure PGIP preferences (even before init cmd) ;; available: this allows setting them after the init cmd. (proof-maybe-askprefs) ;; Now send the initialisation commands. (unwind-protect (progn (run-hooks 'proof-shell-init-hook) (when proof-shell-init-cmd (if (listp proof-shell-init-cmd) (mapc 'proof-shell-invisible-command-invisible-result proof-shell-init-cmd) (proof-shell-invisible-command-invisible-result proof-shell-init-cmd))) (proof-shell-wait) (if proof-assistant-settings (mapcar (lambda (c) (proof-shell-invisible-command c t)) (proof-assistant-settings-cmds)))))))))) (provide 'proof-shell) ;;; proof-shell.el ends here proofgeneral-4.3~pre130510/generic/proof-site.el000066400000000000000000000327441214562307500214660ustar00rootroot00000000000000;; proof-site.el -- Loading stubs for Proof General. ;; ;; Copyright (C) 1998-2003 LFCS Edinburgh. ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-site.el,v 12.28 2013/05/10 09:18:03 da Exp $ ;; ;;; Commentary: ;; ;; Loading stubs and configuration for site and choice of provers. ;; ;; NB: Normally users do not need to edit this file. Developers/installers ;; may want to adjust proof-assistant-table-default below. ;; ;; The environment variables PROOFGENERAL_HOME and PROOFGENERAL_ASSISTANTS ;; can be set to affect load behaviour; see info documentation. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Master table of supported proof assistants. ;; ;;; Code: ;; Entries in proof-assistant-table-default are lists of the form ;; ;; (SYMBOL NAME FILE-EXTENSION [AUTOMODE-REGEXP] [IGNORED-EXTENSIONS-LIST]) ;; ;; FILE-EXTENSION is without dot ".". AUTOMODE-REGEXP is put into ;; auto-mode-alist, if it is not present, a regexp will be made up from ;; FILE-EXTENSION. IGNORED-EXTENSIONS-LIST, if present, is appended to ;; completion-ignored-extensions. See proof-assistant-table for more info. ;; (defconst proof-assistant-table-default '( ;; Main instances of PG. (isar "Isabelle" "thy") (coq "Coq" "v" nil (".vo" ".glob")) (phox "PhoX" "phx") ;; Obscure instances or conflict with other Emacs modes. ;; (lego "LEGO" "l") ;; (ccc "CASL Consistency Checker" "ccc") ;; (hol-light "HOL Light" "ml") ; [for testing] ;; Cut-and-paste management only (pgshell "PG-Shell" "pgsh") (pgocaml "PG-OCaml" "pgml") (pghaskell "PG-Haskell" "pghci") ;; Incomplete/obsolete: ;; (hol98 "HOL" "sml") ;; (acl2 "ACL2" "acl2") ;; (twelf "Twelf" "elf") ;; (plastic "Plastic" "lf") ; obsolete ;; (lclam "Lambda-CLAM" "lcm") ; obsolete ;; (demoisa "Isabelle Demo" "ML") ; obsolete ) "Default value for `proof-assistant-table', which see.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PG version ;; (eval-and-compile ;; WARNING: do not edit next line (constant is edited in Makefile.devel) (defconst proof-general-version "Proof General Version 4.3pre130510. Released by da." "Version string identifying Proof General release.")) (defconst proof-general-short-version (eval-when-compile (progn (string-match "Version \\([^ ]+\\)\\." proof-general-version) (match-string 1 proof-general-version)))) (defconst proof-general-version-year "2012") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Top-level customization groups ;; (defgroup proof-general nil "Customization of Proof General." :group 'applications :prefix "proof-") (defgroup proof-general-internals nil "Customization of Proof General internals for proof assistant configuration." :group 'applications :group 'proof-general :prefix "proof-") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Directories. Set at load time so compiled files can be relocated. ;; Load path must be extended manually during compilation. ;; (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) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; load path. Have one function that adds elements to load-path. ;; Distributions having specific requirements (such as using ;; debian-pkg-add-load-path-item on Debian) only need to change ;; this function. ;; (defun proof-add-to-load-path (dir) "Add DIR to `load-path' if not contained already" (add-to-list 'load-path dir)) (proof-add-to-load-path (concat proof-home-directory "generic/")) (proof-add-to-load-path (concat proof-home-directory "lib/")) ;; Declare some global variables and autoloads (require 'pg-vars) (require 'proof-autoloads) (eval-when-compile (defvar Info-dir-contents nil)) ;; Add the info directory to the Info path (if (file-exists-p proof-info-directory) ; for safety (if (and (boundp 'Info-directory-list) Info-directory-list) ;; Info is already initialized. Update its variables. (progn (add-to-list 'Info-directory-list proof-info-directory) (setq Info-dir-contents nil)) ;; Info is not yet initialized. Change its default. (add-to-list 'Info-default-directory-list proof-info-directory))) (defcustom proof-assistant-table (apply 'append (mapcar ;; Discard entries whose directories have been removed. (lambda (dne) (let ((atts (file-attributes (concat proof-home-directory (symbol-name (car dne)))))) (if (and atts (eq 't (car atts))) (list dne) nil))) proof-assistant-table-default)) "*Proof General's table of supported proof assistants. This is copied from `proof-assistant-table-default' at load time, removing any entries that do not have a corresponding directory under `proof-home-directory'. Each entry is a list of the form (SYMBOL NAME FILE-EXTENSION [AUTOMODE-REGEXP] [IGNORED-EXTENSIONS-LIST]) 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 \(or with extension FILE-EXTENSION) are visited. If present, IGNORED-EXTENSIONS-LIST is a list of file-name extensions to be ignored when doing file-name completion (IGNORED-EXTENSIONS-LIST is added to completion-ignored-extensions). 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'." ;; FIXME: make the last two elements optional in the type :type '(repeat (list symbol string regexp string)) :group 'proof-general-internals) (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)) ".\nIf nil, the default will be ALL available proof assistants. 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 `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 (nth 1 astnt) (nth 0 astnt))) proof-assistant-table)) :group 'proof-general) ;;;###autoload (defun proof-ready-for-assistant (assistantsym &optional assistant-name) "Configure PG for symbol ASSISTANTSYM, name ASSISTANT-NAME. If ASSISTANT-NAME is omitted, look up in `proof-assistant-table'." (unless proof-assistant-symbol (let* ((sname (symbol-name assistantsym)) (assistant-name (or assistant-name (car-safe (cdr-safe (assoc assistantsym proof-assistant-table))) sname)) (cusgrp-rt ;; Normalized a bit to remove spaces and funny characters (replace-regexp-in-string "/\\|[ \t]+" "-" (downcase assistant-name))) (cusgrp (intern cusgrp-rt)) (cus-internals (intern (concat cusgrp-rt "-config"))) (elisp-dir sname) ; NB: dirname same as symbol name! (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)) ;; define the per-prover settings which depend on above (require 'pg-custom) (setq proof-mode-for-shell (proof-ass-sym shell-mode)) (setq proof-mode-for-response (proof-ass-sym response-mode)) (setq proof-mode-for-goals (proof-ass-sym goals-mode)) (setq proof-mode-for-script (proof-ass-sym mode)) ;; Extend the load path if necessary (proof-add-to-load-path ,loadpath-elt) ;; Run hooks for late initialisation (run-hooks 'proof-ready-for-assistant-hook)))))) (defvar proof-general-configured-provers (or (mapcar 'intern (split-string (or (getenv "PROOFGENERAL_ASSISTANTS") ""))) proof-assistants (mapcar (lambda (astnt) (car astnt)) proof-assistant-table)) "A list of the configured proof assistants. Set on startup to contents of environment variable PROOFGENERAL_ASSISTANTS, the lisp variable `proof-assistants', or the contents of `proof-assistant-table'.") ;; Add auto-loads and load-path elements to support the ;; proof assistants selected, and define stub major mode functions (let ((assistants proof-general-configured-provers)) (while assistants (let* ((assistant (car assistants)) ; compiler bogus warning here (tableentry (or (assoc assistant proof-assistant-table) (error "Symbol %s is not in proof-assistant-table (in proof-site)" (symbol-name assistant)))) (assistant-name (nth 1 tableentry)) (regexp (or (nth 3 tableentry) (concat (regexp-quote ".") (regexp-quote (nth 2 tableentry)) "\\'"))) (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 -mode! (proofgen-mode (intern (concat sname "-mode"))) ;; NB: Customization group for each prover is its l.c.'d name! ;; Stub to initialize and load 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) ;; Stop loading if proof-assistant is already set: ;; cannot work 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 (quote ,assistant) ,assistant-name) ;; 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) (dolist (ext (nth 4 tableentry)) (add-to-list 'completion-ignored-extensions ext)) (setq assistants (cdr assistants))))) ;; ;; Easy entry points ;; (defun proof-chose-prover (prompt) (completing-read prompt (mapcar 'symbol-name proof-general-configured-provers))) (defun proofgeneral (prover) "Start proof general for prover PROVER." (interactive (list (proof-chose-prover "Start Proof General for theorem prover: "))) (proof-ready-for-assistant (intern prover) (nth 1 (assoc (intern prover) proof-assistant-table-default))) (require (intern prover))) (defun proof-visit-example-file (prover) "Visit a standardly named example file for prover PROVER." (interactive (list (proof-chose-prover "Visit example file for prover: "))) (find-file (concat proof-home-directory prover "/example." (nth 2 (assoc (intern prover) proof-assistant-table-default))))) (provide 'proof-site) ;;; proof-site.el ends here proofgeneral-4.3~pre130510/generic/proof-splash.el000066400000000000000000000264341214562307500220130ustar00rootroot00000000000000;; proof-splash.el -- Splash welcome screen for Proof General ;; ;; Copyright (C) 1998-2005, 2009, 2010 LFCS Edinburgh. ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-splash.el,v 12.2 2012/01/14 12:50:48 tews Exp $ ;; ;; ;;; Commentary: ;; ;; Provide splash screen for Proof General. ;; ;; The idea is to have a replacement for the usual splash screen. ;; This is slightly tricky: 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. ;; ;;; Code: (require 'proof-site) ;; ;; Customization of splash screen ;; (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 8 "Minimum number of seconds to display splash screen for. The splash screen may be displayed for a wee while 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 (proof-get-image "pg-text" t) nil (proof-get-image "ProofGeneral") nil "Welcome to" (concat proof-assistant " Proof General!") nil (concat "Version " proof-general-short-version ".") nil (concat "(C) LFCS, University of Edinburgh " proof-general-version-year) nil nil :link '(" Read the " "Proof General documentation" (lambda (button) (info "ProofGeneral"))) :link '(" Please report problems at " "Proof General trac" (lambda (button) (browse-url "http://proofgeneral.inf.ed.ac.uk/trac")) "Report bugs at http://proofgeneral.inf.ed.ac.uk/trac") :link '("Visit the " "Proof General wiki" (lambda (button) (browse-url "http://proofgeneral.inf.ed.ac.uk/wiki")) "Write lots of helpful things at http://proofgeneral.inf.ed.ac.uk/wiki") :link '("or the " "homepage" (lambda (button) (browse-url "http://proofgeneral.inf.ed.ac.uk/")) "Browse http://proofgeneral.inf.ed.ac.uk/") nil :link '("Find out about Emacs on the Help menu -- start with the " "Emacs Tutorial" (lambda (button) (help-with-tutorial))) nil "See this screen again with Proof-General -> About" ) "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) (defconst proof-splash-startup-msg '(if (featurep 'proof-config) nil ;; Display additional hint if we guess we're being loaded ;; by shell script rather than find-file. '(list "To start using Proof General, visit a proof script file" "for your prover, using C-x C-f or the File menu.")) "Additional form evaluated and put onto splash screen.") (defconst proof-splash-welcome "*Proof General Welcome*" "Name of the Proof General splash buffer.") (define-derived-mode proof-splash-mode fundamental-mode "Splash" "Mode for splash. \\{proof-splash-mode-map}" (set-buffer-modified-p nil) (setq buffer-read-only t)) (define-key proof-splash-mode-map "q" 'bury-buffer) (define-key proof-splash-mode-map [mouse-3] 'bury-buffer) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defsubst proof-emacs-imagep (img) "See if IMG is an Emacs image descriptor." (and (listp img) (eq (car img) 'image))) (defun proof-get-image (name &optional nojpeg default) "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, then xpm. Gif filename depends on colour depth of display. DEFAULT gives return value in case image not valid." (let ((jpg (vector 'jpeg :file (concat proof-images-directory name ".jpg"))) (gif (vector 'gif :file (concat proof-images-directory ".gif"))) img) (cond (window-system (find-image (list (list :type 'jpeg :file (concat proof-images-directory name ".jpg")) (list :type 'gif :file (concat proof-images-directory name ".gif"))))) (t (or default (concat "[ image " name " ]")))))) (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))) ((proof-emacs-imagep glyph) (car (with-no-warnings ; image-size not available in tty emacs (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. ;; NB: not as polite as it could be: if minibuffer is active, ;; this may deactivate it. ;; NB2: There is something worse here: pending input ;; causes this function to spoil the mode startup, if the splash ;; buffer is killed before the input has been processed. ;; Symptom is ProofGeneral mode instead of the native script mode. ;; (defun proof-splash-remove-screen (&optional nothing) "Remove splash screen and restore window config." (let ((splashbuf (get-buffer proof-splash-welcome))) (proof-splash-unset-frame-titles) (if (and splashbuf proof-splash-timeout-conf) (progn (if (get-buffer-window splashbuf) ;; Restore the window config if splash is being displayed (if (cdr proof-splash-timeout-conf) (set-window-configuration (cdr proof-splash-timeout-conf)))) ;; Indicate removed splash screen; disable timeout (disable-timeout (car proof-splash-timeout-conf)) (setq proof-splash-timeout-conf nil) (proof-splash-remove-buffer))))) (defun proof-splash-remove-buffer () "Remove the splash buffer if it's still present." (let ((splashbuf (get-buffer proof-splash-welcome))) (if splashbuf ;; Kill should be right, but it can cause core dump ;; on XEmacs (kill-buffer splashbuf) (TODO: check Emacs now) (if (eq (selected-window) (window-buffer (selected-window))) (bury-buffer splashbuf))))) (defvar proof-splash-seen nil "Flag indicating the user has been subjected to a welcome message.") (defun proof-splash-insert-contents () "Insert splash buffer contents into current buffer." (let* ((splash-contents (append (eval proof-splash-contents) (eval proof-splash-startup-msg))) s) (setq buffer-read-only nil) (erase-buffer) (while splash-contents (setq s (car splash-contents)) (cond ((proof-emacs-imagep s) (indent-to (proof-splash-centre-spaces s)) (insert-image s)) ((eq s :link) (setq splash-contents (cdr splash-contents)) (let ((spec (car splash-contents))) (if (functionp spec) (setq spec (funcall spec))) (indent-to (proof-splash-centre-spaces (concat (car spec) (cadr spec)))) (insert (car spec)) (insert-button (cadr spec) 'face (list 'link) 'action (nth 2 spec) 'help-echo (concat "mouse-2, RET: " (or (nth 3 spec) "Follow this link")) 'follow-link t))) ((stringp s) (indent-to (proof-splash-centre-spaces s)) (insert s))) (newline) (setq splash-contents (cdr splash-contents))) (goto-char (point-min)) (proof-splash-mode))) ;;;###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, make a key binding to remove this buffer." (interactive "P") (proof-splash-set-frame-titles) (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)) (curwin (get-buffer-window (current-buffer))) (curfrm (and curwin (window-frame curwin))) (after-change-functions nil) ; no font-lock, thank-you. ;; NB: maybe leave next one in for frame-crazy folk ;;(pop-up-frames nil) ; display in the same frame. (splashbuf (get-buffer-create proof-splash-welcome))) (with-current-buffer splashbuf (proof-splash-insert-contents) (let* ((splashwin (display-buffer splashbuf)) (splashfm (window-frame splashwin)) ;; Only save window config if we're on same frame (savedwincnf (if (eq curfrm splashfm) winconf))) (delete-other-windows splashwin) (when timeout (setq proof-splash-timeout-conf (cons (add-timeout proof-splash-time 'proof-splash-remove-screen nil) savedwincnf)) (add-hook 'proof-mode-hook 'proof-splash-timeout-waiter)))) (setq proof-splash-seen t))) (defalias 'pg-about 'proof-splash-display-screen) ;;;###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 (progn ;; disable ordinary emacs splash (setq inhibit-startup-message t) (proof-splash-display-screen (not (called-interactively-p 'any)))) ;; 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 proof-splash-timeout-conf ;; timeout still active (not (input-pending-p))) (sit-for 0.1)) (if proof-splash-timeout-conf ;; not removed yet (proof-splash-remove-screen)) (if (fboundp 'next-command-event) ; 3.3: Emacs removed this (if (input-pending-p) (setq unread-command-events (cons (next-command-event) unread-command-events)))) (remove-hook 'proof-mode-hook 'proof-splash-timeout-waiter)) (defvar proof-splash-old-frame-title-format nil) (defun proof-splash-set-frame-titles () (let ((instance-name (concat (if (not (zerop (length proof-assistant))) (concat proof-assistant " ")) "Proof General"))) (setq proof-splash-old-frame-title-format frame-title-format) (setq frame-title-format (concat instance-name ": %b")))) (defun proof-splash-unset-frame-titles () (when proof-splash-old-frame-title-format (setq frame-title-format proof-splash-old-frame-title-format) (setq proof-splash-old-frame-title-format nil))) (provide 'proof-splash) ;;; proof-splash.el ends here proofgeneral-4.3~pre130510/generic/proof-syntax.el000066400000000000000000000275241214562307500220500ustar00rootroot00000000000000;; proof-syntax.el --- Functions for dealing with syntax ;; ;; Copyright (C) 1997-2001, 2010 LFCS Edinburgh. ;; Authors: David Aspinall, Healfdene Goguen, ;; Thomas Kleymann, Dilip Sequiera ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-syntax.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; (require 'font-lock) (require 'proof-config) ; proof-case-fold-search (require 'proof-compat) ; proof-buffer-syntactic-context (require 'pg-pamacs) ; proof-ass-sym ;;; Commentary: ;; ;;; Code: (defsubst proof-ids-to-regexp (l) "Maps a non-empty list of tokens L to a regexp matching any element. Uses a regexp of the form \\_<...\\_>." (concat "\\_<\\(?:" (regexp-opt l) ; was: (mapconcat 'identity l "\\|") "\\)\\_>")) (defsubst proof-anchor-regexp (e) "Anchor (\\`) and group the regexp E." (concat "\\`\\(" e "\\)")) (defconst proof-no-regexp "\\<\\>" "A regular expression that never matches anything.") (defsubst proof-regexp-alt (&rest args) "Return the regexp which matches any of the regexps ARGS." ;; see regexp-opt (NB: but that is for strings, not regexps) (let ((res "")) (dolist (regexp args) (setq res (concat res (if (string-equal res "") "\\(?:" "\\|\\(?:") regexp "\\)"))) res)) (defsubst proof-regexp-alt-list (args) "Return the regexp which matches any of the regexps ARGS." (apply 'proof-regexp-alt args)) (defsubst 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. (defsubst proof-search-forward (string &optional bound noerror count) "Like search-forward, but set case-fold-search to proof-case-fold-search." (let ((case-fold-search proof-case-fold-search)) (search-forward string bound noerror count))) ;;;###autoload (defsubst proof-replace-regexp-in-string (regexp rep string) "Like replace-regexp-in-string, but set case-fold-search to proof-case-fold-search." (let ((case-fold-search proof-case-fold-search)) (replace-regexp-in-string regexp rep string))) (defsubst 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))) (defsubst 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))) (defsubst proof-re-search-forward-safe (regexp &optional bound noerror count) "Like re-search-forward, but set case-fold-search to proof-case-fold-search." (and regexp (let ((case-fold-search proof-case-fold-search)) (re-search-forward regexp bound noerror count)))) (defsubst 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))) (defsubst proof-string-match-safe (regexp string &optional start) "Like `string-match', but return nil if REGEXP or STRING is nil." (if (and regexp string) (proof-string-match regexp string start))) (defsubst 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)))) (defsubst 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))) (defsubst proof-looking-at-safe (regexp) "Like `proof-looking-at', but return nil if REGEXP is nil." (if regexp (proof-looking-at regexp))) ;; ;; Syntactic context ;; ;; A function named after one in XEmacs (defun proof-buffer-syntactic-context (&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 (syntax-ppss))) ;;(parse-partial-sexp (point-min) (point)))) (cond ((nth 3 pp) 'string) ;; ((nth 7 pp) 'block-comment) ;; "Stefan Monnier" suggests ;; distinguishing between block comments and ordinary comments ;; is problematic: not what XEmacs claims and different to what ;; (nth 7 pp) tells us in GNU Emacs. ((nth 4 pp) 'comment))))) (defsubst proof-looking-at-syntactic-context-default () "Default function for `proof-looking-at-syntactic-context'." (or (proof-buffer-syntactic-context) (save-match-data (when (proof-looking-at-safe proof-script-comment-start-regexp) 'comment)) (save-match-data (when (proof-looking-at-safe proof-string-start-regexp) 'string)))) (defun proof-looking-at-syntactic-context () "Determine if current point is at beginning or within comment/string context. If so, return a symbol indicating this ('comment or 'string). This function invokes if that is defined, otherwise it calls `proof-looking-at-syntactic-context'." (if (fboundp (proof-ass-sym syntactic-context)) (funcall (proof-ass-sym syntactic-context)) (proof-looking-at-syntactic-context-default))) (defun proof-inside-comment (pos) "Return non-nil if POS is inside a comment." (save-excursion (goto-char pos) (eq (proof-buffer-syntactic-context) 'comment))) (defun proof-inside-string (pos) "Return non-nil if POS is inside a comment." (save-excursion (goto-char pos) (eq (proof-buffer-syntactic-context) 'string))) ;; ;; Replacing matches ;; (defsubst proof-replace-string (string to-string) "Non-interactive `replace-string', using `proof-case-fold-search'." (while (proof-search-forward string nil t) (replace-match to-string nil t))) (defsubst proof-replace-regexp (regexp to-string) "Non-interactive `replace-regexp', using `proof-case-fold-search'." (while (proof-re-search-forward regexp nil t) (replace-match to-string nil nil))) (defsubst proof-replace-regexp-nocasefold (regexp to-string) "Non-interactive `replace-regexp', forcing `case-fold-search' to nil." (let ((case-fold-search nil)) (while (proof-re-search-forward regexp nil t) (replace-match to-string nil nil)))) ;; ;; 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-zap-commas}. (defsubst 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 "\\)*")) (defun proof-zap-commas (limit) "Remove the face of all `,' from point to LIMIT. Meant to be used from `font-lock-keywords' as a way 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 ways of doing this were even more bogus...." (while (proof-search-forward "," limit t) (if (memq (get-text-property (1- (point)) 'face) '(proof-declaration-name-face font-lock-variable-name-face font-lock-function-name-face)) (put-text-property (1- (point)) (point) 'face nil)))) ;; ;; Font lock: providing an alternative syntactic fontify ;; region function. ;; ;; The hook font-lock-fontify-region-function is tempting but not ;; really a convenient place. We just want to replace the syntactic ;; fontification function. ;; (eval-after-load "font-lock" '(progn (defadvice font-lock-fontify-keywords-region (before font-lock-fontify-keywords-advice (beg end loudly)) "Call proof assistant specific syntactic region fontify. If it's bound, we call -font-lock-fontify-syntactically-region." (when (and proof-buffer-type (fboundp (proof-ass-sym font-lock-fontify-syntactically-region))) (funcall (proof-ass-sym font-lock-fontify-syntactically-region) beg end loudly))) (ad-activate 'font-lock-fontify-keywords-region))) ;; ;; Functions for doing something like "format" but with customizable ;; control characters. ;; ;;;###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. ;; ; 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) ; (scomint-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)))) (provide 'proof-syntax) ;;; proof-syntax.el ends here proofgeneral-4.3~pre130510/generic/proof-toolbar.el000066400000000000000000000210441214562307500221530ustar00rootroot00000000000000;;; proof-toolbar.el --- Toolbar for Proof General ;; ;; Copyright (C) 1998-2009 David Aspinall / LFCS. ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-toolbar.el,v 12.3 2012/07/15 08:58:14 da Exp $ ;; ;;; Commentary: ;; ;; 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. ;; ;; See `proof-toolbar-entries-default' and `-toolbar-entries' ;; in pg-custom.el for the default generic toolbar and ;; the per-prover toolbar contents variable. ;; ;;; Code: (eval-and-compile (require 'span) (require 'proof-utils) (require 'proof-config) (require 'tool-bar)) ; needed for some emacsen without X ;; ;; Function, icon, button names ;; (defun proof-toolbar-function (token) "Construct name of toolbar function for TOKEN." (intern (concat "proof-toolbar-" (symbol-name token)))) (defun proof-toolbar-icon (token) "Construct name of toolbar icon for TOKEN." (intern (concat "proof-toolbar-" (symbol-name token) "-icon"))) (defun proof-toolbar-enabler (token) "Construct name of toolbar enabler for TOKEN." (intern (concat "proof-toolbar-" (symbol-name token) "-enable-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)) (toolbarp (nth 3 tle)) (iconname (symbol-name icon)) (iconvar (proof-toolbar-icon icon))) (when toolbarp (set iconvar (concat "epg-" iconname))))) (defun proof-toolbar-make-toolbar-items (map tles) "Make toolbar button descriptors from a PA-toolbar-entries entry." ;; Entry format: (TOKEN MENUNAME TOOLTIP TOOLBAR-P [VISIBLE-P]) (dolist (tle tles) (let* ((token (nth 0 tle)) (longtoken (intern (symbol-name token))) (includep (nth 3 tle)) (visiblep (nth 4 tle)) (icon (proof-toolbar-icon token)) (buttonfn (proof-toolbar-function token)) (enabler (proof-toolbar-enabler token)) (tooltip (and includep (nth 2 tle))) (props (append (list :help tooltip) (if (fboundp enabler) (list :enable (list enabler))) (if visiblep (list :visible visiblep))))) (if (eval includep) (apply 'tool-bar-local-item (eval icon) buttonfn longtoken map props))))) ;; ;; Code for displaying and refreshing toolbar ;; (defvar proof-toolbar-map nil "Proof mode toolbar button list. Set in `proof-toolbar-setup'.") (defun proof-toolbar-available-p () "Check if toolbar support is available in this Emacs." (and window-system (featurep 'tool-bar) ;; GNU Emacs tool-bar library (or (image-type-available-p 'xpm) ;; and XPM (image-type-available-p 'png)))) ;; or PNG ;;;###autoload (defun proof-toolbar-setup () "Initialize Proof General toolbar and enable it for all PG buffers. If `proof-toolbar-enable' is nil, change the buffer toolbars back the default toolbar." (interactive) (when (proof-toolbar-available-p) (unless proof-toolbar-map (setq proof-toolbar-map (make-sparse-keymap)) (if (boundp 'image-load-path) (add-to-list 'image-load-path proof-images-directory)) ; rude? (mapc 'proof-toolbar-make-icon (proof-ass toolbar-entries)) (proof-toolbar-make-toolbar-items proof-toolbar-map (proof-ass toolbar-entries))) (proof-map-buffers (append (proof-buffers-in-mode proof-mode-for-script) (proof-associated-buffers)) (when proof-toolbar-enable (set (make-local-variable 'tool-bar-map) proof-toolbar-map)) (when (not proof-toolbar-enable) (kill-local-variable 'tool-bar-map))))) (defun proof-toolbar-enable () "Take action when the toolbar is enabled or disabled." (proof-toolbar-setup) (redraw-display)) ;;;###autoload (autoload 'proof-toolbar-toggle "proof-toolbar") (proof-deftoggle proof-toolbar-enable proof-toolbar-toggle) ;; ;; ;; Proof General Toolbar and Scripting Menu 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 ;; ;; If no -enable function is defined, button is always enabled. ;; ;; To add support for more buttons or alter the default ;; images, -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 (defalias 'proof-toolbar-undo 'proof-undo-last-successful-command) (defun proof-toolbar-undo-enable-p () (proof-with-script-buffer (and (proof-shell-available-p) (> (proof-unprocessed-begin) (point-min))))) ;; Delete (defalias 'proof-toolbar-delete 'proof-undo-and-delete-last-successful-command) (defun proof-toolbar-delete-enable-p () (proof-with-script-buffer (and (not buffer-read-only) (proof-shell-available-p) (> (proof-unprocessed-begin) (point-min))))) ;; Home (defalias 'proof-toolbar-home 'proof-goto-end-of-locked) ;; Next (defalias 'proof-toolbar-next 'proof-assert-next-command-interactive) (defun proof-toolbar-next-enable-p () (proof-with-script-buffer (not (proof-locked-region-full-p)))) ;; Goto (defalias 'proof-toolbar-goto 'proof-goto-point) (defun proof-toolbar-goto-enable-p () (eq proof-buffer-type 'script)) ;; Retract (defalias 'proof-toolbar-retract 'proof-retract-buffer) (defun proof-toolbar-retract-enable-p () (proof-with-script-buffer (not (proof-locked-region-empty-p)))) ;; Use (defalias 'proof-toolbar-use 'proof-process-buffer) (defalias 'proof-toolbar-use-enable-p 'proof-toolbar-next-enable-p) ;; Prooftree (defalias 'proof-toolbar-prooftree 'proof-tree-external-display-toggle) ;; Restart (defalias 'proof-toolbar-restart 'proof-shell-restart) ;; Goal (defalias 'proof-toolbar-goal 'proof-issue-goal) ;; QED (defalias 'proof-toolbar-qed 'proof-issue-save) (defun proof-toolbar-qed-enable-p () (proof-with-script-buffer (and proof-save-command proof-shell-proof-completed (proof-shell-available-p)))) ;; State (defalias 'proof-toolbar-state 'proof-prf) (defalias 'proof-toolbar-state-enable-p 'proof-shell-available-p) ;; Context (defalias 'proof-toolbar-context 'proof-ctxt) (defalias 'proof-toolbar-context-enable-p 'proof-shell-available-p) ;; Command (defalias 'proof-toolbar-command 'proof-minibuffer-cmd) (defalias 'proof-toolbar-command-enable-p 'proof-shell-available-p) ;; Help (I was an alias for this) (defun proof-toolbar-help () (interactive) (info "ProofGeneral")) ;; Find (defalias 'proof-toolbar-find 'proof-find-theorems) (defalias 'proof-toolbar-find-enable-p 'proof-shell-available-p) ;; Info (defalias 'proof-toolbar-info 'proof-query-identifier) (defalias 'proof-toolbar-info-enable-p 'proof-shell-available-p) ;; Visibility (not on toolbar) (defalias 'proof-toolbar-visibility 'pg-toggle-visibility) (defun proof-toolbar-visibility-enable-p () (span-property-safe (span-at (point) 'type) 'idiom)) ;; Interrupt (defalias 'proof-toolbar-interrupt 'proof-interrupt-process) (defun proof-toolbar-interrupt-enable-p () proof-shell-busy) ;; ;; Scripting Menu ;; ;; TODO: pass in map argument, don't use easymenu. ;;;###autoload (defun proof-toolbar-scripting-menu () "Menu made from the Proof General toolbar commands." (let (menu) (dolist (tle (proof-ass toolbar-entries)) ;; Entry format: (TOKEN MENUNAME TOOLTIP TOOLBAR-P VISIBLE-P) (let* ((token (car tle)) (menuname (cadr tle)) (tooltip (nth 2 tle)) (visiblep (nth 4 tle)) (enabler (proof-toolbar-enabler token)) (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))) (when (and menuname (eval visiblep)) (setq menu (cons (vconcat (vector menuname fnval :help tooltip) (if (fboundp enabler) ;; NB: :active not :enable, for easymenu (vector :active (list (proof-toolbar-enabler token)))) (if visiblep (vector :visible visiblep))) menu))))) (reverse menu))) (provide 'proof-toolbar) ;;; proof-toolbar.el ends here proofgeneral-4.3~pre130510/generic/proof-tree.el000066400000000000000000001447261214562307500214650ustar00rootroot00000000000000;;; tree-tree.el --- Proof General prooftree communication. ;; ;; Copyright (C) 2012 Hendrik Tews ;; Authors: Hendrik Tews ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-tree.el,v 12.8 2013/01/21 14:13:56 tews Exp $ ;; ;;; Commentary: ;; ;; Generic code for the communication with prooftree. Prooftree ;; is an ocaml-gtk program that displays proof trees. ;; ;; The main problem with proof tree visualization is that Coq (and ;; probably other proof assistants as well) does not provide any ;; information about which subgoals are new and have been created by ;; the last proof command and which subgoals stem from older proof ;; commands. ;; ;; To solve this problem prooftree relies on unique identification ;; strings of goals, which are called goal or sequent ID's in the ;; code. With these ID's it is easy to keep track which goals are new. ;; ;; A second problem is that, for an undo command, Coq (and probably ;; other proof assistants as well) does not tell which subgoals and ;; which finished branches must be deleted. Therefore prooftree needs ;; a continuously increasing proof state number and keeps a complete ;; undo history for every proof. ;; ;; A third problem is that Coq (and probably other proof assistants as ;; well) is not able to generate the information for a proof tree in ;; the middle of a proof. Therefore, if the user wants to start the ;; proof-tree display in the middle of the proof, it is necessary to ;; retract to the start of the proof and then to reassert to the ;; previous end of the locked region. To achieve this, one has to call ;; `accept-process-output' at suitable points to let Proof General ;; process the `proof-action-list'. ;; ;; A fourth problem is that proof-tree display can only work when the ;; prover output is not suppressed (via `proof-full-annotation'). ;; `proof-shell-should-be-silent' takes care of that. ;; ;; The design of Prooftree, of the glue code inside Proof General ;; (mostly in this file) and of the communication protocol tries to ;; achieve the following two goals: ;; ;; * Functionality is preferably transferred into prooftree, to ;; enlarge Proof General not unnecessarily. ;; ;; * To avoid synchronization trouble the communication between ;; Proof General and prooftree is almost one way only: Only Proof ;; General sends display or undo commands to Prooftree. Prooftree ;; never requests any proof-state information from Proof General. ;; Prooftree only sends a quit message to Proof General when the ;; user closes the proof-tree display of the current proof. This ;; goal requires that some of the heuristics, which decide which ;; subgoals are new and which have to be refreshed, have to be ;; implemented here. ;; ;; In general the glue code here works on the delayed output. That is, ;; the glue code here runs when the next proof command has already ;; been sent to the proof assistant. The glue code makes a light ;; analysis on the output of the proof assistant, extracts the ;; necessary parts with regular expressions and sends appropriate ;; commands to prooftree. This is achieved by calling the main entry ;; here, the function `proof-tree-handle-delayed-output' from the ;; proof shell filter function after `proof-shell-exec-loop' has ;; finished. ;; ;; However, some aspects can not be delayed. Those are treated by ;; `proof-tree-urgent-action'. Its primary use is for inserting ;; special goal-displaying commands into `proof-action-list' before ;; the next real proof command runs. For Coq this needs to be done for ;; newly generated subgoals and for goals that contain an existential ;; variable that got instantiated in the last proof step. ;; ;; Actually, for every proof, Prooftree can display a set of disjunct ;; proof trees, which are organized into layers. More than one proof ;; tree in more than one layer is needed to support the Grap ;; Existential Variables command in Coq. There is one proof tree in ;; the first layer for the original goal. The second layer contains ;; all the goals that the first Grab Existential Variables command ;; created from uninstantiated existential variabes in the main proof. ;; The third layer contains the goals that the second Grap Existential ;; Variables created. ;;; Code: (require 'cl) (eval-when (compile) (require 'proof-shell)) ;; ;; User options ;; (defgroup proof-tree () "Customization for the proof tree visualizer" :group 'proof-general :package-version '(ProofGeneral . "4.2")) (defcustom proof-tree-program (proof-locate-executable "prooftree" t nil) "Command to invoke prooftree." :type 'string :group 'proof-tree) (defcustom proof-tree-arguments () "Command line arguments for prooftree." :type '(repeat string) :group 'proof-tree) ;; ;; Proof assistant options ;; (defgroup proof-tree-internals () "Proof assistant specific customization of prooftree." :group 'proof-general-internals :package-version '(ProofGeneral . "4.2")) ;; defcustom proof-tree-configured is in proof-config.el, because it is ;; needed in pg-custom.el (defcustom proof-tree-ignored-commands-regexp nil "Commands that should be ignored for the prooftree display. The output of commands matching this regular expression is not sent to prooftree. It should match commands that display additional information but do not make any proof progress. Leave at nil to act on all commands. For Coq this regular expression should contain all commands such as Lemma, that can start a proof." :type '(choice regexp (const nil)) :group 'proof-tree-internals) (defcustom proof-tree-navigation-command-regexp nil "Regexp to match a navigation command. A navigation command typically focusses on a different open goal without changing any of the open goals. Leave at nil if there are no navigation commands." :type '(choice regexp (const nil)) :group 'proof-tree-internals) (defcustom proof-tree-cheating-regexp nil "Regexp to match cheating proofer commands. A cheating command finishes the current goal without proving it to permit the user to first focus on other parts of the development. Examples are \"sorry\" in Isabelle and \"admit\" in Coq. Leave at nil if there are no cheating commands." :type '(choice regexp (const nil)) :group 'proof-tree-internals) (defcustom proof-tree-new-layer-command-regexp nil "Regexp to match proof commands that add new goals to a proof. This regexp must match the command that turns the proof assistant into prover mode, which adds the initial goal to the proof. It must further match commands that add additional goals after all previous goals have been proved." :type 'regexp :group 'proof-tree-internals) (defcustom proof-tree-current-goal-regexp nil "Regexp to match the current goal and its ID. The regexp is matched against the output of the proof assistant to extract the current goal with its ID. The regexp must have 2 grouping constructs, the first one matches just the ID, the second one the complete sequent text that is to be sent to prooftree." :type 'regexp :group 'proof-tree-internals) (defcustom proof-tree-update-goal-regexp nil "Regexp to match a goal and its ID. The regexp is matched against the output of additional show-goal commands inserted by Proof General with a command returned by `proof-tree-show-sequent-command'. Proof General inserts such commands to update the goal text in prooftree. This is necessary, for instance, when existential variables get instantiated. This regexp must have 2 grouping constructs, the first matching the ID of the goal, the second the complete sequent text." :type 'regexp :group 'proof-tree-internals) (defcustom proof-tree-additional-subgoal-ID-regexp nil "Regular expression to match ID's of additional subgoals. This regexp is used to extract the ID's of all additionally open goals. The regexp is used in a while loop and must match one subgoal ID with subgroup 1." :type 'regexp :group 'proof-tree-internals) (defcustom proof-tree-existential-regexp nil "Regexp to match existential variables. Existential variables exist for instance in Isabelle/Hol and in Coq. They are placeholders for terms that might (for Coq they must) get instantiated in a later stage of the proof. This regexp should match one existential variable in subgroup 1. It is used inside a while loop to extract all existential variables from the goal text or from a list of existential variables. Leave this variable at nil for proof assistants that do not have existential variables." :type '(choice regexp (const nil)) :group 'proof-tree-internals) (defcustom proof-tree-existentials-state-start-regexp nil "Regexp to match the start of the state display of existential variables. Together with `proof-tree-existentials-state-end-regexp', this regular expression is used to determine the state display of existential variables, which contains information about which existentials are still uninstantiated and about dependencies of instantiated existential variables. Leave this variable nil, if there is no such state display." :type '(choice regexp (const nil)) :group 'proof-tree-internals) (defcustom proof-tree-existentials-state-end-regexp nil "Regexp to match the end of the state display of existential variables. Together with `proof-tree-existentials-state-start-regexp', this regular expression is used to determine the state display of existential variables, which contains information about which existentials are still uninstantiated and about dependencies of instantiated existential variables. If this variable is nil (and if `proof-tree-existentials-state-start-regexp' is non-nil), then the state display expands to the end of the prover output." :type '(choice regexp (const nil)) :group 'proof-tree-internals) (defcustom proof-tree-branch-finished-regexp nil "Regexp to recognize that the current branch has been finished. This must match in precisely the following cases: - The current branch has been finished but there is no current open subgoal because the prover has not switched to the next subgoal. - The last open goal has been proved. " :type 'regexp :group 'proof-tree-internals) (defcustom proof-tree-get-proof-info nil "Proof assistant specific function for information about the current proof. This function takes no arguments. It must return a list, which contains, in the following order: * the current state number (as positive integer) * the name of the current proof (as string) or nil The state number is used to implement undo in prooftree. The proof name is used to distinguish different proofs inside prooftree. The state number is interpreted as the state that has been reached after the last command has been processed. It must be consistent in the following sense. Firstly, it must be strictly increasing for successive commands that can be individually retracted. Secondly, the state number reported after some command X has been processed must be strictly greater than the state reported when X is retracted. Finally, state numbers of commands preceding X must be less than or equal the state reported when X is retracted (but no stuff before X)." :type 'function :group 'proof-tree-internals) (defcustom proof-tree-extract-instantiated-existentials nil "Proof assistant specific function for instantiated existential variables. This function must only be defined if the prover has existential variables, that is, if `proof-tree-existential-regexp' is non-nil. If defined, this function should return the list of currently instantiated existential variables as a list of strings. The function is called with `proof-shell-buffer' as current buffer and with two arguments start and stop, which designate the region containing the last output from the proof assistant. `proof-tree-extract-list' might be useful for writing this function." :type '(choice function (const nil)) :group 'proof-tree-internals) (defcustom proof-tree-show-sequent-command nil "Proof assistant specific function for a show-goal command. This function is applied to an ID of a goal and should return a command (as string) that will display the complete sequent with that ID. The regexp `proof-tree-update-goal-regexp' should match the output of the proof assistant for the returned command, such that `proof-tree-update-sequent' will update the sequent ID inside prooftree. If the proof assistant is unable to redisplay sequent ID the function should return nil and prooftree will not get updated." :type 'function :group 'proof-tree-internals) (defcustom proof-tree-find-begin-of-unfinished-proof nil "Proof assistant specific function for the start of the current proof. This function is called with no argument when the user switches the external proof-tree display on. Then, this function must determine if there is a currently unfinished proof for which the proof-tree display should be started. If yes this function must return the starting position of the command that started this proof. If there is no such proof, this function must return nil." :type 'function :group 'proof-tree-internals) (defcustom proof-tree-find-undo-position nil "Proof assistant specific function for finding the point to undo to. This function is used to convert the state number, which comes with an undo command from Prooftree, into a point position for `proof-retract-until-point'. This function is called in the current scripting buffer with the state number as argument. It must return a buffer position." :type 'function :group 'proof-tree-internals) (defcustom proof-tree-urgent-action-hook () "Normal hook for prooftree actions that cannot be delayed. This hook is called (indirectly) from inside `proof-shell-exec-loop' after the preceeding command and any comments that follow have been choped off `proof-action-list' and before the next command is sent to the proof assistant. This hook can therefore be used to insert additional commands into `proof-action-list' that must be executed before the next real proof command. Functions in this hook can rely on `proof-info' being bound to the result of `proof-tree-get-proof-info'. This hook is used, for instance, for Coq to insert Show commands for newly generated subgoals. (The normal Coq output does not contain the complete sequent text of newly generated subgoals.)" :type 'hook :group 'proof-tree-internals) ;; ;; Internal variables ;; (defvar proof-tree-external-display nil "Display proof trees in external prooftree windows if t. Actually, if this variable is t then the user requested an external proof-tree display. If there was no unfinished proof when proof-tree display was requested and if no proof has been started since then, then there is obviously no proof-tree display. In this case, this variable stays t and the proof-tree display will be started for the next proof. Controlled by `proof-tree-external-display-toggle'.") (defvar proof-tree-process nil "Emacs lisp process object of the prooftree process.") (defconst proof-tree-process-name "proof-tree" "Name of the prooftree process for Emacs lisp.") (defconst proof-tree-process-buffer-name (concat "*" proof-tree-process-name "*") "Name of the buffer for stdout and stderr of the prooftree process.") (defvar proof-tree-process-buffer nil "Buffer for stdout and stderr of the prooftree process.") (defconst proof-tree-emacs-exec-regexp "\nemacs exec: \\([-a-z]+\\) *\\([^\n]*\\)\n" "Regular expression to match callback commands from the prooftree process.") (defvar proof-tree-last-state 0 "Last state of the proof assistant. Used for undoing in prooftree.") (defvar proof-tree-current-proof nil "Name of the current proof or nil if there is none. This variable is only maintained and meaningful if `proof-tree-external-display' is t.") (defvar proof-tree-sequent-hash nil "Hash table to remember sequent ID's. Needed because some proof assistants do not distinguish between new subgoals, which have been created by the last proof command, and older, currently unfocussed subgoals. If Proof General meets a goal, it is treated as new subgoal if it is not in this hash yet. The hash is mostly used as a set of sequent ID's. However, for undo operations it is necessary to delete all those sequents from the hash that have been created in a state later than the undo state. For this purpose this hash maps sequent ID's to the state number in which the sequent has been created. The hash table is initialized in `proof-tree-start-process'.") (defvar proof-tree-existentials-alist nil "Alist mapping existential variables to sequent ID's. Used to remember which goals need a refresh when an existential variable gets instantiated. To support undo commands the old contents of this list must be stored in `proof-tree-existentials-alist-history'. To ensure undo is properly working, this variable should only be changed by using `proof-tree-delete-existential-assoc', `proof-tree-add-existential-assoc' or `proof-tree-clear-existentials'.") (defvar proof-tree-existentials-alist-history nil "Alist mapping state numbers to old values of `proof-tree-existentials-alist'. Needed for undo.") ;; ;; process filter function that receives prooftree output ;; (defvar proof-tree-output-marker nil "Marker in `proof-tree-process-buffer' pointing to new output. This marker points to the next piece of output that needs to get processed.") (defvar proof-tree-filter-continuation nil "Continuation when `proof-tree-process-filter' stops early. A function that handles a command from Prooftee might fail because not all data from Prooftee has yet arrived. In this case the continuation is stored in this variable and will be called from `proof-tree-process-filter' when more output arrives.") (defun proof-tree-stop-external-display () "Prooftree callback for the command \"stop-displaying\"." (if proof-tree-current-proof (message "External proof-tree display switched off")) (proof-tree-quit-proof) (setq proof-tree-external-display nil)) (defun proof-tree-handle-proof-tree-undo (data) "Handle an undo command that arrives from prooftree." (let ((undo-state (string-to-number data))) (if (and (integerp undo-state) (> undo-state 0)) (with-current-buffer proof-script-buffer (goto-char (funcall proof-tree-find-undo-position undo-state)) (proof-retract-until-point)) (display-warning '(proof-general proof-tree) "Prooftree sent an invalid state for undo" :warning)))) (defun proof-tree-insert-script (data) "Handle an insert-command command from Prooftree." (let ((command-length (string-to-number data))) (if (and (integerp command-length) (> command-length 0)) (condition-case nil (progn (insert (with-current-buffer proof-tree-process-buffer (buffer-substring proof-tree-output-marker (+ proof-tree-output-marker command-length)))) ;; received all text -> advance marker (set-marker proof-tree-output-marker (+ proof-tree-output-marker command-length) proof-tree-process-buffer)) (args-out-of-range ;; buffer substring failed because the end position is not ;; there yet ;; need to try again later (setq proof-tree-filter-continuation `(lambda () (proof-tree-insert-script ,data))))) (display-warning '(proof-general proof-tree) "Prooftree sent an invalid data length for insert-command" :warning)))) (defun proof-tree-insert-output (string &optional message) "Insert output or a message into the prooftree process buffer. If MESSAGE is t, a message is inserted and `proof-tree-output-marker' is not touched. Otherwise, if `proof-tree-output-marker' is nil, it is set to point to the newly arrived output." (with-current-buffer proof-tree-process-buffer (let ((moving (= (point) (point-max)))) (save-excursion (when (and (not message) (not proof-tree-output-marker)) (setq proof-tree-output-marker (point-max-marker)) (set-marker-insertion-type proof-tree-output-marker nil)) (goto-char (point-max)) (insert string)) (if moving (goto-char (point-max)))))) (defun proof-tree-process-filter (proc string) "Output filter for prooftree. Records the output in the prooftree process buffer and checks for callback function requests. Such callback functions might fail because the complete output from Prooftree has not arrived yet. In this case they store a continuation function in `proof-tree-filter-continuation that will be called when the next piece of output arrives. `proof-tree-output-marker' points to the next piece of Prooftree output that needs to get processed. If everything is processed, the marker is deleted and `proof-tree-insert-output' sets it again for the next output." (proof-tree-insert-output string) (let ((continuation proof-tree-filter-continuation) command-found command data) ;; clear continuation (setq proof-tree-filter-continuation nil) ;; call continuation -- this might set a continuation again (when continuation (funcall continuation)) (unless proof-tree-filter-continuation ;; there was no continuation or the continuation finished successfully ;; need to look for command after output marker (while (< proof-tree-output-marker (1+ (buffer-size proof-tree-process-buffer))) ;; there is something after the output marker (with-current-buffer proof-tree-process-buffer (save-excursion (goto-char proof-tree-output-marker) (setq command-found (proof-re-search-forward proof-tree-emacs-exec-regexp nil t)) (if command-found (progn (setq command (match-string 1) data (match-string 2)) (set-marker proof-tree-output-marker (point))) (set-marker proof-tree-output-marker (point-max))))) (when command-found (cond ((equal command "stop-displaying") (proof-tree-stop-external-display)) ((equal command "undo") (proof-tree-handle-proof-tree-undo data)) ((equal command "insert-proof-script") (proof-tree-insert-script data)) (t (display-warning '(proof-general proof-tree) (format "Unknown prooftree command %s" command) :warning)))))) ;; one of the handling functions might have set a continuation ;; if not we clear the output marker (unless proof-tree-filter-continuation (set-marker proof-tree-output-marker nil) (setq proof-tree-output-marker nil)))) ;; ;; Process creation ;; (defun proof-tree-process-sentinel (proc event) "Sentinel for prooftee. Runs on process status changes and cleans up when prooftree dies." (proof-tree-insert-output (concat "\nsubprocess status change: " event) t) (unless (proof-tree-is-running) (proof-tree-stop-external-display) (setq proof-tree-process nil))) (defun proof-tree-start-process () "Start the external prooftree process. Does also initialize the communication channel and some internal variables." (let ((old-proof-tree (get-process proof-tree-process-name))) ;; reset output marker (when proof-tree-output-marker (set-marker proof-tree-output-marker nil) (setq proof-tree-output-marker nil)) ;; create buffer (setq proof-tree-process-buffer (get-buffer-create proof-tree-process-buffer-name)) ;; first clean up any old processes (when old-proof-tree (delete-process old-proof-tree) (proof-tree-insert-output "\n\nProcess terminated by Proof General\n\n" t)) ;; now start the new process (proof-tree-insert-output "\nStart new prooftree process\n\n" t) (setq proof-tree-process (apply 'start-process proof-tree-process-name proof-tree-process-buffer proof-tree-program proof-tree-arguments)) (set-process-coding-system proof-tree-process 'utf-8-unix 'utf-8-unix) (set-process-filter proof-tree-process 'proof-tree-process-filter) (set-process-sentinel proof-tree-process 'proof-tree-process-sentinel) (set-process-query-on-exit-flag proof-tree-process nil) ;; other initializations (setq proof-tree-sequent-hash (make-hash-table :test 'equal) proof-tree-last-state 0 proof-tree-existentials-alist nil proof-tree-existentials-alist-history nil) (proof-tree-send-configure))) (defun proof-tree-is-running () "Return t if prooftree is properly running." (and proof-tree-process (eq (process-status proof-tree-process) 'run))) (defun proof-tree-ensure-running () "Ensure the prooftree process is running properly." (unless (proof-tree-is-running) (proof-tree-start-process))) ;; ;; Low-level communication primitives ;; (defconst proof-tree-protocol-version 3 "Version of the communication protocol between Proof General and Prooftree. Must be increased if one of the low-level communication primitives is changed.") (defun proof-tree-send-message (second-line data) "Send a complete message to Prooftree. Send a message with command line SECOND-LINE and all strings in DATA as data sections to Prooftree." (let ((second-line-len (string-bytes second-line))) (assert (< second-line-len 999)) (process-send-string proof-tree-process (format "second line %03d\n%s\n%s%s" (1+ second-line-len) second-line (mapconcat 'identity data "\n") (if data "\n" ""))))) (defun proof-tree-send-configure () "Send the configure message." (proof-tree-send-message (format "configure for \"%s\" and protocol version %02d" proof-assistant proof-tree-protocol-version) ())) (defun proof-tree-send-goal-state (state proof-name command-string cheated-flag layer-flag current-sequent-id current-sequent-text additional-sequent-ids existential-info) "Send the current goal state to prooftree." ;; (message "PTSGS id %s sequent %s ex-info %s" ;; current-sequent-id current-sequent-text existential-info) (let* ((add-id-string (mapconcat 'identity additional-sequent-ids " ")) (second-line (format (concat "current-goals state %d current-sequent %s %s %s " "proof-name-bytes %d " "command-bytes %d sequent-text-bytes %d " "additional-id-bytes %d existential-bytes %d") state current-sequent-id (if cheated-flag "cheated" "not-cheated") (if layer-flag "new-layer" "current-layer") (1+ (string-bytes proof-name)) (1+ (string-bytes command-string)) (1+ (string-bytes current-sequent-text)) (1+ (string-bytes add-id-string)) (1+ (string-bytes existential-info))))) (proof-tree-send-message second-line (list proof-name command-string current-sequent-text add-id-string existential-info)))) (defun proof-tree-send-update-sequent (state proof-name sequent-id sequent-text) "Send the updated sequent text to prooftree." (let ((second-line (format (concat "update-sequent state %d sequent %s proof-name-bytes %d " "sequent-text-bytes %d") state sequent-id (1+ (string-bytes proof-name)) (1+ (string-bytes sequent-text))))) (proof-tree-send-message second-line (list proof-name sequent-text)))) (defun proof-tree-send-switch-goal (proof-state proof-name current-id) "Send switch-to command to prooftree." (let ((second-line (format "switch-goal state %d sequent %s proof-name-bytes %d" proof-state current-id (1+ (string-bytes proof-name))))) (proof-tree-send-message second-line (list proof-name)))) (defun proof-tree-send-branch-finished (state proof-name cmd-string cheated-flag existential-info) "Send branch-finished to prooftree." (proof-tree-send-message (format (concat "branch-finished state %d %s proof-name-bytes %d command-bytes %d " "existential-bytes %d") state (if cheated-flag "cheated" "not-cheated") (1+ (string-bytes proof-name)) (1+ (string-bytes cmd-string)) (1+ (string-bytes existential-info))) (list proof-name cmd-string existential-info))) (defun proof-tree-send-proof-complete (state proof-name) "Send proof-complete to prooftree." (proof-tree-send-message (format "proof-complete state %d proof-name-bytes %d" state (1+ (string-bytes proof-name))) (list proof-name))) (defun proof-tree-send-undo (proof-state) "Tell prooftree to undo." (let ((second-line (format "undo-to state %d" proof-state))) (proof-tree-send-message second-line nil))) (defun proof-tree-send-quit-proof (proof-name) "Tell prooftree to close the window for PROOF-NAME." (let ((second-line (format "quit-proof proof-name-bytes %d" (1+ (string-bytes proof-name))))) (proof-tree-send-message second-line (list proof-name)))) ;; ;; proof-tree-existentials-alist manipulations and history ;; (defun proof-tree-record-existentials-state (state &optional dont-copy) "Store the current state of `proof-tree-existentials-alist' for undo. Usually this involves making a copy of `proof-tree-existentials-alist' because of the destructive updates used on that list. If optional argument DONT-COPY is non-nil no copy is done." (setq proof-tree-existentials-alist-history (cons (cons state (if dont-copy proof-tree-existentials-alist (copy-alist proof-tree-existentials-alist))) proof-tree-existentials-alist-history))) (defun proof-tree-undo-state-var (proof-state var-symbol history-symbol) "Undo changes to VAR-SYMBOL using HISTORY-SYMBOL. This is a general undo function for variables that keep their undo information in a alist that maps state numbers to old values. Argument PROOF-STATE is the state to reestablish, VAR-SYMBOL is (the symbol of) the variable to undo and HISTORY-SYMBOL is (the symbol of) the undo history alist." (let ((undo-not-finished t) (history (symbol-value history-symbol)) (var (symbol-value var-symbol))) (while (and undo-not-finished history) (if (> (caar history) proof-state) (progn (setq var (cdr (car history))) (setq history (cdr history))) (setq undo-not-finished nil))) (set var-symbol var) (set history-symbol history))) (defun proof-tree-undo-existentials (proof-state) "Undo changes in `proof-tree-existentials-alist'. Change `proof-tree-existentials-alist' back to its contents in state PROOF-STATE." (proof-tree-undo-state-var proof-state 'proof-tree-existentials-alist 'proof-tree-existentials-alist-history)) (defun proof-tree-delete-existential-assoc (state ex-assoc) "Delete mapping EX-ASSOC from 'proof-tree-existentials-alist'." (proof-tree-record-existentials-state state) (setq proof-tree-existentials-alist (delq ex-assoc proof-tree-existentials-alist))) (defun proof-tree-add-existential-assoc (state ex-var sequent-id) "Add the mapping EX-VAR -> SEQUENT-ID to 'proof-tree-existentials-alist'. Do nothing if this mapping does already exist." (let ((ex-var-assoc (assoc ex-var proof-tree-existentials-alist))) (if ex-var-assoc (unless (member sequent-id (cdr ex-var-assoc)) (proof-tree-record-existentials-state state) (setcdr ex-var-assoc (cons sequent-id (cdr ex-var-assoc)))) (proof-tree-record-existentials-state state) (setq proof-tree-existentials-alist (cons (cons ex-var (list sequent-id)) proof-tree-existentials-alist))))) (defun proof-tree-clear-existentials () "Clear the mapping in `proof-tree-existentials-alist' and its history." (setq proof-tree-existentials-alist nil) (setq proof-tree-existentials-alist-history nil)) ;; ;; Process urgent output from the proof assistant ;; (defun proof-tree-show-goal-callback (state) "Callback for display-goal commands inserted by this package. Update the sequent and run hooks in `proof-state-change-hook'. Argument STATE is the state number (i.e., an integer) with which the update sequent command should be associated. The STATE is necessary, because a comment following a branching command cat get retired together with the branching command before the show-goal commands that update sequents are processed. The effect of the sequent update would therefore be undone when the comment alone is retracted. You CANNOT put this function directly as callback into `proof-action-list' because callbacks receive the span as argument and this function expects an integer! Rather you should call `proof-tree-make-show-goal-callback', which evaluates to a lambda expressions that you can put into `proof-action-list'." ;;(message "PTSGC %s" state) (proof-tree-update-sequent state) (run-hooks 'proof-state-change-hook)) (defun proof-tree-make-show-goal-callback (state) "Create the callback for display-goal commands." `(lambda (span) (proof-tree-show-goal-callback ,state))) (defun proof-tree-urgent-action (flags) "Handle urgent points before the next item is sent to the proof assistant. Schedule goal updates when existential variables have changed and call `proof-tree-urgent-action-hook'. All this is only done if the current output does not come from a command (with the 'proof-tree-show-subgoal flag) that this package inserted itself. Urgent actions are only needed if the external proof display is currently running. Therefore this function should not be called when `proof-tree-external-display' is nil. This function assumes that the prover output is not suppressed. Therefore, `proof-tree-external-display' being t is actually a necessary precondition. The not yet delayed output is in the region \[proof-shell-delayed-output-start, proof-shell-delayed-output-end]." ;; (message "PTUA flags %s start %s end %s pal %s ptea %s" ;; flags ;; proof-shell-delayed-output-start ;; proof-shell-delayed-output-end ;; proof-action-list ;; proof-tree-existentials-alist) (let* ((proof-info (funcall proof-tree-get-proof-info)) (state (car proof-info)) (start proof-shell-delayed-output-start) (end proof-shell-delayed-output-end) inst-ex-vars) (when (and (not (memq 'proof-tree-show-subgoal flags)) (> state proof-tree-last-state)) ;; Only deal with existentials if the proof assistant has them ;; (i.e., proof-tree-existential-regexp is set) and if there are some ;; goals with existentials. (when (and proof-tree-existential-regexp proof-tree-existentials-alist) (setq inst-ex-vars (with-current-buffer proof-shell-buffer (funcall proof-tree-extract-instantiated-existentials start end))) (dolist (ex-var inst-ex-vars) (let ((var-goal-assoc (assoc ex-var proof-tree-existentials-alist))) (when var-goal-assoc (dolist (sequent-id (cdr var-goal-assoc)) (let ((show-cmd (funcall proof-tree-show-sequent-command sequent-id))) (if show-cmd (setq proof-action-list (cons (proof-shell-action-list-item show-cmd (proof-tree-make-show-goal-callback state) '(no-goals-display no-response-display proof-tree-show-subgoal)) proof-action-list))))) (proof-tree-delete-existential-assoc state var-goal-assoc))))) (run-hooks 'proof-tree-urgent-action-hook)) ;; (message "PTUA END pal %s ptea %s" ;; proof-action-list ;; proof-tree-existentials-alist) )) ;; ;; Process output from the proof assistant ;; (defun proof-tree-quit-proof () "Reset internal state when there is no current proof any more. Because currently it is not possible to undo into the middle of a proof, we can safely flush the `proof-tree-sequent-hash' and `proof-tree-existentials-alist-history' when the current proof is finished or quit." (clrhash proof-tree-sequent-hash) (proof-tree-clear-existentials) (setq proof-tree-current-proof nil)) (defun proof-tree-register-existentials (current-state sequent-id sequent-text) "Register existential variables that appear in SEQUENT-TEXT. If SEQUENT-TEXT contains existential variables, then SEQUENT-ID is stored in `proof-tree-existentials-alist'." (if proof-tree-existential-regexp (let ((start 0)) (while (proof-string-match proof-tree-existential-regexp sequent-text start) (setq start (match-end 0)) (proof-tree-add-existential-assoc current-state (match-string 1 sequent-text) sequent-id))))) (defun proof-tree-extract-goals (start end) "Extract the current goal state information from the delayed output. If there is a current goal, return a list containing (in this order) the ID of the current sequent, the text of the current sequent and the list of ID's of additionally open goals. The delayed output is expected between START and END in the current buffer." (goto-char start) (if (proof-re-search-forward proof-tree-current-goal-regexp end t) (let ((sequent-id (match-string-no-properties 1)) (sequent-text (match-string-no-properties 2)) additional-goal-ids) (goto-char start) (while (proof-re-search-forward proof-tree-additional-subgoal-ID-regexp end t) (let ((other-id (match-string-no-properties 1))) (setq additional-goal-ids (cons other-id additional-goal-ids)))) (setq additional-goal-ids (nreverse additional-goal-ids)) (list sequent-id sequent-text additional-goal-ids)) nil)) (defun proof-tree-extract-list (start end start-regexp end-regexp item-regexp) "Extract items between START-REGEXP and END-REGEXP. In the region given by START and END, determine the subregion between START-REGEXP and END-REGEXP and return the list of all items in the subregion. An item is a match of subgroub 1 of ITEM-REGEXP. The items in the returned list have the same order as in the text. Return nil if START-REGEXP or ITEM-REGEXP is nil. The subregion extends up to END if END-REGEXP is nil." (let (result) (when (and start-regexp item-regexp) (goto-char start) (when (proof-re-search-forward start-regexp end t) (setq start (point)) (if (and end-regexp (proof-re-search-forward end-regexp end t)) (setq end (match-beginning 0))) (goto-char start) (while (proof-re-search-forward item-regexp end t) (setq result (cons (match-string-no-properties 1) result))))) (nreverse result))) (defun proof-tree-extract-existential-info (start end) "Extract the information display of existential variables. This function cuts out the text between `proof-tree-existentials-state-start-regexp' and `proof-tree-existentials-state-end-regexp' from the prover output, including the matches of these regular expressions. If the start regexp is nil, the empty string is returned. If the end regexp is nil, the match expands to the end of the prover output." (goto-char start) (if (and proof-tree-existentials-state-start-regexp (proof-re-search-forward proof-tree-existentials-state-start-regexp end t)) (progn (setq start (match-beginning 0)) (when (and proof-tree-existentials-state-end-regexp (proof-re-search-forward proof-tree-existentials-state-end-regexp end t)) (setq end (match-end 0))) (buffer-substring-no-properties start end)) "")) (defun proof-tree-handle-proof-progress (old-proof-marker cmd-string proof-info) "Send CMD-STRING and goals in delayed output to prooftree. This function is called if there is some real progress in a proof. This function sends the current state, the current goal and the list of additional open subgoals to Prooftree. Prooftree will sort out the rest. The delayed output is in the region \[proof-shell-delayed-output-start, proof-shell-delayed-output-end]. Urgent messages might be before that, following OLD-PROOF-MARKER, which contains the position of `proof-marker', before the next command was sent to the proof assistant." ;; (message "PTHPO cmd |%s| info %s flags %s proof-marker %s start %s end %s" ;; cmd proof-info flags ;; old-proof-marker ;; proof-shell-delayed-output-start ;; proof-shell-delayed-output-end) (let* ((start proof-shell-delayed-output-start) (end proof-shell-delayed-output-end) (proof-state (car proof-info)) (proof-name (cadr proof-info)) (cheated-flag (and proof-tree-cheating-regexp (proof-string-match proof-tree-cheating-regexp cmd-string))) current-goals) ;; Check first for special cases, because Coq's output for finished ;; branches is almost identical to proper goals. (goto-char old-proof-marker) (if (proof-re-search-forward proof-tree-branch-finished-regexp end t) (proof-tree-send-branch-finished proof-state proof-name cmd-string cheated-flag (proof-tree-extract-existential-info start end)) (goto-char start) (setq current-goals (proof-tree-extract-goals start end)) (when current-goals (let ((current-sequent-id (car current-goals)) (current-sequent-text (nth 1 current-goals)) ;; nth 2 current-goals contains the additional ID's (layer-flag (and proof-tree-new-layer-command-regexp (proof-string-match proof-tree-new-layer-command-regexp cmd-string)))) ;; send all to prooftree (proof-tree-send-goal-state proof-state proof-name cmd-string cheated-flag layer-flag current-sequent-id current-sequent-text (nth 2 current-goals) (proof-tree-extract-existential-info start end)) ;; put current sequent into hash (if it is not there yet) (unless (gethash current-sequent-id proof-tree-sequent-hash) (puthash current-sequent-id proof-state proof-tree-sequent-hash)) (proof-tree-register-existentials proof-state current-sequent-id current-sequent-text)))))) (defun proof-tree-handle-navigation (proof-info) "Handle a navigation command. This function is called if there was a navigation command, which results in a different goal being current now. The delayed output of the navigation command is in the region \[proof-shell-delayed-output-start, proof-shell-delayed-output-end]." (let ((start proof-shell-delayed-output-start) (end proof-shell-delayed-output-end) (proof-state (car proof-info)) (proof-name (cadr proof-info))) (goto-char start) (if (proof-re-search-forward proof-tree-current-goal-regexp end t) (let ((current-id (match-string-no-properties 1))) ;; send all to prooftree (proof-tree-send-switch-goal proof-state proof-name current-id))))) (defun proof-tree-handle-proof-command (old-proof-marker cmd proof-info) "Display current goal in prooftree unless CMD should be ignored." ;; (message "PTHPC") (let ((proof-state (car proof-info)) (cmd-string (mapconcat 'identity cmd " "))) (unless (and proof-tree-ignored-commands-regexp (proof-string-match proof-tree-ignored-commands-regexp cmd-string)) (if (and proof-tree-navigation-command-regexp (proof-string-match proof-tree-navigation-command-regexp cmd-string)) (proof-tree-handle-navigation proof-info) (proof-tree-handle-proof-progress old-proof-marker cmd-string proof-info))) (setq proof-tree-last-state (car proof-info)))) (defun proof-tree-handle-undo (proof-info) "Undo prooftree to current state. Send the undo command to prooftree and undo changes to the internal state of this package. The latter involves currently two points: * delete those goals from `proof-tree-sequent-hash' that have been generated after the state to which we undo now * change proof-tree-existentials-alist back to its previous content" ;; (message "PTHU info %s" proof-info) (let ((proof-state (car proof-info))) ;; delete sequents from the hash (maphash (lambda (sequent-id state) (if (> state proof-state) (remhash sequent-id proof-tree-sequent-hash))) proof-tree-sequent-hash) ;; undo changes in other state vars (proof-tree-undo-existentials proof-state) (unless (equal (cadr proof-info) proof-tree-current-proof) ;; went back to a point before the start of the proof that we ;; are displaying; ;; or we have not started to display something (proof-tree-quit-proof)) ;; disable proof tree display when undoing to a point outside a proof (unless proof-tree-current-proof (setq proof-tree-external-display nil)) ;; send undo (if (proof-tree-is-running) (proof-tree-send-undo proof-state)) (setq proof-tree-last-state (- proof-state 1)))) (defun proof-tree-update-sequent (proof-state) "Prepare an update-sequent command for prooftree. This function processes delayed output that the proof assistant generated in response to commands that Proof General inserted in order to keep prooftree up-to-date. Such commands are tagged with a 'proof-tree-show-subgoal flag. This function uses `proof-tree-update-goal-regexp' to find a sequent and its ID in the delayed output. If something is found an appropriate update-sequent command is sent to prooftree. The update-sequent command is associated with state PROOF-STATE for proper undo effects, see also the comments for `proof-tree-show-goal-callback'. The delayed output is in the region \[proof-shell-delayed-output-start, proof-shell-delayed-output-end]." ;; (message "PTUS buf %s output %d-%d state %s" ;; (current-buffer) ;; proof-shell-delayed-output-start proof-shell-delayed-output-end ;; proof-state) (if (proof-tree-is-running) (with-current-buffer proof-shell-buffer (let* ((start proof-shell-delayed-output-start) (end proof-shell-delayed-output-end) (proof-info (funcall proof-tree-get-proof-info)) (proof-name (cadr proof-info))) (goto-char start) (if (proof-re-search-forward proof-tree-update-goal-regexp end t) (let ((sequent-id (match-string-no-properties 1)) (sequent-text (match-string-no-properties 2))) (proof-tree-send-update-sequent proof-state proof-name sequent-id sequent-text) ;; put current sequent into hash (if it is not there yet) (unless (gethash sequent-id proof-tree-sequent-hash) (puthash sequent-id proof-state proof-tree-sequent-hash)) (proof-tree-register-existentials proof-state sequent-id sequent-text))))))) (defun proof-tree-handle-delayed-output (old-proof-marker cmd flags span) "Process delayed output for prooftree. This function is the main entry point of the Proof General prooftree support. It examines the delayed output in order to take appropriate actions and maintains the internal state. The delayed output to handle is in the region \[proof-shell-delayed-output-start, proof-shell-delayed-output-end]. Urgent messages might be before that, following OLD-PROOF-MARKER, which contains the position of `proof-marker', before the next command was sent to the proof assistant. All other arguments are (former) fields of the `proof-action-list' entry that is now finally retired. CMD is the command, FLAGS are the flags and SPAN is the span." ;; (message "PTHDO cmd %s flags %s span %s-%s" cmd flags ;; (if span (span-start span)) (if span (span-end span))) (assert proof-tree-external-display) (unless (or (memq 'invisible flags) (memq 'proof-tree-show-subgoal flags)) (let* ((proof-info (funcall proof-tree-get-proof-info)) (current-proof-name (cadr proof-info))) (save-excursion (if (<= (car proof-info) proof-tree-last-state) ;; went back to some old state: there must have been an undo command (proof-tree-handle-undo proof-info) ;; else -- no undo command ;; first maintain proof-tree-current-proof (cond ((and (null proof-tree-current-proof) current-proof-name) ;; started a new proof (setq proof-tree-current-proof current-proof-name)) ((and proof-tree-current-proof (null current-proof-name)) ;; finished the current proof (proof-tree-send-proof-complete (car proof-info) proof-tree-current-proof) (proof-tree-quit-proof) (setq proof-tree-external-display nil)) ((and proof-tree-current-proof current-proof-name (not (equal proof-tree-current-proof current-proof-name))) ;; new proof before old was finished? (display-warning '(proof-general proof-tree) "Nested proofs are not supported in prooftree display" :warning) ;; try to keep consistency nevertheless (setq proof-tree-current-proof current-proof-name))) ;; send stuff to prooftree now (when current-proof-name ;; we are inside a proof: display something (proof-tree-ensure-running) (proof-tree-handle-proof-command old-proof-marker cmd proof-info))))))) ;; ;; Send undo command when leaving a buffer ;; (defun proof-tree-leave-buffer () "Send an undo command to prooftree when leaving a buffer." (if (and proof-tree-configured (proof-tree-is-running)) (proof-tree-send-undo 0))) (add-hook 'proof-deactivate-scripting-hook 'proof-tree-leave-buffer) ;; ;; User interface ;; (defun proof-tree-display-current-proof (proof-start) "Start an external proof-tree display for the current proof. Coq (and probably other proof assistants as well) does not support outputing the current proof tree. Therefore this function retracts to the start of the current proof, switches the proof-tree display on, and reasserts then until the former end of the locked region. Argument PROOF-START must contain the start position of the current proof." ;;(message "PTDCP %s" proof-tree-external-display) (unless (and proof-script-buffer (equal proof-script-buffer (current-buffer))) (error "Enabling prooftree inside a proof outside the current scripting buffer")) (proof-shell-ready-prover) (assert proof-locked-span) (message "Start proof-tree display for current proof") (save-excursion (save-window-excursion (let ((locked-end (span-end proof-locked-span))) (goto-char proof-start) ;; enable external display to make sure the undo command is send (setq proof-tree-external-display t) (proof-retract-until-point) (while (consp proof-action-list) (accept-process-output)) ;; undo switched external display off; switch on again (setq proof-tree-external-display t) (goto-char locked-end) (proof-assert-until-point) (while (consp proof-action-list) (accept-process-output)))))) (defun proof-tree-external-display-toggle () "Toggle the external proof-tree display. When called outside a proof the external proof-tree display will be enabled for the next proof. When called inside a proof the proof display will be created for the current proof. If the external proof-tree display is currently on, then this toggle will switch it off. At the end of the proof the proof-tree display is switched off." (interactive) (unless proof-tree-configured (error "External proof-tree display not configured for %s" proof-assistant)) (cond (proof-tree-external-display ;; Currently on -> switch off (setq proof-tree-external-display nil) (when proof-tree-current-proof (proof-tree-send-quit-proof proof-tree-current-proof) (proof-tree-quit-proof)) (message "External proof-tree display switched off")) (t ;; Currently off (let ((proof-start (funcall proof-tree-find-begin-of-unfinished-proof))) ;; ensure internal variables are initialized, because otherwise ;; we cannot process undo's after this (proof-tree-ensure-running) (setq proof-tree-current-proof nil) (setq proof-tree-last-state (car (funcall proof-tree-get-proof-info))) (if proof-start ;; inside an unfinished proof -> start for this proof (proof-tree-display-current-proof proof-start) ;; outside a proof -> wait for the next proof (setq proof-tree-external-display t) (proof-tree-send-undo proof-tree-last-state) (message "External proof-tree display switched on for the next proof")))))) ;; ;; Trailer ;; (provide 'proof-tree) ;;; tree-tree.el ends here proofgeneral-4.3~pre130510/generic/proof-unicode-tokens.el000066400000000000000000000120261214562307500234400ustar00rootroot00000000000000;;; proof-unicode-tokens.el --- Support Unicode tokens package ;; ;; Copyright (C) 2008, 2009 David Aspinall / LFCS Edinburgh ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-unicode-tokens.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; ;; ;;; Commentary: ;; ;; Support for Unicode Tokens package: per-prover global enabling, copying ;; configuration tables, adding mode hooks to turn on/off. ;; ;; Initialisation: ;; proof-unicode-tokens-init -> proof-unicode-tokens-reconfigure* ;; ;;; Code: (eval-when-compile (require 'cl)) (eval-when (compile) (require 'scomint) (require 'proof-auxmodes) ; loaded by proof.el, autoloads us (require 'unicode-tokens)) ; it will be loaded by proof-auxmodes (require 'proof-config) ; config variables (defvar proof-unicode-tokens-initialised nil "Flag indicating whether or not we've performed startup.") (defun proof-unicode-tokens-init () "Set tables and configure hooks for modes." (proof-unicode-tokens-configure) (add-hook 'proof-shell-init-hook 'proof-unicode-tokens-configure-prover) (let ((hooks (mapcar (lambda (m) (intern (concat (symbol-name m) "-hook"))) (list proof-mode-for-script proof-mode-for-response proof-mode-for-goals)))) (dolist (hook hooks) (add-hook hook 'proof-unicode-tokens-mode-if-enabled))) (setq proof-unicode-tokens-initialised t)) (defun proof-unicode-tokens-configure () "Set the Unicode Tokens table from prover instances and initialise." (require 'unicode-tokens) ; load now, for unicode-tokens-configuration-variables (dolist (var unicode-tokens-configuration-variables) (if (boundp (proof-ass-symv var)) (set (intern (concat "unicode-tokens-" (symbol-name var) "-variable")) (proof-ass-symv var)))) (unicode-tokens-initialise)) ;;;###autoload (defun proof-unicode-tokens-mode-if-enabled () "Turn on or off the Unicode Tokens minor mode in this buffer." (unicode-tokens-mode (if (proof-ass unicode-tokens-enable) 1 0))) ;;;###autoload (defun proof-unicode-tokens-set-global (flag) "Set global status of unicode tokens mode for PG buffers to be FLAG. Turn on/off menu in all script buffers and ensure new buffers follow suit." (unless proof-unicode-tokens-initialised (proof-unicode-tokens-init)) ;; Configure if already running (proof-map-buffers (append (proof-buffers-in-mode proof-mode-for-script) (proof-associated-buffers) (proof-buffers-in-mode proof-tokens-extra-modes)) (unicode-tokens-mode (if flag 1 0))) (proof-unicode-tokens-configure-prover)) ;;;###autoload (defun proof-unicode-tokens-enable () "Turn on or off Unicode tokens mode in Proof General script buffer. This invokes `unicode-tokens-mode' to toggle the setting for the current buffer, and then sets PG's option for default to match. Also we arrange to have unicode tokens mode turn itself on automatically in future if we have just activated it for this buffer. Note: this function is called when the customize setting for the prover is changed." (interactive) (when (proof-unicode-tokens-support-available) ;; loads unicode-tokens (unless proof-unicode-tokens-initialised (proof-unicode-tokens-init)) (with-no-warnings ; spurious warning on `proof-unicode-tokens-set-global' (proof-unicode-tokens-set-global (not unicode-tokens-mode))))) ;;; ;;; Interface to custom to dynamically change tables (via proof-set-value) ;;; (defun proof-unicode-tokens-reconfigure () "Function called after a token configuration is changed. Switch off tokens in all script buffers, recalculate maps, turn on again." (interactive) (when proof-unicode-tokens-initialised ; not on startup (when (proof-ass unicode-tokens-enable) (proof-map-buffers (proof-buffers-in-mode proof-mode-for-script) (unicode-tokens-mode 0))) (proof-unicode-tokens-configure) (when (proof-ass unicode-tokens-enable) (proof-map-buffers (proof-buffers-in-mode proof-mode-for-script) (unicode-tokens-mode 1))))) ;; functions to dynamically change settings (eval-after-load "unicode-tokens" '(dolist (var unicode-tokens-configuration-variables) (funcall 'defalias (intern (concat "proof-" (symbol-name var))) 'proof-unicode-tokens-reconfigure))) ;;; ;;; Interface to shell ;;; (defun proof-unicode-tokens-configure-prover () (if (proof-ass unicode-tokens-enable) (proof-unicode-tokens-activate-prover) (proof-unicode-tokens-deactivate-prover))) (defun proof-unicode-tokens-activate-prover () (when (and proof-tokens-activate-command (proof-shell-live-buffer) (proof-shell-available-p)) (proof-shell-invisible-command-invisible-result proof-tokens-activate-command))) (defun proof-unicode-tokens-deactivate-prover () (when (and proof-tokens-deactivate-command (proof-shell-live-buffer) (proof-shell-available-p)) (proof-shell-invisible-command-invisible-result proof-tokens-deactivate-command))) (provide 'proof-unicode-tokens) ;;; proof-unicode-tokens.el ends here proofgeneral-4.3~pre130510/generic/proof-useropts.el000066400000000000000000000412571214562307500224050ustar00rootroot00000000000000;;; proof-useropts.el --- Global user options for Proof General ;; ;; Copyright (C) 2009, 2010, 2011 LFCS Edinburgh. ;; Author: David Aspinall and others ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-useropts.el,v 12.7 2012/11/13 08:01:12 tews Exp $ ;; ;;; Commentary: ;; ;; User options for Proof General. ;; ;; The following variables are user options for Proof General. ;; ;; They appear in the 'proof-user-options' customize group and should ;; *not* normally be touched by prover specific code. ;; ;;; Code: (defgroup proof-user-options nil "User options for Proof General." :group 'proof-general :prefix "proof-") ;; ;; Take 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) (when (and (not noninteractive) (featurep 'pg-custom) (featurep 'proof-config)) (if (fboundp sym) (funcall sym) (if (boundp 'proof-assistant-symbol) (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)))))))) (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-next-command-insert-space t "*If non-nil, PG will use heuristics to insert newlines or spaces in scripts. In particular, if electric terminator is switched on, spaces or newlines will be inserted as the user types commands to the prover." :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." :type 'boolean :set 'proof-set-value :group 'proof-user-options) (defcustom proof-imenu-enable nil "*If non-nil, display Imenu menu of items for script buffers." :type 'boolean :set 'proof-set-value :group 'proof-user-options) (defcustom pg-show-hints t "*Whether to display keyboard hints in the minibuffer." :type 'boolean :group 'proof-user-options) (defcustom proof-shell-quiet-errors t "If non-nil, be quiet about errors from the prover. Normally error messages cause a beep. Set this to t to prevent that." :type 'boolean :group 'proof-user-options) ;; FIXME: next one could be integer value for catchup delay (defcustom proof-trace-output-slow-catchup t "*If non-nil, try to redisplay less often during frequent trace output. Proof General will try to configure itself to update the display of tracing output infrequently when the prover is producing rapid, perhaps voluminous, output. This counteracts the situation that otherwise Emacs may consume more CPU than the proof assistant, trying to fontify and refresh the display as fast as output appears." :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 'retract "*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, except for the special value 'retract which means undo first. If nil, Proof General is more relaxed (but may give you a reprimand!)." :type '(choice (const :tag "Do not allow edits" t) (const :tag "Allow edits but automatically retract first" retract) (const :tag "Allow edits without restriction" nil)) :set 'proof-set-value :group 'proof-user-options) (defcustom proof-three-window-enable t "*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." :type 'boolean :set 'proof-set-value :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) ; Pierre: I really don't think this option is useful. remove? (defcustom proof-layout-windows-on-visit-file nil "*Whether to eagerly create auxiliary buffers and display windows. If non-nil, the output buffers are created and (re-)displayed as soon as a proof script file is visited. Otherwise, the buffers are created and displayed lazily. See `proof-layout-windows'." :type 'boolean :set 'proof-set-value :group 'proof-user-options) (defcustom proof-three-window-mode-policy 'smart "*Window splitting policy for three window mode. - If 'vertical then never split horizontally. - If 'horizontal then always have scripting buffer on the right and goal and response buffers on the left (one above the other). - If 'smart or anything else: 'horizontal when the window is wide enough and 'vertical otherwise. The width threshold is given by `split-width-threshold'. See `proof-layout-windows'." :type '(choice (const :tag "Adapt to current frame width" smart) (const :tag "Horizontal (three columns)" horizontal) (const :tag "Horizontal (two columns)" hybrid) (const :tag "Vertical" vertical)) :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-shrink-windows-tofit nil "*If non-nil, automatically shrink output windows to fit contents. In single-frame mode, this option will reduce the size of the goals and response windows to fit their contents." :type 'boolean :group 'proof-user-options) (defcustom proof-auto-raise-buffers t "*If non-nil, automatically raise buffers to display latest output. If this is not set, buffers and windows will not be managed by Proof General." :type 'boolean :group 'proof-user-options) (defcustom proof-colour-locked t "*If non-nil, colour the locked region with `proof-locked-face'. If this is not set, buffers will have no special face set on locked regions." :type 'boolean :set 'proof-set-value :group 'proof-user-options) (defcustom proof-sticky-errors nil "*If non-nil, add highlighting to regions which gave errors. Intended to complement `proof-colour-locked'." :type 'boolean :set 'proof-set-value :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) (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-keep-response-history nil "*Whether to keep a browsable history of responses. With this feature enabled, the buffers used for prover responses will have a history that can be browsed without processing/undoing in the prover. \(Changes to this variable take effect after restarting the prover)." :type 'boolean :set 'proof-set-value :group 'proof-user-options) (defcustom pg-input-ring-size 32 "*Size of history ring of previous successfully processed commands." :type 'integer :group 'proof-user-options) (defcustom proof-general-debug nil "*Non-nil to run Proof General in debug mode. This changes some behaviour (e.g. markup stripping) and displays debugging messages in the response buffer. To avoid erasing messages shortly after they're printed, set `proof-tidy-response' to nil. This is only useful for PG developers." :type 'boolean :group 'proof-user-options) (defcustom proof-use-parser-cache t "*Non-nil to use a simple parsing cache. This can be helpful when editing and reprocessing large files. This variable exists to disable the cache in case of problems." :type 'boolean :group 'proof-user-options) (defcustom proof-follow-mode 'locked "*Choice of how point moves with script processing commands. One of the symbols: 'locked, 'follow, 'followdown, '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 'followdown, point if necessary to stay in writeable region 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 \\[proof-goto-end-of-locked]" :type '(choice (const :tag "Follow locked region" locked) (const :tag "Follow locked region down" followdown) (const :tag "Keep locked region displayed" follow) (const :tag "Never move" ignore)) :group 'proof-user-options) ;; Note: the auto action might be improved a bit: for example, when ;; scripting is turned off because another buffer is being retracted, ;; we almost certainly want to retract the currently edited buffer as ;; well (use case is somebody realising a change has to made in an ;; ancestor file). And in that case (supposing file being unlocked is ;; an ancestor), it seems unlikely that we need to query for saves. (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. For some proof assistants (such as Coq) fully processed buffers make no sense. Setting this option to 'process has then the same effect as leaving it unset (nil). (This behaviour is controlled by `proof-no-fully-processed-buffer'.)" :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-rsh-command nil "*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. For proper behaviour with interrupts, the program should also communicate signals to the remote host." :type '(choice string (const nil)) :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) (defcustom proof-full-annotation nil "*Non-nil causes Proof General to record output for all proof commands. Proof output is recorded as it occurs interactively; normally if many steps are taken at once, this output is suppressed. If this setting is used to enable it, the proof script can be annotated with full details. See also `proof-output-tooltips' to enable automatic display of output on mouse hovers." :type 'boolean :group 'proof-user-options) (defcustom proof-output-tooltips t "*Non-nil causes Proof General to add tooltips for prover output. Hovers will be added when this option is non-nil. Prover outputs can be displayed when the mouse hovers over the region that produced it and output is available (see `proof-full-annotation'). If output is not available, the type of the output region is displayed. Changes of this option will not be reflected in already-processed regions of the script." :type 'boolean :group 'proof-user-options) (defcustom proof-minibuffer-messages nil "*Non-nil causes Proof General to issue minibuffer messages. Minibuffer messages are issed when urgent messages are seen from the prover. You can disable the display of these if they are distracting or too frequent." :type 'boolean :group 'proof-user-options) (defcustom proof-autosend-enable nil "*Non-nil causes Proof General to automatically process the script." :type 'boolean :set 'proof-set-value :group 'proof-user-options) (defcustom proof-autosend-delay 0.8 "*Delay before autosend starts sending commands." :type 'float :set 'proof-set-value :group 'proof-user-options) (defcustom proof-autosend-all nil "*If non-nil, auto send will process whole buffer; otherwise just the next command." :type 'boolean :group 'proof-user-options) (defcustom proof-fast-process-buffer (or (featurep 'ns) ; Mac OS X ; or Windows (speed up TBC, see Trac #308) (memq system-type '(windows-nt ms-dos cygwin))) "*If non-nil, `proof-process-buffer' will use a busy wait to process. This results in faster processing, but disables simultaneous user interaction. This setting gives a big speed-up on certain platforms/Emacs ports, for example Mac OS X." :type 'boolean :group 'proof-user-options) (provide 'proof-useropts) ;;; proof-useropts.el ends here proofgeneral-4.3~pre130510/generic/proof-utils.el000066400000000000000000000704741214562307500216640ustar00rootroot00000000000000;; proof-utils.el --- Proof General utility functions and macros ;; ;; Copyright (C) 1998-2002, 2009, 2011 LFCS Edinburgh. ;; Author: David Aspinall and others ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-utils.el,v 12.1 2012/09/05 23:01:45 pier Exp $ ;; ;;; Commentary: ;; ;; Loading note: this file is required immediately from proof.el, so ;; no autoloads cookies are added here. ;; ;; Compilation note: see etc/development-tips.txt ;; ;;; Code: ;; ;; Give Emacs version mismatch error here. ;; ;; This file is loaded early, and may be first compiled file ;; loaded if proof-site.el is loaded instead of proof-site.elc. ;; (eval-and-compile (defun pg-emacs-version-cookie () (format "GNU Emacs %d.%d" emacs-major-version emacs-minor-version)) (defconst pg-compiled-for (eval-when-compile (pg-emacs-version-cookie)) "Version of Emacs we're compiled for (or running on, if interpreted).")) (if (or (not (boundp 'emacs-major-version)) (< emacs-major-version 23) (string-match "XEmacs" emacs-version)) (error "Proof General is not compatible with Emacs %s" emacs-version)) (unless (equal pg-compiled-for (pg-emacs-version-cookie)) (warn "Proof General compiled for %s but running on %s: \"make clean; make\" is recommended." pg-compiled-for (pg-emacs-version-cookie))) (require 'proof-site) ; basic vars (require 'proof-compat) ; compatibility (require 'pg-pamacs) ; macros for pa config (require 'proof-config) ; config vars (require 'bufhist) ; bufhist (require 'proof-syntax) ; syntax utils (require 'proof-autoloads) ; interface fns (require 'scomint) ; for proof-shell-live-buffer ;;; Code: ;; ;; Handy macros ;; (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))) (defsubst 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)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Simplified version of save-some-buffers, with useful arg ;; (defun proof-save-some-buffers (buffers) "Query the user whether to save each of BUFFERS." ;; code based on extract from files.el in XEmacs 21.4.14 (map-y-or-n-p (lambda (buffer) (if (and (buffer-modified-p buffer) (not (buffer-base-buffer buffer)) (buffer-file-name buffer)) ;; we deliberately don't switch to show the buffer; ;; let's assume user can see it or knows what's in it. (format "Save file %s? " (buffer-file-name buffer)))) (lambda (buffer) (set-buffer buffer) (condition-case () (save-buffer) (error nil))) buffers)) (defun proof-save-this-buffer () "Query the user whether to save the current buffer." (if (and (buffer-modified-p) (buffer-file-name (current-buffer)) (y-or-n-p (format "Save file %s? " (buffer-file-name (current-buffer))))) (save-buffer))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Buffers and filenames (defun proof-file-truename (filename) "Return the true name of the file FILENAME or nil if file non-existent." (and filename (file-exists-p filename) (file-truename filename))) (defun proof-files-to-buffers (filenames) "Convert a list of FILENAMES into a list of BUFFERS." (let (bufs buf) (dolist (file filenames) (if (setq buf (find-buffer-visiting file)) (setq bufs (cons buf bufs)))) bufs)) (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)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Associated buffers ;; (defun pg-save-from-death () "Prevent this associated buffer from being killed: merely erase it. A hook function for `kill-buffer-hook'. This is a fairly crude and not-entirely-robust way to prevent the user accidently killing an associated buffer." (if (and (proof-shell-live-buffer) proof-buffer-type) (progn (let ((bufname (buffer-name))) (bufhist-erase-buffer) (set-buffer-modified-p nil) (bury-buffer) (error "Warning: buffer %s not killed; still associated with prover process" bufname))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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)) (defun pg-remove-specials (&optional start end) "Remove special characters in region. Default to whole buffer. Leave point at END." (let ((start (or start (point-min))) (end (or end (point-max)))) (goto-char start) (while (re-search-forward pg-special-char-regexp end t) (replace-match "")) (goto-char end))) (defun pg-remove-specials-in-string (string) (proof-replace-regexp-in-string pg-special-char-regexp "" string)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Messaging and display functions ;; (defun proof-safe-split-window-vertically () (if (<= (window-height) (* 2 window-min-height)) (enlarge-window (+ 3 (* 2 window-min-height)))) (split-window-vertically)) (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)))) (defun proof-get-window-for-buffer (buffer) "Find a window for BUFFER, display it there, return the window. NB: may change the selected window." ;; IF there *isn't* a visible window showing buffer... (unless (get-buffer-window buffer 0) ;; THEN find somewhere nice to display it (if (and ;; If we're in two-window mode and already displaying a ;; script/response/goals, try to just switch the buffer ;; instead of calling display-buffer which alters sizes. ;; Gives user some stability on display. (not proof-three-window-enable) (> (count-windows) 1) ;; was: (not (eq (next-window) (selected-window))) (memq (window-buffer (next-window nil 'ignoreminibuf)) ;; NB: 3.5: added rest of assoc'd buffers here (cons proof-script-buffer (proof-associated-buffers)))) (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) (if (eq (window-buffer (next-window nil 'ignoreminibuf)) proof-script-buffer) ;; switch this window (set-window-buffer (selected-window) buffer) ;; switch other window (set-window-buffer (next-window nil 'ignoreminibuf) buffer))) ;; o/w: call display buffer to configure windows nicely. (display-buffer buffer))) ;; Return the window, hopefully the one we first thought of. (get-buffer-window buffer 0)) (defun proof-display-and-keep-buffer (buffer &optional pos force) "Display BUFFER and make window according to display mode. 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." (if (or force proof-auto-raise-buffers) (save-excursion (save-selected-window (let ((window (proof-get-window-for-buffer buffer))) (if (window-live-p window) ;; [fails sometimes?] (progn ;; Set the size and point position. (if proof-three-window-enable (set-window-dedicated-p window proof-three-window-enable)) (select-window window) (if proof-shrink-windows-tofit (proof-resize-window-tofit) ;; If we're not shrinking to fit, allow the size of ;; this window to change. [NB: might be nicer to ;; fix the size based on user choice] (setq window-size-fixed nil)) ;; For various reasons, point may get moved around in ;; response buffer. Attempt to normalise its position. (goto-char (or pos (point-max))) (if pos (beginning-of-line) (skip-chars-backward "\n\t ")) ;; Ensure point visible. Again, window may have died ;; inside shrink to fit, for some reason (when (window-live-p window) (unless (pos-visible-in-window-p (point) window) (recenter -1)) (with-current-buffer buffer (if (window-bottom-p window) (unless (local-variable-p 'mode-line-format) ;; Don't show any mode line. (set (make-local-variable 'mode-line-format) nil)) (unless mode-line-format ;; If the buffer gets displayed elsewhere, re-add ;; the modeline. (kill-local-variable 'mode-line-format)))))))))))) (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.) No effect if buffer is dead." (if (buffer-live-p buffer) (with-current-buffer buffer (let ((inhibit-read-only t)) (unless (eq 0 (buffer-size)) ;; checkpoint unless already empty (bufhist-checkpoint-and-erase))) (set-buffer-modified-p nil) (if (eq buffer proof-response-buffer) (setq pg-response-next-error nil)) ; all error msgs lost! (if proof-delete-empty-windows (delete-windows-on buffer t))))) (defun pg-internal-warning (message &rest args) "Display internal warning MESSAGE with ARGS as for format." (let ((formatted (apply 'format message args))) (if (fboundp 'display-warning) (display-warning 'proof-general formatted) (message formatted)))) ;;;###autoload (defun proof-debug (msg &rest args) "Issue the debugging message (format MSG ARGS) in the *PG Debug* buffer. If flag `proof-general-debug' is nil, do nothing." (when proof-general-debug (with-current-buffer (get-buffer-create "*PG Debug*") (help-mode) (let ((formatted (apply 'format msg args)) (log-warning-minimum-level :debug) (warning-minimum-level :debug) (buffer-read-only nil)) (display-warning 'proof-general formatted :debug "*PG Debug*"))))) ;; Utility used in the "Buffers" menu, and throughout (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." (and (buffer-live-p buf) ; maybe use proof-display-and-keep-buffer ? (unless (eq buf (window-buffer (selected-window))) (if noselect (display-buffer buf 'not-this-window) (let ((pop-up-windows t)) (pop-to-buffer buf 'not-this-window 'norecord)))))) ;; Originally based on `shrink-window-if-larger-than-buffer', which ;; has a pretty weird implementation. ;; FIXME: GNU Emacs has useful "window-size-fixed" which we use ;; HOWEVER, it's still not quite the right thing, it seems to me. ;; We'd like to specifiy a *minimum size* for a given buffer, ;; not a maximum. With a frame split with just goals/response ;; we'd still get resize errors here using window-size-fixed. ;; FIXME: shrink-to-fit doesn't really work in three-buffer mode, ;; since shrinking one of the associated buffers tends to enlarge the ;; other (rather than just enlarging the proof state) (defun proof-resize-window-tofit (&optional window) "Shrink the WINDOW to be as small as possible to display its contents. Do not shrink to less than `window-min-height' lines. Do nothing if the buffer contains more lines than the present window height, or if some of the window's contents are scrolled out of view, or if the window is not the full width of the frame, or if the window is the only window of its frame." ;; da: actually seems okay in this case (interactive) (or window (setq window (selected-window))) ;; some checks before resizing to avoid messing custom display ;; [probably somewhat superfluous/extra rare] (if (or ;; The frame must not be minibuffer-only. (eq (frame-parameter (window-frame window) 'minibuffer) 'only) ;; We've got more than one window, right? (= 1 (let ((frame (selected-frame))) (select-frame (window-frame window)) (unwind-protect ;; [why is this protected?] (count-windows) (select-frame frame) (select-window window)))) ;; the window is the full width, right? ;; [if not, we may be in horiz-split scheme, problematic] (not (window-leftmost-p window)) (not (window-rightmost-p window))) ;; OK, we're not going to adjust the height here. Moreover, ;; we'll make sure the height can be changed elsewhere. (setq window-size-fixed nil) (with-current-buffer (window-buffer window) (let* ;; weird test cases: ;; cur=45, max=23, desired=121, extraline=0 ;; current height ;;; ((cur-height (window-height window)) ;; Most window is allowed to grow to ((max-height (/ (frame-height (window-frame window)) (if proof-three-window-enable ;; we're in three-window-mode with ;; all horizontal splits, so share the height. 3 ;; Otherwise assume a half-and-half split. 2))) ;; I find that I'm willing to use a bit more than the max in ;; those cases where it allows me to see the whole ;; response/goal. --Stef (absolute-max-height (truncate (/ (frame-height (window-frame window)) (if proof-three-window-enable ;; we're in three-window-mode with ;; all horizontal splits, so share the height. 2 ;; Otherwise assume a half-and-half split. 1.5)))) ;; If buffer ends with a newline and point is right after it, then ;; add a final empty line (to display the cursor). (extraline (if (and (eobp) (bolp)) 1 0)) ;; (test-pos (- (point-max) extraline)) ;; Direction of resizing based on whether max position is ;; currently visible. [ FIXME: not completely sensible: ;; may be displaying end fraction of buffer! ] ;; (shrink (pos-visible-in-window-p test-pos window)) ;; Likely desirable height is given by count-lines (desired-height ;; FIXME: is count-lines too expensive for v.large ;; buffers? Probably not an issue for us, but one ;; wonders at the shrink to fit strategy. ;; NB: way to calculate pixel fraction? (+ extraline (count-lines (point-min) (point-max))))) ;; Let's shrink or expand. Uses new GNU Emacs function. (let ((window-size-fixed nil)) (set-window-text-height window ;; As explained earlier: use abs-max-height ;; but only if that makes it display all. (if (> desired-height absolute-max-height) max-height desired-height))) (if (window-live-p window) (progn (if (>= (window-text-height window) desired-height) (set-window-start window (point-min))) ;; window-size-fixed is a GNU Emacs buffer local variable ;; which determines window size of buffer. ;; (setq window-size-fixed (window-height window)) )))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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 "da+pg-bugs@inf.ed.ac.uk" "Proof General" (list 'proof-general-version 'proof-assistant) nil nil "*** Proof General now uses Trac for project management and bug reporting, please go to: *** *** http://proofgeneral.inf.ed.ac.uk/trac/search *** *** To see if your bug has been reported already, and a new ticket if not. *** To report a bug, either register yourself as a user, or use the generic account *** username \"pgemacs\" with password \"pgemacs\" *** *** Please only continue with this email mechanism instead IF YOU REALLY MUST. *** The address is not monitored very often and quite possibly will be ignored. *** *** 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 or FAQ files that came with *** the distribution, or the latest versions at *** http://proofgeneral.inf.ed.ac.uk/BUGS and *** http://proofgeneral.inf.ed.ac.uk/FAQ "))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Utils for making functions to adjust user settings ;;; (defun proof-deftoggle-fn (var &optional othername) "Define a function -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"))) (&optional 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 -toggle. The name of the defined function is returned." `(progn (declare-function ,(if othername othername (intern (concat (symbol-name var) "-toggle"))) "proof-utils") (proof-deftoggle-fn (quote ,var) (quote ,othername)))) (defun proof-defintset-fn (var &optional othername) "Define a function -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 (list (read-number (format "Value for %s (int, currently %s): " (symbol-name (quote ,var)) (symbol-value (quote ,var)))))) (unless (integerp arg) ;; type-check to avoid customize type mismatch (error "Value should be an integer!")) (customize-set-variable (quote ,var) arg)))) (defmacro proof-defintset (var &optional othername) "Define a function -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 -intset. The name of the defined function is returned." `(proof-defintset-fn (quote ,var) (quote ,othername))) (defun proof-deffloatset-fn (var &optional othername) "Define a function -floatset for setting an float customize setting VAR. Args as for the macro `proof-deffloatset', except will be evaluated." (eval `(defun ,(if othername othername (intern (concat (symbol-name var) "-floatset"))) (arg) ,(concat "Set `" (symbol-name var) "' to ARG. This function simply uses customize-set-variable to set the variable. It was constructed with `proof-deffloatset-fn'.") (interactive (list (read-number (format "Value for %s (float, currently %s): " (symbol-name (quote ,var)) (symbol-value (quote ,var)))))) (customize-set-variable (quote ,var) arg)))) (defmacro proof-deffloatset (var &optional othername) "Define a function -floatset for setting an float customize setting VAR. The setting function uses `customize-set-variable' to change the variable. OTHERNAME gives an alternative name than the default -floatset. The name of the defined function is returned." `(proof-deffloatset-fn (quote ,var) (quote ,othername))) (defun proof-defstringset-fn (var &optional othername) "Define a function -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 ,(format "sValue for %s (a string): " (symbol-name var))) (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 -stringset. The name of the defined function is returned." `(proof-defstringset-fn (quote ,var) (quote ,othername))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Macris for defining user-level functions (previously in proof-menu.el) ;;; (defun proof-escape-keymap-doc (string) "Avoid action of `substitute-command-keys' on STRING." (replace-regexp-in-string "\\\\" "\\\\=\\\\" string)) (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." `(progn (if ,key (define-key (proof-ass keymap) (quote ,key) (quote ,fn))) (defun ,fn () ,(concat "Shortcut command to insert " (proof-escape-keymap-doc string) " into the current buffer.\nThis simply calls `proof-insert', which see.") (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. STRING may be a string or a function which returns a string. KEY is added onto proof assistant map." `(progn (if ,key (define-key (proof-ass keymap) (quote ,key) (quote ,fn))) (defun ,fn () ,(concat "Command to send " (if (stringp string) (proof-escape-keymap-doc string) "an instruction") " to the proof assistant.") (interactive) ,(if (stringp string) (list 'proof-shell-invisible-command string) (list 'proof-shell-invisible-command (eval string)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Interface to custom lib ;;; ;; EMACSFIXME: A function that custom could provide. (defun pg-custom-save-vars (&rest variables) "Save custom vars VARIABLES." (dolist (symbol variables) (let ((value (get symbol 'customized-value))) ;; See customize-save-customized; adjust properties so ;; that custom-save-all will save the value. (when value (put symbol 'saved-value value) (custom-push-theme 'theme-value symbol 'user 'set value) (put symbol 'customized-value nil)))) (custom-save-all)) ;; FIXME: this doesn't do quite same thing as reset button, ;; which *removes* a setting from `custom-set-variables' list ;; in custom.el. Instead, this adds something to a ;; custom-reset-variables list. (defun pg-custom-reset-vars (&rest variables) "Reset custom vars VARIABLES to their default values." ;; FIXME: probably this XEmacs specific (apply 'custom-reset-variables (mapcar (lambda (var) (list var 'default)) variables))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Finding executables ;; (defun proof-locate-executable (progname &optional returnnopath extrapath) "Search for PROGNAME on environment 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. EXTRAPATH is a list of extra path components" (or (let ((exec-path (append exec-path extrapath))) (executable-find progname)) (if returnnopath progname))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Word utility ;; ;; This is adapted from simple.el in GNU Emacs 23. (defun pg-current-word-pos (&optional strict really-word) "Return the start and end positions of symbol that point is on (or nearby). The return value includes no text properties. If optional arg STRICT is non-nil, return nil unless point is within or adjacent to a symbol or word. In all cases the value can be nil if there is no word nearby. The function, belying its name, normally finds a symbol. If optional arg REALLY-WORD is non-nil, it finds just a word." (save-excursion (let* ((oldpoint (point)) (start (point)) (end (point)) (syntaxes (if really-word "w" "w_")) (not-syntaxes (concat "^" syntaxes))) (skip-syntax-backward syntaxes) (setq start (point)) (goto-char oldpoint) (skip-syntax-forward syntaxes) (setq end (point)) (when (and (eq start oldpoint) (eq end oldpoint) ;; Point is neither within nor adjacent to a word. (not strict)) ;; Look for preceding word in same line. (skip-syntax-backward not-syntaxes (save-excursion (beginning-of-line) (point))) (if (bolp) ;; No preceding word in same line. ;; Look for following word in same line. (progn (skip-syntax-forward not-syntaxes (save-excursion (end-of-line) (point))) (setq start (point)) (skip-syntax-forward syntaxes) (setq end (point))) (setq end (point)) (skip-syntax-backward syntaxes) (setq start (point)))) ;; If we found something nonempty, return it as a pair of positions. (unless (= start end) (cons start end))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Stripping output and message ;; (defsubst proof-shell-strip-output-markup (string &optional push) "Strip output markup from STRING. Convenience function to call function `proof-shell-strip-output-markup'. Optional argument PUSH is ignored." (funcall proof-shell-strip-output-markup string)) (defun proof-minibuffer-message (str) "Output STR in minibuffer." (if proof-minibuffer-messages (message "%s" ;; to escape format characters (concat "[" proof-assistant "] " ;; TODO: rather than stripping, could try fontifying (proof-shell-strip-output-markup str))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Extracting visible text in a buffer ;; ;; NB: this is possible automatic alternative to proof-shell-strip-output, ;; but is more reliable to have specific setting. ;; ;; (defun proof-buffer-substring-visible (start end) ;; "Return the substring from START to END with no invisible property set." ;; (let ((pos start) ;; (vis (get-text-property start 'invisible)) ;; (result "") ;; nextpos) ;; (while (and (< pos end) ;; (setq nextpos (next-single-property-change pos 'invisible ;; nil end))) ;; (unless (get-text-property pos 'invisible) ;; (setq result (concat result (buffer-substring-no-properties ;; pos nextpos)))) ;; (setq pos nextpos)) ;; (unless (get-text-property end 'invisible) ;; (setq result (concat result (buffer-substring-no-properties ;; pos end)))))) (provide 'proof-utils) ;;; proof-utils.el ends here proofgeneral-4.3~pre130510/generic/proof.el000066400000000000000000000026071214562307500205170ustar00rootroot00000000000000;;; proof.el --- Proof General theorem prover interface. ;; ;; Copyright (C) 1998-2009 LFCS Edinburgh. ;; Authors: David Aspinall, Yves Bertot, Healfdene Goguen, ;; Thomas Kleymann and Dilip Sequeira ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; Keywords: languages ;; ;; $Id: proof.el,v 12.1 2012/01/03 09:36:05 tews Exp $ ;; ;;; Commentary: ;; ;; This file loads Proof General. It is required by the ;; individual prover modes. Loading order of PG is: ;; ;; 1. proof-site (variables, autoloads & stubs for mode functions) ;; 2. stub -mode function sets proof-assistant-symbol and related variables ;; 3. prover-dependent variables defined in pg-custom ;; 4. stub explicitly loads /.el and execute real mode function ;; 5. .el requires this file, rest of PG loaded here ;; 6. further modules loaded by autoloads/prover-specific requires. ;; ;; ;;; Code: (require 'proof-site) ; site/prover config, global vars, autoloads (unless noninteractive (proof-splash-message)) ; welcome the user now. (require 'proof-compat) ; Emacs and OS compatibility (require 'proof-utils) ; utilities (require 'proof-config) ; configuration variables (require 'proof-auxmodes) ; auxmode functions (require 'proof-script) ; script mode (require 'proof-tree) ; proof tree visualization with prooftree (require 'proof-shell) ; shell mode (provide 'proof) ;;; proof.el ends here proofgeneral-4.3~pre130510/hol-light/000077500000000000000000000000001214562307500173165ustar00rootroot00000000000000proofgeneral-4.3~pre130510/hol-light/LICENSE-HOL-LIGHT000066400000000000000000000030571214562307500216150ustar00rootroot00000000000000 HOL Light copyright notice, licence and disclaimer (c) University of Cambridge 1998 (c) Copyright, John Harrison 1998-2008 HOL Light version 2.20, hereinafter referred to as "the software", is a computer theorem proving system written by John Harrison. Much of the software was developed at the University of Cambridge Computer Laboratory, New Museums Site, Pembroke Street, Cambridge, CB2 3QG, England. The software is copyright, University of Cambridge 1998 and John Harrison 1998-2007. Permission to use, copy, modify, and distribute the software and its documentation for any purpose and without fee is hereby granted. In the case of further distribution of the software the present text, including copyright notice, licence and disclaimer of warranty, must be included in full and unmodified form in any release. Distribution of derivative software obtained by modifying the software, or incorporating it into other software, is permitted, provided the inclusion of the software is acknowledged and that any changes made to the software are clearly documented. John Harrison and the University of Cambridge disclaim all warranties with regard to the software, including all implied warranties of merchantability and fitness. In no event shall John Harrison or the University of Cambridge be liable for any special, indirect, incidental or consequential damages or any damages whatsoever, including, but not limited to, those arising from computer failure or malfunction, work stoppage, loss of profit or loss of contracts. proofgeneral-4.3~pre130510/hol-light/README000066400000000000000000000031021214562307500201720ustar00rootroot00000000000000HOL Light in Proof General. Written by David Aspinall and Mark Adams. Status: not officially supported yet Maintainer: volunteer required HOL-Light version: SVN trunk (a moving target 8-) - tested on 118) HOL homepage: https://www.cl.cam.ac.uk/~jrh13/hol-light/ ======================================== This is a "technology demonstration" of Proof General for HOL-Light. We have written this in the hope that somebody from the HOL-Light 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 might also be useful for other provers. Another problem is that HOL scripts sometimes use OCaml modules, which will cause confusion because Proof General does not really parse OCaml, it just looks for semicolons. This could be improved by taking a better parser (perhaps from the OCaml mode for Emacs). 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: README,v 12.1 2012/01/19 12:48:02 da Exp $ proofgeneral-4.3~pre130510/hol-light/TODO000066400000000000000000000010351214562307500200050ustar00rootroot00000000000000* Prooftree support: fix problem with successive proofs (try example.ml with tree turned on, gives exn in Prooftree) [da to investigate] * Prooftree: fix evar support so it works Need patch for proof tree program and (maybe) modification of output [ma to do] * PG: add patch for background startup (needs testing) [da to do] * Integrate Tactic recording/proof refactoring (e.g. menu commands, also load point: if it is to work from Proof General, make it work from here, otherwise distribute it separately) [ma to do] proofgeneral-4.3~pre130510/hol-light/TacticRecording/000077500000000000000000000000001214562307500223625ustar00rootroot00000000000000proofgeneral-4.3~pre130510/hol-light/TacticRecording/INSTRUCTIONS000066400000000000000000000023711214562307500242540ustar00rootroot00000000000000To use this: 1. first compile HOL Light and any extra files up to the particular proof you want to record; #use "hol.ml";; #use .... 2. Then process the 'main.ml' file #use "TacticRecording/main.ml";; 3. Then perform the tactic proof you want to record, using g/e's or prove: g `...`;; e (...);; e (...);; OR prove (`...`, ... THEN ... THENL [...]);; 4. Use the ML export commands to output the proof in the form you want: print_executed_proof ();; - Tries to reproduce the inputted proof verbatim, with steps corresponding one-to-one to original. print_flat_proof ();; - Prints the proof as a flatten series single-tactic steps, with no tacticals. print_thenl_proof ();; - Prints the proof as a single-step tactic, connected by THEN for single goals and THENL for multiple goals. This structure directly reflects the tree structure of the proof as it was executed. print_optimal_proof ();; - Like 'print_thenl_proof', but prints a more concise proof, not necessarily reflecting the original tree structure. Currently this only performs one improvement: seeing where THENL can be replaced with THEN. proofgeneral-4.3~pre130510/hol-light/TacticRecording/LIMITATIONS000066400000000000000000000016651214562307500241110ustar00rootroot00000000000000ML objects that get recorded need to be promoted - and the promoted subgoal package commands don't work for unpromoted ML objects - implementor needs to write promotion functions for each type shape - implementor needs to apply these promotion functions to lots of tactics/thms - user needs to promote their own stuff, e.g. their own rules/thms Tactic proofs with embedded arbitrary ML are problematic - sometimes this can still get recorded, and if so then exported ML will work - but exported ML is unlikely to faithfully reproduce original ML text Limitations in HOL Light's pretty printer for HOL terms - it outputs ambiguous expressions without type annotations - this is used by my ML exporter However, in practice the appraoch works well - the same old pool of 100 tactics, 100 rules, 1000 theorems get used - and any promotion that needs doing is easy anyway - hand tweaks are occasionally required for aribitrary ML and type annotations proofgeneral-4.3~pre130510/hol-light/TacticRecording/biolayout.ml000066400000000000000000000022071214562307500247240ustar00rootroot00000000000000(* ========================================================================== *) (* BIOLAYOUT EXPORT (HOL LIGHT) *) (* - Support for BioLayout graph display of recorded tactics *) (* *) (* By Mark Adams *) (* Copyright (c) Univeristy of Edinburgh, 2012 *) (* ========================================================================== *) (* biolayout_nodename *) let biolayout_nodename n = "Node" ^ string_of_int n;; (* biolayout_export *) let biolayout_export path name = let nns = gtree_graph () in let suffix = ".layout" in let fullname = Filename.concat path (name ^ suffix) in let ch = open_out fullname in let export_line ch (n1,n2) = (output_string ch (biolayout_nodename n1); output_string ch "\t"; output_string ch (biolayout_nodename n2); output_string ch "\n") in (print_string ("Exporting to file \"" ^ fullname ^ "\"\n"); do_list (export_line ch) nns; close_out ch);; proofgeneral-4.3~pre130510/hol-light/TacticRecording/dltree.ml000066400000000000000000000236071214562307500242030ustar00rootroot00000000000000(* ========================================================================== *) (* DYNAMIC LOOKUP TREES (HOL Zero) *) (* - Library support for data storage in dynamic indexed binary trees *) (* *) (* By Mark Adams *) (* Copyright (c) Proof Technologies Ltd, 2008-2011 *) (* ========================================================================== *) module Dltree : Dltree_sig = struct (* This module provides library support for operations on dynamic lookup *) (* trees - self-balancing binary trees that store information on nodes *) (* ordered according to an index under '(<)'-comparison. *) (* This is implemented as Andersson trees (also called AA trees), that stay *) (* balanced within a factor of 2 - i.e. the maximum distance from root to *) (* leaf is no more than twice the minimum distance. This has a fairly simple *) (* implementation and yet is one of the most efficient forms of self- *) (* balancing trees. *) (* dltree datatype *) (* The 'dltree' datatype is a binary lookup tree datatype, where an index and *) (* item are held at each node, and leaves hold no information. Comparison *) (* between indexes is done using the polymorphic '(<)' total order relation. *) (* An integer is also held at each node and is used to keep the tree balanced *) (* as items are inserted/removed. This integer represents the distance from *) (* the node to the left-most leaf descendant of the node. Thus every left- *) (* branch node holds a value 1 less than its parent, and a node with a leaf *) (* as its left branch holds value 1. Every right-branch holds an integer *) (* either equal to its parent's or 1 less, and must be strictly less than its *) (* grandparent's. Thus the integer at a node also represents an upper bound *) (* of half the distance from the node to its rightmost leaf descendant, and *) (* thus an upper bound of half the distance from the node to any descendant. *) (* The tree is kept balanced by adjusting nodes' integers and left and right *) (* branches as the tree is updated. This is done by the 'skew' and 'split' *) (* operations. The number of nodes that need to be considered in this *) (* process is at most O(log n). Note that reference types are used for a *) (* node's branches, to save on unnecessary garbage collection that would *) (* otherwise result in rebuilding all ancestor nodes of all adjusted nodes *) (* each time a tree is updated. *) type ('a,'b) dltree0 = Node of (int * ('a * 'b) * ('a,'b) dltree * ('a,'b) dltree) | Leaf and ('a,'b) dltree = ('a,'b) dltree0 ref;; (* dltree_empty : unit -> ('a,'b) dltree *) (* *) (* Returns a fresh empty dltree. *) let dltree_empty () = ref Leaf;; (* dltree_reempty : ('a,'b) dltree -> unit *) (* *) (* Empties a given dltree. *) let dltree_reempty tr = (tr := Leaf);; (* dltree_elems : ('a,'b) dltree -> ('a * 'b) list *) (* *) (* This converts the information held in a given lookup tree into an index- *) (* ordered association list. *) let rec dltree_elems0 tr0 xys0 = match !tr0 with Node (_,xy0,tr1,tr2) -> dltree_elems0 tr1 (xy0::(dltree_elems0 tr2 xys0)) | Leaf -> xys0;; let dltree_elems tr = dltree_elems0 tr [];; (* Node destructors *) let dest_node tr0 = match !tr0 with Node info -> info | Leaf -> failwith "dest_node: ?";; let level tr0 = match !tr0 with Node (l,_,_,_) -> l | Leaf -> 0;; let left_branch tr0 = match !tr0 with Node (_,_,tr1,_) -> tr1 | Leaf -> failwith "left_branch: No left branch";; let right_branch tr0 = match !tr0 with Node (_,_,_,tr2) -> tr2 | Leaf -> failwith "right_branch: No right branch";; let rec leftmost_elem x tr0 = match !tr0 with Node (_,x0,tr1,_) -> leftmost_elem x0 tr1 | Leaf -> x;; let rec rightmost_elem x tr0 = match !tr0 with Node (_,x0,_,tr2) -> rightmost_elem x0 tr2 | Leaf -> x;; (* Tests *) let is_leaf tr0 = match !tr0 with Leaf -> true | _ -> false;; let is_node tr0 = match !tr0 with Node _ -> true | _ -> false;; (* skew *) let skew tr0 = if (is_leaf tr0) or (is_leaf (left_branch tr0)) then () else if (level (left_branch tr0) = level tr0) then let (l0,xy0,tr1,tr2) = dest_node tr0 in let (l1,xy1,tr11,tr12) = dest_node tr1 in (tr0 := Node (l1, xy1, tr11, ref (Node (l0,xy0,tr12,tr2)))) else ();; (* split *) let split tr0 = if (is_leaf tr0) or (is_leaf (right_branch tr0)) then () else if (level (right_branch (right_branch tr0)) = level tr0) then let (l0,xy0,tr1,tr2) = dest_node tr0 in let (l2,xy2,tr21,tr22) = dest_node tr2 in (tr0 := Node (l2 + 1, xy2, ref (Node (l0,xy0,tr1,tr21)), tr22)) else ();; (* dltree_insert : 'a * 'b -> ('a,'b) dltree -> unit *) (* *) (* This inserts the supplied single indexed item into a given lookup tree. *) (* Fails if the tree already contains an entry for the supplied index. *) let rec dltree_insert ((x,_) as xy) tr0 = match !tr0 with Node (_,(x0,_),tr1,tr2) -> ((if (x < x0) then (* Put into left branch *) dltree_insert xy tr1 else if (x0 < x) then (* Put into right branch *) dltree_insert xy tr2 else (* Element already in tree *) failwith "dltree_insert: Already in tree"); (* Rebalance from the node *) skew tr0; split tr0) | Leaf -> (* Put element here *) (tr0 := Node (1, xy, ref Leaf, ref Leaf));; (* dltree_remove : 'a -> ('a,'b) dltree -> unit *) (* *) (* This removes the entry at the supplied index in a given lookup tree. *) (* Fails if the tree does not contain an entry for the supplied index. *) let decrease_level tr0 = let (l0,xy0,tr1,tr2) = dest_node tr0 in let n = 1 + min (level tr1) (level tr2) in if (n < l0) && (is_node tr2) then (tr0 := Node (n,xy0,tr1,tr2); if (is_node tr2) then let (l2,xy2,tr21,tr22) = dest_node tr2 in if (n < level tr2) then (tr2 := Node (n,xy2,tr21,tr22)) else () else ()) else ();; let rec dltree_remove x tr0 = match !tr0 with Node (l0,((x0,_) as xy0),tr1,tr2) -> ((if (x < x0) then (* Element should be in left branch *) dltree_remove x tr1 else if (x0 < x) then (* Element should be in right branch *) dltree_remove x tr2 else (* Node holds element to be removed *) if (is_leaf tr1) && (is_leaf tr2) then (tr0 := Leaf) else if (is_leaf tr1) then let (x2,_) as xy2 = leftmost_elem xy0 tr2 in (dltree_remove x2 tr2; tr0 := Node (l0,xy2,tr1,tr2)) else let (x1,_) as xy1 = rightmost_elem xy0 tr1 in (dltree_remove x1 tr1; tr0 := Node (l0,xy1,tr1,tr2))); (if (is_node tr0) then (decrease_level tr0; skew tr0; skew tr2; (if (is_node tr2) then skew (right_branch tr2) else ()); split tr0; split tr2) else ())) | Leaf -> (* Element not in tree *) failwith "dltree_remove: Not in tree";; (* dltree_elem : 'a -> ('a,'b) dltree -> 'a * 'b *) (* *) (* This returns the index and item held at the supplied index in a given *) (* lookup tree. Fails if the tree has no entry for the supplied index. *) let rec dltree_elem x0 tr = match !tr with Node (_, ((x,_) as xy), tr1, tr2) -> if (x0 < x) then dltree_elem x0 tr1 else if (x < x0) then dltree_elem x0 tr2 else xy | Leaf -> failwith "dltree_elem: Not in tree";; (* dltree_lookup : 'a -> ('a,'b) dltree -> 'b *) (* *) (* This returns the item held at the supplied index in a given lookup tree. *) let rec dltree_lookup x0 tr = let (_,y) = try dltree_elem x0 tr with Failure _ -> failwith "dltree_lookup: Not in tree" in y;; (* dltree_mem : 'a -> ('a,'b) dltree -> bool *) (* *) (* This returns "true" iff the supplied index occurs in a given lookup tree. *) let rec dltree_mem x0 tr = match !tr with Node (_,(x,_),tr1,tr2) -> if (x0 < x) then dltree_mem x0 tr1 else if (x < x0) then dltree_mem x0 tr2 else true | Leaf -> false;; end;; proofgeneral-4.3~pre130510/hol-light/TacticRecording/dltree.mli000066400000000000000000000020061214562307500243420ustar00rootroot00000000000000(* ========================================================================== *) (* DYNAMIC LOOKUP TREES (HOL Zero) *) (* - Library support for data storage in dynamic indexed binary trees *) (* *) (* By Mark Adams *) (* Copyright (c) Proof Technologies Ltd, 2008-2011 *) (* ========================================================================== *) module type Dltree_sig = sig type ('a,'b) dltree val dltree_empty : unit -> ('a,'b) dltree val dltree_reempty : ('a,'b) dltree -> unit val dltree_mem : 'a -> ('a,'b) dltree -> bool val dltree_lookup : 'a -> ('a,'b) dltree -> 'b val dltree_elem : 'a -> ('a,'b) dltree -> 'a * 'b val dltree_elems : ('a,'b) dltree -> ('a * 'b) list val dltree_insert : ('a * 'b) -> ('a,'b) dltree -> unit val dltree_remove : 'a -> ('a,'b) dltree -> unit end;; proofgeneral-4.3~pre130510/hol-light/TacticRecording/ex.dot000066400000000000000000000005471214562307500235140ustar00rootroot00000000000000digraph G { subgraph cluster1 { label = "induction"; 517 -> 518; 517 -> 519; } subgraph cluster2 { label = "base case"; 528; } subgraph cluster3 { label = "step case"; 537 -> 538; 538 -> 540; 540 -> 542; 542 -> 544; 544 -> 546; 546 -> 548; } 512 -> 513; 513 -> 517; 518 -> 528; 519 -> 537; }proofgeneral-4.3~pre130510/hol-light/TacticRecording/ex2.dot000066400000000000000000000002641214562307500235720ustar00rootroot00000000000000digraph G { subgraph cluster0 { label = "process #1" a0->a1->a2->a3 } subgraph cluster1 { label = "process #2" b0->b1->b2->b3 } b3->23 b2->a3 a3->23 }proofgeneral-4.3~pre130510/hol-light/TacticRecording/ex3.dot000066400000000000000000000006061214562307500235730ustar00rootroot00000000000000digraph G { subgraph cluster1 { label = "induction"; 351 -> 352; 351 -> 353; 352 -> 358; subgraph cluster2 { label = "base case"; 358; } 353 -> 367; subgraph cluster3 { label = "step case"; 367 -> 368; 368 -> 370; 370 -> 372; 372 -> 374; 374 -> 376; 376 -> 378; } } 344 -> 345; 345 -> 351; } proofgeneral-4.3~pre130510/hol-light/TacticRecording/ex3.png000066400000000000000000001153341214562307500235760ustar00rootroot00000000000000‰PNG  IHDRû#)2Ï bKGDÿÿÿ ½§“ IDATxœìy TëÿÇŸcË%Ù£ e+?Eꢒ6•nY*Zˆ¤º¡ÛE*I…Û¢R]©®6nÛ÷Rh»·q[(•\[ZÄ $똙óûãÜï|]$cÎÌ™1Ïë/gyžç=ïyæ9ç<çó (ŠDb"Z"T ã!’tëyö왓“SVVÖÓ§O—.] pttìrNNNެ¬laïå¯#’‘‘ÁUèx4==AƒÁg=±±±Üy¼L&SQQQ^^¾ó õõõ!!!ØC¢.e{9Ô?ÆïííKU 8ªt:}̘1ÚÚÚ|Ö ''ÇÝd±XîîîÜME#""‚‚‚º[z9ÔofÏžM§Óñªm >|hee…c…gÛ¶m±±±ñññÜqqqnnnŠŠŠÝÏïåP¿±²²*--ýøñ#Žu à ,P^^>kÖ,¼j»zõêþýû³²²ôôôPõõõEäáÇ,«ÇïU/‡øÁÐÐEÑòòòÁƒã[³¸>~üˆ£-¦L™bhhx÷îÝàà`??? …²`Á‚„„„_~ù¥Ç¦¿vˆOTUU=Þ,’p ãAKKKçñ7Ÿ(+++++)**._¾<)))33ÓÏÏïåË—Ø ííí€ââb …²uëÖ¯9r$?2°OÔÜÜÌׇzÝ,¨©©ÅÅÅá^íçÏŸsæÌùZº¥‘#GörˆÏÖ«««t:—Ï2€W®@UUµ¶¶÷j«ªªóæÍkkkëqCCCŠ¢¯^½ê埭×ÔÔ€ÿŽm ŽfffOŸ>å¿žØØØS§N566Z[[ƒ‚‚¼¼¼|}}ù¯¹äææÊÉÉ5ŠÖE8Ž'NŒŒŒDQ”ÏÛáõõõ öðð P(!!!'NÄK$¯dgg[XXP(¢ˆ,pî$ÈËË7nN·±±!Z >°X,]]]ooï;w­E䀣0vìX ‹„„¢…àFZZÚ‡¼¼¼ˆ"Š@Ç€——×åË—ß¿O´|8räÈ´iÓ† F´QŽj€Édš˜˜ØØØœáØDGGGvvvhh¨¾¾>@__?::Z4`;༚þÃ`0.]º”œœœ-%%eaaaooobbbdddddD¥Rû^Š¢eeeÿýwqqñ½{÷ètú—/_tuu]\\\]]±Å“!¸ÕÕÕ÷îÝËÊÊ¢ÓéÅÅÅ,‹L&5jøðáÚÚÚ:::Ý_)lll¬¨¨(//g0%%%_¾|èèèLš4ÉÆÆÆÎÎÎÄÄǼ| èxœioo/,,,((()))//¯¨¨¨ªªª©©a³ÙØKßYYY¦««‹}%Fellljjª¢¢B¬þt¼PA$99ÙÕÕ•h!’ œ- ‘, ã!’t^à,[¶¬{7/%%emm í.| ãÎâÅ‹»ïDdÙ²eÂŽ8jjjvvv$©Ë~gggBôH8ÐñÂÀÃãóõ™LvppPUU%P’Ä/ -ZD&ÿïF0›Ívww'P$/  4gÎ …‚mJKKÿý÷ÄJ’X ã…„»»;‹ÅP(”ùóçÓh4¢I(ÐñBbîܹrrr€ŽŽŽ¥K—-GrŽ222 ,Ðh´™3g-GrójK]]]eeemm-›ÍÖÕÕL˜0áÖ­[²²²rrrzzzÝo\Bœe€(Šçåå½xñ¢   ¸¸¸¢¢¢µµµ÷Rd2Y]]]__ßØØØÔÔÔÔÔÔ‚;¹‚;ÐñüòæÍ›ÔÔT:ž••U[[+''g```hhhhh8lØ0mmm î +**ÊËË FiiiIIIQQQ]]ŒŒŒ¥¥¥­­íÌ™3'Mš$%GžxßOjjjRRRòòòTTTìíímllìììLLLøñhee%öå¹{÷nII‰ººº““Óš5kÌÍÍq/Ñ ¹s玛›•JUWW_·nÝíÛ·;::ÑPaaaddä¸qã–––'OžljjDCt<\¿~}„ ‚L:õâÅ‹íííÂi7;;ÛËË‹F£©©©ÅÄÄ477 §Ý t|Ÿxð॥%ÀÑÑññãÇ„h¨©© ”““SWW?zô(‹Å"D†¸ÿ êëë½¼¼™>}zNNÑrÐ÷ïßP( ¢¾{b t|oÐét===--­””¢µü‹Â©S§R©Ô}ûö±Ùl¢åˆÐñ_%22’D"999ÕÖÖ­¥Ølö¾}û¨TªƒƒCCCÑrÄèø`±XkÖ¬!‘H‡"ZË7xò䉖––™™Yee%ÑZÄx?¾+®®®çÎ[¸p!Ñr¾MYYÙìÙ³[ZZnݺe``@´Q:þ_ (ºlÙ²«W¯¦§§ÛÚÚ-§¯|üøÛÜ¿_SS“h9" |‚ý/BCC“““SRRÄÈî€Áƒ߸qAGGǶ¶6¢åˆ6ªD‰ŒŒ ))©£G-¤Ÿ¼|ùRQQÑÏÏh!" tü?ÔÖÖª««»¸¸-„/.^¼HMM%ZˆèÇñÿ°qãÆäääââb%%%¢µðÅÒ¥KŸ={–ŸŸßù]rÈÿ ú+'”––R(”øøx¢… (Š–••ñY\FFFD>‹¯\ >>^GGÇÛÛ›Ïzž›îÎøñã½½½q¯vnݺÕÈÈß:™L&Fóõõåîáp8þþþ †††\dzÙl###yyy{{ûÐÐÐׯ_ã% ,,ÌÀÀ¯ÚÐñè”)S<==q¬ÍfÿøãÇŽãp8Ü|ô芢ÿéÓ'ÿéÓ§c ›¨TêŽ;pÑ––† H]].µ $ ãÑ#FìÙ³¯Ú®\¹bccÐÓÓ‹ÇLÿàÁƒØØXì„ÎŽçÒÐÐ¥ñ8qâÿ2JKKOŸ>忪t<ª¨¨øË/¿àU[}}}AAA\\v…šPWWçååÅÅÞ£ã1âãããÆã_ƧOŸ7oÞ俪|HZZZ°üx¸ ¬¬¬¬¬ldd¤¨¨¸|ùò¤¤¤ÌÌL??¿—/_b'´··Š‹‹)ÊÈ‘#;—õñññ÷÷Ǻg>Á>Qss3ÿU 0 ã²²r}}=îÕ:99h4Úï¿ÿþÛo¿u9:f̘‘#G¾zõªóN‰¤¢¢¢¦¦ÆëØ'si”öööM›6!"^¿HÄÿUŠŠŠÌÌÌ”••Em¹Œ’’KKK…sçέEœ€Žï––€£££ètömmmáááÒÒÒcÇŽ-))!ZŽ˜ÿmÒÓÓõõõi4ZPPPMM J:::GŽI£ÑvïÞÝeæ=¤/@Ç÷‰¶¶¶˜˜555yyù-[¶TUU _À©S§FŽI¡P¼¼¼Þ½{'dèxhjjÚ»w¯¦¦&…BY´hQzzºzÙ¼¼¼ÀÀ@UUUiiiOOOsÚH&Ðñ<Ãd2/]ºäàà€ ˆ’’ÒŠ+RSS?}ú„cÙÙÙ¡¡¡úúú}}ýèèhÑ\€Mì€ójúƒÁ¸téRrrrvv¶”””………½½½‰‰‰‘‘‘‘‘•Jí{U(Š–••ýý÷ßÅÅÅ÷îÝ£Óé_¾|ÑÕÕuqqquuÅO†àt<TWWß»w/++‹N§³X,2™_D„t:gÚÛÛ JJJÊËË+**ªªªjjjØl6öÒ7@FFFVV–F£éêêb_‰Q£F›ššª¨¨«À/TINNvuu%Zˆäg C$ èxˆd‘, ã!’t}êw£oß¾]¾|yVV?2 ½/*0Œ¹sç²Ùl¢… pਦ+l6;%%eÅŠ¶¶¶(Šþç?ÿY½zµ¶¶vMMÍ÷ß?hÐ KKËüü|ìd&“¶nݺ   ææflÿñãÇÁž766ÆÆÆr7---±±±žžž›6m²²²Ú³g‡Ã9}útaaáû÷ï׬YÓEVêóçÏAAA?þøc@@ÀŒ3°Dh½+„t…§ f......8§E=>~ü044äp8òòò€;w–••]¿~0iÒ$EÙl¶½½ýŠ+°Õ ^½zE"‘¸!1bDçðb›€óçÏ;88xxx°ÙlEOœ8¸v튢X£Ýe (򯯬¯¯Žúðჾ¾þðáÃëëë{Q8à$''óV„§³%ÄñØÕ'×|\ïr8uuu*•Š¢è©S§yyyÜ‚XšHìoCCÃÎŽÇ6Ë–-cû™Lfbbb}}=ÚÍñeüôÓO€Î9Ïœ9 êEဧއ£šè2#¯ó&–]•ÉdÒÒÒ£Fâ•’úv< Ü()Ч§gó‡;·{ÿþ}@ç…f±Ñ΃zQét|ÿyûö-àóçÏ<•ÂòK–––òT û.•••q÷`¯A(**òT:¾ÿ`½{fffG±~·­­ Ûävº#GŽDFFrïÜ—••ýöÛoØß,«ÇÚ°£c`wîøý’Oc Çc)Qµµµ±M===w1=---@{{{NN‰D2dÈÍ›7[ZZîܹƒ:^½z…¢èÂ… ?ýôÓË—/ãâ⸒Ž=Ša¦NzøðáÐÐЙ3g655¡(ª©©)++ûüùóî2š››µµµ¹Cù 6Lž<¹£££… A8ŽçŸæææÝ»w*++8õîÝ;@DDÄçÏŸ8PUU 111¹{÷îèÑ£-Z4zôè¿þúkܸq¾¾¾eeel6;66vêÔ©ðððøî»ïŒŒŒ<<<ƒ ÊÍÍuvv.**Ú¶m[EEů¿þJ£Ñ»wï–‘‘Áúû.2X,ÖÇ—.]ºbÅŠÍ›72äÎ;d2ùÈ‘#_SØÚÚJXEÞÞìÆ^Wƒoýõ˜[_úOØÇC$ èxˆd‘, ã!’t­ZµjòäɃ ÊÉÉIKK?~}útJJÊ?ü@´œo`aaqÿþ}&“immýòåK¢åˆÐñÿEQOOÏ›7offfb‹|ˆ>Æ û믿>~ûöíJJJÂi[ODEE•••%$$¨~q:âããutt¼½½ù¬çÉ“'ööö ZZZ>>>uuuÜCqqqH'°ŸŒÊÊÊÄÄDWWWkkk>ôôôV¯^ò²Š£äçǃ¶¶¶Ó§OuIÆ+ÏŸ?ßµk׎;h4ZLLLBBBuu56¤îèè¸páBTTv&‚ óÕhkkÿý÷«V­244äG—µkׯÅÅݼysæÌ™¸T8€Žþùç§OŸøÏy÷îÝóçÏc™˜NŸ>}ýúõ{÷îa‡.\¸àáá±víÚ¯•ÅVñÆ CCC ‹K—.AÇw:Ðéô1cÆhkkóYO—Û‚, [¤›ÃáìÝ»·¼¼üÊ•+ÖÖÖžžž#FŒà³­o2{öìäädA·"ŽÀqü?sßq¬ÃálÛ¶-666>>ÐØØ8sæÌ‰'>zôh×®]cƌٹs'ŽÍõˆ••UiiéÇÝØÊËËñ@®^½:eÊ”={öDEE?~EQ%%¥ŸþùÖ­ÊIé IDAT[•••l6;<<ü—_~Á«Å144DQ´¼¼\ ­ˆ#ÐñàãǃÆ«¶)S¦;v,..®¦¦ÆÏÏ/11‘{HQQ144ôðáÀ£GâÕb`ó=;ß,‚`@ǃ–––ΉùDYYÙÈÈhýúõÇ$%%u9ÁÇÇGFF¦´´¯{ûDÍÍÍmEW®@YY¹¾¾÷j±h4Z—ý$IEEEMM ÷;ƒ}"» °ªªªµµµ¸W‹½¢1oÞ¼îû«ªªÜÜÜpo±3555à¿cHg ã™™ÙÓ§Où¯'66öÔ©S€ÖÖÖ   ///__ß;wþðÃEEEØ~???77·   Îe±áŽo¬æææÊÉÉ5 ¯  pT&Nœ‰¢è×^í#õõõ öðð P(!!!'Nhjj¦¤¤$&&:;;ËÉÉmذÁÞÞ¾sÁ?þøãìÙ³€²²²ŸþyÚ´iXV&~ÈÎζ°°à®Ñù|ðòò"Zˆ(^^^—/_~ÿþ=ÑBðáÈ‘#Ó¦M6lÑBDèxðööÖÒÒ !Z\¿~ýÎ;»wï&ZˆˆT*uûöí¿þúknn.ÑZø¢­­mË–- .…ôi¢ tü?,Y²ÄÁÁaÉ’%_¾|!ZKÿ ¨®®>pàÑBDèø@$11±¡¡ÁÓÓSL39&%%ÅÇÇ?~\GG‡h-¢ tüÿÐÐиpáBZZÚÆ‰ÖÂ3™™™«V­ pvv&Z‹HŸ@ý {{ûóçÏ»ººÊÈÈìÛ·ÏgRBãæÍ›ÎÎÎîîî111Dku`ß•… ž9sæàÁƒË—/ÇVÙqΞ=;wî\''§„„qùŠt|¸»»§¦¦^»vÍÎÎNpi6ø‡Édúûû/_¾|ãÆIIIp]ؾß33gÎ|üøqss³¹¹ùo¿ýF´œxùò¥ÍÉ“'Ïž= {÷>ÿUFýèÑ#gggWW×¹sçŠNgßÞÞ¾}ûv33³ööö'Ož,]º”hEât|oÈÊÊž8q"==ýåË—ÆÆÆÁÁÁ‚˜IßwX,Ö©S§ŒcbbÂÃó³³ Ô#Ž@Ç›Y³fåççïØ±ãÌ™3#FŒøñÇ…Ÿ¦½½½ýôéÓ£Göõõµ³³+,,ܺu+\̾@Ç÷ iiéÍ›7¿yó&,,ì×_ÕÓÓsvvÎÈÈhootÓ/^¼ ÒÑÑY³f­­mqqñÉ“'uuuÝî@:žh4Zppð»wï.\¸ÐØØ8gÎ •+W¦¥¥544àØ‹ÅÊÉÉ 300;vìþóŸ-[¶0ŒÄÄD!dwØÀ'P~ü8ÑBÄèøžIKKËÍÍýC[[Ûßß?<<¼¾¾žh-¢t|p8œ üßÿýÑZúÊ?þ(--½gÏ¢…ˆ:ÐñðáÇÃݼråJAA¸tðòòòÛ·o?xðàëׯ¹;Qmii!P•X,–¾¾þ˜1c._¾Œ¢(›Íwss366&Zox{{pßÊÊÊ?~üèÑ£‰U%jÀUq@yyù—/_šššœŒŒfÍšõòåKq¼ÙG"‘öîÝ;wîÜ œ;w.55UJJŠÃáTWW .3¦ØJKK(ŠŠ‹‹‹ŠŠÔÔÔž?>jÔ(‘š:ÖÌÍÍÕÕÕ—,Y‚½¶‚ Õòóó¡ã¹ÀQ xýú5™üÏ7ŸÃá (Z[[ëêêjaa‘ššJ¬¶¾óåË—üqĈ?~DQ”{ožJ¥æçç«M¤€ŽoÞ¼éòž·kœ?þÏ?ÿL.xúôé˜1c¢££ÛÚÚº¼Åáp ‰&‚@ǃ—/_~íi¥¼¼üwß}'d=ý ¼¼¼ºººóí&.,ëéӧ—$²@ǃ¢¢"lß2™¬¢¢’““#+Ä/X° ##CVVVJª‡hQQQ_ÉDÒÏápº¯9C&“555=z4fÌBTõ‡{÷î)**r¯I¸´··¿yó†U"ˆ¤;¾ªªªË†L&:ô¯¿þ>|8QªúÇ„ ž|(ˆµû„Àˆ#?~‡×X ÄØñ(Šçåå½xñ¢   ¸¸¸¢¢¢µµµ÷Rd2Y]]]__ßØØØÔÔ477EÑéÓ§_¹rEø)á ‚ ûöí:tèÆÙlvzzzkk+?±255µ°° *¯2^ˆŸãß¼y“ššJ§Ó³²²jkkåää /^|ˆŒŒ;v,@EEÅÅÅåСCyyyl6›Ÿj Æùóçýüü êêê«W¯~úô)^² ArbHNNæ­Ogâø;w¹Q©TuuõuëÖݾ}»££C FFFŽ7`iiyòäɦ¦&A4$8$-VÍñׯ_Ÿ0a‚ S§N½xñb{{»pÚÍÎÎöòò¢Ñhjjj111ÍÍÍÂi—$3VÇñ<À&´8::>~üX-v§¦¦&00PNNN]]ýèÑ£,‹ßD’c5___ÝHž>}zNNŽ@Ûê ïß¿ P(DùékÀX‰½ãétºžžž––VJJŠàZé………S§N¥R©ûöíãóú/`¬Pqw|dd$‰Drrrª­­PüÀf³÷íÛG¥Rˆc…!®Žg±XkÖ¬!‘H‡½r|yò䉖––™™Yee%!`¬:#–Žg2™ ,‘‘Á’gˆ>oß¾=z´®®nII‰›†±êB?Oð33E===oÞ¼™™™¹páBbÅô‘aÆýõ×_ƒž5kVuuµÐÚ…±Â‚šœœœ’’bkkK¬ž>žÿªúHYY™àj–‘‘Üg±ê .}|||¼ŽŽŽ··7Ÿõ}ºtéR€££#vˆÉdZ[[Gý—={öTTT`‡6lØàîî~øðá 6ÈÈÈ~ùå>•#’‘‘Ág=Ý!6V½”ê7øÆ ˆÅ•kzz:‚ ƒÏzbcc¹sS™L¦¢¢¢¼¼<¶yæÌ™#GŽt/òöíÛ%K–p7333†††|*AQtüøñÞÞÞü×ÓcÕ{)~À1Vâáø­[·ñYI˜L&FóõõEQ”ÍfÉËËÛÛÛ‡††¾~ýš{ZVVVuu5w“Ãᨪªâò_ 300࿞.«^Jñ ޱÇO™2ÅÓÓ“ÏJ:Ãf³üñÇcÇŽa¹°?}úäïï?}út,1•JݱcG9ΠAƒf̘Á¿†´´4Aêêêø¯ª3"«.¥øÇX‰‡ãGŒ±gÏ>+áråÊl…a==½øøøÎÿ’†††ˆˆ,ÿĉ'º—ÍÊÊ¢R©=â_¶ìî/}ŠB¬z)Õ?pŒ•x8^QQ‘ÿ‹E.õõõqqqXî„„„.'ÄÇÇÆ×eGGÇäÉ“OŸ>‹ŒOŸ>nÞ¼‰Km\D!Vß,Å+8ÆJ<O¡PÎ;Çg%Ýùõ×_vvv]ö³X,ÖeÿÖ­[úé'¼Zooo\½z¯ 1D$V½—âcÕǯFYYY í:99º'#‘H***jjjw^»vMFF&,, ¯Ö±O4xð`¼*Ä…X}³¯(V}„€'Pªªªµµµ¸W[UU˜7o^÷ýUUUnnnÜ= cÛ¶mÜÌDYYY|¶^SSPUU峞.«¾”âŪÐÇ›™™á’ø366VEEeÑ¢Eƒ jmm òòòòõõݹsgmmíÚµkÇŒÓÚÚêçççææ„•ºuëÖÞ½{-Ztøða‡Ã)))QTTÄ.ÎúMnn®œœÜ¨Q£øÿ\!6V_+ŧŪàø‰'FFF¢(ÊçÚ‘õõõ öðð P(!!!'Nhjj¦¤¤$&&:;;ËÉÉmذÁÞÞ+òàÁ''§ÖÖÖ?ÿü³sU×¹îÙÙÙ]–*àcÕK)>P¬ú O£~\®\Ÿ? Óé|Ö#:ttthjj†……á^3ŒUﱘI6vìX ‹„„á7- ÒÒÒ>|øàåå…{Í0V¸CÌÜI//¯Ë—/¿ÿžÖqçÈ‘#Ó¦M6l˜ *‡±Âbïíí­¥¥BHëørýúõ;wîìÞ½[@õÃXá Oc ßú;wî™L~òä .µEkk«±±ñ¢E‹Ú ŒÕ×b1ŽÇX²d‰ƒƒÃ’%K¾|ùB”þ ¨®®>pà€@[±Â HbbbCCƒ§§§˜®(””üøq6c…'<ý"àž“ìöíÛÒÒÒëׯDZNá‘‘A¡P„Ö"ŒUw€XÌ$ëÂåË—I$R`` .s¯…Cff¦¼¼üÊ•+…¬ƪ béxEÏž=K¡P<<<˜L&î•ãNRR…Bqww'd «Îˆ«ãQÍÈÈ——·¶¶\êþiooß´i‚ Äö²0V\ÄØñ(Š™™™)++‹Ú%%%––– ‚˜°Î+0VâíxE[ZZ|||ŽŽŽ¢Óµµµ…‡‡KKK;Vø´¿Œ:‘žž®¯¯O£Ñ‚‚‚jjjÝ\/ttt$&&Ž9’F£íÞ½»­­@1="á± ŽGQ´­­-&&FMMM^^~Ë–-UUUBh´‹€S§N9’B¡xyy½{÷NÈúŽ$Çjà8£©©iïÞ½ššš eÑ¢EéééBè9òòòUUU¥¥¥==={Iá"RHf¬šã1˜Læ¥K—QRRZ±bEjjê§OŸpl¢££#;;;44T__ ¯¯-š‹ŠõŽ¤ÅªŽGP^r^ºººRRRp|èÛw Æ¥K—’““³³³¥¤¤,,,ìííMLLŒŒŒŒŒŒ¨Tjß«BQ´¬¬ìï¿ÿ...¾wïNÿòå‹®®®‹‹‹««+¶ °X#!±B$99³e_‹ˆ‘ã¹TWWß»w/++‹N§³X,2™^ì}ܼyó°aÃÊËË•””,--ét:V¤‹ãXÐþ§ fßÌÂúœÍÐÐ|óæÍcÇŽÉÉÉQ©T,ÿ²¾¾þˆ#Pe2™ŠŠŠcÆŒÁŠ©¨¨`é÷œœ>|øÀáp–-[VTT„ààà ¦¦öùóglséÒ¥NNN(Švtt888xxx°ÙlEOœ8¸víŽm -n_“‡UbhhˆÐ£ÚúúúÔÔTìÍÀÀÀ{÷î;wN^^žL&cgΜ9ÓËË +BxÐPÄ Å=ï$¯ŽçfÅ=\µjŠ¢ÇŽ;q⊢l6{Ĉd2;GUU°ÿ~6›ýâŋϟ?geeuÿ§¦¦b绹¹a«‡ÆÆÆŠ‹‹±ýL&311±¾¾Ƕ„·¯ÉCÿíø^Ôbù"ÛÛÛ±3÷ïßðññAQtþüùîîîØ~ƒ&ˆ¸¡®çŠÍ^,X°ðâÅ €¯¯¯««ëÁƒ#""ÚÛÛY,vN|||û›ÛÇ?+Î]þ·¬¬ì·ß~ñ-!Ó]¶ŸÛÝö]-æl;;;ðoǼ ýOc ÇU£G|üøEQ‡ãçççàà€]$)++KIIýõ×_¿üò vÛþÑ£GåååƒÆ~a³ÙJJJÖÖÖíííØ¨ÔËËëìÙ³!!!Ü £Ù³g{zz¢(ZUU…ýO:õðáá¡¡3gÎljj±-¡Å £»<E555eeeŸ?Ž¢h/j±+(îr“§OŸ=ztKK Š¢k×®µ³³Ãö4AÄ %ðÊõÖ­[óçÏŸ6mÚªU«üüü¢££;::°C'OžTVV;v,N?zô¨²²òŒ3jkkÆ Û±cÇúõ뜜°ÕWÊËËœœ”••ÕÕÕ}||:¯…äàààííýýæÍggg •+V`77plKhqãžß]Þ©S§”••CBB°s¾¦sü±cÇjkkkkk£¢¢°Cþþþ'Nä¶BlÐÐæx!0mÚ´5kÖ­EE,n˜ã{<ôã?š›› GF_€÷j œIÆ+ð™«xg ÷ö(Ë\Ðèxñöñ]hjj ®ªª¬^½úÁƒ]NÇä.öñ]——ß·oß¾}û¾v‚$8öñÿ/ÞÀ>žW ãÅŒßÿ}РA ÿåÕ«WÇŽÓù/sçÎå>>„pÙµk—©©©©©©ŽŽ6ËWAAAVVAA¶oßN´@œP] ¬¬,v#‚Kç•ë¾|ùÂb±xZ¼WHII)((@{ZäAA¿‹,|T?mÚ´¯­9J¥RW®\ íÞŸ^–C\´h‘0Ååx‰äææÖ£­™Læ²eË„/IôqwwïÑñ‚XXX`3+Êñ—Ÿ­`“!]PQQqrr¢P(]ö“H$É/ÍñvvvØ›8¡P(+W®$BŽx°jÕªŽŽŽ.;Y,ÖÂ… Ñ#Pšã¥¤¤\]]» lØlöòåˉ’$ú̘1CCC£ËÎÑ£G9’=e 9tØHIIMš4I[[›@I"Ž””ÔªU«:l(Š››’Çt¼­­mç ‚ ^^^ê V­ZÅ} ÐÑÑ1 ‡4`@:^JJªó2™ìììL¬$ÑgøðáÖÖÖÜIC‡533#V’€€Ž6 åûï¿Ç^[†ôŽöLšJ¥.^¼˜h9‚b`:ÞÆÆØttt¬X±‚h9â‹‹ –¼‰Éd~ÿý÷DËÓñRRR...eeåéÓ§-G< ÑhXÐleeE´A1pæÕ°X¬÷ïß———·´´´¶¶ª©©¬­­ïЬãL IDATܹC"‘† ¢££3ðf‰ðOç¸a &ÌÍÍ/_¾— qëŒx8>77÷øñãÿùÏjjjF=mÚ´µk×ÚÚÚö}ž“ŠŠŠ‘‘Qç='??ŸN§Óéô;vlܸÑÜÜÜÅÅÅÛÛ[«9· <H/|ùò%!!›fnn¾{÷nn^f|éèè¸uëÖÚµkÕÔÔ¤¥¥—,YòÇàX?Œ[ÿ  MMMMûöí2dFóöö~üø1ÿuö…¶¶¶ .L™2A++«ôôt\ª…që‘¡‰Íf9rdøðá;vìðòò*++ûå—_„6ÑWZZzñâÅüñÇ£GTTTfÏžmmm-œÖùÆ­ˆ–ã?~þ,´FaÜø‡Ç·µµ.[¶ {ÿ@|IHHèèèè%;¾À¸áŽ?|øð‡vïÞ-œæÞ½{' š•••·mÛ¶ÿ~ƒ! &:#´¸½{÷...nïÞ½=._Ì?BŽ[„íx‡søðáµk×r—?ïOž<±··WPPÐÒÒòññ©««ãŠ‹‹C:íGQôäÉ“óæÍÛºu«ƒƒÃ† øÿaõõõUUU‹‹ã³žo"„¸š››7oÞ<}útSSÓàà`l)V;;;¤¯_¿æG†ÐâÖaßOOO¯¨¨X·n?•<þ|×®];vì Ñh111 ÕÕÕiii€ŽŽŽ .DEEag"âîîŽý}ìØ±µk×>{ölܸq>|:t(ƒÁ¸rå ?J¨TêªU«âââvîÜ)--ÍOU½#è¸æÌ™óñãLJr§å|þü9::š»';;ûþýû|^H-n= äÙ›žžž“'Oæ©ÑîÄÆÆ677c3™LEEEyyylóÌ™3GŽé±”µµ5àýû÷ئ¶¶6·?¼~ýA›7oörŽèÇ EQggg))©‡v.ráÂ…ÚÚÚÎ{V®\¹sçN>• ÂŠ[w„=ª¡Óéü'““ãn²X,¬#ǦUmÙ²eúôéaaaoÞ¼é\ [sý÷ßÔ××WVVN™2…O%€#FÐétþ«êÆ p÷îÝK—.Íœ9sâĉ‹,^¼¸ó4Ìööö«W¯â’ñJ8qëŽP_SSóúõë.1凳mÛ¶ØØØøøx@cc#ö?{ôèÑ®]»ÆŒ³sçNîÉû÷ï>|¸¿¿NNNHHHPPÐ… p‘aeeõðáC\ªêAÇ pæÌ€¶¶¶•••‚‚‚µµõŸþÙ½`ff¦ŽŽ^¯u :n="TÇWTTðšâwõêÕ)S¦ìÙ³'**êøñã(Š*))ýüóÏ·nݪ¬¬Œˆˆ`³Ùááá¿üò v¾Á£GÌÌÌììì¨Tê¾}ûäååqQbhhX^^ŽKU="踰 ½&L¸}ûö­[· †½½}~~~—²ÉÉÉ8ÞtÜzD¨Žÿøñ#¯ä'S¦L9vìX\\\MMŸŸ_bb"÷¢¢bhhèáÇGåîoiiQVVž2eÊ¡C‡ñZMUUµËM|BÜ*++544V¯^­  0qâĨ¨(‡³ÿþÎ[ZZ~ÿýw/è¸õˆPßÒÒ••Å¥6eee##£õë×?~””ÔåîMåG?~åʕ׮]›4iRlllXX.Jh4Zss3.Uõˆ⦬¬ÜyJãÔ©S Þ¸qCWW·Kj~tÜzD¨ŽÇ®?}ú„oµNNNÖe?‰DRQQÁn*~úé§?N™2EZZúâÅ‹€'Nà"àãÇÍÚ%„¸ÔÔÔ ÿÕˆ]­võ%''㛥YÐqë¡:ûxµµµøV[UU˜7o^÷ýUUUÜÌÿØÂ/XO6tèP555¼ÞN¨­­èNq[¸pa{{ûóçϱCX[–––Ü“›šš®_¿ŽïAÇ­G„êxCCCYYÙÜÜ\>ë‰=uêTcc# µµ5((ÈËËË××wçÎ?üðCQQ¶ßÏÏÏÍÍ-((+åááHMM0Œšš¼–ÁÈÍÍ;v,.Uõˆ ãðõõ1bDtt4ÖÍ_½zUMM:Àï¿ÿ®§§glļ†Î:n="Ôg® ÅÜÜ<;;›ÏU™êëë<ìááA¡PBBB°;wššš)))‰‰‰ÎÎÎrrr6l°··ç–Z½z5‚ ‡~úôé»wï¶nÝŠË8EÑœœ®m-踤¥¥>|°lÙ²aÆ•••=yò¤óü{ì. ‚ |}’N!n_m¸ïðÿ ì§Ÿ~ÒÖÖf±X<µ+Êܽ{ŸŸßË90nÝNܺ#ìg®«V­ªªªÊÈÈr»‚#!!ÁÊÊÊÄÄD ­À¸á…°?bÄ[[Û#G޹]QUUuõêU!¬¬ã†Ìß»woFFFff¦ð›Æ­[·6L8ÿ97\ ÀñVVVóçÏ joo~ë8’““sîܹððp2Y7`Üp˜÷\:TQQÑùæ—Øñùóç%K–Ìž=ÛÕÕUh¸ñ1Ž×ÕÕ?|ø0^³… ›Í^±bEKKËÉ“'q¼a÷M`Üø‡°œd‹/~ðàÁÊ•+‡ "vËñ­_¿>333##Cø)4`Üø„Èœdpuu]¸p!ÙKx…Ãáøûû'$$$''ÛÙ٢ƈt¼””Ô©S§çÌ™#?ÓL&ÓÃÃãèÑ£IIIóçÏ'JŒ?è•L>wîÜÚµkÝÝݱÉ^¢IYY™MZZÚõë× _ÄÆ­ßŸ?^JJjÿþýgΜ9~ü¸€r¤ðIrr²¹¹9“É|üø±ˆŒžaÜúñŽÇX¶lÙ“'OZ[[MMMwîÜ):·œß¾};gΜŋ»¹¹=|øPÔV%€qãQq<ÀÐÐ0''',,lïÞ½¦¦¦gΜa±Xê©©© 411yýúuffæ±cÇdddÔó5`ÜxB„–– ),,œ¥¥¥­X±B]]}Þ¼yÍÍÍ)))ïÞ½Û¼ysç|FâŒ[ï¿òYï 2$888((('''%%åôéÓ vvvvvv†††&&&Æ ãé‘u{{{QQQaaá‹/îÞ½ûôéS‡cmm½cÇgggmmmÁ}¡ãö5DÝñØÚçVVV111ùùù÷îÝËÊÊ:pà@ee%@AAÁÐÐpè4hP—â(оÿžÁ`0Œ·oß¾~ýšÅb‘Éä1cÆØÚÚnÞ¼ÙÖÖVSS“ˆO&X`ܺ#Žç‚ ˆ™™™™™Ù?ü¨¯¯ÏÏÏ/(((--­¬¬|üøñ•+Wš››[[[ÛÚÚ°"ƒ "‘HjjjÚÚÚ:::ãÇÇz8###Ñh 7.bæø.¨¨¨`?ÓD 3z‰[JJŠ››Jèr|Et¯\!A‘, ã!’tþøã `G%ຢíêêjmm•H$ƒƒƒ¶¶¶eee4M ¨««š˜˜¼óÎ;XÇTh<± Õ××ß»wO$Ý»wïñãÇ]]]S/1ˆ‹‹‹‹‹ÿUKK‹F£YXXX[[3 ƒaii9»Á•?ÿUTT¡PX[[;44dhhhiiI§Ó]]]i¿šzfF&“uuu‰Åb±XÜÒÒòÃ?%&&9::²Ùlww÷%K–`ò¾Þ 4~>«¯¯OOO¿víZww·……ÅêÕ«ƒƒƒÙlö¢E‹¦9‚¾¾¾••ÕÄ%R©T$ …B¡PÈçóCCC™L¦§§g@@.¾ …#×yèÅ‹gÏžµµµµ±±©««Û½{wccccccZZ—Ë~Ý_IMMmÅŠ»víúꫯž={vãÆ {{û¤¤$¶mÛ¶²²2%½ UÆÏ+ÇŽ377 ýàƒjkkïÞ½maa¡ŠÍ‘Éäµkצ¥¥µ¶¶feeuvv®^½ÚÎή¤¤D›S hü<166–––¶dÉ>Ÿïçç×ÒÒræÌ›ÙÙº¦¦&—Ëýú믫ªªôõõ]\\ìíí«««ggë3Ÿjkkmmm÷ìÙãëëÛÜÜ|äÈL’¬\¹²¨¨¨ªªJ[[ÛÁÁ! à§Ÿ~Â$ÉïÆã›T*_µj•žž^CCÃÑ£GçÂá#‹ÅºuëÖ… Š‹‹™Læ;w°Nôh<Žõõõ9;;ÇÆÆÆÅÅݼy“N§cè?xyy}ÿý÷ ƒÃáÄÇÇcçpv¯Äb±‹‹K___ee%“ÉÄ:Ϋ\½z5999<<\,'''O½·p–AãqéáÇÎÎÎT*µ¢¢ÂÔÔë8¯C"‘vïÞmllÌãñ:;;/^¼8~M2&`¯ÚÛÛ×­[·páÂòòò9^÷qžžžÅÅÅEEE;vì˜xßÉìƒÆãŒD"quuÕÐÐ(,,Ô××Ç:Î |øá‡—.]:þ<ŸÏÇ04gBCC[[[‹‹‹ŒŒ°Î2cIII¼uëV ñxrùò匌ŒÓ§O/]ºë,o($$dÆ <¯¿¿“ÐxÜŠˆˆàñxSgÚÀ—ŒŒŒ—/_=z“­Cãq#55õÙ³gŸþ¹ª7ôôéÓ”””øøøG©b|==½˜˜˜ÄÄD±X¬Šñ_R©455588xâ<×o ®®nÍš5T*uÑ¢E;vìøñÇ'®_»víòåË£¢¢þüç?#„d2ÙÙ³gÝÝÝ£££?ú裿ýíoŠï¤¤¤(8Λ̈́§§§§§çŒ^¦!”››ûš?(((PSS{òä‰"[ùöÛoׯ__^^~÷îÝmÛ¶!„ÜÜÜÆ×öõõÙÛÛ/[¶¬§§g⫾øâ „зß~+“ɺºº(ÊǬH ¹Ï>ûìwÞzÍßüaßþð¿ÛTð—/_¶··Wðn£ÒÒÒ .üå/a2™YYYo¿ýöíÛ·Ç×îØ±£ºº:;;{ÒUhçÎC½û… ݸqC‘r<ïùóçB¡Pñ¡fB¡píÚµ ²gÏmmíñ_'NJSZZúÏþó¯ý«Ý¤Wééé!„®_¿Žzþüy{{;‡ÃQ0 BÈÜÜ|Ù²eÐxð ÝÝÝMMMS»øÆ¤RiLLÌñãÇOž<)_’266f±XT*ÕÞÞ~ün¦ÄÄÄ%K–„……ÕÔÔìÛ·/22òâÅ‹J‰Áb±*++•2ÔôAãq ­­ !¤¬K#óóó9Α#GâââÒÓÓå{Ãò zmmmoÞ¼yãÆ ±X¼fÍ‘H„Z¶lYUUƒÁprrÒÐÐ8zôè[o½¥”$t:½µµU)CM4z{{BÊš4†Ãáœ:u*%%¥»»{çÎÿøÇ?BíííúÓŸ©Tª]\\œT*MLL”¿D"‘èééq8œ'NDDDH¥R¥$100˜t²h@ãq@"‘ „´´´”2šžžž••UHHHzz:úõÀTOOoâ%~ø!Bèþýû¡ªª*__ß«W¯:88?~|ÿþýJI¢££300 ”¡¦òcǾ¾>å»~ýz„|Ú½eË–uwwË~½ªQ~ºF¾÷ò÷¿ÿ½··—Ãáhjj^ºt !túôi¥èííýÙΠñ8 ¯EOOr‡íèè@¹»»#„6nÜ8<<üÝwßÉWÉ·µråJ„|îUù¿4ÍÈÈHYwuôôô@ãÁ+Ðét--­úúzÇ9~üxffæÏ?ÿŒŒŒŒôóó B™››;vLþ1ŸŸŸodd‰’?)ä_ÿúBH,www{yy)˜D®¾¾~ÅŠJjúà( P(L&³ººú“O>QdœçÏŸ'''GEEùøøP(”}ûöŸñÔÔÔ¬¬¬Ü³gÇ[¼xqKKK]]üúûÀÀ@‰”ššz÷îݧOŸFGG+e?^&“ÕÔÔ|öÙgŠ5#Ðx|àp8ÙÙÙ'Nœø½G OÇáÇ>ü{kŒŒÎŸ??u9‰D |ãí¾RYY™üð@¹Ãþ!Ø«ÁÿŽŽŽ¹<××Ledd°X,kkëYÞ.4ÌÍÍÙlvZZÖA”£££#??ßÏÏoö7 Çøøø’’@€u%ˆŽŽ^¼x14¼‹ÅòððˆŒŒÆ:‹BjjjrrrbccÉd #¡ñxrâĉ¶¶6ùICœêïïߺu«‹‹Ë–-[0 ÇSSÓ“'O¦¦¦*ëêÅY666¶}ûv‰DröìY‰„I8;‰3\.·¢¢Â×××ÐÐPñ+ægYHHˆ@ ())ÁpêøŒÇŸ¤¤¤-[¶lܸÃY_fJ*•†……eddäææ:99a˜?jjj™™™nnn®®®¸Ø½ñññùâ‹/Î;çáámh<.‘É䜜œàà`ooùÅ^sSKK‹££cAAAaa!—ËÅ:4·ÔÔÔ³³³ÓÓÓU4·Œ‚rss™LæÈÈHmmí9ê€ÆãÇ«««\¾|ùæÎ©úææfWWW.—ëååUYY9wžæÇ=:^SS³ÿþøøøåË—gggŽŽb˜§»»;""ÂÚÚº©©I œ:ujÁ‚æ™?hjjîÛ·ïÁƒ«V­ °²²úòË/GFFf9FGGGTT”¹¹ùùóç:$‰œg9ÂÆÏfff™™™&&&{÷î•ÏG RÃÃÃEEE›6m233ËÉÉáóùOž< ÓÐÐPõ¦ß4~¾yï½÷²²²ÚÚÚ"""®\¹Â`0ètzLLLMMr÷vúúú ¶oß¾páBww÷¼¼¼§OŸ†‡‡Oœj®ï\ç'CC訨ÈÈÈššš¼¼¼¬¬¬ƒR©T'''''':nmm½xñâ}Õ?<<ÜØØøàÁƒ†††ÒÒÒ»wïJ¥R{{{>Ÿ¿yófcccÕ½%‚ÆÏg$‰Åb±X¬„„‘Htûöíòòò¤¤¤ööv„•J¥Óé´_éêêNz¹L&ëêê‹Åb±¸¹¹¹©©itt”L&[ZZ²Ùìððp6›-ŸG ñ„@"‘ ƒÁصkBèùóç"‘èþýû=joo¯­­½råÊÀÀÀàààÐÐü%ºººêêêFFFÆÆÆ&&&666ò¬¬¬ææú4Aã‰H___¾{3uU^^ž——— ÓÇñ©¹bÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆbÆb'&Äår¿ùæùÏÃÃà ÅÄÄd|mBBÂ\xº¼²@ãjhhèèè˜ø\ùƒ¢ä?~ŒE(U½€|}}ÕÕÕ_¹ŠD"ñx¼YΣRÐx€¶nÝ:666u¹ššš™™ÙìGRh<@4ÍÎÎNMmræß<‚Æ9÷ʧϧcV9h<@!OOÏIKÈd2‡Ã144Ä$ê@ãB¬Y³fâñ«T*õññÁ0’Š@ãÁ/|||&ž $“É7nÄ0Š@ãÁ/6lØ@¡Pä?S(777]]]l#©4ü‚J¥º»»ËK?::êííu"•€Æƒßx{{¿|ù!¤­­íææ†u•€Æƒß¬[·NGG!ôñÇ/X°ë8*×ÕÝèèhWWWkk«D"´µµ-++£Ñh@]]ÝÐÐÐÄÄäwÞÁ:¦Ò@ã‰ehh¨¾¾þÞ½{"‘èÞ½{?îêêšz‰A\\\\\Üø¯ZZZ4ÍÂÂÂÚÚšÁ`0 KKËÙ ®4Ðøùoll¬¢¢B …ÂÚÚÚ¡¡!CCCKKK:îêêJûÕÔ332™¬««K,‹Åâ–––~ø¡¨¨(11qppÐÈÈÈÑÑ‘Íf»»»/Y²“÷õf ñóY}}}zzúµk׺»»-,,V¯^Ìf³-Z4Íôõõ­¬¬&.‘J¥"‘H( …B>ŸÊd2===pñ-¹ÎC/^¼8{ö¬­­­M]]ÝîÝ»ÓÒÒ¸\îôëþJjjj+V¬Øµk×W_}õìÙ³7nØÛÛ'%%Ñh´mÛ¶•••)éM¨ 4~^8v옹¹yhhè|P[[{÷îÝèèh UlŽL&¯]»6--­µµ5++«³³sõêÕvvv%%%ªØœR@ã牱±±´´´%K–ðù|??¿–––3gÎØØØÌÎÖ555¹\î×_]UU¥¯¯ïââboo_]]=;[Ÿhü|P[[kkk»gÏ__ßæææ#GŽ`’dåÊ•EEEUUUÚÚÚ?ýô&I~4ߤRi||üªU«ôôôŽ=:Y,Ö­[·.\¸P\\Ìd2ïܹƒu¢ß@ãq¬¯¯ÏÙÙ9666..îæÍ›t:ëDÿÁËËëûï¿g0'>>ë8¿€³“x%‹]\\úúú*++™L&Öq^ÍÀÀàêÕ«ÉÉÉáááb±899yê½…³ K>tvv¦R©¦¦¦XÇy‰´{÷nccc×ÙÙyñâÅñk’1{5øÓÞÞ¾nݺ… –——Ïñºóôô,...**Ú±cÇÄûNf4g$‰«««††Faa¡¾¾>ÖqfàÃ?¼téÒùóçù|>†1 ñ8ÚÚÚZ\\ldd„u–óððHJJ:xðà­[·°ÊǓ˗/gddœ>}z0Ûâ IDATéÒ¥XgyC!!!6làñxýýý˜€ÆãÆÐÐPDDÇ›:Ó¾ddd¼|ùòèÑ£˜l©©©Ïž=ûüóϱ¢(==½˜˜˜ÄÄD±X<û[‡ÆãƒT*MMM ž8Ïõ¨««[³f •J]´hÑŽ;~üñGùr'''ÒMMM!™LvöìYOOÏ}ûö\¸pAñ·d``’’¢øP3çãñ¡¸¸¸­­íÓO?Udï¾ûîСC|>_GG'!!!##£³³³  àþýûýýýÇŽ¿§ººúÎ;ò£…ƒþãÿøöÛoõôôúúú˜LfOOOhh¨"I444üýýSRR8 ©©©ÈP3&› OOOOOϽLB(77÷5ð_ÿõ_«V­Rp+Çÿ<22òöÛo¿õÖ[2™ìâÅ‹===ÿÒ××÷À2™¬¥¥…L&þùçã«:¤­­ýã?*¦©©‰D"ýßÿýßkþæûö‡ÿݦ‚½| …k×®Up={öhkkÿ:>) —Ëx­åððp~~þæÍ›B999£££kÖ¬_»zõj‰D’‘‘¡`ssóeË– …BÇ™)Ø«Áîî&;;;e (•JcbbŽ?8u­@ 011‘ß»-ZÎă†úþûïÁb±*++gF ñ8ÐÖÖ†RÖ¥‘ùùù‰‰‰åååfff2™,((hÒ<Ú¹¹¹ã'@;::Bzzzãkå_ô677+ž„N§CãÁ+ôöö"„”5i ‡Ã¡Ó饥¥QQQ;wî¤P(þþþãk%Éõë×Ço_’Op0ñ ùÏ###Š'100?Y4k`?$ BHKKK)£éééYYY…„„¤§§#„Î;7qmQQ‘©©éøüòd'ÞÇÔ×ׇRðöp9ÅÇ™h<Èw*äUS¢õë×#„äÓîËÍÍ•³ÊÉ«/ß·‘“ÿü—¿üEñ½½½³?Û4äµèééQî°ò»/yñâEaaáÄ«6oÞ¬¦¦VZZ:¾ä믿¦P(Û¶mS<@OO4¼N×ÒÒª¯¯WpœãÇgffþüóÏ¡ÁÁÁÈÈH??¿   ñ?¸~ýº™™Ùûï¿?¾ÄÄÄ$:::==]þªŸþ9==ýþçäglT__¿bÅ ÅÇ™8rÅ …Âd2«««?ùäEÆyþüyrrrTT”…BÙ·oߤ3žò³4“NÝüš?¸víÚÔ…$Éßßâù¥(++ëííåp8ÊöÁ^ >øûûwttÌå¹¾f*##ƒÅbY[[Ïòv¡ñø`nnÎf³ÓÒÒ°¢ùùù~~~³¿ihŸÿäÉ“°°0 Uoú @ãç›÷Þ{/++«­­-""âÊ•+ ƒN§ÇÄÄÔÔÔ(wo§¯¯¯  `ûöí .twwÈËË{úôixxøÄy æøÎu~244ŒŠŠŠŒŒ¬©©ÉËËËÊÊ:xð •Jurrrrr¢ÓéÖÖÖ‹/žÑWýÃÃßÊd2===pñ-¹ÎC/^¼8{ö¬­­­M]]ÝîÝ»ÓÒÒ¸\îôëþJjjj+V¬Øµk×W_}õìÙ³7nØÛÛ'%%Ñh´mÛ¶•••)éM¨ 4~^8v옹¹yhhè|P[[{÷îÝèèh UlŽL&¯]»6--­µµ5++«³³sõêÕvvv%%%ªØœR@ã牱±±´´´%K–ðù|??¿–––3gÎØØØÌÎÖ555¹\î×_]UU¥¯¯ïââboo_]]=;[Ÿhü|P[[kkk»gÏ__ßæææ#GŽ`’dåÊ•EEEUUUÚÚÚ?ýô&I~4ߤRi||üªU«ôôôŽ=:Y,Ö­[·.\¸P\\Ìd2ïܹƒu¢ß@ãq¬¯¯ÏÙÙ9666..îæÍ›t:ëDÿÁËËëûï¿g0'>>ë8¿€³“x%‹]\\úúú*++™L&Öq^ÍÀÀàêÕ«ÉÉÉáááb±899yê½…³ K>tvv¦R©¦¦¦XÇy‰´{÷nccc×ÙÙyñâÅñk’1{5øÓÞÞ¾nݺ… –——Ïñºóôô,...**Ú±cÇÄûNf4g$‰«««††Faa¡¾¾>ÖqfàÃ?¼téÒùóçù|>†1 ñ8ÚÚÚZ\\ldd„u–óððHJJ:xðà­[·°ÊǓ˗/gddœ>}zéÒ¥XgyC!!!6làñxýýý˜€ÆãÆÐÐPDDÇ›:Ó¾ddd¼|ùòèÑ£˜l©©©Ïž=ûüóϱ¢(==½˜˜˜ÄÄD±X<û[‡ÆãƒT*MMM ž8Ïõ¨««[³f •J]´hÑŽ;~üñGùr'''ÒMMMòM'&&¾ÿþûo½õ–­­mnn®â'[‚‚‚ RRRç Àùx|(..nkkûôÓOä»ï¾;tèŸÏ×ÑÑIHHÈÈÈèìì,((¸ÿ~ÿ±cÇÆ¯Æ©®®¾sçŽüh!,,¬··788øßÿþ÷éÓ§¹\îÿûÿ/ @‘$þþþ)))ÐÔÔTd¨™‚ÆãÃåË—ííí¼Û¨´´ôÂ… ÚÚÚ¡¬¬¬ÂÂÂÛ·o#„D"ÑÍ›7'^|vûömùÑBKKKOOÏ… äËÝÜÜþú׿&$$(Øx„ÇãóùB¡ð£>Rp¨½| …k×®Up={öÈë.7>) —ËX÷áááüüüÍ›7#„Äbñÿþïÿޝúè£ &>Oá™››/[¶L(*>ÔŒÀg<tww755ÙÙÙ)k@©TsüøñÀÀÀ©k‰‰‰üÞí¿üå/“ÖŽŒŒ888(%‹Åª¬¬TÊPÓǶ¶6„².ÌÏÏOLL,//733“ÉdAAA“æÑÎÍÍý½ wîÜ:pà€R’Ðéth|øðkþàÚµk“–888È›•®¬¬¬··—Ãá¨bð×€ýx|ð÷÷ïèè˜Ës}ÍTFF‹Å²¶¶žåíBãñÁÜÜœÍf§¥¥aD9:::òóóýüüfÓÐx܈/))XQ‚èèèÅ‹CãÁë°X,ÈÈÈááa¬³(¤¦¦&'''66–LÆà0''Nœhkk‹ŒŒÄ:È›ëïïߺu«‹‹Ë–-[0 ÇSSÓ“'O¦¦¦^¼xë,oblllûöí‰äìÙ³“._›5pvg¸\nEE…¯¯¯¡¡¡âWÌϲ@PRR‚áÔ#ð?III[¶lÙ¸q#†³¾Ì”T* ËÈÈÈÍÍurrÂ0 4ÔÔÔ233ÝÜÜ\]]q±{322âããóÅ_œ;wÎÃÃÛ0Ðx\"“É999ÁÁÁÞÞÞòmÏM---ŽŽŽ………\.ë8ÐxÜRSSKLLÌÎÎNOOwtt|ôèÖ‰^!77—ÉdŽŒŒÔÖÖΑ£h<¾ñx¼ºººÁÁÁåË—8p`onnvuuår¹^^^•••sçiÐxÜ£Óé555û÷ï_¾|yvvöèè(†yº»»#""¬­­›ššÁ©S§,X€ažI ñ󦦿¾}û}>q¨¹¾sŸ £¢¢"##kjjòòò²²²ggçØØØ¸¸¸›7oÒét¬ý//¯ï¿ÿžÁ`p8œøøx¬ãüÎNâ•X,vqqéë뫬¬d2™XÇy5ƒ«W¯&''‡‡‡‹Åâäää©÷Î2h<.=|øÐÙÙ™J¥VTT˜ššbçuH$ÒîÝ»y<^ggçÅ‹ǯIÆìÕàO{{ûºuë.\X^^>Çë>ÎÓÓ³¸¸¸¨¨hÇŽï;™}Ðxœ‘H$®®®………úúúXÇ™?üðÒ¥KçÏŸçóùÆ€ÆãLhhhkkkqq±‘‘ÖYfÌÃÃ#))éàÁƒ·nÝÂ*4O._¾œ‘‘qúôé¥K—bå …„„lذÇãõ÷÷cCCC<oêLø’‘‘ñòåË£Gb²uh{öìóÏ?Ç:ˆ¢ôôôbbbÅbñìoR©455588xâ<×o ®®nÍš5T*uÑ¢E;vìøñÇåËœœHS455MzyJJÊ+§.›©   ƒ””Ňš)8ÅÅÅmmmŸ~ú©"ƒ|÷Ýw‡âóù::: ÷ïßïïï?vìØøÕ8ÕÕÕwîÜ™t´P[[»wï^EŒÓÐÐð÷÷OII9pà€¦¦¦RÆœ&h<>\¾|ÙÞÞ^Á»JKK/\¸ ­­ÊÊÊ*,,¼}û6BH$ݼysâÅg·oßžt´Ð××wíÚ5öïÿ[‘ ãx<ŸÏ …}ô‘Rœ&Ø«Á¡P¸víZÙ³g¼îrã“Òp¹Ü‰uÎÏÏß¼yóø™LvðàÁÈÈH¥ìÒÈ™››/[¶L(*kÀi‚Ïxèîînjj²³³SÖ€R©4&&æøñãS× “‰÷n§¤¤xyy½ýöÛÊ Çb±*++•;æ‚Æã@[[BHY—Fæçç'&&–——›™™Éd²   IŸÜ¹¹¹wi*++GGGY,–R¶>N‡ÆƒWèííE)kÒ‡C§ÓKKK£¢¢vîÜI¡PüýýÇ×J$’ëׯ߾ÔÛÛ›‘‘qæÌ¥lzƒñ“E³‰!¤¥¥¥”Ñôôôôôô¬¬¬Þ~ûíO>ùäܹs_TTdjj:>ÁÎ;wîÜ9~´:<<Œzøð!…BQü{_™)h<èéé!„úúú”{-ÍúõëBòi÷ÆåææNüš?¸víÚëGxøðáo}’²²²ÞÞ^‡£¬§ >ãñÁßß¿££c.Ïõ5S,ËÚÚz–· Çsss6›––†uåèèèÈÏÏ÷óó›ýMCãq#>>¾¤¤D `D ¢££/^ ¯Ãb±<<<"##å_áWMMMNNNll,™ŒÁa$4ONœ8ÑÖÖ‰u7×ßß¿uëV—-[¶`'¦¦¦'OžLMM½xñ"ÖYÞÄØØØöíÛ%ɤ³¢³ ÎNâ —Ë­¨¨ðõõ544TüŠùY"JJJ0œz>ãñ'))iË–-7nÄpÖ—™’J¥aaa¹¹¹NNN&ÆãššZff¦›››««+.voFFF|||¾øâ‹sçÎyxx`Kd29'''88ØÛÛ;""Bþ í¹©¥¥ÅÑѱ   °°Ëåb[jjj‰‰‰ÙÙÙéé鎎Ž=Â:Ñ+äææ2™Ì‘‘‘ÚÚÚ9rÔÇ7WWW788¸|ùòÌSõÍÍÍ®®®\.×ËË«²²rî<Í{t:½¦¦fÿþýñññË—/ÏÎÎÅ0OwwwDD„µµuSS“@ 8uêÔ‚ 0Ì3 4~>ÐÔÔÜ·o߃V­Z`eeõå—_ŽŒŒÌrŒŽŽŽ¨¨(ssóóçÏ:tH$9;;Ïr†?Ÿ?ÌÌÌ233MLLöîÝ+‰T½Ýááᢢ¢M›6™™™åääðùü'Ož„……ihh¨zÓo?ß¼÷Þ{YYYmmmW®\a0t:=&&¦¦¦F¹{;}}}Û·o_¸p¡»»ûÀÀ@^^ÞÓ§OÃÃÃ'Î5×Àw®ó“¡¡aTTTdddMMM^^^VVÖÁƒ©Tª“““““N·¶¶^¼xñŒ¾ênll|ðàACCCiiéÝ»w¥R©½½=ŸÏß¼y³±±±êÞŽAãç3‰Äb±X,VBB‚H$º}ûvyyyRRR{{;BˆJ¥ÒétÚ¯tuu'½\&“uuu‰Åb±XÜÜÜÜÔÔ4::J&“---Ùlvxx8›Í~÷Ýw±xgoO$‰Á`0Œ]»v’‰QVaIDAT!„ž?.‰îß¿ÿèÑ£öööÚÚÚ+W®  É_¢«««®®ndddlllbbbcc#ÿ—ÁÊÊjnî O4žˆôõõå»7SWåååyyyaû8>•‚#W@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,Ðx@,ðÄ€¸\î7ß|#ÿyxx˜B¡˜˜˜Œ¯MHH˜ O—Wh<@ Ÿ "P”ÜãDZ¥*°W¯¯¯ººú+W‘H$7ËyT ÐÖ­[ÇÆÆ¦.WSS³±±133›ýHªˆF£ÙÙÙ©©M.Ãüû€GÐx Çãñ^ù4ãùtÌ*!äéé9i ™Læp8†††˜äQh<@!ƒ5kÖL<~•J¥>>>FRh<ø…ÏÄ”d2yãÆæQh<øÅ† (Šüg …âææ¦««‹m$U€Æƒ_P©TwwwyéGGG½½½±N¤Ðxðooï—/_"„´µµÝÜܰޣÐxð›uëÖéèè „>þøã `G%ຢíêêjmm•H$ƒƒƒ¶¶¶eee4M ¨««š˜˜¼óÎ;XÇTh<± Õ××ß»wO$Ý»wïñãÇ]]]S/1ˆ‹‹‹‹‹ÿUKK‹F£YXXX[[3 ƒaii9»Á•?ÿUTT¡PX[[;44dhhhiiI§Ó]]]i¿šzfF&“uuu‰Åb±XÜÒÒòÃ?%&&9::²Ùlww÷%K–`ò¾Þ 4~>«¯¯OOO¿víZww·……ÅêÕ«ƒƒƒÙlö¢E‹¦9‚¾¾¾••ÕÄ%R©T$ …B¡PÈçóCCC™L¦§§g@@.¾ …#×yèÅ‹gÏžµµµµ±±©««Û½{wccccccZZ—Ë~Ý_IMMmÅŠ»víúꫯž={vãÆ {{û¤¤$¶mÛ¶²²2%½ UÆÏ+ÇŽ377 ýàƒjkkïÞ½maa¡ŠÍ‘Éäµkצ¥¥µ¶¶feeuvv®^½ÚÎή¤¤D›S hü<166–––¶dÉ>Ÿïçç×ÒÒræÌ›ÙÙº¦¦&—Ëýú믫ªªôõõ]\\ìíí«««ggë3Ÿjkkmmm÷ìÙãëëÛÜÜ|äÈL’¬\¹²¨¨¨ªªJ[[ÛÁÁ! à§Ÿ~Â$ÉïÆã›T*_µj•žž^CCÃÑ£GçÂá#‹ÅºuëÖ… Š‹‹™Læ;w°Nôh<Žõõõ9;;ÇÆÆÆÅÅݼy“N§cè?xyy}ÿý÷ ƒÃáÄÇÇcçpv¯Äb±‹‹K___ee%“ÉÄ:Ϋ\½z5999<<\,'''O½·p–AãqéáÇÎÎÎT*µ¢¢ÂÔÔë8¯C"‘vïÞmllÌãñ:;;/^¼8~M2&`¯ÚÛÛ×­[·páÂòòò9^÷qžžžÅÅÅEEE;vì˜xßÉìƒÆãŒD"quuÕÐÐ(,,Ô××Ç:Î |øá‡—.]:þ<ŸÏÇ04gBCC[[[‹‹‹ŒŒ°Î2cIII¼uëV ñxrùò匌ŒÓ§O/]ºë,o($$dÆ <¯¿¿“ÐxÜŠˆˆàñxSgÚÀ—ŒŒŒ—/_=z“­Cãq#55õÙ³gŸþ9†ž>}š’’ÿèÑ£7DOO/&&&11Q,+1Û4AãñA*•¦¦¦Oœçú ÔÕÕ­Y³†J¥.Z´hÇŽ?þø£|¹““iЦ¦¦ñ „‡‡¯]»vùòåQQQþóŸ‰d``’’¢È oÎÇãCqqq[[Û§Ÿ~ªÈ ß}÷Ý¡C‡ø|¾ŽŽNBBBFFFgggAAÁýû÷ûûû;6~5Nuuõ;wÆ~úé'WW×ÞÞÞÊÊJ¥\±£¡¡áï’ràÀMMMÅœ>h<>\¾|ÙÞÞ^Á»JKK/\¸ ­­ÊÊÊ*,,¼}û6BH$ݼysb•oß¾=ñhaÇŽòÿ”xÇãóùB¡ð£>RÖ˜Ó{5ø  ×®]«à {öì‘×]n|R.—;±ÊÃÃÃùùù›7o–ÿZZZúÏþó¯ý«‚&277_¶l™P(Tâ˜ÓÇîî&%N*•ÆÄÄ?~üäÉ“S× “ñ{·³³³BÆÆÆ,‹J¥ÚÛÛ+ëF'‹UYY©”¡¦mmm!e]™ŸŸÏápŽ9—žž>õ;ÿÜÜ܉»4òk}mmmoÞ¼yãÆ ±X¼fÍ‘H¤x:ÞÚÚªø83ÇÞÞ^„²&áp8§NJIIéîîÞ¹sç?þñ‰k%Éõë×'6¾½½ýOúS`` •Jµ³³‹‹‹“J¥‰‰‰Š'100?Y4k ñ8 ‘HBZZZJMOOÏÊÊ*$$$==!tîܹ‰k‹ŠŠLMM'Î_ §§7ñjÇ?ü!tÿþ}Å“èèè (>ÎŒ@ãq@OO!Ô××§Üaׯ_’O»7.77wü˜UnÙ²eÝÝÝã;?òcÜ·ÞzKñ½½½³?Û4äµèééQî°!ww÷ñ%/^¼(,,œtÃÆ‡‡‡¿ûî;ù¯ò+W®T<@OO4¼N×ÒÒª¯¯WpœãÇgffþüóÏ¡ÁÁÁÈÈH??¿   ñ?¸~ýº™™Ùûï¿?ñUAAAæææÇŽ“ÌçççEFF*!T__¿bÅ ÅÇ™h<P(&“©ødÏŸ?]ºtiXXXllì¾}ûΞ=;ñgò³4“¦©©YYY©¦¦Æãñþçþ§ººº®®NñKóe2YMMrÏñO|çŠ';;ûĉ¿÷¨áé8|øðáÇ_ó×®]{år##£óçÏ¿ñv_©¬¬¬··—Ãá(wØ?ŸñøàïïßÑÑ1—çúš©ŒŒ ‹emm=ËÛ…Æãƒ¹¹9›ÍNKKÃ:ˆrtttäççûùùÍþ¦¡ñ¸_RR"°¢ÑÑÑ‹/†Æƒ×a±X‘‘‘ÃÃÃXgQHMMMNNNll,™ŒÁa$4ONœ8ÑÖÖ¦”3ƒXéïïߺu«‹‹Ë–-[0 ÇSSÓ“'O¦¦¦^¼xë,oblllûöí‰dÒYÑÙg'q†ËåVTTøúú*~Åü, %%%N=Ÿñø“””´eË–7b8ëËLI¥Ò°°°ŒŒŒÜÜ\''' “@ãñGMM-33ÓÍÍÍÕÕ»7###>>>_|ñŹsç<<<° Ç%2™œ““ìíí!ÐöÜÔÒÒâèèXPPPXXÈår±ŽÇ-55µÄÄÄìììôôtGGGE&QÜÜ\&“922R[[;GŽ: ñøÆãñêêê—/_~àÀ¹sª¾¹¹ÙÕÕ•ËåzyyUVVΧ9@ãqN§×ÔÔìß¿?>>~ùòåÙÙÙ£££æéîˆ°¶¶njj§NZ°`†y&ÆÏšššûöí{ðàÁªU«¬¬¬¾üòË‘‘‘YŽÑÑÑenn~þüùC‡‰D"ggçYÎð‡ ñ󇙙Yfffcc£ƒƒC`` ‰‰ÉÞ½{•2éÀë mÚ´ÉÌÌ,''‡Ïç?yò$,,LCCCÕ›~Ðøùæ½÷ÞËÊÊjkk‹ˆˆ¸rå ƒÁ Óé111555ÊÝÛéëë+((ؾ}ûÂ… ÝÝÝòòòž>}>q¨¹¾sŸ £¢¢"##kjjòòò²²²ŸÊd2===pñ-¹ÎC/^¼8{ö¬­­­M]]ÝîÝ»ÓÒÒ¸\îôëþJjjj+V¬Øµk×W_}õìÙ³7nØÛÛ'%%Ñh´mÛ¶•••)éM¨ 4~^8v옹¹yhhè|P[[{÷îÝèèh UlŽL&¯]»6--­µµ5++«³³sõêÕvvv%%%ªØœR@ã牱±±´´´%K–ðù|??¿–––3gÎØØØÌÎÖ555¹\î×_]UU¥¯¯ïââboo_]]=;[Ÿhü|P[[kkk»gÏ__ßæææ#GŽ`’dåÊ•EEEUUUÚÚÚ?ýô&I~4ߤRi||üªU«ôôôŽ=:Y,Ö­[·.\¸P\\Ìd2ïܹƒu¢ß@ãq¬¯¯ÏÙÙ9666..îæÍ›t:ëDÿÁËËëûï¿g0'>>ë8¿€³“x%‹]\\úúú*++™L&Öq^ÍÀÀàêÕ«ÉÉÉáááb±899yê½…³ K>tvv¦R©¦¦¦XÇy‰´{÷nccc×ÙÙyñâÅñk’1{5øÓÞÞ¾nݺ… –——Ïñºóôô,...**Ú±cÇÄûNf4g$‰«««††Faa¡¾¾>ÖqfàÃ?¼téÒùóçù|>†1 ñ8ÚÚÚZ\\ldd„u–óððHJJ:xðà­[·°ÊǓ˗/gddœ>}zéÒ¥XgyC!!!6làñxýýý˜€ÆãÆÐÐPDDÇ›:Ó¾ddd¼|ùòèÑ£˜l©©©Ïž=ûüóϱ¢(==½˜˜˜ÄÄD±X<û[‡ÆãƒT*MMM ž8Ïõ¨««[³f •J]´hÑŽ;~üñGùr'''ÒMMM!™LvöìYww÷èèè>úèoû›â;$AAA))) Žóà|<>·µµ}úé§Š òÝwß:tˆÏçëèè$$$dddtvvÜ¿¿¿¿ÿرcãWãTWWß¹sG~´pêÔ©ààào¿ýöƒ>xöìF‹ÅW®\Q$‰†††¿¿JJÊ455j¦ ñøpùòe{{{ï6*--½pá‚¶¶6B(++«°°ðöíÛ!‘HtóæÍ‰ŸÝ¾}{üháܹs¡wß}!´páB##£7n(CŽÇãñù|¡PøÑG)>ÚôÁ^ >…µk×*8Èž={äu—Ÿ”†ËåN¬ûððp~~þæÍ›å¿êéé!„®_¿Žzþüy{{;‡ÃQ0 BÈÜÜ|Ù²eB¡Pñ¡fÝÝÝMMMvvvÊP*•ÆÄÄ?~üäÉ“S× “ñ{·—,YVSS³oß¾ÈÈÈ‹/*%‹Åª¬¬TÊPÓǶ¶6„².ÌÏÏçp8Gމ‹‹KOOŸúnnîÄ Ë–-«ªªb0NNNG}ë­·”’„N§·¶¶*e¨éƒýxèííE)kÒ‡C§ÓKKK£¢¢vîÜI¡PüýýÇ×J$’ëׯOº}I"‘èééq8œ'NP(”£G*åHƒñ“E³>ãq@"‘ „´´´”2šžžž••UHHHzz:úõÀt\QQ‘©©éÄù ªªªlll|}}¯^½êààpüøñýû÷+%‰ŽŽÎÀÀ€R†š>h<Èûúú”;ìúõëBòi÷ÆåææŽ³Êýýïïííåp8ššš—.]B>}Z)z{{g¶3h<ÈkÑÓÓ£Üa;::BîîîãK^¼xQXX8é*ùÜ«ò‹Úi4š‘‘‘²îêèééÆƒW ÓéZZZõõõ ŽsüøñÌÌÌŸþ!488éçç4þׯ_733{ÿý÷'¾Jþ¤ýë_!±XÜÝÝíåå¥`¹úúú+V(e¨éƒ#W P(L&³ººú“O>QdœçÏŸ'''GEEùøøP(”}ûöM:ã)?K3éh$)55õîÝ»OŸ>ŽŽVÊ~¼L&«©©ùì³ÏjF ñøÀáp²³³Oœ8ñ{žŽÃ‡>|ø5píÚµ© I$R`````ào÷•ÊÊÊä‡ÊöÁ^ >øûûwttÌå¹¾f*##ƒÅbY[[Ïòv¡ñø`nnÎf³ÓÒÒ°¢ùùù~~~³¿ihãñ'))iË–-7nÄpÖ—™’J¥aaa¹¹¹NNN&ÆãššZff¦›››««+.voFFF|||¾øâ‹sçÎyxx`Kd29'''88ØÛÛ;""B~±×ÜÔÒÒâèèXPPPXXÈår±ŽÇ-55µÄÄÄìììôôtGGÇGaèrss™LæÈÈHmmí9ê€ÆãÇ«««\¾|ùæÎ©úææfWWW.—ëååUYY9wžæÇ=:^SS³ÿþøøøåË—gggŽŽb˜§»»;""ÂÚÚº©©I œ:ujÁ‚æ™?hjjîÛ·ïÁƒ«V­ °²²úòË/GFFf9FGGGTT”¹¹ùùóç:$‰œg9ÂÆÏfff™™™&&&{÷î‰DªÞîððpQQѦM›ÌÌÌrrrø|þ“'OÂÂÂ444T½é7ŸoÞ{ャ¬¬¶¶¶ˆˆˆ+W®0 :SSS£Ü½¾¾¾‚‚‚íÛ·/\¸ÐÝÝ}`` //ïéÓ§áááçškà;×ùÉÐÐ0***22²¦¦&///++ëàÁƒT*ÕÉÉÉÉɉN§[[[/^¼xF_õ766>xð ¡¡¡´´ôîÝ»R©ÔÞÞžÏçoÞ¼ÙØØXuoG‰ ñó‰Db±X,+!!A$ݾ}»¼¼<))©½½!D¥Rét:íWººº“^.“ɺººÄb±X,nnnnjj%“É–––l6;<<œÍfËç£ÄhMÐx"Ò××—ïÞ`pä ˆˆˆˆˆˆˆˆ¾š+:tæÌ¬SÌ-"‘ˆÍf+wLhüœ°wïÞ'Ož`bÎa³Ùòço*4~N8räÖˆöã±@ã±@ã±@ã±@ã±@ã±@ã±@ã±Ìì(MMÍóçÏcõt¦šé$™L6ý¿nmm­®®ža$TE]]ÝÃÃcFOP›YãÀ;ØÄÄÄÄÄÄÄÄÄÄÄÄÄÄòÿ,v|ã^ý±sIEND®B`‚proofgeneral-4.3~pre130510/hol-light/TacticRecording/ex3b.dot000066400000000000000000000014271214562307500237370ustar00rootroot00000000000000digraph G { 344 [label = "CONV_TAC"]; 345 [label = "GEN_TAC"]; 351 [label = "INDUCT_TAC"]; 352 [label = "REWRITE_TAC"]; 358 [label = "REAL_ARITH_TAC"]; 353 [label = "REWRITE_TAC"]; 367 [label = "REWRITE_TAC"]; 368 [label = "SIMP_TAC"]; 370 [label = "REWRITE_TAC"]; 372 [label = "REWRITE_TAC"]; 374 [label = "ASM_REWRITE_TAC"]; 376 [label = "REWRITE_TAC"]; 378 [label = "REAL_ARITH_TAC"]; 344 -> 345; 345 -> 351; subgraph cluster1 { label = "induction"; 351 -> 352; 351 -> 353; 352 -> 358; subgraph cluster2 { label = "base case"; 358; } 353 -> 367; subgraph cluster3 { label = "step case"; 367 -> 368; 368 -> 370; 370 -> 372; 372 -> 374; 374 -> 376; 376 -> 378; } } }proofgeneral-4.3~pre130510/hol-light/TacticRecording/examples1.ml000066400000000000000000000022071214562307500246140ustar00rootroot00000000000000#use"TacticRecording/main.ml";; #use "TacticRecording/biolayout.ml";; pg_mode_off ();; g `x = x /\ y = y /\ z = z`;; e (CONJ_TAC);; e (REFL_TAC);; e (CONJ_TAC);; e (REFL_TAC);; e (REFL_TAC);; let th = top_thm ();; g `(!x. x = x) /\ (!y.y = y) /\ (!z.z = z)`;; e (REPEAT CONJ_TAC THEN GEN_TAC);; e (REFL_TAC);; e (REFL_TAC);; e (REFL_TAC);; let th = top_thm ();; g `(!x. x = x) /\ (!y.y = y) /\ (!z.z = z)`;; e (CONJ_TAC);; e (GEN_TAC);; e (REFL_TAC);; e (CONJ_TAC);; e (GEN_TAC);; e (REFL_TAC);; e (GEN_TAC);; e (REFL_TAC);; let th = top_thm ();; g `(!x. x = x) /\ (!y.y = y) /\ (!z.z = z)`;; e (REPEAT CONJ_TAC);; e (GEN_TAC);; e (REFL_TAC);; e (GEN_TAC);; e (REFL_TAC);; e (GEN_TAC);; e (REFL_TAC);; let th = top_thm ();; g `(!x. x = x) /\ (!y.y = y) /\ (!z.z = z)`;; e (REPEAT CONJ_TAC THEN GEN_TAC THEN REFL_TAC);; let th = top_thm ();; print_executed_proof true;; print_flat_proof true;; print_thenl_proof ();; print_packaged_proof ();; print_gv_proof ();; g `(y:A) = z ==> (x:A) = x /\ y = y /\ z = z`;; e (STRIP_TAC);; e (UNDISCH_TAC `(y:A) = z`);; e (DISCH_TAC);; e (CONJ_TAC);; e (REFL_TAC);; e (CONJ_TAC);; e (REFL_TAC);; e (REFL_TAC);; proofgeneral-4.3~pre130510/hol-light/TacticRecording/examples1_output.txt000066400000000000000000000023371214562307500264470ustar00rootroot00000000000000# g `(!x. x = x) /\ (!y.y = y) /\ (!z.z = z)`;; Warning: inventing type variables val it : xgoalstack = 1 subgoal (1 total) `(!x. x = x) /\ (!y. y = y) /\ (!z. z = z)` # e (REPEAT CONJ_TAC);; val it : xgoalstack = 3 subgoals (3 total) `!z. z = z` `!y. y = y` `!x. x = x` # e (GEN_TAC);; val it : xgoalstack = 1 subgoal (3 total) `x = x` # e (REFL_TAC);; val it : xgoalstack = 1 subgoal (2 total) `!y. y = y` # e (GEN_TAC);; val it : xgoalstack = 1 subgoal (2 total) `y = y` # e (REFL_TAC);; val it : xgoalstack = 1 subgoal (1 total) `!z. z = z` # e (GEN_TAC);; val it : xgoalstack = 1 subgoal (1 total) `z = z` # e (REFL_TAC);; val it : xgoalstack = No subgoals # print_executed_proof ();; e (REPEAT CONJ_TAC);; e (GEN_TAC);; e (REFL_TAC);; e (GEN_TAC);; e (REFL_TAC);; e (GEN_TAC);; e (REFL_TAC);; val it : unit = () # print_flat_proof ();; e (CONJ_TAC);; e (GEN_TAC);; e (REFL_TAC);; e (CONJ_TAC);; e (GEN_TAC);; e (REFL_TAC);; e (GEN_TAC);; e (REFL_TAC);; val it : unit = () # print_thenl_proof ();; e (CONJ_TAC THENL [GEN_TAC THEN REFL_TAC; CONJ_TAC THENL [GEN_TAC THEN REFL_TAC; GEN_TAC THEN REFL_TAC]]);; val it : unit = () # print_optimal_proof ();; e (REPEAT CONJ_TAC THEN GEN_TAC THEN REFL_TAC);; val it : unit = () # proofgeneral-4.3~pre130510/hol-light/TacticRecording/examples2.ml000066400000000000000000000026771214562307500246300ustar00rootroot00000000000000#use "hol.ml";; needs "Examples/prime.ml";; #use "TacticRecording/main.ml";; let egcd = define `egcd(m,n) = if m = 0 then n else if n = 0 then m else if m <= n then egcd(m,n - m) else egcd(m - n,n)`;; let egcd = theorem_wrap "egcd" egcd;; let DIVIDES_0 = theorem_wrap "DIVIDES_0" DIVIDES_0;; let WF_INDUCT_TAC = term_tactic_wrap "WF_INDUCT_TAC" WF_INDUCT_TAC;; g `!m n d. d divides egcd(m,n) <=> d divides m /\ d divides n`;; e (GEN_TAC THEN GEN_TAC THEN WF_INDUCT_TAC `m + n` THEN GEN_TAC THEN ONCE_REWRITE_TAC[egcd] THEN ASM_CASES_TAC `m = 0` THEN ASM_REWRITE_TAC[DIVIDES_0] THEN ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[DIVIDES_0] THEN COND_CASES_TAC);; top_goal ();; print_executed_proof ();; print_flat_proof ();; print_thenl_proof ();; print_optimal_proof ();; is_empty [23];; not true or not true;; let EGCD_INVARIANT = prove (`!m n d. d divides egcd(m,n) <=> d divides m /\ d divides n`, GEN_TAC THEN GEN_TAC THEN WF_INDUCT_TAC `m + n` THEN GEN_TAC THEN ONCE_REWRITE_TAC[egcd] THEN ASM_CASES_TAC `m = 0` THEN ASM_REWRITE_TAC[DIVIDES_0] THEN ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[DIVIDES_0] THEN COND_CASES_TAC THEN (W(fun (asl,w) -> FIRST_X_ASSUM(fun th -> MP_TAC(PART_MATCH (lhs o snd o dest_forall o rand) th (lhand w)))) THEN ANTS_TAC THENL [REPEAT(POP_ASSUM MP_TAC) THEN ARITH_TAC; ALL_TAC]) THEN ASM_MESON_TAC[DIVIDES_SUB; DIVIDES_ADD; SUB_ADD; LE_CASES]);; proofgeneral-4.3~pre130510/hol-light/TacticRecording/examples3.ml000066400000000000000000000223221214562307500246160ustar00rootroot00000000000000#use"hol.ml";; needs "Library/products.ml";; #use "TacticRecording/main.ml";; prioritize_real();; AIM: CONT_COMPOSE (Library/analysis.ml) - used by John in his Proof Style paper (* ** LEMMA1 from HOL Light's 100/arithmetic_geometric_mean.ml ** *) let LEMMA_1 = prove (`!x n. x pow (n + 1) - (&n + &1) * x + &n = (x - &1) pow 2 * sum(1..n) (\k. &k * x pow (n - k))`, CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH_EQ; ADD_CLAUSES] THENL [REAL_ARITH_TAC; REWRITE_TAC[ARITH_RULE `1 <= SUC n`]] THEN SIMP_TAC[ARITH_RULE `k <= n ==> SUC n - k = SUC(n - k)`; SUB_REFL] THEN REWRITE_TAC[real_pow; REAL_MUL_RID] THEN REWRITE_TAC[REAL_ARITH `k * x * x pow n = (k * x pow n) * x`] THEN ASM_REWRITE_TAC[SUM_RMUL; REAL_MUL_ASSOC; REAL_ADD_LDISTRIB] THEN REWRITE_TAC[GSYM REAL_OF_NUM_SUC; REAL_POW_ADD] THEN REAL_ARITH_TAC);; let LEMMA_1 = prove (`!x n. x pow (n + 1) - (&n + &1) * x + &n = (x - &1) pow 2 * sum(1..n) (\k. &k * x pow (n - k))`, CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN GEN_TAC THEN HILABEL "induction" (INDUCT_TAC THEN REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH_EQ; ADD_CLAUSES] THENL [HILABEL "base case" REAL_ARITH_TAC; ALL_TAC] THEN HILABEL "step case" (REWRITE_TAC[ARITH_RULE `1 <= SUC n`] THEN SIMP_TAC[ARITH_RULE `k <= n ==> SUC n - k = SUC(n - k)`; SUB_REFL] THEN REWRITE_TAC[real_pow; REAL_MUL_RID] THEN REWRITE_TAC[REAL_ARITH `k * x * x pow n = (k * x pow n) * x`] THEN ASM_REWRITE_TAC[SUM_RMUL; REAL_MUL_ASSOC; REAL_ADD_LDISTRIB] THEN REWRITE_TAC[GSYM REAL_OF_NUM_SUC; REAL_POW_ADD] THEN REAL_ARITH_TAC)));; let LEMMA_1 = theorem_wrap "LEMMA_1" LEMMA_1;; top_thm ();; print_executed_proof true;; print_flat_proof true;; print_packaged_proof ();; print_thenl_proof ();; print_gv_proof ();; let gtr = !the_goal_tree;; let h = gtree_to_hiproof gtr;; let h' = (trivsimp_hiproof o dethen_hiproof) h;; g `!x n. x pow (n + 1) - (&n + &1) * x + &n = (x - &1) pow 2 * sum(1..n) (\k. &k * x pow (n - k))`;; e (CONV_TAC (ONCE_DEPTH_CONV SYM_CONV));; e (GEN_TAC);; e (INDUCT_TAC);; (* *** Subgoal 1 *** *) e (REWRITE_TAC [SUM_CLAUSES_NUMSEG;ARITH_EQ;ADD_CLAUSES]);; e (REAL_ARITH_TAC);; (* *** Subgoal 2 *** *) e (REWRITE_TAC [SUM_CLAUSES_NUMSEG;ARITH_EQ;ADD_CLAUSES]);; e (REWRITE_TAC [ARITH_RULE `1 <= SUC n`]);; e (SIMP_TAC [ARITH_RULE `k <= n ==> SUC n - k = SUC (n - k)`; SUB_REFL]);; e (REWRITE_TAC [real_pow;REAL_MUL_RID]);; e (REWRITE_TAC [REAL_ARITH `k * x * x pow n = (k * x pow n) * x`]);; e (ASM_REWRITE_TAC [SUM_RMUL;REAL_MUL_ASSOC;REAL_ADD_LDISTRIB]);; e (REWRITE_TAC [GSYM REAL_OF_NUM_SUC; REAL_POW_ADD]);; e (REAL_ARITH_TAC);; print_executed_proof true;; print_packaged_proof ();; print_thenl_proof ();; (* LEMMA 2 *) let LEMMA_2 = prove (`!n x. &0 <= x ==> &0 <= x pow (n + 1) - (&n + &1) * x + &n`, REPEAT STRIP_TAC THEN REWRITE_TAC[LEMMA_1] THEN MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE] THEN MATCH_MP_TAC SUM_POS_LE_NUMSEG THEN ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_POW_LE]);; let LEMMA_2 = theorem_wrap "LEMMA_2" LEMMA_2;; print_executed_proof true;; print_flat_proof true;; print_packaged_proof ();; print_gv_proof ();; g `!n x. &0 <= x ==> &0 <= x pow (n + 1) - (&n + &1) * x + &n`;; (* LEMMA 3 *) let LEMMA_3 = prove (`!n x. 1 <= n /\ (!i. 1 <= i /\ i <= n + 1 ==> &0 <= x i) ==> x(n + 1) * (sum(1..n) x / &n) pow n <= (sum(1..n+1) x / (&n + &1)) pow (n + 1)`, REPEAT STRIP_TAC THEN ABBREV_TAC `a = sum(1..n+1) x / (&n + &1)` THEN ABBREV_TAC `b = sum(1..n) x / &n` THEN SUBGOAL_THEN `x(n + 1) = (&n + &1) * a - &n * b` SUBST1_TAC THENL [MAP_EVERY EXPAND_TAC ["a"; "b"] THEN ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_OF_NUM_EQ; LE_1; REAL_ARITH `~(&n + &1 = &0)`] THEN SIMP_TAC[SUM_ADD_SPLIT; ARITH_RULE `1 <= n + 1`; SUM_SING_NUMSEG] THEN REAL_ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `&0 <= a /\ &0 <= b` STRIP_ASSUME_TAC THENL [MAP_EVERY EXPAND_TAC ["a"; "b"] THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LE_DIV THEN (CONJ_TAC THENL [MATCH_MP_TAC SUM_POS_LE_NUMSEG; REAL_ARITH_TAC]) THEN ASM_SIMP_TAC[ARITH_RULE `p <= n ==> p <= n + 1`]; ALL_TAC] THEN ASM_CASES_TAC `b = &0` THEN ASM_SIMP_TAC[REAL_POW_ZERO; LE_1; REAL_MUL_RZERO; REAL_POW_LE] THEN MP_TAC(ISPECL [`n:num`; `a / b`] LEMMA_2) THEN ASM_SIMP_TAC[REAL_LE_DIV] THEN REWRITE_TAC[REAL_ARITH `&0 <= x - a + b <=> a - b <= x`; REAL_POW_DIV] THEN SUBGOAL_THEN `&0 < b` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_POW_LT] THEN MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[REAL_POW_ADD] THEN UNDISCH_TAC `~(b = &0)` THEN CONV_TAC REAL_FIELD);; let LEMMA_3 = theorem_wrap "LEMMA_3" LEMMA_3;; print_executed_proof true;; print_flat_proof true;; print_thenl_proof ();; print_packaged_proof ();; print_gv_proof ();; g `!n x. 1 <= n /\ (!i. 1 <= i /\ i <= n + 1 ==> &0 <= x i) ==> x(n + 1) * (sum(1..n) x / &n) pow n <= (sum(1..n+1) x / (&n + &1)) pow (n + 1)`;; print_flat_proof true;; e (STRIP_TAC);; e (STRIP_TAC);; e (STRIP_TAC);; e (ABBREV_TAC `a = sum (1..n + 1) x / (&n + &1)`);; e (ABBREV_TAC `b = sum (1..n) x / &n`);; e (SUBGOAL_THEN `x (n + 1) = (&n + &1) * a - &n * b` SUBST1_TAC);; (* *** Subgoal 1 *** *) e (EXPAND_TAC "a");; e (EXPAND_TAC "b");; e (ASM_SIMP_TAC [REAL_DIV_LMUL; REAL_OF_NUM_EQ; LE_1; REAL_ARITH `~(&n + &1 = &0)`]);; e (SIMP_TAC [SUM_ADD_SPLIT; ARITH_RULE `1 <= n + 1`; SUM_SING_NUMSEG]);; e (REAL_ARITH_TAC);; (* *** Subgoal 2 *** *) e (SUBGOAL_THEN `&0 <= a /\ &0 <= b` STRIP_ASSUME_TAC);; (* *** Subgoal 2.1 *** *) e (EXPAND_TAC "a");; e (EXPAND_TAC "b");; e (CONJ_TAC);; (* *** Subgoal 2.1.1 *** *) e (MATCH_MP_TAC REAL_LE_DIV);; e (CONJ_TAC);; (* *** Subgoal 2.1.1.1 *** *) e (MATCH_MP_TAC SUM_POS_LE_NUMSEG);; e (ASM_SIMP_TAC [ARITH_RULE `p <= n ==> p <= n + 1`]);; (* *** Subgoal 2.1.1.2 *** *) e (REAL_ARITH_TAC);; (* *** Subgoal 2.1.2 *** *) e (MATCH_MP_TAC REAL_LE_DIV);; e (CONJ_TAC);; (* *** Subgoal 2.1.2.1 *** *) e (MATCH_MP_TAC SUM_POS_LE_NUMSEG);; e (ASM_SIMP_TAC [ARITH_RULE `p <= n ==> p <= n + 1`]);; (* *** Subgoal 2.1.2.2 *** *) e (REAL_ARITH_TAC);; (* *** Subgoal 2.2 *** *) e (ASM_CASES_TAC `b = &0`);; (* *** Subgoal 2.2.1 *** *) e (ASM_SIMP_TAC [REAL_POW_ZERO;LE_1;REAL_MUL_RZERO;REAL_POW_LE]);; (* *** Subgoal 2.2.2 *** *) e (ASM_SIMP_TAC [REAL_POW_ZERO;LE_1;REAL_MUL_RZERO;REAL_POW_LE]);; e (MP_TAC (ISPECL [`n`;`a / b`] LEMMA_2));; e (ASM_SIMP_TAC [REAL_LE_DIV]);; e (REWRITE_TAC [REAL_ARITH `&0 <= x - a + b <=> a - b <= x`; REAL_POW_DIV]);; e (SUBGOAL_THEN `&0 < b` ASSUME_TAC);; (* *** Subgoal 2.2.2.1 *** *) e (ASM_REAL_ARITH_TAC);; (* *** Subgoal 2.2.2.2 *** *) e (ASM_SIMP_TAC [REAL_LE_RDIV_EQ;REAL_POW_LT]);; e (MATCH_MP_TAC EQ_IMP);; e (AP_THM_TAC);; e (AP_TERM_TAC);; e (REWRITE_TAC [REAL_POW_ADD]);; e (UNDISCH_TAC `~(b = &0)`);; e (CONV_TAC REAL_FIELD);; (* AGM *) let AGM = prove (`!n a. 1 <= n /\ (!i. 1 <= i /\ i <= n ==> &0 <= a(i)) ==> product(1..n) a <= (sum(1..n) a / &n) pow n`, INDUCT_TAC THEN REWRITE_TAC[ARITH; PRODUCT_CLAUSES_NUMSEG] THEN REWRITE_TAC[ARITH_RULE `1 <= SUC n`] THEN X_GEN_TAC `x:num->real` THEN ASM_CASES_TAC `n = 0` THENL [ASM_REWRITE_TAC[PRODUCT_CLAUSES_NUMSEG; ARITH; SUM_SING_NUMSEG] THEN REAL_ARITH_TAC; REWRITE_TAC[ADD1] THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `x(n + 1) * (sum(1..n) x / &n) pow n` THEN ASM_SIMP_TAC[LEMMA_3; GSYM REAL_OF_NUM_ADD; LE_1; ARITH_RULE `i <= n ==> i <= n + 1`] THEN GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN MATCH_MP_TAC REAL_LE_RMUL THEN ASM_SIMP_TAC[LE_REFL; LE_1; ARITH_RULE `i <= n ==> i <= n + 1`]]);; g `!n a. 1 <= n /\ (!i. 1 <= i /\ i <= n ==> &0 <= a(i)) ==> product(1..n) a <= (sum(1..n) a / &n) pow n`;; e (INDUCT_TAC);; (* *** Subgoal 1 *** *) e (REWRITE_TAC [ARITH;PRODUCT_CLAUSES_NUMSEG]);; (* *** Subgoal 2 *** *) e (REWRITE_TAC [ARITH;PRODUCT_CLAUSES_NUMSEG]);; e (REWRITE_TAC [ARITH_RULE `1 <= SUC n`]);; e (X_GEN_TAC `x:num->real`);; e (ASM_CASES_TAC `n = 0`);; (* *** Subgoal 2.1 *** *) e (ASM_REWRITE_TAC [PRODUCT_CLAUSES_NUMSEG;ARITH;SUM_SING_NUMSEG]);; e (REAL_ARITH_TAC);; (* *** Subgoal 2.2 *** *) e (REWRITE_TAC [ADD1]);; e (STRIP_TAC);; e (MATCH_MP_TAC REAL_LE_TRANS);; e (EXISTS_TAC `x (n + 1) * (sum (1..n) x / &n) pow n`);; e (ASM_SIMP_TAC [LEMMA_3; GSYM REAL_OF_NUM_ADD; LE_1; ARITH_RULE `i <= n ==> i <= n + 1`]);; e (GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM]);; e (MATCH_MP_TAC REAL_LE_RMUL);; e (ASM_SIMP_TAC [LE_REFL; LE_1; ARITH_RULE `i <= n ==> i <= n + 1`]);; g `!n a. 1 <= n /\ (!i. 1 <= i /\ i <= n ==> &0 <= a(i)) ==> product(1..n) a <= (sum(1..n) a / &n) pow n`;; e (INDUCT_TAC THEN REWRITE_TAC [ARITH;PRODUCT_CLAUSES_NUMSEG] THEN REWRITE_TAC [ARITH_RULE `1 <= SUC n`] THEN X_GEN_TAC `x:num->real` THEN ASM_CASES_TAC `n = 0` THENL [ASM_REWRITE_TAC [PRODUCT_CLAUSES_NUMSEG;ARITH;SUM_SING_NUMSEG] THEN REAL_ARITH_TAC; REWRITE_TAC [ADD1] THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `x (n + 1) * (sum (1..n) x / &n) pow n` THEN ASM_SIMP_TAC [LEMMA_3; GSYM REAL_OF_NUM_ADD; LE_1; ARITH_RULE `i <= n ==> i <= n + 1`] THEN GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN MATCH_MP_TAC REAL_LE_RMUL THEN ASM_SIMP_TAC [LE_REFL; LE_1; ARITH_RULE `i <= n ==> i <= n + 1`]]);; proofgeneral-4.3~pre130510/hol-light/TacticRecording/examples3_LEMMA1.dot000066400000000000000000000005231214562307500257670ustar00rootroot00000000000000digraph G { subgraph cluster0 { label = "induction"; 517->518; 517->519; } subgraph cluster1 { label = "base case"; 528->528 } subgraph cluster2 { label = "step case"; 537->538; 538->540; 540->542; 542->544; 544->546; 546->548; } 512->513; 513->517; 518->528; 519->537; }proofgeneral-4.3~pre130510/hol-light/TacticRecording/examples3_output.txt000066400000000000000000000037041214562307500264500ustar00rootroot00000000000000# let LEMMA_1 = prove (`!x n. x pow (n + 1) - (&n + &1) * x + &n = (x - &1) pow 2 * sum(1..n) (\k. &k * x pow (n - k))`, CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH_EQ; ADD_CLAUSES] THENL [REAL_ARITH_TAC; REWRITE_TAC[ARITH_RULE `1 <= SUC n`]] THEN SIMP_TAC[ARITH_RULE `k <= n ==> SUC n - k = SUC(n - k)`; SUB_REFL] THEN REWRITE_TAC[real_pow; REAL_MUL_RID] THEN REWRITE_TAC[REAL_ARITH `k * x * x pow n = (k * x pow n) * x`] THEN ASM_REWRITE_TAC[SUM_RMUL; REAL_MUL_ASSOC; REAL_ADD_LDISTRIB] THEN REWRITE_TAC[GSYM REAL_OF_NUM_SUC; REAL_POW_ADD] THEN REAL_ARITH_TAC);; val ( LEMMA_1 ) : thm = |- !x n. x pow (n + 1) - (&n + &1) * x + &n = (x - &1) pow 2 * sum (1..n) (\k. &k * x pow (n - k)) # print_executed_proof ();; e ((CONV_TAC (ONCE_DEPTH_CONV SYM_CONV)) THEN GEN_TAC THEN INDUCT_TAC THEN (REWRITE_TAC [SUM_CLAUSES_NUMSEG;ARITH_EQ;ADD_CLAUSES]) THENL [REAL_ARITH_TAC; REWRITE_TAC [ARITH_RULE `1 <= SUC n`]] THEN (SIMP_TAC [ARITH_RULE `k <= n ==> SUC n - k = SUC (n - k)`; SUB_REFL]) THEN (REWRITE_TAC [real_pow;REAL_MUL_RID]) THEN (REWRITE_TAC [REAL_ARITH `k * x * x pow n = (k * x pow n) * x`]) THEN (ASM_REWRITE_TAC [SUM_RMUL;REAL_MUL_ASSOC;REAL_ADD_LDISTRIB]) THEN (REWRITE_TAC [GSYM REAL_OF_NUM_SUC; REAL_POW_ADD]) THEN REAL_ARITH_TAC);; val it : unit = () # print_flat_proof ();; e (CONV_TAC (ONCE_DEPTH_CONV SYM_CONV));; e (GEN_TAC);; e (INDUCT_TAC);; e (REWRITE_TAC [SUM_CLAUSES_NUMSEG;ARITH_EQ;ADD_CLAUSES]);; e (REAL_ARITH_TAC);; e (REWRITE_TAC [SUM_CLAUSES_NUMSEG;ARITH_EQ;ADD_CLAUSES]);; e (REWRITE_TAC [ARITH_RULE `1 <= SUC n`]);; e (SIMP_TAC [ARITH_RULE `k <= n ==> SUC n - k = SUC (n - k)`; SUB_REFL]);; e (REWRITE_TAC [real_pow;REAL_MUL_RID]);; e (REWRITE_TAC [REAL_ARITH `k * x * x pow n = (k * x pow n) * x`]);; e (ASM_REWRITE_TAC [SUM_RMUL;REAL_MUL_ASSOC;REAL_ADD_LDISTRIB]);; e (REWRITE_TAC [GSYM REAL_OF_NUM_SUC; REAL_POW_ADD]);; e (REAL_ARITH_TAC);; proofgeneral-4.3~pre130510/hol-light/TacticRecording/examples4.ml000066400000000000000000000006451214562307500246230ustar00rootroot00000000000000pg_mode_on ();; get_pg_mode ();; g `(?x:num. p(x) /\ q(x) /\ r(x)) ==> (?x. r(x) /\ p(x)) /\ (?x. p(x) /\ (q(x) <=> r(x)))`;; e (STRIP_TAC);; e (STRIP_TAC);; e (X_META_EXISTS_TAC `n1:num` THEN CONJ_TAC);; e (FIRST_X_ASSUM(UNIFY_ACCEPT_TAC [`n1:num`]));; e (ASM_REWRITE_TAC[]);; e (X_META_EXISTS_TAC `n2:num` THEN CONJ_TAC);; e (FIRST_X_ASSUM(UNIFY_ACCEPT_TAC [`n2:num`]));; e (ASM_REWRITE_TAC[]);; let th = top_thm ();; proofgeneral-4.3~pre130510/hol-light/TacticRecording/examples5.ml000066400000000000000000000153351214562307500246260ustar00rootroot00000000000000(* Taken from Library/prime.ml *) prioritize_num();; (* ------------------------------------------------------------------------- *) (* HOL88 compatibility (since all this is a port of old HOL88 stuff). *) (* ------------------------------------------------------------------------- *) let MULT_MONO_EQ = prove (`!m i n. ((SUC n) * m = (SUC n) * i) <=> (m = i)`, REWRITE_TAC[EQ_MULT_LCANCEL; NOT_SUC]);; let LESS_ADD_1 = prove (`!m n. n < m ==> (?p. m = n + (p + 1))`, REWRITE_TAC[LT_EXISTS; ADD1; ADD_ASSOC]);; let LESS_ADD_SUC = ARITH_RULE `!m n. m < (m + (SUC n))`;; let LESS_0_CASES = ARITH_RULE `!m. (0 = m) \/ 0 < m`;; let LESS_MONO_ADD = ARITH_RULE `!m n p. m < n ==> (m + p) < (n + p)`;; let LESS_EQ_0 = prove (`!n. n <= 0 <=> (n = 0)`, REWRITE_TAC[LE]);; let LESS_LESS_CASES = ARITH_RULE `!m n. (m = n) \/ m < n \/ n < m`;; let LESS_ADD_NONZERO = ARITH_RULE `!m n. ~(n = 0) ==> m < (m + n)`;; let NOT_EXP_0 = prove (`!m n. ~((SUC n) EXP m = 0)`, REWRITE_TAC[EXP_EQ_0; NOT_SUC]);; let LESS_THM = ARITH_RULE `!m n. m < (SUC n) <=> (m = n) \/ m < n`;; let NOT_LESS_0 = ARITH_RULE `!n. ~(n < 0)`;; let ZERO_LESS_EXP = prove (`!m n. 0 < ((SUC n) EXP m)`, REWRITE_TAC[LT_NZ; NOT_EXP_0]);; (* ------------------------------------------------------------------------- *) (* General arithmetic lemmas. *) (* ------------------------------------------------------------------------- *) let MULT_FIX = prove( `!x y. (x * y = x) <=> (x = 0) \/ (y = 1)`, REPEAT GEN_TAC THEN STRUCT_CASES_TAC(SPEC `x:num` num_CASES) THEN REWRITE_TAC[MULT_CLAUSES; NOT_SUC] THEN REWRITE_TAC[GSYM(el 4 (CONJUNCTS (SPEC_ALL MULT_CLAUSES)))] THEN GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) (* MMA: this is a problem !!!!) [GSYM(el 3 (CONJUNCTS(SPEC_ALL MULT_CLAUSES)))] THEN MATCH_ACCEPT_TAC MULT_MONO_EQ);; let LESS_EQ_MULT = prove( `!m n p q. m <= n /\ p <= q ==> (m * p) <= (n * q)`, REPEAT GEN_TAC THEN DISCH_THEN(STRIP_ASSUME_TAC o REWRITE_RULE[LE_EXISTS]) THEN ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; RIGHT_ADD_DISTRIB; GSYM ADD_ASSOC; LE_ADD]);; let LESS_MULT = prove( `!m n p q. m < n /\ p < q ==> (m * p) < (n * q)`, REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ((CHOOSE_THEN SUBST_ALL_TAC) o MATCH_MP LESS_ADD_1)) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; RIGHT_ADD_DISTRIB] THEN REWRITE_TAC[GSYM ADD1; MULT_CLAUSES; ADD_CLAUSES; GSYM ADD_ASSOC] THEN ONCE_REWRITE_TAC[GSYM (el 3 (CONJUNCTS ADD_CLAUSES))] THEN MATCH_ACCEPT_TAC LESS_ADD_SUC);; let MULT_LCANCEL = prove( `!a b c. ~(a = 0) /\ (a * b = a * c) ==> (b = c)`, REPEAT GEN_TAC THEN STRUCT_CASES_TAC(SPEC `a:num` num_CASES) THEN REWRITE_TAC[NOT_SUC; MULT_MONO_EQ]);; let LT_POW2_REFL = prove (`!n. n < 2 EXP n`, INDUCT_TAC THEN REWRITE_TAC[EXP] THEN TRY(POP_ASSUM MP_TAC) THEN ARITH_TAC);; (* ------------------------------------------------------------------------- *) (* Properties of the exponential function. *) (* ------------------------------------------------------------------------- *) let EXP_0 = prove (`!n. 0 EXP (SUC n) = 0`, REWRITE_TAC[EXP; MULT_CLAUSES]);; let EXP_MONO_LT_SUC = prove (`!n x y. (x EXP (SUC n)) < (y EXP (SUC n)) <=> (x < y)`, REWRITE_TAC[EXP_MONO_LT; NOT_SUC]);; let EXP_MONO_LE_SUC = prove (`!x y n. (x EXP (SUC n)) <= (y EXP (SUC n)) <=> x <= y`, REWRITE_TAC[EXP_MONO_LE; NOT_SUC]);; let EXP_MONO_EQ_SUC = prove (`!x y n. (x EXP (SUC n) = y EXP (SUC n)) <=> (x = y)`, REWRITE_TAC[EXP_MONO_EQ; NOT_SUC]);; let EXP_EXP = prove (`!x m n. (x EXP m) EXP n = x EXP (m * n)`, REWRITE_TAC[EXP_MULT]);; (* ------------------------------------------------------------------------- *) (* More ad-hoc arithmetic lemmas unlikely to be useful elsewhere. *) (* ------------------------------------------------------------------------- *) let DIFF_LEMMA = prove( `!a b. a < b ==> (a = 0) \/ (a + (b - a)) < (a + b)`, REPEAT GEN_TAC THEN DISJ_CASES_TAC(SPEC `a:num` LESS_0_CASES) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN(CHOOSE_THEN SUBST1_TAC o MATCH_MP LESS_ADD_1) THEN DISJ2_TAC THEN REWRITE_TAC[ONCE_REWRITE_RULE[ADD_SYM] ADD_SUB] THEN GEN_REWRITE_TAC LAND_CONV [GSYM (CONJUNCT1 ADD_CLAUSES)] THEN REWRITE_TAC[ADD_ASSOC] THEN REPEAT(MATCH_MP_TAC LESS_MONO_ADD) THEN POP_ASSUM ACCEPT_TAC);; let NOT_EVEN_EQ_ODD = prove( `!m n. ~(2 * m = SUC(2 * n))`, REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o AP_TERM `EVEN`) THEN REWRITE_TAC[EVEN; EVEN_MULT; ARITH]);; let CANCEL_TIMES2 = prove( `!x y. (2 * x = 2 * y) <=> (x = y)`, REWRITE_TAC[num_CONV `2`; MULT_MONO_EQ]);; let EVEN_SQUARE = prove( `!n. EVEN(n) ==> ?x. n EXP 2 = 4 * x`, GEN_TAC THEN REWRITE_TAC[EVEN_EXISTS] THEN DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST1_TAC) THEN EXISTS_TAC `m * m` THEN REWRITE_TAC[EXP_2] THEN REWRITE_TAC[SYM(REWRITE_CONV[ARITH] `2 * 2`)] THEN REWRITE_TAC[MULT_AC]);; let ODD_SQUARE = prove( `!n. ODD(n) ==> ?x. n EXP 2 = (4 * x) + 1`, GEN_TAC THEN REWRITE_TAC[ODD_EXISTS] THEN DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST1_TAC) THEN ASM_REWRITE_TAC[EXP_2; MULT_CLAUSES; ADD_CLAUSES] THEN REWRITE_TAC[GSYM ADD1; SUC_INJ] THEN EXISTS_TAC `(m * m) + m` THEN REWRITE_TAC(map num_CONV [`4`; `3`; `2`; `1`]) THEN REWRITE_TAC[ADD_CLAUSES; MULT_CLAUSES] THEN REWRITE_TAC[LEFT_ADD_DISTRIB; RIGHT_ADD_DISTRIB] THEN REWRITE_TAC[ADD_AC]);; let DIFF_SQUARE = prove( `!x y. (x EXP 2) - (y EXP 2) = (x + y) * (x - y)`, REPEAT GEN_TAC THEN DISJ_CASES_TAC(SPECL [`x:num`; `y:num`] LE_CASES) THENL [SUBGOAL_THEN `(x * x) <= (y * y)` MP_TAC THENL [MATCH_MP_TAC LESS_EQ_MULT THEN ASM_REWRITE_TAC[]; POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM SUB_EQ_0] THEN REPEAT DISCH_TAC THEN ASM_REWRITE_TAC[EXP_2; MULT_CLAUSES]]; POP_ASSUM(CHOOSE_THEN SUBST1_TAC o REWRITE_RULE[LE_EXISTS]) THEN REWRITE_TAC[ONCE_REWRITE_RULE[ADD_SYM] ADD_SUB] THEN REWRITE_TAC[EXP_2; LEFT_ADD_DISTRIB; RIGHT_ADD_DISTRIB] THEN REWRITE_TAC[GSYM ADD_ASSOC; ONCE_REWRITE_RULE[ADD_SYM] ADD_SUB] THEN AP_TERM_TAC THEN GEN_REWRITE_TAC LAND_CONV [ADD_SYM] THEN AP_TERM_TAC THEN MATCH_ACCEPT_TAC MULT_SYM]);; let ADD_IMP_SUB = prove( `!x y z. (x + y = z) ==> (x = z - y)`, REPEAT GEN_TAC THEN DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[ADD_SUB]);; let ADD_SUM_DIFF = prove( `!v w. v <= w ==> ((w + v) - (w - v) = 2 * v) /\ ((w + v) + (w - v) = 2 * w)`, REPEAT GEN_TAC THEN REWRITE_TAC[LE_EXISTS] THEN DISCH_THEN(CHOOSE_THEN SUBST1_TAC) THEN REWRITE_TAC[ONCE_REWRITE_RULE[ADD_SYM] ADD_SUB] THEN REWRITE_TAC[MULT_2; GSYM ADD_ASSOC] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[ONCE_REWRITE_RULE[ADD_SYM] ADD_SUB; GSYM ADD_ASSOC]);; let EXP_4 = prove( `!n. n EXP 4 = (n EXP 2) EXP 2`, GEN_TAC THEN REWRITE_TAC[EXP_EXP] THEN REWRITE_TAC[ARITH]);; proofgeneral-4.3~pre130510/hol-light/TacticRecording/gvexport.ml000066400000000000000000000036041214562307500245750ustar00rootroot00000000000000(* ========================================================================== *) (* GRAPHVIZ EXPORT (HOL LIGHT) *) (* - Exporting recorded tactics into a Dot file for GraphViz *) (* *) (* By Mark Adams *) (* Copyright (c) Univeristy of Edinburgh, 2012 *) (* ========================================================================== *) let cluster_count = ref 0;; let rec print_gv_graphelem d ge = match ge with Box (l,ges) -> let () = (cluster_count := !cluster_count + 1) in (print_indent d; print_string "subgraph cluster"; print_int !cluster_count; print_string " "; print_string "{\n"; print_indent (d+2); print_string "label = "; print_label l; print_string ";\n"; do_list (print_gv_graphelem (d+2)) ges; print_indent d; print_string "}\n") | Line (id1,id2) -> (print_indent d; print_goalid id1; print_string " -> "; print_goalid id2; print_string ";\n") | Single id -> (print_indent d; print_goalid id; print_string ";\n") | Name (id,x) -> (print_indent d; print_goalid id; print_string " [label = "; print_fstring x; print_string "];\n");; let print_gv_graph ges = let () = (cluster_count := 0) in (print_string "digraph G {\n"; do_list (print_gv_graphelem 2) ges; print_string "}\n");; let print_hiproof_gv_graph h = let h' = (trivsimp_hiproof o rightgroup_hiproof o trivsimp_hiproof o dethen_hiproof) h in let ges = hiproof_graph h' in print_gv_graph ges;; let print_gtree_gv_proof gtr = let h = gtree_to_hiproof gtr in print_hiproof_gv_graph h;; let print_gv_proof () = print_gtree_gv_proof !the_goal_tree;; proofgeneral-4.3~pre130510/hol-light/TacticRecording/hiproofs.ml000066400000000000000000000306371214562307500245560ustar00rootroot00000000000000(* ========================================================================== *) (* HIPROOFS (HOL LIGHT) *) (* - Hiproofs and refactoring operations *) (* *) (* By Mark Adams *) (* Copyright (c) Univeristy of Edinburgh, 2012 *) (* ========================================================================== *) (* This file defines a hiproof [1] datatype and various operations on it. *) (* The datatype closely resembles that proposed in [2], with the notable *) (* difference that atomic steps carry their arity. *) (* [1] "Hiproofs: A Hierarchical Notion of Proof Tree", Denney, Power & *) (* Tourlas, 2006. *) (* [2] "A Tactic Language for Hiproofs", Aspinall, Denney & Luth, 2008. *) (* ** DATATYPE ** *) (* Hiproof datatype *) (* Note that atomic tactics are labelled with their arity, corresponding to *) (* how many subgoals they result in. An arity of -1 indicates unknown, and 0 *) (* indicates a tactic that completes its goal. *) type hiproof = Hactive of goalid (* Active subgoal *) | Hatomic of (goalid * int) (* Atomic tactic + arity *) | Hidentity of goalid (* Null, for wiring *) | Hlabelled of (label * hiproof) (* Box *) | Hsequence of (hiproof * hiproof) (* Serial application *) | Htensor of hiproof list (* Parallel application *) | Hempty;; (* Completed goal *) (* Constructors and destructors *) let hsequence (h1,h2) = Hsequence (h1,h2);; let dest_hsequence h = match h with Hsequence hh -> hh | _ -> failwith "Not a sequence hiproof";; let is_hsequence h = can dest_hsequence h;; let is_hidentity h = match h with Hidentity _ -> true | _ -> false;; let hiproof_id h = match h with Hactive id | Hatomic (id,_) | Hidentity id -> id | _ -> failwith "hiproof_id: Not a unit hiproof";; (* Arity *) let rec hiproof_arity h = match h with Hactive _ -> 1 | Hatomic (_,n) -> n | Hidentity _ -> 1 | Hlabelled (_,h0) -> hiproof_arity h0 | Hsequence (h1,h2) -> hiproof_arity h2 | Htensor hs -> sum (map hiproof_arity hs) | Hempty -> 0;; (* Hitrace *) type hitrace = Hicomment of int list | Hiproof of hiproof;; (* ** TRANSLATION OF GOAL TREE TO HIPROOF ** *) let rec gtree_to_hiproof gtr = let id = gtree_id gtr in let (_,gtrm) = gtr in match !gtrm with Gactive -> Hactive id | Gexit _ -> Hidentity id | Gexecuted (gstp,gtrs) -> let h1 = match gstp with Gatom _ | Gbox (_,_,true) -> Hatomic (id, length gtrs) | Gbox (l,gtr,false) -> Hlabelled (l, gtree_to_hiproof gtr) in let h2 = Htensor (map gtree_to_hiproof gtrs) in Hsequence (h1,h2);; (* ** REFACTORING OPERATIONS ** *) (* Generic refactoring operation *) (* Applies a refactoring function 'foo' at every level of hiproof 'h', from *) (* bottom up. If the 'r' flag is set then refactoring is repeated bottom up *) (* whenever 'foo' makes a change. Note that if 'foo' makes no change then it *) (* should just return its input hiproof (rather than raise an exception). *) let rec refactor_hiproof r foo h = let h' = match h with Hlabelled (l,h0) -> let h0' = refactor_hiproof r foo h0 in Hlabelled (l,h0') | Hsequence (h1,h2) -> let h1' = refactor_hiproof r foo h1 in let h2' = refactor_hiproof r foo h2 in Hsequence (h1',h2') | Htensor hs -> let hs' = map (refactor_hiproof r foo) hs in Htensor hs' | _ -> h in let h'' = if (h' = h) then h else h' in let h''' = foo h'' in if r & not (h''' = h'') then refactor_hiproof r foo h''' else h''';; (* Trivial simplification *) (* Removes basic algebraic identities/zeros. *) let collapse_tensor h hs = match h with Hempty -> hs | Htensor hs0 -> hs0 @ hs | _ -> h :: hs;; let trivsimp_hiproof h = let trivsimp h = match h with Hatomic (id,_) when (gtree_tactic (get_gtree id) = ("ALL_TAC",[])) -> Hidentity id | Hsequence (h1, Hempty) -> h1 | Hsequence (h1, Hidentity _) -> h1 | Hsequence (h1, Htensor hs2) -> if (forall is_hidentity hs2) then h1 else h | Hsequence (Hidentity _, h2) -> h2 | Hsequence (Htensor hs1, h2) -> if (forall is_hidentity hs1) then h2 else h | Htensor [] -> Hempty | Htensor [h0] -> h0 | Htensor hs0 -> Htensor (foldr collapse_tensor hs0 []) | _ -> h in refactor_hiproof true trivsimp h;; (* Matching up two tensored lists to create single tensored list *) let rec matchup_hiproofs0 hs1 hs2 = match hs1 with [] -> [] | h1::hs01 -> let n1 = hiproof_arity h1 in let (hs2a,hs2b) = try chop_list n1 hs2 with Failure _ -> if (n1 = -1) then failwith "matchup_hiproofs: unknown arity" else failwith "matchup_hiproofs: Internal error - \ inconsistent arities" in (h1,hs2a) :: (matchup_hiproofs0 hs01 hs2b);; let matchup_hiproofs hs1 hs2 = let hhs = matchup_hiproofs0 hs1 hs2 in map (fun (h1,hs2) -> Hsequence (h1, Htensor hs2)) hhs;; (* Separating out tensored list into head tensor and tail tensor *) let separate_hiproofs0 h (hs01,hs02) = match h with Hsequence (h1,h2) -> (h1::hs01, h2::hs02) | _ -> let n = hiproof_arity h in let h2 = Htensor (copy n (Hidentity (-1))) in (h::hs01, h2::hs02);; let separate_hiproofs hs = foldr separate_hiproofs0 hs ([],[]);; (* Delabelling *) (* Strips out any boxes from the proof. Note that some boxes, such as *) (* 'SUBGOAL_THEN', cannot be stripped out without spoiling the proof, and so *) (* are left alone. *) let delabel_hiproof h = let delabel h = match h with Hlabelled (Tactical ("SUBGOAL_THEN",_), h0) -> h | Hlabelled (_,h0) -> h0 | _ -> h in refactor_hiproof true delabel h;; let dethen_hiproof h = let dethen h = match h with Hlabelled (Tactical (("THEN" | "THENL"),_), h0) -> h0 | _ -> h in refactor_hiproof true dethen h;; (* Right-grouping *) (* Expands the proof into a right-associative sequence, with tensor *) (* compounding on the right. Leaves all boxes unchanged. *) let rightgroup_hiproof h = let rightgroup h = match h with Hsequence (Hsequence (h1, Htensor hs2), Htensor hs3) -> Hsequence (h1, Htensor (matchup_hiproofs hs2 hs3)) | Hsequence (Hsequence (h1, Htensor hs2), h3) -> Hsequence (h1, Htensor (matchup_hiproofs hs2 [h3])) | Hsequence (Hsequence (h1,h2), h3) -> Hsequence (h1, Hsequence (h2,h3)) | _ -> h in refactor_hiproof true rightgroup h;; (* Left-grouping *) (* Expands the proof into a left-associative sequence. *) let leftgroup_hiproof h = let leftgroup h = match h with Hsequence (h1, Hsequence (h2, h3)) -> Hsequence (Hsequence (h1,h2), h3) | _ -> h in refactor_hiproof true leftgroup h;; (* THEN insertion *) (* Looks for opportunities to use 'THEN' tacticals. Note that assumes a *) (* normal form where trivsimp has taken place. *) let rec head_hiproof_equiv h1 h2 = match (h1,h2) with (Hatomic (id1,_), Hatomic (id2,_)) -> (gtree_tactic o get_gtree) id1 = (gtree_tactic o get_gtree) id2 | (Hidentity _, Hidentity _) -> true | (Hsequence (h1a,h1b), h2) -> head_hiproof_equiv h1a h2 | (h1, Hsequence (h2a,h2b)) -> head_hiproof_equiv h1 h2a | (Hempty, Hempty) -> true | _ -> false;; let thenise_hiproof h = let rec thenise h = match h with Hsequence (h1, Htensor (h2::h2s)) -> if not (is_hidentity h2) & (forall (head_hiproof_equiv h2) h2s) then let (hs2a,hs2b) = separate_hiproofs (h2::h2s) in let h' = Hsequence (Hlabelled (Tactical ("THEN",[]), Hsequence (h1, Htensor hs2a)), Htensor hs2b) in thenise h' else h | _ -> h in refactor_hiproof false thenise h;; (* ** HIPROOF GRAPH ** *) (* Graph element datatype *) type graph_elem = Box of (label * graph_elem list) | Line of (goalid * goalid) | Single of goalid | Name of (goalid * string);; let is_box ge = match ge with Box _ -> true | _ -> false;; let mk_line id1 id2 = Line (id1,id2);; let rec graph_elem_nodes ge = match ge with Box (_,ges) -> graph_nodes ges | Line (id1,id2) -> [id1;id2] | Single id -> [id] | Name (id,x) -> [id] and graph_nodes ges = foldr (fun ge ids -> union (graph_elem_nodes ge) ids) ges [];; (* Utils *) let rec hiproof_ins h = match h with Hactive id -> [id] | Hatomic (id,n) -> [id] | Hidentity id -> [-1] | Hlabelled (l,h0) -> hiproof_ins h0 | Hsequence (h1,h2) -> hiproof_ins h1 | Htensor hs -> flat (map hiproof_ins hs) | Hempty -> [];; let rec hiproof_outs (h:hiproof) : goalid list = match h with Hactive id -> [id] | Hatomic (id,n) -> copy n id | Hidentity id -> [id] | Hlabelled (l,h0) -> hiproof_outs h0 | Hsequence (h1, Htensor hs2) -> let nhs2 = enumerate hs2 in let ids1 = hiproof_outs h1 in let foo (n2,h2) = if (is_hidentity h2) then [el (n2-1) ids1] else hiproof_outs h2 in flat (map foo nhs2) | Hsequence (h1,h2) -> hiproof_outs h2 | Htensor hs -> flat (map hiproof_outs hs) | Hempty -> [];; (* Graph production *) let rec hiproof_graph0 h = match h with Hactive _ -> [] | Hatomic _ -> [] | Hidentity _ -> [] | Hlabelled (l,Hatomic (id,_)) -> [Box (l, [Single id])] | Hlabelled (l,h0) -> [Box (l, hiproof_graph0 h0)] | Hsequence (h1,h2) -> let idids = zip (hiproof_outs h1) (hiproof_ins h2) in let idids' = filter (fun (_,id2) -> (id2 > 0)) idids in (hiproof_graph0 h1) @ (map (fun idid -> Line idid) idids') @ (hiproof_graph0 h2) | Htensor hs -> flat (map hiproof_graph0 hs) | Hempty -> [];; let hiproof_graph h = let ges = hiproof_graph0 h in let ids = graph_nodes ges in let tacname_of_id id = (fst o gtree_tactic1 o get_gtree) id in let ges' = map (fun id -> Name (id, tacname_of_id id)) ids in ges' @ ges;; (* ** OTHER OPERATIONS ** *) (* Tactic trace *) (* Gives a linear trace of the basic tactics used in the proof, ignoring how *) (* they were combined by tacticals. *) let rec hiproof_tactic_trace0 h = match h with Hactive _ -> [active_info] | Hatomic (id, _) -> [gtree_tactic (get_gtree id)] | Hidentity _ -> [] | Hlabelled (_,h0) -> hiproof_tactic_trace0 h0 | Hsequence (h1,h2) -> (hiproof_tactic_trace0 h1) @ (hiproof_tactic_trace0 h2) | Htensor hs -> flat (map hiproof_tactic_trace0 hs) | Hempty -> [];; let hiproof_tactic_trace h = (hiproof_tactic_trace0 o delabel_hiproof) h;; (* Block trace *) (* Gives a linear trace of the hiproofs used in the proof, stopping at boxes. *) let rec hiproof_block_trace0 ns0 h = match h with | Hsequence (h1,h2) -> (hiproof_block_trace0 ns0 h1) @ (hiproof_block_trace0 ns0 h2) | Htensor hs -> let nss = map (fun n -> ns0 @ [n]) (1 -- length hs) in flat (map (fun (ns,h) -> (Hicomment ns) :: hiproof_block_trace0 ns h) (zip nss hs)) | _ -> [Hiproof h];; let hiproof_block_trace h = hiproof_block_trace0 [] h;; proofgeneral-4.3~pre130510/hol-light/TacticRecording/lib.ml000066400000000000000000000030741214562307500234660ustar00rootroot00000000000000 let rec copy n x = if (n > 0) then x::(copy (n-1) x) else [];; let rec enumerate0 n xs = match xs with [] -> [] | x::xs0 -> (n,x)::enumerate0 (n+1) xs0;; let enumerate xs = enumerate0 1 xs;; (* foldr : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b *) let rec foldr f xs a = match xs with x1::xs2 -> f x1 (foldr f xs2 a) | [] -> a;; (* foldr1 : ('a -> 'a -> 'a) -> 'a list -> 'a *) let rec foldr1 f xs = match xs with x::[] -> x | x1::xs2 -> f x1 (foldr1 f xs2) | [] -> failwith "foldr1: Empty list";; (* foldl : ('b -> 'a -> 'b) -> 'b -> 'a list -> 'b *) let rec foldl f a xs = match xs with x1::xs2 -> foldl f (f a x1) xs2 | [] -> a;; (* is_empty *) let is_empty xs = match xs with [] -> true | _ -> false;; (* front *) let rec front xs = match xs with _::[] -> [] | x0::xs0 -> x0::(front xs0) | [] -> failwith "front: Empty list";; (* string_option *) let string_option x0 x_ = match x_ with Some x -> x | None -> x0;; (* print_option *) let print_option x0 x_ = match x_ with Some x -> print_string x | None -> print_string x0;; (* seplists *) let print_seplist p sep xs = if (xs = []) then () else (p (hd xs); do_list (fun x -> print_string sep; p x) (tl xs));; let print_string_seplist sep xs = print_seplist print_string sep xs;; (* sum *) let sum ns = foldl (+) 0 ns;; (* snd_map *) let snd_map f xys = map (fun (x,y) -> (x, f y)) xys;; proofgeneral-4.3~pre130510/hol-light/TacticRecording/main.ml000066400000000000000000000012651214562307500236440ustar00rootroot00000000000000(* Library stuff *) #use "TacticRecording/lib.ml";; #use "TacticRecording/dltree.mli";; #use "TacticRecording/dltree.ml";; (* Datatypes and recording mechanism *) #use "TacticRecording/mldata.ml";; #use "TacticRecording/xthm.ml";; #use "TacticRecording/xtactics.ml";; #use "TacticRecording/tacticrec.ml";; #use "TacticRecording/wrappers.ml";; (* Prooftree support *) #use "TacticRecording/prooftree.ml";; (* Hiproofs & refactoring *) #use "TacticRecording/hiproofs.ml";; (* Export *) #use "TacticRecording/printutils.ml";; #use "TacticRecording/gvexport.ml";; #use "TacticRecording/mlexport.ml";; (* Overwriting the existing HOL Light objects *) #use "TacticRecording/promote.ml";; proofgeneral-4.3~pre130510/hol-light/TacticRecording/mldata.ml000066400000000000000000000010651214562307500241600ustar00rootroot00000000000000 type mlarg = Mlint of int | Mlstring of string | Mlterm of term | Mltype of hol_type | Mlthm of mldata | Mlpair of mlarg * mlarg | Mllist of mlarg list | Mlfn of mldata and mldata = string * mlarg list;; (* ML object name and args *) type label = Tactical of mldata | Label of string;; (* Atomic tests *) let is_atomic_mlarg arg = match arg with Mlthm (_,(_::_)) | Mlpair _ | Mlfn (_, _::_) -> false | _ -> true;; let is_atomic_mldata ((x,args):mldata) = (is_empty args);; (* active_info *) let active_info = ("...",[]);; proofgeneral-4.3~pre130510/hol-light/TacticRecording/mlexport.ml000066400000000000000000000141151214562307500245700ustar00rootroot00000000000000(* ========================================================================== *) (* ML EXPORT (HOL LIGHT) *) (* - Exporting recorded tactics into a proof script *) (* *) (* By Mark Adams *) (* Copyright (c) Univeristy of Edinburgh, 2012 *) (* ========================================================================== *) (* Routines for exporting an ML tactic proof script from the recorded tactic *) (* proof tree, via a hiproof representation. *) (* ** UTILS ** *) (* Printer for tactic is just the ML data printer *) let print_tactic br obj = print_mldata br obj;; (* Printer for subgoal comments *) let print_hicomment_line ns = (print_string "(* *** Subgoal "; print_int (hd ns); do_list (fun n -> print_string "."; print_int n) (tl ns); print_string " *** *)\n");; (* print_tactic_line *) let print_tactic_line_with pr arg = (print_string "e ("; pr false arg; print_string ");;\n");; let print_tactic_line obj = (print_tactic_line_with print_tactic obj);; let print_hitrace_line_with fl pr htr = match htr with Hicomment ns -> if fl then print_hicomment_line ns | Hiproof h -> print_tactic_line_with pr h;; (* print_hiproof0 *) (* This is a utility used in exporters, for basic cases not explicitly dealt *) (* with in the exporter's special cases. Does not print tacticals, other *) (* than 'THEN' (for single arity) and 'THENL' (for multi-arity). Argument *) (* 'pr' is the printer to be used on subcases. *) let print_hiproof0 pr br h = match h with Hactive _ -> print_string "..." | Hatomic (id,_) -> print_tactic br (gtree_tactic (get_gtree id)) | Hidentity _ -> print_string "ALL_TAC" | Hlabelled (_,h0) -> pr br h0 | Hsequence (h1, Htensor h2s) -> (print_string_if br "("; pr false h1; print_string " THENL ["; print_seplist (pr false) "; " h2s; print_string "]"; print_string_if br ")") | Hsequence (h1,Hempty) -> (pr br h1) | Hsequence (h1,h2) -> (print_string_if br "("; pr false h1; print_string " THEN "; pr true h2; print_string_if br ")") | Htensor _ -> failwith "print_hiproof: Unexpected tensor" | Hempty -> failwith "print_hiproof: Unexpected empty";; (* A basic hiproof printer that just uses 'print_hiproof0'. *) let rec print_hiproof1 br h = print_hiproof0 print_hiproof1 br h;; (* print_hiproof2 *) let rec print_hiproof2 br h = match h with Hlabelled (Tactical ("REPEAT", _), Hsequence (h1,h2)) (* if repeated *) -> (print_string_if br "("; print_string "REPEAT "; print_hiproof2 true h1; print_string_if br ")") | Hlabelled (Tactical ("THEN", _), (* if tac2 used *) Hsequence (h1, Htensor (h2::h2s))) -> (print_string_if br "("; print_hiproof2 false h1; print_string " THEN "; print_hiproof2 true h2; print_string_if br ")") | Hlabelled (Tactical (("SUBGOAL_THEN", (* special case *) (Mlterm tm)::[_]) as obj), _) -> (print_tactic br obj) | Hlabelled (Label x, h) -> (print_string_if br "("; print_string "HILABEL "; print_fstring x; print_string " "; print_hiproof2 true h; print_string_if br ")") | _ -> (print_hiproof0 print_hiproof2 br h);; (* ** PRINTERS ** *) (* Executed proof *) (* Prints proof according to how it was executed, i.e. using the original e- *) (* steps and according to any user-supplied 'REPEAT' and 'THEN' tacticals, *) (* but only those parts that actually execute and not according to any other *) (* tacticals. *) let print_hiproof_executed_proof fl h = let h' = trivsimp_hiproof h in let htrs' = hiproof_block_trace h' in do_list (print_hitrace_line_with fl print_hiproof2) htrs';; let print_gtree_executed_proof fl gtr = (print_hiproof_executed_proof fl o gtree_to_hiproof) gtr;; let print_executed_proof fl = print_gtree_executed_proof fl !the_goal_tree;; (* Packaged proof *) (* Prints proof as a monolithic step, spotting opportunities for 'REPEAT' and *) (* multi-arity 'THEN' tacticals in addition to those already in proof. *) (* ! 'REPEAT' not currently catered for. *) let print_hiproof_packaged_proof h = let h' = (trivsimp_hiproof o thenise_hiproof o trivsimp_hiproof o leftgroup_hiproof) h in print_tactic_line_with print_hiproof2 h';; let print_gtree_packaged_proof gtr = (print_hiproof_packaged_proof o gtree_to_hiproof) gtr;; let print_packaged_proof () = print_gtree_packaged_proof !the_goal_tree;; (* THENL proof *) (* Prints proof as a naive monolithic step, using 'THEN' for single arity, *) (* and 'THENL' for multi-arity (even if each subgoal has the same proof). *) (* This gives the full structure of each tactic execution. *) let print_hiproof_thenl_proof h = let h' = (trivsimp_hiproof o delabel_hiproof) h in print_tactic_line_with print_hiproof1 h';; let print_gtree_thenl_proof gtr = (print_hiproof_thenl_proof o gtree_to_hiproof) gtr;; let print_thenl_proof () = print_gtree_thenl_proof !the_goal_tree;; (* Flat proof *) (* This exports a proof as a flat series of e-steps, with no tacticals. *) let print_hiproof_flat_proof fl h = let h' = (trivsimp_hiproof o rightgroup_hiproof o trivsimp_hiproof o delabel_hiproof) h in let htrs' = hiproof_block_trace h' in do_list (print_hitrace_line_with fl print_hiproof2) htrs';; let print_gtree_flat_proof fl gtr = (print_hiproof_flat_proof fl o gtree_to_hiproof) gtr;; let print_flat_proof fl = print_gtree_flat_proof fl !the_goal_tree;; proofgeneral-4.3~pre130510/hol-light/TacticRecording/printutils.ml000066400000000000000000000040371214562307500251350ustar00rootroot00000000000000(* ========================================================================== *) (* PRINTER UTILITIES (HOL LIGHT) *) (* - Various basic utilities used in writing the exporters *) (* *) (* By Mark Adams *) (* Copyright (c) Univeristy of Edinburgh, 2012 *) (* ========================================================================== *) (* Basics *) let print_string_if b x = if b then print_string x;; let print_fstring x = print_string ("\"" ^ String.escaped x ^ "\"");; let print_fterm tm = print_string ("`" ^ string_of_term tm ^ "`");; let print_ftype ty = print_string ("`" ^ string_of_type ty ^ "`");; let print_goalid id = print_int id;; let print_indent d = print_string (String.make d ' ');; (* Printer for 'mldata' *) let rec print_mlarg br arg = match arg with Mlint n -> print_int n | Mlstring x -> print_fstring x | Mlterm tm -> print_fterm tm | Mltype ty -> print_ftype ty | Mlthm prf -> print_mldata br prf | Mlpair (arg1,arg2) -> let sep = if (forall is_atomic_mlarg [arg1;arg2]) then "," else ", " in (print_string_if br "("; print_mlarg false arg1; print_string sep; print_mlarg false arg2; print_string_if br ")") | Mllist args -> let sep = if (forall is_atomic_mlarg args) then ";" else "; " in (print_string "["; print_seplist (print_mlarg false) sep args; print_string "]") | Mlfn f -> (print_mldata br f) and print_mldata br ((x,args):mldata) = (print_string_if (br & not (is_empty args)) "("; print_string x; do_list (fun arg -> print_string " "; print_mlarg true arg) args; print_string_if (br & not (is_empty args)) ")");; (* Printer for labels *) let print_label l = match l with Tactical (x,_) | Label x -> print_fstring x;; proofgeneral-4.3~pre130510/hol-light/TacticRecording/promote.ml000066400000000000000000000332721214562307500244100ustar00rootroot00000000000000(* ========================================================================== *) (* PROMOTTION (HOL LIGHT) *) (* - Overwrites original HOL Light tactics/etc with xgoal/xthm versions *) (* *) (* By Mark Adams *) (* Copyright (c) Univeristy of Edinburgh, 2012 *) (* ========================================================================== *) (* ** TACTICS.ML ** *) (* Tactics *) (* Atomic tactics can be automatically promoted to deal with xgoals and *) (* recording. *) let NO_TAC = tactic_wrap "NO_TAC" NO_TAC;; let ALL_TAC = tactic_wrap "ALL_TAC" ALL_TAC;; let LABEL_TAC = stringthm_tactic_wrap "LABEL_TAC" LABEL_TAC;; let ASSUME_TAC = thm_tactic_wrap "ASSUME_TAC" ASSUME_TAC;; let ACCEPT_TAC = thm_tactic_wrap "ACCEPT_TAC" ACCEPT_TAC;; let CONV_TAC = conv_tactic_wrap "CONV_TAC" CONV_TAC;; let REFL_TAC = tactic_wrap "REFL_TAC" REFL_TAC;; let ABS_TAC = tactic_wrap "ABS_TAC" ABS_TAC;; let MK_COMB_TAC = tactic_wrap "MK_COMB_TAC" MK_COMB_TAC;; let AP_TERM_TAC = tactic_wrap "AP_TERM_TAC" AP_TERM_TAC;; let AP_THM_TAC = tactic_wrap "AP_THM_TAC" AP_THM_TAC;; let BINOP_TAC = tactic_wrap "BINOP_TAC" BINOP_TAC;; let SUBST1_TAC = thm_tactic_wrap "SUBST1_TAC" SUBST1_TAC;; let SUBST_ALL_TAC = thm_tactic_wrap "SUBST_ALL_TAC" SUBST_ALL_TAC;; let BETA_TAC = tactic_wrap "BETA_TAC" BETA_TAC;; let SUBST_VAR_TAC = thm_tactic_wrap "SUBST_VAR_TAC" SUBST_VAR_TAC;; let DISCH_TAC = tactic_wrap "DISCH_TAC" DISCH_TAC;; let MP_TAC = thm_tactic_wrap "MP_TAC" MP_TAC;; let EQ_TAC = tactic_wrap "EQ_TAC" EQ_TAC;; let UNDISCH_TAC = term_tactic_wrap "UNDISCH_TAC" UNDISCH_TAC;; let SPEC_TAC = termpair_tactic_wrap "SPEC_TAC" SPEC_TAC;; let X_GEN_TAC = term_tactic_wrap "X_GEN_TAC" X_GEN_TAC;; let GEN_TAC = tactic_wrap "GEN_TAC" GEN_TAC;; let EXISTS_TAC = term_tactic_wrap "EXISTS_TAC" EXISTS_TAC;; let CHOOSE_TAC = thm_tactic_wrap "CHOOSE_TAC" CHOOSE_TAC;; let CONJ_TAC = tactic_wrap "CONJ_TAC" CONJ_TAC;; let DISJ1_TAC = tactic_wrap "DISJ1_TAC" DISJ1_TAC;; let DISJ2_TAC = tactic_wrap "DISJ2_TAC" DISJ2_TAC;; let DISJ_CASES_TAC = thm_tactic_wrap "DISJ_CASES_TAC" DISJ_CASES_TAC;; let CONTR_TAC = thm_tactic_wrap "CONTR_TAC" CONTR_TAC;; let MATCH_ACCEPT_TAC = thm_tactic_wrap "MATCH_ACCEPT_TAC" MATCH_ACCEPT_TAC;; let MATCH_MP_TAC = thm_tactic_wrap "MATCH_MP_TAC" MATCH_MP_TAC;; let STRIP_ASSUME_TAC = thm_tactic_wrap "STRIP_ASSUME_TAC" STRIP_ASSUME_TAC;; let STRUCT_CASES_TAC = thm_tactic_wrap "STRUCT_CASES_TAC" STRUCT_CASES_TAC;; let STRIP_TAC = tactic_wrap "STRIP_TAC" STRIP_TAC;; let X_META_EXISTS_TAC = term_tactic_wrap "X_META_EXISTS_TAC" X_META_EXISTS_TAC;; let META_EXISTS_TAC = tactic_wrap "META_EXISTS_TAC" META_EXISTS_TAC;; let ANTS_TAC = tactic_wrap "ANTS_TAC" ANTS_TAC;; (* Special cases, already fully hand-promoted *) let SUBGOAL_THEN = xSUBGOAL_THEN;; (* Tacticals *) (* Tacticals need to be hand-promoted to deal with xgoals, but this is *) (* trivial and is done in 'xtactics.ml'. They are further promoted here to *) (* get recorded as boxes, using the tactical-wrap functions. *) let (THEN) = btactical_wrap "THEN" (xTHEN);; let (THENL) = btactical_wrap "THENL" (xTHENL);; let (ORELSE) = btactical_wrap "ORELSE" (xORELSE);; let TRY = tactical_wrap "TRY" xTRY;; let REPEAT = tactical_wrap "REPEAT" xREPEAT;; let EVERY = tactical_wrap "EVERY" xEVERY;; let FIRST = tactical_wrap "FIRST" xFIRST;; let MAP_EVERY = list_tactical_wrap "MAP_EVERY" xMAP_EVERY;; let MAP_FIRST = list_tactical_wrap "MAP_FIRST" xMAP_FIRST;; let CHANGED_TAC = tactical_wrap "CHANGED_TAC" xCHANGED_TAC;; let REPLICATE_TAC = int_tactical_wrap "REPLICATE_TAC" xREPLICATE_TAC;; (* Subgoal commands *) let e = xe;; let r = xr;; let set_goal = xset_goal;; let g = xg;; let b = xb;; let p = xp;; let top_goal = xtop_goal;; let top_thm = xtop_thm;; let prove = xprove;; (* ** COMMON HOL API ** *) (* Rules *) let ADD_ASSUM = term_rule_wrap "ADD_ASSUM" ADD_ASSUM;; let ASSUME = conv_wrap "ASSUME" ASSUME;; let BETA_CONV = conv_wrap "BETA_CONV" BETA_CONV;; let CCONTR = term_rule_wrap "CCONTR" CCONTR;; let CHOOSE = termthmpair_rule_wrap "CHOOSE" CHOOSE;; let CONJ = drule_wrap "CONJ" CONJ;; let CONJUNCT1 = rule_wrap "CONJUNCT1" CONJUNCT1;; let CONJUNCT2 = rule_wrap "CONJUNCT2" CONJUNCT2;; let CONTR = term_rule_wrap "CONTR" CONTR;; let DEDUCT_ANTISYM_RULE = drule_wrap "DEDUCT_ANTISYM_RULE" DEDUCT_ANTISYM_RULE;; let DISCH = term_rule_wrap "DISCH" DISCH;; let DISJ1 = thm_conv_wrap "DISJ1" DISJ1;; let DISJ2 = term_rule_wrap "DISJ2" DISJ2;; let DISJ_CASES = trule_wrap "DISJ_CASES" DISJ_CASES;; let EQ_MP = drule_wrap "EQ_MP" EQ_MP;; let EQF_INTRO = rule_wrap "EQF_INTRO" EQF_INTRO;; let EQF_ELIM = rule_wrap "EQF_ELIM" EQF_ELIM;; let EQT_INTRO = rule_wrap "EQT_INTRO" EQT_INTRO;; let EQT_ELIM = rule_wrap "EQT_ELIM" EQT_ELIM;; let ETA_CONV = conv_wrap "ETA_CONV" ETA_CONV;; let EXISTS = termpair_rule_wrap "EXISTS" EXISTS;; let GEN = term_rule_wrap "GEN" GEN;; let GENL = termlist_rule_wrap "GENL" GENL;; let IMP_ANTISYM_RULE = drule_wrap "IMP_ANTISYM_RULE" IMP_ANTISYM_RULE;; let IMP_TRANS = drule_wrap "IMP_TRANS" IMP_TRANS;; let INST = terminst_rule_wrap "INST" INST;; let INST_TYPE = typeinst_rule_wrap "INST_TYPE" INST_TYPE;; let MP = drule_wrap "MP" MP;; let NOT_ELIM = rule_wrap "NOT_ELIM" NOT_ELIM;; let NOT_INTRO = rule_wrap "NOT_INTRO" NOT_INTRO;; let PROVE_HYP = drule_wrap "PROVE_HYP" PROVE_HYP;; let REFL = conv_wrap "REFL" REFL;; let SELECT_RULE = rule_wrap "SELECT_RULE" SELECT_RULE;; let SPEC = term_rule_wrap "SPEC" SPEC;; let SPECL = termlist_rule_wrap "SPECL" SPECL;; let SUBS = thmlist_rule_wrap "SUBS" SUBS;; let SUBS_CONV = thmlist_conv_wrap "SUBS_CONV" SUBS_CONV;; let SYM = rule_wrap "SYM" SYM;; let SYM_CONV = conv_wrap "SYM_CONV" SYM_CONV;; let TRANS = drule_wrap "TRANS" TRANS;; let UNDISCH = rule_wrap "UNDISCH" UNDISCH;; let ABS = term_rule_wrap "ABS" ABS;; let MK_COMB = prule_wrap "MK_COMB" MK_COMB;; let AP_THM = thm_conv_wrap "AP_THM" AP_THM;; let AP_TERM = term_rule_wrap "AP_TERM" AP_TERM;; let NUM_SUC_CONV = conv_wrap "NUM_SUC_CONV" NUM_SUC_CONV;; let NUM_PRE_CONV = conv_wrap "NUM_PRE_CONV" NUM_PRE_CONV;; let NUM_ADD_CONV = conv_wrap "NUM_ADD_CONV" NUM_ADD_CONV;; let NUM_SUB_CONV = conv_wrap "NUM_SUB_CONV" NUM_SUB_CONV;; let NUM_MULT_CONV = conv_wrap "NUM_MULT_CONV" NUM_MULT_CONV;; let NUM_EXP_CONV = conv_wrap "NUM_EXP_CONV" NUM_EXP_CONV;; let NUM_EQ_CONV = conv_wrap "NUM_EQ_CONV" NUM_EQ_CONV;; let NUM_LT_CONV = conv_wrap "NUM_LT_CONV" NUM_LT_CONV;; let NUM_LE_CONV = conv_wrap "NUM_LE_CONV" NUM_LE_CONV;; let NUM_GT_CONV = conv_wrap "NUM_GT_CONV" NUM_GT_CONV;; let NUM_EVEN_CONV = conv_wrap "NUM_EVEN_CONV" NUM_EVEN_CONV;; let NUM_ODD_CONV = conv_wrap "NUM_ODD_CONV" NUM_ODD_CONV;; (* Theorems *) let ETA_AX = theorem_wrap "ETA_AX" ETA_AX;; let INFINITY_AX = theorem_wrap "INFINITY_AX" INFINITY_AX;; let BOOL_CASES_AX = theorem_wrap "BOOL_CASES_AX" BOOL_CASES_AX;; let SELECT_AX = theorem_wrap "SELECT_AX" SELECT_AX;; let TRUTH = theorem_wrap "TRUTH" TRUTH;; let EXCLUDED_MIDDLE = theorem_wrap "EXCLUDED_MIDDLE" EXCLUDED_MIDDLE;; let PAIR_EQ = theorem_wrap "PAIR_EQ" PAIR_EQ;; let PAIR_SURJECTIVE = theorem_wrap "PAIR_SURJECTIVE" PAIR_SURJECTIVE;; let FST = theorem_wrap "FST" FST;; let SND = theorem_wrap "SND" SND;; let IND_SUC_0 = theorem_wrap "IND_SUC_0" IND_SUC_0;; let IND_SUC_INJ = theorem_wrap "IND_SUC_INJ" IND_SUC_INJ;; let NOT_SUC = theorem_wrap "NOT_SUC" NOT_SUC;; let SUC_INJ = theorem_wrap "SUC_INJ" SUC_INJ;; let num_INDUCTION = theorem_wrap "num_INDUCTION" num_INDUCTION;; let num_CASES = theorem_wrap "num_CASES" num_CASES;; let num_RECURSION = theorem_wrap "num_RECURSION" num_RECURSION;; let PRE = theorem_wrap "PRE" PRE;; let ADD = theorem_wrap "ADD" ADD;; let SUB = theorem_wrap "SUB" SUB;; let MULT = theorem_wrap "MULT" MULT;; let EXP = theorem_wrap "EXP" EXP;; let LT = theorem_wrap "LT" LT;; let LE = theorem_wrap "LE" LE;; let GT = theorem_wrap "GT" GT;; let GE = theorem_wrap "GE" GE;; let EVEN = theorem_wrap "EVEN" EVEN;; let ODD = theorem_wrap "ODD" ODD;; (* ** OTHER HOL LIGHT ** *) (* More tactics *) let REWRITE_TAC = thmlist_tactic_wrap "REWRITE_TAC" REWRITE_TAC;; let PURE_REWRITE_TAC = thmlist_tactic_wrap "PURE_REWRITE_TAC" PURE_REWRITE_TAC;; let ONCE_REWRITE_TAC = thmlist_tactic_wrap "ONCE_REWRITE_TAC" ONCE_REWRITE_TAC;; let ASM_REWRITE_TAC = thmlist_tactic_wrap "ASM_REWRITE_TAC" ASM_REWRITE_TAC;; let PURE_ASM_REWRITE_TAC = thmlist_tactic_wrap "PURE_ASM_REWRITE_TAC" PURE_ASM_REWRITE_TAC;; let ONCE_ASM_REWRITE_TAC = thmlist_tactic_wrap "ONCE_ASM_REWRITE_TAC" ONCE_ASM_REWRITE_TAC;; let GEN_REWRITE_TAC = convconvthmlist_tactic_wrap "GEN_REWRITE_TAC" GEN_REWRITE_TAC;; let SIMP_TAC = thmlist_tactic_wrap "SIMP_TAC" SIMP_TAC;; let PURE_SIMP_TAC = thmlist_tactic_wrap "PURE_SIMP_TAC" PURE_SIMP_TAC;; let ONCE_SIMP_TAC = thmlist_tactic_wrap "ONCE_SIMP_TAC" ONCE_SIMP_TAC;; let ASM_SIMP_TAC = thmlist_tactic_wrap "ASM_SIMP_TAC" ASM_SIMP_TAC;; let PURE_ASM_SIMP_TAC = thmlist_tactic_wrap "PURE_ASM_SIMP_TAC" PURE_ASM_SIMP_TAC;; let ONCE_ASM_SIMP_TAC = thmlist_tactic_wrap "ONCE_ASM_SIMP_TAC" ONCE_ASM_SIMP_TAC;; let ABBREV_TAC = term_tactic_wrap "ABBREV_TAC" ABBREV_TAC;; let EXPAND_TAC = string_tactic_wrap "EXPAND_TAC" EXPAND_TAC;; let ASM_CASES_TAC = term_tactic_wrap "ASM_CASES_TAC" ASM_CASES_TAC;; let COND_CASES_TAC = tactic_wrap "COND_CASES_TAC" COND_CASES_TAC;; let ARITH_TAC = tactic_wrap "ARITH_TAC" ARITH_TAC;; let INDUCT_TAC = tactic_wrap "INDUCT_TAC" INDUCT_TAC;; let REAL_ARITH_TAC = tactic_wrap "REAL_ARITH_TAC" REAL_ARITH_TAC;; let ASM_REAL_ARITH_TAC = tactic_wrap "ASM_REAL_ARITH_TAC" ASM_REAL_ARITH_TAC;; (* More rules *) let RATOR_CONV = conv_conv_wrap "RATOR_CONV" RATOR_CONV;; let RAND_CONV = conv_conv_wrap "RAND_CONV" RAND_CONV;; let LAND_CONV = conv_conv_wrap "LAND_CONV" LAND_CONV;; let ABS_CONV = conv_conv_wrap "ABS_CONV" ABS_CONV;; let BINDER_CONV = conv_conv_wrap "BINDER_CONV" BINDER_CONV;; let SUB_CONV = conv_conv_wrap "SUB_CONV" SUB_CONV;; let BINOP_CONV = conv_conv_wrap "BINOP_CONV" BINOP_CONV;; let GSYM = rule_wrap "GSYM" GSYM;; let CONJUNCTS = multirule_wrap "CONJUNCTS" CONJUNCTS;; let SPEC_ALL = rule_wrap "SPEC_ALL" SPEC_ALL;; let ISPECL = termlist_rule_wrap "ISPECL" ISPECL;; let ALL_CONV = conv_wrap "ALL_CONV" ALL_CONV;; let (REPEATC) = conv_conv_wrap "REPEATC" REPEATC;; let ONCE_DEPTH_CONV = conv_conv_wrap "ONCE_DEPTH_CONV" ONCE_DEPTH_CONV;; let REWRITE_RULE = thmlist_rule_wrap "REWRITE_RULE" REWRITE_RULE;; let num_CONV = conv_wrap "num_CONV" num_CONV;; let ARITH_RULE = conv_wrap "ARITH_RULE" ARITH_RULE;; let REAL_ARITH = conv_wrap "REAL_ARITH" REAL_ARITH;; let REAL_FIELD = conv_wrap "REAL_FIELD" REAL_FIELD;; (* More theorems *) let CONJ_ASSOC = theorem_wrap "CONJ_ASSOC" CONJ_ASSOC;; let IMP_IMP = theorem_wrap "IMP_IMP" IMP_IMP;; let EQ_IMP = theorem_wrap "EQ_IMP" EQ_IMP;; let ARITH = theorem_wrap "ARITH" ARITH;; let ARITH_EQ = theorem_wrap "ARITH_EQ" ARITH_EQ;; let ADD_ASSOC = theorem_wrap "ADD_ASSOC" ADD_ASSOC;; let ADD_CLAUSES = theorem_wrap "ADD_CLAUSES" ADD_CLAUSES;; let LEFT_ADD_DISTRIB = theorem_wrap "LEFT_ADD_DISTRIB" LEFT_ADD_DISTRIB;; let RIGHT_ADD_DISTRIB = theorem_wrap "RIGHT_ADD_DISTRIB" RIGHT_ADD_DISTRIB;; let MULT_CLAUSES =theorem_wrap "MULT_CLAUSES" MULT_CLAUSES;; let SUB_REFL = theorem_wrap "SUB_REFL" SUB_REFL;; let ADD1 = theorem_wrap "ADD1" ADD1;; let EQ_MULT_LCANCEL = theorem_wrap "EQ_MULT_LCANCEL" EQ_MULT_LCANCEL;; let LE_EXISTS = theorem_wrap "LE_EXISTS" LE_EXISTS;; let LE_ADD = theorem_wrap "LE_ADD" LE_ADD;; let LE_1 = theorem_wrap "LE_1" LE_1;; let LE_REFL = theorem_wrap "LE_REFL" LE_REFL;; let LT_SUC = theorem_wrap "LT_SUC" LT_SUC;; let LT_EXISTS = theorem_wrap "LT_EXISTS" LT_EXISTS;; let LT_NZ = theorem_wrap "LT_NZ" LT_NZ;; let EXP_EQ_0 = theorem_wrap "EXP_EQ_0" EXP_EQ_0;; let FACT = theorem_wrap "FACT" FACT;; let = theorem_wrap "" ;; let REAL_ADD_LDISTRIB = theorem_wrap "REAL_ADD_LDISTRIB" REAL_ADD_LDISTRIB;; let REAL_OF_NUM_ADD = theorem_wrap "REAL_OF_NUM_ADD" REAL_OF_NUM_ADD;; let REAL_OF_NUM_EQ = theorem_wrap "REAL_OF_NUM_EQ" REAL_OF_NUM_EQ;; let REAL_OF_NUM_SUC = theorem_wrap "REAL_OF_NUM_SUC" REAL_OF_NUM_SUC;; let REAL_MUL_ASSOC = theorem_wrap "REAL_MUL_ASSOC" REAL_MUL_ASSOC;; let REAL_MUL_SYM = theorem_wrap "REAL_MUL_SYM" REAL_MUL_SYM;; let REAL_MUL_RID = theorem_wrap "REAL_MUL_RID" REAL_MUL_RID;; let REAL_MUL_RZERO = theorem_wrap "REAL_MUL_RZERO" REAL_MUL_RZERO;; let REAL_DIV_LMUL = theorem_wrap "REAL_DIV_LMUL" REAL_DIV_LMUL;; let REAL_POS = theorem_wrap "REAL_POS" REAL_POS;; let REAL_LE_TRANS = theorem_wrap "REAL_LE_TRANS" REAL_LE_TRANS;; let REAL_LE_MUL = theorem_wrap "REAL_LE_MUL" REAL_LE_MUL;; let REAL_LE_RMUL = theorem_wrap "REAL_LE_RMUL" REAL_LE_RMUL;; let REAL_LE_DIV = theorem_wrap "REAL_LE_DIV" REAL_LE_DIV;; let REAL_LE_SQUARE = theorem_wrap "REAL_LE_SQUARE" REAL_LE_SQUARE;; let REAL_LE_RDIV_EQ = theorem_wrap "REAL_LE_RDIV_EQ" REAL_LE_RDIV_EQ;; let real_pow = theorem_wrap "real_pow" real_pow;; let REAL_POW_2 = theorem_wrap "REAL_POW_2" REAL_POW_2;; let REAL_POW_ZERO = theorem_wrap "REAL_POW_ZERO" REAL_POW_ZERO;; let REAL_POW_ADD = theorem_wrap "REAL_POW_ADD" REAL_POW_ADD;; let REAL_POW_DIV = theorem_wrap "REAL_POW_DIV" REAL_POW_DIV;; let REAL_POW_LE = theorem_wrap "REAL_POW_LE" REAL_POW_LE;; let REAL_POW_LT = theorem_wrap "REAL_POW_LT" REAL_POW_LT;; let SUM_RMUL = theorem_wrap "SUM_RMUL" SUM_RMUL;; let SUM_ADD_SPLIT = theorem_wrap "SUM_ADD_SPLIT" SUM_ADD_SPLIT;; let SUM_POS_LE_NUMSEG = theorem_wrap "SUM_POS_LE_NUMSEG" SUM_POS_LE_NUMSEG;; let SUM_CLAUSES_NUMSEG = theorem_wrap "SUM_CLAUSES_NUMSEG" SUM_CLAUSES_NUMSEG;; let SUM_SING_NUMSEG = theorem_wrap "SUM_SING_NUMSEG" SUM_SING_NUMSEG;; let PRODUCT_CLAUSES_NUMSEG = theorem_wrap "PRODUCT_CLAUSES_NUMSEG" PRODUCT_CLAUSES_NUMSEG;;proofgeneral-4.3~pre130510/hol-light/TacticRecording/prooftree.ml000066400000000000000000000155751214562307500247360ustar00rootroot00000000000000(* ========================================================================= *) (* HOL Light subgoal package amended for Proof General's Prooftree. *) (* *) (* Mark Adams, School of Informatics, University of Edinburgh *) (* *) (* (c) Copyright, University of Edinburgh, 2012 *) (* ========================================================================= *) (* This file provides alternatives to HOL Light's subgoal package commands *) (* that output additional annotations specifically for Prooftree. These *) (* annotations get intercepted by Proof General, which removes them from the *) (* output displayed to the Proof General user. Annotation can be switched *) (* off completely with the 'pg_mode_off' command. *) (* Note that this assumes the existence of xgoals (see 'xtactics.ml'). *) (* ------------------------------------------------------------------------- *) (* Proof General mode, for providing extra annotations for Prooftree. *) (* ------------------------------------------------------------------------- *) let pg_mode = ref (false : bool);; let pg_mode_on () = (pg_mode := true);; let pg_mode_off () = (pg_mode := false);; let get_pg_mode () = !pg_mode;; (* ------------------------------------------------------------------------- *) (* The Prooftree global state is an ever increasing counter. *) (* ------------------------------------------------------------------------- *) let the_pt_global_state = ref 1;; let inc_pt_global_state () = (the_pt_global_state := !the_pt_global_state + 1);; let pt_global_state () = !the_pt_global_state;; (* ------------------------------------------------------------------------- *) (* The Prooftree proof state is the length of the goal stack. *) (* ------------------------------------------------------------------------- *) let pt_proof_state () = length !current_xgoalstack;; let pt_back_to_proof_state n : xgoalstack = let pst = pt_proof_state () in if (0 <= n) & (n <= pst) then (current_xgoalstack := snd (chop_list (pst-n) !current_xgoalstack); !current_xgoalstack) else failwith "Not a valid Prooftree state number";; (* ------------------------------------------------------------------------- *) (* Subgoal package commands adjusted to update Prooftree global state. *) (* ------------------------------------------------------------------------- *) let the_tactic_flag = ref false;; let xe tac = let result = xe tac in (inc_pt_global_state (); the_tactic_flag := true; (* So that special info gets displayed *) result);; let xr n = let result = xr n in (inc_pt_global_state (); result);; let xset_goal (asl,w) = let result = xset_goal (asl,w) in (inc_pt_global_state (); result);; let xg t = let fvs = sort (<) (map (fst o dest_var) (frees t)) in (if fvs <> [] then let errmsg = end_itlist (fun s t -> s^", "^t) fvs in warn true ("Free variables in goal: "^errmsg) else ()); xset_goal([],t);; let xb () = let result = xb () in (inc_pt_global_state (); result);; (* ------------------------------------------------------------------------- *) (* Special Prooftree printers for xgoals and xgoalstacks. *) (* ------------------------------------------------------------------------- *) let the_new_goal_ids = ref ([] : goalid list);; let print_prooftree_xgoal ((g,id) : xgoal) : unit = ((if (!pg_mode) then (print_string ("[Goal ID " ^ string_of_goal_id id ^ "]"); print_newline ())); print_goal g);; let (print_prooftree_xgoalstack:xgoalstack->unit) = let print_prooftree_xgoalstate k gs = let (_,gl,_) = gs in let n = length gl in let s = if n = 0 then "No subgoals" else (string_of_int k)^" subgoal"^(if k > 1 then "s" else "") ^" ("^(string_of_int n)^" total)" in print_string s; print_newline(); if gl = [] then () else (do_list (print_prooftree_xgoal o C el gl) (rev(1--(k-1))); (if (!pg_mode) then print_string "[*]"); print_prooftree_xgoal (el 0 gl)) in fun l -> ((if (!pg_mode) & (!the_tactic_flag) then let xs = map string_of_int (!the_new_goal_ids) in (the_tactic_flag := false; print_string "[New Goal IDs: "; print_string_seplist " " xs; print_string "]"; print_newline ())); (if l = [] then print_string "Empty goalstack" else if tl l = [] then let (_,gl,_ as gs) = hd l in print_prooftree_xgoalstate 1 gs else let (_,gl,_ as gs) = hd l and (_,gl0,_) = hd(tl l) in let p = length gl - length gl0 in let p' = if p < 1 then 1 else p + 1 in print_prooftree_xgoalstate p' gs); (if (!pg_mode) then let (vs,theta) = if (l = []) then ([],[]) else let ((vs,(_,theta,_)),_,_) = hd l in (vs,theta) in let foo v = let (x,_) = dest_var v in x ^ if (can (rev_assoc v) theta) then " using" else " open" in let xs = map foo vs in (print_newline(); print_string "(dependent evars: "; print_string_seplist ", " xs; print_string ")"; print_newline ())));; (* ------------------------------------------------------------------------- *) (* Adjust the OCaml prompt to carry information for Prooftree. *) (* ------------------------------------------------------------------------- *) let original_prompt_fn = !Toploop.read_interactive_input in Toploop.read_interactive_input := fun prompt buffer len -> let basic_prompt = "<" in (* 'prompt' arg is ignored *) let prompt' = if (!pg_mode) then let pst = pt_proof_state () and gst = pt_global_state () in " " ^ basic_prompt ^ " " ^ string_of_int gst ^ " || " ^ string_of_int pst ^ " " ^ basic_prompt ^ " " else prompt in original_prompt_fn prompt' buffer len;; (* ------------------------------------------------------------------------- *) (* Printing the goal of a given Prooftree goal id. *) (* ------------------------------------------------------------------------- *) let xgoal_of_id (id:goalid) : xgoal = let gsts = !current_xgoalstack in let find_goal (_,xgs,_) = find (fun (g,id0) -> id0 = id) xgs in let xg = tryfind find_goal gsts in xg;; (* ------------------------------------------------------------------------- *) (* Install the new goal-related printers. *) (* ------------------------------------------------------------------------- *) #install_printer print_prooftree_xgoal;; #install_printer print_prooftree_xgoalstack;; proofgeneral-4.3~pre130510/hol-light/TacticRecording/tacticrec.ml000066400000000000000000000307001214562307500246550ustar00rootroot00000000000000(* ========================================================================== *) (* TACTIC RECORDING (HOL LIGHT) *) (* - Mechanism to record tactic proofs at the user level *) (* *) (* By Mark Adams *) (* Copyright (c) Univeristy of Edinburgh, 2011-2012 *) (* ========================================================================== *) (* This file implements a mechanism for recording tactic proofs at the level *) (* of interactive proof steps. A recorded proof takes the form of a tree of *) (* goals, and is capable of capturing both complete and incomplete proofs, as *) (* well as hierarchy correspoding to tacticals. *) (* The crucial mechanism by which goals in the subgoal package state are *) (* linked to parts of the stored goal tree is based on unique goal id *) (* numbers. Each goal in the subgoal package state is annotated with such an *) (* id, and this is also stored at each level of the goal tree. As a tactic *) (* is executed, the id from the goal in the subgoal package state that it *) (* executes on is used to locate the corresponding part of the goal tree, and *) (* the ids of the resulting subgoals are used to label the corresponding *) (* subparts of the goal tree. *) open Dltree;; (* ** MODES ** *) (* Store goal sequent flag *) (* Intermediate goal results are only stored if this flag is set. This can *) (* be used to cut down on memory usage. *) let store_goalsequent_flag = ref true;; (* ** GOAL TREE DATATYPES & STATE ** *) (* Goal tree datatype *) (* This is the datatype for recording tactic proofs as a tree of goals, with *) (* structure corresponding to interactive proof steps. The structural aspect *) (* is captured by 'gtree0': *) (* Gactive - Leaf for an active goal in the proof; *) (* Gexecuted - Node for a goal that has had a tactic successfully executed *) (* on it. Carries a list of subtrees, one for each of the *) (* resulting subgoals, where the list is empty for a tactic that *) (* completes its goal; *) (* Gexit - Wiring exiting a box, indicating destination goal. *) type ginfo = (goalid * goalid) (* Goal id & Parent id *) * string option (* Goal name (optional) *) * goal option (* Goal sequent (optional) *) * unit option ref;; (* Formal proof (optional) *) type gstep = Gatom of mldata (* Atomic tactic *) | Gbox of (label * gtree * bool) (* Box for a tactical; flag for special *) and gtree0 = Gactive (* Active goal *) | Gexecuted of (gstep * (* Tactic structure *) (* Executed tactic *) gtree list) (* Resulting subgoals *) | Gexit of goalid (* Exit the box *) and gtree = ginfo (* Various info about goal *) * gtree0 ref;; (* Goal plumbing *) (* Example *) (* Figure 1(b) in Denny et al would be represented by the following: *) (* *) (* (_, ref *) (* Gexecuted *) (* (Gbox (Tactical ("T1",[]) *) (* (_, ref *) (* Gexecuted *) (* (Gatom ("T2",[]), *) (* [ (_, ref Gexecuted (Gatom ("WF",[]), [])); *) (* (_, ref Gexit _) ])), *) (* [ (_, ref *) (* Gexecuted *) (* (Gbox (Tactical ("DP",[])) *) (* (_, ref *) (* Gexecuted *) (* (Gatom ("Normalise",[]), *) (* [ (_, ref Gexecuted (Gatom ("Taut",[]), [])) ])), *) (* [])) ])) *) (* Destructors *) let ginfo_id (((id,_),_,_,_):ginfo) : goalid = id;; let ginfo_pid (((_,pid),_,_,_):ginfo) : goalid = pid;; let ginfo_name ((_,x_,_,_):ginfo) : string = match x_ with Some x -> x | None -> failwith "Goal not named";; let ginfo_sqt ((_,_,sqt_,_):ginfo) : goal = match sqt_ with Some sqt -> sqt | None -> failwith "Goal sequent not stored";; let ginfo_fproof ((_,_,_,prf_):ginfo) : unit = match !prf_ with Some prf -> prf | None -> failwith "Goal's formal proof not stored";; let gtree_id ((info,_):gtree) = ginfo_id info;; let gtree_pid ((info,_):gtree) = ginfo_pid info;; let gtree_name ((info,_):gtree) = ginfo_name info;; let gtree_sqt ((info,_):gtree) = ginfo_sqt info;; let gtree_fproof ((info,_):gtree) = ginfo_fproof info;; let gstep_tactic (gstp:gstep) = match gstp with Gatom obj | Gbox (Tactical obj, _, true) -> obj | Gbox _ -> failwith "gstep_tactic: Not an atomic tactic";; let gtree_proof ((_,gtrm):gtree) = match (!gtrm) with Gexecuted (gstp,_) -> gstp | _ -> failwith "gtree_proof: Not executed";; let gtree_tactic gtr = (gstep_tactic o gtree_proof) gtr;; let gtree_tactic1 ((_,gtrm) as gtr :gtree) = match !gtrm with Gactive -> active_info | _ -> gtree_tactic gtr;; (* Tests *) let is_active_gtree ((_,gtrm):gtree) = match !gtrm with Gactive -> true | _ -> false;; (* Dummy values *) let dummy_goal_info : ginfo = ((0,0), None, None, ref None);; let dummy_goal_tree : gtree = (dummy_goal_info, ref Gactive);; (* Goal tree database *) let the_goal_tree = ref dummy_goal_tree;; (* Location database *) (* This database is maintained in parallel with the goal tree, to enable fast *) (* location of the subtree corresponding to a goal (as opposed to laboriously *) (* traversing the tree to find the branch with the right id). *) let the_gtree_locations = (dltree_empty () : (goalid, gtree ref) dltree);; let get_gtree id = !(dltree_lookup id the_gtree_locations);; let deregister_gtree gtr = (dltree_remove (gtree_id gtr) the_gtree_locations);; let register_gtree gtr = (dltree_insert (gtree_id gtr, ref gtr) the_gtree_locations);; (* Initialisation of the goal tree state *) let init_goal_tree g = let g_ = if (!store_goalsequent_flag) then Some g else None in let ginfo = ((!the_goal_id_counter,0), None, g_, ref None) in let gtr = (ginfo, ref Gactive) in (the_goal_tree := gtr; dltree_reempty the_gtree_locations; register_gtree gtr);; (* ** GTREE UTILITIES ** *) (* All children *) let rec gtree_all_children gtr = let (_,gtrm) = gtr in match (!gtrm) with Gexecuted (gstp,gtrs) -> (gstep_all_children gstp) @ gtrs @ flat (map gtree_all_children gtrs) | _ -> [] and gstep_all_children gstp = match gstp with Gatom _ | Gbox (_,_,true) -> [] | Gbox (_,gtr,false) -> gtr::(gtree_all_children gtr);; (* ** PLUMBING ** *) (* These utilities do the plumbing for tactic applications and tactical *) (* applications, promoting operations from goals to xgoals and incorporating *) (* the results into gtrees. *) (* Creating a sub gtree *) (* This creates a new xgoal for a goal, giving it a fresh id and registering *) (* it in the locations database. Used on all new subgoals. *) let new_active_subgtree pid (g:goal) : goalid * gtree = let id = (inc_goal_id_counter (); !the_goal_id_counter) in let g_ = if (!store_goalsequent_flag) then Some g else None in let info = ((id,pid), None, g_, ref None) in let gtr = (info, ref Gactive) in (register_gtree gtr; (id,gtr));; (* Extension *) (* This extends a gtree with the subgoals resulting from applying a tactic. *) let extend_gtree (pid:goalid) (gstp:gstep) (gs':goal list) : xgoal list = let gtr = get_gtree pid in let (_,gtrm) = gtr in let () = try assert (!gtrm = Gactive) with Assert_failure _ -> failwith "extend_gtree: Internal error - Not active" in let (ids',gtrs) = unzip (map (new_active_subgtree pid) gs') in let xgs' = zip gs' ids' in (gtrm := Gexecuted (gstp,gtrs); xgs');; (* Deletion *) (* This deletes from a gtree the result of applying a tactic to a given goal, *) (* also deleting the resulting subgoals from the locations database. *) let delete_step (id:goalid) = let gtr = get_gtree id in let (_,gtrm) = gtr in let () = match (!gtrm) with Gexecuted _ -> () | _ -> failwith "delete_step: Internal error - Not executed" in let gtrs = gtree_all_children gtr in (gtrm := Gactive; do_list deregister_gtree gtrs);; (* Externalising *) (* This is used for turning a box's active subgoal to exit wiring. *) let externalise_gtree ((id0,id):goalid*goalid) : unit = let (_,gtrm) = get_gtree id0 in match (!gtrm) with Gactive -> (gtrm := Gexit id) | _ -> failwith "externalise_gtree: Internal error - Not active";; (* ** SUBGOAL PACKAGE OPERATIONS FOR XGOALS ** *) (* A few of the xtactic subgoal package commands are adjusted here. *) (* Starting/finishing a tactic proof *) (* For commands that start a tactic proof, 'mk_xgoalstate' is adjusted to *) (* initialise the goal tree. Commands that return a tactic proof's resulting *) (* theorem, the theorem is adjusted to be an 'xthm' that carries a reference *) (* to the goal tree. *) let mk_xgoalstate (g:goal) : xgoalstate = let result = mk_xgoalstate g in (init_goal_tree g; result);; let (xTAC_PROOF : goal * xtactic -> thm) = fun (g,tac) -> let gstate = mk_xgoalstate g in let _,sgs,just = xby tac gstate in if sgs = [] then just null_inst [] else failwith "TAC_PROOF: Unsolved goals";; let xprove(t,tac) = let th = xTAC_PROOF(([],t),tac) in let t' = concl th in let th' = if t' = t then th else try EQ_MP (ALPHA t' t) th with Failure _ -> failwith "prove: justification generated wrong theorem" in mk_xthm (th', ("",[])) let xset_goal(asl,w) = current_xgoalstack := [mk_xgoalstate(map (fun t -> "",ASSUME t) asl,w)]; !current_xgoalstack;; let xg t = let fvs = sort (<) (map (fst o dest_var) (frees t)) in (if fvs <> [] then let errmsg = end_itlist (fun s t -> s^", "^t) fvs in warn true ("Free variables in goal: "^errmsg) else ()); xset_goal([],t);; (* Undoing a tactic proof step *) (* 'xb' needs to be adjusted to delete the undone step in the goal tree. *) let xb () = let result = xb () in let (_,xgs,_) = hd result in let (_,id) = hd xgs in (delete_step id; result);; (* ** GTREE OPERATIONS ** *) (* Goal id graph *) let rec gtree_graph0 gtr graph0 = let (info,gtrm) = gtr in let ((id,pid),_,g_,_) = info in match !gtrm with Gactive -> (pid,id)::graph0 | Gexit id -> failwith "???" | Gexecuted (_,gtrs) -> (pid,id)::(foldr gtree_graph0 gtrs graph0);; let gtree_graph () = let nns = gtree_graph0 (!the_goal_tree) [] in tl nns;; (* remove (0,0) at head of dumped list *) (* Goal id trace *) let rec gtree_id_trace gtr = let (_,gtrm) = gtr in match !gtrm with Gactive -> [gtree_id gtr] | Gexit id -> let gtr1 = get_gtree id in gtree_id_trace gtr1 | Gexecuted (gstp,gtrs1) -> (match gstp with Gatom _ | Gbox (_,_,true) -> (gtree_id gtr) :: flat (map gtree_id_trace gtrs1) | Gbox (_,gtr1,false) -> gtree_id_trace gtr1);; (* Tactic trace *) let rec gtree_tactic_trace gtr = map (gtree_tactic1 o get_gtree) (gtree_id_trace gtr);; proofgeneral-4.3~pre130510/hol-light/TacticRecording/wrappers.ml000066400000000000000000000315661214562307500245720ustar00rootroot00000000000000(* ========================================================================== *) (* WRAPPER FUNCTIONS (HOL LIGHT) *) (* - Functions for promoting thm/goal-related ML objects for xthm/xgoal *) (* *) (* By Mark Adams *) (* Copyright (c) Univeristy of Edinburgh, 2011-2012 *) (* ========================================================================== *) (* ** THEOREM-RELATED WRAPPER FUNCTIONS ** *) (* mldata_as_meta_arg *) let mldata_as_meta_arg (obj:mldata) = match obj with (x, ((_::_) as args)) -> Mlfn (x, front args) | _ -> failwith "mldata_as_meta_arg: Unexpected empty rule arg list";; let mldata_as_meta2_arg (obj:mldata) = match obj with (x, ((_::_) as args)) -> Mlfn (x, (front o front) args) | _ -> failwith "mldata_as_meta_arg: Unexpected empty rule arg list";; (* detect_rule_app *) (* Based on the assumption that the given meta function actually executes its *) (* rule argument at some point, this utility detects such an execution during *) (* the demotion of a given xrule argument to a rule. The meta function's *) (* result is returned along with an 'farg' that captures the rule. *) let detect_rule_app (mfunc:('a->thm)->'b) (xr:'a->xthm) : 'c = let temp = ref (Mlfn ("", []) : mlarg) in let r arg = let xth = xr arg in let (th,obj) = dest_xthm xth in (temp := mldata_as_meta_arg obj; th) in let th = mfunc r in (th,!temp);; let detect_metarule_app (mfunc:(('a->thm)->'b->thm)->'c) (xmr:('a->xthm)->'b->xthm) : 'd = let temp = ref (Mlfn ("",[]) : mlarg) in let mr marg arg = let xmarg arg0 = let th = marg arg0 in let obj = ("", [Mlfn ("",[])]) in mk_xthm (th,obj) in let xth = xmr xmarg arg in let (th,obj) = dest_xthm xth in (temp := mldata_as_meta2_arg obj; th) in let th = mfunc mr in (th,!temp);; (* Theorem wrapper *) let theorem_wrap (x:string) (th:thm) : xthm = (th, (x,[]));; (* Rule wrappers *) (* Lots of rule wrappers are required because there are many different type *) (* shapes for rules. *) let rule_wrap0 obj (r:'a->thm) (arg:'a) : xthm = let th' = r arg in mk_xthm (th',obj);; let conv_wrap x (r:term->thm) (tm:term) : xthm = rule_wrap0 (x, [Mlterm tm]) r tm;; let thm_conv_wrap x (r:thm->term->thm) (xth:xthm) tm : xthm = let (th,prf) = dest_xthm xth in rule_wrap0 (x, [Mlthm prf; Mlterm tm]) (r th) tm;; let thmlist_conv_wrap x (r:thm list->term->thm) xths (tm:term) : xthm = let (ths,prfs) = unzip (map dest_xthm xths) in rule_wrap0 (x, [Mllist (map (fun prf -> Mlthm prf) prfs); Mlterm tm]) (r ths) tm;; let rule_wrap x (r:thm->thm) (xth:xthm) : xthm = let (th,prf) = dest_xthm xth in rule_wrap0 (x, [Mlthm prf]) r th;; let drule_wrap x (r:thm->thm->thm) (xth1:xthm) (xth2:xthm) : xthm = let (th1,prf1) = dest_xthm xth1 in let (th2,prf2) = dest_xthm xth2 in rule_wrap0 (x, [Mlthm prf1; Mlthm prf2]) (r th1) th2;; let prule_wrap x (r:thm*thm->thm) ((xth1:xthm),(xth2:xthm)) : xthm = let (th1,prf1) = dest_xthm xth1 in let (th2,prf2) = dest_xthm xth2 in rule_wrap0 (x, [Mlpair(Mlthm prf1, Mlthm prf2)]) r (th1,th2);; let trule_wrap x (r:thm->thm->thm->thm) (xth1:xthm) (xth2:xthm) (xth3:xthm) : xthm = let (th1,prf1) = dest_xthm xth1 in let (th2,prf2) = dest_xthm xth2 in let (th3,prf3) = dest_xthm xth3 in rule_wrap0 (x, [Mlthm prf1; Mlthm prf2; Mlthm prf3]) (r th1 th2) th3;; let term_rule_wrap x (r:term->thm->thm) tm (xth:xthm) : xthm = let (th,prf) = dest_xthm xth in rule_wrap0 (x, [Mlterm tm; Mlthm prf]) (r tm) th;; let termpair_rule_wrap x (r:term*term->thm->thm) (tm1,tm2) (xth:xthm) : xthm = let (th,prf) = dest_xthm xth in rule_wrap0 (x, [Mlpair(Mlterm tm1,Mlterm tm2); Mlthm prf]) (r (tm1,tm2)) th;; let termthmpair_rule_wrap x (r:term*thm->thm->thm) (tm,xth0) (xth:xthm) : xthm = let (th0,prf0) = dest_xthm xth0 in let (th,prf) = dest_xthm xth in rule_wrap0 (x, [Mlpair(Mlterm tm, Mlthm prf0); Mlthm prf]) (r (tm,th0)) th;; let termlist_rule_wrap x (r:term list->thm->thm) tms (xth:xthm) : xthm = let (th,prf) = dest_xthm xth in rule_wrap0 (x, [Mllist (map (fun tm -> Mlterm tm) tms); Mlthm prf]) (r tms) th;; let terminst_rule_wrap x (r:(term*term)list->thm->thm) theta (xth:xthm) : xthm = let (th,prf) = dest_xthm xth in rule_wrap0 (x, [Mllist (map (fun (tm1,tm2) -> Mlpair(Mlterm tm1, Mlterm tm2)) theta); Mlthm prf]) (r theta) th;; let typeinst_rule_wrap x (r:(hol_type*hol_type)list->thm->thm) theta (xth:xthm) : xthm = let (th,prf) = dest_xthm xth in rule_wrap0 (x, [Mllist (map (fun (tm1,tm2) -> Mlpair(Mltype tm1, Mltype tm2)) theta); Mlthm prf]) (r theta) th;; let thmlist_rule_wrap x (r:thm list->thm->thm) xths (xth:xthm) : xthm = let (ths,prfs) = unzip (map dest_xthm xths) in let (th,prf) = dest_xthm xth in rule_wrap0 (x, [Mllist (map (fun prf -> Mlthm prf) prfs); Mlthm prf]) (r ths) th;; (* Multi-rule wrappers *) let multirule_wrap0 obj (r:'a->thm list) (arg:'a) : xthm list = let ths' = r arg in let n = length ths' in let infos' = map (fun i -> ("el", [Mlint i; Mlfn obj])) (0 -- (n-1)) in map mk_xthm (zip ths' infos');; let multirule_wrap x (r:thm->thm list) (xth:xthm) : xthm list = let (th,prf) = dest_xthm xth in multirule_wrap0 (x, [Mlthm prf]) r th;; (* Meta rule wrappers *) let meta_rule_wrap0 info0 (mr:('a->thm)->'b->thm) (xr:'a->xthm) (arg:'b) : xthm = let (th',f) = detect_rule_app (fun r -> mr r arg) xr in let (x,args0) = info0 in let obj' = (x, f::args0) in (th',obj');; let conv_conv_wrap x (mc:conv->conv) (xc:term->xthm) (tm:term) : xthm = meta_rule_wrap0 (x, [Mlterm tm]) mc xc tm;; (* ** TACTIC-RELATED WRAPPER FUNCTIONS ** *) (* These functions are for promoting existing tactics and tacticals. *) (* Generic basic wrapper util *) (* Applies a tactic and incorproates the results into the goal tree. Takes *) (* an "infotactic", i.e. like a normal tactic that works on 'goal' and *) (* returns 'goalstate', but that also returns a 'gstep' summary of the *) (* operation. This is used to promote every basic tactic-based function. *) let infotactic_wrap (infotac:goal->goalstate*mldata) (xg:xgoal) : xgoalstate = let (g,id) = dest_xgoal xg in let ((meta,gs,just),obj) = infotac g in let xgs = extend_gtree id (Gatom obj) gs in (meta,xgs,just);; (* Generic box wrapper util *) (* Sets up a box to apply an xtactic within, applies the xtactic (which *) (* incorporates itself into the goal tree) and wires up the resulting *) (* subgoals to external subgoals of the box. Note that this is not quite *) (* generic enough for 'SUBGOAL_THEN' (because there is not a total surjection *) (* between internal and external goals). *) let infobox_wrap (xinfotac:xgoal->xgoalstate*label) (xg:xgoal) : xgoalstate = let (g,id) = dest_xgoal xg in let (id0,gtr0) = new_active_subgtree id g in let xg0 = mk_xgoal (g,id0) in let ((meta,xgs0,just),l) = xinfotac xg0 in let (gs0,ids0) = unzip (map dest_xgoal xgs0) in let xgs = extend_gtree id (Gbox (l,gtr0,false)) gs0 in let ids = map xgoal_id xgs in (do_list externalise_gtree (zip ids0 ids); (meta,xgs,just));; (* Tactic wrapper *) (* This is for wrapping around a tactic, to promote it to work on xgoals and *) (* incorporate the results into an existing gtree. *) let tactic_wrap0 obj (tac:tactic) : xtactic = let infotac g = (tac g, obj) in infotactic_wrap infotac;; let tactic_wrap x tac = tactic_wrap0 (x, []) tac;; let string_tactic_wrap x (tac:string->tactic) (s:string) : xtactic = tactic_wrap0 (x, [Mlstring s]) (tac s);; let term_tactic_wrap x (tac:term->tactic) (tm:term) : xtactic = tactic_wrap0 (x, [Mlterm tm]) (tac tm);; let termpair_tactic_wrap x (tac:term*term->tactic) (tm1,tm2) : xtactic = tactic_wrap0 (x, [Mlpair (Mlterm tm1, Mlterm tm2)]) (tac (tm1,tm2));; let termlist_tactic_wrap x (tac:term list->tactic) tms : xtactic = tactic_wrap0 (x, [Mllist (map (fun tm -> Mlterm tm) tms)]) (tac tms);; let thm_tactic_wrap x (tac:thm->tactic) (xth:xthm) : xtactic = let (th,prf) = dest_xthm xth in tactic_wrap0 (x, [Mlthm prf]) (tac th);; let thmlist_tactic_wrap x (tac:thm list->tactic) (xths:xthm list) : xtactic = let (ths,prfs) = unzip (map dest_xthm xths) in tactic_wrap0 (x, [Mllist (map (fun prf -> Mlthm prf) prfs)]) (tac ths);; let stringthm_tactic_wrap x (tac:string->thm->tactic) s (xth:xthm) : xtactic = let (th,prf) = dest_xthm xth in tactic_wrap0 (x, [Mlstring s; Mlthm prf]) (tac s th);; (* Meta-tactic wrapper *) (* For tactics that take rule arguments. *) let meta_tactic_wrap0 info0 (mtac:('a->thm)->tactic) (xr:'a->xthm) : xtactic = let infotac g = let (gst,f) = detect_rule_app (fun r -> mtac r g) xr in let (x,args0) = info0 in let obj = (x, f::args0) in (gst,obj) in infotactic_wrap infotac;; let conv_tactic_wrap x (mtac:conv->tactic) (xc:xconv) : xtactic = meta_tactic_wrap0 (x, []) mtac xc;; let metameta_tactic_wrap info0 (mmtac:(('a->thm)->'b->thm)->tactic) (xmr:('a->xthm)->'b->xthm) : xtactic = let infotac g = let (gst,f) = detect_metarule_app (fun mr -> mmtac mr g) xmr in let (x,args0) = info0 in let obj = (x, f::args0) in (gst,obj) in infotactic_wrap infotac;; let convconvthmlist_tactic_wrap x (mmtac:(conv->conv)->thm list->tactic) (xmc:xconv->xconv) (xths:xthm list) : xtactic = let (ths,prfs) = unzip (map dest_xthm xths) in metameta_tactic_wrap (x, [Mllist (map (fun prf -> Mlthm prf) prfs)]) (fun mc -> mmtac mc ths) xmc;; (* Tactical wrapper *) (* This is for wrapping around a tactical, to incorporate the results into a *) (* box in an existing gtree, where the execution of the tactical's tactics is *) (* captured inside the box, so that they can be stepped through and/or *) (* refactored. Thus we cannot take the tactical as a black box; it must *) (* already be promoted to work with xtactics and xgoals. This must done by *) (* hand for each tactical by trivially adjusting its original source code. *) let tactical_wrap0 obj (xttcl:'a->xtactic) (arg:'a) : xtactic = let xinfotac xg = (xttcl arg xg, Tactical obj) in infobox_wrap xinfotac;; let tactical_wrap x (xttcl:'a->xtactic) (xtac:'a) : xtactic = tactical_wrap0 (x,[]) xttcl xtac;; let btactical_wrap x (xttcl:'a->'b->xtactic) (xtac1:'a) (xtac2:'b) : xtactic = tactical_wrap0 (x,[]) (xttcl xtac1) xtac2;; let int_tactical_wrap x (xttcl:int->'a->xtactic) (n:int) (xtac:'a) : xtactic = tactical_wrap0 (x, [Mlint n]) (xttcl n) xtac;; let list_tactical_wrap x (xttcl:('a->xtactic)->'a list->xtactic) (xtac:'a->xtactic) (l:'a list) : xtactic = tactical_wrap0 (x,[]) (xttcl xtac) l;; (* HILABEL *) (* Command for putting the result of a tactic into a box and giving the box a *) (* label (distinct from a tactical label). *) let HILABEL x (xtac:xtactic) : xtactic = let xinfotac xg = (xtac xg, Label x) in infobox_wrap xinfotac;; (* xSUBGOAL_THEN - seems to be a special case *) let xASSUME = conv_wrap "ASSUME" ASSUME;; let xSUBGOAL_THEN (tm:term) (ttac:xthm_tactic) (xg:xgoal) : xgoalstate = let arg = xASSUME tm in let (g,id) = dest_xgoal xg in let (id0,gtr0) = new_active_subgtree id g in let xg0 = mk_xgoal (g,id0) in let (meta,xgs0,just) = ttac arg xg0 in let (asl,_) = g in let g2 = (asl,tm) in let obj = ("SUBGOAL_THEN", [Mlterm tm; (mldata_as_meta_arg o gtree_tactic) gtr0]) in let (gs0,ids0) = unzip (map dest_xgoal xgs0) in let xgs = extend_gtree id (Gbox (Tactical obj, gtr0, true)) (g2::gs0) in let ids1 = map xgoal_id (tl xgs) in let just' = fun i l -> PROVE_HYP (hd l) (just i (tl l)) in (do_list externalise_gtree (zip ids0 ids1); (meta,xgs,just'));; (* let SUBGOAL_TAC s tm prfs = match prfs with p::ps -> (warn (ps <> []) "SUBGOAL_TAC: additional subproofs ignored"; SUBGOAL_THEN tm (LABEL_TAC s) THENL [p; ALL_TAC]) | [] -> failwith "SUBGOAL_TAC: no subproof given";; let (FREEZE_THEN :thm_tactical) = fun ttac th (asl,w) -> let meta,gl,just = ttac (ASSUME(concl th)) (asl,w) in meta,gl,fun i l -> PROVE_HYP th (just i l);; *) proofgeneral-4.3~pre130510/hol-light/TacticRecording/xtactics.ml000066400000000000000000000426101214562307500245410ustar00rootroot00000000000000(* ========================================================================= *) (* HOL Light subgoal package amended for id-carrying goals. *) (* *) (* Mark Adams, School of Informatics, University of Edinburgh *) (* *) (* (c) Copyright, University of Edinburgh, 2012 *) (* ========================================================================= *) (* The 'xgoal' variant of the 'goal' datatype is defined here, to label *) (* goals with a unique goal id. This gives a basis for recording tactic *) (* proofs. Variants of all the datatypes depending on 'goal', such as *) (* 'xgoalstate' and 'xtactic', are also defined, along with a variant *) (* subgoal package. ML names are given an "x" prefix to keep them distinct *) (* from the originals for now (but originals are overwritten later, in *) (* 'install.ml'). *) (* The goal id counter is only adjusted in this file by being incremented in *) (* 'mk_xgoalstate', used when starting a new subgoal package proof. *) (* Xtactics are assumed to give their resulting xgoals id labels based on an *) (* appropriately updated goal id counter. *) (* After the implementation of xgoals themselves at the start of this file, *) (* the rest of the file is more-or-less copied verbatim from HOL Light's *) (* original 'tactics.ml', with just a few changes required. This enables an *) (* easy diff operation with the original if required to check that the *) (* changes are valid. *) (* ------------------------------------------------------------------------- *) (* Goal counter for providing goal ids. *) (* ------------------------------------------------------------------------- *) type goalid = int;; let string_of_goal_id (id:goalid) = string_of_int id;; let the_goal_id_counter = ref (0 : goalid);; let inc_goal_id_counter () = (the_goal_id_counter := !the_goal_id_counter + 1);; (* ------------------------------------------------------------------------- *) (* An xgoal extends a goal with an identity. *) (* ------------------------------------------------------------------------- *) type xgoal = goal * goalid;; let equals_xgoal (((a,w),_):xgoal) (((a',w'),_):xgoal) = forall2 (fun (s,th) (s',th') -> s = s' & equals_thm th th') a a' & w = w';; let mk_xgoal (gn:goal*goalid) : xgoal = gn;; let dest_xgoal (gn:xgoal) : goal*goalid = gn;; let xgoal_goal ((g,id):xgoal) : goal = g;; let xgoal_id ((g,id):xgoal) : goalid = id;; (* ------------------------------------------------------------------------- *) (* The xgoalstate is like goalstate but for xgoals instead of goals. *) (* ------------------------------------------------------------------------- *) type xgoalstate = (term list * instantiation) * xgoal list * justification;; (* ------------------------------------------------------------------------- *) (* A goalstack but for xgoals. *) (* ------------------------------------------------------------------------- *) type xgoalstack = xgoalstate list;; (* ------------------------------------------------------------------------- *) (* Refinements for xgoals. *) (* ------------------------------------------------------------------------- *) type xrefinement = xgoalstate -> xgoalstate;; (* ------------------------------------------------------------------------- *) (* Tactics for xgoals. *) (* ------------------------------------------------------------------------- *) type xtactic = xgoal -> xgoalstate;; type xthm_tactic = xthm -> xtactic;; type xthm_tactical = xthm_tactic -> xthm_tactic;; (* ------------------------------------------------------------------------- *) (* Instantiation of xgoals. *) (* ------------------------------------------------------------------------- *) let (inst_xgoal:instantiation->xgoal->xgoal) = fun p ((thms,w),id) -> (map (I F_F INSTANTIATE_ALL p) thms,instantiate p w),id;; (* ------------------------------------------------------------------------- *) (* Validity check for xtactics. *) (* ------------------------------------------------------------------------- *) let (xVALID:xtactic->xtactic) = let fake_thm ((asl,w),id) = let asms = itlist (union o hyp o snd) asl [] in mk_fthm(asms,w) and false_tm = `_FALSITY_` in fun tac ((asl,w),id) -> let ((mvs,i),gls,just as res) = tac ((asl,w),id) in let ths = map fake_thm gls in let asl',w' = dest_thm(just null_inst ths) in let asl'',w'' = inst_goal i (asl,w) in let maxasms = itlist (fun (_,th) -> union (insert (concl th) (hyp th))) asl'' [] in if aconv w' w'' & forall (C mem maxasms) (subtract asl' [false_tm]) then res else failwith "VALID: Invalid tactic";; (* ------------------------------------------------------------------------- *) (* Various simple combinators for tactics, identity tactic etc. *) (* ------------------------------------------------------------------------- *) let (xTHEN),(xTHENL) = let propagate_empty i [] = [] and propagate_thm th i [] = INSTANTIATE_ALL i th in let compose_justs n just1 just2 i ths = let ths1,ths2 = chop_list n ths in (just1 i ths1)::(just2 i ths2) in let rec seqapply l1 l2 = match (l1,l2) with ([],[]) -> null_meta,[],propagate_empty | ((tac:xtactic)::tacs),((goal:xgoal)::goals) -> let ((mvs1,insts1),gls1,just1 as gstate1) = tac goal in let goals' = map (inst_xgoal insts1) goals in let ((mvs2,insts2),gls2,just2 as gstate2) = seqapply tacs goals' in ((union mvs1 mvs2,compose_insts insts1 insts2), gls1@gls2,compose_justs (length gls1) just1 just2) | _,_ -> failwith "seqapply: Length mismatch" in let justsequence just1 just2 insts2 i ths = just1 (compose_insts insts2 i) (just2 i ths) in let tacsequence ((mvs1,insts1),gls1,just1 as gstate1) tacl = let ((mvs2,insts2),gls2,just2 as gstate2) = seqapply tacl gls1 in let jst = justsequence just1 just2 insts2 in let just = if gls2 = [] then propagate_thm (jst null_inst []) else jst in ((union mvs1 mvs2,compose_insts insts1 insts2),gls2,just) in let (then_: xtactic -> xtactic -> xtactic) = fun tac1 tac2 g -> let _,gls,_ as gstate = tac1 g in tacsequence gstate (replicate tac2 (length gls)) and (thenl_: xtactic -> xtactic list -> xtactic) = fun tac1 tac2l g -> let _,gls,_ as gstate = tac1 g in if gls = [] then tacsequence gstate [] else tacsequence gstate tac2l in then_,thenl_;; let ((xORELSE): xtactic -> xtactic -> xtactic) = fun tac1 tac2 g -> try tac1 g with Failure _ -> tac2 g;; let (xFAIL_TAC: string -> xtactic) = fun tok g -> failwith tok;; let (xALL_TAC:xtactic) = fun g -> null_meta,[g],fun _ [th] -> th;; let xTRY tac = xORELSE tac xALL_TAC;; let rec xREPEAT tac g = (xORELSE (xTHEN tac (xREPEAT tac)) xALL_TAC) g;; let xEVERY tacl = itlist (fun t1 t2 -> xTHEN t1 t2) tacl xALL_TAC;; let (xFIRST: xtactic list -> xtactic) = fun tacl g -> end_itlist (fun t1 t2 -> xORELSE t1 t2) tacl g;; let xMAP_EVERY tacf lst = xEVERY (map tacf lst);; let xMAP_FIRST tacf lst = xFIRST (map tacf lst);; let (xCHANGED_TAC: xtactic -> xtactic) = fun tac g -> let (meta,gl,_ as gstate) = tac g in if meta = null_meta & length gl = 1 & equals_xgoal (hd gl) g then failwith "CHANGED_TAC" else gstate;; let rec xREPLICATE_TAC n tac = if n <= 0 then xALL_TAC else xTHEN tac (xREPLICATE_TAC (n - 1) tac);; (* ------------------------------------------------------------------------- *) (* Combinators for theorem continuations adjusted for xthms and xtactics. *) (* ------------------------------------------------------------------------- *) let ((xTHEN_TCL): xthm_tactical -> xthm_tactical -> xthm_tactical) = fun ttcl1 ttcl2 ttac -> ttcl1 (ttcl2 ttac);; let ((xORELSE_TCL): xthm_tactical -> xthm_tactical -> xthm_tactical) = fun ttcl1 ttcl2 ttac th -> try ttcl1 ttac th with Failure _ -> ttcl2 ttac th;; let rec xREPEAT_TCL ttcl ttac th = (xORELSE_TCL (xTHEN_TCL ttcl (xREPEAT_TCL ttcl)) I) ttac th;; let (xREPEAT_GTCL: xthm_tactical -> xthm_tactical) = let rec xREPEAT_GTCL ttcl ttac th g = try ttcl (xREPEAT_GTCL ttcl ttac) th g with Failure _ -> ttac th g in xREPEAT_GTCL;; let (xALL_THEN: xthm_tactical) = I;; let (xNO_THEN: xthm_tactical) = fun ttac th -> failwith "NO_THEN";; let xEVERY_TCL ttcll = itlist (fun t1 t2 -> xTHEN_TCL t1 t2) ttcll xALL_THEN;; let xFIRST_TCL ttcll = end_itlist (fun t1 t2 -> xORELSE_TCL t1 t2) ttcll;; (* ------------------------------------------------------------------------- *) (* Tactics to augment assumption list. Note that to allow "ASSUME p" for *) (* any assumption "p", these add a PROVE_HYP in the justification function, *) (* just in case. *) (* ------------------------------------------------------------------------- *) let (xLABEL_TAC: string -> xthm_tactic) = fun s thm ((asl,w),id) -> let thm' = xthm_thm thm in null_meta,[(((s,thm')::asl,w),id)], fun i [th] -> PROVE_HYP (INSTANTIATE_ALL i thm') th;; (* ------------------------------------------------------------------------- *) (* Manipulation of assumption list. *) (* ------------------------------------------------------------------------- *) let mk_asm_xthm th = mk_xthm0 "" th;; let (xFIND_ASSUM: xthm_tactic -> term -> xtactic) = fun ttac t (((asl,w),id) as g) -> ttac (mk_asm_xthm (snd(find (fun (_,th) -> concl th = t) asl))) g;; let (xPOP_ASSUM: xthm_tactic -> xtactic) = fun ttac -> function ((((_,th)::asl),w),id) -> ttac (mk_asm_xthm th) ((asl,w),id) | _ -> failwith "POP_ASSUM: No assumption to pop";; let (xASSUM_LIST: (xthm list -> xtactic) -> xtactic) = fun aslfun ((asl,w),id) -> aslfun (map (mk_asm_xthm o snd) asl) ((asl,w),id);; let (xPOP_ASSUM_LIST: (xthm list -> xtactic) -> xtactic) = fun asltac ((asl,w),id) -> asltac (map (mk_asm_xthm o snd) asl) (([],w),id);; let (xEVERY_ASSUM: xthm_tactic -> xtactic) = fun ttac -> xASSUM_LIST (xMAP_EVERY ttac);; let (xFIRST_ASSUM: xthm_tactic -> xtactic) = fun ttac (((asl,w),id) as g) -> tryfind (fun (_,th) -> ttac (mk_asm_xthm th) g) asl;; let (xRULE_ASSUM_TAC :(xthm->xthm)->xtactic) = fun rule ((asl,w),id) -> (xTHEN (xPOP_ASSUM_LIST(K xALL_TAC)) (xMAP_EVERY (fun (s,th) -> xLABEL_TAC s (rule (mk_asm_xthm th))) (rev asl))) ((asl,w),id);; (* ------------------------------------------------------------------------- *) (* Operate on assumption identified by a label. *) (* ------------------------------------------------------------------------- *) let (xUSE_THEN:string->xthm_tactic->xtactic) = fun s ttac (((asl,w),id) as gl) -> let th = try assoc s asl with Failure _ -> failwith("USE_TAC: didn't find assumption "^s) in ttac (mk_asm_xthm th) gl;; let (xREMOVE_THEN:string->xthm_tactic->xtactic) = fun s ttac ((asl,w),id) -> let th = try assoc s asl with Failure _ -> failwith("USE_TAC: didn't find assumption "^s) in let asl1,asl2 = chop_list(index s (map fst asl)) asl in let asl' = asl1 @ tl asl2 in ttac (mk_asm_xthm th) ((asl',w),id);; (* ------------------------------------------------------------------------- *) (* General tool to augment a required set of theorems with assumptions. *) (* ------------------------------------------------------------------------- *) let (xASM :(xthm list -> xtactic)->(xthm list -> xtactic)) = fun tltac ths (((asl,w),id) as g) -> tltac (map (mk_asm_xthm o snd) asl @ ths) g;; (* ------------------------------------------------------------------------- *) (* A printer for xgoals etc. *) (* ------------------------------------------------------------------------- *) let print_xgoal ((g,x):xgoal) : unit = print_goal g;; let (print_xgoalstack:xgoalstack->unit) = let print_xgoalstate k gs = let (_,gl,_) = gs in let n = length gl in let s = if n = 0 then "No subgoals" else (string_of_int k)^" subgoal"^(if k > 1 then "s" else "") ^" ("^(string_of_int n)^" total)" in print_string s; print_newline(); if gl = [] then () else do_list (print_xgoal o C el gl) (rev(0--(k-1))) in fun l -> if l = [] then print_string "Empty goalstack" else if tl l = [] then let (_,gl,_ as gs) = hd l in print_xgoalstate 1 gs else let (_,gl,_ as gs) = hd l and (_,gl0,_) = hd(tl l) in let p = length gl - length gl0 in let p' = if p < 1 then 1 else p + 1 in print_xgoalstate p' gs;; (* ------------------------------------------------------------------------- *) (* Convert an xtactic into an xrefinement. *) (* ------------------------------------------------------------------------- *) let (xby:xtactic->xrefinement) = fun tac ((mvs,inst),gls,just) -> let g = hd gls and ogls = tl gls in let ((newmvs,newinst),subgls,subjust) = tac g in let n = length subgls in let mvs' = union newmvs mvs and inst' = compose_insts inst newinst and gls' = subgls @ map (inst_xgoal newinst) ogls in let just' i ths = let i' = compose_insts inst' i in let cths,oths = chop_list n ths in let sths = (subjust i cths) :: oths in just i' sths in (mvs',inst'),gls',just';; (* ------------------------------------------------------------------------- *) (* Rotate for xgoalstate. *) (* ------------------------------------------------------------------------- *) let (xrotate:int->xrefinement) = let rotate_p (meta,sgs,just) = let sgs' = (tl sgs)@[hd sgs] in let just' i ths = let ths' = (last ths)::(butlast ths) in just i ths' in (meta,sgs',just') and rotate_n (meta,sgs,just) = let sgs' = (last sgs)::(butlast sgs) in let just' i ths = let ths' = (tl ths)@[hd ths] in just i ths' in (meta,sgs',just') in fun n -> if n > 0 then funpow n rotate_p else funpow (-n) rotate_n;; (* ------------------------------------------------------------------------- *) (* Refinement proof, tactic proof etc for xgoals/xtactics. *) (* ------------------------------------------------------------------------- *) let (mk_xgoalstate:goal->xgoalstate) = fun (asl,w) -> if type_of w = bool_ty then let id = (inc_goal_id_counter (); !the_goal_id_counter) in null_meta,[((asl,w),id)], (fun inst [th] -> INSTANTIATE_ALL inst th) else failwith "mk_goalstate: Non-boolean goal";; let (xTAC_PROOF : goal * xtactic -> thm) = fun (g,tac) -> let gstate = mk_xgoalstate g in let _,sgs,just = xby tac gstate in if sgs = [] then just null_inst [] else failwith "TAC_PROOF: Unsolved goals";; let xprove(t,tac) = let th = xTAC_PROOF(([],t),tac) in let t' = concl th in let th' = if t' = t then th else try EQ_MP (ALPHA t' t) th with Failure _ -> failwith "prove: justification generated wrong theorem" in mk_xthm (th', ("",[])) (* ------------------------------------------------------------------------- *) (* Subgoal package for xgoals. *) (* ------------------------------------------------------------------------- *) let current_xgoalstack = ref ([] :xgoalstack);; let (xrefine:xrefinement->xgoalstack) = fun r -> let l = !current_xgoalstack in let h = hd l in let res = r h :: l in current_xgoalstack := res; !current_xgoalstack;; let flush_xgoalstack() = let l = !current_xgoalstack in current_xgoalstack := [hd l];; let xe tac = xrefine(xby(xVALID tac));; let xr n = xrefine(xrotate n);; let xset_goal(asl,w) = current_xgoalstack := [mk_xgoalstate(map (fun t -> "",ASSUME t) asl,w)]; !current_xgoalstack;; let xg t = let fvs = sort (<) (map (fst o dest_var) (frees t)) in (if fvs <> [] then let errmsg = end_itlist (fun s t -> s^", "^t) fvs in warn true ("Free variables in goal: "^errmsg) else ()); xset_goal([],t);; let xb() = let l = !current_xgoalstack in if length l = 1 then failwith "Can't back up any more" else current_xgoalstack := tl l; !current_xgoalstack;; let xp() = !current_xgoalstack;; let xtop_realgoal() = let (_,(((asl,w),_)::_),_)::_ = !current_xgoalstack in asl,w;; let xtop_goal() = let asl,w = xtop_realgoal() in map (concl o snd) asl,w;; let xtop_thm() = let (_,[],f)::_ = !current_xgoalstack in mk_xthm (f null_inst [], ("",[]));; (* ------------------------------------------------------------------------- *) (* Install the goal-related printers. *) (* ------------------------------------------------------------------------- *) #install_printer print_xgoal;; #install_printer print_xgoalstack;; proofgeneral-4.3~pre130510/hol-light/TacticRecording/xthm.ml000066400000000000000000000014131214562307500236730ustar00rootroot00000000000000 (* ** DATATYPE ** *) (* The 'xthm' datatype *) (* This couples a theorem with an 'mldata' representation of its proof. For *) (* named ML objects, this 'mldata' will simply be the ML name of the theorem. *) (* For rule applications, it will capture the rule and its arguments. *) type xthm = thm * mldata;; type xconv = term -> xthm;; (* Constructors and destructors *) let mk_xthm (xth:thm*mldata) : xthm = xth;; let mk_xthm0 x th = mk_xthm (th, (x,[]));; let dest_xthm ((th,prf):xthm) : thm * mldata = (th,prf);; let xthm_thm ((th,_):xthm) = th;; let xthm_proof ((_,prf):xthm) = prf;; let name_xthm x ((th,_):xthm) : xthm = (th, (x,[]));; (* ** INSTALL PRINTERS ** *) let print_xthm ((th,_):xthm) = print_thm th;; #install_printer print_xthm;; proofgeneral-4.3~pre130510/hol-light/example.ml000066400000000000000000000005501214562307500213030ustar00rootroot00000000000000(* Example proof script for HOL Proof General. $Id: example.ml,v 12.2 2012/02/08 18:29:13 da Exp $ *) g `A /\ B ==> B /\ A`;; e DISCH_TAC;; e CONJ_TAC;; e (ASM_SIMP_TAC[]);; e (ASM_SIMP_TAC[]);; let and_comms = top_thm();; g `A /\ B ==> B /\ A`;; e DISCH_TAC;; e CONJ_TAC;; e (ASM_SIMP_TAC[]);; e (ASM_SIMP_TAC[]);; let and_comms2 = top_thm();; proofgeneral-4.3~pre130510/hol-light/hol-light-autotest.el000066400000000000000000000013651214562307500234020ustar00rootroot00000000000000;; hol-light-autotest.el: tests of HOL Light Proof General. ;; ;; You can run these by issuing "make test.hol-light" in PG home dir. ;; ;; $Id: hol-light-autotest.el,v 1.1 2012/02/08 17:41:57 da Exp $ ;; (eval-when-compile (require 'cl)) (eval-when (compile) (require 'proof-site) (proof-ready-for-assistant 'coq) (defvar coq-compile-before-require nil)) (require 'pg-autotest) (unless noninteractive (pg-autotest start 'debug) (pg-autotest log ".autotest.log") ; convention (pg-autotest timestart 'total) (pg-autotest remark "Testing standard examples...") (pg-autotest script-wholefile "hol-light/example.ml") (proof-shell-wait) (pg-autotest remark "Complete.") (pg-autotest timetaken 'total) (pg-autotest exit)) proofgeneral-4.3~pre130510/hol-light/hol-light-unicode-tokens.el000066400000000000000000000137431214562307500244640ustar00rootroot00000000000000;;; -*- coding: utf-8; -*- ;; coq-unicode-tokens.el --- (No) Tokens for Unicode Tokens package ;; ;; Copyright(C) 2012 David Aspinall / University of Edinburgh ;; Author: David Aspinall ;; ;; This file is loaded by `proof-unicode-tokens.el'. ;; ;; It sets the variables defined at the top of unicode-tokens.el, ;; unicode-tokens- is set from hol-light-. See the corresponding ;; variable for documentation. ;; ;; For HOL Light, there is no dedicated token syntax, we simply ;; define replacements for common ASCII sequences. ;; ;; FIXME TODO: ;; - only do it for quoted text ;; - fix unicode tokens sorting so longs tokens handled first (broken?) ;; <=> not <= > (require 'proof-unicode-tokens) (defconst hol-light-token-format "%s") ; plain tokens (defconst hol-light-token-match nil) (defconst hol-light-hexcode-match nil) (defun hol-light-unicode-tokens-set (sym val) "Change a Unicode Tokens configuration variable and restart." (set-default sym val) (when (featurep 'hol-light-unicode-tokens) ; not during loading (proof-unicode-tokens-configure))) (defcustom hol-light-token-symbol-map '(;; Greek letters ("alpha" "α") ("beta" "β") ("gamma" "γ") ("delta" "δ") ("epsilon" "ε") ("zeta" "ζ") ("eta" "η") ("theta" "θ") ("iota" "ι") ("kappa" "κ") ("lambda" "λ") ("mu" "μ") ("nu" "ν") ("xi" "ξ") ("pi" "Ï€") ("rho" "Ï") ("sigma" "σ") ("tau" "Ï„") ("upsilon" "Ï…") ("phi" "Ï•") ("chi" "χ") ("psi" "ψ") ("omega" "ω") ("Gamma" "Γ") ("Delta" "Δ") ("Theta" "Θ") ("Lambda" "Λ") ("Xi" "Ξ") ("Pi" "Π") ("Sigma" "Σ") ("Upsilon" "Î¥") ("Phi" "Φ") ("Psi" "Ψ") ("Omega" "Ω") ;; logic ("forall" "∀") ("exists" "∃") (":num" ":â„•" type) ;; ? (":complex" ":â„‚" type) (":real" ":â„" type) (":int" ":ℤ" type) ("rat" "ℚ" type) ("bool" "B" underline type) ("false" "false" bold sans) ("true" "true" bold sans) ("lhd" "⊲") ("rhd" "⊳") ("<=" "≤") (">=" "≥") ("=>" "⇒") ("->" "→") ; or ⟶ or ⟹ if you prefer ("<-" "â†") ; or ⟵ or ⟸ ("<->" "↔") ; or ⟷ ... ("++" "⧺") ("<<" "《") (">>" "》") ;; Equivalence ("===" "≡") ; equiv ("=/=" "≢") ; complement equiv ("=~=" "≅") ; pequiv ("==b" "≡") ; NB: same presentation ("<>b" "≢") ; NB: same presentation ("-->" "⟹-") ; Morphisms ("++>" "⟹+") ; ("==>" "⟹") ; (":=" "≔") ("|-" "⊢") ("<>" "≠") ("-|" "⊣") ("\\/" "∨") ("/\\" "∧") ("~" "¬") ) ;; an alist of token name, unicode char sequence "Table mapping Coq tokens to Unicode strings. You can adjust this table to add entries, or to change entries for glyphs that not are available in your Emacs or chosen font. When a file is visited, tokens are replaced by the strings in this table. When the file is saved, the reverse is done. The string mapping can be anything, but should be such that tokens can be uniquely recovered from a decoded text; otherwise results will be undefined when files are saved." :type 'unicode-tokens-token-symbol-map :set 'hol-light-unicode-tokens-set :group 'coq :tag "Coq Unicode Token Mapping") (defcustom hol-light-shortcut-alist '(; short cut, REAL unicode string ("<>" . "â‹„") ("|>" . "⊳") ("\\/" . "∨") ("/\\" . "∧") ("+O" . "⊕") ("-O" . "⊖") ("xO" . "⊗") ("/O" . "⊘") (".O" . "⊙") ("|+" . "†") ("|++" . "‡") ("<=" . "≤") ("|-" . "⊢") (">=" . "≥") ("-|" . "⊣") ("||" . "∥") ("==" . "≡") ("~=" . "≃") ("~~~" . "â‰") ("~~" . "≈") ("~==" . "≅") ("|<>|" . "⋈") ("|=" . "⊨") ("=." . "â‰") ("_|_" . "⊥") ("=/" . "≱") ("=/" . "≠") ("==/" . "≢") ("~/" . "â‰") ("~=/" . "≄") ("~~/" . "≉") ("~==/" . "≇") ("<-" . "â†") ("<=" . "â‡") ("->" . "→") ("=>" . "⇒") ("<->" . "↔") ("<=>" . "⇔") ("|->" . "↦") ("<--" . "⟵") ("<==" . "⟸") ("-->" . "⟶") ("==>" . "⟹") ("<==>" . "⟷") ("|-->" . "⟼") ("<--" . "â†âޝ") ("<-->" . "⟷") ("<<" . "⟪") ("[|" . "⟦") (">>" . "⟫") ("|]" . "⟧") ("``" . "â€") ("''" . "“") ("--" . "–") ("---" . "—") ("''" . "″") ("'''" . "‴") ("''''" . "â—") (":=" . "≔") ;; some word shortcuts, started with backslash otherwise ;; too annoying, perhaps. ("\\int" . "ℤ") ("\\rat" . "ℚ") ("\\complex" . "â„‚") ("\\euro" . "€") ("\\yen" . "Â¥") ("\\cent" . "¢")) "Shortcut key sequence table for Unicode strings. You can adjust this table to add more entries, or to change entries for glyphs that not are available in your Emacs or chosen font. These shortcuts are only used for input; no reverse conversion is performed. This means that the target strings need to have a defined meaning to be useful." :type '(repeat (cons (string :tag "Shortcut sequence") (string :tag "Unicode string"))) :set 'hol-light-unicode-tokens-set :group 'coq :tag "Coq Unicode Input Shortcuts") ;; ;; Controls ;; (defconst hol-light-control-char-format-regexp ;; FIXME: fix Coq identifier syntax below "\\(\s*%s\s*\\)\\([a-zA-Z0-9']+\\)") (defconst hol-light-control-char-format " %s ") (defconst hol-light-control-characters '(("Subscript" "__" sub) ("Superscript" "^^" sup))) (defconst hol-light-control-region-format-regexp "\\(\s*%s\{\\)\\([^}]*\\)\\(\}\s*\\)") (defconst hol-light-control-regions '(("Subscript" "," "" sub) ("Superscript" "^" "" sup) ("Bold" "BOLD" "" bold) ("Italic" "ITALIC" "" italic) ("Script" "SCRIPT" "" script) ("Frakt" "FRACT" "" frakt) ("Roman" "ROMAN" "" serif))) (provide 'hol-light-unicode-tokens) ;;; hol-light-unicode-tokens.el ends here proofgeneral-4.3~pre130510/hol-light/hol-light.el000066400000000000000000000450571214562307500215420ustar00rootroot00000000000000;; hol-light.el Basic Proof General instance for HOL Light ;; ;; Copyright (C) 2010-12 LFCS Edinburgh, David Aspinall. ;; ;; Author: David Aspinall ;; Mark Adams ;; ;; $Id: hol-light.el,v 12.20 2013/01/15 14:40:18 tews Exp $ ;; ;; See the README file in this directory for information. ;; (require 'proof-easy-config) ; easy configure mechanism (require 'proof-syntax) ; functions for making regexps (or (proof-try-require 'caml-font) ; use OCaml Emacs mode syntax (defvar caml-font-lock-keywords nil)) ; (eval-when (compile) (require 'proof-tree) (defvar caml-font-lock-keywords nil)) (defcustom hol-light-home (or (getenv "HOLLIGHT_HOME") (concat (getenv "HOME") "/hol_light")) "*Directory holding the local installation of HOL Light." :type 'string :group 'hol-light) (defcustom hol-light-prog-name (or (getenv "HOLLIGHT_OCMAL") (getenv "OCAML") "ocaml") "*Name of the OCaml interpreter to launch HOL Light." :type 'string :group 'hol-light) (defcustom hol-light-use-custom-toplevel t "*If non-nil, we use a custom toplevel for Proof General. This configures extra annotations inside HOL Light to help recognise portions of output from the proof assistant. If this is incompatible with your usage of HOL Light for some reason, you can change this setting to run in a degraded (less robust) way which interfaces with the standard top level. You need to restart Emacs if you change this setting." :type 'boolean :group 'hol-light) (defconst hol-light-pre-sync-cmd (format "#use \"%shol-light/pg_prompt.ml\";; " proof-home-directory) "Command used to configure prompt annotations for Proof General.") (defcustom hol-light-init-cmd (append (list (format "#cd \"%s\"" hol-light-home) "#use \"hol.ml\"") (if hol-light-use-custom-toplevel (list (format "#use \"%shol-light/pg_tactics.ml\"" proof-home-directory)) (list "let rec pg_repeat f n = match n with 0 -> () | _ -> (f(); pg_repeat f (n-1));;" "let pg_undo n = (pg_repeat n (fun ()->let _ = b() in ()); p());;" "let pg_kill() = current_goalstack:=[];;" "let pg_forget id = ();;" "let pg_restart() = print_string \"*** Session restarted.\";;"))) "*Commands used to start up a running HOL Light session." :type '(list string) :group 'hol-light) ;; ;; Regular expressions for matching output with ;; standard or custom top levels ;; (defconst hol-light-plain-start-goals-regexp (concat "^\\(val it : x?goalstack = \\)" "\\(?:.+\n\\)*" "\\(?:[0-9]*[0-9] subgoals? ([0-9]+ total)\\|No subgoals\\)") "Value for `proof-shell-start-goals-regexp' with standard top level.") (defconst hol-light-annotated-start-goals-regexp hol-light-plain-start-goals-regexp "Value for `proof-shell-start-goals-regexp' with custom top level.") (defconst hol-light-plain-interrupt-regexp "Interrupted" "Value for `proof-shell-interrupt-regexp' with standard top level.") (defconst hol-light-annotated-interrupt-regexp hol-light-plain-interrupt-regexp ;; TODO "Value for `proof-shell-interrupt-regexp' with custom top level.") (defconst hol-light-plain-prompt-regexp "\\(val it : unit = ()\n\\)?^# " "Value for `proof-shell-annotated-prompt-regexp' with standard top level.") (defconst hol-light-annotated-prompt-regexp "\\(val it : unit = ()\n\\)?.*" "Value for `proof-shell-annotated-prompt-regexp' with custom top level.") (defconst hol-light-plain-error-regexp (proof-regexp-alt "Characters [0-9]+-[0-9]+:" "^Exception: Failure" "^Parse error: " "^Cannot find file" "^Error: Unbound value" "^Error: Syntax error" ;; TODO: more here ) "Value for `proof-shell-error-regexp' with standard top level.") (defconst hol-light-annotated-error-regexp ;; ".+" ;; unfortunately not enough, this is only for failwith hol-light-plain-error-regexp "Value for `proof-shell-error-regexp' with custom top level.") (defconst hol-light-plain-proof-completed-regexp "Initial goal proved" "Value for `proof-shell-proof-completed-regexp' with standard top level.") (defconst hol-light-annotated-proof-completed-regexp hol-light-plain-proof-completed-regexp ;; TODO "Value for `proof-shell-proof-completed-regexp' with standard top level.") (defconst hol-light-plain-message-start "^Warning \\|\\*\*\\*" "Value for `proof-shell-eager-annotation-start' with standard top level.") (defconst hol-light-annotated-message-start "^Warning \\|\\*\\*\\*" ;; TODO "Value for `proof-shell-eager-annotation-start' with custom top level.") (defconst hol-light-plain-message-end "\n" ;; TODO "Value for `proof-shell-eager-annotation-start' with standard top level.") (defconst hol-light-annotated-message-end "\n" ;; TODO "Value for `proof-shell-eager-annotation-start' with custom top level.") ;;; ;;; State ;;; (defvar hol-light-keywords nil) (defvar hol-light-rules nil) (defvar hol-light-tactics nil) (defvar hol-light-tacticals nil) ;;; ;;; Main configuration ;;; (proof-easy-config 'hol-light "HOL Light" proof-assistant-home-page "https://www.cl.cam.ac.uk/~jrh13/hol-light/" proof-prog-name hol-light-prog-name proof-terminal-string ";;" proof-shell-pre-sync-init-cmd hol-light-pre-sync-cmd proof-shell-init-cmd hol-light-init-cmd ;; Regexps for matching tactic script inputs: all approximations, of course. proof-goal-command-regexp "^g[ `]" proof-save-command-regexp "top_thm()" proof-goal-with-hole-regexp "let \\(\\([^ \t=]*\\)\\)[ \t]*=[ \t]*prove" proof-save-with-hole-regexp "let \\(\\([^ \t=]*\\)\\)[ \t]*=[ \t]*top_thm()" proof-non-undoables-regexp "b()" ; and others.. proof-goal-command "g `%s`;;" proof-save-command "val %s = top_thm();;" proof-kill-goal-command "pg_kill();;" proof-undo-n-times-cmd "pg_undo %s;;" proof-forget-id-command "pg_forget \"%s\";;" proof-shell-restart-cmd "pg_restart();;" proof-showproof-command "p();;" proof-auto-multiple-files t proof-shell-cd-cmd "#cd \"%s\";;" proof-shell-filename-escapes '(("\\\\" . "\\\\") ("\"" . "\\\"")) proof-shell-annotated-prompt-regexp (if hol-light-use-custom-toplevel hol-light-annotated-prompt-regexp hol-light-plain-prompt-regexp) proof-shell-interrupt-regexp (if hol-light-use-custom-toplevel hol-light-annotated-interrupt-regexp hol-light-plain-interrupt-regexp) proof-shell-start-goals-regexp (if hol-light-use-custom-toplevel hol-light-annotated-start-goals-regexp hol-light-plain-start-goals-regexp) proof-shell-error-regexp (if hol-light-use-custom-toplevel hol-light-annotated-error-regexp hol-light-plain-error-regexp) proof-shell-proof-completed-regexp (if hol-light-use-custom-toplevel hol-light-annotated-proof-completed-regexp hol-light-plain-proof-completed-regexp) proof-shell-eager-annotation-start (if hol-light-use-custom-toplevel hol-light-annotated-message-start hol-light-plain-message-start) proof-shell-eager-annotation-end (if hol-light-use-custom-toplevel hol-light-annotated-message-end hol-light-plain-message-end) ;; FIXME: add optional help topic parameter to help command. proof-info-command "help \"hol\"" ;; 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);;" ;; ;; Syntax and syntax table entries for proof scripts ;; proof-script-comment-start "(*" proof-script-comment-end "*)" proof-script-syntax-table-entries '(?\` "\"" ?\$ "." ?\/ "." ?\\ "." ?+ "." ?- "." ?= "." ?% "." ?< "." ?> "." ?\& "." ?. "w" ?_ "w" ?\' "w" ?\| "." ?\* ". 23n" ?\( "()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 all this information here! ;; hol-light-keywords '("g" "expand" "e" "store_thm" "top_thm" "by" "Define" "xDefine" "Hol_defn" "Induct" "Cases" "Cases_on" "Induct_on" "std_ss" "arith_ss" "list_ss" "define_type") hol-light-rules '("REFL" "TRANS" "MK_COMB" "ABS" "BETA" "BETA_CONV" "ASSUME" "EQ_MP" "DEDUCT_ANTISYM_RULE" "INST_TYPE" "INST" "TRUTH" "CONJ" "CONJUNCT1" "CONJUNCT2" "PINST" "PROVE_HYP" "T_DEF" "TRUTH" "EQT_ELIM" "EQT_INTRO" "AND_DEF" "CONJ" "CONJUNCT1" "CONJUNCT2" "CONJ_PAIR" "CONJUNCTS" "IMP_DEF" "MP" "DISCH" "DISCH_ALL" "UNDISCH" "UNDISCH_ALL" "IMP_ANTISYM_RULE" "ADD_ASSUM" "EQ_IMP_RULE" "IMP_TRANS" "FORALL_DEF" "SPEC" "SPECL" "SPEC_VAR" "SPEC_ALL" "ISPEC" "ISPECL" "GEN" "GENL" "GEN_ALL th" "EXISTS_DEF" "EXISTS" "SIMPLE_EXISTS" "CHOOSE" "SIMPLE_CHOOSE" "OR_DEF" "DISJ1" "DISJ2" "DISJ_CASES" "SIMPLE_DISJ_CASES" "F_DEF" "NOT_DEF" "NOT_ELIM" "NOT_INTRO" "EQF_INTRO" "EQF_ELIM" "CONTR" "EXISTS_UNIQUE_DEF" "EXISTENCE" "EQ_REFL" "REFL_CLAUSE" "EQ_SYM" "EQ_SYM_EQ" "EQ_TRANS" "AC" "BETA_THM" "ABS_SIMP" "CONJ_ASSOC" "CONJ_SYM" "CONJ_ACI" "DISJ_ASSOC" "DISJ_SYM" "DISJ_ACI" "IMP_CONJ" "IMP_IMP" "IMP_CONJ_ALT" "LEFT_OR_DISTRIB" "RIGHT_OR_DISTRIB" "FORALL_SIMP" "EXISTS_SIMP" "EQ_IMP" "EQ_CLAUSES" "NOT_CLAUSES_WEAK" "AND_CLAUSES" "OR_CLAUSES" "IMP_CLAUSES" "IMP_EQ_CLAUSE" "EXISTS_UNIQUE_THM" "EXISTS_REFL" "EXISTS_UNIQUE_REFL" "UNWIND_THM1" "UNWIND_THM2" "FORALL_UNWIND_THM2" "FORALL_UNWIND_THM1" "SWAP_FORALL_THM" "SWAP_EXISTS_THM" "FORALL_AND_THM" "AND_FORALL_THM" "LEFT_AND_FORALL_THM" "RIGHT_AND_FORALL_THM" "EXISTS_OR_THM" "OR_EXISTS_THM" "LEFT_OR_EXISTS_THM" "RIGHT_OR_EXISTS_THM" "LEFT_EXISTS_AND_THM" "RIGHT_EXISTS_AND_THM" "TRIV_EXISTS_AND_THM" "LEFT_AND_EXISTS_THM" "RIGHT_AND_EXISTS_THM" "TRIV_AND_EXISTS_THM" "TRIV_FORALL_OR_THM" "TRIV_OR_FORALL_THM" "RIGHT_IMP_FORALL_THM" "RIGHT_FORALL_IMP_THM" "LEFT_IMP_EXISTS_THM" "LEFT_FORALL_IMP_THM" "TRIV_FORALL_IMP_THM" "TRIV_EXISTS_IMP_THM" "EXISTS_UNIQUE_ALT" "EXISTS_UNIQUE") hol-light-tactics '("ABS_TAC" "ACCEPT_TAC" "ALL_TAC" "ANTS_TAC" "AP_TERM_TAC" "AP_THM_TAC" "ASSUME_TAC" "BETA_TAC" "BINOP_TAC" "CHANGED_TAC" "CHEAT_TAC" "CHOOSE_TAC" "CONJ_TAC" "CONTR_TAC" "CONV_TAC" "DISCARD_TAC" "DISCH_TAC" "DISJ1_TAC" "DISJ2_TAC" "DISJ_CASES_TAC" "EQ_TAC" "EXISTS_TAC" "FAIL_TAC" "GEN_TAC" "LABEL_TAC" "MATCH_ACCEPT_TAC" "MATCH_MP_TAC " "META_EXISTS_TAC" "META_SPEC_TAC" "MK_COMB_TAC" "MP_TAC" "NO_TAC" "RECALL_ACCEPT_TAC" "REFL_TAC" "REPLICATE_TAC" "RULE_ASSUM_TAC " "SPEC_TAC" "STRIP_ASSUME_TAC" "STRIP_GOAL_THEN" "STRIP_TAC" "STRUCT_CASES_TAC" "SUBGOAL_TAC" "SUBST1_TAC" "SUBST_ALL_TAC" "SUBST_VAR_TAC" "UNDISCH_TAC" "X_CHOOSE_TAC" "X_GEN_TAC" "X_META_EXISTS_TAC") hol-light-tacticals '("ORELSE" "FIRST" "CHANGED_TAC" "THEN" "THENL" "EVERY" "REPEAT" "MAP_EVERY" "IMP_RES_THEN" "FIND_ASSUM" "POP_ASSUM" "ASSUM_LIST" "EVERY_ASSUM" "FIRST_ASSUM" "CONJUCTS_THEN" "DISJ_CASES_THEN" "DISCH_THEN" "X_CHOOSE_THEN" "MAP_EVERY" "CHOOSE_THEN" "STRIP_THM_THEN" "SUBGOAL_THEN" "FREEZE_THEN") proof-script-font-lock-keywords (append caml-font-lock-keywords (list (cons (proof-ids-to-regexp hol-light-keywords) 'font-lock-keyword-face) (cons (proof-ids-to-regexp hol-light-tactics) 'proof-tactics-name-face) (cons (proof-ids-to-regexp hol-light-rules) 'font-lock-keyword-face) (cons (proof-ids-to-regexp hol-light-tacticals) 'proof-tacticals-name-face))) ;; ;; Some decoration of the goals output [FIXME: not yet HOL Light] ;; 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)) ;; ;; Some decoration of the response output ;; proof-goals-font-lock-keywords (setq proof-goals-font-lock-keywords (list ;; Help system output (cons (proof-ids-to-regexp '("^----------[-]+$" "SYNOPSIS" "DESCRIPTION" "FAILURE CONDITIONS" "EXAMPLES" "SEE ALSO")) 'font-lock-keyword-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. ) ;;; ;;; Prooftree configuration (experimental, ongoing) ;;; ;; regexps for recognising additional markup in output (defvar hol-light-update-goal-regexp (concat "\\[Goal ID \\([0-9]+\\)\\]" "\\s-*\n\\(\\(?:.+\n\\)*\\)\\(?:\n\\|$\\)")) (defconst hol-light-current-goal-regexp ;; match final (focused) subgoal. (concat (regexp-quote "[*]") "\\[Goal ID \\([0-9]+\\)\\]" "\\s-*\n\\(\\(?:.+\n\\)*\\)\\(?:\n\\|$\\)")) (defconst hol-light-additional-subgoal-regexp "\\[New Goal IDs: \\([0-9 ]+\\)\\]" "HOL Light instance of `proof-tree-additional-subgoal-ID-regexp'.") (defconst hol-light-statenumber-regexp "\\([0-9]+\\)|\\([0-9]+\\)" "Regular expression to match prompt with state numbers. The first number is a global state counter which increases with processed steps. The second number is the number of steps within the currently open proof.") (defconst hol-light-existential-regexp "\\(\\?[0-9]+\\)" "Regexp for `proof-tree-existential-regexp'.") (defconst hol-light-existentials-state-start-regexp "^(dependent evars:" "HOL Light instance of `proof-tree-existentials-state-start-regexp'.") (defconst hol-light-existentials-state-end-regexp ")\n" "HOL Light instance of `proof-tree-existentials-state-end-regexp'.") (setq ;; These ones belong in script mode config proof-tree-configured t proof-tree-get-proof-info 'hol-light-get-proof-info proof-tree-find-begin-of-unfinished-proof 'hol-light-find-begin-of-unfinished-proof ;; These ones belong in shell mode proof-tree-branch-finished-regexp "No subgoals" proof-tree-show-sequent-command (lambda (id) (format "print_xgoal_of_id \"%s\";;" id)) proof-tree-current-goal-regexp hol-light-current-goal-regexp proof-tree-additional-subgoal-ID-regexp hol-light-additional-subgoal-regexp proof-tree-update-goal-regexp hol-light-update-goal-regexp proof-tree-cheating-regexp "CHEAT_TAC" ;; others... proof-tree-existential-regexp hol-light-existential-regexp proof-tree-existentials-state-start-regexp hol-light-existentials-state-start-regexp proof-tree-existentials-state-end-regexp hol-light-existentials-state-end-regexp ) ;; end setq proof tree stuff ;;; get proof info: uses last goals output ;;; FIXME problem here: this is called BEFORE last goals output ;;; is set. Can we move order without harming Coq? ;; TEMP to fix compile. Will use Coq-stype annotated prompt for proof tree now. (defvar proof-shell-delayed-output-start nil) (defvar proof-shell-delayed-output-end nil) (defvar proof-info nil) (defvar proof-action-list nil) (defun proof-shell-action-list-item (&rest args)) (defconst hol-light-show-sequent-command "print_xgoal_of_id %s;;") (defun hol-light-get-proof-info () "Return proof info for Prooftree for HOL Light. See `proof-tree-get-proof-info'." (let ((proof-state-number 0) (proof-name "Goal")) ; no named goals (when (and t ; (> proof-nesting-depth 0) ; inside a proof (string-match hol-light-statenumber-regexp proof-shell-last-prompt)) (setq proof-state-number (string-to-number (match-string 1 proof-shell-last-prompt)))) (list proof-state-number proof-name))) (defun hol-light-find-begin-of-unfinished-proof () ;; Quick hack, we should use some internal proof script stuff here (save-excursion (re-search-backward "^g" nil t))) ;;; FIXME: this is duplicated from coq.el. It might be kind of generic. ;;; However, for HOL Light the default behaviour is actually to print out ;;; exactly the new subgoals arising from a previous tactic allocation, ;;; or the currently focused goal (top of stack). (defun hol-light-proof-tree-get-new-subgoals () "Check for new subgoals and issue appropriate Show commands. This is a hook function for `proof-tree-urgent-action-hook'. This function examines the current goal output and searches for new unknown subgoals. Those subgoals have been generated by the last proof command and we must send their complete sequent text eventually to prooftree. Because subgoals may change with the next proof command, we must execute the additionally needed Show commands before the next real proof command. The ID's of the open goals are checked with `proof-tree-sequent-hash' in order to find out if they are new. For any new goal an appropriate Show Goal command with a 'proof-tree-show-subgoal flag is inserted into `proof-action-list'. Then, in the normal delayed output processing, the sequent text is send to prooftree as a sequent update (see `proof-tree-update-sequent') and the ID of the sequent is registered as known in `proof-tree-sequent-hash'. The not yet delayed output is in the region \[proof-shell-delayed-output-start, proof-shell-delayed-output-end]." ;; (message "CPTGNS start %s end %s" ;; proof-shell-delayed-output-start ;; proof-shell-delayed-output-end) (with-current-buffer proof-shell-buffer (let ((start proof-shell-delayed-output-start) (end proof-shell-delayed-output-end)) (goto-char start) (while (proof-re-search-forward hol-light-update-goal-regexp end t) (let ((subgoal-id (match-string-no-properties 1))) (unless (gethash subgoal-id proof-tree-sequent-hash) (setq proof-action-list (cons (proof-shell-action-list-item (format hol-light-show-sequent-command subgoal-id) (proof-tree-make-show-goal-callback (car proof-info)) '(no-goals-display no-response-display proof-tree-show-subgoal)) proof-action-list)))))))) (add-hook 'proof-tree-urgent-action-hook 'hol-light-proof-tree-get-new-subgoals) ;;; ;;; Menu commands ;;; (proof-definvisible hol-light-dump-proof "dump_proof();;") (defpgdefault menu-entries '(["Dump refactored proof" hol-light-dump-proof t])) (provide 'hol-light) proofgeneral-4.3~pre130510/hol-light/pg_prompt.ml000066400000000000000000000043051214562307500216610ustar00rootroot00000000000000(* ========================================================================= *) (* HOL Light tweaks for Proof General. *) (* *) (* Mark Adams, David Aspinall. *) (* LFCS, School of Informatics, University of Edinburgh *) (* *) (* (c) Copyright University of Edinburgh and authors, 2012. *) (* *) (* This file adjust the OCaml prompt to help Proof General synchronization. *) (* It is loaded before HOL Light. *) (* ========================================================================= *) (* ------------------------------------------------------------------------- *) (* Proof General mode, providing extra annotations in output *) (* ------------------------------------------------------------------------- *) let pg_mode = ref (true : bool);; let pg_mode_on () = (pg_mode := true);; let pg_mode_off () = (pg_mode := false);; let pg_prompt_info = ref (fun () -> "");; (* ------------------------------------------------------------------------- *) (* Adjust the OCaml prompt to carry information for Proof General *) (* ------------------------------------------------------------------------- *) let original_prompt_fn = !Toploop.read_interactive_input in (Toploop.read_interactive_input := fun prompt buffer len -> let prompt' = if (!pg_mode) then "" ^ (!pg_prompt_info()) ^ "" else prompt in original_prompt_fn prompt' buffer len);; (* ------------------------------------------------------------------------- *) (* Adjust error printing to markup error messages *) (* ------------------------------------------------------------------------- *) (* Doesn't really work, as many errors are from OCaml top level and not printed in this way. let print_exn e = match e with Failure x -> Format.print_string (if (!pg_mode) then "" ^ x ^ "" else x) | _ -> Format.print_string (Printexc.to_string e);; #install_printer print_exn;; *) proofgeneral-4.3~pre130510/hol-light/pg_tactics.ml000066400000000000000000000314661214562307500220020ustar00rootroot00000000000000(* ========================================================================= *) (* HOL Light subgoal package amended for Proof General and Prooftree. *) (* *) (* Mark Adams, David Aspinall. *) (* LFCS, School of Informatics, University of Edinburgh *) (* *) (* (c) Copyright University of Edinburgh and authors, 2012. *) (* *) (* This file contains some functions that are modified from the *) (* original HOL Light code, and is therefore subject to the HOL Light *) (* copyright, see the file LICENSE-HOL-LIGHT in this directory. *) (* *) (* ========================================================================= *) (* *) (* This file overwrites HOL Light's subgoal package commands with variants *) (* that output additional annotations specifically for Prooftree. These get *) (* intercepted by Proof General, which removes them from the output *) (* displayed to the Proof General user. *) (* TODO: 1. add urgent message annotations for errors and strings output during long-running tactics 2. fix on/off: don't turn off prompt annotation, support Prooftree on/off. *) (* ------------------------------------------------------------------------- *) (* Goal counter for providing goal ids. *) (* ------------------------------------------------------------------------- *) type goal_id = int;; let string_of_goal_id id = string_of_int id;; let the_goal_counter = ref (0 : goal_id);; let inc_goal_counter () = (the_goal_counter := !the_goal_counter + 1);; let reset_goal_counter () = (the_goal_counter := 0; !the_goal_counter);; (* ------------------------------------------------------------------------- *) (* An xgoal extends a goal with an identity. *) (* ------------------------------------------------------------------------- *) type xgoal = goal * goal_id;; let dest_xgoal (gx : xgoal) = gx;; (* ------------------------------------------------------------------------- *) (* The xgoalstate is like goalstate but for xgoals instead of goals. *) (* ------------------------------------------------------------------------- *) type xgoalstate = (term list * instantiation) * xgoal list * justification;; (* ------------------------------------------------------------------------- *) (* A goalstack but for xgoals. Overwrites original HL datatype. *) (* ------------------------------------------------------------------------- *) type goalstack = xgoalstate list;; (* ------------------------------------------------------------------------- *) (* A refinement but for xgoals. *) (* ------------------------------------------------------------------------- *) type xrefinement = xgoalstate -> xgoalstate;; (* ------------------------------------------------------------------------- *) (* Instantiation of xgoals. *) (* ------------------------------------------------------------------------- *) let (inst_xgoal:instantiation->xgoal->xgoal) = fun p ((thms,w),id) -> (map (I F_F INSTANTIATE_ALL p) thms,instantiate p w),id;; (* ------------------------------------------------------------------------- *) (* A printer for xgoals and xgoalstacks. *) (* ------------------------------------------------------------------------- *) let the_new_goal_ids = ref ([] : goal_id list);; let the_tactic_flag = ref false;; let print_string_seplist sep xs = if (xs = []) then () else (print_string (hd xs); do_list (fun x -> print_string sep; print_string x) (tl xs));; let print_xgoal ((g,id) : xgoal) : unit = ((if (!pg_mode) then (print_string ("[Goal ID " ^ string_of_goal_id id ^ "]"); print_newline ())); print_goal g);; let (print_xgoalstack:goalstack->unit) = let print_xgoalstate k gs = let (_,gl,_) = gs in let n = length gl in let s = if n = 0 then "No subgoals" else (string_of_int k)^" subgoal"^(if k > 1 then "s" else "") ^" ("^(string_of_int n)^" total)" in print_string s; print_newline(); if gl = [] then () else (do_list (print_xgoal o C el gl) (rev(1--(k-1))); (if (!pg_mode) then print_string "[*]"); print_xgoal (el 0 gl)) in fun l -> ((if (!pg_mode) & (!the_tactic_flag) then let xs = map string_of_int (!the_new_goal_ids) in (the_tactic_flag := false; print_string "[New Goal IDs: "; print_string_seplist " " xs; print_string "]"; print_newline ())); (if l = [] then print_string "Empty goalstack" else if tl l = [] then let (_,gl,_ as gs) = hd l in print_xgoalstate 1 gs else let (_,gl,_ as gs) = hd l and (_,gl0,_) = hd(tl l) in let p = length gl - length gl0 in let p' = if p < 1 then 1 else p + 1 in print_xgoalstate p' gs); (if (!pg_mode) then let (vs,theta) = if (l = []) then ([],[]) else let ((vs,(_,theta,_)),_,_) = hd l in (vs,theta) in let foo v = let (x,_) = dest_var v in "?" (* FIXME: Coq syntax for meta vars is expected by Prooftree *) ^ x ^ if (can (rev_assoc v) theta) then " using" else " open" in let xs = map foo vs in (print_newline(); print_string "(dependent evars:"; if xs != [] then (print_string " "; print_string_seplist ", " xs; print_string ","); print_string ")"; print_newline ())));; (* ------------------------------------------------------------------------- *) (* Goal labelling, for fresh xgoals. *) (* ------------------------------------------------------------------------- *) let label_goals (gs : goal list) : xgoal list = let gxs = map (fun g -> inc_goal_counter (); (g, !the_goal_counter)) gs in (the_new_goal_ids := map snd gxs; gxs);; (* ------------------------------------------------------------------------- *) (* Version of 'by' for xrefinements. *) (* ------------------------------------------------------------------------- *) let (xby:tactic->xrefinement) = fun tac ((mvs,inst),glsx,just) -> let gx = hd glsx and oglsx = tl glsx in let (g,id) = dest_xgoal gx in let ((newmvs,newinst),subgls,subjust) = tac g in let subglsx = label_goals subgls in let n = length subglsx in let mvs' = union newmvs mvs and inst' = compose_insts inst newinst and glsx' = subglsx @ map (inst_xgoal newinst) oglsx in let just' i ths = let i' = compose_insts inst' i in let cths,oths = chop_list n ths in let sths = (subjust i cths) :: oths in just i' sths in (mvs',inst'),glsx',just';; (* ------------------------------------------------------------------------- *) (* Rotate but for xgoalstate. Only change is different ML datatype. *) (* ------------------------------------------------------------------------- *) let (xrotate:int->xrefinement) = let rotate_p (meta,sgs,just) = let sgs' = (tl sgs)@[hd sgs] in let just' i ths = let ths' = (last ths)::(butlast ths) in just i ths' in (meta,sgs',just') and rotate_n (meta,sgs,just) = let sgs' = (last sgs)::(butlast sgs) in let just' i ths = let ths' = (tl ths)@[hd ths] in just i ths' in (meta,sgs',just') in fun n -> if n > 0 then funpow n rotate_p else funpow (-n) rotate_n;; (* ------------------------------------------------------------------------- *) (* Perform refinement proof, tactic proof etc. *) (* ------------------------------------------------------------------------- *) let (mk_xgoalstate:goal->xgoalstate) = fun (asl,w) -> if type_of w = bool_ty then null_meta,[((asl,w), reset_goal_counter ())], (fun inst [th] -> INSTANTIATE_ALL inst th) else failwith "mk_goalstate: Non-boolean goal";; (* ------------------------------------------------------------------------- *) (* The global state counts the total number of proof steps taken. *) (* ------------------------------------------------------------------------- *) let the_pg_global_state = ref 1;; let inc_pg_global_state () = (the_pg_global_state := !the_pg_global_state + 1);; let dec_pg_global_state n = (the_pg_global_state := !the_pg_global_state - n);; let pg_global_state () = !the_pg_global_state;; (* ------------------------------------------------------------------------- *) (* The proof state number is the length of the current goal stack. *) (* ------------------------------------------------------------------------- *) let the_current_xgoalstack = ref ([] : goalstack);; let pg_proof_state () = length !the_current_xgoalstack;; (* ------------------------------------------------------------------------- *) (* Subgoal package for xgoals and with a constrained undo protocol for *) (* interacting with Proof General to track the state. These overwrite the *) (* existing commands and may cause breakage of interactive proofs. *) (* *) (* The restrictions are: *) (* - top_thm may only be called once and closes the currently open proof. *) (* - the back command b() is not allowed to appear in a file. *) (* *) (* ------------------------------------------------------------------------- *) let (xrefine:xrefinement->goalstack) = fun r -> let l = !the_current_xgoalstack in let h = hd l in let res = r h :: l in the_current_xgoalstack := res; !the_current_xgoalstack;; let flush_goalstack() = let l = !the_current_xgoalstack in the_current_xgoalstack := [hd l];; let e tac = let result = xrefine(xby(VALID tac)) in (inc_pg_global_state (); the_tactic_flag := true; result);; let r n = (inc_pg_global_state (); xrefine(xrotate n));; let set_goal(asl,w) = let aths = map ASSUME asl in (inc_pg_global_state (); the_current_xgoalstack := [mk_xgoalstate(map (fun th -> "",th) aths,w)]; !the_current_xgoalstack);; let g t = let fvs = sort (<) (map (fst o dest_var) (frees t)) in (if fvs <> [] then let errmsg = end_itlist (fun s t -> s^", "^t) fvs in warn true ("Free variables in goal: "^errmsg) else ()); set_goal([],t);; let p() = !the_current_xgoalstack;; let b() = failwith "Undo with b() is not available in Proof General top level";; let top_realgoal() = let (_,(((asl,w),id)::_),_)::_ = !the_current_xgoalstack in asl,w;; let top_goal() = let asl,w = top_realgoal() in map (concl o snd) asl,w;; let plain_top_thm() = let (_,[],f)::_ = !the_current_xgoalstack in f null_inst [];; let top_thm() = let t = plain_top_thm() in (inc_pg_global_state(); the_current_xgoalstack := []; t);; (* ------------------------------------------------------------------------- *) (* Undo handling functions for Proof General *) (* ------------------------------------------------------------------------- *) let pg_undo n = let l = !the_current_xgoalstack in if length l < n then failwith "pg_undo: called with too many steps" else (dec_pg_global_state n; the_current_xgoalstack := snd (chop_list n l); p());; let pg_kill() = let n = length (!the_current_xgoalstack) in (dec_pg_global_state n; the_current_xgoalstack := []; print_string "*** Proof aborted.\n");; let pg_forget s = print_string ("*** Remove theorem "^s^"\n");; let pg_restart() = print_string "*** Session restarted.\n";; (* ------------------------------------------------------------------------- *) (* Configure the annotated prompt. *) (* ------------------------------------------------------------------------- *) pg_prompt_info := fun () -> let pst = pg_proof_state () and gst = pg_global_state () in string_of_int gst ^ "|" ^ string_of_int pst;; (* ------------------------------------------------------------------------- *) (* Printing the goal of a given Prooftree goal id. *) (* ------------------------------------------------------------------------- *) let print_xgoal_of_id (id:goal_id) : unit = let gsts = !the_current_xgoalstack in let find_goal (_,xgs,_) = find (fun (g,id0) -> id0 = id) xgs in let xg = tryfind find_goal gsts in print_xgoal xg;; (* ------------------------------------------------------------------------- *) (* Install the new goal-related printers. *) (* ------------------------------------------------------------------------- *) #install_printer print_xgoal;; #install_printer print_xgoalstack;; proofgeneral-4.3~pre130510/hol-light/temp-prooftree-configure.patch000066400000000000000000000015071214562307500252710ustar00rootroot00000000000000Index: generic/proof-tree.el =================================================================== RCS file: /disk/cvs/proofgen/ProofGeneral/generic/proof-tree.el,v retrieving revision 12.3 diff -c -r12.3 proof-tree.el *** generic/proof-tree.el 19 Jan 2012 13:23:56 -0000 12.3 --- generic/proof-tree.el 19 Jan 2012 13:25:30 -0000 *************** *** 492,498 **** "Send the configure message." (proof-tree-send-message (format "configure for \"%s\" and protocol version %02d" ! proof-assistant proof-tree-protocol-version) ())) --- 492,499 ---- "Send the configure message." (proof-tree-send-message (format "configure for \"%s\" and protocol version %02d" ! ;; temporarily pretend every proof assistant is Coq ! "Coq" ;; was proof-assistant proof-tree-protocol-version) ())) proofgeneral-4.3~pre130510/hol98/000077500000000000000000000000001214562307500163725ustar00rootroot00000000000000proofgeneral-4.3~pre130510/hol98/README000066400000000000000000000035031214562307500172530ustar00rootroot00000000000000HOL Proof General, for HOL98. Written by David Aspinall. Status: not officially supported yet Maintainer: volunteer required HOL version: HOL4/HOL98, tested with HOL 4 Kananaskis 2 HOL homepage: http://hol.sourceforge.net ======================================== This is a "technology demonstration" of Proof General for HOL4. 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 might also be useful for other provers. 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: README,v 12.0 2011/10/13 10:54:49 da Exp $ proofgeneral-4.3~pre130510/hol98/example.sml000066400000000000000000000015411214562307500205430ustar00rootroot00000000000000(* Example proof script for HOL Proof General. $Id: example.sml,v 12.0 2011/10/13 10:54:49 da Exp $ *) 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. *) proofgeneral-4.3~pre130510/hol98/hol98.el000066400000000000000000000126671214562307500176730ustar00rootroot00000000000000;; hol98.el Basic Proof General instance for HOL 98 ;; ;; Copyright (C) 2000 LFCS Edinburgh. ;; ;; Author: David Aspinall ;; ;; $Id: hol98.el,v 12.0 2011/10/13 10:54:49 da Exp $ ;; ;; 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 (defvar hol98-keywords nil) (defvar hol98-rules nil) (defvar hol98-tactics nil) (defvar hol98-tacticals nil) (proof-easy-config 'hol98 "HOL" proof-prog-name "hol.unquote" proof-terminal-string ";" proof-script-comment-start "(*" proof-script-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-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. 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);" proof-forget-id-command ";" ;; vacuous: but empty string doesn't give ;; new prompt ;; 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 da+pg-feedback@inf.ed.ac.uk") (provide 'hol98) proofgeneral-4.3~pre130510/hol98/root2.sml000066400000000000000000000073721214562307500201650ustar00rootroot00000000000000(* Example proof by Konrad Slind. See http://www.cs.kun.nl/~freek/comparison/ Taken from HOL4 distribution hol98/examples/root2.sml *) (*---------------------------------------------------------------------------*) (* Challenge from Freek Wiedijk: the square root of two is not rational. *) (* I've adapted a proof in HOL Light by John Harrison. *) (*---------------------------------------------------------------------------*) load "transcTheory"; open arithmeticTheory BasicProvers; (*---------------------------------------------------------------------------*) (* Need a predicate on reals that picks out the rational ones *) (*---------------------------------------------------------------------------*) val Rational_def = Define `Rational r = ?p q. ~(q=0) /\ (abs(r) = &p / &q)`; (*---------------------------------------------------------------------------*) (* Trivial lemmas *) (*---------------------------------------------------------------------------*) val EXP_2 = Q.prove(`!n:num. n**2 = n*n`, REWRITE_TAC [TWO,ONE,EXP] THEN RW_TAC arith_ss []); val EXP2_LEM = Q.prove(`!x y:num. ((2*x)**2 = 2*(y**2)) = (2*(x**2) = y**2)`, REWRITE_TAC [TWO,EXP_2] THEN PROVE_TAC [MULT_MONO_EQ,MULT_ASSOC,MULT_SYM]); (*---------------------------------------------------------------------------*) (* Lemma: squares are not doublings of squares, except trivially. *) (*---------------------------------------------------------------------------*) val lemma = Q.prove (`!m n. (m**2 = 2 * n**2) ==> (m=0) /\ (n=0)`, completeInduct_on `m` THEN NTAC 2 STRIP_TAC THEN `?k. m = 2*k` by PROVE_TAC[EVEN_DOUBLE,EXP_2,EVEN_MULT,EVEN_EXISTS] THEN VAR_EQ_TAC THEN `?p. n = 2*p` by PROVE_TAC[EVEN_DOUBLE,EXP_2,EVEN_MULT, EVEN_EXISTS,EXP2_LEM] THEN VAR_EQ_TAC THEN `k**2 = 2*(p**2)` by PROVE_TAC [EXP2_LEM] THEN `(k=0) \/ k < 2*k` by numLib.ARITH_TAC THENL [FULL_SIMP_TAC arith_ss [EXP_2], PROVE_TAC [MULT_EQ_0, DECIDE (Term `~(2 = 0n)`)]]); (*---------------------------------------------------------------------------*) (* The proof moves the problem from R to N, then uses lemma *) (*---------------------------------------------------------------------------*) local open realTheory transcTheory in val SQRT_2_IRRATIONAL = Q.prove (`~Rational (sqrt 2r)`, RW_TAC std_ss [Rational_def,abs,SQRT_POS_LE,REAL_POS] THEN Cases_on `q = 0` THEN ASM_REWRITE_TAC [] THEN SPOSE_NOT_THEN (MP_TAC o Q.AP_TERM `\x. x pow 2`) THEN RW_TAC arith_ss [SQRT_POW_2, REAL_POS, REAL_POW_DIV, REAL_EQ_RDIV_EQ,REAL_LT, REAL_POW_LT] THEN REWRITE_TAC [REAL_OF_NUM_POW, REAL_MUL, REAL_INJ] THEN PROVE_TAC [lemma]) end; (*---------------------------------------------------------------------------*) (* The following is a bit more declarative *) (*---------------------------------------------------------------------------*) infix THEN1; fun ie q tac = Q_TAC SUFF_TAC q THEN1 tac; local open realTheory transcTheory in val SQRT_2_IRRATIONAL = Q.prove (`~Rational (sqrt 2r)`, ie `!p q. ~(q=0) ==> ~(sqrt 2 = & p / & q)` (RW_TAC std_ss [Rational_def,abs,SQRT_POS_LE,REAL_POS] THEN PROVE_TAC[]) THEN RW_TAC std_ss [] THEN ie `~(sqrt 2 = & p / & q)` (PROVE_TAC []) THEN ie `~(2 * q**2 = p**2)` (DISCH_TAC THEN SPOSE_NOT_THEN (MP_TAC o Q.AP_TERM `\x. x pow 2`) THEN RW_TAC arith_ss [SQRT_POW_2,REAL_POS, REAL_POW_DIV,REAL_EQ_RDIV_EQ,REAL_LT, REAL_POW_LT] THEN ASM_REWRITE_TAC [REAL_OF_NUM_POW, REAL_MUL,REAL_INJ]) THEN PROVE_TAC [lemma]) end; proofgeneral-4.3~pre130510/images/000077500000000000000000000000001214562307500166745ustar00rootroot00000000000000proofgeneral-4.3~pre130510/images/ProofGeneral.gif000066400000000000000000000433651214562307500217610ustar00rootroot00000000000000GIF89až·ç±²m“˜G…ŒG.r. U!?2* AX'dE;K6,¶±©H@žTMáÙÎ.ݱŸ@8‹rYؘ„e#:xWK:6œ˜B>’ŽŒƒ†Ö|J5?Y==?054©¡–40ÚÐÆ´Ea”|lÇz&*¤–{*,ÓÍÃxy;¸6#IF)nl:À„s±ž’ ™Ž€4#+51C# vZæ¿©N¢J8ÀŒv&"¨£hcXGƒ6YÍÆ¼SW':þÚº*"µtJ€g¦pxQ§yf(h)  ÞÍ×ES¼‘ŠHBD‘I†¶^Wîéß‚laĨŸq52!©xk±žŽedd::>gH™!4¥Žz­*Mb("  BB@ >44зª­‚w–`P¬–„‹GS+& -&>:=^E>6* =?F–†>"""56D誓$b%gX€"§£¢rTIstr*Dv6þ¶¨‹u9T*K!*üʬX6’¯Š†cU $F¿žŠ½Œ.U—›Z5.~ƒ{¹¹wKILªfcbb, :9:3% &Dl-9b颌`80°€U455|B@ )9K)!Dð²˜`t1Á¤–È¢’¾mÀº³/N,šx^š)K&Xp  £€w'J$$^$mn16##A5/&/+1nTJéâØ#:&#!È–‚o+h”jZù¾£}zxÜ¡‹úÒµ¢’JªUFOcP*V W@1"…‹y&}º®Ò¬?þ¿f-šôìî àôI®«;õÓ@i¨¬²"…ç›c“Nrfvh#ºl×_iöךsÙA—Ýg»í†›f¤1×\ƒµ$EÑpH]yzFZÂ&Û7A¥‘ŸgüµÛÿ§‹rÓõ¡b€&1_eLñÚe×Ú‰4hÄo2ÊgùA %n»Ù6‡nž•¦ p|€BH +bf!¤ÁÕT#Fˆ›·di®éÚ€Ûå9gÏ)X'Iš÷[rʺc‰g„C_÷uÖYkà© €g<(i-¾è(‚ŽzråmVòW ¢qᆠRˆªh¦Ùæ«þG`@%ºå'¨Gæév<ŽÖß‚~òG㜘šœrpب,±{ühYEàfë‰6òº¯µÈ§ÏíÖm¼…ÈÛf$ á¹Pˆ9¦™jFP»îVsļ²¶ã‚§"Êv sÙ(c”Ræû[žÚË%—…*מŒŠyYƒÐÝI p“îyb¤øuæéfž:ˆ¯£{l8æºgFÐj»ï¶/½0ÃŒ EÚÚ'~ú…f³ŽF,ñ r ²ëxl{KŠæl}ü8ÐilýIXíw¥«mk1+øqÄ–K2šg²ëªÊð†ín¬-/ñ&Ày ¤tº¦Ù¸u j­²@£aÂ6¦Øsþ ?ËXâãÄCmà°sÒp‘ŒC™í[›Ìu»”¿¶åmÀKà”Ÿmñ¾&R ]h˜x#ÑŒÞ)z—øÑArÀ™àL*4Á-˜â’û¾®ðqF³®ª&Sž¼š`§¬¼¼²rþ2l›Ò ã“&Ü{€C·7áq¯÷ÅÑ7ÒÑ"(Çî¾§±¼óeðïQæÉÊã2󘫩93=0[Ä®¦±I)nqÔhŒ 7e}6ÐQè/Ó˜†‹ºLÀú51¡UkI¼Ú]‹|Å´mrfB^þ$w2•­]­ú{ †ÐIKc JPv•»$ýfuþjà–ÔãÀ÷í8wÈ }œ%›ýLG¼êÝÏ(6µa3½0Y ”Ç®éojš\5 @¶%ô ¨€ÑÛ>µ1ÅIã™o¤0:&‹Ž<’“oH£‹$: ZÄ;󜩎åÓ®f³ÉqÑ‹]Ûbå\•&¯¥)V.Û\  ª1HtM4ÔTc,<®.YDäÑžb4"#øÑo÷éÓÅJÓÀIò‰wìY£æ¢Ð„\‹äñ¾˜¿bÒeg,€\ÄÄb¯I$b ¡ÔÓ‡ƒÝ‘`úÒ•4_‰>"¹±Nªñ^áxÕ>"ªN5Öé%XPÉ/ 3…czåºÆÎ­rTV²ªy£Ù¬OÐIþÝvˆê·!)RRTÔ¥ÐPiѾ½°ÜG«¦j«›ÈŬ€‰\tõf˜—tµÈÑÌi2¦(Àh|5„6ɉzÒ¥«Õ¶5FgP°†^) µ%QLoþ¤jÆ=ò( –¨-uoYä“ÑŽPÉaVÕª$00W€ øÀçè¬6(Lî’H&.–Œ Tªi¾P|SˤGœáwyڸƅ§/H8¤÷„ˆ¨ϧ{3¤þŒ`€þzT˜é‚r‘+„<`™åê9ra†–‘‘ÆñD™KÏÈd\Œu#ÜoòäZæ˜ÆÑzjÛí¨¤™Ì•  iZ¹©.E¤ìÙvåÕÎ’ÁSLb’AWõæ¾ã¹ªøªË˜h#!emÒäY%|Ö~èHý¶ôBÄÚÐc¶ÒÖ—™B  –µB“ßAekÁ¿&ŽÍ4îb0?*&ob”¸sžËçY/ÖÅ…Bæø—ä³ââï®a±  ìÛ"vFS+ •:vÞk-LÑÀ@ƒfNà¹ÈN«àÄ®„X©ÌÔÅå¶¹tœ‹¼ƒVð1ßñUÎIï…Ó‚þSÖ2ì¾».èÑ‘¼{-cËìI/ÒMƒ>_-»"$xos]ië}ºx„†Y «þ•zUþ „Žƒ0îÜYÏ{6ƒË<~n@·´]›Ûõž€‹Nö36ÂòWi&›I{ÊJTÊxhÇl‡ŠOå×(õ$ ÿ™³íüèÈ€ÜsÀ¯~‡^€Ù=¿›»g;W\yÑø]l^B„Ÿð„ì.Èq°ñWwŸ¤3N]©6£w¶nΜCðôåô„g3I’‚.Èä­3g¹mƒtL9àj.‚€9ضl 7·qÖþ×4¶ã|ˆÂ¹O .ipnGÃPeÏ ûy=\‹z'Ó tàwL!³ç@KÞÁÿ%”¦øt|h²`j"+à|”מ4%Ò#úQBDRvSbW#%+Gz~ô•K6bl^…$l-à vkµ·_$C&E=6öU‰@FÅ—L¡•ƒ '/˜3FÌ€ ÏWy.°€d7Ù0gW9c@j#1@@z•UDtgp¼BµB{€ ³V‚y7\í´–° 00ç`†3À0`mr· ††ƒ¼¶&3{ir.aÏ÷¨7!vWÙSv‚Ø-‚,0ç}þü …ãNyÃpJrH†R4, =$(]µ7\Õ€ bP+Љ–p E ü—M`¨Ð†ór ï0f€]•W G{Ì“dÍGy(gEÓ¢ÓÇW‚È8¸ã )>²^ŸÖ{2E· ¤S©´$ÁpFÄ·Y562Лp •BæÂ!Ð Áp‡ñ2d    ·`°‡=`2¤æ`YGy•×.çsg%dlÕ#3qs_à Ef‘t¯gŒÕX×tÌPì³·*é²E 2 X Ö‰,  °g›`E §€ ¨ +j ¹ kÈg•gˆ9±Ò[÷þЉÖi—+‚PQò(Nûño—ñ>@©T‡…[t´S ³$’Çôg×§À Y¥• í §p h„!Eð0ïP’›ðUpgb©=0Ð|°¸EÊ+’·uðæC¾BZÛ"bÒ]ós'úÒ$›…EE>Ts $_„ô^È2!…´9È$6NI :`Kp ¹ .~6ð@té×"sÀZuü‡`ç  0  ªPuh9ÐÃ|ö,PER#J¾Rmy lÜÿ˜z5$ã‘yRäÜP„GàøÔ9vXd0Ep ½þà906ðFð÷p¾0ž÷ Â0¡Éé§ Ip¨ù‚li§pÕ`À’ï'/›$a¸à§q3Äy3…iHØÂ‹ 7¼TBËÖPìµrkãCõ56‚J*²ÐÜ dµh 92`À7B\Àôð ,Ê¢ßy ßÉžâpná[µŠ±¦‰”@›îç`Õ@ïö•8b3OViue“£¤$¦a‚ KPU'Yòsæ^¥äSGy Ù´&VŠ.°›÷@÷ð$Š-ú lʦ´à¦oú ´0§Ï`\ x° Ç0ZU–P:  ªÐRþbuI’÷nÁÐz˜"(,W8ß¡ÅB0F~Ŷ¤Ç^%„@½8ö%”×5@ÐÇgúep` öðÔà \p múªlÊ qÚ¦œ§qjð@ÇÐä°U¹A0­é24C’a`p¹¨ÿa-3éieÓ¡…—vûÁW0b¥ybeÛãTP#ô¥«ò:Ç YPF@¢°Ú¦ÀâÀö@_ö x@ ¾ P«·z@¹pY0ÀŠª@þwÈ3F¸¹H*eà!J;ÄâiäÄ:…3(ˆkãsbe{2,Ë‚¥¡ñqú×p ë ã ®múþ¦îÚ` ö0³ŸÐ p Íð„p Зð™ð-J   BÐÒ£ãdè¶E {V¨Ð›þÁKÛÓaT,ä[ãSbë¥-n³rË©ñˆ=£a#”xm 0D}ð ðª´À¾ êÀê Ñð•b¡Iÿ°°‰@Òp ™ ¯Ïp àæ§›€ þçH´X¨ p 7µt·Ḵ"Þ¡iÆh_ÖPƒ+_Ë‹açCÅB©äC)¢Q çFªPÀ%@t°¯s ðêà šñ¼ÁÛ ñР𢉢tð„õ__p Ç.ÚÔ@ªþv)d’#/ÇÊ­„¤ðe.6¡©U” #±yR­öQwkãFlcoJ>»t½IÕÐ é@°¦ð 5Ú!µ@ð`¼Ý ÷° ÝÀ» œÀñ¢$j h*êÐ „À`ž€›  ‹Õ€{Cz9GD(ÓÒ/sÄ=)L àÕ B ,*§þÛ!âð° »` Öå èÀ IÌå0Šż` »€¼ßIý@„ ´tp^¹†¤*Âd Œ´ŒñQtÓŒ¦¥;ÅS{sˆ¨ˆò3E8œYºbXXt9ÄþrÚ¿â ½À WÅ ƒP N0NŒÙ€ ŽP Å ; Ž¿° ° @Ûx @ ðsPV`È·*™Ó9s0e†T4±Ü¦”in‡e¥1º8WP8³8Ld+IR±Â<½@ª,°¿Ï »ý ÷° P À ‰ìõðËàÙ PÉõ *€ ~ È0 *PÅ æRÍ@¥<帥ÚÊ [õå«, Äœ[LjË{¥HÓl³z!:4cÃ²Ö í - œ·½ ÈÛüÌÓ¼‹LàÚÌÍòà áì©pÒ(þ ~`õ€ µ€!bÀ¦º0·V¬,+s òc€¥0±ãÏr5X=•fI@ÐAbÐPcB„ÇPQ!ä>=c {0Ñ´ ·‘쎀  €‰\?€ ?P ƒ0Ž@ Î)Ò~ðÖ© 40ñ &·  jÐffâRЭþ¼¹†²92~Ö„fê"uìÂ|Òyg§}OmHC“,b¶$ÞÙ¦… Å0Å€ Û<^ Ö° ò0ØÐ4ÀÖ¡0 4°nP š0 * n=á0×0§×IFÅ•9í H%>›"ç;'ãeQº0™BzͶJ4[jþt•öœäk  ó ذÐ0Åå ä và?ÀÒØP õ `ß=ÅÔÞL<?pÒÆ ]€ Ö°!µ |í´Ü5E\¢7s¤:rÌb­3p@äZûÔcwÌ “v:Mú»¥"PD>, íà] аÄR Þ¢Àá@Ù`Íû=­ àÛ¼Þ£à ?ÐË0å°­ ưÆàJ di[eþ£SÁAÜÜ3WEÝ=ê"ÎPaªÌt„9ÃO1Â>dXß¡ar‰ð£Ô pÖÀ æmÛü )`ÉN` òþY NÁ w ž@ÔPB°4àã‹äÞ°×Pª…Ð ÖW:ò;yC(•˜uzÿ¼#Tôàë%l ¶yùM²ÅãuQµ‰ ;@ Ö`.ú¢uðYŽPÉØ Ô t@¢ß)tÃë3àÈ` Éä©PIöÛÁL¡ˆBÓZÆ"‡KèûZIp©Š´yFhP¤³3tÓ>„½::PB  Ì 0ú¤ ¼užŽð Ù@œÁßiBWë»Á )ðÌÞìù­m¶Û%)–._bfJu„¾7Ôså“'wiot¢±R3^öå;[âþ0ßÙïß© ìiì@ÛÌö0+ðBðÅ+ÖP3ð‹Ðì‹n 3`Tý›‡tñÖÂí3ñâTñD„˸è ¯I…+ÕÆAËê/‰ià“úÈÒ 2ÌûïÅ.šg0Ý „PÅŠ@÷¼AǼrÿ¹AÐ Zðó@Ïõ {4í8Üa%DüìéC$~«åt¢ñ˜1BUTåREeKëQ>z@Tb/÷\òÉã€öã° YPÅÖP$úh¿QìgÄ`›àóH Íž ?° ÐVZ2Q*PΩéâ”zÞS"ûqs@õFÚ¤¤5wÎþ9Q¹54ŠLrÐ ºPì)ê·rp®Ô° ¢ÖT0r0ç97ð.À @ YàÉ€òŸ d-<wâhëé–’SÒd¾¡K .8á ÔeD ‘=gÎ9³Gƒ2ŠÊø]äGÁHD‡ :<“$d‘A ò‘ÄÏ$DÙN8%dXëÖM×#:<áÉzoµn¼²¹‘—è{8ÏÐøÈ“5Ô*´ˆ‚%Ù¢dÈB%Ûê$Ç=rÙP`¶2Ù¶$H°® ºúLØ"Äp-bÔ€2/ÈÁI€&IØH]Á(WžA S¡@8Ð$xâçÊGð<Ëþ¹ºN†nå°µ²à( hÐãàÅ{[Ž5;›<ðã±uT\-*æ‘ìË }âËq²]™Î¸ùÇýb̸ñcǽˆK:ܮ䅎ÎE§ÂV¼\?2BÞ8  ¿ü —m?بhjœnà‹ Ox‘a“\Ñm·T~Cf‘6’ؼãJë°½ 3+ºÈÂk¼•öØ¢3úª»Àª+±£ä4Ln¹ÆRziDç*„6R‚OàéL¾Ÿ@¢‚  Á¦‹PR)†ŽL¬‘cœqb;ã‘n„Fˆò ‰dŒñc‘EB1fÃûèC… ËDÈêZë®…Âþ+²:i°=Hð+Œ(Hn$ÃrS±åÌ,¢Á(óDÇèyrÀ 禎A°Y œbêY²žGî¡fœ$€Üé‘x’°š/”ɇ+°xðØTÜ¡»‡Â²Z¢¡Q—äé%ÉB¢îÄë3‰$ Ï4ÉÅírIØDs…Óä£jH´':è %“l°Ag~ˆÕ‚]è !“÷±!6TâxóKdü@æAG>Ú2íÒr1ÐÈt¥®Wƒs ±^ùLñOBŸ5 ÚhÃC N˜Zb3Ƶé"›10s^b᱆.ez,è-Ò&“*mÐ¥Þxîþɲp$àÁŠÝi¥ Œ¡f0ˆ#TQ65,b’EX/6Eаã ;ï®.”Í&@{N6S"$„Ü(Gž6á% :lÀ›*xA'ƒbÀæ2Å´ ›œx±G¼?Ø) èaVˆÞ×yŘ;h´¥†ÜÜnÃÃ"¾z²…;sôÑÏ øk‹#–"¬Ý>CkCÞzí„°ÉÆ‘,² Hä^b®GžáA®RQ!S^‚Š$ègG"a~VV4i~±ÊësÕótô›Ã“9æ';¤õE2ñŽeÈHlŒÑD‹±e°ƒe;èË@+þ’’!P£*ÐàE8ú6 tÁo*è 4˜ D¸ 8×ï²PD cÈ€E j  ø XÒ0Þ"¸$*OÏÊ“éØç’ÄO~ôsVžÅ+µî/á@²R÷’çMÑ©ç¨3»íèÂè‡#~Ï-;—ºPŒ `ƒbòCn±Œld£ŘÇ<ºÐ €ÀÝó‚È19 ,É_X †^™¼àPbdóNüæp‡ÎÏtвU•¬±¬‹ F‹ÂâD—Á¼ï†È‚H‰H´‡;¨@d\@gòjƱaþ—Yƒž®¬G1ÂlübSöœÇ21Œ¤`à û Ed‰´ o(¦± ´¥NÂù[h(A&Á¦%kýªf0#^„(ÄBÆD aU Ské3 Ä$dÃN‡#²±JzæÔ Ø€4Ê‘ 8¢ŒÅÇ,0 l ÂòPAdý0ÊÞ@Ð+be 8A'€mK!÷kÝ~<í\µé¦G´0qM CBÇDµ d2N3ç35 dC¦cäk8º¸\l$%Sè@s“:Vü`? RåaÇPøA¬ˆ„6npÌ‚Ø`Ny(#ô­M0*bFŸ­þ‚5"uÝE4À¨ æb‰9É&A„§Dî›Ùè§-ä‘.2 ÂÙ°î¦W|p¥Àò*œ”su†N¡6<` mx¿;t„e?4ùŠkš‘KØ—±Õá®B ™HZI`œ9í†s¥KœÌë4Ý–µÀ(†‡ëä_@y¢PD¤±‹5¬!&Xƒ"ÂQŽ:ð⻈Ç.°yhA@D•QÿâÍõ€ˆëP–ÿ¢1ó»&…Ó–ƒ°…çÆ°êœx>#œ°=[VïwÎÈDáÂÎKéÎDlX€’®¹­¡ˆx\@ã>»Ø@†x¬þaÓå@=D!г‡#ãçz@ k‹Œ`q½ÓH4JàPNfçŽzyTZ°;ϨèÉ]êR§@F“9ÈÓÛ’U—nŰÀ~0Qøb¦ÉF)|àƒ”b á»ØãM£Þýù …2”á npÄ ê0r®9$x·+·)¿¾·( Y3 ÎA‰<£?¸9‰­f¡­p¢Œèë9X/¡cÄÆH¼–F~H"Ïi¾9¹–3˜€@A¤i É>ª#7 Ë (…Lù"°ƒj{®À:w†¹ “ ÚŠ“a°+hš¦j+±ŠŸú ‚Hă@ŽÁð1‹T¾Zà ID¯^™ÂÙJŽÌ,ÐbñޱIhÉptƒ8X;€†,‡K©¶s)'ˆK2ÏTHô‹š´ID+‹¢¦¡”Ÿ±º&‡©OƒP±ôê±@{‹e:N `QbÌ霄y‰6‰¨IG;ê²l#h#G.; †ÞÙ6 Øþ.™ü ²Òù c¨#0´»ó„øl$ "Œ`ñ/´ø•Ì$¤dK)à Œª³çœ-‘HÎ) ÷ô7h_ …ñ1Òrà› p't¸¸ÞiG)•©R+µR1Mؤ†Z˜€=ÀŸŒ"+¼›¦öÔƒÁªDJ4%Ê€´9>þá€Ù¹'*>u3 „$E¹ƒ ˜hªQ Ëd€¶ÜGà«s%€IDíE Ñ­€ÍYA„SX¨…†h)¼ B»"«p¢7 YÕŽ¬»˜¾HtÂ3Ù•å)‘ï bihz]¸Zø€pH Ph…™A„y°]å7š‚€‰M þ‚ bTc8¨ÔȆ/H1è4HÙ L ’ºOb1†H¯ú¼h‹A;ÎRÝ‹\[-g„É܈lBŒ—À x ‹ÛVx% ý…yP‚¿aæjCMTa••Y‡l•4 „/¨…Zè…Dª>ªYÎÉ$‘3Õ7Éð=泎´¢€hj˜²y+ä µ7Ã@W’¥Z …~ OˆÕ@—¾é‚)è‚_°ƒA(IˆØ ÑEM ¸0yOÀ›4ø‚c(X1PÖhð¤Í$‘ Hàî¸;Y>ŒlΆ¨Ñ¢Ô:ÓÔ…ÉØ¡+¶«™€kY  :ÀRð:ðyèþL±Ghd˜á†yDýôô—Q…y„;x„ <øB¸„Lè…Jˆ† e9ÐØ“JÀ‹Y)g¼JcyÚCN͘tÊÑÉh>ˆ ׆#°ZàZZx†N ‚N_è†{˜G h„. ['ˆ…ë²£™YId-*Oà‚]°‡ ‡t ¸„4è1^(`1à5oÈŠ22ac¾]“ €m•&²Þ³Dü ™!zž¦áÕÜ®½j ‚:H0à…~À)år#"[l¨€)0¥(& P‚ÑÜ9èzè¾M!ÞBàuÞ 1pþZ+L*2ÞªŽAòi‘-üµ°ik>jü&bÛŽ9p áÙ®‡/È<È„4H<À>à^ †^5ª_H*Òí‚.ØwRIsK‡—£{(bzø‚è€tðXâZXK@á´bBê7L¥Óq›”ÒåD¢ãŸþ!P±™¨Ð:©AP†p4`@ƒ4¦{`c<°{È* ‚4 ‚Làå6²ƒtÔÔ£§/â…r!ØtH‡/ —ëY „LGÞX^P1ƒD(3ÆÞrú1A´&²ù9‘¢~Ëà´JÎûGºU­Ž˜€D<áhhåk8ágþ8zÀåc~c^Öå4Èj°e\^á]hæejHfzXæKx9B„&xP‡˜æhH€JPƒJ°„†S8:ó¡ÖQ’1ÔºMFÚMôâPç´¨Ñ9á±M–^³÷¹Ô=pZ8ÆÍ]ÈvèW¶gZøø< †.d^VjC&U;†/e&àc DVæcp9ð€ Ø6äLƒ`KPÖ@ÀhInè…„H8˜ J~EÂÍ5‘¦“ H-Æ@1r¦‘DÐr$#pë@¨ ÆÍÅ@…^¨……Y_ ê:Èzð€§hCÞ[­ö€þ0„t Íf‚Kè®VdEîj®rè6Î>ðaèÉN€hPì@Tˆ€è…¶Z4¸‹˜~OÁüR”.Jâ|±tˆãD<Û×à%¹mŒ^ì …‚Ctl ˆTHkWžl ¾åƒLhj¢Ï>†ÔNbP„J«´8 Ah€hí „×ÎoA {˜c_ð…{HÖZ0ëiVƒ[8K°„duëhëÜN€=ÈıBQOÜiQ¶Ù'$¤;©¹ŒÚp^˜€ZFL{nìhT`ð@˜40a<ð{àj8†®&„tˆjÍÞ€ðg€=0þSЃ&Ï„8„ׯïp…Xd*>]uøijņƒJ¸T¨†/ŒNl5wkÀ¹–Oùd<ÛOcÉ/i _”‘…p1ÈPk5oq4ènï¶ç…Œ†JàhTPƒO(X@ƒL8†LïêKø©î€þs˜„i`òiõo8"p…)çorÈﮦ}Àƒ: ÐýéZˆ†Bhk(ÚÞVtŽÆõÝváFƒ^p «Õª>Ë/©HÂK¨„`BXŒ„BñC¿( æBhåh(ó¸v4XHJ§>°‡÷Vµªnê×&<þ|õiuS0õCHu®æo®¾z †XÐÍXìHseµõÞvððu¶nk³¦øðˆT¹>n–ðð¼X>89û5@©-¼hpKXk³fxC×ÜnvŒ6ák8€[hK0k'÷"–ãtÈêÍà AcPø„I0H uS°‡ ‚Cèo¿„c}X÷:˜ã~Z[¯vívëÿéô4Ÿð‰_saçzjf´ÁiX¾òÀÖèù¿îT:9qK°vAgùcŒpŠÇh4ø€ZPƒW¨„8ðhxp‚­ƒ:(b¬Þì—“÷4¨*‚ù^J3…?§Ïôª&mþÈ·úu÷…i.„ÑWìŦ皇yp¿v•oó Oì0—ð±7ë `°„Dùé‹{fi/ºxðÕô?FÓùï{ èŸö4‡d»'X0Àƒ…¦Bp9 ß€[6jY¸€Ø~àÇwzi¸&h†©'xè·ô´Ïm_xÓ_j¯õ@¸v˜×í‹§ð×7ëH—ÿH†^h1#gŒÑÕç Â>w”1TÆï!? uMÐ¥‹E¡ÑÔêX JŽ£E DòäF4×,ݺÕî‹@Y°ø’‰žLö}¡G¨ƒ r„2Q¡’‰Xˆ¤8Èò hB_Ò¥‚ç*£ýz%ˆþVè@Ñ:vea©ÐÆZ]3j<ò-ÜLZQwÅW5¨\ì9c±œÀ‚6äࡆ ì±t W ¸&CŽœk·î\’µÐÔjײ]„B‘¡¬8`g&; ò`/ujF!L,åBˆÐ¥KQ¿Ò— UÓ˜¢‡ßðÔ!Í\•F‡†ØO PDcÖGTR ZÇ­(V½DÚY0ÆØ]rÙ(×IÍEP‰%–°PQæ)4$Dø5A¥…ˆÊÖ}MBêhWŽ‚ÑXùŒ%}´Â`˜Ó˜>™ (øLb °´èH3¼}S»v2V]‡ZÒÎí츂\ïµUˆcÉ%Š‘¨Í-ycIrÉeW!,œX.¦™ê’a iä½Tji/½´•]“RÖW*«®&‚ÊÝR[Kþ4G¨ ‚ òv&“¤ ,´ð‘Ú˜éX›=Ô¼Vs_ðH “I,(¹Bƒ¶f ¼hsŠÛ,µuE‚Ô®zyÍ–ŽÚœ’nÕ§âe÷Fv ,ÜÂYB bØš¬=Yÿá7“L -ÁrAñ˜öä”ÚéØ#eØVs@5!£b3j¼”c4ïUt¥Ü–›$MÞÚ¥“o¬‘’Aö1ÏÆÁÑôÍ­F÷Ŭ¾–9É4Kܼ$ªÉcqyNaž™ll$e­?cŠQ;¥cS&_ôôňµ”t•VÒŽj€ŠðíÄŠmÐÉó=¨aYŠþô‹êKYŒ4MØâ$púÐ%j½öFŠR”ƒ—Ê´ì°Z€1x0Ns^ŒúĨn‚  ÐúÄcö¤¶OÌÔ Ý9'y¨ÆÜþ¼á¡ÂRy{ÖÇ,ñ6°ÌË,ÉÉ(£ŒÍ^½@^/¢‹ÆADxÚËb¦E¦$ÞºËX˜V‰WÜ,‰‘HX 0( ò£Sjda¿à`ûã„0¨1;Ÿ"„8ÆjVˆ”}ìmÕ€–È~×T0ãy“’ÖxT‰M0‚É» F¸å7ît tÙRŒö SÂ%熘“’·¢Tëlä×;¢¦­ŒŒ¦¥é†œ9þe²Åêô×:2pa'p:=0)(Ôeop3ÀÀ@ðàjä®(­?ÁO*{åµÕ»³ôQt,—c † M Ûã‡$÷ñÉgpᢋ¾ (`àžÐ÷ÄǤҨL_ ÑUŠR?¤„@’­ãÄØf÷Dx€x2ä#h‰xj°*pŒçHpŒcäQ5î™­]ªs^S,@¡wAä‰qGø¥ ù†Á-\ •IT‚5Ü¢¢²„½ìµxg‡ˆÐ€lc— ‡‹ 1PÊ1–}ÉÞ²…‘ÞOª´ghÝUB ÅŠ|™ƒ’æÆÑÐ`þ,ª—]>Î,íЂBD…ÞþöaÀ2E]ia\¢!qNFÜkS‘O ÌìÖg©c4àº/8ŠOpâCäX9¶!c¨¢§¸…Þö§Ë­¡1K5Z žJÄ·gÀôNhV8quÅ:‹ÂÏ $:ÏQ‰&zð•¡ ‡º|''tbÄN@Ñ5H<ÂÄ¥…/’u åŽK>锬T·È T¨R+h96°Ž§XÅÚ¨.9óâ¼€DÈGáÝ‹à±-jÀ°eÏ|ø—$X0ʨT=”Q„«•œù=% hð©·êmö ÜQ?E°Ž GþäÄJåð%KPÏ}ìS´ü­9V ? =JÜ>§øaˆ‚Š™°Ž4ˆ*6´ŠWœC¢pƒfï®èYð™Wf‚&0û6T™îVQ!LݾX•ÚPègô@0Kì£8†?Pë!¨n ùÛp­kp$:Üh'ׯvÀs§ë šaÝ 'ð89ÂbÇ" ` <ÐCÀã?0špÔ€IðÛE-7Dr0ºÀÝ™ûŠ|êÂZðœ#¯½†©7…{bRjJÀc=DÚx“œpÃׂÃ{«¥DíÓwˆG¼ÇÔB‚¸nÇ?~‚0Bí þN@„0Ô îZˆ…µÝmDkŒæ}‰M‡óѪ…wŠj¡}ü-Š[¨×\:âG PÞÔ–ÿˆ!# {h#êîà¦Á«þ˜/áÂ@€60Á1 œÁ+ˆL.!߉¨ lO䀩¡Ò<ÙjÕ Œ|fU W°Ê™=ƒ©Á…¦^‹|‚>Œ°èÁp™‚:¤…©à¾m úQGÓwøð B´ØCôC?^}49@!¼À!ï5Àà àx¬S>í˜.@‘?°á5Ô?±H¹àE¬, •­òôM€é!qÑŸ“„ŸªJ˜Ãþ7¨Ã4â•™‚F…áÈŸåÑßf$ÝqDƒUâ0ÖȄÑÛhÞLƒˆ9ð€ÂÙÄÂ14ˆºB)B0@€Dd½„eÁ0Ÿ¡ÁÇì‹$©ô4ÏßÀˆL Á Ò´–[(£€-)@$àCe]WdËYÂmÃum×v  ‚‘hoho©‘ Â4aQ†ãKˆÑÈäÓÞh  L¬*Ü“º‘ ÌäÈz‰JZx)x ‰vËF°¥X®g3¹L!ý ªØLåÄýbFÃ<Ñ1´€“6@,ƒ’6@¤À€V¢z@ ´ý§+¸ÂN*4ÃsþãbRÊ+m¨|=D—N쟴TÑpPŽTßi‰g31Í LС(ЬÄézd_ZÜ›dØÈŽZ†¤Ï œL¶dD/Ã1\B‘)þ9xÃ2,鋃4@"äÁ ¤ÀrÛ)¾@„cÐð†ò-2^ƒÝˆ©iaÐu§ŒŒ…J¼ˆòÍ@ÍÇ#ÎhåUÊéeÜűŨxG˜rM@ÞŸë6L”2«‘òÃ9 âZËìÈöL¸àÒB4P\K¨,½®ÞsÈÈ€ÍèJäÓ˜Ò½Îìζ—F®mùª¯ wÔQÝ`ÖYÌG ìä:-9ì€Å¶@„n d9h/"ì@”€<ðòZ¡`‚DÊEQ·xª‘u)²E½‚ØMu†J¨àP½É쳌ÑA†Ñé¬D^CiÔÒ.'±ÐŽâEó¤LÍ}3à’ÉxK5ÁSt×Ùþå"T@´ÔbÂÆ–Ø!d— `«=š" 4@ N°ª‘õBüýF -dgKL(ñ¨ë¼Í A¾bÑAŸfä­­Ò‚à>Æ\x%mŸŽÆ À¾Ì¡¤ *T LGøˆA¸@üäè@ÈÖÁ܆ÊmC Ì^o®·šn)žØ!¼‚¿Î0™âÅ s¨ìj%- ©Ïa¶Ó*©Š*Il¦ÌÎ,£EH°JÄhå5x»jÆ6’æ[°eŒJh8KÍY¹TB´×æÜ`(yeâ:nb?”qÖ,ѱ>…–í)¸PRGf¼.‘ô1{z7Ü‚ Â-¼ÂaÏþþHÊHžÄëäI$¨ˆLlW ØYá4¢üAJ™’JÅ: s!ˆ4¨\”@ü=$–=¼Â)¨ÁþáB–[Ê‹ˆ;‹A?àÔH|,ÉY%À“l31EÝt¶Ä-œþ*PÀÏ|äm3KäR‰ŸY„çhÜ[ÒÉgêYÆ\PÙSÀða%jA àã\ßö\ã£nƒ!>bÁ\×¶*¬Ð[`‡ôAa øq< 0+^37¼‚ Q&Cm£—fuV¯ÀÊþÓe\ò6‚DGc¹LQ>ß¼HÕHà Ü@ @<@DÁ¬C#x\ð8AT@@À¼9°ÜE|Ümc‚cA<±áôƒeQÉa”lgÒþÐ)ýÇ.COqՈɜ¨zãÌf5¤xb×R¹¬½†÷WÖgк¡ø‰M•QòèÆ6kû€Ç=À*HäÃÀ09ȃLÁhA#¬ÂD0Ô€&°¼AhCÃ%¼ÅWb˜ŸÚG$÷.n-àïs[TÞ€°Ã•HQeUjŸ£8$5LÌ x¡J\$X÷k‰è§ÝôM¬%\ ü_¢@@@ ÁƒÀ‚&C\Á*È&¼€œ@+ðÀ\_A´h0Hƒ|6bÒecÒ‘9D ¶gÒcÿT‹tDø4äßàÅeÞèkWþ]¥8`ÀØQçyö`.ÊŸxs’Ž®^uJV.Ñ3 °7pbÁ¥7z>DB¥wA1HA£ûC  @€&ÌC¤K‚(x~×v+¤4ªç@Â:È:¨.q†Û:dªÌuŸ­^ƒ)Æ%Wµ÷Õ•=ó“\1!Åìg5X7KñM?•K¬š¢ÿŸ¥_œ@#`$@À0œú0@ÀÀ·?C+À70LÁºc Ä|+tÁ`A`#3Ïl½›¾[¸­&ÀašRÔ¤²¥”]»Ò«ø#q÷î̲¹ý‰e™ÌC"Ó X¿f<ÛÒ«¥dèè†6”€¥û€ª7B h9tþÁ ØB”_A#L&D&Hä+X@Â|mKø6Àéß²§}Ò¡Áü’%è°g"´;ûÎþ‰A4èáÒW¾å'=qÕ‚^Ø“>Ndx5i.×­¤'U'SYŠ¥¢»7LÁhB>Ì¡˜¥GA>°A¬Bذ$t-´A+(“Û|ØB€åa}$ŸY3µ*zxÉÎ÷¡Á9Ö*QÜ<ýû™Y¾÷/=-è…Ý[y±ëC2³˜ ±† ëÆ¥zÇå{°À1Hƒþ9iù:X›m'¸o/¸‚ç#@œ€@$¹(lV!Š‚%Ú5‡^ƒ"Ä=Ê0*ã·þ‘ ZiA¹Å•šJTR£FL¯h0€ü€&-6iæ¬y“E»J>+´ÅŠZP"¢QŠ&A‚@ÑV]Qˆ…¥¡•"D°º5B!K,ª~µÔ«Xbîõë§ŽT?>i2ÙKG‡ÚJ#·î‘'€Ã2˜p' 0<ðxbD‡hædT„£ ™hn鸥èJ5– E{)Q¦Ì›¥g¨Õ® X JPk©R(µj9 ´b*‹B…ÈfµšògµÆ­jý ìðvÆYDsÙÔé„hÒY¨; FL?Pxðd/÷ ¡KÒ¶eúX‘}c4]äÉÈ‘Ÿe˜oÝ Æº]þ05Á¾Za¶÷bB­´›¤1¶ËŠ,ÑzìÛ€j…ë®ë…·hŠK%TJâ/¨ÔÙª*æ, 櫚ªE Ë k»#8ó Ä’öSãR\¸¦Å®ùÀ±¤”rA2úÄ‘éšÌB|m¥.Œ7¥3ð@Zz: ¥¢F#2·@ ‰`Ù¤[ACÞÀòªšJ PÃÖˆÊ7ÞÌlŽF 8 ºÙ ‚Ê+• @¥ó+”™[uaŽE!Ò±÷"2r¾˜ƒ–¯aQ“‚b0=/Ä 7‰bZÌJšôÐŒ°64 Øm7ÚP:Ñž2Ó’@ÄSÐ7+޹ß@Sç§ŸPþ3ª­†£7oD…n^¹q‰[ö"‰9’HB—ÇÞƒTBI1¢Ï…i¹F³Íö㯪^¢‘m¶8H£Æð5õ& 8uÀ Á…¢Ö ¸­©ë.L8ª°ý¯µ“„³ªªBÉ×@ÛõOÎ^cM Bóc‡$T½Å…n¹Mˆ3àPжÚ&ŒlÒz‘ ƒ[ªý³`P †…ép›@36i&_tqR©’BwBXk Dj§ ŽWÞÜæ• Ìg=B¥ç*±äÂ@Nda»]:¢× \«äÆ7[»1¿WD¾±Tö@¹Û½8jÊÚÈÕˆ#9J;eSÏÚÑ •=b!—ªÁT|þeªEUÚ…Z`ycM`¬©µ)0-q•7Û\³’±'6{MÖJ ”ÖŽ`Í×B5é–kC®ÄtØãŒ3€(¾ø3’8CQ_†ìHŽFØCz#ŒP ‘DNÉ^{²wÁ{ Äƒ"„˜Cúó§§Ã…ìuÈÁû=¼gáûè?+1ê¿ßýúÅ8ë{r ho€¯ÐÁûA¿~ð€ à-NÁì½âØ;…®'ë%¢‚"H„@h½ìqO%4! 4@ ”ÞsŸ÷8  o”k#AÈà q˜Cî‡=ôáD!‘ˆE$â¤lhD%.‘‰MtâƒX®$æpP´â±ØÃ*f±‡“Ù¢¿ÈE1î0Œ_ #ψÆ&;proofgeneral-4.3~pre130510/images/ProofGeneral.jpg000066400000000000000000000373731214562307500217760ustar00rootroot00000000000000ÿØÿàJFIFHHÿþCreated with The GIMPÿÛC     ÿÛC  ÿÀî´"ÿÄ  ÿÄG!1"AQ 2aq‘¡#BR± CrÁÑá$%3bðñcs‚’¢Ââ²ÿÄÿÄ6!1AQaq"¡‘±ÁÑ2Báð$34r²ñÿÚ ?âz@% ¤ €‹"Öè<ðÊ:xÞ÷ô8+ Æ1“º‚¿‰»¤ʻ ƒÏË$F²7«¡òÁfXBÛønpÆbÞ©µtÀ-¹Ì ˜˜IZJ ­é„Ìv›“ͰEd–6!#3ÒîÓ׃å†cqy¤€Ð¼¨®áIÂ;ÇÚZ´’0‹³{¥„Ž€âÄ‹-˜¤-Æ“Áë†Y»MZ¯Å]o*¶7= p¨ùü¼ÿšŽ`k­ÜÎ/ÄÑ>AíÐö¿_/ubay{­ç‡%µ®–Ã?±}M>‚•!VRT,AA0žêC~.<à3|ŽÙjc!íå#!A HH6¶ÈuÞô ºà“ñT¢¦¼ÊB_¯¦9š “Á+}%¯æÖÃWå©íXò§…Çž<-´©Àá"ä`ícA²‚\HO™”°6“káQPy¥_›ya´m©PßͺcÔ×€AðÛÓ-iuR˜$Š©oUûÀ>XÌ T¦Âˆ=q˜cÁH~/ªU)/YW7Á/.EÀÂs!¶…n@éòÆB@'h$\ó½Áìµ&‚ÓHÜG‚ZúŒ1žêT¾}xùáô`Ú™ ¤uÀê»eÂol'D̟Г2š lœmFǛᬇÝHÜžŠyÞì‹ØúâÁÖá&élÒ#´îØ-~0^—Bf>Ù76mÏç†9f"êsS„ø–y>ƒÌàõqJŽè íKbÉ· Ä£it¾Ê­gxQ#4çsè?Ê^,f"#{…;­òÂOÕ…>Xd7¥²ãî“Ï™Â4 %W<æÈ9N°I¨JK,— ’’mÉ>€\ý°È \v ,ÈKÝ\”FǧMn,Ôó‹UÛI*R ®Ë‹T¥È0jÔçã<Ÿ‰™ ) PEñº˜rF™èEZŽÄüƒM¬Âim·V\ØÄ»!C¼réP%v*)rSÀ±ر;_h>NɺÇYÓ÷rûÐä!Ó›po ¶ó`¨6¥]Isz½ü“ש~!ŒO¥¬:|ïÉ\;¡Gz÷öÙs’RÏwsp˲¥]Q¤&3ÏÜþÍ_݉«i$¼ƒ˜¦å§ïR„ïŠðþ±£r’}‘ùƒŠò™5kÞ‚lãlpz#÷ÅÛL:›¸+6øõjÛ±RÍEÓ8ÙΘöa ÄÙXŽÞõ!¡Ä´Ž 5[¡êzzZª/aØçÌbøÓ:×½) :¯OSéˆ7hÝ-s)WÑœh‘­N©.î¥#†_<‘ôW$|ïòÂwÏá;è®>ë‹#ð3¦ÿõýÇÔy( q±á#Œ™»”Úâýp¤w–àH²úœr6érú Ýa4p§¹*´é%$$Ûç=ø[ŠG#TòR‹7Ï6ÃÁ¤%K‡!iÎBmÓ ¾„¼6ŽžC `Änãm”·}·ã“…%v‡&#š¢Òá<‡Ô”ƒkã0fC×JÂ1˜ddPA0nœ$$Ü/¥ºá£ëKKÜØëŒzfÄ‘k 3\îñ³¼ùà1Æë´G¼Qª¨i ’9úá´Ú‰¸¸üä¶ß~xHH2@)Q8+qÀ:Ý1ªNæ:žä_< RÃýâA±=p»Ï8» Žçœʹ}üј"P™àÈt+Ñ ]Gò 6£néi¤k^í€~Šo¦mÈô3 –칆n9sü†>Ôà„)N¸.UÐ XÕ*ZE1˜l 6Óm„¥>@kbš'F‹¹JX²G$ù`<½Ö;¯I™&vS¥=ÏÛ°Q¹ÈY3a䑃Z.™AÖ½[­KDh¬ÔQß<á²PÚ >Bç“å× ä}0Î:Œí.T4†âVŸSt¹´¯ö«ØTÚ@*X <r"Øê&†f¬»;ðܽ§¤ÄC‹e •ö=åÆÎ×”©!!@¤’<Ï–'.DÀçnAÓ²°…²°ë‚?>WA´³*¹—²[]ªÒ¦(r‡D&èvªè*jàð{¤%oØ‚ m <(âÂí= ^¤én˜ë…×%ù´ERªÒÔn£":‰gø–缪þa>–ÆŒèWjÐÙC ÆÑ¬ù#.9•#É÷u¬ýN¥º‡€áL—¿h¤ ‹$(by8æ¾ÜYÅü›7I4N¿—Þ¤ªAqj›àºCö·|Ìnñ!+PS€.HÆ"^“–Ùi´}lUz÷ UøÆu–»Ú¨GheÓj«&,i-¼cEi‰=Ù¾Ç;O¨¸¸ò<A“Îú{?/V¿ÒºcØŽ³ZH¿‡ø­òë‹·³–gGϱreOL³-tÕ–áLì²"C ÚU¼…+»t\|;’µd•‰åG³iWͨÓf} ’߃%•Ç‘"6\†Út×õ­Ú67(¤¡*Rm`σãºÈËqÅún°Qõ!3ó4.&Ç—ç]¼–ªÐª®P*­¼Û››)*¿Ä’x8¹¦Qéú£§2©@!}üE$nØ«]*û(öÅ#˜hSrÕZfXš›=Ot–xøÚ=?,XŸ3Q/ð÷ž;'Žqe˜ÍQ ÈU™­"6Ïù›D¸*‚îýÉNF’Ž4²… ŽB±e5iP'×Ò”“õbkM$%Šˆ·üä…ó üñ»†ÉQàà±4‰<÷__ÂÍn~s7‡?á2}Q Û ›})±`\q°½º¸5JïKˆGOØ©´©¹¶Ä¤‚›kŽªk.®ö‰Í¥ÜÉ™ól–ë—i™n©âOªYlmIú X.éŽ}ÔŒÝUÕ}tTìñšjsVõQ2jŽ)†¤¨îP•%ï»üM4°¸¸•€RDÔ÷ª ÊôÙÑr¬%øS.E1´ÿ ‹E|æ)gç‹1zvµP/R>§¢ÖÁÏ`³o3°?ʯr×e¾Ö²XDÚæ(­*Å2åÐÕ±óÞêR>wÄ¡®ÊݽjÔm(—˜Qo†Œ"Õ-ò":œ O,__f¾ æ#¨ëÌðn"¾Y.‹n£È?\Óog¦ ë553²uF–û›¶–¶(ØýBp_øžö¿áX‹Ôöw"Çûj‚ªDí;Ùº¿0ê&†WrËÈríJ•E“Lrý|$ ƒô8ÛȽµ;8jdW²FyÕ8ºw›ªJ‹˜3~SPˆ§T@P3Ùh¿+°K‹S©H$ ðI>Í_jVˆQÿÒsV•M›I¥ÓªóJèoÓÉÿ•hR~X¡5'(äJ¦e^Bí{ êξ£´gl«Ev/pñèìºmû—Z'‚b†TJ’‡HîÔ´Ñôn¬)á¤ý üÆÿ²W+¨`7þf"çF¿Â·»dvcÔ=3D©g<¹ZbåF©T)S„„K€µ•SßqiR‘Ú¶¥!m®+—»ÂôC¬®™I]¶½Å½:ŒKs&¤v‹ìû•)½œµª¿2dÊ„# æx3D¸S!Ùd~óIqJ»FËaÅ-%-©N¡P:2‘#;‚Ͷ•Q늷`K„×ÄómÜ·Ûš>×ùRÄõlHáq,#†ÞýÖv½j9êŽí¹ü*ëêóŸáŠö!h”:z`Þ²gf³Þyrt Ÿu„ÂaÅXþ±(*%_u)Vù[¢(w{mõÀš;Zy aÐ ~7JŠ7Š qïºðø AMîp2c(JJì:ó|œ°ƒÀàôÃgRÓ  Zµx´>;åµmlØz`¤G¬‹,ÛD`ïUåä0³n¸]wÁ¤hxCa-(Ãe @P6úc0“!EÚq˜DŠ(ú“‰qЕ\$ry'ÚìE%D¥=|ñ!šV ‚õÃy4ÿzä&öÁ ÆA+Ò³^ÁD[Šà]Èãæ0á…8žB­~8Á9ô¢—74-†¢?v°Ž/Åñcã ¤´šOb!i@ZÍ¹6Jx¾>@l$ÿ,>nÒ“´ò:á'Ȭ¦˜ÒFÈ„ ÑsW^W©®Î7sY=Açeþ¼¯Ó~Æ]˜ó¶»k.M¨È‡–ÞjSñضX -¿ÏîîmEÈ—S~/Šé˜¨dŽ,qÒd.“æŒ/2DÔ\Ÿ6 Je5º‹óÊnžÒw¼µÝ)A@Y)ô6Ζ\"î‡Ð]“Ô›¤Ôn7' Üš=µUrT´^uÓžËmÆÓü»L£²¨ †”'¾ÄDðB›ïyvVå…*꺮TN)tv‚Èyá°²·¼…nIø‹SÍ¡¯ž).Õ9«0j†¸æLåZuå{ÅQäÃmó~â2VCM@nI'©8…åì¼™2ÄsÊ7#0a·Ã“jÃ#ªÈe:8Ñvc±.°9_Ð ÖŒê•%„7U‚µQ¦35—¥ P£tŸ2:\bÊìß™´‡²’HŸ)ºDìÆ¶ôJóÐϼ¼9±pî(Bz©@*Àt'¥ìß_Ì:UK¬¹F¯>φ©Í½žä–BT«„¬°$ Û¢}BH7Û %kû¹#+Uõ^<Öc×*SÒä¢S¶j[îÀZ‘Â’78RÎä®ÿ l›úl<´¸€ãuçJã¯dÉâˆÃ‹]¯ýÙtj»í¹¯´ÃËZô‚ZI ÒÀ¬T]Iþ¹µ¥'æöħG»Möqö£À™ ¨2Mª»:0E72å*‚žd©\ ˆL˜ßá¥!j ôÇääTÓ6²«kØ lß³k#æêNµP3þDKŸ‰ÒêM»4H.€[Uº¡@”©= I MÒq i1’cä‡ÄÙ¯v™@s ‹±ß”Ú3ìïíØŸZU¡™†¶jR#¯Öò…D¯kRcº‡^Jz!Ý­4—R9ý’#n)iù‘9j„÷q+}FS]Ëdum²,¥ü‰×›ùcô íê쥞;NönÊÊÐÌŽºîp§ËyúD(Á*’üUG Ia/~ídrJ˜ÛnxüíVhÕj|ù+0$G”ênC2[R\mÄ›)*Iå*Aä†1sfˇL¼·•”ê]Ny#þÜÓ˜<üǰ6=—Šov¶‚N%)hmAõÀfß\S¶ý0õ™ÁöBob1É#q;pcÅRʃ¥â­ˆo{A7çî•«r¿,8 ²†ŠÅ±ÍA  ,Ú%*QîÛø¯ÎDŠÚ#¬ó<5S­¶ò‰Wž>™êq{Pxù`¤8¶‚sA²‰¦@@ÚØ¸úã0Í·ÊSbq˜„µ'Î>^Ó{_™0Tž¿Ï}°@¿žÄVælŸ<FéhDaɤ¦ÏÅó¶H†ܤ“~pUð­‰a¼„¥N¯Ëä(= ¤ééJŠR¤Ûëƒqa‚ÖôØ`Tv€‘dŽAãRꛌHâÝyÀ'6vEˆ Ý9 ®Ÿ3S¤Õ™ ˆÜöW%÷› Cî/ŽÕµ™ò´®Ñ•XÔê›2¦Ð ZëX%%A+FáÓ”))±òlzcˆ½øuE ôÇb{äº&~bhÌ“V.CÔly‚+§z¿mÄ0æÃû©mlHê¢á7µ€ZG &möý–£áù ›$ e¤û ýÈ\ÅíÕ§‘´ÿT'šYJ£>òÖÂÒ8[dÜÿ\tÅS¥t*ÞwÌÍÑè1зHÜ뮯cQÛ—YáäŸPÉïWlÝ‚ÅVm>±DQ‚Ì•–‘!&íÝW;V‚•¤É@rG8§4{/Ò¡f¸t HaöÞxô¨Š %Ç?t©k'qÿ™d?,jqå \¬¦GM‘™^4-Z™sI2Kò½*‡sîs„¹5›)/‡¥íýÑwµ$ð<Üãi}®Ú˜2Ÿe])Õ2Œ™™B‘2m/7L‚¨ˆ–#*,±…hq‚¢@%ÂÚˆkmeÔØðuR/fºVKËô˜¹b“± ¯"RÐP»mshPR–¤¬acn Œt(kæOÏyS.v_×4 Tò®xÊÆ=YöêfY2jâ!J…”\¥aGÆ  ÈÈ•™1ÌFÀ“ô#øZذ¡vرï³GÔå~{u:TÈ3£"¨¦dBžÉzVs ÅíÞ4£cpxR –Ú®•„¨Ýöš-s´" æC­®[E-§“Ôß價²¦–§6æ'ÎÙ9‰4¹uE:ÍSål} „›^Hº;Ä8pbo¾}ƒ;hwfד[ÒÍ4…G‘9_“ïÉ|¥]P—$:â›I‚›ƒc|;¨ã†Vö{*Ü…³²]©¡£“½¥r¶gZ³F\ÈY€J¤Jf'¾ÄqPê€ó® ‹ü%G“n¤ãó¥í ÈÔ ÇiNÎt­£ß³ÅUõ 'úÓ%Âá¸õ^ã÷Çyû|å<­++Ó³¦x¨?•’r´û‘žÚnÒRå–:-;P±cæEˆ8áv¶E—š(,Ó63}õJCòŸ)UÉSŠ+$ýÉÁ¾ˆK’žé‰œÈclj¾Wôº J¦0¯x]‡G®<ÃFúÖ˜!Ric­¤ü+?Ï ”Žé­þ^cqÜ…DyK=d#z:áĆ ˆxARÊü-«§–L £hâøãc½ŠóŸä¾?)µY]p¤5¥ .÷xf†CŠñzáÓ\ <[œÁ¡´…¹)I‚ÚåŒÂª€Ñ±W$Œf!ª4Zzp]`‘es|?D´!MÎ#Ñž$’¥t7Á8އT<\|ðbº›Jr·žJ®yç×ꋼõÇÇwØ&ùX!@XŒ ­L”é¢C¡hQúaú–¾âÄ}p2YQ*òõÈ[m’0¼:©Ž “aÇ„ƒa~˜ê7°ï´:î@ÙêM1Ï|Ë“ªÆœMÑî¯-±ÝB.(ú…ž9Zü×æÛžN7ߨ4¥¯R³üÅQE‚ÒOÍo¬ÿôÀ³!¼râ­ºÎgTc[ÞÇÚÿeqvËî“§ÌÏ]Aˆÿã/ÃCd|N%ÅòãôÆ´iÍ6&Nr6x©Ï Èl¥ØÍƒÊAHP'æA¶ ùŒm´Ÿ/½3M”†Pâ›Mj£=Ä2>"–î ã¦å¦ÿ+ãTôãFhz‹’Ó˜³6`ª?QEMkj4Y}Ú,>!bVORoù0þ, áÙîUŽt:z cûÿÔ/^{G1\ÔÄVäR=ÞcñGíÝ yä¤$ Ø^Éð™QƒZUí&Ô £ž)™j»§6¥E-=VyöÒÃ`Ü:P,mnA“Å¯Ó ê†šå9È•(´êcSg >©ËS!G $}}0G*{'õ‡ýß›"g¨1éﺖÌÈä)+<%I¹Ç>dy‘‚Ö7ájA½máIíx΄v­÷Ûo­Ðúð¥ÚÇí,Ìy‹Táꎚh4Õ4j²êUw^j¢±ýgr†ÐZ6øÔORqhé÷ô‹ûPdVÚüw²¶MªÅd€ƒ¥6*¸òÞ èý0©ìeí²4áüù¥uÜ­™¡4ÝÕs}ÖWBNĬ)µk­&äXuµ Ù‡íGOyºgdY“XeÄ¥á0RŠTVÐ}$+P xèn“e1PÓŠö€@5ÅŸçtL£Õñ%{^âÛ;éµ…|ë?·³Û¯C+½ždv\™’ë5ô2Û•Õf¤MŒ–%·Gü•âBT‹~?!ŠkPtÂ<7q¦CŠC*º€àxzßƬh7jnÅ5¬µ{Yh›ù“[uè´YF£H’ëA pGyÕ£…§•9‡¼ñÛL¢i³‘(u¤K’óØGt«ž¦ëßóúãQÒ<±i”,’hÚÇu³,¹cQ$€9x³¶ÜÛ­ÌT— ×fFq>&ßP?žTûÖ…¹Ûnq)©È5Ê̺«‰6ò—ÏÌàmN–’¤E¹ã΃ ùZñ‰Æ £´ÖÐ%·æÆM÷%ÖØzièG‡Œ*¨Í6\Û›àÆQªÐ„f©ŽÊ À[ôÁ6`¨zy[XŽÒ$í†DŽÉozzÏ>•8¢¾PÔÆl$nëôÆaó,¤ã0¿Šäo Déñuwp0U¸¾ìöòä`ƒ”Öš!hxû!€YOx;ò5‘\!6 2€#ÅôĤ8›ùÛ¦>7>½ÁtÜR„’b8ãÞÑÂëXî髸øQ×®<{ÒÖ¾¶˜÷ûU.ÊOp˜i HÄ k©JœNÉ¿º%õíèyÆóûD躗žÛ`Y…Ñá­åŸ%%×þ•! Dp7¨§•L[½ûNj¶‘ê½n¡¦”(òèÿ€:ögbH ª3kJ[ZTž[W|ãhÄ~Ûx·[“˜Ç21iΟÓz„sJv·µ.µö“ÉNæm:”vD†{‡R±¶÷K€¸cJêUª†•Ì—.€Ãˆ&:› †ZBH#q$^ÿL_úíÓ,Â…e]G¦¾˜/0žò[ }Ý*ºÒ9°'¨ôè0;µ>žäö²;™ã(T¢Ï¥ÔRáO†°¶Iéb?":ƒÁSK'ƒ3{­ÇP“¨Aø¬w@ú­EÓ=:Î:‡S«jÝR¨cÓéÎî}‚T¯zctû jrºïà”©†\E$!Ö@ZT…Šc¨ç^Êš0½@ìYž CEöa©ÖRmÅ$›\ ±sû »?Óé²Í™¶Gp°¤¼®‹&ö7ó݇²¥a…÷ý¦‚¨é¸ÒÇJË?)Ò¸XÐÆr]µÿ+Q?¥t¸ñôÃE©H¶åWk.ôéf"þÃZ 8H Wãœo¶Ó¶Æ±öÁÎù>VlÊhYb‰Iv] –Ò‹ƒ%A.¼ó†Û”}Ý ™$ãFšœ’D‹â혙8°†È(¬>Vn.fcÌNºú^È´E6c)ƒòÃRÙ(¹ žq剛‚ý0ÎK‰*+R¾Øq|û¨ºO•}}mpoé†3¥(lèqíç’âü=pÞK+uÀ~Øz6ÊU䓌ñïå›ú༠ËCV¹ç -¶,|z÷€aÀÓ6NËÌ&2œL–{ãbzyf-eÕoK–úã1Ñ@]ÖŒ{Ùuò1ñÉ S]ÚUϦ¥•¸~÷—¦=ƒ=×=à0²‹ð­¼ñÂÂ0xS2iä§1’.‘Á=p»í’ÝÒÎØUÇ Çe,©ßÚ(|$§<~¸o6¬ÛqTc4”GŠB'áûñæbeJë ¯uçbD7}ûn›6Ip‚ž‡©Á\§©æÚŸ8ažñÅϨ³m¸wŠNósð¦çÎÖdUYÞÅ-Òíø )IÜ‘¨Ãœµ§ÑêÕX‘«³„S-{YŒÚ·¼àþw ææÿLX˜jäu}Õ|Y¬#?á/T§¬R—Jd´«†¤2•®Ã›ožn:uIµÅŽ/Ÿg.ž;UÑ^ϲRíÓŠ\\©.§ìb°Oö†+J¦F…=.™ÌEŽm p8°éço?ž/>•øk²þ¨eðéC¯Oƒ=––9Ü}•~WIÿ׋\ÆÆ†µVG’rfÖþéæEÈ™†‘L©9UµX)`© mQ¸>¢ÖÄž¯žëù–ƒ'.6†ÍAar!ÅJƒ/;ü{R —óµÈàñ‹ƒ±ý'.V4E ´¤Ÿy~ì¥yoùñ‰wg]/<-s£ 1Óu.Á=}O·ž›g[Û¿š·ÇÍËÆcvÇ·!T9Wû[èî˜ÌÊI_~¨³&ÄŽ²\Hëuó°óÏâK¥Ú»í•Õ;Jt‰èÔvR/.DK².x%d§q<ÛŸ¶(hV±ç=AÕZ¾lÑúåJ——!A¤µ ÷P—BBõ‚¬žùM÷… \^äbÑö"ç­Z¬û@rÝSõ ¯WËðò¤¹UÕYï8Ã@§ºa²•+açPBH6±P× ¿á¼FÅã;v=È¿dÐø‹/Pc\á[¦‡Ðß¿e'­W;}ö‹›þ‹ë£æXh§kÔ̸¼iï-á=,¢—?³çƒÙg±ÝJ²[9FÈñi±›`*d¹ 2gÍ!@€ô·n¾HHgºi[n[ãÖ(y? j|Êm1Y§“Îô€›Zâßc'ööíÊÇ*© §6ÌgÿyLoúÃЧ\l|qQ´–NfNQÕ3É÷ZmíÏYgRufDL§¡@‰ …ÊARùéñ¸®qªŒ£72Kj ,²ø¿zä—v 6b²zøor&×6ã>³ÌÄ0Ïz£"bŠz’.<þ¿ËÆÒöZ®@y”x› +l€;Ä«…¤óæ K-‚G9¾jœÌør ÛʘòfcÉo²Šó „ÉÇ~,Ö¤4å­¸´¥'p¸ºIÜ..Ô$.Ê@#foËYuÙnD§LiKBR°Ú‹j†äž>Dr<ñ¨RX«)´Oy%L›¦ÀQŠP²ˆúž1TÜWX7oå=VcÛó¶”Bxî¸\¯»7ääøfhu—]a“Õ-#¾ ü)ãêIúàZhu7]y¶»µwW ­a½ãå¾×úuÄ]ï„äYp²RHÀççnŸŸåƒÈy‡YJÜi)¸Üñé„Vјê‹Ê-¤$‚nGŸÓ —ÔxLiÐDw’ü&ã°¥Ò,8°ëþžiœ(Žj~V¿ÙFum÷ž"O…<|¬N\xóc’·ž‹±¹Ã<‘1,jÜ$X†Ý oÅçà$yô¸á:š}—‰%§ÙX™â6æ»Â››ÞÛG8£ÙÞ¡’ëÓ²â¦í‰Wk¹|)#j†à¡çê?\Í6¦û«Ç­ÿïŠú¬—Z”™lH² SÈ÷ÀqÜ@Ù@Øî¶çLµRµ–ÚB†Ý¥VHAõ78ØŠî¿ÿ¡žæÐà?º·™KÒêM”Ìb,òþ¤ý¢wM¤™Ýº[J÷„ûänä#‹5¹sƒfkåjm°„\ðɰû’~ø¹âF‡mºÙaBõó2FËyC¸fSˆujïBÂÉ·‰V7Úß|M½™½–òšsEuó#0ΟßTZ(îc!*,¥;¹#yt“Ç zг´„ ¾ü12T”ÖÑjR ŸøHJŽÐGîÞäüïŠï³~f…”u’šÃ/¡¦ªÊ÷‡yÁ å³oí„‹üÏ®-²!lxÍf÷V~ ÑhrñzÖ63ašV˜À°ÐwïGnl•Ñ~Ù]©u;QªtÆUnSæÓ[m§›pÜ8Ø[gçmªú,zkF›5“øµQµ7…d¾÷(䟰ÆÁå],N{Êb‹´ ¾Ü¨ ÿÆAø~ŠIR>ªËßÛ—Sè’3Э<š—[Š s Æ,]#ÜÝê¯ù¬8ÚoQ$‚6ÙYù\#n¢©Z´–µ3=È­2 p}^ç»mÂ/qùÿ×–=j>Cª¡Ì‘B^gmÔP”Ý$Ûò… š|TGi|m–Häân—ûºîÔ•l6REŠ}-|RIïR¡~CüK ‰¨>åVe9Q¤Ka}è ‘åòã퇳魲¢èiFüqë‡ùÞ$êlSZ GPJ¶7ð•$ªÜú“ÇË ½ n¡çU`.E‡<`šöÅâQ®êHå´¬ ŠýNŽæá¹ÆÈUú`›´åm¥DókÚöûáhôW@Pm`ƒt¨ÞÞ·<ãºÇ+¥í^²ÛtçjMªTVV €]Äž„QòÄO>PZ¦Öä{HŽâÔ¦RŽ‰ä‚Ÿ•—¥±?‹”Ùuà‡G!H$æ9¸¶¼b{)l½„8´Ù Y °ôþwÄ}çdQõŸ8¤$ -¬p>®KâVÓ/8¸\ßcÇÏgÐéõJsh”‘Þ¡%m½ûÈ?Ÿž8Êðv”½f¨^uN­vëñ^ßË*ÍmÊ Ep’¢AW?¦fúä¸l·€ÙHJE•éÏ–#Y}uŠÝW{h³h뱿 é‰Ç6Ô£Ž…« gY9nºÔÆÞRPUgG>!ÐùóœÓšbÔª?âùFÊþÐèP³7I «ÐzÛ”˜ ˆ„‡Þ9>òʼn¢]¤3¶Š¼êòíAICìòã:Ow%‚A-¨ê¨<Œí‡!®;¶Å¦pÎ;sãß„H×\é½Èõ¤kµ‘æ<½*K¯¡’‰ÉG»ísãÚ,~œâ€ŸN¬PjqëÜJˆ´©¥ƒÊ\IÜ?Q‹Ó_»D+U#¦¯JŽÓqØ ´¤øÚQåI_­ùô¶*¦)Ó3¦DæÝ= êºü ?ÏÓòƳ©d=ÍñEPãÿ­rbø6Kzy“GmW§•-±®öÔÍ KAɯ©ª½^{©;†è­ •'ŸŽÆÀùuëlk¢ê–2l¢ì©­ewUÈ¿ñaŠêª\Ÿ~”nãlÙ†Á>`:ùvM–¹²ùQ=O·óÆ:G]eQHçJë<+;&ç8³ZîÞ‘ûKüJW'õĺ›WL†—ß…bÇÄ}1¯r%Õé2~"Ô”8‘¸(_Ÿ^>øœe¼ìºdväæ m²Èèñ$ýºq…%€rrc÷ ÿöUÃʵÿh®\Ò*ýAšÎX®@†ÝJ2^.6âw§…þË… UÁçO칡«šç}Êu¥2úÚRêtϯ”¡Ë]h'÷ñÊ®Î9;S´'´ÎWí/ô²·?0å3ð…ÓžØúaMÙÄ¥;’’—ÅíÉÜų’}¥Ý½;>Ç~NÓú4jzä:}ö[JŠ@à®ëøR‘ñy Hi;qî¬àšÃ¥ûP¶ï9û;;1jv}δL±ÙÓ,DVM\F“HމQ©-è©’T—cÈl2_tƒ±@-§7 ÃìÏ욤Çj5?QrÚ*ï8ÞZ0ª‘MMÄOnm°ò\(_~ó<8¤x $lp"Ÿí‡×ŠþwkQjZcX0Q«3%Tç*RÓÉ’—Qt•¸Pâ—QÞ,%cv,ì·ízÐjÊ]Fv쯜)*SŽÈ§Ê£ft<šLÇe3)ɱZq¥¿ß°ÛÀ«rBÁ;|no´kº[ô‰8Ú둵{vãÒÇ’08æ•Ï”£©¦zµ•“™t‡µeR§ã¿¿•yèòYqM:ûkjÐâ“Áׂ оÔ}šk}—us9èf©5>nV«{©¨3¡2á[o•¤)*±&×êqÓÎÇþßź}—«4ÍQêTÚ¦e“Tv¨ŒÛ6KÅCÛ$©iÚ½´6•%)ðnR´¿ÚßÚB{Jv§®ŸªÎO¥æÊe=RW&aÆ¥0ÈŒ´© óÚÃfýñ×qŇÃ6/d—P‡‘EÍù­n£B"œØyU¹'χ +kCáóãŠò <ªBË+U2i fWéO/Á1’oãMÈý7bX¥µ#jË|Ý_/ˤZ£ÔúÃUHäneÔ­#ÖÆöÿ¯\^É‘¥ ‰q—½·˜JÛ=nàôŬí!À…k0-p!GæÀŠÃ݉'Ÿ§ëÅ )º‚Jüɶ$u S޶¥¡$mó·_Ó×H˜<7½ùäüþ¸ƒOª‹]}Ò ·@ø”›:uù y¬Ô—7rGÌútÆHŒôBP7ÒßåˆÎi›1÷OxJɵïÏéòÁÝE­ÔPŒÛ9ŠŠÒT¢zƒ×õÄÛ'da—¨M*LCߺÎnOB~ǧíˆvQrŽÖeŽý}ýŒ4²³¸ ‡Â[ ÛË%c1FîRüu¡i6)R,AûÛ”»f…ÙK¿¤(Ý}®éEj·_ˆ&À~ŸLEçÔƒvg}ÍÍíÿl=Í5åÊu{o´_ðÀì—–%fê‹nîã1eJo à:›}>X+i­²ˆß•¶QLƒHŸTª.SªJ)È Í[©%+·;ª½=:ü‰ê½A2n5=´¡–ÎÖÛU‡ãÃŽÕ.Ž„1†ö¡ó$ù“ëçq¤©*AÂx>–ùãšÞöÑ;ásž=HÔUÊZ–é%KIéúàÌ,¬ŽçÄÐ$ZÊ=qâŒñYQ$x­nz}.q$§ÊØÀJÏõ ÿ<.÷8%Þ÷3ätTrº¤Åe>ñëR@¾öüüNÒø„fu;/.·M#á7QÛnŸa‹¢ŽÛï<_C),¥<§T ²‚®zZüaÖ@ìUŸõ×)Öó®ŸW詤Rsj93¤:‡\zC/¾Ù KdmÛ`’G6ã‘Èd³E{Ï{ôÒè÷ ׿]Œã}Í_(Àu’âAJ‚©ñÖzô¶Mñkç\¨ìJæ\ÌJ\EQ¦ Í[hq¡a!iB¬l¢Ž ØãY¨:E틚(”ý!oMæVòfU§S%F‹˜ûÉ%-E ^Cá½à7å6ç‚p3£Û " Z~bìÙ—j-E–Ü–¥æ&ƒÖÉ)á™\ÛÒÇ óŽC,Ò/o²ÐÅ+a˜¾Ýˆÿ*éÍÙnRõ~©i5J|ˆ%òô5>¶ÒÉXSªYJä‹‚.°Ÿù°?(i†æ Ã̺’*:«P\‰# Æ- >N´§SábûÔ«Y­'HÔÞÞ91ö¥fßgd¯Êe}ãµÎL}ÇÈ^ñ½`)+H6²H))ãƒÙ{·fxÈqäEÎÞÎ=E¥ˆ=óU)aPìèu>î• 6¸’`énÎ2Ék‡~Oûêˆ&é® öùvÿ}Õi÷³Ç±¦x¡;%ý r=‰ND©ÆS–.¢Û‚T‡’)PVÑáP%)è9ƒÛ'+Òô›µFjÒ AZiùn²ôx-¼­ÊK*Y[W'©î”ÝÉÆýi·A´Û/ɉ;?êœ-ò™T¨H§!õ¼â€+qÅ X%>@¥ Ç<½£¤´ƒ´çlšÖ¾hiœÍ2€뱪L%§™ÌVã8”©Bêîî ¾ÿ[àŒ„èõ~Ч¨E‡'ͼ©UQ ;’xþ;w¿®ÄXºAýãºÊú|ñê³YUrHD(êJ7UÔ/‡ô|¯% 7"«(2ÐY<ªê"ÞB÷Á hµ; nèÅO>´¶Ò ®„?Ï:30 Æ*‹.,DFÉçûD1¤Èb›v¡ˆ•¨›žq#‹U(ePö”îøŽîx¿§Ï ÊR²n‡glçRšSOÜPÂl¤Æd‘ùƒ¾6ÃÙu4KÐÍVƒ%ÄòE´ù‹.£G§þ:56§–ä\’â ¡77ûq&ÑîÐ:©¢TŒÉ‘t¡Æ’¼ã#uS ‡Âc>$6[°;Ç'iâã‹âQµºE#⽑<.ƽL˜¸Õ'©y­T¹¢OTÇ·©¦ŒiNïSÁ²Yô÷›Nîï}®l Ôg¯Ç­ås6m-К£µJÎrâæFÝb#“Ÿu†$wËt>çí"°¦¤mWìd-eÀy<¦Ê]¬»wÒ«qsÝ·PEjµLŸ?(²¹ 3e'»C®4JQe,lée9IJí}ö£³4Ò*SWQl‹8™y&2ÂÅ­bþ®}N9à8“Ei[Õñ‹ZÝ@~ÚvúUy¿Er†xÖTåuÄ“5ÇÛ“K}‰Pª&½)Š.›4©Él¨G*S‘Ö”(‚R°’F.zffÖ,±“süø:ƒê¦[ËTÚ½=Ra@QŽæÉ ~1¥=öÈ䤀”›õååÚ·Û¾M2\îŒå ‹3‚øõ]:%ÂIR{Í©Oybn. 83 Ú«ÚE·#·Vì¤ÓÑ'º°cdiŒX)q=Ò,| ³«àp ½¯ˆ%ìïÕÝg¦ÊòLU½ñÚÚkØëk¯ZÿNÔ­i‘{(¿O¥Õ²ÆyÒÉÌÀ[9qç_޹4éÌøåûÎÆ”De –U¸¾!+ÇåÞT}‰–>Ò×[ùŽ:Ï–}±Ú‹¤è¥gº·³>›1qªÜe¬§Z«²âœBÒò &éq SMÙ+ @îÛ!)Z›Ÿ©yËS3hÉ£P®K•L†µ~Ö4gRÛm[E‰JHI·aˆcv“j«>\\€p(ûŽÿU/•(% DI6¾3 |Ù’Ø÷„TR”xQ|±˜—†Ð« mZH²¯‹O@d“—ç2/à™—(ክ[[º@úY=ž]+‰Tay£ö!_á‰äÑ*S‹ˆÒ±d„­›¸±à×ô·éˆ~p‰Z nÃĵ¼¾X—Ëu,¦é >Ïûð+1Ó)™š’òd¶Q%¦üø­Öǃqò?¦Œéu¥#4mTŽeÊœ˜ŒÆT‡ä9µ¶Ûl•-DØ9$ò0Ž|Ñüë§-F9Ã+I§¢¢…¹o#ÂèJŠUe.±Mî..9“iþv®iV°PõܾÅr`uØ.³Þ¡áÈñ6HÝkßià‘cÅðs¶h§;@VáÖ(ð%¾˜K}Kðõ0ÌvÔGvÃh„ŸŸŒ53ž‘ÉA™ÏHä¤óެ>ó«EO”—A‹ùb?O£Ô+nª}Eâ”X’·H·ùý°êBƒKBTø–ÈSoSþ^m@¿ÊÝðíÚ/À·[s5­nÍB4SS芦PØ „È[<8¡ÐØôþxjЫީR$½Þ8³r§åéîÎRÝ܇²,9¸údY!IKeBå|ø¾bÿ½Ž†y¯÷DÕV²w\mÝ~£œXZwQŽý¾[€$¹p Ëê1Z>ÊßR£²«ЃӮ Ð3;´l¼*o.Zç‘ÀeSh!ÈÍB‚æš½6=n7%g´Žç‚]‰/v ¡Ép‹YÞxà‘ýø£s6y.6 ßX)s”n$[׃‰§djÊ:«q³Žwªª4H‘—¶Í•¨¬©6|¯×Ž:à‘BXÔLx|7Wê·@àµ[Ñì±Xvˆ©.IË$6·¦¸QeGA<‡oÏK}¸ÁQË:6VWwK_•Œ¡£Äu³ÆJT¥¹!N6V@B¶¥w©iôÆž{==µý—µ» R´“"S+b¿’2|6æÆ«T ATö˜i¶–¨ô´÷å;nR‘¿j’OX×h_é ö'kPäiû¹Q+ ÊY±/ŬeЕ s±Ê¢Û¦QïXQ*)X &ÉZH!$/L'(Å«ænäzæXÕŒhóë_~Ë¡•EÕ99)ÍÓzÔæXnº–êðã¨!—#wKqÅ¿vÖ²h¶… <.z)&sž[Ô9Ú”çäùõXÔàóŸŽDTÅ{¨e(*%@!KZÔBP›,%#r­ºØæNqþ’'e¼úŠ —»4jGyB­3SŒ¶*ðY+q°°Rlêî’E­¸\€¡s‡y—úHZžêtLÕ/²&j/åÙÊ—L¾ja\()WxÁr6››í[‰SM–&gÏÉ)+ã%çW%¿ÜG_·~9]€£ÄDèÏSj4öû§Z(Sj*XRH Ü’n9#œ~ 5{LÝÓWÍfXw.æIÔ×7\X}Æ™óOéŽþj'ô¹2&• r¤ö$«M÷ÐáJ[Ï-#fÍ Þñ]ÂÝzc†}«5.öƒí9¨û•2³´H9ß9Ô«íQßT|’ä…3½ „©Â Àæü¦°ÝÕ¤q·!šÛ²ª\§2••:Û×_ˆ«¨Æ`Ñ¢3 ÷ÉR‘»•~¿ž3øõ¹û(þ'ÉGQÙʼºbÀìç-)‘YŒUÊÊ‚~…â1]I>£ç‰¾ƒ1ÜM•RÜw>’Â@òL1’沫½~©GDé#pWùn¬Ê”Õ’6«çoïÀYuE²I¸²Óbvúý½0â¨úÐéÚ²7$§çéˆídº†Ô£`oɽì~\aXÚH±©µ"œ§&/c×QY۷О:O©¹uª•,žÀUÒB‚…î úâ!”—¹afä…qõ·ùbË¡”¾ÐWrŸyéþìÏ ì£3¼•U•òE'LäÍÎõB€¶´@mIµ”I_—sˆ¬Û"­˜Þ¨©D©Õ]ljýßáu«ÙÝüÁ˜\£²Ùj4WƒûÄy› ËTÄ„-vï{¤zþXi­%ºÉN5¤·S¹(Ѭ8´†™)<£äq1J[€UÉ;AUý/‰„:fɺy ·Äpn™LÄ·¼’ ®yôùüñÇL@ÙqÓ–”z‘§è§”©¶@°¸°àO,O2Å ÊZ)Nâ.GCýþ¸VVžu ‹/ ½¼À烂paÈOwÅøµÏ•¾xQòr”’W8"ÔÊ;‘€eDíDž?ëé‰5˜Ú©Êi — ío+ ñÇ÷}p.•-+m.–ì•M¾žƒ(n-°@®-çþ®q%$ââ©Ô쩚Í&œã„÷qžq)ô Xý~_LU­FVàT-Î,Ô3—'TS jkH@ù¥ý¾/ÓWR›óŽ@Ùlústá2ü¿]ÓÄ:Ý3擌ÂþöV–WÿÙproofgeneral-4.3~pre130510/images/README000066400000000000000000000011651214562307500175570ustar00rootroot00000000000000$Id: README,v 12.1 2012/01/11 10:55:34 da Exp $ Icons for Proof General. The images in this directory were made with The Gimp and Inkscape. They were created in my spare time as a donation to the Proof General project. The images here are released under the Creative Commons license, see https://creativecommons.org/licenses/by-sa/3.0/ The Inkscape-based search icon includes portions from Andrew Fitzsimon's Etiquette search icon (under CC 2.0). [ Inkscape-based icons forthcoming ] Note for developers: the sources for images have been moved to the PG graphics repository. David Aspinall proofgeneral-4.3~pre130510/images/epg-abort.png000066400000000000000000000004631214562307500212650ustar00rootroot00000000000000‰PNG  IHDRàw=øúIDATH‰íT1nÂ@œ=#Ñì~)"ÿ”ö"%éîJž”/ð—¥J‘I‡}gìP!˜ÆÒinfvÇ6ðÄc"›1›q*?©®’j•¿¸%HR ¶v-N¸Qü³ˆ¿Rãýk‚¤Úøð5&̘ ›…lV„6SÄ›dµ/Fw&Õ®¬åUBë º4^îƒÃÉñšðF;8%êH¾öÎBy袻ÔÒ_5Hª ’/¾ãγY¥p6 +h®ètoa¡¿Ñ}òWÞ,¹WèyÒ9âÀÈŠJ™"²ì™Ïjy`TßH‚$D$D÷à˜|nú*’ê¾õg|â>ñEGlCÌK[œIEND®B`‚proofgeneral-4.3~pre130510/images/epg-abort.xpm000066400000000000000000000016141214562307500213040ustar00rootroot00000000000000/* XPM */ static char * epg_abort_xpm[] = { "24 24 12 1", " c None", ". c #870D0D", "+ c #E1C2C2", "@ c #860C0C", "# c #FEFDFD", "$ c #CA9494", "% c #C28585", "& c #FEFCFC", "* c #FFFEFE", "= c #FDFBFB", "- c #FCF9F9", "; c #9C3939", " ", " ", " ", " ", " ", " .. +@ ", " .. #$@@ ", " .. #%@@ ", " .. &%@@ ", " .. #* $@@ ", " @. * +@@ ", " ......@@@..... ", " .....@@....... ", " .. #+@@ * *# ", " ..=+@@ &**** ", " .@$@@ * ", " .@@@*** ", " ..@-**** ", " $@@* * * ", " ;@ ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-command.png000066400000000000000000000015341214562307500215740ustar00rootroot00000000000000‰PNG  IHDRàw=ø#IDATH‰í”;l[e†Ÿsþÿû8>NŽIˆcB!ŠRÚ…v@\HܶŠÔ•!V6$$a`€J D*C‘¬(´©Ó$-nÛi_ŽûܪJ b˳~Òû~—WqÄE;¬ðö™ÓÓN>ûÂÂô}¯yÃðéƒ 2lËìÙ–éJ¡ûq’A”šF  *ˆâH Ñ—Rw³†Dq:ÐΞ}§:55¶þÌ“'Ï]¹øåÕÉt×ÎòŒ“Ͼ:UÌ—„®Ýk"ŠA„Ð4Ò$Å #@Ã:*…0Ž1¤À4I¢P(äüüâñ¹¹Âñ¢y©öûÉeŒÜ½Q”‚»†ŒJA’*AD¥Z§²ÞÄÎJZî ªÖ;Ý_ˆže×=ˆTš&2Žt=%C”)åÅD.cüiUaÑõ†„QB X¦•‘X¦Á eNÏ—Ø„êBåæêW•Ú›ëwz}Øè{rßÅ4K´\«7›Œ[:cù,JAEToíríöN)†Ð±s&m; ©F·l-ù!°ô×[Ê ðÑufÇçóŸ×¹±µË\ÙÁócÜýk.³å"Ï*cIa”& „ Uø>*7Ú_¼þÙß…EêºN†8¶ÅX>Ç¥Õ&ç—7q!Ã0æåÇá©Åc ü®m2b™Ä©BhqœÐr=Vê]qX%@£Ñàäl‰7ž å{TÖšœ[ºÅ0ŒÉPd„θcÓõ|:žOϲºÙno¶÷?i{á÷‡aP«Õ˜.HfJEfF'Xœ™ ìäøô§5ž=1ÃFÓårµÎÜdœ€ØÔQÉA»}ÿÝÃÄï˜loï±Ó)ùQ½Ýy{t$3ú≹t½ÉÖv'Ÿe¶ìðíRßî¸(…›*Uí Âóÿ$ &'§ß_^þ%ºÝhT»ƒäƒ·>úúõÇò­~}¥Þ]ý±Ú¼²²ÕZ«íô¦Êc9k¡T Uê›_7;ïùQòÅ¿h##vlš™ïºÝÖ+‡v¡kù‚eNH¡ŸÒ¡\Þé«ðÇ›8âˆÿ—ßkr*~ëIEND®B`‚proofgeneral-4.3~pre130510/images/epg-command.xpm000066400000000000000000000105731214562307500216170ustar00rootroot00000000000000/* XPM */ static char * epg_command_xpm[] = { "24 24 198 2", " c None", ". c #F0ECE9", "+ c #D0C1B5", "@ c #C39E81", "# c #A37451", "$ c #966B48", "% c #A97C59", "& c #BA8D69", "* c #C09370", "= c #BE9473", "- c #BB9476", "; c #BD9677", "> c #BC9678", ", c #B99578", "' c #C19F84", ") c #C9AA91", "! c #D1B299", "~ c #D1B59F", "{ c #7C7C8E", "] c #A5A5AD", "^ c #E5E4E3", "/ c #E7E3DF", "( c #E7DBD1", "_ c #CFB29B", ": c #C39169", "< c #D69766", "[ c #D99966", "} c #D49563", "| c #CA8E5E", "1 c #CD8F5F", "2 c #CB8C5D", "3 c #BF8658", "4 c #BF8659", "5 c #C48A5B", "6 c #C3885B", "7 c #BD8457", "8 c #C2885A", "9 c #C88D5D", "0 c #C58A5C", "a c #8989A4", "b c #ADADB2", "c c #CEC7C0", "d c #A37F63", "e c #D19667", "f c #D99865", "g c #D69765", "h c #CC9060", "i c #8B6241", "j c #573C27", "k c #64442B", "l c #533825", "m c #4A3E37", "n c #685547", "o c #836753", "p c #745E4E", "q c #765F4F", "r c #85859D", "s c #AFAFB0", "t c #D4C5B9", "u c #B38058", "v c #D39260", "w c #C28657", "x c #BC8154", "y c #BA8154", "z c #C38759", "A c #CC8E5D", "B c #D59462", "C c #C58A5B", "D c #C18859", "E c #B47F54", "F c #876B55", "G c #CDCDCD", "H c #DBDBDB", "I c #EAEAEA", "J c #78788D", "K c #B5B5B5", "L c #C0B5AD", "M c #865D3E", "N c #C7895A", "O c #D79562", "P c #D69462", "Q c #D18F5D", "R c #A76F47", "S c #7C5032", "T c #91613E", "U c #956541", "V c #9A6843", "W c #A77249", "X c #C28456", "Y c #D3915E", "Z c #D38F5C", "` c #BC8A67", " . c #CEBEB2", ".. c #717185", "+. c #B7B7B7", "@. c #A6A5A5", "#. c #2D2118", "$. c #624028", "%. c #865A39", "&. c #7A5235", "*. c #6A452B", "=. c #432A1A", "-. c #65442C", ";. c #BE8558", ">. c #BE8457", ",. c #B88156", "'. c #C28759", "). c #D1905E", "!. c #CE8754", "~. c #8B6C58", "{. c #737387", "]. c #B1B1B1", "^. c #B7B2AE", "/. c #3D2D22", "(. c #25170E", "_. c #1A100A", ":. c #0A0604", "<. c #010000", "[. c #4A3423", "}. c #A2704A", "|. c #B47D52", "1. c #7B5234", "2. c #865B3A", "3. c #825939", "4. c #855A3A", "5. c #815637", "6. c #6D462B", "7. c #665448", "8. c #969696", "9. c #C5B8AE", "0. c #9A704F", "a. c #996843", "b. c #654129", "c. c #170F09", "d. c #513926", "e. c #A27049", "f. c #BB8054", "g. c #8F6341", "h. c #7E5739", "i. c #6C4B31", "j. c #5D3F28", "k. c #433226", "l. c #85807D", "m. c #BFBFBF", "n. c #76768C", "o. c #757575", "p. c #B2A49A", "q. c #B98861", "r. c #D89764", "s. c #C58758", "t. c #7F5233", "u. c #1D130C", "v. c #926745", "w. c #7D5639", "x. c #6A462D", "y. c #8E5D3B", "z. c #885A39", "A. c #7A5133", "B. c #6B462C", "C. c #3F3128", "D. c #797992", "E. c #606060", "F. c #9E9591", "G. c #A27C61", "H. c #D09264", "I. c #D4925F", "J. c #C68050", "K. c #422A19", "L. c #754E32", "M. c #865A3A", "N. c #8C603E", "O. c #442E1D", "P. c #22160D", "Q. c #2F241C", "R. c #524943", "S. c #8A8785", "T. c #535365", "U. c #2D2D2F", "V. c #676666", "W. c #C1BBB8", "X. c #CAB5A5", "Y. c #B89983", "Z. c #807268", "`. c #6A6561", " + c #6C645E", ".+ c #443327", "++ c #573924", "@+ c #643F26", "#+ c #7E6F63", "$+ c #CBCBCB", "%+ c #0E0E10", "&+ c #555557", "*+ c #F3F3F3", "=+ c #E0DFDF", "-+ c #B0AEAC", ";+ c #A4A09F", ">+ c #D7D5D5", ",+ c #FDFDFD", " ", " ", " ", " ", " ", " ", " . + @ # $ % & * = - ; ; > , ' ) ! ~ ", "{ ] ^ / ( _ : < [ [ [ } | 1 2 3 4 5 6 7 8 9 0 5 ", "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 H I ", "J K L M N O P Q R S T U V W X Y Z ` . ", "..+.@.#.$.%.&.*.=.-.;.N >.,.'.).!.~. ", "{.].^./.(._.:.<.[.}.|.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.`. +.+++@+#+$+ ", "%+&+ *+=+-+;+>+,+ ", " ", " ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-context.png000066400000000000000000000015711214562307500216430ustar00rootroot00000000000000‰PNG  IHDRàw=ø@IDATH‰í”OHcGÇ?y]•øbT´ä²zhs„BRSÖ€°²E¤¡TðP!G/"öh/{)k½vIÚ¢"hè¥%’ƒ/I“àS!&úÈ&yÏ™4!kc¯ e?0‡ßo¾3ßßoføÈ‡Æò8ÑÛÛë´ÙlÏLÓ|—N§ÿl¶ÐjµÚÇçµ8›ÍF«Õêßÿi055õzhh苾¾¾ÏªÕªžH$~9<<ü!ŸÏ'kº±±±oFGG¿ž®åb±ØæîîîbSƒöööžééé7###¯ …‚%›Í‡ë¢J¥r-„øHx<žo½^ï÷š¦µÅãq’É{_!Ä]¥Ry üDß3p:/çææ~/ lmm°¸¸ˆÍfÃ0 òù<ëëë{«««Ó'''loo399‰ÇãÁf³Q,‰F£2Wàm½Âååå›`0(º»»E ªª Ã0ÄÝÝÈd2"‰ˆH$"&&&dWW—lii‘ápX^^^JÃ0¤a2ËH$"ö÷÷ /êÁ`PÌÎΊÁÁAqpp LÓB‘Ëå„Ûí­­­bccClnnJ@úý~™ËådÙÓÓ#].—ˆF£Âï÷ àW¥f’L&éïïÇív£(Jíì9;;Ã4MÎÏÏ™™™Àçóa·Ûëf2t]GÓ4EÁçó¼xÖxãmmmtvvÖãB¡GGG:::°Ûíõ"°X,8ÆÇÇ9==u]ׯ€O?1EQðz½x½ÞÇSïaµZYZZBJÙ˜¶Ôhooï;Ó4©T*On¤ë:¥R !DS”’R©Tï@H§Ó¥R©ŸK¥’¼¹¹yra6›@Ó4 Ãhª3 MÓ ÍæoWVVD±X¹¾¾>ŸO>T&UU•årY6R.—…ªªÀK€O3™Ì—±Xì™ËåBJÉíí-©TŠùùy‰„^.—_ÇÇÇÎjµj©½¦‹‹ B¡kkkòêêê7àGà]³.æ¸âa”¹ÿÆt¯µÖÑÃPòuþõ›>Ðxbø£‰Î c #8B8B8B", ", c #EDEDED", "' c #8E8E8E", ") c #6E6E6E", "! c #505050", "~ c #0A0A0A", "{ c #1B1B1B", "] c #C0C0C0", "^ c #ECECEC", "/ c #A5A5A5", "( c #616161", "_ c #2F2F2F", ": c #090909", "< c #5E5E5E", "[ c #C4C4C4", "} c #BCBCBC", "| c #181818", "1 c #7E7E7E", "2 c #8D8D8D", "3 c #888888", "4 c #767676", "5 c #010101", "6 c #4C4C4C", "7 c #525252", "8 c #030303", "9 c #464646", "0 c #818181", "a c #919191", "b c #474747", "c c #070707", "d c #A4A4A4", "e c #121212", "f c #6F6F6F", "g c #D3D3D3", "h c #FBFBFB", "i c #FDFDFD", "j c #E1E1E1", "k c #3D3D3D", "l c #0D0D0D", "m c #050505", "n c #BABABA", "o c #E6E6E6", "p c #CECECE", "q c #B8B8B8", "r c #0B0B0B", "s c #565656", "t c #222222", "u c #B9B9B9", "v c #FCFCFC", "w c #FEFEFE", "x c #EBEBEB", "y c #3A3A3A", "z c #999999", "A c #9B9B9B", "B c #000000", "C c #494949", "D c #B2B2B2", "E c #131313", "F c #2D2D2D", "G c #C5C5C5", "H c #4A4A4A", "I c #303030", "J c #393939", "K c #E4E4E4", "L c #171717", "M c #797979", "N c #939393", "O c #C7C7C7", "P c #404040", "Q c #BDBDBD", "R c #868686", "S c #F4F4F4", "T c #9F9F9F", "U c #F6F6F6", "V c #AFAFAF", "W c #FAFAFA", "X c #3C3C3C", "Y c #F7F7F7", "Z c #F3F3F3", "` c #959595", " . c #EFEFEF", ".. c #636363", "+. c #333333", "@. c #E3E3E3", "#. c #D5D5D5", "$. c #7A7A7A", "%. c #F8F8F8", "&. c #7B7B7B", "*. c #101010", "=. c #7C7C7C", "-. c #F0F0F0", ";. c #E8E8E8", ">. c #444444", ",. c #B0B0B0", "'. c #989898", "). c #252525", "!. c #555555", "~. c #E2E2E2", "{. c #CBCBCB", "]. c #373737", "^. c #1D1D1D", "/. c #545454", "(. c #353535", "_. c #8F8F8F", ":. c #D9D9D9", "<. c #A8A8A8", "[. c #656565", "}. c #CFCFCF", "|. c #2C2C2C", "1. c #B7B7B7", "2. c #BBBBBB", "3. c #D7D7D7", " ", " ", " ", " ", " . + + @ # + + + $ ", " % & * * * = - ; > * * * = ", " , ' * ) ! ~ ~ ~ { ] ^ / * ( _ : : ~ < [ ", " } * ) | | 1 2 3 4 5 6 * 7 8 9 0 a 0 b c d ", " * * e f g h i j [ [ k l m n o h h p [ q r q ", " * s t u v w x y c z A B C x D E F G H 7 ", " * I J $ w w K L 8 M x B 2 i N c e O 2 B ", " * I P w w w v Q R S B T U = V W T 5 ", " 0 I P w w w w w w w B T w w T B ", " } I X Y w w w w w w Z B ` i w i ` 5 ", " ...+.@.w w w w w i #.B $.%. w %.&.E ", " *.=.-.w w w w ;.>.B B g %. %.g 5 ,. ", " '.).!.#.;.~.{.].^.] /.(._.:.^ :._.(./.^ ", " <.7 5 5 5 c [.}. ) |.B B B |.) ", " $ 1.1.1.2. 3.1.1.1.3. ", " ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-find.png000066400000000000000000000015261214562307500210770ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATH‰í“KhSYÆ¿{îë˜ÞÜ$MÛhRë³>ê Ç*#Œ£Å'êFÄÇB¢¸ñ¸‘.Q]Ìf¦ŒˆŒ3N]ø¨–‚¡Uc­ª© &M®yÜX’Üœ­³ˆVnúÛœÅùþßwÎùŸ?0Ì÷Fü–b‡wÌìÊñ“dÕYöSÚˆ<-¦†jºýR—Ü|òÀ¢R·{ŸVY=oÕ²úþPÔp«¾êîXO÷¥_7×úê€c­Á•Áh|×Ä ÛbB5qÚ(;™<4*!úª¿7^8uõtÃî¯ Øx®ýå®—ó"‹Ð©U"àQ€‹Ê¼Žß§–¹uéÔ Œ1F†`>cæÜù{sª­V¡2¼:E•“«)gW0Ö&CLtË5-M¥v(''’$í?zæŒy'‘áûs<È <Æ9Ïò œó(ç¼·PàF¢åìÍ{5 }iÀ8ÿ¼fþBnWEèªQ`  ²òÌ”‰Ëÿ\öÞ¾×éÐù¥yj)#ždµt „°È ú×X$Œ?N#Ï»º´ÏÝ@EÑ«¨´V¯œž5kfh¤§4õ.v–hàÝ ±€°ò ‘4ƒ\6z„•iŠBÊ(¥>BÈEQ68*F\¾óàýKëùË@Ûëÿ69¶lßæph#@•Ïãm,†×Á¼é'Ð C:Òp(2Én·û0¥t,Ëët]¯¤¶­Â¡•MrÊnZ½|÷”•›\o¢q¯‘0]¢(â¿ çÑz·×nµ¡/™Á·v£ñ—¿1ƺþŸ¿ßï°&‘Hì1MSóx< ”"[Édòz&“ÙkšæÃ9ëvŒÚ•z¼k¬YßÛóøÁt«€”•ËŠFðÙ£@ó•yè}A|åååG|>ßϪªVØl6€‰D"ápø™a‹Š5HÕôšÉ Wõ–­î}ÔΈ$%û^ c #E4E4E4", ", c #DDEEF6", "' c #95C6DD", ") c #92C7DA", "! c #93CEE6", "~ c #BEE7F3", "{ c #AEDFEF", "] c #BAE7F3", "^ c #A5C7D0", "/ c #97ABB5", "( c #A3A3A3", "_ c #BAD9E6", ": c #B3E0EF", "< c #B5E5F2", "[ c #C3EDF6", "} c #CAF1F8", "| c #C9F1F8", "1 c #CFF4F9", "2 c #E0FCFE", "3 c #C2E5F0", "4 c #F2F8F9", "5 c #FCFCFC", "6 c #D2D2D2", "7 c #53595C", "8 c #A3D6E9", "9 c #B9E8F4", "0 c #CFF3FA", "a c #E1FDFE", "b c #E4FDFE", "c c #EAFEFE", "d c #EFFEFE", "e c #E7FFFF", "f c #D9F2F2", "g c #9EA9A9", "h c #CCCCCC", "i c #FDFDFD", "j c #898989", "k c #8F9E9E", "l c #C8F0F8", "m c #D3F6FA", "n c #ECFFFF", "o c #F9FFFF", "p c #FEFFFF", "q c #EBFFFF", "r c #E4FEFE", "s c #DBF1F4", "t c #EEF4F7", "u c #FBFBFB", "v c #99A2A5", "w c #B7D4DB", "x c #D5F7FB", "y c #E3FEFE", "z c #E6FFFF", "A c #F6FFFF", "B c #F7FFFF", "C c #D7F0F1", "D c #95ABB1", "E c #CED7DC", "F c #A6B0B5", "G c #A6C5CD", "H c #E5FFFF", "I c #F1FFFF", "J c #FBFFFF", "K c #EDFFFF", "L c #C3D9D9", "M c #444A4B", "N c #B1B2B2", "O c #F9F9F9", "P c #DFDFDF", "Q c #B0B0B1", "R c #CACECF", "S c #CBD3D6", "T c #C0DDE0", "U c #DAF3F3", "V c #E8FFFF", "W c #E0FBFC", "X c #ACCDD6", "Y c #41555E", "Z c #AEAEAE", "` c #EBEBEB", " . c #909090", ".. c #3F3F3F", "+. c #363C3F", "@. c #93B2C1", "#. c #C9E5F2", "$. c #BACACF", "%. c #7D9297", "&. c #D4F1F4", "*. c #E3FDFD", "=. c #E1FBFB", "-. c #CFE7E7", ";. c #B2C8C9", ">. c #99BECB", ",. c #A7C0C8", "'. c #5C6468", "). c #7E7E7E", "!. c #444444", "~. c #1D1D1D", "{. c #222222", "]. c #292F31", "^. c #697981", "/. c #D9DCDD", "(. c #ABC3CF", "_. c #92B6C4", ":. c #9FC4CF", "<. c #C5E4EA", "[. c #899B9C", "}. c #718A91", "|. c #4D6A77", "1. c #5D8599", "2. c #B9C8CD", "3. c #A7A7A7", "4. c #FAFAFA", "5. c #D6D6D6", "6. c #979797", "7. c #2D2D2D", "8. c #161616", "9. c #353535", "0. c #282828", "a. c #575757", "b. c #D4D4D4", "c. c #E8ECEE", "d. c #747E83", "e. c #394E58", "f. c #82A4B3", "g. c #4A6876", "h. c #4F6E7D", "i. c #486775", "j. c #5A6970", "k. c #6A6A6A", "l. c #474747", "m. c #3C3C3C", "n. c #424242", "o. c #464646", "p. c #4F4F4F", "q. c #D6D7D7", "r. c #EFF1F2", "s. c #D1D6D9", "t. c #CDCFD0", "u. c #DBDDDE", "v. c #7C7C7C", "w. c #494949", "x. c #676767", "y. c #C9C9C9", "z. c #C3C3C3", "A. c #E9E9E9", " ", " ", " ", " ", " . + @ ", " # $ % & * = - ; > ", " , ' ) ! ~ { ] ^ / ", " ( _ : < [ } | 1 2 3 4 5 ", " 6 7 8 9 0 a b c d e f g h ", " i j k l m a n o p q r s t ", " u v w x y z A B e C D E ", " F G H H H I J o K H L M N ", " O P Q R S T U H H z e V H W X Y Z ", " ` 6 ...+.@.#.$.%.&.*.H =.-.;.>.,.'. ", " ).!.~.{.].^./. (._.:.<.[.}.|.1.2.3.4. ", " 5.6.7.8.7.9.0.a.b. c.d.e.f.g.h.i.j. O ", "> k.l.m.n.o.n.p. q.r.s.t.u. 5 ", " v.w.x.3.y.z.A. ", " ", " ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-goal.png000066400000000000000000000020541214562307500210760ustar00rootroot00000000000000‰PNG  IHDRàw=øóIDATH‰í”oh•eÀçyß÷ÞÝ»ÝíºéL¶,M %‚Ô0 K0’Ô4FÄRú #Ë5A“±þJ¡ø¡r™X…aøiùÁläŸ"ÊÚÔ6Íœ:ÛÝî}ïû>ÏéÃjŸûZøƒóáü·s8Üæô\üX‘ˆb’ÀË 3™»A!0ŒCzV ã{8#LÆã,!!Î@QŠø …0"Šb¼Œ‡æÊñð+%änEÎqüƒžéΉ93éÿ#&sw•µY™£Ã#dkË)äóŒåIV$)„“ܼ‰±–êyiR"„FHÍ«¢¢6ƒ„ †zû8}ô>ùƒ£~ëý–âŸ×©3PšsŒ}÷;¡1QLñ¤–xܼ”ÃyÏ8ê+RSS Mp¡*IâŽ2¼ñR³|™Hrúèî_º­]ÄÖ¦ lÛÛÊŒê W.ÓѼ“ö}ÉÌ΢QžÖåÛy¿ï^jx›ÖCk‰ExgÍ6}½ŽÒÉQØÿ3?ÜH8j«1AìP3»†('´¯ïbr$¦£y'ϵ>ö¦]¤(ãÆ¥€Ëç'èzú c7`ÍËÙñØ•uœ9ø+gºûñ¯øi) 4]Êêe/²÷ð®]¹Ææ¦­´¿»…Å/䣮ýä¯Ç¼Õ¼‹ÎOÚh[ÛIçá6ÆsãT×giiè ©kàù=«ù°¹‡ñ¡"Æü-³¥Õ,¨_Èæ¶°íå7™‘šò[Ö½@TPv|ÕÉüE É–UÓÒÐAû¡Mìký”² @nh‚¥"5„“'ŽéúUu:ðËqÐÏÐÝÝïMçÇÎ}£§®ŸÐ“W{§Ý?±ïûÝ èkÝ- èúUuÓµ•¯.S?b;µª³œ=×φg×Ñ÷cUsʱê°c]À©áãX'/"Ò<¡ 9zù ¬„4^|€ž–6žØð8Ù9×4àF¨˜1€¹sСŸŠŠr¬+K„˜|Mâ$Ià2¶OЍ$‰ü©#ør÷:>ßBU¶¿NÉóçÙ¾}Kl¤öÎüDÕñ“ëaµ„H"Œ$‰$ÄjLÚy8_)ÓˆXc| Y<ÿ.º{[ÉÖTbÄÇWÏgé’8+W>E&ĉÁÇC§Š/`EA Æ9|/‰‰lëpš þž{É”fɤg#ƒ?éðàêï[(Å`0FÀ9œ¢p( X± 1ElDˆ`ý"6ŠÀOg "F‘‘+WÕº?™BŒYŇuŠ #85‹‚8Œ§§–Ø8T¡ÈVA%&ð‚ýuoóæ/n¿É¿ØÓ1IEND®B`‚proofgeneral-4.3~pre130510/images/epg-goal.xpm000066400000000000000000000124701214562307500211210ustar00rootroot00000000000000/* XPM */ static char * epg_goal_xpm[] = { "24 24 258 2", " c None", ". c #ABE3A3", "+ c #ABE49E", "@ c #A5E097", "# c #99D08C", "$ c #9CC475", "% c #92B863", "& c #8ABD65", "* c #7DBF67", "= c #87D470", "- c #89D873", "; c #87DA74", "> c #7DD667", ", c #7FD664", "' c #78D65D", ") c #76D85D", "! c #70D957", "~ c #74D857", "{ c #6CD152", "] c #67CC4E", "^ c #6AD951", "/ c #69CD52", "( c #6CCD4B", "_ c #6CDB50", ": c #71DC53", "< c #BAE9AB", "[ c #AEDA9E", "} c #9FB674", "| c #5F541F", "1 c #656D33", "2 c #40522F", "3 c #4D7542", "4 c #5F9152", "5 c #659E58", "6 c #558745", "7 c #65A353", "8 c #5D9A4A", "9 c #4F8C41", "0 c #569B48", "a c #4E943E", "b c #3D752D", "c c #3F722A", "d c #559734", "e c #5E9835", "f c #579A36", "g c #60BF49", "h c #6FDB56", "i c #BFE2B1", "j c #909A68", "k c #A4A460", "l c #859458", "m c #6A692D", "n c #5C5A22", "o c #5E5C24", "p c #5A5720", "q c #565C22", "r c #3E4016", "s c #3C4318", "t c #3F4516", "u c #3E6726", "v c #447F32", "w c #478D36", "x c #69D44E", "y c #C0D7B8", "z c #90986C", "A c #A3C098", "B c #000000", "C c #84A178", "D c #95B785", "E c #7D9A6E", "F c #7CA469", "G c #89BB79", "H c #88B670", "I c #95CA75", "J c #78A958", "K c #74AA59", "L c #6FB859", "M c #7AAE49", "N c #305827", "O c #305E25", "P c #63C84C", "Q c #C5D3BC", "R c #ABAF87", "S c #9EB499", "T c #8BA481", "U c #60785A", "V c #92BB85", "W c #769A69", "X c #7BA86A", "Y c #669859", "Z c #56824A", "` c #80C068", " . c #67B351", ".. c #CFD4C4", "+. c #B6B992", "@. c #A1B49A", "#. c #8C9C85", "$. c #7C8D77", "%. c #A9CBA0", "&. c #89A781", "*. c #86A57A", "=. c #86B47A", "-. c #79A86D", ";. c #8FCA7D", ">. c #5C8854", ",. c #80C06F", "'. c #619A55", "). c #5A954B", "!. c #D1D4CB", "~. c #C6C4A8", "{. c #C9D6C3", "]. c #BAD4B6", "^. c #819D79", "/. c #91B586", "(. c #ADE0A3", "_. c #89B483", ":. c #7CA96F", "<. c #8CC579", "[. c #557C4A", "}. c #44693A", "|. c #517F44", "1. c #CDC8C2", "2. c #DCD7C6", "3. c #ADB4A7", "4. c #98A294", "5. c #C2DDC1", "6. c #CEECC8", "7. c #CDEAC0", "8. c #A4CC98", "9. c #79A271", "0. c #517647", "a. c #D3CDC4", "b. c #D8D4CE", "c. c #DCDCD8", "d. c #B4B9B3", "e. c #CAD2CA", "f. c #DDEBD8", "g. c #DAEAD6", "h. c #D7EBD2", "i. c #D4E8CD", "j. c #CEE9C6", "k. c #CBE7C7", "l. c #CDEAC2", "m. c #C8E9B9", "n. c #C1E7B2", "o. c #BAE6B1", "p. c #B7E7AA", "q. c #B4E3A5", "r. c #4E6849", "s. c #5E8156", "t. c #99D78C", "u. c #D8CFC3", "v. c #E7E5E5", "w. c #DBDFDB", "x. c #EAEEE9", "y. c #E7ECE3", "z. c #E0EBDF", "A. c #DCECDA", "B. c #D8EADA", "C. c #D8E9D4", "D. c #D6E8CF", "E. c #D6EBCD", "F. c #CBEBC2", "G. c #CEE6C1", "H. c #C4E7BB", "I. c #C3E8B8", "J. c #BEE7B1", "K. c #83AE77", "L. c #ACE79E", "M. c #D0C8BC", "N. c #C3C3C3", "O. c #909091", "P. c #CDC9CC", "Q. c #E9E6E7", "R. c #EDECEE", "S. c #ECEDE9", "T. c #EBF0EA", "U. c #E9EDE6", "V. c #E6ECE7", "W. c #E1EBE2", "X. c #E3EBE1", "Y. c #DEECDA", "Z. c #DBEBD6", "`. c #D5E9D0", " + c #D3EACF", ".+ c #D0E9CA", "++ c #CCE8C6", "@+ c #C7E8BF", "#+ c #8C7B3D", "$+ c #A2C097", "%+ c #B2DBA9", "&+ c #B4E8AD", "*+ c #CFCBC0", "=+ c #A3916C", "-+ c #C1C1C3", ";+ c #E1E1E4", ">+ c #EEEBEB", ",+ c #ECECED", "'+ c #EDEDEE", ")+ c #EDEDED", "!+ c #EFF0EE", "~+ c #EFEDEE", "{+ c #EDEBED", "]+ c #EAECE7", "^+ c #E7EDE6", "/+ c #E3ECE3", "(+ c #E0E9E1", "_+ c #DFECDB", ":+ c #DFEDD7", "<+ c #D7ECCE", "[+ c #D5EBCC", "}+ c #AEA167", "|+ c #BBCBA7", "1+ c #C8E5BD", "2+ c #C1E8B9", "3+ c #E1DCD4", "4+ c #CABDA4", "5+ c #ECECEE", "6+ c #EAECEC", "7+ c #EEEEEF", "8+ c #EEECED", "9+ c #ECEDEE", "0+ c #EDECEC", "a+ c #EEEDEC", "b+ c #ECEDEB", "c+ c #ECEDEC", "d+ c #E9EEE9", "e+ c #E9EDE5", "f+ c #E7EDE4", "g+ c #E8EADF", "h+ c #E1EAE0", "i+ c #DEEEDA", "j+ c #DBE9D5", "k+ c #CDD6B1", "l+ c #D1E0BE", "m+ c #D1EAC7", "n+ c #CDEAC6", "o+ c #EDE8EA", "p+ c #EAE6E3", "q+ c #EFEFED", "r+ c #EDEDEC", "s+ c #EDEDEF", "t+ c #EEEEED", "u+ c #EBECEC", "v+ c #ECECEB", "w+ c #EEEEEC", "x+ c #EEEDED", "y+ c #EBEDEC", "z+ c #EBEEEA", "A+ c #EDECEA", "B+ c #EBEBE8", "C+ c #E9EAE5", "D+ c #E5ECE3", "E+ c #E4EBE3", "F+ c #DEEBD8", "G+ c #DBEAD8", "H+ c #DAEBD4", "I+ c #DFEED9", " ", " ", " ", " ", " ", ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : ", "< [ } | | | 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 B F G H B I B J K B L M | N O P ", "Q | R S B B T B U B V W B X B B Y Z B ` | B B .", "..| +.B @.#.B $.%.B &.B *.B =.-.;.B >.,.| '.B ).", "!.| ~.B {.B B B ].B B B ^./.(._.B :.B <.| [.}.|.", "1.| 2.B B 3.4.B B 5.6.7.B B B B 8.B 9.B | B B 0.", "a.| b.B c.d.B e.f.g.h.i.j.k.l.m.n.o.p.q.| r.s.t.", "u.| v.B B B w.x.y.z.A.B.C.D.E.F.G.H.I.J.| B K.L.", "M.| N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+%+&+", "*+=+-+;+>+,+'+)+!+~+{+]+^+/+(+_+:+g.<+[+}+|+1+2+", "3+4+5+,+6+5+7+8+9+0+a+b+c+d+e+f+g+h+i+j+k+l+m+n+", "o+p+a+q+6+r+s+t+u+v+w+9+x+y+z+A+B+C+D+E+F+G+H+I+", " ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-goto.png000066400000000000000000000006141214562307500211240ustar00rootroot00000000000000‰PNG  IHDRàw=øSIDATH‰í‘=KÃP†Ÿ#ÒЛÜü‚tgA7u„n.NiE—6ÁA;ºˆ‚“ÅMAqÖÁåbz 5Æ|Ô:Úwɽ'çyßséÿ)pÝ‹?°¯éÚXFßzàºÛC˜Ÿj€p¸nûæM`7fKLülø¶}PfîÛöÐJ±…É)}¥Nûf–5ï[Ölÿ®TØËaÏèO!"Øi+51û=c:@¥]­n ²€È™ˆd²EHê,ÀJ3 Ÿ™A¤Ö Ã;`:ñ>‹Í øQ‘¥øØê-¥&Eäz6ë}5‰9¯Û½3æcÞQô<޳ŒÈ PÍ.]\7*|þ°MOë¬I“ýSÀC|}÷´¶ WJlµUfàiýÔRla@¬yZ_•™'BîË¿ïògqPã vuXv¤‘òõ *X)†~\®IEND®B`‚proofgeneral-4.3~pre130510/images/epg-goto.xpm000066400000000000000000000026471214562307500211540ustar00rootroot00000000000000/* XPM */ static char * epg_goto_xpm[] = { "24 24 48 1", " c None", ". c #B26363", "+ c #8F1D1D", "@ c #8A1414", "# c #D2A4A4", "$ c #BB7575", "% c #8B1616", "& c #870D0D", "* c #C08181", "= c #C58A8A", "- c #8C1616", "; c #C38686", "> c #BE7B7B", ", c #8D1818", "' c #B87070", ") c #E6CCCC", "! c #E8D0D0", "~ c #D0A0A0", "{ c #8D1919", "] c #880E0E", "^ c #870E0E", "/ c #B06060", "( c #EFDFDF", "_ c #9D3A3A", ": c #9A3535", "< c #ECD8D8", "[ c #CE9D9D", "} c #870F0F", "| c #BC7878", "1 c #BA7474", "2 c #D3A6A6", "3 c #F4E9E9", "4 c #E5CBCB", "5 c #8B1515", "6 c #880F0F", "7 c #E9D2D2", "8 c #F1E2E2", "9 c #F5EAEA", "0 c #DEBCBC", "a c #8A1313", "b c #D7ADAD", "c c #EFDEDE", "d c #D5ABAB", "e c #EDDADA", "f c #D9B3B3", "g c #B16262", "h c #E0C1C1", "i c #DBB8B8", " ", " ", " ", " ", " ", " . + ", " @# $@ ", " %&* =&% ", " -&&; >&&- ", " ,&&&' )! ~&&&, ", " {&&]^/(_:<[^]&&{ ", " ,&&&&{ }} |&&&&, ", " -&&&&! 1234&&&&- ", " 5&&67 89 0%&&5 ", " a&6b c&&a ", " 6&d e&6 ", " %f g& ", " h i ", " ", " ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-help.png000066400000000000000000000016261214562307500211100ustar00rootroot00000000000000‰PNG  IHDRàw=ø]IDATH‰í“Koe†ŸÏxnÎø2®c;ޤD Iš”–D*R ˆ[ÙÁ 6lø”-X±g‹Ø¸E,Jµ‘Ê…@JâVNÝø‚Û3ž±‡«8n•ïö“žç;:ïÿz„~æ„é#€ßîòô¹AŸ;ËO›»Üܯâyˆ’€–ÖQ%ØýânO–x<2}ºŸÁ°JÒÒÎ$HG4 Qñ}pkmP9ûŒå?´`h!æ‚â5A  ®ÙlŠZÝÆŒè´ñÑÓ:’.áÙìCi,Öó£=bD# à{>†!Ñèx|»ü¿lÝfy§„àt‹©d§Ï ­R ¯ë3þdìØRO"á¶ù"ƒæõC‡ò_?îP5‘KcÌбUp“&w 5š÷šháàÃMàÚmdGbzhš»›uÊE—¦#ã"´ý…û!ÖVeœ—&¢„£*Nɦ+ßsÏÍÍGüD ÍîFž¨eUdFbQjͦ¡Swlª¾€+HXt’uÖ·+„Ø»Y(°Cþh*ÉS¹ å£&/->Æ~¡Äå‹“Ôš <Ïg}¯ÀG_}`ÁQ§My½zŒ×÷ÞyýYÿú­M EåÂÔ“é4766)תe‘÷Þx•HÌäåO>¦°RìÉ ôȲxí TÅéBËó(WþfmoŸb¥JÛu˜šáòÂb•¥[[ôbœxh‹çgÑ” AE!gY¼yå Â&R@@ ˆDã1œ¶Ë»W¯žÈèYÓQT ÃàŒa*e1a†+;ynü& K ¹p¿Òbï×­Ó ’Z\4N4¤Ó°]~Þø“çgˆ%^˜™¤4(VlWЧøtÑUC‘ÈŠ|öݜϥ9½ ®Ì §Ø>(Òô:˜!ssò| c #889788", ", c #0C250D", "' c #243114", ") c #62622C", "! c #9B9A5C", "~ c #65652D", "{ c #2A4D1D", "] c #113212", "^ c #102E11", "/ c #153B15", "( c #225A23", "_ c #233E13", ": c #1B3612", "< c #133413", "[ c #0F2C0F", "} c #0C230D", "| c #1F3014", "1 c #808045", "2 c #8D8D54", "3 c #737537", "4 c #244D1C", "5 c #1B4C1C", "6 c #143815", "7 c #113312", "8 c #1A461B", "9 c #276025", "0 c #1D461B", "a c #163A16", "b c #172E11", "c c #142D10", "d c #394621", "e c #5F6533", "f c #395024", "g c #254619", "h c #3D5E24", "i c #32632A", "j c #123312", "k c #235E24", "l c #253A12", "m c #1F4D1F", "n c #123212", "o c #1A2710", "p c #313C1E", "q c #242817", "r c #27261A", "s c #2A281A", "t c #32311C", "u c #454422", "v c #67692E", "w c #5F712E", "x c #2D4B20", "y c #19471A", "z c #224918", "A c #1A4519", "B c #172B16", "C c #45423B", "D c #161311", "E c #121212", "F c #1D1F1F", "G c #292B2A", "H c #2C302E", "I c #2C2F2E", "J c #373533", "K c #6C6A4D", "L c #6D7231", "M c #20431A", "N c #123412", "O c #204B19", "P c #1B3510", "Q c #31382A", "R c #0F0E0D", "S c #20211B", "T c #312820", "U c #513A31", "V c #433028", "W c #513B32", "X c #44342A", "Y c #34332B", "Z c #2F342F", "` c #423F2F", " . c #3F5722", ".. c #103011", "+. c #1F3711", "@. c #13170C", "#. c #343024", "$. c #704F40", "%. c #5E4336", "&. c #A97C67", "*. c #8B6354", "=. c #CF967C", "-. c #C18C71", ";. c #BD8870", ">. c #8E6957", ",. c #1D1F16", "'. c #1E3216", "). c #122F10", "!. c #695741", "~. c #2C2118", "{. c #372820", "]. c #695247", "^. c #916C61", "/. c #564238", "(. c #443428", "_. c #4A392A", ":. c #BD9178", "<. c #CDA386", "[. c #193916", "}. c #393022", "|. c #1A150D", "1. c #211C16", "2. c #3C332A", "3. c #543E36", "4. c #252119", "5. c #1E1910", "6. c #2E2416", "7. c #9F8873", "8. c #FACBAB", "9. c #866C50", "0. c #726050", "a. c #231C13", "b. c #27231D", "c. c #5B463D", "d. c #B8836E", "e. c #342E27", "f. c #221C11", "g. c #322718", "h. c #B09C85", "i. c #F3C5A6", "j. c #F4BB9F", "k. c #826758", "l. c #2E271E", "m. c #43352E", "n. c #855F50", "o. c #EDB59A", "p. c #795E51", "q. c #3E3228", "r. c #433628", "s. c #B99785", "t. c #DEB49D", "u. c #BF8775", "v. c #9A705E", "w. c #4D3832", "x. c #5E443C", "y. c #7A574B", "z. c #BC8B77", "A. c #C3937D", "B. c #8D6455", "C. c #D5907D", "D. c #C29D90", "E. c #C8A492", "F. c #98765F", "G. c #99705C", "H. c #574039", "I. c #694B40", "J. c #5D3E35", "K. c #66463B", "L. c #966555", "M. c #79584A", "N. c #C48C78", "O. c #B0958B", "P. c #AC9284", "Q. c #A87A63", "R. c #4C372F", "S. c #65352F", "T. c #592A27", "U. c #291616", "V. c #442916", "W. c #482F1B", "X. c #40291A", "Y. c #805850", "Z. c #87746B", "`. c #BE836D", " + c #5A4036", ".+ c #825C4D", "++ c #5D4037", "@+ c #79564C", "#+ c #9A6254", "$+ c #835C47", "%+ c #664431", "&+ c #8F473C", "*+ c #946C5F", "=+ c #D28C78", "-+ c #895D4F", ";+ c #624539", ">+ c #533C34", ",+ c #876256", "'+ c #C7917F", ")+ c #E1A591", "!+ c #FDCDAD", "~+ c #F6C4A7", "{+ c #C29C80", "]+ c #8F6353", "^+ c #AA7362", "/+ c #60453B", "(+ c #75554A", "_+ c #8F685D", ":+ c #EBAF97", "<+ c #FACAB0", "[+ c #FED4B2", "}+ c #F1BC9E", "|+ c #8E7663", "1+ c #654D46", "2+ c #715247", "3+ c #9C7265", "4+ c #BA8878", "5+ c #F3BBA2", "6+ c #DAAD96", "7+ c #8E6A5D", "8+ c #544948", " ", " ", " . + @ # $ % & * = - ; ", " > + , ' ) ! ~ { ] ^ / ( _ ", " : < [ } | 1 2 3 4 5 6 7 8 9 ", " 0 a + b c d e f g h i j 7 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+ ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-home.png000066400000000000000000000015201214562307500211010ustar00rootroot00000000000000‰PNG  IHDRàw=øsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœãIDATHÇÍ–ËOSA‡s§—ÛÒ()m(`c$˜ˆb`ÃFIX>#uçÊ…Q1n´ÿ÷Fâ‚hâ4Qî$Q0‘Òò‚¼û¸÷öÎ̽."¯RÔ'9«É9ßyÍ9ü_Ç"»ÕÈX!ðwI–uÃ!IG®IýU@È[ÞBeùUnQ‘Ÿ›ûL$[%+¹Î$¹o†G—7êJ;ïñûê(¥/Nž=§´^½&{*«ê].çk8sû:»ïB¢tÛˆÒV<!GOÎ.,-E2EC{»}ÿƒA ² BiZmi<Ï#–õ¦¶ñ¸ÛSSCâ##°8‡5>Žú¶6ÅURK€¤Ïò–ô”RÚç=ÜWÝÔdKD"°8ðD‰p>’‘`Y» ZUù¤¨¬¬ápk«=ƒ'ëî9cHÅã ’‡0…P!^ƒmmJࣀ¿;Çí¾r¬£Ó©NN"µ°sÅÈfár^\¹¹æL4ÚÑœŸß׿¸8¿m›>ðU\²Ûí[.w9x,mzzÇ–²²W]oCCæà@ÿ7ÍÆ[‘è—M„¼å-6JŸž8Áaw:±8<¼½ç¿ˆ0 èóó( ‰¢(ÊÜÄÄÅæœœ—ýË˳kEîñûê@H¿Âñ¶÷¸®Ã䂱Œ„k¸®ãÓûw’"ŸHÒçûíZ‘uM+²­˜ª.°T œó•6ÌdP ®iŒ¦YYšf¬îMM©TUxW c #DE9E9E", ", c #892423", "' c #8A2423", ") c #C16F6F", "! c #DC9797", "~ c #D48080", "{ c #DD9C9C", "] c #AA4F4F", "^ c #DFA1A1", "/ c #B65F5F", "( c #DD9A9A", "_ c #D07676", ": c #CF7272", "< c #D37E7E", "[ c #DE9D9D", "} c #B66666", "| c #DE9F9F", "1 c #AA5252", "2 c #DD9D9D", "3 c #D17979", "4 c #D27A7A", "5 c #D78888", "6 c #D37D7D", "7 c #8A2625", "8 c #9F4342", "9 c #DB9999", "0 c #CF7A7A", "a c #CB6D6D", "b c #CC6F6F", "c c #DC9B9B", "d c #973534", "e c #D59292", "f c #CE7979", "g c #C76767", "h c #D69090", "i c #BA6666", "j c #8E2A29", "k c #D08989", "l c #CC7B7B", "m c #C36262", "n c #C56868", "o c #D48F8F", "p c #B96565", "q c #C98181", "r c #D49090", "s c #BF5C5C", "t c #C16262", "u c #D49292", "v c #B66161", "w c #8C2B2A", "x c #D08888", "y c #BD5858", "z c #BC5757", "A c #BD5959", "B c #D08A8A", "C c #CB8181", "D c #B95454", "E c #B85151", "F c #CC8181", "G c #C77878", "H c #B54F4F", "I c #B44C4C", "J c #B14949", "K c #B04646", "L c #C37272", "M c #882221", "N c #BC6666", "O c #AD4343", "P c #AC4141", "Q c #BD6868", "R c #B65B5B", "S c #A93D3D", "T c #A83B3B", "U c #B85E5E", "V c #892221", "W c #B35454", "X c #A73A3A", "Y c #A63838", "Z c #B45656", "` c #B15050", " . c #B15151", ".. c #882322", " ", " ", " . ", " + @ # $ $ $ $ ", " % & * = - $ ; > , ", " ' ) ! ~ { ] $ ^ ^ , ", " ' / ( _ : < [ } > | , ", " # 1 2 3 : : : 4 5 6 > , ", " 7 8 9 0 a a a a a a b c $ ", " d e f g g g g g g g g h i ' ", " j k l m m m m m m m m m n o p % ", " ' q r s s s s s s s s s s s t u v ' ", " $ $ w x y z z z z z z z z z z A B 7 $ $ ", " $ C D E E E E E E E E E E D F $ ", " $ G H I I I I I I I I I I H G $ ", " $ ) J K K K K K K K K K K K L M ", " $ N O P P P P P P P P P P P Q M ", " $ R S T T T T T T T T T T T U V ", " $ W X Y Y Y Y Y Y Y Y Y Y Y Z M ", " $ ` ` ` ` ` . . . . . . . . ... ", " $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-info.png000066400000000000000000000013241214562307500211060ustar00rootroot00000000000000‰PNG  IHDRàw=ø›IDATH‰í•AOQ…¿ÎL‡Ú–B ÐPPR jAhÔhqCÄ%K7$„- kMü€Æ¥ ?À ‰K£1‘„H€  +h$i¨D’i‚¡”v¦3.±Ô¶¶qËIÞbî¼sλ÷Îçø,Õmë– ãØ$óùXƒÍ ĵÿ4Áw|×@¼bƒÏ@þl|†ÌæË)HåÅ=N¸rî<G/8šººê­6¶¶Òj,¶³×@~Ÿ@9,¥"–O@ð1´Þ›qt´ÉÉN4Í".,dëÁ僶›Ð/ÃÇH犕„e±Àp.;PøÆåio¯£±±0q÷UsïpÈäžE‰ŒàÁxÁ0,hi‘in¶`{{Š¢qÌÁ› x¶V-êA·~pœž\–FF<Œ{PUƒéi…Hä{ÑÁ½&·;ñÓ¦•Èkñ:ØÝ¿#ù¼Áêjš™™Š¢â÷Ûim•ÿN‡Ûäzí2°K 5õTAÓ æçS,-í#Ë¡«„8€$›\ûÍŸ©q²þ”XÓŒÓU+ŠJ¤ê §A/;8å‘×L®ªW0øv¹(¤Sµ¤Sše â*(«p´^»ÁѺɫ…Ñ“\¿Ö xnƒµ^,øýB¡éësLª(JÎ’Jid³:Þ‚h¢oák5åíqÃÔSx™´Ùæôpx]ßÞ>Ö‰¬¾»›Ó“ɬ¾¼|`ƒï x•4÷ö¸K)Uø›záá°(Þ 4y·S×@ô|&“I/.&·‰×xþ”ý †$ðÝ…Þ8ƒ öWàË;ØX‚Ù²÷BµNt4ƒíds°¹ñluüsTÀ/oéç–'÷2IEND®B`‚proofgeneral-4.3~pre130510/images/epg-info.xpm000066400000000000000000000056701214562307500211360ustar00rootroot00000000000000/* XPM */ static char * epg_info_xpm[] = { "24 24 106 2", " c None", ". c #FBFBFC", "+ c #F2F2F5", "@ c #EEEEF3", "# c #FCFCFD", "$ c #D6D6E6", "% c #AAAAD7", "& c #7878C1", "* c #6969BB", "= c #F3F3F4", "- c #B7B7D5", "; c #4242BB", "> c #1818B6", ", c #0606BB", "' c #2323C6", ") c #4242CE", "! c #2B2BC4", "~ c #1818B7", "{ c #4141BA", "] c #8888CB", "^ c #2A2ABA", "/ c #0101BD", "( c #6F6FDA", "_ c #D3D3F3", ": c #7979DC", "< c #0000BE", "[ c #2929BA", "} c #FEFEFE", "| c #BCBCD6", "1 c #7D7DDD", "2 c #EEEEFA", "3 c #8888E0", "4 c #0101BE", "5 c #D6D6E5", "6 c #4141BB", "7 c #0202BD", "8 c #1717C3", "9 c #2B2BC8", "0 c #2A2AC7", "a c #1818C3", "b c #FCFCFC", "c c #A9A9D7", "d c #0808BF", "e c #7171DA", "f c #D8D8F4", "g c #1717B6", "h c #7878C2", "i c #0707BB", "j c #0505BE", "k c #4343CF", "l c #8181DE", "m c #C1C1EF", "n c #F8F8FD", "o c #8E8EE2", "p c #0606BC", "q c #6666BC", "r c #0909BF", "s c #8686E0", "t c #6666BB", "u c #8282DF", "v c #F0F0F4", "w c #7171BF", "x c #0404BC", "y c #7171C0", "z c #FAFAFB", "A c #A2A2D3", "B c #1515B7", "C c #D0D0E4", "D c #3939BA", "E c #F8F8FA", "F c #A2A2CE", "G c #1B1BBB", "H c #0303BE", "I c #2727C8", "J c #4B4BD1", "K c #A7A7E8", "L c #FAFAFD", "M c #AFAFEA", "N c #4040CE", "O c #0F0FC2", "P c #A2A2CF", "Q c #EEEEF0", "R c #6D6DC2", "S c #1414BB", "T c #E7E7F8", "U c #EAEAF9", "V c #EDEDFA", "W c #EBEBF9", "X c #C8C8F1", "Y c #2F2FCA", "Z c #1414BC", "` c #EFEFF0", " . c #A2A2C9", ".. c #2D2DBC", "+. c #3E3EC5", "@. c #5D5DD3", "#. c #5959D4", "$. c #5B5BCC", "%. c #3C3CC0", "&. c #C1C1DA", "*. c #8A8ACC", "=. c #5B5BBF", "-. c #4D4DBC", ";. c #F8F8F9", ">. c #E4E4EB", ",. c #DEDEE7", " ", " ", " ", " . + @ @ + . ", " # $ % & * * & % $ # ", " = - ; > , ' ) ! ~ { - = ", " = ] ^ / / / ( _ : < < [ ] = ", " } | [ / / / / 1 2 3 < < 4 [ | } ", " 5 6 < / 7 8 9 9 0 a < < < < 6 5 ", " b c ~ < / d e f f _ : < < < < g c b ", " + h i < / j k l m n o < < < < p h + ", " @ q 4 < / / j r s n o < < < < < q @ ", " @ t / < / / / / u n o < < < < < q @ ", " v w x < / / / / u n o < < < < x y v ", " z A B < / / / / u n o < < < < B A z ", " C D < / / / / u n o < < < < D C ", " E F G / H I J K L M N O < G P E ", " Q R S r : T U V W X Y Z R Q ", " ` ...+.@.#.#.@.$.%. .` ", " . &.*.=.-.-.=.*.&.. ", " ;.>.,.,.>.;. ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-interrupt.png000066400000000000000000000004011214562307500222020ustar00rootroot00000000000000‰PNG  IHDRàw=øÈIDATH‰í”1 Â@EߊAÉ,­Ó ’Ò‹Øxo°×Hmé ¬…4Þ Vß" ÑD³™ Xd``vߟÏCü}(ŠRœ÷³W’¤ýà%X-é­ð,^fgßèÜæDà¬ýɸAc \:Y~~{lÈ‘f&¼sy­ôZT“\sÓjaÔÐÅÆo|[wàl”˜;X}¼aÑðQí9¦Ë ŸF» xE$|UÀ¾¼£“­ ^y¿®aÑ >ÄOâÿVŠu IEND®B`‚proofgeneral-4.3~pre130510/images/epg-interrupt.xpm000066400000000000000000000020271214562307500222300ustar00rootroot00000000000000/* XPM */ static char * epg_interrupt_xpm[] = { "24 24 21 1", " c None", ". c #FFC9C9", "+ c #FF6868", "@ c #FF2828", "# c #FF0000", "$ c #FF0707", "% c #FFD1D1", "& c #FF4848", "* c #FF4F4F", "= c #FFC8C8", "- c #FF6C6C", "; c #FF1717", "> c #FF8888", ", c #FFA6A6", "' c #FF3E3E", ") c #FF5D5D", "! c #FFCACA", "~ c #FF7777", "{ c #FF6161", "] c #FF7C7C", "^ c #FFCDCD", " ", " ", " ", " ", " .+@#$@+% ", " +########+ ", " &##########* ", " +############+ ", " =##############= ", " -;;;;;;;;;;;;;;- ", " > > ", " ", " , , ", " '))))))))))))))' ", " +##############+ ", " =##############! ", " +############~ ", " &##########{ ", " +########] ", " =+@#$@+^ ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-next.png000066400000000000000000000002701214562307500211300ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATH‰c`Ã0ã’hçåýïÂÎþÒ…ýïÞ_¿^k#> Є2+?žAK Ȳˆ H²ˆ ˆ²ˆൈ‰DCðéØEM 2+?Æ*Œ3(±€¨TDŽ$åR, +'² “ádåçÏçI5xŒêâ7ÄD°ÇrIEND®B`‚proofgeneral-4.3~pre130510/images/epg-next.xpm000066400000000000000000000014221214562307500211500ustar00rootroot00000000000000/* XPM */ static char * epg_next_xpm[] = { "24 24 4 1", " c None", ". c #870D0D", "+ c #CE9C9C", "@ c #E8D1D1", " ", " ", " ", " ", " ", " .+@ ", " ....+ ", " ......+ ", " ........+ ", " ..........+ ", " ............+ ", " .............. ", " ............+ ", " ..........+ ", " ........+ ", " ......+ ", " ....+ ", " .+@ ", " ", " ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-prooftree.png000066400000000000000000000005331214562307500221610ustar00rootroot00000000000000‰PNG  IHDRàw=øsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÛ4ïÛ»·ÛIDATHÇí”= 1„¿ØÈª(v‚7xà ,-ÛÅÆCˆ°²+ÁÔ¢`á9„œÁV±ŠMŠ-”ì+:UHxy™É›Ÿ±>u¥¬–y•D¢Ðõÿƒ1¡iz4Hîò<Ã.ŽR¾ b‚ðK%*RØ/|K@‘+.oìIEND®B`‚proofgeneral-4.3~pre130510/images/epg-prooftree.xpm000066400000000000000000000014101214562307500221740ustar00rootroot00000000000000/* XPM */ static char * epg_prooftree_xpm[] = { "24 24 3 1", " c None", ". c #A52A2A", "+ c #0000FF", " ", " ", " . ", " . ", " . ", " ..... ", " . ", " . ", " . ", " ", " ++ .. ", " + .. ", " + .. ", " + .. ", " + .. ", " + . ", " + . ", " + . ", " +++++ ..... ", " + . ", " + . ", " + . ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-qed.png000066400000000000000000000022651214562307500207310ustar00rootroot00000000000000‰PNG  IHDRàw=ø|IDATH‰í•ËoÔUÇ?÷÷šßt¦3Ó– -•¶èÂh¢£Q7.ÔàÂh4ưи11FÝ”…[W¸ð‰¢,4ˆbŒÑHˆ’hKByCK¦™Î£Ng~Ï{¯‹*Á?€ïòœ{Î'9÷ä{àŽn#q³àýë´e¤“.Â0h†£ó7}û_ öêXÆ#3ùòÎ[ê×)—žŽ A¾\ÅWHE 4R b­8;U¸®~Ó`¯n˵‘Y›eia™Ó£„u5ùØ–!KIÒ6i35[»3<¼¥ŸÚ²‡+bæ=IÕ1cE¤!Œ%÷ hЄ2F¦c’éÉðÆ;¯qdì8§G/`ìzé9}püË- 7“âÑÁ5<¹c;ÍÂeÒûs0_!¦6°\—V¢´Â |Â8"Ö +a’˦ˆ‚l¦`°ux#y´Gh:RI†6t"î}ŠôºI6=ÙF iPÉ }wQ*Î0=}…(Žˆ¥Ä@Ó±&G.“ã§o~¡<[^?‡eÛà`V‚%•`ùÇ]4¯˜c¾îX.C÷måõÏðáÇû(•f±, G+6 ¬ÇM¹\8~Û±PŠUÀ©B‘µ¹v"©q,e%8tvŽ¿ÎHºuŸFÄ>SçÏòé—³ù) 4¦ ý›6ø!S'/aƒ0ŒU@¥á!µ`}W! -Ÿf™„IsuŸPÄ"¦^«pâÈŸ,.-¡QônìÁ f'§ARÉ]íiº²i~ge à%‘6YöBBeÐ ¡î+êž$RšHi%#üVËÖd:ÓÈ(¤R(’°-R ײxpÛï¿÷6\¸N’d[šjÃ#R°R)×6èÉ¡(¥ídÚ]²í6a}ÛÛ‚8ŽÑZÑhzÌLN¬Ž(›éÀ±-ÂÐG p ‡mCH$¡,É0’˜ØäºÛɵ;ô­qÈÚ>3%‹ùj‹„ãà&\.NÙ½wÿ*`°˜ùj‘( ±,“þž^^|åj¥2_|»(% ‰›u1 ͶÏ¿üõ…<ßw€±W(Ì.P,×R#cõ/ÀúÍ”ÊóÄR#eL¡Rf÷'_‘hK0][¤;¦Ò°H¤\¢†G2éb;9²¹˜0ð˜+V©Ö=yù:û°z»{Éd²xQ‹f«ÁÌâ³µ ɤC+ðèëjC AjM–J±F+aðôö|ýÙa ÇÇ H-JßàkÀßgǨÖk,6–ð‚J®|VK††"’ŠD6Ecq™ÀˆåÊŽÿúÇžçSYXfa©ÅøùéÌóšÙ õ 35›'Š‚(@Ê;4I§¤ÓIrNŒ+%ö}ijϿIi¾B,%Žmß´ùµ5ýíØ!žxèqš¾GGDJáÍ8"Ê¥0Ñôe]~øüLàX^`ìÌeqâ|A;ué–·âºÄÈ«ïê=?Ëï¼»{〾cAS]jÒ "šJpîrá ;º­þJ;&a;÷IEND®B`‚proofgeneral-4.3~pre130510/images/epg-qed.xpm000066400000000000000000000146271214562307500207560ustar00rootroot00000000000000/* XPM */ static char * epg_qed_xpm[] = { "24 24 328 2", " c None", ". c #321D18", "+ c #36201A", "@ c #422922", "# c #432B24", "$ c #38251F", "% c #1F2219", "& c #8D8F8A", "* c #3E231D", "= c #502E25", "- c #663F33", "; c #653F34", "> c #462A21", ", c #3E2821", "' c #37251F", ") c #30231E", "! c #2D221F", "~ c #29211D", "{ c #212219", "] c #2B3223", "^ c #394932", "/ c #2B3826", "( c #412723", "_ c #3D2420", ": c #462923", "< c #502C22", "[ c #784333", "} c #B36A50", "| c #A15E47", "1 c #6D4030", "2 c #57372D", "3 c #442F27", "4 c #3A2B25", "5 c #352A25", "6 c #2F2622", "7 c #2A241F", "8 c #2A241E", "9 c #24211A", "0 c #22211A", "a c #25281D", "b c #394831", "c c #A4C096", "d c #6D8D64", "e c #945D53", "f c #512F2B", "g c #452823", "h c #4B2A23", "i c #693A2D", "j c #B86547", "k c #FDD0A5", "l c #F2B385", "m c #AD6248", "n c #6A4334", "o c #50382F", "p c #473731", "q c #4B3F39", "r c #413833", "s c #3F3731", "t c #363029", "u c #302C24", "v c #2C2B22", "w c #303225", "x c #49573C", "y c #9FB990", "z c #7C9B71", "A c #BC8175", "B c #5D3934", "C c #50302B", "D c #56312A", "E c #7A4536", "F c #DB8059", "G c #FEFBED", "H c #FEE8CA", "I c #D27D5B", "J c #835544", "K c #6A4F44", "L c #685852", "M c #7A7472", "N c #635C57", "O c #474039", "P c #3A332C", "Q c #322D26", "R c #2E2C23", "S c #414635", "T c #59654C", "U c #546349", "V c #3F4934", "W c #7F534D", "X c #613E39", "Y c #50312D", "Z c #56332D", "` c #7A493D", " . c #CD7E60", ".. c #F2AE81", "+. c #E79064", "@. c #9A5942", "#. c #6D4639", "$. c #634A41", "%. c #867E7A", "&. c #F0E4CB", "*. c #7E7D78", "=. c #4C453D", "-. c #3E3730", ";. c #38322A", ">. c #4D5140", ",. c #555C48", "'. c #333326", "). c #38392A", "!. c #36372A", "~. c #533635", "{. c #6A4642", "]. c #5C3B38", "^. c #623F3B", "/. c #784D44", "(. c #8C5547", "_. c #945643", ":. c #9D5E47", "<. c #764A3A", "[. c #604035", "}. c #594239", "|. c #655751", "1. c #8B8680", "2. c #645E57", "3. c #4E453C", "4. c #413A30", "5. c #555845", "6. c #4E503F", "7. c #342F26", "8. c #353025", "9. c #3E392C", "0. c #3F392E", "a. c #3F292C", "b. c #503536", "c. c #6A4845", "d. c #6B4946", "e. c #67433E", "f. c #6D463E", "g. c #7B4D41", "h. c #915C47", "i. c #5D3B32", "j. c #573C34", "k. c #533D35", "l. c #56453D", "m. c #5C4F46", "n. c #4C4138", "o. c #4B4136", "p. c #5A5846", "q. c #51513F", "r. c #342D23", "s. c #342E24", "t. c #40382B", "u. c #534638", "v. c #665544", "w. c #402B30", "x. c #472F33", "y. c #654748", "z. c #5F4040", "A. c #614140", "B. c #62403E", "C. c #6C453F", "D. c #825344", "E. c #583931", "F. c #523A33", "G. c #533E36", "H. c #544238", "I. c #544539", "J. c #504637", "K. c #595342", "L. c #575340", "M. c #3D3427", "N. c #3B3227", "O. c #3F3529", "P. c #483C2F", "Q. c #886F5B", "R. c #E1CFB9", "S. c #483139", "T. c #50393F", "U. c #523A3F", "V. c #5A3E41", "W. c #614144", "X. c #5F3D3F", "Y. c #674341", "Z. 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 #573F4A", "'+ c #5D444E", ")+ c #573E46", "!+ c #5B3E44", "~+ c #67434A", "{+ c #905C67", "]+ c #8D5C64", "^+ c #87594F", "/+ c #724C41", "(+ c #4A3531", "_+ c #4C3931", ":+ c #544236", "<+ c #696048", "[+ c #796D4E", "}+ c #958154", "|+ c #77653F", "1+ c #5C4E34", "2+ c #463B2A", "3+ c #473C2D", "4+ c #4F4335", "5+ c #56483A", "6+ c #635244", "7+ c #795C6E", "8+ c #634956", "9+ c #583E48", "0+ c #5F4249", "a+ c #845963", "b+ c #ECBCC1", "c+ c #DAA5AC", "d+ c #7B504F", "e+ c #734C41", "f+ c #48332E", "g+ c #43322B", "h+ c #544839", "i+ c #6B6247", "j+ c #A28C59", "k+ c #F8EBCB", "l+ c #E9DAAC", "m+ c #99885E", "n+ c #665940", "o+ c #493F2F", "p+ c #372E23", "q+ c #342B22", "r+ c #312720", "s+ c #9B7693", "t+ c #624758", "u+ c #543B47", "v+ c #553B44", "w+ c #67454E", "x+ c #895665", "y+ c #90606C", "z+ c #5F3E3F", "A+ c #744C3F", "B+ c #4B352E", "C+ c #45372F", "D+ c #5B5341", "E+ c #66553E", "F+ c #AB9561", "G+ c #FDF1DB", "H+ c #F8EAC7", "I+ c #938155", "J+ c #4D412D", "K+ c #362D20", "L+ c #B48BAC", "M+ c #705567", "N+ c #59424E", "O+ c #4E3841", "P+ c #4C353D", "Q+ c #4D333A", "R+ c #563C40", "S+ c #4C3536", "T+ c #7B5140", "U+ c #4A362F", "V+ c #504B3E", "W+ c #473B2F", "X+ c #514231", "Y+ c #A28D5B", "Z+ c #9C895B", "`+ c #615338", " @ c #4A402E", ".@ c #332B1F", "+@ c #806279", "@@ c #5D4655", "#@ c #493540", "$@ c #402E36", "%@ c #3E2B32", "&@ c #3D2A30", "*@ c #433034", "=@ c #453232", "-@ c #764E3E", ";@ c #51453A", ">@ c #443B32", ",@ c #3D332A", "'@ c #43382C", ")@ c #5C4F3A", "!@ c #534632", "~@ c #3F3526", "{@ c #2E271C", "]@ c #3C2C36", "^@ c #37272F", "/@ c #302228", "(@ c #2D1F24", "_@ c #322427", ":@ c #3E2F2E", "<@ c #825A47", "[@ c #615443", "}@ c #594638", "|@ c #423B30", "1@ c #F5E8C5", "2@ c #4A4034", "3@ c #332A20", "4@ c #2F271D", "5@ c #352C22", "6@ c #3C2D38", "7@ c #2C1F26", "8@ c #291E23", "9@ c #281D22", "0@ c #291D20", "a@ c #332B29", "b@ c #7D6A52", "c@ c #645442", "d@ c #755540", "e@ c #F3D9B5", "f@ c #322B23", "g@ c #918C8F", "h@ c #261E1F", "i@ c #573C30", "j@ c #50372C", "k@ c #3D2921", "l@ c #33221C", "m@ c #28201D", " ", " ", " ", " . + @ # $ % & ", " * = - ; > , ' ) ! ~ { ] ^ / ", " ( _ : < [ } | 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+H+Y+Z+`+ @.@ ", " +@@@#@$@%@&@*@=@-@;@>@,@'@H+)@!@~@{@ ", " +@+@]@^@/@(@_@:@<@[@}@|@1@2@3@4@5@ ", " 6@+@+@7@8@9@0@a@b@c@d@e@H+f@ ", " +@g@ h@i@j@k@l@m@ ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-restart.png000066400000000000000000000003441214562307500216400ustar00rootroot00000000000000‰PNG  IHDRàw=ø«IDATH‰í”Kƒ0 D‡Š­/Øž$RYQ)' út ® Hl2;çy]wkÈV¢7€y·4æÏé ø Âì2ÜÍžI2gÝ'ÉxX•hóàÐT–ÀÁеžI»Á+r¥±Œý$(Ì«¸whÁ*Ñ3L aÚ·£E.DmºYpÙAÿÔ@5Áø?€¹y½>y‡3£Âl[$æQªx­ƒ®«ë}ÉpLÁ\³IEND®B`‚proofgeneral-4.3~pre130510/images/epg-restart.xpm000066400000000000000000000014251214562307500216610ustar00rootroot00000000000000/* XPM */ static char * epg_restart_xpm[] = { "24 24 4 1", " c None", ". c #C58989", "+ c #870D0D", "@ c #D5AAAA", " ", " ", " ", " ", " .+++. ", " .+++++++ ", " .+++++++++ ", " +++. .+ ", " +++. + ", " +++++++ +++ ", " @++++++ +++++ ", " +++++ ++++++@ ", " +++ +++++++ ", " + .+++ ", " +. .+++ ", " +++++++++. ", " +++++++. ", " .+++. ", " ", " ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-retract.png000066400000000000000000000002731214562307500216210ustar00rootroot00000000000000‰PNG  IHDRàw=ø‚IDATH‰í”1À ¡»¿ÊÞdî[y@ºI eªð‚Dì“"R:ú½²U@­šª¦œûÑ»ÖîòZJ5x|‹(¨…™%xšsŸA›š¥˜!hSS”•–¡` ¬´!Eh¥Œê A”Ò­»ì¦x}»ïfßÒ_diô}× ñ¡ú5|GIEND®B`‚proofgeneral-4.3~pre130510/images/epg-retract.xpm000066400000000000000000000014251214562307500216410ustar00rootroot00000000000000/* XPM */ static char * epg_retract_xpm[] = { "24 24 4 1", " c None", ". c #870D0D", "+ c #860C0C", "@ c #CB9797", " ", " ", " ", " ", " ", " .......+..... ", " ............. ", " @.@ ", " ... ", " @...@ ", " ..... ", " @.....@ ", " ....... ", " @.......@ ", " ......... ", " @.........@ ", " ........... ", " ............. ", " ", " ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-state.png000066400000000000000000000015521214562307500212760ustar00rootroot00000000000000‰PNG  IHDRàw=ø1IDATH‰í”MH+W†Ÿ¤™Œ"˜ŸEëÀC"Õ€ ÅÞ¤ )ˆ-Ü®„þ,Änª‹HÑ¥º° ¡¥tSär/ .‚Äf“ T Â5.äª(Óth%‰ÄœÓE÷ŽtY(÷…Ãð}¼ç<ç^¼Ñÿ^›Þ{@°¡~ Úø†WCþü7à·€ ȆeÞõëzX*€hXÏ;Ø< ‡ÃµX,&r¹œ, 2—ËÉX,&Ãáp x<ñz½ôõõ‰qzz*òù¼Èf³bllL†Q¾°ŒÂ4MQ©T„lP¥R‘¦iÞO444$óù¼xU–e‰ÙÙYün(D£QQ©T„â ‰F£ÙlVÖjµ×Bqvv&zzzjš¦ýÔÔÔäpÞ|º®£(ŠíÿS]×0 ‡Ã.Ð4ÍÑÙÙùi0ü àÐ4íÑN§MÓðx<¶UUq¹þÖðððw p{{Ëúú:ËËË”ËåG*•J,,,L&BØz<Ï»ðOŽÅbQîîî211A©TBJÉää$BŠÅ"…B¥¥% d2Z[[¸¾¾ææææáôw߉D!º®ãñxhkk»7‹E‰kkk´··ãr¹èèè@UÕûKloosyyI(zm¢ëx<.R©”Èd2²Z­Êjµ*/..äææ¦TE677ËÁÁA™J¥D*•'''¢V«‰jµ*LÓSSSÂëõй¹9133S€‡OÅSàûH$âp´´´`Yétš­­-FGGéîîf~~~žžžÆï÷£( –e±²²Àøø8>ŸÕÕÕ×_Í𹪪ONç[¡PˆÞÞ^t]¿I&“ߤÓé€.§Óù³ªªïÔ7F" ÃÀçóɃƒƒ_–J¥ßls922²‡?«×GGGûûûÏ÷öö~¬÷ü~¨¿¿ÿë®®®OÜn·àêê*{||üK<ÿªî³¸ÝîfÃ0êõùùù¯år¹hç ƒO\.×Û–e½, v/ïý‡ú ÌI ã'VtIEND®B`‚proofgeneral-4.3~pre130510/images/epg-state.xpm000066400000000000000000000063311214562307500213160ustar00rootroot00000000000000/* XPM */ static char * epg_state_xpm[] = { "24 24 124 2", " c None", ". c #D7D7D7", "+ c #B7B7B7", "@ c #BBBBBB", "# c #F2F2F2", "$ c #6E6E6E", "% c #2C2C2C", "& c #000000", "* c #CFCFCF", "= c #656565", "- c #070707", "; c #010101", "> c #525252", ", c #A8A8A8", "' c #ECECEC", ") c #545454", "! c #353535", "~ c #8F8F8F", "{ c #D9D9D9", "] c #C0C0C0", "^ c #1D1D1D", "/ c #373737", "( c #CBCBCB", "_ c #E2E2E2", ": c #E8E8E8", "< c #D5D5D5", "[ c #555555", "} c #252525", "| c #989898", "1 c #B0B0B0", "2 c #D3D3D3", "3 c #F8F8F8", "4 c #444444", "5 c #FEFEFE", "6 c #F0F0F0", "7 c #7C7C7C", "8 c #101010", "9 c #131313", "0 c #7B7B7B", "a c #7A7A7A", "b c #FDFDFD", "c c #E3E3E3", "d c #333333", "e c #636363", "f c #EFEFEF", "g c #959595", "h c #F3F3F3", "i c #F7F7F7", "j c #3C3C3C", "k c #303030", "l c #BCBCBC", "m c #9F9F9F", "n c #404040", "o c #818181", "p c #FAFAFA", "q c #AFAFAF", "r c #949494", "s c #F6F6F6", "t c #F4F4F4", "u c #868686", "v c #BDBDBD", "w c #FCFCFC", "x c #808080", "y c #8D8D8D", "z c #C7C7C7", "A c #121212", "B c #939393", "C c #EBEBEB", "D c #797979", "E c #030303", "F c #171717", "G c #E4E4E4", "H c #393939", "I c #4A4A4A", "J c #C5C5C5", "K c #2D2D2D", "L c #B2B2B2", "M c #494949", "N c #9B9B9B", "O c #999999", "P c #3A3A3A", "Q c #B9B9B9", "R c #222222", "S c #565656", "T c #B8B8B8", "U c #0B0B0B", "V c #C4C4C4", "W c #CECECE", "X c #FBFBFB", "Y c #E6E6E6", "Z c #BABABA", "` c #050505", " . c #0D0D0D", ".. c #3D3D3D", "+. c #E1E1E1", "@. c #6F6F6F", "#. c #A4A4A4", "$. c #474747", "%. c #919191", "&. c #464646", "*. c #4C4C4C", "=. c #767676", "-. c #888888", ";. c #7E7E7E", ">. c #181818", ",. c #5E5E5E", "'. c #0A0A0A", "). c #090909", "!. c #2F2F2F", "~. c #616161", "{. c #A5A5A5", "]. c #1B1B1B", "^. c #505050", "/. c #8E8E8E", "(. c #EDEDED", "_. c #8B8B8B", ":. c #B1B1B1", "<. c #DCDCDC", "[. c #848484", "}. c #979797", "|. c #C1C1C1", "1. c #EEEEEE", "2. c #C8C8C8", "3. c #DADADA", " ", " ", " ", " ", " ", " . + + + . @ + + + # ", " $ % & & & % $ * = - ; ; ; > , ", " ' ) ! ~ { ' { ~ ! ) ] ^ / ( _ : < [ } | ", " 1 ; 2 3 3 2 & & 4 : 5 5 5 5 6 7 8 ", " 9 0 3 5 3 a & < b 5 5 5 5 5 c d e f ", " ; g b 5 b g & h 5 5 5 5 5 5 i j k l ", " & m 5 5 m & 5 5 5 5 5 5 5 n k o ", " ; m p q r s m & t u v w 5 5 5 n k x ", " & y z A - B b y & C D E F G 5 5 # H k x ", " > I J K 9 L C M & N O - P C 5 w Q R S x ", " T U T V W X X Y Z ` ...V V +.b X 2 @.A x x ", " #.- $.o %.o &.E > x *.; =.-.y ;.>.>.$ x l ", " V ,.'.).).!.~.x {.' ] ].'.'.'.^.$ x /.(. ", " r x x x _.:. <.r x x x [.}. ", " # |.|.|.1. 2.|.|.3. ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-undo.png000066400000000000000000000002631214562307500211210ustar00rootroot00000000000000‰PNG  IHDRàw=øzIDATH‰c`Ã0R¢¹—×ÁœazåçÏXÍb!Óà †éĨ%ÉR &Ér &ÊJ Æk5 ÆiA;/ïj LèÐä–I- ðæR‚ W> *£cEcU,ÀgU-@²ˆ`Y4 Fåø1$ª@7V=IEND®B`‚proofgeneral-4.3~pre130510/images/epg-undo.xpm000066400000000000000000000014221214562307500211370ustar00rootroot00000000000000/* XPM */ static char * epg_undo_xpm[] = { "24 24 4 1", " c None", ". c #E8D1D1", "+ c #CE9C9C", "@ c #870D0D", " ", " ", " ", " ", " ", " .+@ ", " +@@@@ ", " +@@@@@@ ", " +@@@@@@@@ ", " +@@@@@@@@@@ ", " +@@@@@@@@@@@@ ", " @@@@@@@@@@@@@@ ", " +@@@@@@@@@@@@ ", " +@@@@@@@@@@ ", " +@@@@@@@@ ", " +@@@@@@ ", " +@@@@ ", " .+@ ", " ", " ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/epg-use.png000066400000000000000000000002751214562307500207530ustar00rootroot00000000000000‰PNG  IHDRàw=ø„IDATH‰íÔ;1 „áú=+5'àÀ{€l‰Ð®c[ˆeZ'3ó+–þ^·hðÚ¶Ñ5{îûÉ/ è†\™Ã=Ù÷(ú‡ë¦Ô(¢öääÓyJÀœbÖžqËôŒJ\Sdí©pn[ºae>)*íéðn]}¿ÿ*º`ŒvöÒÒ:£#gFõX$IEND®B`‚proofgeneral-4.3~pre130510/images/epg-use.xpm000066400000000000000000000014211214562307500207650ustar00rootroot00000000000000/* XPM */ static char * epg_use_xpm[] = { "24 24 4 1", " c None", ". c #870D0D", "+ c #CB9797", "@ c #860C0C", " ", " ", " ", " ", " ", " ............. ", " ........... ", " +.........+ ", " ......... ", " +.......+ ", " ....... ", " +.....+ ", " ..... ", " +...+ ", " ... ", " +.+ ", " ............. ", " .......@..... ", " ", " ", " ", " ", " ", " "}; proofgeneral-4.3~pre130510/images/hiddenproof.xpm000066400000000000000000000031461214562307500217270ustar00rootroot00000000000000/* XPM */ static char * hiddenproof_xpm[] = { "16 16 84 1", " c None", ". c #F7DFFF", "+ c #F4D3FF", "@ c #F1C7FF", "# c #EEBAFF", "$ c #EBAEFF", "% c #E8A0FF", "& c #E594FF", "* c #E287FF", "= c #DF7CFF", "- c #DC70FF", "; c #AE22FE", "> c #F3CFFF", ", c #29202B", "' c #281E2B", ") c #281D2B", "! c #271B2B", "~ c #27182B", "{ c #26152B", "] c #26142B", "^ c #DB6CFF", "/ c #D85FFF", "( c #8200DC", "_ c #000000", ": c #EFBFFF", "< c #ECB3FF", "[ c #E9A7FF", "} c #E69BFF", "| c #E38FFF", "1 c #E082FF", "2 c #DD76FF", "3 c #DA68FF", "4 c #D75DFF", "5 c #D44FFF", "6 c #7200BF", "7 c #ECB0FF", "8 c #281B2B", "9 c #27192B", "0 c #26162B", "a c #25122B", "b c #25102B", "c c #D759FF", "d c #D44DFF", "e c #D140FF", "f c #7000BE", "g c #DC6FFF", "h c #D962FF", "i c #D657FF", "j c #D349FF", "k c #D03EFF", "l c #CD30FF", "m c #6C00B6", "n c #E492FF", "o c #25112B", "p c #D552FF", "q c #D247FF", "r c #CF3AFF", "s c #CC2EFF", "t c #C921FF", "u c #6100A3", "v c #D144FF", "w c #CE37FF", "x c #CB2AFF", "y c #C81FFF", "z c #C511FF", "A c #DD72FF", "B c #250F2B", "C c #240C2B", "D c #240A2B", "E c #23072B", "F c #CB27FF", "G c #C71AFF", "H c #C50FFF", "I c #C202FF", "J c #DB69FF", "K c #CA25FF", "L c #C717FF", "M c #C40CFF", "N c #C100FF", "O c #6200A6", "P c #B42BFE", "Q c #7D00D0", "R c #6700AE", "S c #590096", " ", " ", " ", " .+@#$%&*=-; ", " >,')!~{]^/(_ ", " :<[}|123456_ ", " 7890{abcdef_ ", " %&*=ghijklm_ ", " n{]o/pqrstu_ ", " 12345vwxyzu_ ", " AbBCDEFGHIu_ ", " JijklKLMNNO_ ", " P(QfffRuuuS_ ", " ___________ ", " ", " "}; proofgeneral-4.3~pre130510/isar/000077500000000000000000000000001214562307500163655ustar00rootroot00000000000000proofgeneral-4.3~pre130510/isar/Example-Tokens.thy000066400000000000000000000017601214562307500217530ustar00rootroot00000000000000(* Example proof document for Isabelle/Isar Proof General, using symbols. View and process this document with Unicode Tokens engaged. For a more exhaustive test of token display, visit the test file etc/isar/TokensAcid.thy. Check the FAQ for more advice. $Id: Example-Tokens.thy,v 12.1 2012/04/30 13:17:13 da Exp $ *) theory "Example-Tokens" imports Main begin text {* Proper proof text -- \<^bitalic>naive version\<^eitalic>. *} theorem and_comms: "\ \ \ \ \ \ \" proof assume "\ \ \" then show "\ \ \" proof assume "\" and "\" then show ?thesis .. qed qed text {* \<^bbold>Unstructured\<^ebold> proof script. *} theorem "\\<^isub>\ \ \\<^isub>\ \ \\<^isub>\ \ \\<^isub>\" apply (rule impI) apply (erule conjE) apply (rule conjI) apply assumption apply assumption done end proofgeneral-4.3~pre130510/isar/Example.thy000066400000000000000000000010451214562307500205060ustar00rootroot00000000000000(* Example proof document for Isabelle/Isar Proof General. $Id: Example.thy,v 12.0 2011/10/13 10:54:50 da Exp $ *) theory Example imports Main begin text {* Proper proof text -- \textit{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 {* Unstructured proof script. *} theorem "A & B --> B & A" apply (rule impI) apply (erule conjE) apply (rule conjI) apply assumption apply assumption done end proofgeneral-4.3~pre130510/isar/README000066400000000000000000000023621214562307500172500ustar00rootroot00000000000000Isabelle/Isar Proof General Written by Markus Wenzel and David Aspinall. Contributions from David von Oheimb, Stefan Berghofer, Sebastian Skalberg, Gerwin Klein, Tjark Weber. Status: supported Maintainers: David Aspinall, Makarius Wenzel Isabelle versions: Isabelle2011 (earlier versions not guaranteed) Isabelle homepage: http://www.cl.cam.ac.uk/Research/HVG/Isabelle/ =========================================================================== Isabelle/Isar Proof General has full support for multiple file scripting, with dependencies between theories communicated between Isabelle and Proof General. There is full support for Unicode Tokens, 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. ======================================== $Id: README,v 12.0 2011/10/13 10:54:50 da Exp $ proofgeneral-4.3~pre130510/isar/ex/000077500000000000000000000000001214562307500170015ustar00rootroot00000000000000proofgeneral-4.3~pre130510/isar/ex/Knaster_Tarski.thy000066400000000000000000000071601214562307500224570ustar00rootroot00000000000000(********** This file is copied from Isabelle2011. **********) (* Title: HOL/Isar_Examples/Knaster_Tarski.thy Author: Markus Wenzel, TU Muenchen Typical textbook proof example. *) header {* Textbook-style reasoning: the Knaster-Tarski Theorem *} theory Knaster_Tarski imports Main "~~/src/HOL/Library/Lattice_Syntax" begin subsection {* Prose version *} text {* According to the textbook \cite[pages 93--94]{davey-priestley}, the Knaster-Tarski fixpoint theorem is as follows.\footnote{We have dualized the argument, and tuned the notation a little bit.} \textbf{The Knaster-Tarski Fixpoint Theorem.} Let @{text L} be a complete lattice and @{text "f: L \ L"} an order-preserving map. Then @{text "\{x \ L | f(x) \ x}"} is a fixpoint of @{text f}. \textbf{Proof.} Let @{text "H = {x \ L | f(x) \ x}"} and @{text "a = \H"}. For all @{text "x \ H"} we have @{text "a \ x"}, so @{text "f(a) \ f(x) \ x"}. Thus @{text "f(a)"} is a lower bound of @{text H}, whence @{text "f(a) \ a"}. We now use this inequality to prove the reverse one (!) and thereby complete the proof that @{text a} is a fixpoint. Since @{text f} is order-preserving, @{text "f(f(a)) \ f(a)"}. This says @{text "f(a) \ H"}, so @{text "a \ f(a)"}. *} subsection {* Formal versions *} text {* The Isar proof below closely follows the original presentation. Virtually all of the prose narration has been rephrased in terms of formal Isar language elements. Just as many textbook-style proofs, there is a strong bias towards forward proof, and several bends in the course of reasoning. *} theorem Knaster_Tarski: fixes f :: "'a::complete_lattice \ 'a" assumes "mono f" shows "\a. f a = a" proof let ?H = "{u. f u \ u}" let ?a = "\?H" show "f ?a = ?a" proof - { fix x assume "x \ ?H" then have "?a \ x" by (rule Inf_lower) with `mono f` have "f ?a \ f x" .. also from `x \ ?H` have "\ \ x" .. finally have "f ?a \ x" . } then have "f ?a \ ?a" by (rule Inf_greatest) { also presume "\ \ f ?a" finally (order_antisym) show ?thesis . } from `mono f` and `f ?a \ ?a` have "f (f ?a) \ f ?a" .. then have "f ?a \ ?H" .. then show "?a \ f ?a" by (rule Inf_lower) qed qed text {* Above we have used several advanced Isar language elements, such as explicit block structure and weak assumptions. Thus we have mimicked the particular way of reasoning of the original text. In the subsequent version the order of reasoning is changed to achieve structured top-down decomposition of the problem at the outer level, while only the inner steps of reasoning are done in a forward manner. We are certainly more at ease here, requiring only the most basic features of the Isar language. *} theorem Knaster_Tarski': fixes f :: "'a::complete_lattice \ 'a" assumes "mono f" shows "\a. f a = a" proof let ?H = "{u. f u \ u}" let ?a = "\?H" show "f ?a = ?a" proof (rule order_antisym) show "f ?a \ ?a" proof (rule Inf_greatest) fix x assume "x \ ?H" then have "?a \ x" by (rule Inf_lower) with `mono f` have "f ?a \ f x" .. also from `x \ ?H` have "\ \ x" .. finally show "f ?a \ x" . qed show "?a \ f ?a" proof (rule Inf_lower) from `mono f` and `f ?a \ ?a` have "f (f ?a) \ f ?a" .. then show "f ?a \ ?H" .. qed qed qed end proofgeneral-4.3~pre130510/isar/ex/PER.thy000066400000000000000000000204621214562307500201610ustar00rootroot00000000000000(********** This file is copied from Isabelle2011. It has been beautified with Tokens \ Replace Shortcuts **********) (* Title: HOL/ex/PER.thy Author: Oscar Slotosch and Markus Wenzel, TU Muenchen *) header {* Partial equivalence relations *} theory PER imports Main begin text {* Higher-order quotients are defined over partial equivalence relations (PERs) instead of total ones. We provide axiomatic type classes @{text "equiv < partial_equiv"} and a type constructor @{text "'a quot"} with basic operations. This development is based on: Oscar Slotosch: \emph{Higher Order Quotients and their Implementation in Isabelle HOL.} Elsa L. Gunter and Amy Felty, editors, Theorem Proving in Higher Order Logics: TPHOLs '97, Springer LNCS 1275, 1997. *} subsection {* Partial equivalence *} text {* Type class @{text partial_equiv} models partial equivalence relations (PERs) using the polymorphic @{text "\ :: 'a \ 'a \ bool"} relation, which is required to be symmetric and transitive, but not necessarily reflexive. *} class partial_equiv = fixes eqv :: "'a \ 'a \ bool" (infixl "\" 50) assumes partial_equiv_sym [elim?]: "x \ y \ y \ x" assumes partial_equiv_trans [trans]: "x \ y \ y \ z \ x \ z" text {* \medskip The domain of a partial equivalence relation is the set of reflexive elements. Due to symmetry and transitivity this characterizes exactly those elements that are connected with \emph{any} other one. *} definition "domain" :: "'a::partial_equiv set" where "domain = {x. x \ x}" lemma domainI [intro]: "x \ x \ x \ domain" unfolding domain_def by blast lemma domainD [dest]: "x \ domain \ x \ x" unfolding domain_def by blast theorem domainI' [elim?]: "x \ y \ x \ domain" proof assume xy: "x \ y" also from xy have "y \ x" .. finally show "x \ x" . qed subsection {* Equivalence on function spaces *} text {* The @{text \} relation is lifted to function spaces. It is important to note that this is \emph{not} the direct product, but a structural one corresponding to the congruence property. *} instantiation "fun" :: (partial_equiv, partial_equiv) partial_equiv begin definition eqv_fun_def: "f \ g \ \x \ domain. \y \ domain. x \ y \ f x \ g y" lemma partial_equiv_funI [intro?]: "(\x y. x \ domain \ y \ domain \ x \ y \ f x \ g y) \ f \ g" unfolding eqv_fun_def by blast lemma partial_equiv_funD [dest?]: "f \ g \ x \ domain \ y \ domain \ x \ y \ f x \ g y" unfolding eqv_fun_def by blast text {* The class of partial equivalence relations is closed under function spaces (in \emph{both} argument positions). *} instance proof fix f g h :: "'a::partial_equiv \ 'b::partial_equiv" assume fg: "f \ g" show "g \ f" proof fix x y :: 'a assume x: "x \ domain" and y: "y \ domain" assume "x \ y" then have "y \ x" .. with fg y x have "f y \ g x" .. then show "g x \ f y" .. qed assume gh: "g \ h" show "f \ h" proof fix x y :: 'a assume x: "x \ domain" and y: "y \ domain" and "x \ y" with fg have "f x \ g y" .. also from y have "y \ y" .. with gh y y have "g y \ h y" .. finally show "f x \ h y" . qed qed end subsection {* Total equivalence *} text {* The class of total equivalence relations on top of PERs. It coincides with the standard notion of equivalence, i.e.\ @{text "\ :: 'a \ 'a \ bool"} is required to be reflexive, transitive and symmetric. *} class equiv = assumes eqv_refl [intro]: "x \ x" text {* On total equivalences all elements are reflexive, and congruence holds unconditionally. *} theorem equiv_domain [intro]: "(x::'a::equiv) \ domain" proof show "x \ x" .. qed theorem equiv_cong [dest?]: "f \ g \ x \ y \ f x \ g (y::'a::equiv)" proof - assume "f \ g" moreover have "x \ domain" .. moreover have "y \ domain" .. moreover assume "x \ y" ultimately show ?thesis .. qed subsection {* Quotient types *} text {* The quotient type @{text "'a quot"} consists of all \emph{equivalence classes} over elements of the base type @{typ 'a}. *} typedef 'a quot = "{{x. a \ x}| a::'a::partial_equiv. True}" by blast lemma quotI [intro]: "{x. a \ x} \ quot" unfolding quot_def by blast lemma quotE [elim]: "R \ quot \ (\a. R = {x. a \ x} \ C) \ C" unfolding quot_def by blast text {* \medskip Abstracted equivalence classes are the canonical representation of elements of a quotient type. *} definition eqv_class :: "('a::partial_equiv) \ 'a quot" ("\_\") where "\a\ = Abs_quot {x. a \ x}" theorem quot_rep: "\a. A = \a\" proof (cases A) fix R assume R: "A = Abs_quot R" assume "R \ quot" then have "\a. R = {x. a \ x}" by blast with R have "\a. A = Abs_quot {x. a \ x}" by blast then show ?thesis by (unfold eqv_class_def) qed lemma quot_cases [cases type: quot]: obtains (rep) a where "A = \a\" using quot_rep by blast subsection {* Equality on quotients *} text {* Equality of canonical quotient elements corresponds to the original relation as follows. *} theorem eqv_class_eqI [intro]: "a \ b \ \a\ = \b\" proof - assume ab: "a \ b" have "{x. a \ x} = {x. b \ x}" proof (rule Collect_cong) fix x show "(a \ x) = (b \ x)" proof from ab have "b \ a" .. also assume "a \ x" finally show "b \ x" . next note ab also assume "b \ x" finally show "a \ x" . qed qed then show ?thesis by (simp only: eqv_class_def) qed theorem eqv_class_eqD' [dest?]: "\a\ = \b\ \ a \ domain \ a \ b" proof (unfold eqv_class_def) assume "Abs_quot {x. a \ x} = Abs_quot {x. b \ x}" then have "{x. a \ x} = {x. b \ x}" by (simp only: Abs_quot_inject quotI) moreover assume "a \ domain" then have "a \ a" .. ultimately have "a \ {x. b \ x}" by blast then have "b \ a" by blast then show "a \ b" .. qed theorem eqv_class_eqD [dest?]: "\a\ = \b\ \ a \ (b::'a::equiv)" proof (rule eqv_class_eqD') show "a \ domain" .. qed lemma eqv_class_eq' [simp]: "a \ domain \ (\a\ = \b\) = (a \ b)" using eqv_class_eqI eqv_class_eqD' by (blast del: eqv_refl) lemma eqv_class_eq [simp]: "(\a\ = \b\) = (a \ (b::'a::equiv))" using eqv_class_eqI eqv_class_eqD by blast subsection {* Picking representing elements *} definition pick :: "'a::partial_equiv quot \ 'a" where "pick A = (SOME a. A = \a\)" theorem pick_eqv' [intro?, simp]: "a \ domain \ pick \a\ \ a" proof (unfold pick_def) assume a: "a \ domain" show "(SOME x. \a\ = \x\) \ a" proof (rule someI2) show "\a\ = \a\" .. fix x assume "\a\ = \x\" from this and a have "a \ x" .. then show "x \ a" .. qed qed theorem pick_eqv [intro, simp]: "pick \a\ \ (a::'a::equiv)" proof (rule pick_eqv') show "a \ domain" .. qed theorem pick_inverse: "\pick A\ = (A::'a::equiv quot)" proof (cases A) fix a assume a: "A = \a\" then have "pick A \ a" by simp then have "\pick A\ = \a\" by simp with a show ?thesis by simp qed end proofgeneral-4.3~pre130510/isar/ex/README000066400000000000000000000003711214562307500176620ustar00rootroot00000000000000This directory contains some example files copied from the Isabelle distribution. These are re-distributed with Proof General for convenience of trying out PG without needing a local installation of Isabelle. They can also be used as test cases. proofgeneral-4.3~pre130510/isar/ex/Sqrt.thy000066400000000000000000000067611214562307500204720ustar00rootroot00000000000000(* Title: HOL/ex/Sqrt.thy Author: Markus Wenzel, TU Muenchen *) header {* Square roots of primes are irrational *} theory Sqrt imports Complex_Main "~~/src/HOL/Number_Theory/Primes" begin text {* The square root of any prime number (including @{text 2}) is irrational. *} theorem sqrt_prime_irrational: assumes "prime (p::nat)" shows "sqrt (real p) \ \" proof from `prime p` have p: "1 < p" by (simp add: prime_nat_def) assume "sqrt (real p) \ \" then obtain m n :: nat where n: "n \ 0" and sqrt_rat: "\sqrt (real p)\ = real m / real n" and gcd: "gcd m n = 1" by (rule Rats_abs_nat_div_natE) have eq: "m\ = p * n\" proof - from n and sqrt_rat have "real m = \sqrt (real p)\ * real n" by simp then have "real (m\) = (sqrt (real p))\ * real (n\)" by (auto simp add: power2_eq_square) also have "(sqrt (real p))\ = real p" by simp also have "\ * real (n\) = real (p * n\)" by simp finally show ?thesis .. qed have "p dvd m \ p dvd n" proof from eq have "p dvd m\" .. with `prime p` pos2 show "p dvd m" by (rule prime_dvd_power_nat) then obtain k where "m = p * k" .. with eq have "p * n\ = p\ * k\" by (auto simp add: power2_eq_square mult_ac) with p have "n\ = p * k\" by (simp add: power2_eq_square) then have "p dvd n\" .. with `prime p` pos2 show "p dvd n" by (rule prime_dvd_power_nat) qed then have "p dvd gcd m n" .. with gcd have "p dvd 1" by simp then have "p \ 1" by (simp add: dvd_imp_le) with p show False by simp qed corollary "sqrt (real (2::nat)) \ \" by (rule sqrt_prime_irrational) (rule two_is_prime_nat) subsection {* Variations *} text {* Here is an alternative version of the main proof, using mostly linear forward-reasoning. While this results in less top-down structure, it is probably closer to proofs seen in mathematics. *} theorem assumes "prime (p::nat)" shows "sqrt (real p) \ \" proof from `prime p` have p: "1 < p" by (simp add: prime_nat_def) assume "sqrt (real p) \ \" then obtain m n :: nat where n: "n \ 0" and sqrt_rat: "\sqrt (real p)\ = real m / real n" and gcd: "gcd m n = 1" by (rule Rats_abs_nat_div_natE) from n and sqrt_rat have "real m = \sqrt (real p)\ * real n" by simp then have "real (m\) = (sqrt (real p))\ * real (n\)" by (auto simp add: power2_eq_square) also have "(sqrt (real p))\ = real p" by simp also have "\ * real (n\) = real (p * n\)" by simp finally have eq: "m\ = p * n\" .. then have "p dvd m\" .. with `prime p` pos2 have dvd_m: "p dvd m" by (rule prime_dvd_power_nat) then obtain k where "m = p * k" .. with eq have "p * n\ = p\ * k\" by (auto simp add: power2_eq_square mult_ac) with p have "n\ = p * k\" by (simp add: power2_eq_square) then have "p dvd n\" .. with `prime p` pos2 have "p dvd n" by (rule prime_dvd_power_nat) with dvd_m have "p dvd gcd m n" by (rule gcd_greatest_nat) with gcd have "p dvd 1" by simp then have "p \ 1" by (simp add: dvd_imp_le) with p show False by simp qed end proofgeneral-4.3~pre130510/isar/ex/Sqrt_Script.thy000066400000000000000000000040741214562307500220110ustar00rootroot00000000000000(* Title: HOL/ex/Sqrt_Script.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 2001 University of Cambridge *) header {* Square roots of primes are irrational (script version) *} theory Sqrt_Script imports Complex_Main "~~/src/HOL/Number_Theory/Primes" begin text {* \medskip Contrast this linear Isabelle/Isar script with Markus Wenzel's more mathematical version. *} subsection {* Preliminaries *} lemma prime_nonzero: "prime (p::nat) \ p \ 0" by (force simp add: prime_nat_def) lemma prime_dvd_other_side: "(n::nat) * n = p * (k * k) \ prime p \ p dvd n" apply (subgoal_tac "p dvd n * n", blast dest: prime_dvd_mult_nat) apply auto done lemma reduction: "prime (p::nat) \ 0 < k \ k * k = p * (j * j) \ k < p * j \ 0 < j" apply (rule ccontr) apply (simp add: linorder_not_less) apply (erule disjE) apply (frule mult_le_mono, assumption) apply auto apply (force simp add: prime_nat_def) done lemma rearrange: "(j::nat) * (p * j) = k * k \ k * k = p * (j * j)" by (simp add: mult_ac) lemma prime_not_square: "prime (p::nat) \ (\k. 0 < k \ m * m \ p * (k * k))" apply (induct m rule: nat_less_induct) apply clarify apply (frule prime_dvd_other_side, assumption) apply (erule dvdE) apply (simp add: nat_mult_eq_cancel_disj prime_nonzero) apply (blast dest: rearrange reduction) done subsection {* Main theorem *} text {* The square root of any prime number (including @{text 2}) is irrational. *} theorem prime_sqrt_irrational: "prime (p::nat) \ x * x = real p \ 0 \ x \ x \ \" apply (rule notI) apply (erule Rats_abs_nat_div_natE) apply (simp del: real_of_nat_mult add: abs_if divide_eq_eq prime_not_square real_of_nat_mult [symmetric]) done lemmas two_sqrt_irrational = prime_sqrt_irrational [OF two_is_prime_nat] end proofgeneral-4.3~pre130510/isar/ex/Tarski.thy000066400000000000000000000757611214562307500210040ustar00rootroot00000000000000(********** This file is copied from Isabelle2011. It has been beautified with Tokens -> Replace Shortcuts **********) (* Title: HOL/ex/Tarski.thy Author: Florian Kammüller, Cambridge University Computer Laboratory *) header {* The Full Theorem of Tarski *} theory Tarski imports Main "~~/src/HOL/Library/FuncSet" begin text {* Minimal version of lattice theory plus the full theorem of Tarski: The fixedpoints of a complete lattice themselves form a complete lattice. Illustrates first-class theories, using the Sigma representation of structures. Tidied and converted to Isar by lcp. *} record 'a potype = pset :: "'a set" order :: "('a * 'a) set" definition monotone :: "['a \ 'a, 'a set, ('a *'a)set] \ bool" where "monotone f A r = (\x\A. \y\A. (x, y): r \ ((f x), (f y)) : r)" definition least :: "['a \ bool, 'a potype] \ 'a" where "least P po = (SOME x. x: pset po & P x & (\y \ pset po. P y \ (x,y): order po))" definition greatest :: "['a \ bool, 'a potype] \ 'a" where "greatest P po = (SOME x. x: pset po & P x & (\y \ pset po. P y \ (y,x): order po))" definition lub :: "['a set, 'a potype] \ 'a" where "lub S po = least (%x. \y\S. (y,x): order po) po" definition glb :: "['a set, 'a potype] \ 'a" where "glb S po = greatest (%x. \y\S. (x,y): order po) po" definition isLub :: "['a set, 'a potype, 'a] \ bool" where "isLub S po = (%L. (L: pset po & (\y\S. (y,L): order po) & (\z\pset po. (\y\S. (y,z): order po) \ (L,z): order po)))" definition isGlb :: "['a set, 'a potype, 'a] \ bool" where "isGlb S po = (%G. (G: pset po & (\y\S. (G,y): order po) & (\z \ pset po. (\y\S. (z,y): order po) \ (z,G): order po)))" definition "fix" :: "[('a \ 'a), 'a set] \ 'a set" where "fix f A = {x. x: A & f x = x}" definition interval :: "[('a*'a) set,'a, 'a ] \ 'a set" where "interval r a b = {x. (a,x): r & (x,b): r}" definition Bot :: "'a potype \ 'a" where "Bot po = least (%x. True) po" definition Top :: "'a potype \ 'a" where "Top po = greatest (%x. True) po" definition PartialOrder :: "('a potype) set" where "PartialOrder = {P. refl_on (pset P) (order P) & antisym (order P) & trans (order P)}" definition CompleteLattice :: "('a potype) set" where "CompleteLattice = {cl. cl: PartialOrder & (\S. S \ pset cl \ (\L. isLub S cl L)) & (\S. S \ pset cl \ (\G. isGlb S cl G))}" definition CLF_set :: "('a potype * ('a \ 'a)) set" where "CLF_set = (SIGMA cl: CompleteLattice. {f. f: pset cl \ pset cl & monotone f (pset cl) (order cl)})" definition induced :: "['a set, ('a * 'a) set] \ ('a *'a)set" where "induced A r = {(a,b). a : A & b: A & (a,b): r}" definition sublattice :: "('a potype * 'a set)set" where "sublattice = (SIGMA cl: CompleteLattice. {S. S \ pset cl & \ pset = S, order = induced S (order cl) \: CompleteLattice})" abbreviation sublat :: "['a set, 'a potype] \ bool" ("_ \= _" [51,50]50) where "S \= cl \ S : sublattice `` {cl}" definition dual :: "'a potype \ 'a potype" where "dual po = \ pset = pset po, order = converse (order po) \" locale S = fixes cl :: "'a potype" and A :: "'a set" and r :: "('a * 'a) set" defines A_def: "A \ pset cl" and r_def: "r \ order cl" locale PO = S + assumes cl_po: "cl : PartialOrder" locale CL = S + assumes cl_co: "cl : CompleteLattice" sublocale CL < PO apply (simp_all add: A_def r_def) apply unfold_locales using cl_co unfolding CompleteLattice_def by auto locale CLF = S + fixes f :: "'a \ 'a" and P :: "'a set" assumes f_cl: "(cl,f) : CLF_set" (*was the equivalent "f : CLF_set``{cl}"*) defines P_def: "P \ fix f A" sublocale CLF < CL apply (simp_all add: A_def r_def) apply unfold_locales using f_cl unfolding CLF_set_def by auto locale Tarski = CLF + fixes Y :: "'a set" and intY1 :: "'a set" and v :: "'a" assumes Y_ss: "Y \ P" defines intY1_def: "intY1 \ interval r (lub Y cl) (Top cl)" and v_def: "v \ glb {x. ((%x: intY1. f x) x, x): induced intY1 r & x: intY1} \ pset=intY1, order=induced intY1 r\" subsection {* Partial Order *} lemma (in PO) dual: "PO (dual cl)" apply unfold_locales using cl_po unfolding PartialOrder_def dual_def by auto lemma (in PO) PO_imp_refl_on [simp]: "refl_on A r" apply (insert cl_po) apply (simp add: PartialOrder_def A_def r_def) done lemma (in PO) PO_imp_sym [simp]: "antisym r" apply (insert cl_po) apply (simp add: PartialOrder_def r_def) done lemma (in PO) PO_imp_trans [simp]: "trans r" apply (insert cl_po) apply (simp add: PartialOrder_def r_def) done lemma (in PO) reflE: "x \ A \ (x, x) \ r" apply (insert cl_po) apply (simp add: PartialOrder_def refl_on_def A_def r_def) done lemma (in PO) antisymE: "\ (a, b) \ r; (b, a) \ r \ \ a = b" apply (insert cl_po) apply (simp add: PartialOrder_def antisym_def r_def) done lemma (in PO) transE: "\ (a, b) \ r; (b, c) \ r\ \ (a,c) \ r" apply (insert cl_po) apply (simp add: PartialOrder_def r_def) apply (unfold trans_def, fast) done lemma (in PO) monotoneE: "\ monotone f A r; x \ A; y \ A; (x, y) \ r \ \ (f x, f y) \ r" by (simp add: monotone_def) lemma (in PO) po_subset_po: "S \ A \ \ pset = S, order = induced S r \ \ PartialOrder" apply (simp (no_asm) add: PartialOrder_def) apply auto -- {* refl *} apply (simp add: refl_on_def induced_def) apply (blast intro: reflE) -- {* antisym *} apply (simp add: antisym_def induced_def) apply (blast intro: antisymE) -- {* trans *} apply (simp add: trans_def induced_def) apply (blast intro: transE) done lemma (in PO) indE: "\ (x, y) \ induced S r; S \ A \ \ (x, y) \ r" by (simp add: add: induced_def) lemma (in PO) indI: "\ (x, y) \ r; x \ S; y \ S \ \ (x, y) \ induced S r" by (simp add: add: induced_def) lemma (in CL) CL_imp_ex_isLub: "S \ A \ \L. isLub S cl L" apply (insert cl_co) apply (simp add: CompleteLattice_def A_def) done declare (in CL) cl_co [simp] lemma isLub_lub: "(\L. isLub S cl L) = isLub S cl (lub S cl)" by (simp add: lub_def least_def isLub_def some_eq_ex [symmetric]) lemma isGlb_glb: "(\G. isGlb S cl G) = isGlb S cl (glb S cl)" by (simp add: glb_def greatest_def isGlb_def some_eq_ex [symmetric]) lemma isGlb_dual_isLub: "isGlb S cl = isLub S (dual cl)" by (simp add: isLub_def isGlb_def dual_def converse_def) lemma isLub_dual_isGlb: "isLub S cl = isGlb S (dual cl)" by (simp add: isLub_def isGlb_def dual_def converse_def) lemma (in PO) dualPO: "dual cl \ PartialOrder" apply (insert cl_po) apply (simp add: PartialOrder_def dual_def refl_on_converse trans_converse antisym_converse) done lemma Rdual: "\S. (S \ A \( \L. isLub S \ pset = A, order = r\ L)) \ \S. (S \ A \ (\G. isGlb S \ pset = A, order = r\ G))" apply safe apply (rule_tac x = "lub {y. y \ A & (\k \ S. (y, k) \ r)} \pset = A, order = r\ " in exI) apply (drule_tac x = "{y. y \ A & (\k \ S. (y,k) \ r) }" in spec) apply (drule mp, fast) apply (simp add: isLub_lub isGlb_def) apply (simp add: isLub_def, blast) done lemma lub_dual_glb: "lub S cl = glb S (dual cl)" by (simp add: lub_def glb_def least_def greatest_def dual_def converse_def) lemma glb_dual_lub: "glb S cl = lub S (dual cl)" by (simp add: lub_def glb_def least_def greatest_def dual_def converse_def) lemma CL_subset_PO: "CompleteLattice \ PartialOrder" by (simp add: PartialOrder_def CompleteLattice_def, fast) lemmas CL_imp_PO = CL_subset_PO [THEN subsetD] (*declare CL_imp_PO [THEN PO.PO_imp_refl, simp] declare CL_imp_PO [THEN PO.PO_imp_sym, simp] declare CL_imp_PO [THEN PO.PO_imp_trans, simp]*) lemma (in CL) CO_refl_on: "refl_on A r" by (rule PO_imp_refl_on) lemma (in CL) CO_antisym: "antisym r" by (rule PO_imp_sym) lemma (in CL) CO_trans: "trans r" by (rule PO_imp_trans) lemma CompleteLatticeI: "\ po \ PartialOrder; (\S. S \ pset po \ (\L. isLub S po L)); (\S. S \ pset po \ (\G. isGlb S po G))\ \ po \ CompleteLattice" apply (unfold CompleteLattice_def, blast) done lemma (in CL) CL_dualCL: "dual cl \ CompleteLattice" apply (insert cl_co) apply (simp add: CompleteLattice_def dual_def) apply (fold dual_def) apply (simp add: isLub_dual_isGlb [symmetric] isGlb_dual_isLub [symmetric] dualPO) done lemma (in PO) dualA_iff: "pset (dual cl) = pset cl" by (simp add: dual_def) lemma (in PO) dualr_iff: "((x, y) \ (order(dual cl))) = ((y, x) \ order cl)" by (simp add: dual_def) lemma (in PO) monotone_dual: "monotone f (pset cl) (order cl) \ monotone f (pset (dual cl)) (order(dual cl))" by (simp add: monotone_def dualA_iff dualr_iff) lemma (in PO) interval_dual: "\ x \ A; y \ A\ \ interval r x y = interval (order(dual cl)) y x" apply (simp add: interval_def dualr_iff) apply (fold r_def, fast) done lemma (in PO) trans: "(x, y) \ r \ (y, z) \ r \ (x, z) \ r" using cl_po apply (auto simp add: PartialOrder_def r_def) unfolding trans_def by blast lemma (in PO) interval_not_empty: "interval r a b \ {} \ (a, b) \ r" apply (simp add: interval_def) using trans by blast lemma (in PO) interval_imp_mem: "x \ interval r a b \ (a, x) \ r" by (simp add: interval_def) lemma (in PO) left_in_interval: "\ a \ A; b \ A; interval r a b \ {} \ \ a \ interval r a b" apply (simp (no_asm_simp) add: interval_def) apply (simp add: PO_imp_trans interval_not_empty) apply (simp add: reflE) done lemma (in PO) right_in_interval: "\ a \ A; b \ A; interval r a b \ {} \ \ b \ interval r a b" apply (simp (no_asm_simp) add: interval_def) apply (simp add: PO_imp_trans interval_not_empty) apply (simp add: reflE) done subsection {* sublattice *} lemma (in PO) sublattice_imp_CL: "S \= cl \ \ pset = S, order = induced S r \ \ CompleteLattice" by (simp add: sublattice_def CompleteLattice_def r_def) lemma (in CL) sublatticeI: "\ S \ A; \ pset = S, order = induced S r \ \ CompleteLattice \ \ S \= cl" by (simp add: sublattice_def A_def r_def) lemma (in CL) dual: "CL (dual cl)" apply unfold_locales using cl_co unfolding CompleteLattice_def apply (simp add: dualPO isGlb_dual_isLub [symmetric] isLub_dual_isGlb [symmetric] dualA_iff) done subsection {* lub *} lemma (in CL) lub_unique: "\ S \ A; isLub S cl x; isLub S cl L\ \ x = L" apply (rule antisymE) apply (auto simp add: isLub_def r_def) done lemma (in CL) lub_upper: "\S \ A; x \ S\ \ (x, lub S cl) \ r" apply (rule CL_imp_ex_isLub [THEN exE], assumption) apply (unfold lub_def least_def) apply (rule some_equality [THEN ssubst]) apply (simp add: isLub_def) apply (simp add: lub_unique A_def isLub_def) apply (simp add: isLub_def r_def) done lemma (in CL) lub_least: "\ S \ A; L \ A; \x \ S. (x,L) \ r \ \ (lub S cl, L) \ r" apply (rule CL_imp_ex_isLub [THEN exE], assumption) apply (unfold lub_def least_def) apply (rule_tac s=x in some_equality [THEN ssubst]) apply (simp add: isLub_def) apply (simp add: lub_unique A_def isLub_def) apply (simp add: isLub_def r_def A_def) done lemma (in CL) lub_in_lattice: "S \ A \ lub S cl \ A" apply (rule CL_imp_ex_isLub [THEN exE], assumption) apply (unfold lub_def least_def) apply (subst some_equality) apply (simp add: isLub_def) prefer 2 apply (simp add: isLub_def A_def) apply (simp add: lub_unique A_def isLub_def) done lemma (in CL) lubI: "\ S \ A; L \ A; \x \ S. (x,L) \ r; \z \ A. (\y \ S. (y,z) \ r) \ (L,z) \ r \ \ L = lub S cl" apply (rule lub_unique, assumption) apply (simp add: isLub_def A_def r_def) apply (unfold isLub_def) apply (rule conjI) apply (fold A_def r_def) apply (rule lub_in_lattice, assumption) apply (simp add: lub_upper lub_least) done lemma (in CL) lubIa: "\ S \ A; isLub S cl L \ \ L = lub S cl" by (simp add: lubI isLub_def A_def r_def) lemma (in CL) isLub_in_lattice: "isLub S cl L \ L \ A" by (simp add: isLub_def A_def) lemma (in CL) isLub_upper: "\isLub S cl L; y \ S\ \ (y, L) \ r" by (simp add: isLub_def r_def) lemma (in CL) isLub_least: "\ isLub S cl L; z \ A; \y \ S. (y, z) \ r\ \ (L, z) \ r" by (simp add: isLub_def A_def r_def) lemma (in CL) isLubI: "\ L \ A; \y \ S. (y, L) \ r; (\z \ A. (\y \ S. (y, z):r) \ (L, z) \ r)\ \ isLub S cl L" by (simp add: isLub_def A_def r_def) subsection {* glb *} lemma (in CL) glb_in_lattice: "S \ A \ glb S cl \ A" apply (subst glb_dual_lub) apply (simp add: A_def) apply (rule dualA_iff [THEN subst]) apply (rule CL.lub_in_lattice) apply (rule dual) apply (simp add: dualA_iff) done lemma (in CL) glb_lower: "\S \ A; x \ S\ \ (glb S cl, x) \ r" apply (subst glb_dual_lub) apply (simp add: r_def) apply (rule dualr_iff [THEN subst]) apply (rule CL.lub_upper) apply (rule dual) apply (simp add: dualA_iff A_def, assumption) done text {* Reduce the sublattice property by using substructural properties; abandoned see @{text "Tarski_4.ML"}. *} lemma (in CLF) [simp]: "f: pset cl \ pset cl & monotone f (pset cl) (order cl)" apply (insert f_cl) apply (simp add: CLF_set_def) done declare (in CLF) f_cl [simp] lemma (in CLF) f_in_funcset: "f \ A \ A" by (simp add: A_def) lemma (in CLF) monotone_f: "monotone f A r" by (simp add: A_def r_def) lemma (in CLF) CLF_dual: "(dual cl, f) \ CLF_set" apply (simp add: CLF_set_def CL_dualCL monotone_dual) apply (simp add: dualA_iff) done lemma (in CLF) dual: "CLF (dual cl) f" apply (rule CLF.intro) apply (rule CLF_dual) done subsection {* fixed points *} lemma fix_subset: "fix f A \ A" by (simp add: fix_def, fast) lemma fix_imp_eq: "x \ fix f A \ f x = x" by (simp add: fix_def) lemma fixf_subset: "\ A \ B; x \ fix (%y: A. f y) A \ \ x \ fix f B" by (simp add: fix_def, auto) subsection {* lemmas for Tarski, lub *} lemma (in CLF) lubH_le_flubH: "H = {x. (x, f x) \ r & x \ A} \ (lub H cl, f (lub H cl)) \ r" apply (rule lub_least, fast) apply (rule f_in_funcset [THEN funcset_mem]) apply (rule lub_in_lattice, fast) -- {* @{text "\x:H. (x, f (lub H r)) \ r"} *} apply (rule ballI) apply (rule transE) -- {* instantiates @{text "(x, ???z) \ order cl to (x, f x)"}, *} -- {* because of the def of @{text H} *} apply fast -- {* so it remains to show @{text "(f x, f (lub H cl)) \ r"} *} apply (rule_tac f = "f" in monotoneE) apply (rule monotone_f, fast) apply (rule lub_in_lattice, fast) apply (rule lub_upper, fast) apply assumption done lemma (in CLF) flubH_le_lubH: "\ H = {x. (x, f x) \ r & x \ A} \ \ (f (lub H cl), lub H cl) \ r" apply (rule lub_upper, fast) apply (rule_tac t = "H" in ssubst, assumption) apply (rule CollectI) apply (rule conjI) apply (rule_tac [2] f_in_funcset [THEN funcset_mem]) apply (rule_tac [2] lub_in_lattice) prefer 2 apply fast apply (rule_tac f = "f" in monotoneE) apply (rule monotone_f) apply (blast intro: lub_in_lattice) apply (blast intro: lub_in_lattice f_in_funcset [THEN funcset_mem]) apply (simp add: lubH_le_flubH) done lemma (in CLF) lubH_is_fixp: "H = {x. (x, f x) \ r & x \ A} \ lub H cl \ fix f A" apply (simp add: fix_def) apply (rule conjI) apply (rule lub_in_lattice, fast) apply (rule antisymE) apply (simp add: flubH_le_lubH) apply (simp add: lubH_le_flubH) done lemma (in CLF) fix_in_H: "\ H = {x. (x, f x) \ r & x \ A}; x \ P \ \ x \ H" by (simp add: P_def fix_imp_eq [of _ f A] reflE CO_refl_on fix_subset [of f A, THEN subsetD]) lemma (in CLF) fixf_le_lubH: "H = {x. (x, f x) \ r & x \ A} \ \x \ fix f A. (x, lub H cl) \ r" apply (rule ballI) apply (rule lub_upper, fast) apply (rule fix_in_H) apply (simp_all add: P_def) done lemma (in CLF) lubH_least_fixf: "H = {x. (x, f x) \ r & x \ A} \ \L. (\y \ fix f A. (y,L) \ r) \ (lub H cl, L) \ r" apply (rule allI) apply (rule impI) apply (erule bspec) apply (rule lubH_is_fixp, assumption) done subsection {* Tarski fixpoint theorem 1, first part *} lemma (in CLF) T_thm_1_lub: "lub P cl = lub {x. (x, f x) \ r & x \ A} cl" apply (rule sym) apply (simp add: P_def) apply (rule lubI) apply (rule fix_subset) apply (rule lub_in_lattice, fast) apply (simp add: fixf_le_lubH) apply (simp add: lubH_least_fixf) done lemma (in CLF) glbH_is_fixp: "H = {x. (f x, x) \ r & x \ A} \ glb H cl \ P" -- {* Tarski for glb *} apply (simp add: glb_dual_lub P_def A_def r_def) apply (rule dualA_iff [THEN subst]) apply (rule CLF.lubH_is_fixp) apply (rule dual) apply (simp add: dualr_iff dualA_iff) done lemma (in CLF) T_thm_1_glb: "glb P cl = glb {x. (f x, x) \ r & x \ A} cl" apply (simp add: glb_dual_lub P_def A_def r_def) apply (rule dualA_iff [THEN subst]) apply (simp add: CLF.T_thm_1_lub [of _ f, OF dual] dualPO CL_dualCL CLF_dual dualr_iff) done subsection {* interval *} lemma (in CLF) rel_imp_elem: "(x, y) \ r \ x \ A" apply (insert CO_refl_on) apply (simp add: refl_on_def, blast) done lemma (in CLF) interval_subset: "\ a \ A; b \ A \ \ interval r a b \ A" apply (simp add: interval_def) apply (blast intro: rel_imp_elem) done lemma (in CLF) intervalI: "\ (a, x) \ r; (x, b) \ r \ \ x \ interval r a b" by (simp add: interval_def) lemma (in CLF) interval_lemma1: "\ S \ interval r a b; x \ S \ \ (a, x) \ r" by (unfold interval_def, fast) lemma (in CLF) interval_lemma2: "\ S \ interval r a b; x \ S \ \ (x, b) \ r" by (unfold interval_def, fast) lemma (in CLF) a_less_lub: "\ S \ A; S \ {}; \x \ S. (a,x) \ r; \y \ S. (y, L) \ r \ \ (a,L) \ r" by (blast intro: transE) lemma (in CLF) glb_less_b: "\ S \ A; S \ {}; \x \ S. (x,b) \ r; \y \ S. (G, y) \ r \ \ (G,b) \ r" by (blast intro: transE) lemma (in CLF) S_intv_cl: "\ a \ A; b \ A; S \ interval r a b \\ S \ A" by (simp add: subset_trans [OF _ interval_subset]) lemma (in CLF) L_in_interval: "\ a \ A; b \ A; S \ interval r a b; S \ {}; isLub S cl L; interval r a b \ {} \ \ L \ interval r a b" apply (rule intervalI) apply (rule a_less_lub) prefer 2 apply assumption apply (simp add: S_intv_cl) apply (rule ballI) apply (simp add: interval_lemma1) apply (simp add: isLub_upper) -- {* @{text "(L, b) \ r"} *} apply (simp add: isLub_least interval_lemma2) done lemma (in CLF) G_in_interval: "\ a \ A; b \ A; interval r a b \ {}; S \ interval r a b; isGlb S cl G; S \ {} \ \ G \ interval r a b" apply (simp add: interval_dual) apply (simp add: CLF.L_in_interval [of _ f, OF dual] dualA_iff A_def isGlb_dual_isLub) done lemma (in CLF) intervalPO: "\ a \ A; b \ A; interval r a b \ {} \ \ \ pset = interval r a b, order = induced (interval r a b) r \ \ PartialOrder" apply (rule po_subset_po) apply (simp add: interval_subset) done lemma (in CLF) intv_CL_lub: "\ a \ A; b \ A; interval r a b \ {} \ \ \S. S \ interval r a b \ (\L. isLub S \ pset = interval r a b, order = induced (interval r a b) r \ L)" apply (intro strip) apply (frule S_intv_cl [THEN CL_imp_ex_isLub]) prefer 2 apply assumption apply assumption apply (erule exE) -- {* define the lub for the interval as *} apply (rule_tac x = "if S = {} then a else L" in exI) apply (simp (no_asm_simp) add: isLub_def split del: split_if) apply (intro impI conjI) -- {* @{text "(if S = {} then a else L) \ interval r a b"} *} apply (simp add: CL_imp_PO L_in_interval) apply (simp add: left_in_interval) -- {* lub prop 1 *} apply (case_tac "S = {}") -- {* @{text "S = {}, y \ S = False \ everything"} *} apply fast -- {* @{text "S \ {}"} *} apply simp -- {* @{text "\y:S. (y, L) \ induced (interval r a b) r"} *} apply (rule ballI) apply (simp add: induced_def L_in_interval) apply (rule conjI) apply (rule subsetD) apply (simp add: S_intv_cl, assumption) apply (simp add: isLub_upper) -- {* @{text "\z:interval r a b. (\y:S. (y, z) \ induced (interval r a b) r \ (if S = {} then a else L, z) \ induced (interval r a b) r"} *} apply (rule ballI) apply (rule impI) apply (case_tac "S = {}") -- {* @{text "S = {}"} *} apply simp apply (simp add: induced_def interval_def) apply (rule conjI) apply (rule reflE, assumption) apply (rule interval_not_empty) apply (simp add: interval_def) -- {* @{text "S \ {}"} *} apply simp apply (simp add: induced_def L_in_interval) apply (rule isLub_least, assumption) apply (rule subsetD) prefer 2 apply assumption apply (simp add: S_intv_cl, fast) done lemmas (in CLF) intv_CL_glb = intv_CL_lub [THEN Rdual] lemma (in CLF) interval_is_sublattice: "\ a \ A; b \ A; interval r a b \ {} \ \ interval r a b \= cl" apply (rule sublatticeI) apply (simp add: interval_subset) apply (rule CompleteLatticeI) apply (simp add: intervalPO) apply (simp add: intv_CL_lub) apply (simp add: intv_CL_glb) done lemmas (in CLF) interv_is_compl_latt = interval_is_sublattice [THEN sublattice_imp_CL] subsection {* Top and Bottom *} lemma (in CLF) Top_dual_Bot: "Top cl = Bot (dual cl)" by (simp add: Top_def Bot_def least_def greatest_def dualA_iff dualr_iff) lemma (in CLF) Bot_dual_Top: "Bot cl = Top (dual cl)" by (simp add: Top_def Bot_def least_def greatest_def dualA_iff dualr_iff) lemma (in CLF) Bot_in_lattice: "Bot cl \ A" apply (simp add: Bot_def least_def) apply (rule_tac a="glb A cl" in someI2) apply (simp_all add: glb_in_lattice glb_lower r_def [symmetric] A_def [symmetric]) done lemma (in CLF) Top_in_lattice: "Top cl \ A" apply (simp add: Top_dual_Bot A_def) apply (rule dualA_iff [THEN subst]) apply (rule CLF.Bot_in_lattice [OF dual]) done lemma (in CLF) Top_prop: "x \ A \ (x, Top cl) \ r" apply (simp add: Top_def greatest_def) apply (rule_tac a="lub A cl" in someI2) apply (rule someI2) apply (simp_all add: lub_in_lattice lub_upper r_def [symmetric] A_def [symmetric]) done lemma (in CLF) Bot_prop: "x \ A \ (Bot cl, x) \ r" apply (simp add: Bot_dual_Top r_def) apply (rule dualr_iff [THEN subst]) apply (rule CLF.Top_prop [OF dual]) apply (simp add: dualA_iff A_def) done lemma (in CLF) Top_intv_not_empty: "x \ A \ interval r x (Top cl) \ {}" apply (rule notI) apply (drule_tac a = "Top cl" in equals0D) apply (simp add: interval_def) apply (simp add: refl_on_def Top_in_lattice Top_prop) done lemma (in CLF) Bot_intv_not_empty: "x \ A \ interval r (Bot cl) x \ {}" apply (simp add: Bot_dual_Top) apply (subst interval_dual) prefer 2 apply assumption apply (simp add: A_def) apply (rule dualA_iff [THEN subst]) apply (rule CLF.Top_in_lattice [OF dual]) apply (rule CLF.Top_intv_not_empty [OF dual]) apply (simp add: dualA_iff A_def) done subsection {* fixed points form a partial order *} lemma (in CLF) fixf_po: "\ pset = P, order = induced P r\ \ PartialOrder" by (simp add: P_def fix_subset po_subset_po) lemma (in Tarski) Y_subset_A: "Y \ A" apply (rule subset_trans [OF _ fix_subset]) apply (rule Y_ss [simplified P_def]) done lemma (in Tarski) lubY_in_A: "lub Y cl \ A" by (rule Y_subset_A [THEN lub_in_lattice]) lemma (in Tarski) lubY_le_flubY: "(lub Y cl, f (lub Y cl)) \ r" apply (rule lub_least) apply (rule Y_subset_A) apply (rule f_in_funcset [THEN funcset_mem]) apply (rule lubY_in_A) -- {* @{text "Y \ P \ f x = x"} *} apply (rule ballI) apply (rule_tac t = "x" in fix_imp_eq [THEN subst]) apply (erule Y_ss [simplified P_def, THEN subsetD]) -- {* @{text "reduce (f x, f (lub Y cl)) \ r to (x, lub Y cl) \ r"} by monotonicity *} apply (rule_tac f = "f" in monotoneE) apply (rule monotone_f) apply (simp add: Y_subset_A [THEN subsetD]) apply (rule lubY_in_A) apply (simp add: lub_upper Y_subset_A) done lemma (in Tarski) intY1_subset: "intY1 \ A" apply (unfold intY1_def) apply (rule interval_subset) apply (rule lubY_in_A) apply (rule Top_in_lattice) done lemmas (in Tarski) intY1_elem = intY1_subset [THEN subsetD] lemma (in Tarski) intY1_f_closed: "x \ intY1 \ f x \ intY1" apply (simp add: intY1_def interval_def) apply (rule conjI) apply (rule transE) apply (rule lubY_le_flubY) -- {* @{text "(f (lub Y cl), f x) \ r"} *} apply (rule_tac f=f in monotoneE) apply (rule monotone_f) apply (rule lubY_in_A) apply (simp add: intY1_def interval_def intY1_elem) apply (simp add: intY1_def interval_def) -- {* @{text "(f x, Top cl) \ r"} *} apply (rule Top_prop) apply (rule f_in_funcset [THEN funcset_mem]) apply (simp add: intY1_def interval_def intY1_elem) done lemma (in Tarski) intY1_mono: "monotone (%x: intY1. f x) intY1 (induced intY1 r)" apply (auto simp add: monotone_def induced_def intY1_f_closed) apply (blast intro: intY1_elem monotone_f [THEN monotoneE]) done lemma (in Tarski) intY1_is_cl: "\ pset = intY1, order = induced intY1 r \ \ CompleteLattice" apply (unfold intY1_def) apply (rule interv_is_compl_latt) apply (rule lubY_in_A) apply (rule Top_in_lattice) apply (rule Top_intv_not_empty) apply (rule lubY_in_A) done lemma (in Tarski) v_in_P: "v \ P" apply (unfold P_def) apply (rule_tac A = "intY1" in fixf_subset) apply (rule intY1_subset) unfolding v_def apply (rule CLF.glbH_is_fixp [OF CLF.intro, unfolded CLF_set_def, of "\pset = intY1, order = induced intY1 r\", simplified]) apply auto apply (rule intY1_is_cl) apply (erule intY1_f_closed) apply (rule intY1_mono) done lemma (in Tarski) z_in_interval: "\ z \ P; \y\Y. (y, z) \ induced P r \ \ z \ intY1" apply (unfold intY1_def P_def) apply (rule intervalI) prefer 2 apply (erule fix_subset [THEN subsetD, THEN Top_prop]) apply (rule lub_least) apply (rule Y_subset_A) apply (fast elim!: fix_subset [THEN subsetD]) apply (simp add: induced_def) done lemma (in Tarski) f'z_in_int_rel: "\ z \ P; \y\Y. (y, z) \ induced P r \ \ ((%x: intY1. f x) z, z) \ induced intY1 r" apply (simp add: induced_def intY1_f_closed z_in_interval P_def) apply (simp add: fix_imp_eq [of _ f A] fix_subset [of f A, THEN subsetD] reflE) done lemma (in Tarski) tarski_full_lemma: "\L. isLub Y \ pset = P, order = induced P r \ L" apply (rule_tac x = "v" in exI) apply (simp add: isLub_def) -- {* @{text "v \ P"} *} apply (simp add: v_in_P) apply (rule conjI) -- {* @{text v} is lub *} -- {* @{text "1. \y:Y. (y, v) \ induced P r"} *} apply (rule ballI) apply (simp add: induced_def subsetD v_in_P) apply (rule conjI) apply (erule Y_ss [THEN subsetD]) apply (rule_tac b = "lub Y cl" in transE) apply (rule lub_upper) apply (rule Y_subset_A, assumption) apply (rule_tac b = "Top cl" in interval_imp_mem) apply (simp add: v_def) apply (fold intY1_def) apply (rule CL.glb_in_lattice [OF CL.intro [OF intY1_is_cl], simplified]) apply auto apply (rule indI) prefer 3 apply assumption prefer 2 apply (simp add: v_in_P) apply (unfold v_def) apply (rule indE) apply (rule_tac [2] intY1_subset) apply (rule CL.glb_lower [OF CL.intro [OF intY1_is_cl], simplified]) apply (simp add: CL_imp_PO intY1_is_cl) apply force apply (simp add: induced_def intY1_f_closed z_in_interval) apply (simp add: P_def fix_imp_eq [of _ f A] reflE fix_subset [of f A, THEN subsetD]) done lemma CompleteLatticeI_simp: "\ \ pset = A, order = r \ \ PartialOrder; \S. S \ A \ (\L. isLub S \ pset = A, order = r \ L) \ \ \ pset = A, order = r \ \ CompleteLattice" by (simp add: CompleteLatticeI Rdual) theorem (in CLF) Tarski_full: "\ pset = P, order = induced P r\ \ CompleteLattice" apply (rule CompleteLatticeI_simp) apply (rule fixf_po, clarify) apply (simp add: P_def A_def r_def) apply (rule Tarski.tarski_full_lemma [OF Tarski.intro [OF _ Tarski_axioms.intro]]) proof - show "CLF cl f" .. qed end proofgeneral-4.3~pre130510/isar/interface000077500000000000000000000105051214562307500202540ustar00rootroot00000000000000#!/usr/bin/env bash # # $Id: interface,v 12.0 2011/10/13 10:54:50 da Exp $ # # Proof General interface wrapper for Isabelle. ## self references THIS="$(cd "$(dirname "$0")"; pwd)" SUPER="$(cd "$THIS/.."; pwd)" ## diagnostics usage() { echo echo "Usage: isabelle emacs [OPTIONS] [FILES ...]" echo echo " Options are:" echo " -L NAME abbreviates -l NAME -k NAME" echo " -U BOOL enable UTF-8 communication (default true)" echo " -f FONT specify Emacs font" 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 emacs)" echo " -u BOOL use personal .emacs file (default true)" echo " -w BOOL use window system (default true)" echo " -x BOOL render Isabelle symbols via Unicode (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="" KEYWORDS="" LOGIC="$ISABELLE_LOGIC" UNICODE="" FONT="" GEOMETRY="" PROGNAME="emacs" INITFILE="true" WINDOWSYSTEM="true" UNICODE_SYMBOLS="" getoptions() { OPTIND=1 while getopts "L:U:f:g:k:l:m:p:u:w:x:" OPT do case "$OPT" in L) KEYWORDS="$OPTARG" LOGIC="$OPTARG" ;; U) UNICODE="$OPTARG" ;; f) FONT="$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) UNICODE_SYMBOLS="$OPTARG" ;; \?) usage ;; esac done } eval "OPTIONS=($PROOFGENERAL_OPTIONS)" getoptions "${OPTIONS[@]}" getoptions "$@" shift $(($OPTIND - 1)) # args declare -a FILES=() if [ "$#" -eq 0 ]; then FILES["${#FILES[@]}"]="Scratch.thy" else while [ "$#" -gt 0 ]; do FILES["${#FILES[@]}"]="$1" shift done fi ## main declare -a ARGS=() if [ -n "$FONT" ]; then ARGS["${#ARGS[@]}"]="-fn" ARGS["${#ARGS[@]}"]="$FONT" fi if [ -n "$GEOMETRY" ]; then ARGS["${#ARGS[@]}"]="-geometry" ARGS["${#ARGS[@]}"]="$GEOMETRY" fi [ "$INITFILE" = false ] && ARGS["${#ARGS[@]}"]="-q" [ "$WINDOWSYSTEM" = false ] && ARGS["${#ARGS[@]}"]="-nw" ARGS["${#ARGS[@]}"]="-l" ARGS["${#ARGS[@]}"]="$SUPER/isar/interface-setup.el" if [ -n "$KEYWORDS" ]; then if [ -f "$ISABELLE_HOME_USER/etc/isar-keywords-$KEYWORDS.el" ]; then ARGS["${#ARGS[@]}"]="-l" ARGS["${#ARGS[@]}"]="$ISABELLE_HOME_USER/etc/isar-keywords-$KEYWORDS.el" elif [ -f "$ISABELLE_HOME/etc/isar-keywords-$KEYWORDS.el" ]; then ARGS["${#ARGS[@]}"]="-l" ARGS["${#ARGS[@]}"]="$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" ARGS["${#ARGS[@]}"]="$ISABELLE_HOME_USER/etc/isar-keywords.el" elif [ -f "$ISABELLE_HOME/etc/isar-keywords.el" ]; then ARGS["${#ARGS[@]}"]="-l" ARGS["${#ARGS[@]}"]="$ISABELLE_HOME/etc/isar-keywords.el" fi for FILE in "$ISABELLE_HOME/etc/proofgeneral-settings.el" \ "$ISABELLE_HOME_USER/etc/proofgeneral-settings.el" do if [ -f "$FILE" ]; then ARGS["${#ARGS[@]}"]="-l" ARGS["${#ARGS[@]}"]="$FILE" fi done case "$LOGIC" in /*) ;; */*) LOGIC="$(pwd -P)/$LOGIC" ;; esac export PROOFGENERAL_HOME="$SUPER" export PROOFGENERAL_ASSISTANTS="isar" export PROOFGENERAL_LOGIC="$LOGIC" export PROOFGENERAL_UNICODE="$UNICODE" export PROOFGENERAL_UNICODE_SYMBOLS="$UNICODE_SYMBOLS" export ISABELLE_OPTIONS # Isabelle2008 compatibility [ -z "$ISABELLE_PROCESS" ] && export ISABELLE_PROCESS="$ISABELLE" [ -z "$ISABELLE_TOOL" ] && export ISABELLE_TOOL="$ISATOOL" exec "$PROGNAME" "${ARGS[@]}" "${FILES[@]}" proofgeneral-4.3~pre130510/isar/interface-setup.el000066400000000000000000000020251214562307500220040ustar00rootroot00000000000000;; 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 ;; ;; interface-setup.el,v 7.0 2002/08/29 09:14:03 da Exp ;; ;; ;; Tool bar ;; (if (and window-system (fboundp 'tool-bar-mode)) (tool-bar-mode t)) ;; ;; Unicode ;; (let ((unicode (getenv "PROOFGENERAL_UNICODE"))) (if (and unicode (not (equal unicode ""))) (customize-set-variable 'proof-shell-unicode (equal unicode "true")))) ;; ;; Unicode symbols ;; (let ((symbols (getenv "PROOFGENERAL_UNICODE_SYMBOLS"))) (if (and symbols (not (equal symbols ""))) (customize-set-variable 'isar-unicode-tokens-enable (equal symbols "true")))) ;; ;; Proof General startup ;; (if (not (featurep 'proof-site)) (load (concat (getenv "PROOFGENERAL_HOME") "/generic/proof-site.el"))) proofgeneral-4.3~pre130510/isar/isabelle-system.el000066400000000000000000000321601214562307500220130ustar00rootroot00000000000000;; isabelle-system.el --- Interface with Isabelle system ;; ;; Copyright (C) 2000 LFCS Edinburgh, David Aspinall. ;; ;; Author: David Aspinall ;; Maintainer: Proof General maintainer ;; ;; $Id: isabelle-system.el,v 12.4 2012/08/30 14:30:23 monnier Exp $ ;; ;; Most of this code is taken from the final version of Isamode. ;; -------------------------------------------------------------- ;; ;;; Code: (eval-when-compile (require 'cl)) ; mapcan, eval-when (eval-when (compile) (require 'span) (require 'scomint) (require 'proof-site) (require 'proof-menu) (require 'proof-syntax) (proof-ready-for-assistant 'isar) ; compile for isar (defvar proof-assistant-menu nil)) (declare-function mapcan "cl-extra") ; spurious bytecomp warning ;; The isabelle custom group won't have been defined yet. (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/" "URL of web page for Isabelle." :type 'string :group 'isabelle) ;;; ================ Extract Isabelle settings ================ (defcustom isa-isabelle-command (or (if proof-rsh-command ;; not much hope to locate executable remotely (concat proof-rsh-command " isabelle")) (getenv "ISABELLE_TOOL") (proof-locate-executable "isabelle" nil (list ;; support default unpack in home dir situation (concat (getenv "HOME") "/Isabelle/bin/"))) "path_to_isabelle_is_unknown") "Command to invoke the main Isabelle wrapper 'isabelle'. Emacs should be able to find `isabelle' 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) (defvar isabelle-not-found nil "Non-nil if user has been prompted for `isabelle' already and it wasn't found.") (defun isa-set-isabelle-command (&optional force) "Make sure `isa-isabelle-command' points to a valid executable. If it does not, or if prefix arg supplied, prompt the user for the proper setting. If `proof-rsh-command' is set, leave this unverified. Otherwise, returns non-nil if isa-isabelle-command is surely an executable with full path." (interactive "p") (when (and (not noninteractive) (not proof-rsh-command) (or force isabelle-not-found (not (file-executable-p isa-isabelle-command)))) (setq isa-isabelle-command (read-file-name "Full path to `isabelle' command (anything non-executable if you don't have it): " nil nil nil)) (unless (file-executable-p isa-isabelle-command) (setq isabelle-not-found t) (beep) (warn "Proof General: isabelle command not found; some menus will be incomplete and Isabelle may not run correctly. Please check your Isabelle installation."))) (or proof-rsh-command (file-executable-p isa-isabelle-command))) (defun isa-shell-command-to-string (command) "Like shell-command-to-string except the last character is stripped." (let ((s (shell-command-to-string command))) (if (equal (length s) 0) s (substring s 0 -1)))) (defun isa-getenv (envvar &optional default) "Extract environment variable ENVVAR setting using the `isabelle' program. If the isabelle 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-isabelle-command) (if (or proof-rsh-command (file-executable-p isa-isabelle-command)) (let ((setting (isa-shell-command-to-string (concat "\"" isa-isabelle-command "\" getenv -b " envvar)))) (if (string-equal setting "") default setting)) (or (getenv envvar) default))) ;;; ;;; ======= Interaction with System using Isabelle tools ======= ;;; (defcustom isabelle-program-name-override nil "*Name of executable program to run Isabelle. You can set customize this in case the automatic settings mechanism does not work for you, perhaps because isabelle is not on your path, or you are running it remotely. The logic image name is tagged onto the end." :type 'file :group 'isabelle) (defun isa-tool-list-logics () "Generate a list of available object logics." (if (isa-set-isabelle-command) (delete "" (split-string (isa-shell-command-to-string (concat "\"" isa-isabelle-command "\" findlogics")) "[ \t]")))) (defcustom isabelle-logics-available nil "*List of logics available to use with Isabelle. If the `isabelle' program is available, this is automatically generated with the Lisp form `(isa-tool-list-logics)'." :type (list 'string) :group 'isabelle) (unless noninteractive (setq isabelle-logics-available (isa-tool-list-logics))) (defcustom isabelle-chosen-logic nil "*Choice of logic to use with Isabelle. If non-nil, added onto the Isabelle command line for invoking Isabelle. You can set this as a file local variable, using a special comment at the top of your theory file, like this: (* -*- isabelle-chosen-logic: \"ZF\" -*- *)" :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) (put 'isabelle-chosen-logic 'safe-local-variable 'stringp) (defvar isabelle-chosen-logic-prev nil "Value of `isabelle-chosen-logic' on last call of `isabelle-set-prog-name'.") (defun isabelle-hack-local-variables-function () "Hook function for `hack-local-variables-hook'." (if (and isabelle-chosen-logic (not (equal isabelle-chosen-logic isabelle-chosen-logic-prev)) (proof-shell-live-buffer)) (message "Warning: chosen logic %s does not match running Isabelle instance" isabelle-chosen-logic))) (add-hook 'hack-local-variables-hook 'isabelle-hack-local-variables-function) (defun isabelle-set-prog-name (&optional filename) "Make proper command line for running Isabelle. This function sets `proof-prog-name' and `isar-prog-args'." (let* ;; The ISABELLE_PROCESS and PROOFGENERAL_LOGIC values (set when ;; run under the interface wrapper script) indicate command line ;; is set in current Isabelle settings environment. ((isabelle (or isabelle-program-name-override ; override in Emacs (getenv "ISABELLE_PROCESS") ; command line override (isa-getenv "ISABELLE_PROCESS") ; choose to match isabelle "isabelle-process")) ; to (isabelle-opts (split-string (or (getenv "ISABELLE_OPTIONS") ""))) (opts (append (list "-PI") ;; Proof General + Isar (if proof-shell-unicode (list "-m" "PGASCII") nil) isabelle-opts)) (logic (or isabelle-chosen-logic (getenv "PROOFGENERAL_LOGIC"))) (logicarg (if (and logic (not (equal logic ""))) (list logic) nil))) (setq isabelle-chosen-logic-prev isabelle-chosen-logic) (setq isar-prog-args (append opts logicarg)) (setq proof-prog-name isabelle))) (defun isabelle-choose-logic (logic) "Adjust isabelle-prog-name and proof-prog-name for running LOGIC." (interactive (list (completing-read "Use logic: " (mapcar 'list (cons "Default" isabelle-logics-available))))) (if (proof-shell-live-buffer) (error "Can't change logic while Isabelle is running, please exit process first!")) (customize-set-variable 'isabelle-chosen-logic (unless (string-equal logic "Default") logic)) (isabelle-set-prog-name) ;; Settings are potentially different between logics, and ;; so are Isar keywords. Set these to nil so they get ;; automatically re-initialised. ;; FIXME: Isar keywords change not handled yet. (setq proof-assistant-settings nil) (setq proof-menu-settings nil)) (defun isa-view-doc (docname) "View Isabelle document DOCNAME, using Isabelle tools." (if (isa-set-isabelle-command) (apply 'start-process "isa-view-doc" nil (list isa-isabelle-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-isabelle-command) (let ((docs (isa-shell-command-to-string (concat "\"" isa-isabelle-command "\" doc")))) (unless (string-equal docs "") (mapcan (function (lambda (docdes) (if (proof-string-match "^[ \t]+\\(\\S-+\\)[ \t]+" docdes) (list (list (substring docdes (match-beginning 1) (match-end 1)) (substring docdes (match-end 0))))))) (split-string docs "\n")))))) (defconst isabelle-verbatim-regexp "\\`\^VERBATIM: \\(\\(.\\|\n\\)*\\)\\'" "Regexp matching internal marker for verbatim command output.") (defun isabelle-verbatim (str) "Mark internal command STR for verbatim output." (concat "\^VERBATIM: " str)) ;;; ========== Utility functions ========== (defcustom isabelle-refresh-logics t "*Whether to refresh the list of logics during an interactive session. If non-nil, then `isabelle findlogics' will be used to regenerate the `isabelle-logics-available' setting. If this tool does not work for you, you should disable this behaviour." :type 'boolean :group 'isabelle) (defvar 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.") (defvar isabelle-logics-menu-entries nil "Menu of logics available.") (defun isabelle-logics-menu-calculate () (setq isabelle-logics-menu-entries (cons "Logics" (append '(["Default" (isabelle-choose-logic nil) :active (not (proof-shell-live-buffer)) :style radio :selected (not isabelle-chosen-logic) :help "Switch to default 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) :help (format "Switch to %s logic" l))) isabelle-logics-available))))) (unless noninteractive (isabelle-logics-menu-calculate)) (defvar isabelle-time-to-refresh-logics t "Non-nil if we should refresh the logics list.") (defun isabelle-logics-menu-refresh () "Refresh isabelle-logics-menu-entries, returning new entries." (interactive) (if (and isabelle-refresh-logics (or isabelle-time-to-refresh-logics (called-interactively-p 'any))) (progn (setq isabelle-logics-available (isa-tool-list-logics)) (isabelle-logics-menu-calculate) ;; update the menu manually (easy-menu-add-item proof-assistant-menu nil isabelle-logics-menu-entries) (setq isabelle-time-to-refresh-logics nil) ;; just done it, don't repeat! (run-with-timer 4 nil ;; short delay to avoid doing this too often (lambda () (setq isabelle-time-to-refresh-logics t)))))) (defun isabelle-menu-bar-update-logics () "Update logics menu." (and (current-local-map) (keymapp (lookup-key (current-local-map) (vector 'menu-bar (intern proof-assistant)))) (isabelle-logics-menu-refresh))) (add-hook 'menu-bar-update-hook 'isabelle-menu-bar-update-logics) ;; Added in PG 3.4: load isar-keywords file. ;; This roughly follows the method given in the interface script. ;; It could be used to add an elisp command at the bottom of ;; a theory file, if we sorted out the load order a bit, or ;; added a facility to reconfigure. ;; TODO: also add something to spill out a keywords file? (defun isabelle-load-isar-keywords (&optional kw) (interactive "sLoad isar keywords: ") (let ((userhome (isa-getenv "ISABELLE_HOME_USER")) (isahome (isa-getenv "ISABELLE_HOME")) (isarkwel "%s/etc/isar-keywords-%s.el") (isarel "%s/etc/isar-keywords.el") (ifrdble (lambda (f) (if (file-readable-p f) f)))) (load-file (or (and kw (funcall ifrdble (format isarkwel userhome kw))) (and kw (funcall ifrdble (format isarkwel isahome kw))) (funcall ifrdble (format isarel userhome)) (funcall ifrdble (format isarel isahome)) (locate-library "isar-keywords"))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Context-senstive in-span menu additions ;; (defun isabelle-create-span-menu (span idiom name) (if (eq idiom 'proof) (let ((thm (span-property span 'name))) (list (vector "Visualise dependencies" `(proof-shell-invisible-command ,(format "thm_deps %s;" thm)) (not (string-equal thm proof-unnamed-theorem-name))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; XML as an SML string: add escapes for quotes ;; (defun isabelle-xml-sml-escapes (xmlstring) (replace-regexp-in-string "\"" "\\\"" xmlstring t t)) (defun isabelle-process-pgip (xmlstring) "Return an Isabelle or Isabelle/Isar command to process PGIP in XMLSTRING." (format "ProofGeneral.process_pgip \"%s\";" (isabelle-xml-sml-escapes xmlstring))) (provide 'isabelle-system) ;;; isabelle-system.el ends here proofgeneral-4.3~pre130510/isar/isar-autotest.el000066400000000000000000000077501214562307500215240ustar00rootroot00000000000000;; isar-autotest.el: tests of Isar Proof General. ;; ;; You can run these by issuing "make test.isar" in PG home dir. ;; ;; $Id: isar-autotest.el,v 12.2 2012/09/02 21:44:46 da Exp $ ;; (defvar isar-long-tests nil "Whether or not to perform lengthy tests") (require 'pg-autotest) (eval-when (compile) (require 'cl) (require 'proof-site) (proof-ready-for-assistant 'isar)) (declare-function isar-tracing:auto-quickcheck-toggle "isar.el") (declare-function isar-tracing:auto-solve-direct-toggle "isar.el") (declare-function isar-proof:parallel-proofs-toggle "isar.el") (unless noninteractive (pg-autotest start) ; can add 'debug flag for debug-on-error (pg-autotest log ".autotest.log") ; convention (pg-autotest timestart 'total) (pg-autotest remark "Testing standard Example.thy, Example-Xsym.thy") (pg-autotest script-wholefile "isar/Example.thy") ;; Test Trac#344 (nested spans bug with old-style undo) ;; TODO: should test with both undo styles (pg-autotest eval (proof-retract-buffer)) (proof-shell-wait) (goto-char 135) ; first line (pg-autotest eval (proof-goto-point)) (proof-shell-wait) (pg-autotest eval (proof-retract-buffer)) (proof-shell-wait) (goto-char 135) ; first line (pg-autotest eval (proof-goto-point)) (proof-shell-wait) (pg-autotest eval (proof-process-buffer)) (pg-autotest assert-full) ;; Speed up prover (pg-autotest eval (isar-tracing:auto-quickcheck-toggle 0)) (pg-autotest eval (isar-tracing:auto-solve-direct-toggle 0)) ; autosolve hammers this! (pg-autotest eval (proof-full-annotation-toggle 0)) (pg-autotest eval (isar-proof:parallel-proofs-toggle 0)) (proof-shell-wait) (pg-autotest script-wholefile "isar/Example-Tokens.thy") (pg-autotest remark "Testing prove-as-you-go (not replay)") (find-file ".autotest.thy") (erase-buffer) ; just in case exists (setq buffer-file-name nil) (pg-autotest eval (proof-electric-terminator-toggle 1)) (pg-autotest eval (insert "theory Example imports Main begin ")) ; no \n (proof-electric-terminator) (pg-autotest eval (insert "theorem and_comms: \"A & B --> B & A\"\n")) (proof-electric-terminator) (pg-autotest eval (insert "apply auto done\n")) (pg-autotest eval (insert "end")) (proof-electric-terminator) (pg-autotest assert-full) ;; Test Trac#138 (pg-autotest eval (proof-undo-last-successful-command)) (proof-shell-wait) (pg-autotest eval (proof-goto-end-of-locked)) (pg-autotest eval (insert "(* this is a comment *)")) (pg-autotest eval (proof-goto-point)) (proof-shell-wait) (pg-autotest eval (skip-chars-backward " \n\t")) (pg-autotest eval (insert " ")) ;; shouldn't give read-only error! (set-buffer-modified-p nil) (kill-buffer ".autotest.thy") (pg-autotest remark "Now in tokens mode") (pg-autotest eval (proof-unicode-tokens-toggle)) (pg-autotest script-wholefile "isar/Example-Tokens.thy") (pg-autotest remark "Testing random jumps and edits") (pg-autotest script-randomjumps "isar/Example.thy" 8) (when isar-long-tests (pg-autotest remark "Larger files...") (pg-autotest script-wholefile "etc/isar/AHundredTheorems.thy") (pg-autotest script-wholefile "isar/ex/Tarski.thy") (pg-autotest script-randomjumps "isar/ex/Tarski.thy" 10)) ; better test? (pg-autotest remark "Testing restarting the prover") (pg-autotest quit-prover) (pg-autotest remark "Simple test of multiple file behaviour:") (pg-autotest script-wholefile "etc/isar/multiple/C.thy") (pg-autotest assert-processed "etc/isar/multiple/C.thy") (pg-autotest assert-processed "etc/isar/multiple/A.thy") (pg-autotest assert-processed "etc/isar/multiple/B.thy") (pg-autotest retract-file "etc/isar/multiple/B.thy") (pg-autotest assert-unprocessed "etc/isar/multiple/B.thy") (pg-autotest assert-unprocessed "etc/isar/multiple/C.thy") (pg-autotest assert-processed "etc/isar/multiple/A.thy") (pg-autotest quit-prover) (pg-autotest remark "Complete") (pg-autotest timetaken 'total) (pg-autotest exit) ) proofgeneral-4.3~pre130510/isar/isar-find-theorems.el000066400000000000000000000410011214562307500224030ustar00rootroot00000000000000;; isar-find-theorems.el A search form for Isabelle's find_theorems command. ;; ;; Copyright (C) 2007 Tjark Weber ;; ;; 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. ;; ;; $Id: isar-find-theorems.el,v 12.0 2011/10/13 10:54:50 da Exp $ ;; (require 'pg-vars) (declare-function proof-find-theorems "pg-user") ;; search form field values (defvar isar-find-theorems-data (list "" ;; num "" ;; pattern "none" ;; intro "none" ;; elim "none" ;; dest "" ;; name "" ;; simp ) "Values of the Find Theorems search form's fields.") ;; make the original (minibuffer based) "Find theorems" command (from ;; ../generic/pg-user.el) available as isar-find-theorems-minibuffer; ;; return '(nil) so that isar-find-theorems-minibuffer works as a ;; value for isar-find-theorems-command (defun isar-find-theorems-minibuffer () "Search for items containing given constants (using the minibuffer)." (interactive) (let ((proof-find-theorems-command "find_theorems %s")) (call-interactively 'proof-find-theorems)) '(nil)) ;; isar-find-theorems-form (just like isar-find-theorems-minibuffer) can be ;; called interactively, and can be used as a value for ;; proof-find-theorems-command (returning '(nil) means that the actual ;; "find_theorems" command will NOT be issued to Isabelle by ;; proof-find-theorems in this case, but only later on by a handler function ;; for the form's "Find" button) (defun isar-find-theorems-form () "Search for items containing given constants (using a search form)." (interactive) (apply 'isar-find-theorems-create-searchform isar-find-theorems-data) '(nil)) ;; update the universal key bindings (see ../generic/pg-vars.el) ;; ;; C-c C-a C-m is bound to isar-find-theorems-minibuffer ;; C-c C-a C-f is bound to isar-find-theorems-form ;; ;; Note that C-c C-a C-f, although C-c C-a usually invokes the prover ;; assistant specific keymap, is defined as a universal key binding here. ;; This way it will be available in the same buffers as C-c C-f. (setq proof-universal-keys (cons '([(control c) (control a) (control m)] . isar-find-theorems-minibuffer) (cons '([(control c) (control a) (control f)] . isar-find-theorems-form) proof-universal-keys))) ;; Documentation, taken from isabelle/NEWS: ;; ;; * Command 'find_theorems' searches for a list of criteria instead of a ;; list of constants. Known criteria are: intro, elim, dest, name:string, ;; simp:term, and any term. Criteria can be preceded by '-' to select ;; theorems that do not match. Intro, elim, dest select theorems that ;; match the current goal, name:s selects theorems whose fully qualified ;; name contain s, and simp:term selects all simplification rules whose ;; lhs match term. Any other term is interpreted as pattern and selects ;; all theorems matching the pattern. Available in ProofGeneral under ;; 'ProofGeneral -> Find Theorems' or C-c C-f. Example: ;; ;; C-c C-f (100) "(_::nat) + _ + _" intro -name: "HOL." ;; ;; prints the last 100 theorems matching the pattern "(_::nat) + _ + _", ;; matching the current goal as introduction rule and not having "HOL." ;; in their name (i.e. not being defined in theory HOL). ;; search form widgets (set in isar-find-theorems-create-searchform ;; and accessed in the "Find" handler) (defvar isar-find-theorems-widget-number nil "Search form widget for the number of theorems.") (defvar isar-find-theorems-widget-pattern nil "Search form widget for search patterns.") (defvar isar-find-theorems-widget-intro nil "Search form widget for intro rules.") (defvar isar-find-theorems-widget-elim nil "Search form widget for elim rules.") (defvar isar-find-theorems-widget-dest nil "Search form widget for dest rules.") (defvar isar-find-theorems-widget-name nil "Search form widget for theorem names.") (defvar isar-find-theorems-widget-simp nil "Search form widget for simplification rules.") ;; creates (or switches to) the search form buffer (defun isar-find-theorems-create-searchform (num pattern intro elim dest name simp &optional errmsg) "Create (or switch to) the Find Theorems search form buffer." (if (get-buffer "*Find Theorems*") (switch-to-buffer "*Find Theorems*") ;; create a new search form (switch-to-buffer "*Find Theorems*") (widget-insert (concat "\n " (if (fboundp 'propertize) (propertize "Find Theorems" 'face 'bold) "Find Theorems") "\n\n")) ;; pattern (widget-insert " Search pattern: ") (setq isar-find-theorems-widget-pattern (widget-create 'editable-field :size 50 :help-echo "A pattern to match in the theorem." pattern)) (widget-insert " ") (widget-create 'push-button :help-echo "Click for help." :notify (lambda (&rest ignore) (isar-find-theorems-create-help)) "?") ;; name (widget-insert "\n\n Theorem name: ") (setq isar-find-theorems-widget-name (widget-create 'editable-field :size 50 :help-echo "Part of the theorem's name." name)) (widget-insert " ") (widget-create 'push-button :help-echo "Click for help." :notify (lambda (&rest ignore) (isar-find-theorems-create-help)) "?") ;; intro (widget-insert "\n\n Rules matching the current goal: ") (widget-create 'push-button :help-echo "Click for help." :notify (lambda (&rest ignore) (isar-find-theorems-create-help)) "?") (widget-insert "\n\n INTRO:\n ") (setq isar-find-theorems-widget-intro (widget-create 'radio-button-choice :value intro :indent 6 :button-args (list :help-echo "Click to select one option.") '(item "none") '(item "intro") '(item "-intro"))) ;; elim (widget-insert "\n ELIM:\n ") (setq isar-find-theorems-widget-elim (widget-create 'radio-button-choice :value elim :indent 6 :button-args (list :help-echo "Click to select one option.") '(item "none") '(item "elim") '(item "-elim"))) ;; dest (widget-insert "\n DEST:\n ") (setq isar-find-theorems-widget-dest (widget-create 'radio-button-choice :value dest :indent 6 :button-args (list :help-echo "Click to select one option.") '(item "none") '(item "dest") '(item "-dest"))) ;; simp (widget-insert "\n Simplification pattern: ") (setq isar-find-theorems-widget-simp (widget-create 'editable-field :size 42 :help-echo "A pattern to match in the left-hand side of a simplification rule." simp)) (widget-insert " ") (widget-create 'push-button :help-echo "Click for help." :notify (lambda (&rest ignore) (isar-find-theorems-create-help)) "?") ;; num (widget-insert "\n\n Number of results: ") (setq isar-find-theorems-widget-number (widget-create 'editable-field :size 10 :help-echo "Maximum number of results to be displayed." num)) (widget-insert " ") (widget-create 'push-button :help-echo "Click for help." :notify (lambda (&rest ignore) (isar-find-theorems-create-help)) "?") ;; Find (widget-insert "\n\n ") (widget-create 'push-button :help-echo "Click to submit this form." :notify (lambda (&rest ignore) (let ((num (widget-value isar-find-theorems-widget-number)) (pattern (widget-value isar-find-theorems-widget-pattern)) (intro (widget-value isar-find-theorems-widget-intro)) (elim (widget-value isar-find-theorems-widget-elim)) (dest (widget-value isar-find-theorems-widget-dest)) (name (widget-value isar-find-theorems-widget-name)) (simp (widget-value isar-find-theorems-widget-simp))) (kill-buffer "*Find Theorems*") (isar-find-theorems-submit-searchform num pattern intro elim dest name simp))) "Find") ;; Reset form (widget-insert " ") (widget-create 'push-button :help-echo "Click to reset this form." :notify (lambda (&rest ignore) (kill-buffer "*Find Theorems*") (isar-find-theorems-create-searchform "" "" "none" "none" "none" "" "")) "Reset Form") (widget-insert "\n") ;; errmsg (if errmsg (widget-insert (concat "\n " (if (fboundp 'propertize) (propertize (concat errmsg "\n See help for details.") 'face 'bold) (concat errmsg "\n See help for details.")) "\n"))) (use-local-map widget-keymap) (widget-setup) (goto-char 37)) ;; beginning of the "Search pattern" text field ) ;; creates the search form help buffer (defun isar-find-theorems-create-help () "Create a help text buffer for the Find Theorems search form." (with-output-to-temp-buffer "*Find Theorems - Help*" (princ (concat "\n" "*** Find Theorems - Help ***\n" "\n" "Command \"Find Theorems\" (C-c C-f) searches for theorems that satisfy a list of\n" "user-supplied criteria. Known criteria are:\n" "\n" "* Search pattern: a pattern that occurs in the theorem, e.g. \"(_::nat) + _\".\n" "\n" "* Theorem name: a substring of the theorem's fully qualified name. (Treats \"*\"\n" " as a wildcard character.)\n" "\n" "* Intro, Elim, Dest: select theorems that match the current goal as\n" " introduction/elimination/destruction rule.\n" "\n" "* Simplification pattern: selects simplification rules whose left-hand side\n" " matches the given pattern.\n" "\n" "* Number of results: an upper bound on the number of theorems that are\n" " displayed. (Leave empty to use Isabelle's default value.)\n" "\n" "Multiple search patterns, theorem names and simplification patterns can be\n" "given, separated by spaces. (Patterns containing a space must be enclosed in\n" "double-quotes.) Criteria can be preceded by \"-\" to select theorems that do not.\n" "match. (Patterns that begin with a \"-\" must be enclosed in double-quotes.)\n" "\n" "A minibuffer based \"Find Theorems\" command is available via (C-c C-a C-m). See\n" "the Isabelle NEWS file for up-to-date documentation. A search form is available\n" "via (C-c C-a C-f). Variable proof-find-theorems-command (customizable via\n" "Proof-General > Advanced > Internals > Prover Config) controls the default\n" "behavior of the \"Find Theorems\" command: set to isar-find-theorems-form or\n" "isar-find-theorems-minibuffer.\n" ))) ) ;; parses the search form's data and calls isar-find-theorems ;; with an appropriate argument string, or displays the search ;; form again, but with an error message (defun isar-find-theorems-submit-searchform (num pattern intro elim dest name simp) "Parse the Find Theorems search form's data." (let (num_ pattern_ intro_ elim_ dest_ name_ simp_ searchstring) ;; pattern (setq pattern_ (isar-find-theorems-parse-criteria "" pattern)) (if (not (pop pattern_)) (isar-find-theorems-create-searchform num pattern intro elim dest name simp (concat "Invalid search pattern: " (car pattern_))) (setq pattern_ (car pattern_)) ;; name (setq name_ (isar-find-theorems-parse-criteria "name: " name)) (if (not (pop name_)) (isar-find-theorems-create-searchform num pattern intro elim dest name simp (concat "Invalid theorem name: " (car name_))) (setq name_ (car name_)) ;; simp (setq simp_ (isar-find-theorems-parse-criteria "simp: " simp)) (if (not (pop simp_)) (isar-find-theorems-create-searchform num pattern intro elim dest name simp (concat "Invalid simplification pattern: " (car simp_))) (setq simp_ (car simp_)) ;; num (setq num_ (isar-find-theorems-parse-number num)) (if (not num_) (isar-find-theorems-create-searchform num pattern intro elim dest name simp "Number of results must be a positive integer.") ;; intro (setq intro_ (if (equal intro "none") "" intro)) ;; elim (setq elim_ (if (equal elim "none") "" elim)) ;; dest (setq dest_ (if (equal dest "none") "" dest)) ;; success: save data, call isar-find-theorems (setq isar-find-theorems-data (list num pattern intro elim dest name simp)) (setq searchstring (format "find_theorems %s" (mapconcat 'identity (isar-find-theorems-filter-empty (list num_ pattern_ intro_ elim_ dest_ name_ simp_)) " "))) ;; note that proof-find-theorems with an argument provided ;; will merely pass this on to Isabelle, and NOT display ;; the search form again (proof-find-theorems searchstring)))))) ) ;; "Multiple search patterns, theorem names and simplification terms can be ;; given, separated by spaces. (Patterns containing a space must be enclosed ;; in double-quotes.) Criteria can be preceded by "-" to select theorems that ;; do not match. (Patterns that begin with a "-" must be enclosed in double- ;; quotes.)" ;; ;; returns (t parsed-string) (where parsed-string may be empty) or ;; (nil errmsg) in case of an error (defun isar-find-theorems-parse-criteria (option-string criteria-string) "Parse search patterns/theorem names/simplification terms, separated by \" \", possibly preceded by \"-\", and possibly escaped by double-quotes." ;; This code might benefit greatly from the use of regexps. (let ((tokens nil) (errmsg nil)) ;; turn criteria-string into a list of (string) tokens (while (and (not (equal criteria-string "")) (not errmsg)) ;; ignore space (if (equal (elt criteria-string 0) ?\ ) (setq criteria-string (substring criteria-string 1)) ;; - is a token ;; Note: This is still a bit weird, as it treats a - following a - ;; just like the first -, i.e. not as part of a pattern. Oh ;; well. (if (equal (elt criteria-string 0) ?-) (progn (setq tokens (cons "-" tokens)) (setq criteria-string (substring criteria-string 1))) ;; " starts a token: search for the next ", regard as one token ;; Note: This is still a bit weird, as it does not require the ;; closing double-quotes to be followed by a space. Oh well. (if (equal (elt criteria-string 0) ?\") (let ((i 1)) (while (and (< i (length criteria-string)) (not (equal (elt criteria-string i) ?\"))) (setq i (1+ i))) (if (equal i (length criteria-string)) (setq errmsg "missing closing double-quotes.") (setq i (1+ i)) (setq tokens (cons (substring criteria-string 0 i) tokens)) (setq criteria-string (substring criteria-string i)))) ;; everything else: search for the next space, regard as one token ;; Note: This is still a bit weird, as it scans over double-quotes. ;; Oh well. (let ((i 1)) (while (and (< i (length criteria-string)) (not (equal (elt criteria-string i) ?\ ))) (setq i (1+ i))) (setq tokens (cons (substring criteria-string 0 i) tokens)) (setq criteria-string (substring criteria-string i))) ))) ) (if errmsg (list nil errmsg) (setq tokens (nreverse tokens)) ;; convert the tokens into argument strings; make sure every "-" is ;; followed by a pattern/name (i.e. not by another "-") (let ((strings nil) (negated nil)) (while (and tokens (not errmsg)) (let ((token (car tokens))) (if (equal token "-") (if negated (setq errmsg "- may not be followed by another -.") (setq negated t) (setq tokens (cdr tokens))) (setq strings (cons (concat (if negated "-" "") option-string ;; wrap token in double-quotes if necessary (if (equal (elt token 0) ?\") token (concat "\"" token "\""))) strings)) (setq negated nil) (setq tokens (cdr tokens)))) ) (if errmsg (list nil errmsg) (if negated (list nil "- must be followed by a search criterion.") (setq strings (nreverse strings)) (list t (mapconcat 'identity strings " ")) ))))) ) ;; auxiliary functions ;; returns "" if num is "", "(num)" if num is a string encoding a positive ;; integer, and nil otherwise (defun isar-find-theorems-parse-number (num) "Parse the number of theorems to be displayed." (if (equal num "") "" (let ((numval (string-to-number num))) (if (and (wholenump numval) (not (equal numval 0))) (concat "(" (number-to-string numval) ")") nil))) ) (defun isar-find-theorems-filter-empty (strings) "Build a new list by removing empty strings from a (non-circular) list." (if (not strings) nil (if (equal (car strings) "") (isar-find-theorems-filter-empty (cdr strings)) (cons (car strings) (isar-find-theorems-filter-empty (cdr strings))))) ) (provide 'isar-find-theorems) proofgeneral-4.3~pre130510/isar/isar-keywords.el000066400000000000000000000255761214562307500215310ustar00rootroot00000000000000;; ;; Keyword classification tables for Isabelle/Isar. ;; Generated from Pure + Pure-ProofGeneral + HOL + HOLCF + IOA + HOL-Boogie + HOL-Nominal + HOL-Statespace. ;; *** DO NOT EDIT *** DO NOT EDIT *** DO NOT EDIT *** ;; (defconst isar-keywords-major '("\\." "\\.\\." "Isabelle\\.command" "Isar\\.begin_document" "Isar\\.define_command" "Isar\\.edit_document" "Isar\\.end_document" "ML" "ML_command" "ML_prf" "ML_val" "ProofGeneral\\.inform_file_processed" "ProofGeneral\\.inform_file_retracted" "ProofGeneral\\.kill_proof" "ProofGeneral\\.pr" "ProofGeneral\\.process_pgip" "ProofGeneral\\.restart" "ProofGeneral\\.undo" "abbreviation" "also" "apply" "apply_end" "arities" "assume" "atom_decl" "attribute_setup" "automaton" "ax_specification" "axiomatization" "axioms" "back" "boogie_end" "boogie_open" "boogie_status" "boogie_vc" "by" "cannot_undo" "case" "cd" "chapter" "class" "class_deps" "classes" "classrel" "code_abort" "code_class" "code_const" "code_datatype" "code_deps" "code_include" "code_instance" "code_library" "code_module" "code_modulename" "code_monad" "code_pred" "code_reflect" "code_reserved" "code_thms" "code_type" "coinductive" "coinductive_set" "commit" "constdefs" "consts" "consts_code" "context" "corollary" "cpodef" "datatype" "declaration" "declare" "def" "default_sort" "defer" "defer_recdef" "definition" "defs" "disable_pr" "display_drafts" "domain" "domain_isomorphism" "done" "enable_pr" "end" "equivariance" "example_proof" "exit" "export_code" "extract" "extract_type" "finalconsts" "finally" "find_consts" "find_theorems" "fix" "fixpat" "fixrec" "from" "full_prf" "fun" "function" "global" "guess" "have" "header" "help" "hence" "hide_class" "hide_const" "hide_fact" "hide_type" "inductive" "inductive_cases" "inductive_set" "init_toplevel" "instance" "instantiation" "interpret" "interpretation" "judgment" "kill" "kill_thy" "lemma" "lemmas" "let" "linear_undo" "local" "local_setup" "locale" "method_setup" "moreover" "new_domain" "next" "nitpick" "nitpick_params" "no_notation" "no_syntax" "no_translations" "no_type_notation" "nominal_datatype" "nominal_inductive" "nominal_inductive2" "nominal_primrec" "nonterminals" "normal_form" "notation" "note" "obtain" "oops" "oracle" "overloading" "parse_ast_translation" "parse_translation" "pcpodef" "pr" "prefer" "presume" "pretty_setmargin" "prf" "primrec" "print_abbrevs" "print_antiquotations" "print_ast_translation" "print_attributes" "print_binds" "print_cases" "print_claset" "print_classes" "print_codeproc" "print_codesetup" "print_commands" "print_configs" "print_context" "print_drafts" "print_facts" "print_induct_rules" "print_interps" "print_locale" "print_locales" "print_methods" "print_orders" "print_quotconsts" "print_quotients" "print_quotmaps" "print_rules" "print_simpset" "print_statement" "print_syntax" "print_theorems" "print_theory" "print_trans_rules" "print_translation" "proof" "prop" "pwd" "qed" "quickcheck" "quickcheck_params" "quit" "quotient_definition" "quotient_type" "realizability" "realizers" "recdef" "recdef_tc" "record" "refute" "refute_params" "remove_thy" "rep_datatype" "repdef" "schematic_corollary" "schematic_lemma" "schematic_theorem" "sect" "section" "setup" "show" "simproc_setup" "sledgehammer" "sledgehammer_params" "smt_status" "sorry" "specification" "statespace" "subclass" "sublocale" "subsect" "subsection" "subsubsect" "subsubsection" "syntax" "term" "termination" "text" "text_raw" "then" "theorem" "theorems" "theory" "thm" "thm_deps" "thus" "thy_deps" "touch_thy" "translations" "txt" "txt_raw" "typ" "type_notation" "typed_print_translation" "typedecl" "typedef" "types" "types_code" "ultimately" "undo" "undos_proof" "unfolding" "unused_thms" "use" "use_thy" "using" "value" "values" "welcome" "with" "write" "{" "}")) (defconst isar-keywords-minor '("actions" "advanced" "and" "assumes" "attach" "avoids" "begin" "binder" "compose" "congs" "constrains" "contains" "datatypes" "defines" "file" "fixes" "for" "functions" "hide_action" "hints" "identifier" "if" "imports" "in" "infix" "infixl" "infixr" "initially" "inputs" "internals" "is" "lazy" "module_name" "monos" "morphisms" "notes" "obtains" "open" "output" "outputs" "overloaded" "permissive" "pervasive" "post" "pre" "rename" "restrict" "shows" "signature" "states" "structure" "to" "transitions" "transrel" "unchecked" "uses" "where")) (defconst isar-keywords-control '("Isabelle\\.command" "Isar\\.begin_document" "Isar\\.define_command" "Isar\\.edit_document" "Isar\\.end_document" "ProofGeneral\\.inform_file_processed" "ProofGeneral\\.inform_file_retracted" "ProofGeneral\\.kill_proof" "ProofGeneral\\.process_pgip" "ProofGeneral\\.restart" "ProofGeneral\\.undo" "cannot_undo" "exit" "init_toplevel" "kill" "linear_undo" "quit" "undo" "undos_proof")) (defconst isar-keywords-diag '("ML_command" "ML_val" "ProofGeneral\\.pr" "boogie_status" "cd" "class_deps" "code_deps" "code_thms" "commit" "disable_pr" "display_drafts" "enable_pr" "export_code" "find_consts" "find_theorems" "full_prf" "header" "help" "kill_thy" "nitpick" "normal_form" "pr" "pretty_setmargin" "prf" "print_abbrevs" "print_antiquotations" "print_attributes" "print_binds" "print_cases" "print_claset" "print_classes" "print_codeproc" "print_codesetup" "print_commands" "print_configs" "print_context" "print_drafts" "print_facts" "print_induct_rules" "print_interps" "print_locale" "print_locales" "print_methods" "print_orders" "print_quotconsts" "print_quotients" "print_quotmaps" "print_rules" "print_simpset" "print_statement" "print_syntax" "print_theorems" "print_theory" "print_trans_rules" "prop" "pwd" "quickcheck" "refute" "remove_thy" "sledgehammer" "smt_status" "term" "thm" "thm_deps" "thy_deps" "touch_thy" "typ" "unused_thms" "use_thy" "value" "values" "welcome")) (defconst isar-keywords-theory-begin '("theory")) (defconst isar-keywords-theory-switch '()) (defconst isar-keywords-theory-end '("end")) (defconst isar-keywords-theory-heading '("chapter" "section" "subsection" "subsubsection")) (defconst isar-keywords-theory-decl '("ML" "abbreviation" "arities" "atom_decl" "attribute_setup" "automaton" "axiomatization" "axioms" "boogie_end" "boogie_open" "class" "classes" "classrel" "code_abort" "code_class" "code_const" "code_datatype" "code_include" "code_instance" "code_library" "code_module" "code_modulename" "code_monad" "code_reflect" "code_reserved" "code_type" "coinductive" "coinductive_set" "constdefs" "consts" "consts_code" "context" "datatype" "declaration" "declare" "default_sort" "defer_recdef" "definition" "defs" "domain" "domain_isomorphism" "equivariance" "extract" "extract_type" "finalconsts" "fixpat" "fixrec" "fun" "global" "hide_class" "hide_const" "hide_fact" "hide_type" "inductive" "inductive_set" "instantiation" "judgment" "lemmas" "local" "local_setup" "locale" "method_setup" "new_domain" "nitpick_params" "no_notation" "no_syntax" "no_translations" "no_type_notation" "nominal_datatype" "nonterminals" "notation" "oracle" "overloading" "parse_ast_translation" "parse_translation" "primrec" "print_ast_translation" "print_translation" "quickcheck_params" "quotient_definition" "realizability" "realizers" "recdef" "record" "refute_params" "repdef" "setup" "simproc_setup" "sledgehammer_params" "statespace" "syntax" "text" "text_raw" "theorems" "translations" "type_notation" "typed_print_translation" "typedecl" "types" "types_code" "use")) (defconst isar-keywords-theory-script '("inductive_cases")) (defconst isar-keywords-theory-goal '("ax_specification" "boogie_vc" "code_pred" "corollary" "cpodef" "example_proof" "function" "instance" "interpretation" "lemma" "nominal_inductive" "nominal_inductive2" "nominal_primrec" "pcpodef" "quotient_type" "recdef_tc" "rep_datatype" "schematic_corollary" "schematic_lemma" "schematic_theorem" "specification" "subclass" "sublocale" "termination" "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" "interpret")) (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 '("ML_prf" "also" "let" "moreover" "note" "txt" "txt_raw" "unfolding" "using" "write")) (defconst isar-keywords-proof-asm '("assume" "case" "def" "fix" "presume")) (defconst isar-keywords-proof-asm-goal '("guess" "obtain" "show" "thus")) (defconst isar-keywords-proof-script '("apply" "apply_end" "back" "defer" "prefer")) (provide 'isar-keywords) proofgeneral-4.3~pre130510/isar/isar-mmm.el000066400000000000000000000042101214562307500204260ustar00rootroot00000000000000;; isar-mmm.el Configure MMM mode for Isar (for LaTeX, SML mode) ;; ;; Copyright (C) 2003 David Aspinall ;; Authors: David Aspinall ;; Licence: GPL ;; ;; $Id: isar-mmm.el,v 12.0 2011/10/13 10:54:50 da Exp $ ;; ;; Presently, we deal with several cases of {* text *}. ;; It's not a good idea to do too much, since searching for the ;; regions and fontifying them is slow. ;; ;; TODO: ;; --- fontification for antiquotations has been lost, could ;; add that into LaTeX mode somehow. ;; --- support for X-Symbols inside MMM mode? (eek) ;; --- more insertion commands might be nice. ;; (Presently just C-c % t and C-c % M) ;; (require 'mmm-auto) (require 'proof-syntax) ; proof-ids-to-regexp (defconst isar-start-latex-regexp (concat "\\(" (proof-ids-to-regexp ;; Perhaps section is too much? The fontification is nice but ;; section headers are a bit short to use LaTeX mode in. (list "text" "header" ".*section")) ;; Next one is nice but hammers font lock a bit too much ;; if there are lots of -- {* short comments *} ;; "\\|\-\-" ;; NB: doesn't work with \\<--\\> "\\)[ \t]+{\\*")) (defconst isar-start-sml-regexp (concat "\\(" (proof-ids-to-regexp (list "ML" "ML_command" "ML_setup" "typed_print_translation")) "\\)[ \t]+{\\*")) (mmm-add-group 'isar `((isar-latex :submode LaTeX-mode :face mmm-comment-submode-face :front ,isar-start-latex-regexp :back "\\*}" :insert ((?t isar-text nil @ "text {*" @ " " _ " " @ "*}" @) (?t isar-text_raw nil @ "text_raw {*" @ " " _ " " @ "*}" @) (?s isar-section nil @ "section {*" @ " " _ " " @ "*}" @) (?d isar-header nil @ "header {*" @ " " _ " " @ "*}" @))) (isar-sml :submode sml-mode :face mmm-code-submode-face :front ,isar-start-sml-regexp :back "\\*}" :insert ((?u isar-ML-setup nil @ "ML_setup {*" @ " " _ " " @ "*}" @) (?c isar-ML-command nil @ "ML_command {*" @ " " _ " " @ "*}" @) (?m isar-ML nil @ "ML {*" @ " " _ " " @ "*}" @) (?p isar-print-trans nil @ "typed_print_translation {*" @ " " _ " " @ "*}" @))))) (provide 'isar-mmm) ;;; isar-mmm.el ends here proofgeneral-4.3~pre130510/isar/isar-profiling.el000066400000000000000000000035211214562307500216350ustar00rootroot00000000000000;; isar-profiling.el: simple profiling Isar Proof General. ;; ;; You can run these tests by issuing "make profile.isar" in PG home dir. ;; ;; $Id: isar-profiling.el,v 12.0 2011/10/13 10:54:50 da Exp $ ;; (eval-when-compile (require 'cl)) (eval-when (compile) (require 'proof-site) (proof-ready-for-assistant 'isar)) (declare-function isar-tracing:auto-solve-toggle "isar.el") (declare-function isar-tracing:auto-quickcheck-toggle "isar.el") (declare-function isar-proof:parallel-proofs-toggle "isar.el") (require 'pg-autotest) (require 'pg-dev) (unless noninteractive (pg-autotest log ".profile.log") ; convention (pg-autotest timestart 'total) (pg-autotest-find-file "etc/isar/AHundredTheorems.thy") (pg-autotest eval (proof-shell-ready-prover)) (pg-autotest eval (isar-tracing:auto-solve-toggle 0)) ; autosolve hammers this! (pg-autotest eval (isar-tracing:auto-quickcheck-toggle 0)) (pg-autotest eval (isar-proof:parallel-proofs-toggle 0)) (pg-autotest eval (proof-full-annotation-toggle 0)) (proof-shell-wait) ;; Simple profiling test. Cf TRAC #324 (pg-autotest timestart) (pg-autotest process-wholefile "etc/isar/AHundredTheorems.thy") (pg-autotest timetaken) ;; Same again with profiling (profile-pg) (pg-autotest timestart) (pg-autotest process-wholefile "etc/isar/AHundredTheorems.thy") (pg-autotest timetaken) (pg-autotest timestart) (pg-autotest process-wholefile "etc/isar/AHundredTheorems.thy") (pg-autotest timetaken) (pg-autotest timestart) (pg-autotest process-wholefile "etc/isar/AHundredProofs.thy") (pg-autotest timetaken) (elp-results) (let ((results (with-current-buffer "*ELP Profiling Results*" (buffer-string)))) (with-current-buffer pg-autotest-log (goto-char (point-min)) (insert "ELP Profiling Results: \n" results "\n\n"))) (pg-autotest exit) ) proofgeneral-4.3~pre130510/isar/isar-syntax.el000066400000000000000000000451311214562307500211750ustar00rootroot00000000000000;; isar-syntax.el Syntax expressions for Isabelle/Isar ;; Copyright (C) 1994-2004, 2009, 2010 LFCS Edinburgh. ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; Authors: David Aspinall ;; Markus Wenzel ;; ;; $Id: isar-syntax.el,v 12.0 2011/10/13 10:54:50 da Exp $ ;; (require 'cl) ; remove-if, remove-if-not (require 'proof-syntax) (require 'isar-keywords) ; NB: we want to load isar-keywords at runtime ;; ----- character syntax (defconst isar-script-syntax-table-entries '(?\$ "." ?\/ "." ?\\ "\\" ?+ "." ?- "." ?= "." ?% "." ?< "w" ?> "w" ?\& "." ?. "w" ?_ "w" ?\' "w" ?? "w" ?` "\"" ?\( "()1" ?\) ")(4" ?\{ "(}1b" ?\} "){4b" ?\* ". 23n") "Syntax table entries for Isar scripts. This list is in the right format for proof-easy-config.") (defconst isar-script-syntax-table-alist ;; NB: this is used for imenu. Probably only need word syntax (let ((syn isar-script-syntax-table-entries) al) (while syn (setq al (cons (cons (char-to-string (car syn)) (cadr syn)) al)) (setq syn (cddr syn))) al)) (defun isar-init-syntax-table () "Set appropriate values for syntax table in current buffer." (let ((syn isar-script-syntax-table-entries)) (while syn (modify-syntax-entry (car syn) (cadr syn)) (setq syn (cddr syn))))) (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 ?\{ "(}") (modify-syntax-entry ?\} "){")) ;; ----- keyword groups (defconst isar-keyword-begin "begin") (defconst isar-keyword-end "end") (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-proper (append isar-keywords-theory isar-keywords-proof-enclose isar-keywords-proof)) (defconst isar-keywords-improper (append isar-keywords-theory-script isar-keywords-proof-script isar-keywords-qed-global)) (defconst isar-keyword-level-alist (append (mapcar (lambda (w) (cons w 1)) (append isar-keywords-theory-heading isar-keywords-theory-begin isar-keywords-theory-end)) (mapcar (lambda (w) (cons w 2)) (append isar-keywords-theory-script isar-keywords-theory-goal)) (mapcar (lambda (w) (cons w 3)) (append isar-keywords-proof-heading isar-keywords-theory-goal)) (mapcar (lambda (w) (cons w 4)) isar-keywords-proof-block))) (defconst isar-keywords-outline (mapcar 'car isar-keyword-level-alist)) (defconst isar-keywords-indent-open (append isar-keywords-theory-goal isar-keywords-proof-goal isar-keywords-proof-asm-goal isar-keywords-proof-open '("notepad"))) (defconst isar-keywords-indent-close (append isar-keywords-save isar-keywords-proof-close isar-keywords-theory-end)) (defconst isar-keywords-indent-enclose (append isar-keywords-proof-block isar-keywords-proof-close isar-keywords-qed-block isar-keywords-theory-end (list isar-keyword-begin))) ;; ----- regular expressions (defconst isar-ext-first "\\(?:\\\\<\\^?[A-Za-z]+>\\|[A-Za-z]\\)") (defconst isar-ext-rest "\\(?:\\\\<\\^?[A-Za-z]+>\\|[A-Za-z0-9'_]\\)") (defconst isar-text "[^\^A- ]*") (defconst isar-long-id-stuff (concat "\\(?:" isar-ext-rest "\\|\\.\\)+")) (defconst isar-id (concat "\\(" isar-ext-first isar-ext-rest "*\\)")) (defconst isar-idx (concat isar-id "\\(?:\\.[0-9]+\\)?")) (defconst isar-string "\"\\(\\(?:[^\"]\\|\\\\\"\\)*\\)\"") (defun isar-ids-to-regexp (ids) "Hack list IDS of keywords IDS to make a regexp matching any of them. Note: IDS may have full-stops already regexp quoted." ; a nuisance! (let* ((unquoted (mapcar (lambda (s) (replace-regexp-in-string (regexp-quote "\\.") "." s)) ids)) (cleaned (remove "{" (remove "}" unquoted))) (words (if cleaned (list (regexp-opt cleaned 'words)))) ;; } is not a word constituent, so \_<}\_> fails (rbrace (if (member "}" ids) '("}"))) ;; { similarly, must also prevent {* matching (lbrace (if (member "{" ids) '("\\(?:{\\(?:\\b\\|[^\\*]\\)\\)")))) (mapconcat 'identity (append words lbrace rbrace) "\\|"))) ;; tests ; (isar-ids-to-regexp '("bla" "blubber")) ; (isar-ids-to-regexp '("bla" "\\." "blubber")) ; (isar-ids-to-regexp '("bla" "\\." "blubber" "{")) ; NB: string-match not entirely accurate, syntax table affects \_< \_> behaviour ; (string-match (isar-ids-to-regexp '("bla" "}" "blubber" "{")) "}") ; 0 ; (string-match (isar-ids-to-regexp '("bla" "}" "blubber" "{")) "*}") ; 1 [OK] ; (string-match (isar-ids-to-regexp '("bla" "}" "blubber" "{")) "*}bla") ; 1 [OK] ; (string-match (isar-ids-to-regexp '("bla" "}" "blubber" "{")) "ug{*") ; nil ; (string-match (isar-ids-to-regexp '("bla" "}" "blubber" "{")) "ug{") ; 2 ; (string-match (isar-ids-to-regexp '("bla" "}" "blubber" "{")) "}ug") ; 0 ; (string-match (isar-ids-to-regexp '("bla" "}" "blubber" "{")) "}\n ug") ; 0 ; (string-match (isar-ids-to-regexp '("foo" "\\." "Foo\\.bar")) "boo.foo") ; nil/4 ; (string-match (isar-ids-to-regexp '("foo" "\\." "Foo\\.bar")) "Foo.bar") ; 0 ; (string-match (isar-ids-to-regexp '("foo" "\\." "Foo\\.bar")) "bar.foo") ; 4 ; (string-match (isar-ids-to-regexp '("foo" "\\." "Foo\\.bar")) "bar. foo") ; 5 (defconst isar-any-command-regexp ;; allow terminator to be considered as command start: ;; FIXME: really needs change in generic function to take account of this, ;; since the end character of a command is not the start (concat ";\\|" (isar-ids-to-regexp isar-keywords-major)) "Regexp matching any Isabelle/Isar command keyword or the terminator character.") (defconst isar-name-regexp (concat "\\s-*\\(" isar-string "\\|" isar-id "\\)\\s-*") "Regexp matching Isabelle/Isar names; surrounding space and contents grouped. Group number 1 matches the identifier possibly with quotes; group number 2 matches contents of quotes for quoted identifiers.") (defconst isar-improper-regexp "\\(\\<[A-Za-z][A-Za-z0-9'_]*_tac\\>\\|\\\\)" "Regexp matching low-level features") (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 "\"\\|`\\|\\*}") (defun isar-syntactic-context () (let ((sc (proof-looking-at-syntactic-context-default))) (or (if (eq sc 'string) (save-excursion (save-match-data (and (or (looking-at isar-string-start-regexp) (re-search-backward isar-string-start-regexp nil t)) (skip-chars-backward " \t\n-") (looking-at "[ \t\n]*--") 'comment)))) sc))) ;; antiquotations (defconst isar-antiq-regexp (concat "@{\\(?:[^\"{}]\\|" isar-string "\\)*}") "Regexp matching Isabelle/Isar antiquotations.") ;; keyword nesting (defconst isar-nesting-regexp (isar-ids-to-regexp (list isar-keyword-begin isar-keyword-end))) (defun isar-nesting () "Determine keyword nesting" (let ((nesting 0) (limit (point))) (save-excursion (goto-char (point-min)) (while (proof-re-search-forward isar-nesting-regexp limit t) (cond ((proof-buffer-syntactic-context)) ((equal (match-string 0) isar-keyword-begin) (incf nesting)) ((equal (match-string 0) isar-keyword-end) (decf nesting))))) nesting)) (defun isar-match-nesting (limit) (block nil (while (proof-re-search-forward isar-nesting-regexp limit t) (and (not (proof-buffer-syntactic-context)) (if (equal (match-string 0) isar-keyword-begin) (> (isar-nesting) 1) (> (isar-nesting) 0)) (return t))))) ;; ----- Isabelle inner syntax highlight (defface isabelle-string-face (proof-face-specs (:foreground "springgreen4") (:background "springgreen1") ()) "*Face for fontifying string contents in Isabelle." :group 'proof-faces) (defface isabelle-quote-face (proof-face-specs (:foreground "Gray80") (:background "Gray30") (:italic t)) "*Face for quotes (string delimiters) in Isabelle." :group 'proof-faces) (defface isabelle-class-name-face (proof-face-specs (:foreground "red") (:foreground "red3") (:bold t)) "*Face for Isabelle term / type highlighting" :group 'proof-faces) (defface isabelle-tfree-name-face (proof-face-specs (:foreground "purple") (:foreground "purple3") (:bold t)) "*Face for Isabelle term / type highlighting" :group 'proof-faces) (defface isabelle-tvar-name-face (proof-face-specs (:foreground "purple") (:foreground "purple3") (:bold t)) "*Face for Isabelle term / type highlighting" :group 'proof-faces) (defface isabelle-free-name-face (proof-face-specs (:foreground "blue") (:foreground "blue3") (:bold t)) "*Face for Isabelle term / type highlighting" :group 'proof-faces) (defface isabelle-bound-name-face (proof-face-specs (:foreground "green4") (:foreground "green") (:bold t)) "*Face for Isabelle term / type highlighting" :group 'proof-faces) (defface isabelle-var-name-face (proof-face-specs (:foreground "darkblue") (:foreground "blue3") (:bold t)) "*Face for Isabelle term / type highlighting" :group 'proof-faces) (defconst isabelle-string-face 'isabelle-string-face) (defconst isabelle-quote-face 'isabelle-quote-face) (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) ;; font-lock syntactic fontification ;; adapted from font-lock.el in GNU Emacs 23.1.1 (defun isar-font-lock-fontify-syntactically-region (start end &optional loudly ppss) "Put proper face on each string and comment between START and END. START should be at the beginning of a line." (let ((comment-end-regexp (replace-regexp-in-string "^ *" "" comment-end)) state beg) (if loudly (message "Fontifying %s... (syntactically...)" (buffer-name))) (goto-char start) ;; ;; Find the `start' state. (setq state (or ppss (syntax-ppss start))) ;; ;; Find each interesting place between here and `end'. (while (let ((instring (nth 3 state)) (incomment (nth 4 state))) (when (or instring incomment) (setq beg (max (nth 8 state) start)) (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table)) (cond (instring (put-text-property (1+ beg) (1- (point)) 'face isabelle-string-face) (put-text-property beg (1+ beg) 'face isabelle-quote-face) (put-text-property (1- (point)) (point) 'face isabelle-quote-face)) (t (put-text-property beg (point) 'face font-lock-comment-face)))) (< (point) end)) (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table))))) ;; font-lock keywords fontification (defvar isar-font-lock-keywords-1 (list (cons 'isar-match-nesting 'font-lock-preprocessor-face) (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-type-face) (cons (isar-ids-to-regexp isar-keywords-proper) '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-improper-regexp 'font-lock-reference-face) (cons isar-antiq-regexp '(0 'font-lock-variable-name-face t)))) (put 'isar-goals-mode 'font-lock-extra-managed-props '(invisible sendback)) (put 'isar-response-mode 'font-lock-extra-managed-props '(invisible sendback)) (defun isar-output-flkprops (start regexp end props) `(,(concat "\\(" start "\\)\\(" regexp "\\)\\(" end "\\)") (1 '(face nil invisible t) prepend) (2 ',props prepend) (,(+ 3 (regexp-opt-depth regexp)) '(face nil invisible t) prepend))) (defun isar-output-flk (start regexp end face) (isar-output-flkprops start regexp end (list 'face face))) (defvar isar-output-font-lock-keywords-1 (list '("\^A[IJKLMNOPV]" (0 '(face nil invisible t) t)) (isar-output-flkprops "\^AW" "\\(?:[^\^A]\\|\^A[^X]\\)*" "\^AX" '(face (:underline t) mouse-face 'highlight sendback t)) (isar-output-flk "\^A0" "\\(?:[^\^A]\\|\^A[^1]\\)*" "\^A1" 'proof-warning-face) ;; done generically at the moment: ;; (isar-output-flk "\^AM" "\\(?:[^\^A]\\|\^A[^N]\\)*" "\^AN" 'proof-error-face) (isar-output-flk "\^AB" isar-text "\^AA" 'isabelle-class-name-face) (isar-output-flk "\^AC" isar-text "\^AA" 'isabelle-tfree-name-face) (isar-output-flk "\^AD" isar-text "\^AA" 'isabelle-tvar-name-face) (isar-output-flk "\^AE" isar-text "\^AA" 'isabelle-free-name-face) (isar-output-flk "\^AF" isar-text "\^AA" 'isabelle-bound-name-face) (isar-output-flk "\^AG" isar-text "\^AA" 'isabelle-var-name-face) (isar-output-flk "\^AH" isar-text "\^AA" 'proof-declaration-name-face) ) "*Font-lock table for Isabelle output terms.") (defun isar-strip-output-markup (string) "Remove invisible output markup from STRING" (replace-regexp-in-string "\^A." "" string)) (defconst isar-shell-font-lock-keywords '(("\^A." (0 '(face nil invisible t))))) (defvar isar-goals-font-lock-keywords (append (list "^theory:" "^proof (prove):" "^proof (state):" "^proof (chain):" "^goal.*:" "^picking.*:" "^using.*:" "^calculation:" "^this:" "^abbreviations:" "^term bindings:" "^facts:" "^cases:" "^prems:" "^fixed variables:" "^structures:" "^abbreviations:" "^type constraints:" "^default sorts:" "^used type variable names:" "^flex-flex pairs:" "^constants:" "^variables:" "^type variables:" "^\\s-*[0-9][0-9]?\\. ") isar-output-font-lock-keywords-1) "*Font-lock table for Isabelle/Isar output.") ;; ----- variations on undo (defconst isar-linear-undo "linear_undo") (defconst isar-undo "ProofGeneral.undo;") (defconst isar-pr (if (member "ProofGeneral\\.pr" isar-keywords-major) "ProofGeneral.pr" ; does right thing "pr" ; See Trac #292 )) (defun isar-remove (name) (concat "init_toplevel; kill_thy " name ";")) (defun isar-undos (linearp i) (if (> i 0) (concat (if linearp "linear_undo " "undos_proof ") (int-to-string i) ";" (if linearp (concat " " isar-pr ";")) ) nil)) ; was proof-no-command (defun isar-cannot-undo (cmd) (concat "cannot_undo \"" cmd "\";")) (defconst isar-undo-commands (list isar-linear-undo isar-undo "init_toplevel" "kill_thy" "undos_proof" "cannot_undo")) (defconst isar-theory-start-regexp (proof-anchor-regexp (isar-ids-to-regexp (append isar-keywords-theory-begin isar-keywords-theory-switch)))) (defconst isar-end-regexp (proof-anchor-regexp (isar-ids-to-regexp isar-keywords-theory-end))) (defconst isar-undo-fail-regexp (proof-anchor-regexp (isar-ids-to-regexp isar-keywords-control))) (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)) ;; ----- imenu (defconst isar-keywords-imenu (append isar-keywords-theory-begin isar-keywords-theory-heading isar-keywords-theory-decl isar-keywords-theory-script isar-keywords-theory-goal)) (defconst isar-entity-regexp (concat "\\(" (isar-ids-to-regexp isar-keywords-imenu) "\\)")) (defconst isar-named-entity-regexp (concat isar-entity-regexp "\\(?:\\s-*(\\s-*in[^)]+)\\)?" isar-name-regexp "[[:=]" )) (defconst isar-named-entity-name-match-number (1+ (regexp-opt-depth isar-entity-regexp))) (defconst isar-generic-expression (mapcar (lambda (kw) (list (capitalize kw) (concat "\\<" kw "\\>" "\\(?:\\s-*(\\s-*in[^)]+)\\)?" isar-name-regexp "[[:=]") 1)) isar-keywords-imenu)) ;; ----- 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") (defconst isar-outline-heading-alist isar-keyword-level-alist) (provide 'isar-syntax) proofgeneral-4.3~pre130510/isar/isar-unicode-tokens.el000066400000000000000000000440261214562307500226000ustar00rootroot00000000000000;;; -*- coding: utf-8; -*- ;; isar-unicode-tokens.el --- Tokens for Unicode Tokens package ;; ;; Copyright(C) 2008, 2009 David Aspinall / LFCS Edinburgh ;; Author: David Aspinall ;; ;; This file is loaded by proof-auxmodes.el for proof-unicode-tokens.el. ;; ;; It sets the variables defined at the top of unicode-tokens.el, ;; unicode-tokens- is set from isar-. See the corresponding ;; variable for documentation. ;; (require 'cl) ; for-loop (eval-when (compile) (require 'unicode-tokens) ; it's loaded dynamically at runtime (require 'proof-unicode-tokens)) ; that file loads us at runtime ;; ;; Customization ;; (defgroup isabelle-tokens nil "Variables which configure Isabelle tokens for Unicode Tokens mode." :group 'isabelle :prefix "isar-") (defun isar-set-and-restart-tokens (sym val) "Function to restart Unicode Tokens when a token value is adjusted." (set-default sym val) (when (featurep 'isar-unicode-tokens) ; not during loading (isar-init-token-symbol-map) (isar-init-shortcut-alists) (if (featurep 'unicode-tokens) (unicode-tokens-initialise)))) ;; ;; Controls ;; (defconst isar-control-region-format-regexp "\\(\\\\<\\^%s>\\)\\(.*?\\)\\(\\\\<\\^%s>\\)") (defconst isar-control-char-format-regexp (concat "\\(\\\\<\\^%s>\\)\\(" "\\(?:\\\\<[A-Za-z]+>\\|[^\\]\\)" ; cf isar-ext-first "\\)")) (defconst isar-control-char-format "\\<^%s>") (defconst isar-control-region-format-start "\\<^%s>") (defconst isar-control-region-format-end "\\<^%s>") (defcustom isar-control-characters '(("Subscript" "sub" sub) ("Id subscript" "isub" sub) ("Superscript" "sup" sup) ("Id superscript" "isup" sup) ("Loc" "loc" keyword) ("Constant" "const" keyword) ("Bold" "bold" bold) ;; unofficial/unsupported: ("Italic" "italic" italic)) "Control character tokens for Isabelle." :group 'isabelle-tokens :set 'isar-set-and-restart-tokens) (defcustom isar-control-regions '(("Subscript" "bsub" "esub" sub) ("Superscript" "bsup" "esup" sup) ;; unofficial/unsupported: ("Id subscript" "bisub" "eisub" sub) ("Id superscript" "bisup" "eisup" sup) ("Bold" "bbold" "ebold" bold) ("Italic" "bitalic" "eitalic" italic) ("Script" "bscript" "escript" script) ("Frakt" "bfrakt" "efrakt" frakt) ("Roman" "bserif" "eserif" serif) ("Sans" "bsans" "esans" sans) ("Overline" "boverline" "eoverline" overline) ("Underline" "bunderline" "eunderline" underline) ("Big" "bbig" "ebig" big) ("Small" "bsmall" "esmall" small) ; ("Large symbols" "bbigsyms" "ebigsyms" large-symbols) ) "Control sequence tokens for Isabelle." :group 'isabelle-tokens :set 'isar-set-and-restart-tokens) ;; ;; Symbols ;; (defconst isar-token-format "\\<%s>") ;(defconst isar-token-variant-format-regexp ; "\\\\<\\(%s\\)\\([:][a-zA-Z0-9]+\\)?>") ; syntax change required (defconst isar-token-variant-format-regexp "\\\\<\\(%s\\)[0-9]*>") ; unofficial interpretation of usual syntax (defcustom isar-greek-letters-tokens '(("alpha" "α") ("beta" "β") ("gamma" "γ") ("delta" "δ") ("epsilon" "ε") ; varepsilon (some is epsilon), although PG can use dups ("zeta" "ζ") ("eta" "η") ("theta" "θ") ("iota" "ι") ("kappa" "κ") ("lambda" "λ") ("mu" "μ") ("nu" "ν") ("xi" "ξ") ("pi" "Ï€") ("rho" "Ï") ("sigma" "σ") ("tau" "Ï„") ("upsilon" "Ï…") ("phi" "φ") ("chi" "χ") ("psi" "ψ") ("omega" "ω") ("Gamma" "Γ") ("Delta" "Δ") ("Theta" "Θ") ("Lambda" "Λ") ("Xi" "Ξ") ("Pi" "Π") ("Sigma" "Σ") ("Upsilon" "Î¥") ("Phi" "Φ") ("Psi" "Ψ") ("Omega" "Ω")) "Greek letter token map for Isabelle." :type 'unicode-tokens-token-symbol-map :group 'isabelle-tokens :set 'isar-set-and-restart-tokens) (defcustom isar-misc-letters-tokens '(("bool" "B" bold underline) ("complex" "â„‚") ("nat" "â„•") ("rat" "ℚ") ("real" "â„") ("int" "ℤ")) "Miscellaneous letter token map for Isabelle." :type 'unicode-tokens-token-symbol-map :group 'isabelle-tokens :set 'isar-set-and-restart-tokens) (defcustom isar-symbols-tokens '(("leftarrow" "â†") ("rightarrow" "→") ("Leftarrow" "â‡") ("Rightarrow" "⇒") ("leftrightarrow" "↔") ("Leftrightarrow" "⇔") ("mapsto" "↦") ("longleftarrow" "⟵") ("Longleftarrow" "⟸") ("longrightarrow" "⟶") ("Longrightarrow" "⟹") ("longleftrightarrow" "⟷") ("Longleftrightarrow" "⟺") ("longmapsto" "⟼") ("midarrow" "–") ; #x002013 en dash ("Midarrow" "‗") ; #x002017 double low line (not mid) ("hookleftarrow" "↩") ("hookrightarrow" "↪") ("leftharpoondown" "↽") ("rightharpoondown" "â‡") ("leftharpoonup" "↼") ("rightharpoonup" "⇀") ("rightleftharpoons" "⇌") ("leadsto" "â†") ("downharpoonleft" "⇃") ("downharpoonright" "⇂") ("upharpoonleft" "↿") ;; ("upharpoonright" "↾") ;; overlaps restriction ("restriction" "↾") ;; same as above ("Colon" "∷") ("up" "↑") ("Up" "⇑") ("down" "↓") ("Down" "⇓") ("updown" "↕") ("Updown" "⇕") ("langle" "⟨") ("rangle" "⟩") ("lceil" "⌈") ("rceil" "⌉") ("lfloor" "⌊") ("rfloor" "⌋") ("lparr" "⦇") ("rparr" "⦈") ("lbrakk" "⟦") ("rbrakk" "⟧") ("lbrace" "⦃") ("rbrace" "⦄") ("guillemotleft" "«") ("guillemotright" "»") ("bottom" "⊥") ("top" "⊤") ("and" "∧") ("And" "â‹€") ("or" "∨") ("Or" "â‹") ("forall" "∀") ("exists" "∃") ("nexists" "∄") ("not" "¬") ("box" "â–¡") ("diamond" "â—‡") ("turnstile" "⊢") ("Turnstile" "⊨") ("tturnstile" "⊩") ("TTurnstile" "⊫") ("stileturn" "⊣") ("surd" "√") ("le" "≤") ("ge" "≥") ("lless" "≪") ("ggreater" "≫") ("lesssim" "âª") ("greatersim" "⪎") ("lessapprox" "⪅") ("greaterapprox" "⪆") ("in" "∈") ("notin" "∉") ("subset" "⊂") ("supset" "⊃") ("subseteq" "⊆") ("supseteq" "⊇") ("sqsubset" "âŠ") ("sqsupset" "âŠ") ("sqsubseteq" "⊑") ("sqsupseteq" "⊒") ("inter" "∩") ("Inter" "â‹‚") ("union" "∪") ("Union" "⋃") ("squnion" "⊔") ("Squnion" "⨆") ("sqinter" "⊓") ("Sqinter" "⨅") ("setminus" "∖") ("propto" "âˆ") ("uplus" "⊎") ("Uplus" "⨄") ("noteq" "≠") ("sim" "∼") ("doteq" "â‰") ("simeq" "≃") ("approx" "≈") ("asymp" "â‰") ("cong" "≅") ("smile" "⌣") ("equiv" "≡") ("frown" "⌢") ("Join" "â¨") ("bowtie" "⋈") ("prec" "≺") ("succ" "≻") ("preceq" "≼") ("succeq" "≽") ("parallel" "∥") ("bar" "¦") ("plusminus" "±") ("minusplus" "∓") ("times" "×") ("div" "÷") ("cdot" "â‹…") ("star" "⋆") ("bullet" "∙") ("circ" "∘") ("dagger" "†") ("ddagger" "‡") ("lhd" "⊲") ("rhd" "⊳") ("unlhd" "⊴") ("unrhd" "⊵") ("triangleleft" "â—") ("triangleright" "â–·") ("triangle" "â–µ") ; or â–³ ("triangleq" "≜") ("oplus" "⊕") ("Oplus" "â¨") ("otimes" "⊗") ("Otimes" "⨂") ("odot" "⊙") ("Odot" "⨀") ("ominus" "⊖") ("oslash" "⊘") ("dots" "…") ("cdots" "⋯") ("Sum" "∑") ("Prod" "âˆ") ("Coprod" "âˆ") ("infinity" "∞") ("integral" "∫") ("ointegral" "∮") ("clubsuit" "♣") ("diamondsuit" "♢") ("heartsuit" "♡") ("spadesuit" "â™ ") ("aleph" "ℵ") ("emptyset" "∅") ("nabla" "∇") ("partial" "∂") ("Re" "ℜ") ("Im" "â„‘") ("flat" "â™­") ("natural" "â™®") ("sharp" "♯") ("angle" "∠") ("copyright" "©") ("registered" "®") ("hyphen" "â€") ("inverse" "¯¹") ; X-Symb: just "¯" ("onesuperior" "¹") ("twosuperior" "²") ("threesuperior" "³") ("onequarter" "¼") ("onehalf" "½") ("threequarters" "¾") ("ordmasculine" "º") ("ordfeminine" "ª") ("section" "§") ("paragraph" "¶") ("exclamdown" "¡") ("questiondown" "¿") ("euro" "€") ("pounds" "£") ("yen" "Â¥") ("cent" "¢") ("currency" "¤") ("degree" "°") ("amalg" "⨿") ("mho" "â„§") ("lozenge" "â—Š") ("wp" "℘") ("wrong" "≀") ;; #x002307 ("struct" "â‹„") ;; #x0022c4 ("acute" "´") ("index" "ı") ("dieresis" "¨") ("cedilla" "¸") ("hungarumlaut" "ʺ") ("spacespace" "â€") ;; #x002001 ("module" "⟨module⟩" bold) ("some" "ϵ")) "Symbol token map for Isabelle. The standard set of Isabelle symbols." :type 'unicode-tokens-token-symbol-map :group 'isabelle-tokens :set 'isar-set-and-restart-tokens) (defcustom isar-extended-symbols-tokens '(("stareq" "≛") ("defeq" "â‰") ("questioneq" "≟") ("vartheta" "Ï‘") ; ("o" "ø") ("varpi" "Ï–") ("varrho" "ϱ") ("varsigma" "Ï‚") ("varphi" "Ï•") ("hbar" "â„") ("ell" "â„“") ("ast" "∗") ("bigcirc" "â—¯") ("bigtriangleup" "â–³") ("bigtriangledown" "â–½") ("ni" "∋") ("mid" "∣") ("notlt" "≮") ("notle" "≰") ("notprec" "⊀") ("notpreceq" "â‹ ") ("notsubset" "⊄") ("notsubseteq" "⊈") ("notsqsubseteq" "â‹¢") ("notgt" "≯") ("notge" "≱") ("notsucc" "âŠ") ("notsucceq" "â‹¡") ("notsupset" "⊅") ("notsupseteq" "⊉") ("notsqsupseteq" "â‹£") ("notequiv" "≢") ("notsim" "â‰") ("notsimeq" "≄") ("notapprox" "≉") ("notcong" "≇") ("notasymp" "≭") ("nearrow" "↗") ("searrow" "↘") ("swarrow" "↙") ("nwarrow" "↖") ("vdots" "â‹®") ("ddots" "⋱") ("closequote" "’") ("openquote" "‘") ("opendblquote" "â€") ("closedblquote" "“") ("emdash" "—") ("prime" "′") ("doubleprime" "″") ("tripleprime" "‴") ("quadrupleprime" "â—") ("nbspace" " ") ("thinspace" " ") ("notni" "∌") ("colonequals" "≔") ("foursuperior" "â´") ("fivesuperior" "âµ") ("sixsuperior" "â¶") ("sevensuperior" "â·") ("eightsuperior" "â¸") ("ninesuperior" "â¹")) "Extended symbols token map for Isabelle. These are not defined standardly." :type 'unicode-tokens-token-symbol-map :group 'isabelle-tokens :set 'isar-set-and-restart-tokens) (defun isar-try-char (charset code1 code2) (and (charsetp charset) ; prevent error (char-to-string (make-char charset code1 code2)))) (defcustom isar-symbols-tokens-fallbacks `(;; Faked long symbols ("longleftarrow" "â†-") ("Longleftarrow" "â‡â€“") ("longrightarrow" "–→") ("Longrightarrow" "–⇒") ("longleftrightarrow" "â†â†’") ("Longleftrightarrow" "â‡â‡’") ("longmapsto" "â˜â†’") ;; bracket composition alternatives ("lparr" "(|") ("rparr" "|)") ;; an example of using characters from another charset. ;; to expand this table, see output of M-x list-charset-chars ("lbrakk" ,(isar-try-char 'japanese-jisx0208 #x22 #x5A)) ("rbrakk" ,(isar-try-char 'japanese-jisx0208 #x22 #x5A)) ("lbrakk" "[|") ("rbrakk" "|]") ("lbrace" "{|") ("rbrace" "|}")) "Fallback alternatives to `isar-symbols-tokens'. The first displayable composition will be displayed to replace the tokens." :type 'unicode-tokens-token-symbol-map :group 'isabelle-tokens :set 'isar-set-and-restart-tokens) (defcustom isar-bold-nums-tokens '(("zero" "0" bold) ("one" "1" bold) ("two" "2" bold) ("three" "3" bold) ("four" "4" bold) ("five" "5" bold) ("six" "6" bold) ("seven" "7" bold) ("eight" "8" bold) ("nine" "9" bold)) "Tokens for bold numerals." :type 'unicode-tokens-token-symbol-map :group 'isabelle-tokens :set 'isar-set-and-restart-tokens) (defun isar-map-letters (f1 f2 &rest symbs) (loop for x below 26 for c = (+ 65 x) collect (cons (funcall f1 c) (cons (funcall f2 c) symbs)))) (defconst isar-script-letters-tokens ; \ \ ... (isar-map-letters (lambda (x) (format "%c" x)) (lambda (x) (format "%c" x)) 'script)) (defconst isar-roman-letters-tokens ; \ \ ... (isar-map-letters (lambda (x) (downcase (format "%c" x))) (lambda (x) (downcase (format "%c" x))) 'serif)) (defconst isar-fraktur-uppercase-letters-tokens ; \ \ .. (isar-map-letters (lambda (x) (format "%c%c" x x)) (lambda (x) (format "%c" x)) 'frakt)) (defconst isar-fraktur-lowercase-letters-tokens ; \ \ .. (isar-map-letters (lambda (x) (downcase (format "%c%c" x x))) (lambda (x) (downcase (format "%c" x))) 'frakt)) (defcustom isar-token-symbol-map nil "Table mapping Isabelle symbol token names to Unicode strings. See `unicode-tokens-token-symbol-map'. You can adjust this table to change the default entries. Each element is a list (TOKNAME COMPOSITION FONTSYMB ...) COMPOSITION is usually a string, perhaps containing Unicode characters. For Isabelle, the token TOKNAME is made into the token \\." :type 'unicode-tokens-token-symbol-map :group 'isabelle :set 'isar-set-and-restart-tokens :tag "Isabelle Unicode Token Mapping") (defcustom isar-user-tokens nil "User-defined additions to `isar-token-symbol-map'. Each element is a list (TOKNAME COMPOSITION FONTSYMB ...) COMPOSITION is usually a string, perhaps containing Unicode characters. For Isabelle, the token TOKNAME is made into the token \\." :type 'unicode-tokens-token-symbol-map :group 'isabelle :set 'isar-set-and-restart-tokens :tag "User extensions for Isabelle Token Mapping") (defun isar-init-token-symbol-map () "Initialise the default value for `unicode-tokens-token-symbol-map'." (custom-set-default 'isar-token-symbol-map (append isar-symbols-tokens isar-extended-symbols-tokens isar-user-tokens isar-misc-letters-tokens isar-greek-letters-tokens isar-bold-nums-tokens isar-script-letters-tokens isar-roman-letters-tokens isar-fraktur-uppercase-letters-tokens isar-fraktur-lowercase-letters-tokens isar-user-tokens isar-symbols-tokens-fallbacks))) (isar-init-token-symbol-map) ;; ;; Shortcuts ;; (defcustom isar-symbol-shortcuts '(("\\/" . "\\") ("/\\" . "\\") ("+O" . "\\") ("-O" . "\\") ("xO" . "\\") ("/O" . "\\") (".O" . "\\") ("|+" . "\\") ("|++" . "\\") ("<=" . "\\") ("|-" . "\\") (">=" . "\\") ("-|" . "\\") ("||" . "\\") ("==" . "\\") ("~=" . "\\") ("~:" . "\\") ("~~~" . "\\") ("~~" . "\\") ("~==" . "\\") ("|<>|" . "\\") ("|=" . "\\") ("=." . "\\") ("_|_" . "\\") ("") ("~>=" . "\\") ("==/" . "\\") ("~/" . "\\") ("~=/" . "\\") ("~~/" . "\\") ("<-" . "\\") ("<=" . "\\") ("->" . "\\") ("=>" . "\\") ("<->" . "\\") ("<=>" . "\\") ("|->" . "\\") ("<--" . "\\") ("<==" . "\\") ("-->" . "\\") ("==>" . "\\") ("<==>" . "\\") ("|-->" . "\\") ("<->" . "\\") ("<<" . "\\") (">>" . "\\") ("<>" . "\\") ("[|" . "\\") ("|]" . "\\") ("{|" . "\\") ("|}" . "\\") ("(|" . "\\") ("|)" . "\\") ;; useful for unicode-tokens-replace-shortcuts ("ALL" . "\\") ("EX" . "\\") ("!!" . "\\") ;; TODO: put these into replacement shortcuts, perhaps ;; ("~" . "\\") ;; ("!" . "\\") ;; ("?" . "\\") ;; extra misc, switch them off if you don't like them ;("|>" . "\\") ; clashes with ML parsing combinator ("<|" . "\\")) "Shortcut key sequence table for symbol tokens input. See `unicode-tokens-shortcut-alist'." :type 'unicode-tokens-shortcut-alist :set 'isar-set-and-restart-tokens :group 'isabelle :tag "Isabelle symbol shortcuts") (defcustom isar-shortcut-alist nil "Shortcut key sequence table for token input. See `unicode-tokens-shortcut-alist'." :type 'unicode-tokens-shortcut-alist :set 'isar-set-and-restart-tokens :group 'isabelle :tag "Isabelle Unicode Input Shortcuts") (defun isar-init-shortcut-alists () "Set defaults for `isar-shortcut-alist' and `isar-shortcut-replacement-alist'." (custom-set-default 'isar-shortcut-alist (append isar-symbol-shortcuts ;; LaTeX-like syntax for symbol names, easier to type (mapcar (lambda (tokentry) (cons (concat "\\" (car tokentry)) (format isar-token-format (car tokentry)))) (append isar-greek-letters-tokens isar-symbols-tokens))))) ;; todo: allow shortcuts for replacements to be a different list ;; (setq unicode-tokens-shortcut-replacement-alist nil)) (isar-init-shortcut-alists) ;; ;; To generate special menu entries ;; (defconst isar-tokens-customizable-variables '(("Symbols" isar-symbols-tokens) ("Extended Symbols" isar-extended-symbols-tokens) ("User Tokens" isar-user-tokens) ("Misc Letters" isar-misc-letters-tokens) ("Greek Letters" isar-greek-letters-tokens) ("Fallbacks" isar-symbols-tokens-fallbacks) ("Shortcuts" isar-symbol-shortcuts))) ;; ;; prover symbol support ;; (eval-after-load "isar" '(setq proof-tokens-activate-command (isar-markup-ml "change print_mode (insert (op =) \"xsymbols\")") proof-tokens-deactivate-command (isar-markup-ml "change print_mode (remove (op =) \"xsymbols\")"))) (provide 'isar-unicode-tokens) ;;; isar-unicode-tokens.el ends here proofgeneral-4.3~pre130510/isar/isar.el000066400000000000000000000535731214562307500176620ustar00rootroot00000000000000;; isar.el --- Major mode for Isabelle/Isar proof assistant ;; ;; Copyright (C) 1994-2010 LFCS Edinburgh. ;; ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; Maintainers: David Aspinall, Makarius, Stefan Berghofer ;; ;; Authors: David Aspinall ;; Markus Wenzel ;; ;; Contributors: David von Oheimb, Sebastian Skalberg ;; ;; $Id: isar.el,v 12.1 2011/10/17 09:25:36 da Exp $ ;; ;;; Code: (eval-when-compile (require 'cl)) (eval-when (compile) (require 'span) (require 'proof-syntax) (require 'pg-goals) (require 'pg-vars) (require 'outline) (defvar comment-quote-nested nil) (defvar isar-use-find-theorems-form nil) (defvar isar-use-linear-undo nil) (proof-ready-for-assistant 'isar)) ; compile for isar (require 'proof) (require 'isabelle-system) ; system code (require 'isar-find-theorems) ; "Find Theorems" search form ;; ;; 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) (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). (eval-after-load "pg-custom" '(setq isar-toolbar-entries (assq-delete-all 'qed (assq-delete-all 'goal isar-toolbar-entries)))) (defun isar-strip-terminators () "Remove explicit Isabelle/Isar command terminators `;' from the buffer." (interactive) (save-excursion (goto-char (point-min)) (while (proof-search-forward ";" (point-max) t) (while (not (proof-buffer-syntactic-context)) (delete-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." (set (make-local-variable 'indent-tabs-mode) nil) (setq proof-assistant-home-page isar-web-page proof-guess-command-line 'isabelle-set-prog-name proof-prog-name-guess t ;; proof script syntax proof-terminal-string ";" ; forcibly ends a command proof-electric-terminator-noterminator t ; don't insert it proof-script-command-start-regexp isar-any-command-regexp proof-script-integral-proofs 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 ;; For func-menu and finding goal..save regions 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 proof-goal-with-hole-result isar-named-entity-name-match-number proof-save-with-hole-regexp nil proof-script-imenu-generic-expression isar-generic-expression imenu-syntax-alist isar-script-syntax-table-alist 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 proof-showproof-command "pr" proof-goal-command "lemma \"%s\"" proof-save-command "qed" proof-context-command "print_context" proof-info-command "welcome" proof-query-identifier-command '((nil "thm %s;") (string "term \"%s\";") (comment "term \"%s\";")) proof-shell-start-silent-cmd "disable_pr" proof-shell-stop-silent-cmd "enable_pr" proof-shell-trace-output-regexp "\^AI\^AV" proof-script-preprocess 'isar-command-wrapping ;; command hooks proof-goal-command-p 'isar-goal-command-p proof-really-save-command-p 'isar-global-save-command-p 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) ;; proof assistant settings (setq proof-use-pgip-askprefs t) ;; others: find theorems, undo config (isar-configure-from-settings)) (defun isar-shell-mode-config-set-variables () "Configure generic proof shell mode variables for Isabelle/Isar." (setq proof-shell-annotated-prompt-regexp "^\\w*[>#] \^AS" ;; 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-interrupt-regexp "\^AM\\*\\*\\* Interrupt" proof-shell-error-regexp "\^AM\\*\\*\\*" proof-shell-proof-completed-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 proof-shell-start-goals-regexp "\^AO" proof-shell-end-goals-regexp "\^AP" proof-shell-init-cmd nil proof-shell-restart-cmd "ProofGeneral.restart" proof-shell-eager-annotation-start-length 2 proof-shell-eager-annotation-start "\^AI\\|\^AK" proof-shell-eager-annotation-end "\^AJ\\|\^AL" proof-shell-strip-output-markup 'isar-strip-output-markup pg-special-char-regexp "\^A[0-9A-Z]" pg-subterm-help-cmd "term %s" proof-cannot-reopen-processed-files t ;; Urgent messages delimited by eager annotations proof-shell-clear-response-regexp "\^AIProof General, please clear the response buffer." proof-shell-clear-goals-regexp "\^AIProof General, please clear the goals buffer." proof-shell-theorem-dependency-list-regexp "\^AIProof General, theorem dependencies of \"\\(.*\\)\" are \"\\(.*\\)\"\\(\^AJ\\)" proof-shell-retract-files-regexp "\^AIProof General, you can unlock the file \"\\(.*\\)\"\^AJ" proof-shell-process-file (cons "\^AIProof General, this file is loaded: \"\\(.*\\)\"\^AJ" (lambda () (match-string 1))) proof-shell-match-pgip-cmd "\^AI 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 CMD preserves the proofstate." (proof-string-match isar-undo-skip-regexp cmd)) ;; ;; Commands specific to isar ;; (proof-defshortcut isar-bold "\\<^bold>%p" [(control b)]) (proof-defshortcut isar-local "\\<^loc>%p" [(control c)]) (proof-defshortcut isar-super "\\<^sup>%p" [(control u)]) (proof-defshortcut isar-sub "\\<^sub>%p" [(control l)]) (proof-defshortcut isar-longsuper "\\<^bsup>%p\\<^esup>" [?u]) (proof-defshortcut isar-longsub "\\<^bsub>%p\\<^esub>" [?l]) (proof-defshortcut isar-idsub "\\<^isub>%p" [(control i)]) (proof-defshortcut isar-raw "\\<^raw:%p>" [(control r)]) (proof-defshortcut isar-antiquote "@{text \"%p\"}" [(control a)]) (proof-defshortcut isar-ml "ML {* %p *}" [(control x)]) ;; ;; Isar shell startup and exit hooks ;; (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.") (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 (not proof-shell-silent) (proof-with-current-buffer-if-exists proof-goals-buffer (let ((current-width ;; Actually, one might want the width of the ;; proof-response-buffer instead. Never mind. (max 20 (window-width (get-buffer-window proof-goals-buffer t))))) (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)) ;; ;; Shell mode command adjusting ;; (defsubst isar-string-wrapping (string) (concat "\"" (replace-regexp-in-string "[\000-\037\"\\\\]" (lambda (str) (format "\\\\%03d" (string-to-char str))) string) "\"")) (defsubst isar-positions-of (filename start end) (let ((line (line-number-at-pos start))) (format "(\"file\"=%s, \"line\"=\"%d\") " (isar-string-wrapping filename) ; cache this? line))) (defcustom isar-wrap-commands-singly t "Non-nil to use command wrapping around commands sent to Isabelle. This slows down interactive processing slightly." :type 'boolean :group 'isabelle) (defun isar-command-wrapping (filename start end string) "A value for `proof-script-preprocess'." (if isar-wrap-commands-singly (list "Isabelle.command " (isar-positions-of filename start end) (isar-string-wrapping string)) (list (replace-regexp-in-string "\n" "\\\\<^newline>" string)))) (defun isar-preprocessing () "Insert sync markers and other hacks. Uses variables `string' and `scriptspan' passed by dynamic scoping." (with-no-warnings ; dynamic scoping of string, scriptspan (if (proof-string-match isabelle-verbatim-regexp string) (setq string (match-string 1 string)) (unless (string-match ";[ \t]*\\'" string) (setq string (concat string ";"))) (setq string (concat "\\<^sync>; " (isar-shell-adjust-line-width) string " \\<^sync>;"))))) ;; ;; Configuring proof output buffer ;; (defun isar-mode-config () (isar-mode-config-set-variables) (isar-init-syntax-table) (setq proof-script-font-lock-keywords isar-font-lock-keywords-1) (set (make-local-variable 'comment-quote-nested) nil) ;; can cope with nested comments (set (make-local-variable 'outline-regexp) isar-outline-regexp) (set (make-local-variable 'outline-heading-end-regexp) isar-outline-heading-end-regexp) (set (make-local-variable 'outline-heading-alist) isar-outline-heading-alist) (set (make-local-variable 'blink-matching-paren-dont-ignore-comments) t) (add-hook 'proof-shell-insert-hook 'isar-preprocessing) (proof-config-done)) (defun isar-shell-mode-config () "Configure Proof General proof shell for Isabelle/Isar." (isar-init-output-syntax-table) (isar-shell-mode-config-set-variables) (set (make-local-variable 'font-lock-extra-managed-props) '(invisible)) (setq proof-shell-font-lock-keywords isar-shell-font-lock-keywords) (proof-shell-config-done)) (defun isar-response-mode-config () (isar-init-output-syntax-table) (setq proof-response-font-lock-keywords (append proof-response-font-lock-keywords isar-output-font-lock-keywords-1)) (setq font-lock-multiline t) (make-local-variable 'jit-lock-chunk-size) (setq jit-lock-chunk-size 2000) (proof-response-config-done)) (defun isar-goals-mode-config () (setq pg-goals-change-goal "prefer %s") (setq pg-goals-error-regexp proof-shell-error-regexp) (isar-init-output-syntax-table) (setq proof-goals-font-lock-keywords (append proof-goals-font-lock-keywords isar-goals-font-lock-keywords)) (setq font-lock-multiline t) (make-local-variable 'jit-lock-chunk-size) (setq jit-lock-chunk-size 2000) (proof-goals-config-done)) (provide 'isar) ;;; isar.el ends here proofgeneral-4.3~pre130510/isar/isartags000066400000000000000000000040461214562307500201310ustar00rootroot00000000000000#!/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: isartags,v 12.0 2011/10/13 10:54:50 da Exp $ # 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; } proofgeneral-4.3~pre130510/lego/000077500000000000000000000000001214562307500163555ustar00rootroot00000000000000proofgeneral-4.3~pre130510/lego/BUGS000066400000000000000000000035561214562307500170510ustar00rootroot00000000000000-*- 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. proofgeneral-4.3~pre130510/lego/README000066400000000000000000000017511214562307500172410ustar00rootroot00000000000000LEGO Proof General Written by Thomas Kleymann and Dilip Sequeira. Later maintainance by David Aspinall and Paul Callaghan. Status: *unsupported* (but tell us about problems) 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 /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: README,v 12.0 2011/10/13 10:54:50 da Exp $ proofgeneral-4.3~pre130510/lego/example.l000066400000000000000000000003571214562307500201720ustar00rootroot00000000000000(* Example proof script for Lego Proof General. $Id: example.l,v 12.0 2011/10/13 10:54:50 da Exp $ *) Module example Import lib_logic; Goal {A,B:Prop}(A /\ B) -> (B /\ A); intros; Refine H; intros; andI; Immed; Save and_comms; proofgeneral-4.3~pre130510/lego/example2.l000066400000000000000000000000531214562307500202450ustar00rootroot00000000000000Module example2 Import "readonly/readonly";proofgeneral-4.3~pre130510/lego/lego-syntax.el000066400000000000000000000105321214562307500211520ustar00rootroot00000000000000;; lego-syntax.el Syntax of LEGO ;; Copyright (C) 1994 - 1998 LFCS Edinburgh. ;; Author: Thomas Kleymann and Dilip Sequeira ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; Maintainer: Paul Callaghan ;; ;; $Id: lego-syntax.el,v 12.0 2011/10/13 10:54:50 da Exp $ ;; (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 "\\\\|\\ ;; ;; $Id: lego.el,v 12.1 2012/08/30 14:30:23 monnier Exp $ ;; (require 'proof) (require 'lego-syntax) (eval-when-compile (require 'outline)) ;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 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-handle-output (lambda (cmd string) (when (proof-string-match "^Module" cmd) ;; prevent output and just give a minibuffer message (setq proof-shell-last-output-kind 'systemspecific) (message "Imports 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-cd "Cd \"%s\";" "*Command of the inferior process to change the directory.") (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" "Major mode for LEGO proof scripts. \\{lego-mode-map}" (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 proof-response-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) ?\;) (setq ct (+ 1 ct))) (setq i (+ 1 i))))) (setq span (next-span span 'type))) (list (concat "Undo " (int-to-string ct) ";")))) (defun lego-goal-command-p (span) "Decide whether argument is a goal or not" (proof-string-match lego-goal-command-regexp (or (span-property span 'cmd) ""))) (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) 'proverproc)) ((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))) (when ans (list ans)))); was (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 (proof-shell-live-buffer) (proof-with-current-buffer-if-exists 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 t)))) (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-mode-config () (setq proof-terminal-string ";") (setq proof-script-comment-start "(*") (setq proof-script-comment-end "*)") (setq proof-assistant-home-page lego-www-home-page) (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-prog-name lego-prog-name) (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 pg-topterm-goalhyplit-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 (set proof-script-font-lock-keywords lego-font-lock-keywords-1) (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) ;; GNU Emacs (make-local-variable 'tags-table-list) (setq tags-table-list (cons lego-tags tags-table-list)))) (and (boundp 'tag-table-alist) ;; XEmacs (setq tag-table-alist (append '(("\\.l$" . lego-tags) ("lego" . lego-tags)) tag-table-alist))) (set (make-local-variable 'blink-matching-paren-dont-ignore-comments) t) ;; hooks and callbacks (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 () "Function to update `proof-included-files-list'. Value for `proof-shell-compute-new-files-list', which see. For LEGO, we assume that module identifiers coincide with file names." (let ((module (match-string 1))) (cdr (member-if (lambda (filename) (lego-equal-module-filename module filename)) proof-included-files-list)))) (defun lego-shell-mode-config () (setq proof-shell-cd-cmd lego-shell-cd 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 pg-subterm-first-special-char ?\360 pg-subterm-start-char ?\372 pg-subterm-sep-char ?\373 pg-subterm-end-char ?\374 pg-topterm-regexp "\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 pg-subterm-anns-use-stack nil proof-shell-handle-output-system-specific lego-shell-handle-output lego-shell-current-line-width nil ;; LEGO uses Unicode escape prefix: liable to create problems proof-shell-unicode nil proof-shell-process-file (cons "Creating mark \"\\(.*\\)\" \\[\\(.*\\)\\]" (lambda () (let ((match (match-string 2))) (if (equal match "") match (concat (file-name-sans-extension match) ".l"))))) proof-shell-retract-files-regexp "forgot back through Mark \"\\(.*\\)\"" proof-shell-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 pg-goals-change-goal "Next %s;" pg-goals-error-regexp lego-error-regexp) (setq font-lock-keywords lego-font-lock-terms) (lego-init-syntax-table) (proof-goals-config-done)) (provide 'lego) proofgeneral-4.3~pre130510/lego/legotags000077500000000000000000000043271214562307500201160ustar00rootroot00000000000000#!/usr/bin/perl # # Or perhaps: /usr/local/bin/perl # # $Id: legotags,v 12.0 2011/10/13 10:54:50 da Exp $ # 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; } proofgeneral-4.3~pre130510/lego/root2.l000066400000000000000000000273121214562307500176040ustar00rootroot00000000000000(************************************************************************ Conor McBride's proof that 2 has no rational root. This proof is accepted by LEGO version 1.3.1 with its standard library. *************************************************************************) Make lib_nat; (* loading basic logic, nat, plus, times etc *) (* note, plus and times are defined by recursion on their first arg *) (************************************************************************ Alternative eliminators for nat LEGO's induction tactic figures out which induction principle to use by looking at the type of the variable on which we're doing induction. Consequently, we can persuade the tactic to use an alternative induction principle if we alias the type. Nat_elim is just the case analysis principle for natural numbers---the same as the induction principle except that there's no inductive hypothesis in the step case. It's intended to be used in combination with... ...NAT_elim, which performs no case analysis but says you can have an inductive hypothesis for any smaller value, where y is smaller than suc (plus x y). This is `well-founded induction' for the < relation, but expressed more concretely. The effect is very similar to that of `Case' and `Fix' in Coq. ************************************************************************) [Nat = nat]; [NAT = Nat]; (* case analysis: just a weakening of induction *) Goal Nat_elim : {Phi:nat->Type} {phiz:Phi zero} {phis:{n:Nat}Phi (suc n)} {n:Nat}Phi n; intros ___; Expand Nat; Induction n; Immed; intros; Immed; Save; (* suc-plus guarded induction: the usual proof *) Goal NAT_elim : {Phi:nat->Type} {phi:{n:Nat} {ih:{x,y|Nat}(Eq n (suc (plus x y)))->Phi y} Phi n} {n:NAT}Phi n; intros Phi phi n'; (* claim that we can build the hypothesis collector for each n *) Claim {n:nat}{x,y|Nat}(Eq n (suc (plus x y)))->Phi y; (* use phi on the claimed collector *) Refine phi n' (?+1 n'); (* now build the collector by one-step induction *) Induction n; Qnify; (* nothing to collect for zero *) intros n nhyp; Induction x; (* case analysis on the slack *) Qnify; Refine phi; (* if the bound is tight, use phi to *) Immed; (* generate the new member of the collection *) Qnify; Refine nhyp; (* otherwise, we've already collected it *) Immed; Save; (*************************************************************************** Equational laws governing plus and times: some of these are doubtless in the library, but it takes longer to remember their names than to prove them again. ****************************************************************************) Goal plusZero : {x:nat}Eq (plus x zero) x; Induction x; Refine Eq_refl; intros; Refine Eq_resp suc; Immed; Save; Goal plusSuc : {x,y:nat}Eq (plus x (suc y)) (suc (plus x y)); Induction x; intros; Refine Eq_refl; intros; Refine Eq_resp suc; Immed; Save; Goal plusAssoc : {x,y,z:nat}Eq (plus (plus x y) z) (plus x (plus y z)); Induction x; intros; Refine Eq_refl; intros; Refine Eq_resp suc; Immed; Save; Goal plusComm : {x,y:nat}Eq (plus x y) (plus y x); Induction y; Refine plusZero; intros y yh x; Refine Eq_trans (plusSuc x y); Refine Eq_resp suc; Immed; Save; Goal plusCommA : {x,y,z:nat}Eq (plus x (plus y z)) (plus y (plus x z)); intros; Refine Eq_trans ? (plusAssoc ???); Refine Eq_trans (Eq_sym (plusAssoc ???)); Refine Eq_resp ([w:nat]plus w z); Refine plusComm; Save; Goal timesZero : {x:nat}Eq (times x zero) zero; Induction x; Refine Eq_refl; intros; Immed; Save; Goal timesSuc : {x,y:nat}Eq (times x (suc y)) (plus x (times x y)); Induction x; intros; Refine Eq_refl; intros x xh y; Equiv Eq (suc (plus y (times x (suc y)))) ?; Equiv Eq ? (suc (plus x (plus y (times x y)))); Refine Eq_resp; Qrepl xh y; Refine plusCommA; Save; Goal timesComm : {x,y:nat}Eq (times x y) (times y x); Induction y; Refine timesZero; intros y yh x; Refine Eq_trans (timesSuc ??); Refine Eq_resp (plus x); Immed; Save; Goal timesDistL : {x,y,z:nat}Eq (times (plus x y) z) (plus (times x z) (times y z)); Induction x; intros; Refine Eq_refl; intros x xh y z; Refine Eq_trans (Eq_resp (plus z) (xh y z)); Refine Eq_sym (plusAssoc ???); Save; Goal timesAssoc : {x,y,z:nat}Eq (times (times x y) z) (times x (times y z)); Induction x; intros; Refine Eq_refl; intros x xh y z; Refine Eq_trans (timesDistL ???); Refine Eq_resp (plus (times y z)); Immed; Save; (********************************************************************** Inversion principles for equations governing plus and times: these aren't in the library, at least not in this form. ***********************************************************************) [Phi|Type]; (* Inversion principles are polymorphic in any goal *) Goal plusCancelL : {y,z|nat}{phi:{q':Eq y z}Phi}{x|nat} {q:Eq (plus x y) (plus x z)}Phi; intros ___; Induction x; intros; Refine phi q; intros x xh; Qnify; Refine xh; Immed; Save; Goal timesToZero : {a,b|Nat} {phiL:(Eq a zero)->Phi} {phiR:(Eq b zero)->Phi} {tz:Eq (times a b) zero} Phi; Induction a; intros; Refine phiL (Eq_refl ?); intros a; Induction b; intros; Refine phiR (Eq_refl ?); Qnify; Save; Goal timesToNonZero : {x,y|nat} {phi:{x',y'|nat}(Eq x (suc x'))->(Eq y (suc y'))->Phi} {z|nat}{q:Eq (times x y) (suc z)}Phi; Induction x; Qnify; intros x xh; Induction y; intros __; Qrepl timesZero (suc x); Qnify; intros; [EQR=Eq_refl]; Refine phi Then Immed; Save; (* I actually want plusDivisionL, but plusDivisionR is easier to prove, because here we do induction where times does computation. *) Goal plusDivisionR : {b|nat}{a,x,c|Nat} {phi:{c'|nat}(Eq (times c' (suc x)) c)-> (Eq a (plus b c'))->Phi} {q:Eq (times a (suc x)) (plus (times b (suc x)) c)} Phi; Induction b; intros _____; Refine phi; Immed; Refine Eq_refl; intros b bh; Induction a; Qnify; intros a x c phi; Qrepl plusAssoc (suc x) (times b (suc x)) c; Refine plusCancelL; Refine bh; intros c q1 q2; Refine phi q1; Refine Eq_resp ? q2; Save; (* A bit of timesComm gives us the one we really need. *) Goal plusDivisionL : {b|nat}{a,x,c|Nat} {phi:{c'|nat}(Eq (times (suc x) c') c)-> (Eq a (plus b c'))->Phi} {q:Eq (times (suc x) a) (plus (times (suc x) b) c)} Phi; intros _____; Qrepl timesComm (suc x) a; Qrepl timesComm (suc x) b; Refine plusDivisionR; intros c'; Qrepl timesComm c' (suc x); Immed; Save; Discharge Phi; (************************************************************************** Definition of primality: This choice of definition makes primality easy to exploit (especially as it's presented as an inversion principle), but hard to establish. ***************************************************************************) [Prime = [p:nat] {a|NAT}{b,x|Nat}{Phi|Prop} {q:Eq (times p x) (times a b)} {phiL:{a':nat} (Eq a (times p a'))->(Eq x (times a' b))->Phi} {phiR:{b':nat} (Eq b (times p b'))->(Eq x (times a b'))->Phi} Phi ]; (************************************************************************** Proof that 2 is Prime. Nontrivial because of the above definition. Manageable because 1 is the only number between 0 and 2. ***************************************************************************) Goal doublePlusGood : {x,y:nat}Eq (times (suc (suc x)) y) (plus (times two y) (times x y)); intros __; Refine Eq_trans ? (Eq_sym (plusAssoc ???)); Refine Eq_resp (plus y); Refine Eq_trans ? (Eq_sym (plusAssoc ???)); Refine Eq_refl; Save; Goal twoPrime : Prime two; Expand Prime; Induction a; Induction n; intros useless b x _; Refine timesToZero Then Expand Nat Then Qnify; (* Qnify needs to know it's a nat *) intros; Refine phiL; Refine +1 (Eq_sym (timesZero ?)); Refine Eq_refl; Induction n; intros useless b x _; Qrepl plusZero b; intros; Refine phiR; Refine +1 Eq_sym q; Refine Eq_sym (plusZero x); intros n nhyp b x _; Qrepl doublePlusGood n b; Refine plusDivisionL; intros c q1 q2; Qrepl q2; intros __; Refine nhyp|one (Eq_refl ?) q1; intros a' q3 q4; Refine phiL (suc a'); Refine Eq_resp suc; Refine Eq_trans ? (Eq_sym (plusSuc ??)); Refine Eq_resp ? q3; Refine Eq_resp (plus b) q4; intros b' q3 q4; Refine phiR b'; Immed; Qrepl q3; Qrepl q4; Refine Eq_sym (doublePlusGood ??); Save; (************************************************************************** Now the proof that primes (>=2) have no rational root. It's the classic `minimal counterexample' proof unwound as an induction: we apply the inductive hypothesis to the smaller counterexample we construct. ***************************************************************************) [pm2:nat] [p=suc (suc pm2)] (* p is at least 2 *) [Pp:Prime p]; Goal noRatRoot : {b|NAT}{a|Nat}{q:Eq (times p (times a a)) (times b b)} and (Eq a zero) (Eq b zero); Induction b; Induction n; (* if b is zero, so is a, and the result holds *) intros useless; intros a; Refine timesToZero; Expand Nat; Qnify; Refine timesToZero; Refine ?+1; intros; Refine pair; Immed; Refine Eq_refl; intros b hyp a q; (* otherwise, build a smaller counterexample *) Refine Pp q; (* use primality once *) Refine cut ?+1; (* standard technique for exploiting symmetry *) intros H a' aq1 aq2; Refine H; Immed; Refine Eq_trans aq2; Refine timesComm; intros c bq; Qrepl bq; Qrepl timesAssoc p c c; Refine timesToNonZero ? (Eq_sym bq); (* need c to be nonzero *) intros p' c' dull cq; Qrepl cq; intros q2; Refine Pp (Eq_sym q2); (* use primality twice *) Refine cut ?+1; (* symmetry again *) intros H a' aq1 aq2; Refine H; Immed; Refine Eq_trans aq2; Refine timesComm; intros d aq; Qrepl aq; Qrepl timesAssoc p d d; intros q3; Refine hyp ? (Eq_sym q3); (* now use ind hyp *) Next +2; Expand NAT Nat; Qnify; (* trivial solution *) Next +1; (* show induction was properly guarded *) Refine Eq_trans bq; Expand p; Qrepl cq; Refine plusComm; Save; Discharge pm2; (********************************************************************** Putting it all together ***********************************************************************) [noRatRootTwo = noRatRoot zero twoPrime : {b|nat}{a|nat}(Eq (times two (times a a)) (times b b))-> (Eq a zero /\ Eq b zero)]; proofgeneral-4.3~pre130510/lib/000077500000000000000000000000001214562307500161755ustar00rootroot00000000000000proofgeneral-4.3~pre130510/lib/README000066400000000000000000000003531214562307500170560ustar00rootroot00000000000000This directory contains general library lisp files. Some of these have been developed as part of the Proof General project; others have been taken from other sources. See individual files for copyright holder and license details. proofgeneral-4.3~pre130510/lib/bufhist.el000066400000000000000000000306111214562307500201640ustar00rootroot00000000000000;; bufhist.el --- keep read-only history of buffer contents for browsing ;; Copyright (C) 2006, 2009 David Aspinall / University of Edinburgh ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; Keywords: tools ;; ;; $Id: bufhist.el,v 12.0 2011/10/13 10:54:50 da Exp $ ;; ;; 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 library implements a minor mode for which keeps a ring history of ;; buffer contents. Intended to be used for small buffers which are ;; intermittently updated (e.g. status panels/displays), for which history ;; browsing is useful. ;; ;; TODO: this will be replaced by a more PG-specific and efficient ;; approach which keep regions within a single buffer rather than ;; copying strings in and out. That way we can use cloned (indirect) ;; buffers which allow independent browsing of the history. ;; ;; FIXMEs: - autoloading this doesn't work too well. ;; - advice on erase-buffer doesn't work ;; - duplicated first item in ring after clear (& on startup). ;; - buttons are put at top of buffer but inserts happen before them ;; (require 'ring) (declare-function bufhist-ordinary-erase-buffer "bufhist") ;;; First a function which ought to be in ring.el (defun bufhist-ring-update (ring index newitem) "Update RING at position INDEX with NEWITEM." (if (ring-empty-p ring) (error "Accessing an empty ring") (let* ((hd (car ring)) (ln (car (cdr ring))) (vec (cdr (cdr ring)))) (aset vec (ring-index index hd ln (length vec)) newitem)))) ;;; Now our code (defgroup bufhist nil "In-memory history of buffer contents" :group 'tools) (defcustom bufhist-ring-size 30 "*Default size of buffer history ring." :group 'bufhist :type 'integer) (defvar bufhist-ring nil "Ring history of buffer. Always non-empty.") (defvar bufhist-ring-pos nil "Current position in ring history of buffer.") (defvar bufhist-lastswitch-modified-tick nil "Value of (buffer-modified-tick) at last switch buffer.") (defvar bufhist-read-only-history t "Whether history is editable.") (defvar bufhist-saved-mode-line-format nil "Ordinary value of `mode-line-format' for this buffer.") (defvar bufhist-normal-read-only nil "Ordinary value `buffer-read-only' for this buffer.") (defvar bufhist-top-point 0 "Poistion of top of real buffer contents, after buttons.") (defun bufhist-mode-line-format-entry () (when bufhist-ring-pos (let* ((histpos (- (ring-length bufhist-ring) bufhist-ring-pos)) (histsize (ring-length bufhist-ring)) (desc (format "History %d of %d; mouse-1 previous; mouse-3 next" histpos histsize)) (indicator (format "[%d/%d]" histpos histsize))) (propertize indicator 'help-echo desc 'keymap (eval-when-compile (let ((map (make-sparse-keymap))) ;; FIXME: clicking can go wrong here because the ;; current buffer can be something else which has no hist! (define-key map [mode-line mouse-1] 'bufhist-prev) (define-key map [mode-line mouse-3] 'bufhist-next) ;; (define-key map [mode-line control mouse-1] 'bufhist-first) ;; (define-key map [mode-line control mouse-3] 'bufhist-last) map)) 'mouse-face 'mode-line-highlight)))) ;simple: ; '(" [hist:" ; (:eval (int-to-string (- (ring-length bufhist-) ; bufhist-ring-pos))) "/" ; (:eval (int-to-string (ring-length bufhist-ring))) "]")) ;;; Minor mode (defconst bufhist-minor-mode-map (let ((map (make-sparse-keymap))) ;; (define-key map [mouse-2] 'bufhist-popup-menu) (define-key map [(meta left)] 'bufhist-prev) (define-key map [(meta right)] 'bufhist-next) (define-key map [(meta up)] 'bufhist-first) (define-key map [(meta down)] 'bufhist-last) (define-key map [(meta c)] 'bufhist-clear) (define-key map [(meta d)] 'bufhist-delete) map) "Keymap for `bufhist-minor-mode'.") ;;;###autoload (define-minor-mode bufhist-mode "Minor mode retaining an in-memory history of the buffer contents. Commands:\\ \\[bufhist-prev] bufhist-prev go back in history \\[bufhist-next] bufhist-next go forward in history \\[bufhist-first] bufhist-first go to first item in history \\[bufhist-last] bufhist-last go to last (current) item in history. \\[bufhist-clear] bufhist-clear clear history. \\[bufhist-delete] bufhist-clear delete current item from history." nil "" bufhist-minor-mode-map :group 'bufhist (if bufhist-mode (bufhist-init) (bufhist-exit))) (make-variable-buffer-local 'bufhist-ring) (make-variable-buffer-local 'bufhist-ring-pos) (make-variable-buffer-local 'bufhist-lastswitch-modified-tick) (make-variable-buffer-local 'bufhist-read-only-history) (make-variable-buffer-local 'bufhist-top-point) (defun bufhist-get-buffer-contents () "Return the stored representation of the current buffer contents. This is as a pair (POINT . CONTENTS)." (cons (point) (buffer-substring bufhist-top-point (point-max)))) (fset 'bufhist-ordinary-erase-buffer (symbol-function 'erase-buffer)) ;(defalias 'bufhist-ordinary-erase-buffer 'erase-buffer) (defun bufhist-restore-buffer-contents (buf) "Restore BUF as the contents of the current buffer." (bufhist-ordinary-erase-buffer) (bufhist-insert-buttons) (insert (cdr buf)) ;; don't count this as a buffer update (setq bufhist-lastswitch-modified-tick (buffer-modified-tick)) (goto-char (car buf))) (defun bufhist-checkpoint () "Add buffer contents to the ring history. No action if not in bufhist mode." (interactive) (if bufhist-mode ;; safety (ring-insert bufhist-ring (bufhist-get-buffer-contents)))) ;; Unfortunately, erase-buffer doesn't call before-change-functions. ;; We could provide advice for erase-buffer, but instead make this part of API. (defun bufhist-erase-buffer () "Erase buffer contents, maybe running bufhist-before-change-function first." (if (and bufhist-mode (memq 'bufhist-before-change-function before-change-functions)) (let ((before-change-functions nil) (after-change-functions nil)) (bufhist-before-change-function))) (erase-buffer) (bufhist-insert-buttons)) (defun bufhist-checkpoint-and-erase () "Add buffer contents to history then erase. Only erase if not in bufhist mode" (interactive) (bufhist-checkpoint) (bufhist-erase-buffer)) (defun bufhist-switch-to-index (n &optional nosave browsing) "Switch to position N in buffer history, maybe updating history. If optional NOSAVE is non-nil, do not try to save current contents." (unless (equal n bufhist-ring-pos) ;; we're moving to different position (let ((tick (buffer-modified-tick))) ;; Save changes back to history for most recent contents or for ;; older contents if we have read-write history (unless (or nosave (and bufhist-read-only-history (not (eq bufhist-ring-pos 0))) (equal tick bufhist-lastswitch-modified-tick)) ;; If we're browsing away from position 0, checkpoint instead ;; of updating. ;; NB: logic here should ideally keep flag to say whether ;; changes are "during" a browse or not. This is going ;; to result in too many checkpoints if we have manual ;; editing. (if (and browsing (eq bufhist-ring-pos 0)) ;(progn (bufhist-checkpoint) ; (setq n (1+ n))) ;; Otherwise update in-position (bufhist-ring-update bufhist-ring bufhist-ring-pos (bufhist-get-buffer-contents)))) (setq bufhist-lastswitch-modified-tick tick) (let ((before-change-functions nil) (buffer-read-only nil)) (bufhist-restore-buffer-contents (ring-ref bufhist-ring n))) (if bufhist-read-only-history (setq buffer-read-only (if (eq n 0) bufhist-normal-read-only t))) (setq bufhist-ring-pos n) (force-mode-line-update) (if browsing (message "History position %d of %d in %s" (- (ring-length bufhist-ring) n) (ring-length bufhist-ring) (buffer-name)))))) (defun bufhist-first () "Switch to most oldest buffer contents." (interactive) (bufhist-switch-to-index (1- (ring-length bufhist-ring)) nil 'browsing)) (defun bufhist-last () "Switch to last (most recent; current) buffer contents." (interactive) (bufhist-switch-to-index 0 nil 'browsing)) (defun bufhist-prev (&optional n) "Browse backward in the history of buffer contents." (interactive "p") (bufhist-switch-to-index (mod (+ bufhist-ring-pos (or n 1)) (ring-length bufhist-ring)) nil 'browsing)) (defun bufhist-next (&optional n) "Browse forward in the history of buffer contents." (interactive "p") (bufhist-prev (- (or n 1)))) (defun bufhist-delete () "Delete the current item in the buffer history." (interactive) (message "History item deleted from buffer %s." (buffer-name)) (unless (eq 0 bufhist-ring-pos) (ring-remove bufhist-ring bufhist-ring-pos) (bufhist-switch-to-index (1- bufhist-ring-pos) 'nosave))) ;; FIXME: glitch here: we get duplicated first item after clear. ;; Bit like on startup: we always get empty buffer/current contents ;; twice. Reason is because of invariant of non-empty ring; ;; when we checkpoint we always add to ring. (defun bufhist-clear () "Clear history." (interactive) (message "Buffer history in %s cleared." (buffer-name)) (bufhist-switch-to-index 0 'nosave) (setq bufhist-ring (make-ring (ring-size bufhist-ring))) (setq bufhist-ring-pos 0) (bufhist-checkpoint) (setq bufhist-lastswitch-modified-tick (buffer-modified-tick)) (force-mode-line-update)) ;; Setup functions ;;;###autoload (defun bufhist-init (&optional readwrite ringsize) "Initialise a ring history for the current buffer. The history will be read-only unless READWRITE is non-nil. For read-only histories, edits to the buffer switch to the latest version. The size defaults to `bufhist-ring-size'." (interactive) (setq bufhist-ring (make-ring (or ringsize bufhist-ring-size))) (setq bufhist-normal-read-only buffer-read-only) (setq bufhist-read-only-history (not readwrite)) (setq bufhist-ring-pos 0) (setq bufhist-saved-mode-line-format mode-line-format) (save-excursion (goto-char (point-min)) (bufhist-insert-buttons)) (bufhist-checkpoint) (setq mode-line-format (cons '(bufhist-mode (:eval (bufhist-mode-line-format-entry))) ;; surely it's always a list, but in case not (if (listp mode-line-format) mode-line-format (list mode-line-format)))) (force-mode-line-update) (make-local-variable 'before-change-functions) (bufhist-set-readwrite readwrite)) ;;;###autoload (defun bufhist-exit () "Stop keeping ring history for current buffer." (interactive) (bufhist-switch-to-index 0) (setq bufhist-ring-pos nil) (bufhist-set-readwrite t) (setq mode-line-format bufhist-saved-mode-line-format) (force-mode-line-update)) (defun bufhist-set-readwrite (readwrite) "Set `before-change-functions' for read-only history." (if readwrite ;; edit directly (progn (setq before-change-functions (remq 'bufhist-before-change-function before-change-functions))) ; (ad-disable-advice 'erase-buffer 'before 'bufhist-last-advice))) ;; readonly history: switch to latest contents (setq before-change-functions (cons 'bufhist-before-change-function before-change-functions)))) ; (ad-enable-advice 'erase-buffer 'before 'bufhist-last-advice)))) ;; Restore the latest buffer contents before changes from elsewhere. (defun bufhist-before-change-function (&rest args) "Restore the most recent contents of the buffer before changes." (bufhist-switch-to-index 0)) ;; Unfortunately, erase-buffer does not call before-change-function ; (defadvice erase-buffer (before bufhist-last-advice activate) ; (if (and bufhist-mode bufhist-read-only-history) ; (bufhist-last))) ; (ad-activate-on 'erase-buffer))) ;;; ;;; Buttons ;;; (define-button-type 'bufhist-next 'follow-link t 'help-echo "Next" 'action #'bufhist-next) (define-button-type 'bufhist-prev 'follow-link t 'help-echo "Previous" 'action #'bufhist-prev) ;; Little bit tricky: inserts by clients start at (point-min) which ;; is going to insert above these buttons (defun bufhist-insert-buttons () (when bufhist-mode (let ((inhibit-read-only t)) (save-excursion (goto-char (point-min)) (insert-text-button " < " :type 'bufhist-prev) (insert " ") (insert-text-button " > " :type 'bufhist-next) (insert "\n\n") (setq bufhist-top-point (point)))))) (provide 'bufhist) proofgeneral-4.3~pre130510/lib/holes.el000066400000000000000000000625121214562307500176370ustar00rootroot00000000000000;;; holes.el --- a little piece of elisp to define holes in your buffer ;; ;; Copyright (C) 2001 Pierre Courtieu ;; ;; $Id: holes.el,v 12.2 2012/09/19 13:34:47 pier Exp $ ;; ;; This file uses spans, an interface for extent (XEmacs) and overlays ;; (emacs), by Healfdene Goguen for the proofgeneral mode. ;; ;; Credits also to Stefan Monnier for great help in making this file ;; cleaner. ;; ;; Further cleanups by David Aspinall. ;; ;; This software is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public ;; License version 2, as published by the Free Software Foundation. ;; ;; This software 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 version 2 for more details ;; (enclosed in the file GPL). ;; ;; See documentation in variable holes-short-doc. ;; ;;; Commentary: ;; ;; See documentation of `holes-mode'. (eval-when-compile (require 'span)) (require 'cl) ;;; Code: ;;; ;;; initialization ;;; (defvar holes-default-hole (let ((ol (make-overlay 0 0))) (delete-overlay ol) ol) "An empty detached hole used as the default hole. You should not use this variable.") (defvar holes-active-hole holes-default-hole "The current active hole. There can be only one active hole at a time, and this is this one. This is not buffer local.") ;;; ;;; Customizable ;;; (defgroup holes nil "Customization for Holes minor mode." :prefix "holes-" :group 'editing) (defcustom holes-empty-hole-string "#" "String to be inserted for empty hole (don't put an empty string)." :type 'string :group 'holes) (defcustom holes-empty-hole-regexp "#\\|@{\\([^{}]*\\)}" "Regexp denoting a hole in abbrevs. Subgroup 1 is treated specially: if it matches, it is assumed that everything before it and after it in the regexp matches delimiters which should be removed when making the text into a hole." :type 'regexp :group 'holes) ;(defcustom holes-search-limit 1000 ; "Number of chars to look forward when looking for the next hole, unused for now.") ;unused for the moment ;; The following is customizable by a command of the form: ;;for dark background ;;(custom-set-faces ;; '(holes-active-hole-face ;; ((((type x) (class color) (background light)) ;; (:background "paleVioletRed"))) ;; ) ;; ) (defface active-hole-face '((((class grayscale) (background light)) :background "dimgrey") (((class grayscale) (background dark)) :background "LightGray") (((class color) (background dark)) :background "darkred" :foreground "white") (((class color) (background light)) :background "paleVioletRed" :foreground "black")) "Font Lock face used to highlight the active hole." :group 'holes) (defface inactive-hole-face '((((class grayscale) (background light)) :background "lightgrey") (((class grayscale) (background dark)) :background "Grey") (((class color) (background dark)) :background "mediumblue" :foreground "white") (((class color) (background light)) :background "lightsteelblue" :foreground "black")) "Font Lock face used to highlight the active hole." :group 'holes) ;;; ;;; Keymaps ;;; (defvar hole-map (let ((map (make-sparse-keymap))) (define-key map [(mouse-1)] 'holes-mouse-set-active-hole) (define-key map [(mouse-3)] 'holes-mouse-destroy-hole) (define-key map [(mouse-2)] 'holes-mouse-forget-hole) map) "Keymap to use on the holes's overlays. This keymap is used only when point is on a hole. See `holes-mode-map' for the keymap of `holes-mode'.") (defvar holes-mode-map (let ((map (make-sparse-keymap))) (define-key map [(control c) (h)] 'holes-set-make-active-hole) (define-key map [(control c) (control y)] 'holes-replace-update-active-hole) (define-key map [(control meta down-mouse-1)] 'holes-mouse-set-make-active-hole) (define-key map [(control meta shift down-mouse-1)] 'holes-mouse-replace-active-hole) (define-key map [(control c) (control j)] 'holes-set-point-next-hole-destroy) map) "Keymap of `holes-mode'. This one is active whenever we are on a buffer where `holes-mode' is active. This is not the keymap used on holes's overlay (see `hole-map' instead).") (easy-menu-define nil (list holes-mode-map) "Menu used in Holes minor mode." '("Holes" ;; da: I tidied this menu a bit. I personally think this "trick" ;; of inserting strings to add documentation looks like a real ;; mess in menus ... I've removed it for the three below since ;; the docs below appear in popup in messages anyway. ;; ;; "Make a hole active click on it" ;; "Disable a hole click on it (button 2)" ;; "Destroy a hole click on it (button 3)" ["Make Hole At Point" holes-set-make-active-hole t] ["Make Selection A Hole" holes-set-make-active-hole t] ["Replace Active Hole By Selection" holes-replace-update-active-hole t] ["Jump To Active Hole" holes-set-point-next-hole-destroy t] ["Forget All Holes" holes-clear-all-buffer-holes t] ;; look a bit better at the bottom "---" ["About Holes" holes-show-doc t] "Hint: make hole with mouse: C-M-select" "Hint: replace hole with mouse: C-M-Shift-select" )) ;;; ;;; Utility functions ;;; (defun holes-region-beginning-or-nil () "Return the beginning of the acitve region, or nil." (and mark-active (region-beginning))) (defun holes-region-end-or-nil () "Return the end of the acitve region, or nil." (and mark-active (region-end))) (defun holes-copy-active-region () "Copy and retuurn the active region." (assert mark-active nil "the region is not active now.") (copy-region-as-kill (region-beginning) (region-end)) (car kill-ring)) (defun holes-is-hole-p (span) "Non-nil if SPAN is a HOLE." (span-property span 'hole)) (defun holes-hole-start-position (hole) "Return start position of HOLE." (assert (holes-is-hole-p hole) t "holes-hole-start-position: %s is not a hole") (span-start hole)) (defun holes-hole-end-position (hole) "Return end position of HOLE." (assert (holes-is-hole-p hole) t "holes-hole-end-position: %s is not a hole") (span-end hole)) (defun holes-hole-buffer (hole) "Return the buffer of HOLE." "Internal." (assert (holes-is-hole-p hole) t "holes-hole-buffer: %s is not a hole") (span-buffer hole)) (defun holes-hole-at (&optional pos) "Return the hole (a span) at POS in current buffer. If pos is not in a hole raises an error." (span-at (or pos (point)) 'hole)) (defun holes-active-hole-exist-p () "Return t if the active hole exists and is not empty (ie detached). Use this to know if the active hole is set and usable (don't use the active-hole-marker variable)." (not (span-detached-p holes-active-hole))) (defun holes-active-hole-start-position () "Return the position of the start of the active hole. See `active-hole-buffer' to get its buffer. Returns an error if active hole doesn't exist (the marker is set to nothing)." (assert (holes-active-hole-exist-p) t "holes-active-hole-start-position: no active hole") (holes-hole-start-position holes-active-hole)) (defun holes-active-hole-end-position () "Return the position of the start of the active hole. See `active-hole-buffer' to get its buffer. Returns an error if active hole doesn't exist (the marker is set to nothing)." (assert (holes-active-hole-exist-p) t "holes-active-hole-end-position: no active hole") (holes-hole-end-position holes-active-hole)) (defun holes-active-hole-buffer () "Return the buffer containing the active hole. Raise an error if the active hole is not set. Don't care if the active hole is empty." (assert (holes-active-hole-exist-p) t "holes-active-hole-buffer: no active hole") (holes-hole-buffer holes-active-hole)) (defun holes-goto-active-hole () "Set point to active hole. Raises an error if active-hole is not set." (interactive) (assert (holes-active-hole-exist-p) t "holes-goto-active-hole: no active hole") (goto-char (holes-active-hole-start-position))) (defun holes-highlight-hole-as-active (hole) "Highlight a HOLE with the `active-hole-face'. DON'T USE this as it would break synchronization (non active hole highlighted)." (assert (holes-is-hole-p hole) t "holes-highlight-hole-as-active: %s is not a hole") (set-span-face hole 'active-hole-face)) (defun holes-highlight-hole (hole) "Highlight a HOLE with the not active face. DON'T USE this as it would break synchronization (active hole non highlighted)." (assert (holes-is-hole-p hole) t "holes-highlight-hole: %s is not a hole") (set-span-face hole 'inactive-hole-face)) (defun holes-disable-active-hole () "Disable the active hole. The goal remains but is not the active one anymore. Does nothing if the active hole is already disable." (if (not (holes-active-hole-exist-p)) () ;; HACK: normal hole color, this way undo will show this hole ;; normally and not as active hole. Ideally, undo should restore ;; the active hole, but it doesn't, so we put the 'not active' ;; color. (holes-highlight-hole holes-active-hole) (setq holes-active-hole holes-default-hole))) (defun holes-set-active-hole (hole) "Set active hole to HOLE. Error if HOLE is not a hole." (assert (holes-is-hole-p hole) t "holes-set-active-hole: %s is not a hole") (if (holes-active-hole-exist-p) (holes-highlight-hole holes-active-hole)) (setq holes-active-hole hole) (holes-highlight-hole-as-active holes-active-hole)) (defun holes-is-in-hole-p (&optional pos) "Return non-nil if POS (default: point) is in a hole, nil otherwise." (holes-hole-at pos)) (defun holes-make-hole (start end) "Make and return an (span) hole from START to END." (let ((ext (span-make start end))) (set-span-properties ext `(hole t mouse-face highlight priority 100 ;; what should I put here? I want big priority face secondary-selection start-open nil end-open t duplicable t evaporate t ;; really disappear if empty ;; pointer frame-icon-glyph keymap ,hole-map help-echo "this is a \"hole\", button 2 to forget, button 3 to destroy, button 1 to make active" 'balloon-help "this is a \"hole\", button 2 to forget, button 3 to destroy, button 1 to make active")) ext)) (defun holes-make-hole-at (&optional start end) "Make a hole from START to END. If no arg default hole after point. If only one arg: error. Return the span." (interactive) (let* ((rstart (or start (holes-region-beginning-or-nil) (point))) (rend (or end (holes-region-end-or-nil) (point)))) (if (eq rstart rend) (progn (goto-char rstart) (insert holes-empty-hole-string) (setq rend (point)))) (holes-make-hole rstart rend))) (defun holes-clear-hole (hole) "Clear the HOLE." (assert (holes-is-hole-p hole) t "holes-clear-hole: %s is not a hole") (if (and (holes-active-hole-exist-p) (eq holes-active-hole hole)) (holes-disable-active-hole)) (span-delete hole)) (defun holes-clear-hole-at (&optional pos) "Clear hole at POS (default=point)." (interactive) (if (not (holes-is-in-hole-p (or pos (point)))) (error "Holes-clear-hole-at: no hole here")) (holes-clear-hole (holes-hole-at (or pos (point))))) (defun holes-map-holes (function &optional object from to) "Map function FUNCTION across holes." (fold-spans function object from to nil nil 'hole)) (defun holes-clear-all-buffer-holes (&optional start end) "Clear all holes leaving their contents. Operate betwenn START and END if non nil." (interactive) (holes-disable-active-hole) (span-mapcar-spans 'holes-clear-hole (or start (point-min)) (or end (point-max)) 'hole)) ;; limit ? (defun holes-next (pos buffer) "Return the first hole after POS in BUFFER. Or after the hole at pos if there is one (default pos=point). If no hole found, return nil." (holes-map-holes (lambda (h x) (and (holes-is-hole-p h) h)) buffer pos)) (defun holes-next-after-active-hole () "Internal." (assert (holes-active-hole-exist-p) t "next-active-hole: no active hole") (holes-next (holes-active-hole-end-position) (holes-active-hole-buffer))) (defun holes-set-active-hole-next (&optional buffer pos) "Set the active hole in BUFFER to the first hole after POS. Default pos = point and buffer = current." (interactive) (let ((nxthole (holes-next (or pos (point)) (or buffer (current-buffer))))) (if nxthole (holes-set-active-hole nxthole) (holes-disable-active-hole)))) ;;;(defun holes-set-active-hole-next-after-active () ;; "sets the active hole to the first hole after active ;; hole.";;;; ;;; (interactive) ;; (holes-next-after-active-hole) ;;) (defun holes-replace-segment (start end str &optional buffer) "Erase chars between START and END, and replace them with STR." (with-current-buffer (or buffer (current-buffer)) (goto-char end) ;; Insert before deleting, so the markers at `start' and `end' ;; don't get mixed up together. (insert str) (delete-region start end))) (defun holes-replace (str &optional thehole) "Replace the current hole by STR, replace THEHOLE instead if given. Do not use this, it breaks the right colorization of the active goal(FIXME?). Use `replace-active-hole' instead." (if (and (not thehole) (not (holes-active-hole-exist-p))) (error "No hole to fill") ;; defensive: replacing the hole should make it detached and ;; therefore inexistent. other reason: this is a hack: unhighlight ;; so that undo wont show it highlighted) (if (and (holes-active-hole-exist-p) thehole (eq holes-active-hole thehole)) (holes-disable-active-hole) ) (let ((exthole (or thehole holes-active-hole))) (holes-replace-segment (holes-hole-start-position exthole) (holes-hole-end-position exthole) (or str (car kill-ring)) ;kill ring? (span-buffer exthole) ) (span-detach exthole) ;; this seems necessary for span overlays, ;; where the buffer attached to the span is not removed ;; automatically by the fact that the span is removed from the ;; buffer (holes-replace-segment should perhaps take care of ;; that) ))) (defun holes-replace-active-hole (&optional str) "Replace the active hole by STR, if no str is given, then put the selection instead." (if (not (holes-active-hole-exist-p)) nil (holes-replace (or str (current-kill 0) (error "Nothing to put in hole")) holes-active-hole))) (defun holes-replace-update-active-hole (&optional str) "Replace the active hole by STR. Like `holes-replace-active-hole', but then sets the active hole to the following hole if it exists." (interactive) (assert (holes-active-hole-exist-p) t "holes-replace-update-active-hole: no active hole") (if (holes-active-hole-exist-p) (let ((nxthole (holes-next-after-active-hole))) (holes-replace-active-hole (or str (and mark-active (holes-copy-active-region)) (current-kill 0) (error "Nothing to put in hole"))) (if nxthole (holes-set-active-hole nxthole) (setq holes-active-hole holes-default-hole))))) (defun holes-delete-update-active-hole () "Deletes the active hole and supresses its content. Sets `holes-active-hole' to the next hole if it exists." (interactive) (holes-replace-update-active-hole "")) ;;;###autoload (defun holes-set-make-active-hole (&optional start end) "Make a new hole between START and END or at point, and make it active." (interactive) (holes-set-active-hole (holes-make-hole-at start end))) ;; mouse stuff, I want to make something close to `mouse-track-insert' ;; of XEmacs, but with modifier ctrl-meta and ctrl-meta-shift ;; Emacs and XEmacs have different ways of dealing with mouse ;; selection, but `mouse-track'(XEmacs) mouse-drag-region(Emacs) ;; have nearly the same meaning for me. So I define this ;; track-mouse-selection. (defalias 'holes-track-mouse-selection 'mouse-drag-track) (defsubst holes-track-mouse-clicks () "See `mouse-track-click-count'" (+ mouse-selection-click-count 1)) (defun holes-mouse-replace-active-hole (event) "Replace the active hole with one under mouse EVENT." (interactive "*e") (holes-track-mouse-selection event) (save-excursion ;;HACK: nothing if one click (but a second is perhaps coming) (if (and (eq (holes-track-mouse-clicks) 1) (not mark-active)) () (if (not mark-active) (error "Nothing to put in hole") (holes-replace-update-active-hole (current-kill 0)) (message "hole replaced"))))) (defun holes-destroy-hole (&optional span) "Destroy the hole SPAN." (interactive) (let* ((sp (or span (holes-hole-at (point)) (error "No hole to destroy")))) (save-excursion (if (and (holes-active-hole-exist-p) (eq sp holes-active-hole)) (holes-disable-active-hole)) (holes-replace "" sp) (span-detach sp)) (message "hole killed"))) (defsubst holes-hole-at-event (event) "Return the hole at EVENT." (span-at-event event 'hole)) (defun holes-mouse-destroy-hole (event) "Destroy the hole at EVENT." (interactive "*e") (holes-destroy-hole (holes-hole-at-event event))) ;;;(span-at-event EVENT &optional PROPERTY BEFORE AT-FLAG) ;;comprend pas?? (defun holes-mouse-forget-hole (event) "Delete and deactivate the hole at EVENT." (interactive "*e") (save-excursion (let ((ext (holes-hole-at-event event))) (if (eq ext holes-active-hole) (holes-disable-active-hole)) (span-detach ext))) (message "hole deleted")) (defun holes-mouse-set-make-active-hole (event) "Make a new hole at EVENT click activate it." (interactive "*e") (holes-track-mouse-selection event) (if (and (eq (holes-track-mouse-clicks) 1) (not mark-active)) (holes-set-make-active-hole (point) (point)) (if mark-active (holes-set-make-active-hole) (let ((ext (holes-hole-at-event event))) (if (and ext (holes-is-hole-p ext)) (error "Already a hole here") (holes-set-active-hole (holes-make-hole-at))))))) (defun holes-mouse-set-active-hole (event) "Make the hole at EVENT click active." (interactive "*e") (let ((ext (holes-hole-at-event event))) (if (and ext (holes-is-hole-p ext)) (holes-set-active-hole ext) (error "No hole here")))) (defun holes-set-point-next-hole-destroy () "Moves the point to current active hole (if any and if in current buffer). Destroy it and makes the next hole active if any." (interactive) (assert (holes-active-hole-exist-p) nil "no active hole") (assert (eq (current-buffer) (holes-active-hole-buffer)) nil "active hole not in this buffer") (holes-goto-active-hole) (holes-delete-update-active-hole)) ;; utilities to be used in conjunction with abbrevs. ;; The idea is to put abbrevs of the form: ;;(define-abbrev-table 'tuareg-mode-abbrev-table ;; '( ;; ("l" "let # = # in" replace-#-after-abbrev2 0) ;; ) ;; ) ;; where replace-#-after-abbrev2 should be a function which replace the ;; two #'s (two occurences going backward from abbrev expantion point) ;; by holes and leave point at the first # (deleting ;; it). holes-set-point-next-hole-destroy allow to go to the next hole. ;;following function allow to replace occurrences of a string by a ;;hole. (defun holes-replace-string-by-holes-backward (limit) "Change each occurrence of REGEXP into a hole. Sets the active hole to the last created hole and unsets it if no hole is created. Return the number of holes created." (holes-disable-active-hole) (let ((n 0)) (save-excursion (while (re-search-backward holes-empty-hole-regexp limit t) (incf n) (if (not (match-end 1)) (holes-make-hole (match-beginning 0) (match-end 0)) (holes-make-hole (match-beginning 1) (match-end 1)) ;; delete end first to avoid shifting of marks (delete-region (match-end 1) (match-end 0)) (delete-region (match-beginning 0) (match-beginning 1))) (holes-set-active-hole-next))) n)) (defun holes-skeleton-end-hook () "Default hook after a skeleton insertion: put holes at each interesting position." ;; Not all versions of skeleton provide `skeleton-positions' and the ;; corresponding @ operation :-( (unless (boundp 'mmm-inside-insert-by-key) ; pc: this hack is ok for me (when (boundp 'skeleton-positions) (dolist (pos skeleton-positions) ;; put holes here (holes-set-make-active-hole pos pos))))) (defconst holes-jump-doc (concat "Hit \\[holes-set-point-next-hole-destroy] to jump " "to active hole. C-h v holes-doc to see holes doc.") "Shortcut reminder string for jumping to active hole.") (defun holes-replace-string-by-holes-backward-jump (pos &optional noindent) "Put holes between POS and point, backward, indenting. \"#\" and \"@{..}\" between this positions will become holes." (unless noindent (save-excursion (indent-region pos (point) nil))) (let ((n (holes-replace-string-by-holes-backward pos))) (case n (0 nil) ; no hole, stay here. (1 (goto-char pos) (holes-set-point-next-hole-destroy)) ; if only one hole, go to it. (t (goto-char pos) (unless (active-minibuffer-window) ; otherwise minibuffer gets hidden (message (substitute-command-keys "\\[holes-set-point-next-hole-destroy] to jump to active hole. \\[holes-short-doc] to see holes doc."))))))) ;;;###autoload (define-minor-mode holes-mode "Toggle Holes minor mode. With arg, turn Outline minor mode on if arg is positive, off otherwise. The mode `holes-mode' is meant to help program editing. It is useful to build complicated expressions by copy pasting several peices of text from different parts of a buffer (or even from different buffers). HOLES A hole is a piece of (highlighted) text that may be replaced by another part of text later. There is no information stored on the file for holes, so you can save and modify files containing holes with no harm... You can even insert or delete characters inside holes like any other characters. USE At any time only one particular hole, called \"active\", can be \"filled\". Holes can be in several buffers but there is always one or zero active hole globally. It is highlighted with a different color. Functions described below have default shortcuts when `holes-mode' is on that you can customize. TO DEFINE A HOLE, two methods: o Select a region with keyboard or mouse, then use \\[holes-set-make-active-hole]. If the selected region is empty, then a hole containing # is created at point. o Select text with mouse while pressing ctrl and meta (`C-M-select'). If the selected region is empty (i.e. if you just click while pressing ctrl+meta), then a hole containing # is created. TO ACTIVATE A HOLE, click on it with the button 1 of your mouse. The previous active hole will be deactivated. TO FORGET A HOLE without deleting its text, click on it with the button 2 (middle) of your mouse. TO DESTROY A HOLE and delete its text, click on it with the button 3 of your mouse. TO FILL A HOLE with a text selection, first make sure it is active, then two methods: o Select text with keyboard or mouse and hit \\[holes-replace-update-active-hole] o Select text with mouse while pressing ctrl, meta and shift (`C-M-S-select'). This is a generalization of the `mouse-track-insert' feature of XEmacs. This method allows you to fill different holes faster than with the usual copy-paste method. After replacement the next hole is automatically made active so you can fill it immediately by hitting again \\[holes-replace-update-active-hole] or `C-M-S-select'. TO JUMP TO THE ACTIVE HOLE, just hit \\[holes-set-point-next-hole-destroy]. You must be in the buffer containing the active hole. the point will move to the active hole, and the active hole will be destroyed so you can type something to put at its place. The following hole is automatically made active, so you can hit \\[holes-set-point-next-hole-destroy] again. It is useful in combination with abbreviations. For example in `coq-mode' \"fix\" is an abbreviation for Fixpoint # (# : #) {struct #} : # := #, where each # is a hole. Then hitting \\[holes-set-point-next-hole-destroy] goes from one hole to the following and you can fill-in each hole very quickly. COMBINING HOLES AND SKELETONS `holes' minor mode is made to work with minor mode `skeleton' minor mode. KNOWN BUGS o Don't try to make overlapping holes, it doesn't work. (what would it mean anyway?) o Cutting or pasting a hole will not produce new holes, and undoing on holes cannot make holes re-appear." nil " Holes" holes-mode-map :group 'holes (if holes-mode (add-hook 'skeleton-end-hook 'holes-skeleton-end-hook nil t) (remove-hook 'skeleton-end-hook 'holes-skeleton-end-hook t) (holes-clear-all-buffer-holes))) ;;;###autoload (defun holes-abbrev-complete () "Complete abbrev by putting holes and indenting. Moves point at beginning of expanded text. Put this function as call-back for your abbrevs, and just expanded \"#\" and \"@{..}\" will become holes." (if holes-mode (holes-replace-string-by-holes-backward-jump last-abbrev-location))) ;;;###autoload (defun holes-insert-and-expand (s) "Insert S, expand it and replace #s and @{]s by holes." ;; insert the expansion of abbrev s, and replace #s by holes. It was ;; possible to implement it with a simple ((insert s) (expand-abbrev)) ;; but undo would show the 2 steps, which is bad. (let ((pos (point)) (ins (abbrev-expansion s))) (insert (or ins s)) (setq last-abbrev-location pos) (holes-abbrev-complete))) (provide 'holes) ;;; holes.el ends here proofgeneral-4.3~pre130510/lib/local-vars-list.el000066400000000000000000000122221214562307500215320ustar00rootroot00000000000000;;; local-vars.el --- local variables list utilities ;; ;; Copyright (C) 2006 Pierre Courtieu ;; Authors: Pierre Courtieu ;; Maintainer: Pierre Courtieu ;; ;; $Id: local-vars-list.el,v 12.1 2012/07/11 09:08:13 pier Exp $ ;; This software is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public ;; License version 2, as published by the Free Software Foundation. ;; ;; This software 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 version 2 for more details ;; (enclosed in the file GPL). ;;; Commentary: ;; See documentation in variable local-var-list-doc ;;; History: ;; ;;; Help: (defconst local-vars-list-doc nil "From Emacs Info: A file can contain a \"local variables list\", which specifies the values to use for certain Emacs variables when that file is edited. See info node \"(emacs)File Variables\". local-vars-list provides two useful functions: \\[local-vars-list-get] that reads a local variable value at the end of the file. \\[local-vars-list-set] that writes a local variable value at the end of the file.") (defun local-vars-list-find () "Find the local variable definition paragraph. Return a list containing the prefix and the suffix of its first line, or throw 'notfound if not found. Sets the point at the beginning of the second line of the paragraph." (goto-char (point-max)) (catch 'notfound (if (not (re-search-backward "Local Variables:" nil t)) (throw 'notfound nil)) (let ((bol (save-excursion (beginning-of-line) (point))) (eol (save-excursion (end-of-line) (point))) (lpattern) (rpattern)) (setq lpattern (buffer-substring bol (point))) (re-search-forward "Local Variables:" eol t) (setq rpattern (buffer-substring (point) eol)) (forward-line 1) (beginning-of-line) (cons lpattern (cons rpattern nil))))) (defun local-vars-list-goto-var (symb lpat rpat) "Search a line defining local variable symb at current line and below. If successful set point to the beginning of the *value* and return t. Otherwise set point to the beginning of the last line of the local variables list (the one containing \"End:\"), and return nil. lpat and rpat are the suffix and prefix of the local variable list. Note: this function must be called when at the beginning of a local variable definition (or at the \"End:\" line)." (let* ((symbname (symbol-name symb)) (found nil) (endreached nil) (eol)) (while (and (not found) (not endreached)) (setq eol (save-excursion (end-of-line) (point))) (search-forward lpat eol) (re-search-forward "\\([^ :]+\\):" eol) (let ((varname (match-string 1))) (cond ((string-equal varname "End") (setq endreached t) (beginning-of-line)) ((string-equal varname symbname) (setq found t)) (t (forward-line 1) (beginning-of-line))))) (if found t nil))) ; precond: really be on a var def line (defun local-vars-list-get-current (lpat rpat) "Return the value written in the local variable list at current line. lpat and rpat are the suffix and prefix of the local variable list. Note: this function must be called when at the beginning of a local variable definition (or at the \"End:\" line)." (let ((bol (save-excursion (beginning-of-line) (point))) (eol (save-excursion (end-of-line) (point))) (varname "")) (catch 'notfound (if (not (search-forward lpat eol t)) (throw 'notfound nil)) (if (not (re-search-forward "\\([^ :]+\\):" eol t)) (throw 'notfound nil)) (setq varname (match-string 1)) (let ((boexp (point))) (if (not (search-forward rpat eol t)) (throw 'notfound nil)) (search-backward rpat bol) ; should always succeed (read (buffer-substring boexp (point))))))) ; TODO: catch errors here? (defun local-vars-list-get (symb) "Return the value written in the local variable list for variable symb. Raises an error if symb is not in the list. Note: Using `file-local-variables-alist' is not comfortable here since editing by hand the file variable zone does not modify this alist. Proceed by looking in the file instead." (save-excursion (let* ((lrpat (local-vars-list-find)) (dummy (if lrpat t (error "local variables zone not found. "))) (lpat (car lrpat)) (rpat (car (cdr lrpat))) ) (beginning-of-line) (if (local-vars-list-goto-var symb lpat rpat) t (error "variable %s not found" symb)) (beginning-of-line) (local-vars-list-get-current lpat rpat)))) (defun local-vars-list-get-safe (symb) "Return true if variable SYMB belongs to the local variable list of the current buffer." (condition-case nil (local-vars-list-get symb) (error nil))) (defun local-vars-list-set (symb val) "Write the value val in the local variable list for variable symb. If the variable is already specified in the list, replace the value. If no local variable list is found, create one at the end of the buffer first." (add-file-local-variable symb val)) (provide 'local-vars-list) ;;; Local Variables: *** ;;; fill-column: 85 *** ;;; indent-tabs-mode: nil *** ;;; End: *** proofgeneral-4.3~pre130510/lib/maths-menu.el000066400000000000000000000322441214562307500206020ustar00rootroot00000000000000;;; maths-menu.el --- insert maths characters from a menu -*-coding: iso-2022-7bit;-*- ;; Copyright (C) 2003, 2012 Free Software Foundation, Inc. ;; Author: Dave Love ;; Keywords: convenience ;; Version for Proof General modified by David Aspinall, 2007-8. ;; - Hooks added to insert tokenised versions of unicode characters. ;; - Added more characters to the menus. ;; - Define insertion functions following menu names (useful for keybindings) ;; $Id: maths-menu.el,v 12.1 2012/08/30 14:30:23 monnier Exp $ ;; 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. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; Defines a minor mode which defines a menu bar item allowing a wide ;; range of maths/technical characters (roughly the LaTeX repertoire) ;; to be inserted into the buffer by selecting menu items. ;; Menu display only works properly under X with Gtk menus and if the ;; menu uses a font with a suitable repertoire. (Lucid and Motif ;; toolkit menus can't display multilingual text. I don't know about ;; MS Windows menus.) It will work with tmm in tty mode iff the tty ;; displays Unicode. The tmm version (via F10) is also useful under a ;; window system when the menus don't display the characters ;; correctly, but where the symbols have word syntax, tmm won't ;; provide an ASCII selector for them, which can be a pain to use ;; without a mouse. ;; See also the TeX and sgml Quail input modes. These will probably ;; behave better if you can remember the input sequences. For ;; instance, this minor mode won't give you the ability to insert into ;; the minibuffer via the menu, though presumably it could be added to ;; the minibuffer menu. ;;; Code: (defvar maths-menu-filter-predicate (lambda (char) t) "Predicate function used to filter menu elements") (defvar maths-menu-tokenise-insert #'insert "Function used to insert possibly formatted or escaped character.") (defun maths-menu-build-menu (spec) (let ((map (make-sparse-keymap "Characters"))) (dolist (pane spec) (let* ((name (pop pane)) (pane-map (make-sparse-keymap name))) (define-key-after map (vector (intern name)) (cons name pane-map)) (dolist (elt pane) (let ((fname (intern (concat "maths-menu-insert-" (replace-regexp-in-string " " "-" (cadr elt)))))) (fset fname `(lambda () (interactive) (funcall maths-menu-tokenise-insert ,(car elt)))) (define-key-after pane-map (vector (intern (string (car elt)))) ; convenient unique symbol (list 'menu-item (format "%c (%s)" (car elt) (cadr elt)) fname :visible `(funcall maths-menu-filter-predicate ,(car elt)))))))) map)) (defvar maths-menu-menu (maths-menu-build-menu '(("Logic" (?$A!D(B "and") (?$A!E(B "or") (?$,1x (B "for all") (?$,1x#(B "there exists") (?$,1x$(B "there does not exist") (?$,1yd(B "down tack") (?$,1ye(B "up tack")) ("Binops 1" (?,A1(B "plus-minus sign") (?$,1x3(B "minus-or-plus sign") (?,AW(B "multiplication sign") (?,Aw(B "division sign") (?$,1x2(B "minus sign") (?$,1x7(B "asterisk operator") (?$,1z&(B "star operator") (?$,2"+(B "white circle") (?$,1s"(B "bullet") (?,A7(B "middle dot") (?$,1xI(B "intersection") (?$,1xJ(B "union") (?$,1yN(B "multiset union") (?$,1yS(B "square cap") (?$,1yT(B "square cup") (?$,1xH(B "logical or") (?$,1xG(B "logical and") (?$,1x6(B "set minus") (?$,1x`(B "wreath product")) ("Binops 2" (?$,1z$(B "diamond operator") (?$,2!s(B "white up-pointing triangle") (?$,2!}(B "white down-pointing triangle") (?$,2"#(B "white left-pointing small triangle") (?$,2!y(B "white right-pointing small triangle") (?$,2"!(B "white left-pointing triangle") (?$,2!w(B "white right-pointing triangle") (?$,1yU(B "circled plus") (?$,1yV(B "circled minus") (?$,1yW(B "circled times") (?$,1yX(B "circled division slash") (?$,1yY(B "circled dot operator") (?$,2"O(B "large circle") (?$,1s (B "dagger") (?$,1s!(B "double dagger") (?$,1yt(B "normal subgroup of or equal to") (?$,1yu(B "contains as normal subgroup or equal to")) ("Relations 1" (?$,1y$(B "less-than or equal to") (?$,1y:(B "precedes") (?$,1y*(B "much less-than") (?$,1yB(B "subset of") (?$,1yF(B "subset of or equal to") (?$,1yO(B "square image of") (?$,1yQ(B "square image of or equal to") (?$,1x((B "element of") (?$,1x)(B "not an element of") (?$,1yb(B "right tack") (?$,1y%(B "greater-than or equal to") (?$,1y;(B "succeeds") (?$,1y=(B "succeeds or equal to") (?$,1y+(B "much greater-than") (?$,1yC(B "superset of") (?$,1yG(B "superset of or equal to") (?$,1yP(B "square original of") (?$,1yR(B "square original of or equal to") (?$,1x+(B "contains as member") (?$,1y!(B "identical to") (?$,1y"(B "not identical to") ) ("Relations 2" (?$,1yc(B "left tack") (?$,1x\(B "tilde operator") (?$,1xc(B "asymptotically equal to") (?$,1xm(B "equivalent to") (?$,1xh(B "almost equal to") (?$,1xe(B "approximately equal to") (?$,1y (B "not equal to") (?$,1xp(B "approaches the limit") (?$,1x=(B "proportional to") (?$,1yg(B "models") (?$,1xC(B "divides") (?$,1xE(B "parallel to") (?$,1z((B "bowtie") (?$,1z((B "bowtie") (?$,1{#(B "smile") (?$,1{"(B "frown") (?$,1xy(B "estimates") (?$,1z_(B "z notation bag membership")) ("Arrows" (?$,1vp(B "leftwards arrow") (?$,1wP(B "leftwards double arrow") (?$,1vr(B "rightwards arrow") (?$,1wR(B "rightwards double arrow") (?$,1vt(B "left right arrow") (?$,1wT(B "left right double arrow") (?$,1w&(B "rightwards arrow from bar") (?$,1w)(B "leftwards arrow with hook") (?$,1w<(B "leftwards harpoon with barb upwards") (?$,1w=(B "leftwards harpoon with barb downwards") (?$,1wL(B "rightwards harpoon over leftwards harpoon") (?$,1w&(B "rightwards arrow from bar") (?$,1w*(B "rightwards arrow with hook") (?$,1w@(B "rightwards harpoon with barb upwards") (?$,1wA(B "rightwards harpoon with barb downwards") (?$,1v}(B "rightwards wave arrow") (?$,1vq(B "upwards arrow") (?$,1wQ(B "upwards double arrow") (?$,1vs(B "downwards arrow") (?$,1wS(B "downwards double arrow") (?$,1vu(B "up down arrow") (?$,1vw(B "north east arrow") (?$,1vx(B "south east arrow") (?$,1vy(B "south west arrow") (?$,1vv(B "north west arrow") (?$,1w[(B "rightwards triple arrow")) ("Long arrows" (?$,2'v(B "long rightwards arrow") (?$,2'w(B "long left right arrow") (?$,2'x(B "long left double arrow") (?$,2'y(B "long right double arrow") (?$,2'z(B "long left right double arrow") (?$,2'{(B "long left arrow from bar") (?$,2'|(B "long right arrow from bar") (?$,2'}(B "long left double arrow bar") (?$,2'~(B "long right double arrow from bar") (?$,2'(B "long rightwards squiggle arrow")) ("Symbols 1" (?$,1uu(B "alef symbol") ; don't use letter alef (avoid bidi confusion) (?$,1uO(B "planck constant over two pi") (?$,1 Q(B "latin small letter dotless i") (?$,1uS(B "script small l") (?$,1uX(B "script capital p") (?$,1u\(B "black-letter capital r") (?$,1uQ(B "black-letter capital i") (?$,1ug(B "inverted ohm sign") (?$,1s2(B "prime") (?$,1x%(B "empty set") (?$,1x'(B "nabla") (?$,1x:(B "square root") (?$,1x;(B "cube root") (?$,1x@(B "angle") (?,A,(B "not sign") (?$,2#o(B "music sharp sign") (?$,1x"(B "partial differential") (?$,1x>(B "infinity") ) ("Symbols 2" (?$,2!a(B "white square") (?$,2"'(B "white diamond") (?$,2!u(B "white up-pointing small triangle") (?$,1x1(B "n-ary summation") (?$,1x/(B "n-ary product") (?$,1x0(B "n-ary coproduct") (?$,1xK(B "integral") (?$,1xN(B "contour integral") (?$,1z"(B "n-ary intersection") (?$,1z#(B "n-ary union") (?$,1z!(B "n-ary logical or") (?$,1z (B "n-ary logical and") (?$,1uU(B "double-struck capital n") (?$,1uY(B "double-struck capital p") (?$,1uZ(B "double-struck capital q") (?$,1u](B "double-struck capital r") (?$,1ud(B "double-struck capital z") (?$,1uP(B "script capital i") (?$,1![(B "latin small letter lambda with stroke") (?$,1xT(B "therefore") (?$,1s&(B "horizontal ellipsis") (?$,1zO(B "midline horizontal ellipsis") (?$,1zN(B "vertical ellipsis") (?$,1zQ(B "down right diagonal ellipsis") (?$,1zP(B "up right diagonal ellipsis") (?$,2,!(B "z notation spot") (?$,2,"(B "z notation type colon")) ("Delimiters" (?\$,1zj(B "left floor") (?\$,1zh(B "left ceiling") (?\$,1{)(B "left-pointing angle bracket") (?\$,1zk(B "right floor") (?\$,1zi(B "right ceiling") (?\$,1{*(B "right-pointing angle bracket") (?\$,2=Z(B "left white square bracket") (?\$,2=[(B "right white square bracket") (?\$,2=J(B "left double angle bracket") (?\$,2=K(B "right double angle bracket") (?\$,2,'(B "z notation left image bracket") (?\$,2,((B "z notation right image bracket") (?\$,2,)(B "z notation left binding bracket") (?\$,2,*(B "z notation right binding bracket")) ("Greek LC" (?$,1'1(B "alpha") (?$,1'2(B "beta") (?$,1'3(B "gamma") (?$,1'4(B "delta") (?$,1'5(B "epsilon") (?$,1'6(B "zeta") (?$,1'7(B "eta") (?$,1'8(B "theta") (?$,1'Q(B "theta symbol") (?$,1'9(B "iota") (?$,1':(B "kappa") (?$,1';(B "lamda") (?$,1'<(B "mu") (?$,1'=(B "nu") (?$,1'>(B "xi") (?$,1'@(B "pi") (?$,1'V(B "pi symbol") (?$,1'A(B "rho") (?$,1'q(B "rho symbol") (?$,1'C(B "sigma") (?$,1'B(B "final sigma") (?$,1'D(B "tau") (?$,1'E(B "upsilon") (?$,1'F(B "phi") (?$,1'U(B "phi symbol") (?$,1'G(B "chi") (?$,1'H(B "psi") (?$,1'I(B "omega")) ("Greek UC" (?$,1&s(B "Gamma") (?$,1&t(B "Delta") (?$,1&x(B "Theta") (?$,1&{(B "Lamda") (?$,1&~(B "Xi") (?$,1' (B "Pi") (?$,1'#(B "Sigma") (?$,1'%(B "Upsilon") (?$,1'&(B "Phi") (?$,1'((B "Psi") (?$,1')(B "Omega")) ("Sub/super" (?$,1s}(B "superscript left parenthesis") (?$,1s~(B "superscript right parenthesis") (?$,1sz(B "superscript plus sign") (?$,1s{(B "superscript minus") (?$,1sp(B "superscript zero") (?,A9(B "superscript one") (?,A2(B "superscript two") (?,A3(B "superscript three") (?$,1st(B "superscript four") (?$,1su(B "superscript five") (?$,1sv(B "superscript six") (?$,1sw(B "superscript seven") (?$,1sx(B "superscript eight") (?$,1sy(B "superscript nine") (?$,1t-(B "subscript left parenthesis") (?$,1t.(B "subscript right parenthesis") (?$,1t*(B "subscript plus sign") (?$,1t+(B "subscript minus") (?$,1t (B "subscript zero") (?$,1t!(B "subscript one") (?$,1t"(B "subscript two") (?$,1t#(B "subscript three") (?$,1t$(B "subscript four") (?$,1t%(B "subscript five") (?$,1t&(B "subscript six") (?$,1t'(B "subscript seven") (?$,1t((B "subscript eight") (?$,1t)(B "subscript nine"))))) (defvar maths-menu-mode-map (let ((map (make-sparse-keymap))) (define-key map [menu-bar maths] `(menu-item "Maths" ,maths-menu-menu :help "Menu of maths characters to insert")) map)) ;;;###autoload (define-minor-mode maths-menu-mode "Install a menu for entering mathematical characters. Uses window system menus only when they can display multilingual text. Otherwise the menu-bar item activates the text-mode menu system. This mode is only useful with a font which can display the maths repertoire." nil nil maths-menu-mode-map) (provide 'maths-menu) ;;; maths-menu.el ends here proofgeneral-4.3~pre130510/lib/pg-dev.el000066400000000000000000000123471214562307500177100ustar00rootroot00000000000000;;; pg-dev.el --- Developer settings for Proof General ;; ;; Copyright (C) 2008-2011 LFCS Edinburgh. ;; Author: David Aspinall and others ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-dev.el,v 12.2 2012/08/30 14:30:23 monnier Exp $ ;; ;;; Commentary: ;; ;; Some configuration of Emacs Lisp mode for developing PG, not needed ;; for ordinary users. ;; ;;; Code: (require 'whitespace) (eval-when-compile (require 'cl)) (eval-when (compile) (require 'proof-site)) (with-no-warnings (setq proof-general-debug t)) ;; Use checkdoc, eldoc, Flyspell, whitespace, copyright update ;; and byte compilation on save: (add-hook 'emacs-lisp-mode-hook (lambda () (checkdoc-minor-mode 1) (turn-on-eldoc-mode) (flyspell-prog-mode) (customize-set-variable 'whitespace-action '(cleanup)) (define-key emacs-lisp-mode-map [(control c)(control c)] 'emacs-lisp-byte-compile) (add-hook 'write-file-functions 'whitespace-write-file-hook nil t) (add-hook 'before-save-hook 'copyright-update nil t))) ;; Fill in template for new files (add-hook 'find-file-hook 'auto-insert) ;; Configure indentation for our macros (put 'proof-if-setting-configured 'lisp-indent-function 1) (put 'proof-eval-when-ready-for-assistant '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) (put 'proof-map-buffers 'lisp-indent-function 'defun) (put 'proof-with-current-buffer-if-exists 'lisp-indent-function 'defun) (defconst pg-dev-lisp-font-lock-keywords (list (concat "(\\(def" ;; also proof-def ;; Function like things: ;; Variable like things "\\(pgcustom\\|pacustom\\)\\)" ;; Any whitespace and declared object. "[ \t'\(]*" "\\(\\sw+\\)?") '(1 font-lock-keyword-face) '(3 (cond ((match-beginning 2) 'font-lock-variable-name-face) (t 'font-lock-function-name-face)) nil t))) ;; Not working, see font-lock.el for usual emacs lisp settings. ;;(add-hook 'emacs-lisp-mode-hook ;; (lambda () ;; (font-lock-add-keywords nil ;; 'pg-dev-lisp-font-lock-keywords))) ;; ;; Path set for a clean environment to byte-compile within Emacs ;; without loading. ;; (defun pg-loadpath () (interactive) (proof-add-to-load-path "../generic/") (proof-add-to-load-path "../lib/")) ;;; ;;; Unload utility (not wholly successful) ;;; (defun unload-pg () "Attempt to unload Proof General (for development use only)." (interactive) (mapcar (lambda (feat) (condition-case nil (unload-feature feat 'force) (error nil))) '(proof-splash pg-assoc pg-xml proof-depends proof-indent proof-site proof-shell proof-menu pg-pbrpm pg-pgip proof-script proof-autoloads pg-response pg-goals proof-toolbar proof-easy-config proof-config proof-mmm proof proof-utils proof-syntax pg-user pg-custom proof-maths-menu proof-unicode-tokens pg-thymodes pg-autotest ;; isar-syntax isar-find-theorems isar-unicode-tokens isar-autotest interface-setup isabelle-system isar isar-mmm isar-keywords ;; coq-abbrev coq-db coq-unicode-tokens coq-local-vars coq coq-syntax coq-indent coq-autotest))) ;; ;; Proling interesting packages ;; (require 'elp) ;;;###autoload (defun profile-pg () "Configure Proof General for profiling. Use M-x elp-results to see results." (interactive) (elp-instrument-package "proof-") (elp-instrument-package "pg-") (elp-instrument-package "scomint") (elp-instrument-package "unicode-tokens") (elp-instrument-package "coq") (elp-instrument-package "isar") (elp-instrument-package "span") (elp-instrument-package "replace-") ; for replace-regexp etc (elp-instrument-package "re-search-") ; for re-search-forwad etc (elp-instrument-package "skip-chars-") ; for skip chars etc (elp-instrument-list '(string-match match-string re-search-forward re-search-backward skip-chars-forward skip-chars-backward goto-char insert set-marker marker-position nreverse nconc mapc member redisplay sit-for overlay-put overlay-start overlay-end make-overlay buffer-live-p kill-buffer process-status get-buffer-process delete-overlay move-overlay accept-process-output)) (elp-instrument-package "font-lock")) ;; improve readability of profile results, give milliseconds (defun elp-pack-number (number width) (format (concat "%" (number-to-string (- width 3)) ".2f") (* 100 (string-to-number number)))) ;; ;; Make references to bugs clickable; [e.g., trac #1] ;; (defun pg-bug-references () (interactive) (if (fboundp 'bug-reference-mode) (with-no-warnings (bug-reference-mode 1) (setq bug-reference-bug-regexp "\\(?:[Tt]rac ?#\\)\\([0-9]+\\)" bug-reference-url-format "http://proofgeneral.inf.ed.ac.uk/trac/ticket/%s")))) (add-hook 'emacs-lisp-mode-hook 'pg-bug-references) (add-hook 'isar-mode-hook 'pg-bug-references) (add-hook 'coq-mode-hook 'pg-bug-references) (add-hook 'emacs-lisp-mode-hook 'goto-address-mode) (provide 'pg-dev) ;;; pg-dev.el ends here proofgeneral-4.3~pre130510/lib/pg-fontsets.el000066400000000000000000000041341214562307500207720ustar00rootroot00000000000000;;; pg-fontsets.el --- Define fontsets useful for Proof General ;; ;; Copyright (C) 2008 David Aspinall / LFCS Edinburgh ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: pg-fontsets.el,v 12.1 2012/03/01 15:49:43 tews Exp $ ;; ;;; Commentary: ;; ;; Define some fontsets to try to select fonts that display many symbols. ;; ;; Select one of these fontsets via the menu Options -> Set Font/Fontset ;; or, with M-x set-default-font ;; ;; Recommended & free fonts to install on your system are: ;; ;; DejaVu LGC (Sans and Sans Mono). See http://dejavu.sourceforge.net ;; Liberation (Sans and Mono). See https://fedorahosted.org/liberation-fonts/ ;; ;;; Code: (eval-and-compile (require 'fontset)) ; needed for some emacsen without X (defcustom pg-fontsets-default-fontset nil "*Name of default fontset to use with Proof General." :type 'string :group 'proof-user-options) (defvar pg-fontsets-names nil "*List of fontsets to use with Proof General.") (defun pg-fontsets-make-fontsetsizes (basefont) (dolist (size '(10 12 14 18 22)) (add-to-list 'pg-fontsets-names (create-fontset-from-fontset-spec (replace-regexp-in-string "%T" (car (split-string basefont)) (replace-regexp-in-string "%S" (int-to-string size) (replace-regexp-in-string "%F" basefont "-*-%F-*-*-*--%S-*-*-*-*-*-fontset-PG%T, gnu-unifont:-*-%F-*-*-*--%S-*-*-*-*-*-iso10646-1" ;ascii:-*-%F-medium-r-normal--%S-*-*-*-*-*-mac-roman, ;latin-iso8859-1:-*-%F-medium-r-normal--%S-*-*-*-*-*-mac-roman, ;mule-unicode-0100-24ff:-*-%F-medium-r-normal--%S--*-*-*-*-*-iso10646-1, ;mule-unicode-2500-33ff:-*-%F-medium-r-normal--%S--*-*-*-*-*-iso10646-1, ;mule-unicode-e000-ffff:-*-%F-medium-r-normal--%S--*-*-*-*-*-iso10646-1" ))))))) (defconst pg-fontsets-base-fonts '("dejavu lgc sans mono" "liberation mono" "stixregular" "lucidasanstypewriter")) (defun pg-fontsets-make-fontsets () (setq pg-fontsets-names nil) (mapcar 'pg-fontsets-make-fontsetsizes pg-fontsets-base-fonts)) (pg-fontsets-make-fontsets) (provide 'pg-fontsets) ;;; pg-fontsets.el ends here proofgeneral-4.3~pre130510/lib/proof-compat.el000066400000000000000000000102461214562307500211300ustar00rootroot00000000000000;; proof-compat.el Operating system and Emacs version compatibility ;; ;; Copyright (C) 2000-2010 LFCS Edinburgh. ;; Author: David Aspinall and others ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: proof-compat.el,v 12.1 2012/09/02 21:55:42 da Exp $ ;; ;; 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 (since v3.7) is for the ;; main codebase to be written for the latest stable version of ;; GNU Emacs, following GNU Emacs advice on obsolete function calls. ;; ;; Since Proof General 4.0, XEmacs is not supported at all. ;; (eval-when-compile (require 'easymenu)) (require 'cl) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Architecture flags ;;; ;; can use eval-and-compile to allow optimisation, but that would ;; require recompilation for Windows (defvar proof-running-on-win32 (memq system-type '(win32 windows-nt cygwin)) "Non-nil if Proof General is running on a windows variant system.") ;; Workaround a small bug in Carbon Emacs Winter 2008 (at least) ;; Menu presses query this variable, but it's not bound unless ;; mode engaged. Not noticeable in normal use, but it is as soon ;; as debug-on-error is engaged. (with-no-warnings (if (and (boundp 'carbon-emacs-package-version) (not (boundp 'mac-key-mode))) (setq mac-key-mode nil))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Modifications and adjustments ;;; ;; Remove a custom setting. Needed to support dynamic reconfiguration. ;; (We'd prefer that repeated defcustom calls acted like repeated ;; "defvar treated as defconst" in XEmacs) (defun pg-custom-undeclare-variable (symbol) "Remove a custom setting SYMBOL. Done by removing all properties mentioned by custom library. The symbol itself is left defined, in case it has been changed in the current Emacs session." (mapc (lambda (prop) (remprop symbol prop)) '(default standard-value force-value variable-comment saved-variable-comment variable-documentation group-documentation custom-set custom-get custom-options custom-requests custom-group custom-prefix custom-tag custom-links custom-version saved-value theme-value theme-face))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; GNU Emacs compatibility with XEmacs ;;; (unless (fboundp 'save-selected-frame) (defmacro save-selected-frame (&rest body) "Execute forms in BODY, then restore the selected frame. The value returned is the value of the last form in BODY." (let ((old-frame (gensym "ssf"))) `(let ((,old-frame (selected-frame))) (unwind-protect (progn ,@body) (select-frame ,old-frame)))))) ;; These functions are used in the intricate logic around ;; shrink-to-fit. ;; window-leftmost-p, window-rightmost-p: my implementations (or (fboundp 'window-leftmost-p) (defun window-leftmost-p (window) (zerop (car (window-edges window))))) (or (fboundp 'window-rightmost-p) (defun window-rightmost-p (window) (>= (nth 2 (window-edges window)) (frame-width (window-frame window))))) (or (fboundp 'window-bottom-p) (defun window-bottom-p (window) (>= (nth 3 (window-edges window)) (frame-height (window-frame window))))) ;; find-coding-system emulation for GNU Emacs (unless (fboundp 'find-coding-system) (defun find-coding-system (name) "Retrieve the coding system of the given name, or nil if non-such." (condition-case nil (check-coding-system name) (error nil)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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))))) ;; End of proof-compat.el (provide 'proof-compat) proofgeneral-4.3~pre130510/lib/scomint.el000066400000000000000000000262311214562307500201770ustar00rootroot00000000000000;;; scomint.el --- Simplified comint for less interactive shells ;; ;; Copyright (C) 2009 LFCS Edinburgh. ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: scomint.el,v 12.1 2011/10/13 14:35:09 da Exp $ ;;; Commentary: ;; ;; This is a heavily simplified comint for Proof General. ;; Much of the code is taken from comint.el. ;; ;; The reason to provide this is to remove some of ;; the interactive features which are otherwise ;; hard to disentangle. ;; (defvar scomint-buffer-maximum-size 800000 "The maximum size in characters for SComint buffers. SComint buffers are truncated from the top to be no greater than this number, if non-nil.") (defvar scomint-output-filter-functions nil "Functions to call after output is inserted into the buffer.") (defvar scomint-mode-map (let ((map (make-sparse-keymap))) (define-key map "\C-m" 'scomint-send-input) (define-key map "\C-c\C-c" 'scomint-interrupt-process) map)) (defvar scomint-last-input-start nil) (defvar scomint-last-input-end nil) (defvar scomint-last-output-start nil) (defvar scomint-exec-hook nil "Hook run each time a process is exec'd by `scomint-exec'. This is called after the process is cranked up. It is useful for things that must be done each time a process is executed in a Comint mode buffer.") (put 'scomint-output-filter-functions 'permanent-local t) (put 'scomint-mode 'mode-class 'special) (define-derived-mode scomint-mode fundamental-mode "SComint" "Major mode for interacting with a background inferior interpreter. Interpreter name is same as buffer name, sans the asterisks. Return at end of buffer sends line as input. Return not at end copies rest of line to end and sends it. \\{scomint-mode-map} Entry to this mode runs the hooks on `scomint-mode-hook'." (setq mode-line-process '(":%s")) (set (make-local-variable 'scomint-last-input-start) (point-min-marker)) (set (make-local-variable 'scomint-last-input-end) (point-min-marker)) (set (make-local-variable 'scomint-last-output-start) (make-marker)) (set (make-local-variable 'window-point-insertion-type) t) ; Emacs 23-ism? (make-local-variable 'font-lock-defaults) (setq font-lock-defaults '(nil t)) (add-hook 'change-major-mode-hook 'font-lock-defontify nil t) (set (make-local-variable 'next-line-add-newlines) nil)) (defsubst scomint-check-proc (buffer) "Return non-nil if there is a living process associated w/buffer BUFFER. Living means the status is `open', `run', or `stop'. BUFFER can be either a buffer or the name of one." (let ((proc (get-buffer-process buffer))) (and proc (memq (process-status proc) '(open run stop))))) ;;;###autoload (defun scomint-make-in-buffer (name buffer program &optional startfile &rest switches) "Make a Comint process NAME in BUFFER, running PROGRAM. If BUFFER is nil, it defaults to NAME surrounded by `*'s. PROGRAM should be either a string denoting an executable program to create via `start-file-process', or a cons pair of the form (HOST . SERVICE) denoting a TCP connection to be opened via `open-network-stream'. If there is already a running process in that buffer, it is not restarted. Optional fourth arg STARTFILE is the name of a file to send the contents of to the process. If PROGRAM is a string, any more args are arguments to PROGRAM." (unless (or (fboundp 'start-process) (fboundp 'start-file-process)) (error "Multi-processing is not supported for this system")) (setq buffer (get-buffer-create (or buffer (concat "*" name "*")))) ;; If no process, or nuked process, crank up a new one and put buffer in ;; comint mode. Otherwise, leave buffer and existing process alone. (unless (scomint-check-proc buffer) (with-current-buffer buffer (unless (derived-mode-p 'scomint-mode) (scomint-mode))) ; Install local vars, mode, keymap, ... (scomint-exec buffer name program startfile switches)) buffer) ;;;###autoload (defun scomint-make (name program &optional startfile &rest switches) "Make a Comint process NAME in a buffer, running PROGRAM. The name of the buffer is made by surrounding NAME with `*'s. PROGRAM should be either a string denoting an executable program to create via `start-file-process', or a cons pair of the form (HOST . SERVICE) denoting a TCP connection to be opened via `open-network-stream'. If there is already a running process in that buffer, it is not restarted. Optional third arg STARTFILE is the name of a file to send the contents of the process to. If PROGRAM is a string, any more args are arguments to PROGRAM." (apply #'scomint-make-in-buffer name nil program startfile switches)) (defun scomint-exec (buffer name command startfile switches) "Start up a process named NAME in buffer BUFFER for Comint modes. Runs the given COMMAND with SWITCHES with output to STARTFILE. Blasts any old process running in the buffer. Doesn't set the buffer mode. You can use this to cheaply run a series of processes in the same Comint buffer. The hook `scomint-exec-hook' is run after each exec." (with-current-buffer buffer (let ((proc (get-buffer-process buffer))) ; Blast any old process. (if proc (delete-process proc))) ;; Crank up a new process (let ((proc (if (consp command) (open-network-stream name buffer (car command) (cdr command)) (scomint-exec-1 name buffer command switches)))) (set-process-filter proc 'scomint-output-filter) ;; Jump to the end, and set the process mark. (goto-char (point-max)) (set-marker (process-mark proc) (point)) ;; Feed it the startfile. (cond (startfile ;;This is guaranteed to wait long enough ;;but has bad results if the comint does not prompt at all ;; (while (= size (buffer-size)) ;; (sleep-for 1)) ;;I hope 1 second is enough! (sleep-for 1) (goto-char (point-max)) (insert-file-contents startfile) (setq startfile (buffer-substring (point) (point-max))) (delete-region (point) (point-max)) (scomint-send-string proc startfile))) (run-hooks 'scomint-exec-hook) buffer))) ;; This auxiliary function cranks up the process for comint-exec in ;; the appropriate environment. (defun scomint-exec-1 (name buffer command switches) (let ((process-environment (nconc ;; If using termcap, we specify `emacs' as the terminal type ;; because that lets us specify a width. ;; If using terminfo, we specify `dumb' because that is ;; a defined terminal type. `emacs' is not a defined terminal type ;; and there is no way for us to define it here. ;; Some programs that use terminfo get very confused ;; if TERM is not a valid terminal type. ;; ;; There is similar code in compile.el. (if (and (boundp 'system-uses-terminfo) system-uses-terminfo) (list "TERM=dumb" "TERMCAP=" (format "COLUMNS=%d" (window-width))) (list "TERM=emacs" (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width)))) (unless (getenv "EMACS") (list "EMACS=t")) (list (format "INSIDE_EMACS=%s,comint" emacs-version)) process-environment)) (default-directory (if (file-accessible-directory-p default-directory) default-directory "/")) proc decoding encoding changed) (let ((exec-path (if (file-name-directory command) ;; If the command has slashes, make sure we ;; first look relative to the current directory. (cons default-directory exec-path) exec-path))) (setq proc (apply (if (fboundp 'start-file-process) ;; da: start-file-process is Emacs23 only 'start-file-process 'start-process) name buffer command switches))) ;; Some file name handler cannot start a process, fe ange-ftp. (unless (processp proc) (error "No process started")) (let ((coding-systems (process-coding-system proc))) (setq decoding (car coding-systems) encoding (cdr coding-systems))) ;; Even if start-file-process left the coding system for encoding data ;; sent from the process undecided, we had better use the same one ;; as what we use for decoding. But, we should suppress EOL ;; conversion. (if (and decoding (not encoding)) (setq encoding (coding-system-change-eol-conversion decoding 'unix) changed t)) (if changed (set-process-coding-system proc decoding encoding)) proc)) (defalias 'scomint-send-string 'process-send-string) (defun scomint-send-eof () "Send an EOF to the current buffer's process." (interactive) (condition-case nil ;; this fails if process has died already (scomint-send-input t t) (error nil)) (process-send-eof)) (defun scomint-send-input (&optional no-newline artificial) "Send input to process. After the process output mark, sends all text from the process mark to point as input to the process. This command also sends and inserts a final newline, unless NO-NEWLINE is non-nil." (interactive) ;; Note that the input string does not include its terminal newline. (let ((proc (get-buffer-process (current-buffer)))) (let* ((pmark (process-mark proc)) (start (marker-position pmark))) (unless (< (point) start) ;; Update the markers before we send the input ;; in case we get output amidst sending the input. (set-marker scomint-last-input-start pmark) (unless no-newline (insert ?\n)) (set-marker scomint-last-input-end (point)) (set-marker (process-mark proc) (point)) (process-send-region proc start (point)))))) ;; TODO: run this on a timer rather than on every I/O (defun scomint-truncate-buffer (&optional string) "Truncate the buffer to `scomint-buffer-maximum-size'." (interactive) (if scomint-buffer-maximum-size (save-excursion (save-restriction (widen) (if (> (point-max) scomint-buffer-maximum-size) (let ((inhibit-read-only t)) (delete-region (point-min) (- (point-max) scomint-buffer-maximum-size)))))))) (defun scomint-strip-ctrl-m (&optional string) "Strip trailing `^M' characters from the current output group." (interactive) (let ((pmark (process-mark (get-buffer-process (current-buffer))))) (save-excursion (condition-case nil (goto-char (if (called-interactively-p 'any) scomint-last-input-end scomint-last-output-start)) (error nil)) (while (re-search-forward "\r+$" pmark t) (replace-match "" t t))))) ;; The purpose of using this filter for comint processes is to keep ;; comint-last-input-end from moving forward when output is inserted. (defun scomint-output-filter (process string) (let ((oprocbuf (process-buffer process))) ;; First check for killed buffer or no input. (when (and string (buffer-live-p oprocbuf)) (with-current-buffer oprocbuf ;; Insert STRING (let (;; The point should float after any insertion we do. (saved-point (copy-marker (point) t))) (goto-char (process-mark process)) (set-marker scomint-last-output-start (point)) (insert string) ;; Advance process-mark (set-marker (process-mark process) (point)) ;; Run these hooks with point where the user had it. (goto-char saved-point) (run-hook-with-args 'scomint-output-filter-functions string) ;; (scomint-truncate-buffer) (set-marker saved-point (point))))))) (defun scomint-interrupt-process () (interactive) (interrupt-process)) (provide 'scomint) ;;; scomint.el ends here proofgeneral-4.3~pre130510/lib/span.el000066400000000000000000000207341214562307500174660ustar00rootroot00000000000000;;; span.el --- Datatype of "spans" for Proof General ;; ;; Copyright (C) 1998-2009 LFCS Edinburgh ;; Author: Healfdene Goguen ;; Maintainer: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: span.el,v 12.0 2011/10/13 10:54:50 da Exp $ ;; ;;; Commentary: ;; ;; Spans are our abstraction of extents/overlays. Nowadays ;; we implement them directly with overlays. ;; ;; In future this module should be used to implement the abstraction ;; for script buffers (only) more directly. ;; ;;; Code: (eval-when-compile (require 'cl)) ;For lexical-let. (defalias 'span-start 'overlay-start) (defalias 'span-end 'overlay-end) (defalias 'span-set-property 'overlay-put) (defalias 'span-property 'overlay-get) (defalias 'span-make 'make-overlay) (defalias 'span-detach 'delete-overlay) (defalias 'span-set-endpoints 'move-overlay) (defalias 'span-buffer 'overlay-buffer) (defun span-read-only-hook (overlay after start end &optional len) (unless inhibit-read-only (error "Region is read-only"))) (add-to-list 'debug-ignored-errors "Region is read-only") (defsubst span-read-only (span) "Set SPAN to be read only." ;; Note: using the standard 'read-only property does not work. ;; (overlay-put span 'read-only t)) (span-set-property span 'modification-hooks '(span-read-only-hook)) (span-set-property span 'insert-in-front-hooks '(span-read-only-hook))) (defsubst span-read-write (span) "Set SPAN to be writeable." (span-set-property span 'modification-hooks nil) (span-set-property span 'insert-in-front-hooks nil)) (defsubst span-write-warning (span fun) "Give a warning message when SPAN is changed, unless `inhibit-read-only' is non-nil." (lexical-let ((fun fun)) (let ((funs (list (lambda (span afterp beg end &rest args) (if (and (not afterp) (not inhibit-read-only)) (funcall fun beg end)))))) (span-set-property span 'modification-hooks funs) (span-set-property span 'insert-in-front-hooks funs)))) ;; We use end first because proof-locked-queue is often changed, and ;; its starting point is always 1 (defsubst span-lt (s u) (or (< (span-end s) (span-end u)) (and (eq (span-end s) (span-end u)) (< (span-start s) (span-start u))))) (defsubst spans-at-point-prop (pt prop) (let (ols) (if (null prop) (overlays-at pt) (dolist (ol (overlays-at pt)) (if (overlay-get ol prop) (push ol ols))) ols))) (defsubst spans-at-region-prop (start end prop) "Return a list of the spans in START END with PROP." (let (ols) (if (null prop) (overlays-in start end) (dolist (ol (overlays-in start end)) (if (overlay-get ol prop) (push ol ols))) ols))) (defsubst span-at (pt prop) "Return some SPAN at point PT with property PROP." (car-safe (spans-at-point-prop pt prop))) (defsubst span-delete (span) "Run the 'span-delete-actions and delete SPAN." (mapc (lambda (predelfn) (funcall predelfn)) (span-property span 'span-delete-actions)) (delete-overlay span)) (defsubst span-add-delete-action (span action) "Add ACTION to the list of functions called when SPAN is deleted." (span-set-property span 'span-delete-actions (cons action (span-property span 'span-delete-actions)))) ;; The next two change ordering of list of spans: (defsubst span-mapcar-spans (fn start end prop) "Map function FN over spans between START and END with property PROP." (mapcar fn (spans-at-region-prop start end prop))) (defsubst span-mapc-spans (fn start end prop) "Apply function FN to spans between START and END with property PROP." (mapc fn (spans-at-region-prop start end prop))) (defsubst span-mapcar-spans-inorder (fn start end prop) "Map function FN over spans between START and END with property PROP." (mapcar fn (sort (spans-at-region-prop start end prop) 'span-lt))) (defun span-at-before (pt prop) "Return the smallest SPAN at before PT with property PROP. A span is before PT if it begins before the character before PT." (let ((ols (if (eq (point-min) pt) nil ;; (overlays-at pt) (overlays-in (1- pt) pt)))) ;; Check the PROP is set. (when prop (dolist (ol (prog1 ols (setq ols nil))) (if (overlay-get ol prop) (push ol ols)))) ;; Eliminate the case of an empty overlay at (1- pt). (dolist (ol (prog1 ols (setq ols nil))) (if (>= (overlay-end ol) pt) (push ol ols))) ;; "Get the smallest". I have no idea what that means, so I just do ;; something somewhat random but vaguely meaningful. -Stef (car (last (sort ols 'span-lt))))) (defsubst prev-span (span prop) "Return span before SPAN with property PROP." (span-at-before (span-start span) prop)) ; overlays are [start, end) (defsubst next-span (span prop) "Return span after SPAN with property PROP." ;; Presuming the span-extents.el is the reference, its code does the ;; same as the code below. (span-at (span-end span) prop)) (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)))) (defsubst span-raise (span) "Set priority of SPAN to make it appear above other spans." (span-set-property span 'priority 100)) (defsubst span-string (span) (with-current-buffer (overlay-buffer span) (buffer-substring-no-properties (overlay-start span) (overlay-end span)))) (defsubst set-span-properties (span plist) "Set SPAN's properties from PLIST which is a plist." (while plist (overlay-put span (car plist) (cadr plist)) (setq plist (cddr plist)))) (defsubst span-find-span (overlay-list &optional prop) "Return first overlay of OVERLAY-LIST having property PROP (default 'span). Return nil if no such overlay belong to the list." (let ((l overlay-list)) (while (and l (not (overlay-get (car l) (or prop 'span)))) (setq l (cdr l))) (car l))) (defsubst span-at-event (event &optional prop) "Find a span at position of EVENT, optionally with property PROP." (span-find-span (overlays-at (posn-point (event-start event))) prop)) (defun fold-spans (f &optional buffer from to maparg ignored-flags prop val) (with-current-buffer (or buffer (current-buffer)) (let ((ols (overlays-in (or from (point-min)) (or to (point-max)))) res) ;; Check the PROP. (when prop (dolist (ol (prog1 ols (setq ols nil))) (if (if val (eq val (overlay-get ol prop)) (overlay-get ol prop)) (push ol ols)))) ;; Iterate in order. (setq ols (sort ols 'span-lt)) (while (and ols (not (setq res (funcall f (pop ols) maparg))))) res))) (defsubst span-detached-p (span) "Is this SPAN detached? nil for no, t for yes." (null (overlay-buffer span))) (defsubst set-span-face (span face) "Set the FACE of a SPAN." (overlay-put span 'face face)) (defsubst set-span-keymap (span map) "Set the keymap of SPAN to MAP." (overlay-put span 'keymap map)) ;; ;; Generic functions built on low-level concrete ones. ;; (defsubst span-delete-spans (start end prop) "Delete all spans between START and END with property PROP set." (span-mapc-spans 'span-delete start end prop)) (defsubst span-property-safe (span name) "Like span-property, but return nil if SPAN is nil." (and span (span-property span name))) (defsubst span-set-start (span value) "Set the start point of SPAN to VALUE." (span-set-endpoints span value (span-end span))) (defsubst span-set-end (span value) "Set the end point of SPAN to VALUE." (span-set-endpoints span (span-start span) value)) ;; ;; Handy overlay utils ;; (defun span-make-self-removing-span (beg end &rest props) "Add a self-removing span from BEG to END with properties PROPS. The span will remove itself after a timeout of 2 seconds." (let ((ol (make-overlay beg end))) (while props (overlay-put ol (car props) (cadr props)) (setq props (cddr props))) (add-timeout 2 'delete-overlay ol) ol)) (defun span-delete-self-modification-hook (span &rest args) "Hook for overlay modification-hooks, which deletes SPAN." (if (span-live-p span) (span-delete span))) (defun span-make-modifying-removing-span (beg end &rest props) "Add a self-removing span from BEG to END with properties PROPS. The span will remove itself after any edit within its range. Return the span." (let ((ol (make-overlay beg end))) (while props (overlay-put ol (car props) (cadr props)) (setq props (cddr props))) (span-set-property ol 'modification-hooks (list 'span-delete-self-modification-hook)) ol)) (provide 'span) ;;; span.el ends here proofgeneral-4.3~pre130510/lib/texi-docstring-magic.el000066400000000000000000000340351214562307500225450ustar00rootroot00000000000000;; texi-docstring-magic.el --- munge internal docstrings into texi ;; ;; Keywords: lisp, docs, tex ;; Author: David Aspinall ;; Copyright (C) 1998 David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: texi-docstring-magic.el,v 12.1 2012/08/30 14:30:23 monnier Exp $ ;; ;; 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 use 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. ;; ;; ------ ;; ;; Thanks to: Christoph Conrad for an Emacs compatibility fix. ;; ;; (eval-when-compile (require 'cl)) (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. Escape @, { and } characters ("\\(@\\)" t "@@") ("\\({\\)" t "@{") ("\\(}\\)" t "@}") ;; 1. Indented lines are gathered into @lisp environment. ("^\\(\n\\|.+\\)$" t (let ((line (match-string 0 docstring))) (if (save-match-data (string-match "^[ \t]" line)) ;; whitespace (if in-quoted-region line (setq in-quoted-region t) (concat "@lisp\n" line)) ;; non-white space/carriage return (if (and in-quoted-region (not (equal line "\n"))) (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." (with-temp-buffer (insert string) (untabify (point-min) (point-max)) (buffer-string))) (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." ;; NB: might be nice to use a 'default-value-description ;; property here, in case the default value is computed. (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 &optional noerror) (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))))) (noerror (message "Warning: symbol `%s' not defined" (symbol-name symbol)) "") (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 (&optional noerror) "Update all texi docstring magic annotations in buffer. With prefix arg, no errors on unknown symbols. (This results in @def .. @end being deleted if not known)." (interactive "P") (save-excursion (goto-char (point-min)) (let ((magic (concat "^" (regexp-quote texi-docstring-magic-comment) "\\s-*\\(\\(\\w\\|\\-\\)+\\)[ \t]*$")) p symbol deleted) (while (re-search-forward magic nil t) (setq symbol (intern (match-string 1))) (forward-line) (setq p (point)) ;; delete any whitespace following magic comment (skip-chars-forward " \n\t") (delete-region 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)) (setq deleted t))) (insert (texi-docstring-magic-texi-for symbol noerror)) (unless deleted ;; Follow newly inserted @def with a single blank. (insert "\n")))))) (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) (and (fboundp 'function-at-point) (function-at-point)) (and (fboundp 'function-called-at-point) (function-called-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) proofgeneral-4.3~pre130510/lib/unicode-chars.el000066400000000000000000007414421214562307500212570ustar00rootroot00000000000000;; unicode-chars.el --- table of Unicode characters ;; ;; Author: David Aspinall ;; $Id: unicode-chars.el,v 12.1 2012/08/16 14:20:10 da Exp $ ;; ;; Adapted from Norman Walsh's unichars.el (iso8879 names removed) ;; ;; The names are standard, see ;; http://www.unicode.org/unicode/standard/standard.html ;; http://www.unicode.org/Public/UNIDATA (defvar unicode-chars-alist '(;Unicode name Codept ("NULL" . #x000000) ("START OF HEADING" . #x000001) ("START OF TEXT" . #x000002) ("END OF TEXT" . #x000003) ("END OF TRANSMISSION" . #x000004) ("ENQUIRY" . #x000005) ("ACKNOWLEDGE" . #x000006) ("BELL" . #x000007) ("BACKSPACE" . #x000008) ("CHARACTER TABULATION" . #x000009) ("LINE FEED (LF)" . #x00000a) ("LINE TABULATION" . #x00000b) ("FORM FEED (FF)" . #x00000c) ("CARRIAGE RETURN (CR)" . #x00000d) ("SHIFT OUT" . #x00000e) ("SHIFT IN" . #x00000f) ("DATA LINK ESCAPE" . #x000010) ("DEVICE CONTROL ONE" . #x000011) ("DEVICE CONTROL TWO" . #x000012) ("DEVICE CONTROL THREE" . #x000013) ("DEVICE CONTROL FOUR" . #x000014) ("NEGATIVE ACKNOWLEDGE" . #x000015) ("SYNCHRONOUS IDLE" . #x000016) ("END OF TRANSMISSION BLOCK;" . #x000017) ("CANCEL" . #x000018) ("END OF MEDIUM" . #x000019) ("SUBSTITUTE" . #x00001a) ("ESCAPE" . #x00001b) ("INFORMATION SEPARATOR FOUR" . #x00001c) ("INFORMATION SEPARATOR THREE" . #x00001d) ("INFORMATION SEPARATOR TWO" . #x00001e) ("INFORMATION SEPARATOR ONE" . #x00001f) ("SPACE" . #x000020) ("EXCLAMATION MARK" . #x000021) ("QUOTATION MARK" . #x000022) ("NUMBER SIGN" . #x000023) ("DOLLAR SIGN" . #x000024) ("PERCENT SIGN" . #x000025) ("AMPERSAND" . #x000026) ("APOSTROPHE" . #x000027) ("LEFT PARENTHESIS" . #x000028) ("RIGHT PARENTHESIS" . #x000029) ("ASTERISK" . #x00002a) ("PLUS SIGN" . #x00002b) ("COMMA" . #x00002c) ("HYPHEN-MINUS" . #x00002d) ("FULL STOP" . #x00002e) ("SOLIDUS" . #x00002f) ("DIGIT ZERO" . #x000030) ("DIGIT ONE" . #x000031) ("DIGIT TWO" . #x000032) ("DIGIT THREE" . #x000033) ("DIGIT FOUR" . #x000034) ("DIGIT FIVE" . #x000035) ("DIGIT SIX" . #x000036) ("DIGIT SEVEN" . #x000037) ("DIGIT EIGHT" . #x000038) ("DIGIT NINE" . #x000039) ("COLON" . #x00003a) ("SEMICOLON" . #x00003b) ("LESS-THAN SIGN" . #x00003c) ("EQUALS SIGN" . #x00003d) ("GREATER-THAN SIGN" . #x00003e) ("QUESTION MARK" . #x00003f) ("COMMERCIAL AT" . #x000040) ("LATIN CAPITAL LETTER A" . #x000041) ("LATIN CAPITAL LETTER B" . #x000042) ("LATIN CAPITAL LETTER C" . #x000043) ("LATIN CAPITAL LETTER D" . #x000044) ("LATIN CAPITAL LETTER E" . #x000045) ("LATIN CAPITAL LETTER F" . #x000046) ("LATIN CAPITAL LETTER G" . #x000047) ("LATIN CAPITAL LETTER H" . #x000048) ("LATIN CAPITAL LETTER I" . #x000049) ("LATIN CAPITAL LETTER J" . #x00004a) ("LATIN CAPITAL LETTER K" . #x00004b) ("LATIN CAPITAL LETTER L" . #x00004c) ("LATIN CAPITAL LETTER M" . #x00004d) ("LATIN CAPITAL LETTER N" . #x00004e) ("LATIN CAPITAL LETTER O" . #x00004f) ("LATIN CAPITAL LETTER P" . #x000050) ("LATIN CAPITAL LETTER Q" . #x000051) ("LATIN CAPITAL LETTER R" . #x000052) ("LATIN CAPITAL LETTER S" . #x000053) ("LATIN CAPITAL LETTER T" . #x000054) ("LATIN CAPITAL LETTER U" . #x000055) ("LATIN CAPITAL LETTER V" . #x000056) ("LATIN CAPITAL LETTER W" . #x000057) ("LATIN CAPITAL LETTER X" . #x000058) ("LATIN CAPITAL LETTER Y" . #x000059) ("LATIN CAPITAL LETTER Z" . #x00005a) ("LEFT SQUARE BRACKET" . #x00005b) ("REVERSE SOLIDUS" . #x00005c) ("RIGHT SQUARE BRACKET" . #x00005d) ("CIRCUMFLEX ACCENT" . #x00005e) ("LOW LINE" . #x00005f) ("GRAVE ACCENT" . #x000060) ("LATIN SMALL LETTER A" . #x000061) ("LATIN SMALL LETTER B" . #x000062) ("LATIN SMALL LETTER C" . #x000063) ("LATIN SMALL LETTER D" . #x000064) ("LATIN SMALL LETTER E" . #x000065) ("LATIN SMALL LETTER F" . #x000066) ("LATIN SMALL LETTER G" . #x000067) ("LATIN SMALL LETTER H" . #x000068) ("LATIN SMALL LETTER I" . #x000069) ("LATIN SMALL LETTER J" . #x00006a) ("LATIN SMALL LETTER K" . #x00006b) ("LATIN SMALL LETTER L" . #x00006c) ("LATIN SMALL LETTER M" . #x00006d) ("LATIN SMALL LETTER N" . #x00006e) ("LATIN SMALL LETTER O" . #x00006f) ("LATIN SMALL LETTER P" . #x000070) ("LATIN SMALL LETTER Q" . #x000071) ("LATIN SMALL LETTER R" . #x000072) ("LATIN SMALL LETTER S" . #x000073) ("LATIN SMALL LETTER T" . #x000074) ("LATIN SMALL LETTER U" . #x000075) ("LATIN SMALL LETTER V" . #x000076) ("LATIN SMALL LETTER W" . #x000077) ("LATIN SMALL LETTER X" . #x000078) ("LATIN SMALL LETTER Y" . #x000079) ("LATIN SMALL LETTER Z" . #x00007a) ("LEFT CURLY BRACKET" . #x00007b) ("VERTICAL LINE" . #x00007c) ("RIGHT CURLY BRACKET" . #x00007d) ("TILDE" . #x00007e) ("DELETE" . #x00007f) ("BREAK PERMITTED HERE" . #x000082) ("NO BREAK HERE" . #x000083) ("NEXT LINE (NEL)" . #x000085) ("START OF SELECTED AREA" . #x000086) ("END OF SELECTED AREA" . #x000087) ("CHARACTER TABULATION SET" . #x000088) ("CHARACTER TABULATION WITH JUSTIFICATION" . #x000089) ("LINE TABULATION SET" . #x00008a) ("PARTIAL LINE FORWARD" . #x00008b) ("PARTIAL LINE BACKWARD" . #x00008c) ("REVERSE LINE FEED" . #x00008d) ("SINGLE SHIFT TWO" . #x00008e) ("SINGLE SHIFT THREE" . #x00008f) ("DEVICE CONTROL STRING" . #x000090) ("PRIVATE USE ONE" . #x000091) ("PRIVATE USE TWO" . #x000092) ("SET TRANSMIT STATE" . #x000093) ("CANCEL CHARACTER" . #x000094) ("MESSAGE WAITING" . #x000095) ("START OF GUARDED AREA" . #x000096) ("END OF GUARDED AREA" . #x000097) ("START OF STRING" . #x000098) ("SINGLE CHARACTER INTRODUCER" . #x00009a) ("CONTROL SEQUENCE INTRODUCER" . #x00009b) ("STRING TERMINATOR" . #x00009c) ("OPERATING SYSTEM COMMAND" . #x00009d) ("PRIVACY MESSAGE" . #x00009e) ("APPLICATION PROGRAM COMMAND" . #x00009f) ("NO-BREAK SPACE" . #x0000a0) ("INVERTED EXCLAMATION MARK" . #x0000a1) ("CENT SIGN" . #x0000a2) ("POUND SIGN" . #x0000a3) ("CURRENCY SIGN" . #x0000a4) ("YEN SIGN" . #x0000a5) ("BROKEN BAR" . #x0000a6) ("SECTION SIGN" . #x0000a7) ("DIAERESIS" . #x0000a8) ("COPYRIGHT SIGN" . #x0000a9) ("FEMININE ORDINAL INDICATOR" . #x0000aa) ("LEFT-POINTING DOUBLE ANGLE QUOTATION MARK" . #x0000ab) ("NOT SIGN" . #x0000ac) ("SOFT HYPHEN" . #x0000ad) ("REGISTERED SIGN" . #x0000ae) ("MACRON" . #x0000af) ("DEGREE SIGN" . #x0000b0) ("PLUS-MINUS SIGN" . #x0000b1) ("SUPERSCRIPT TWO" . #x0000b2) ("SUPERSCRIPT THREE" . #x0000b3) ("ACUTE ACCENT" . #x0000b4) ("MICRO SIGN" . #x0000b5) ("PILCROW SIGN" . #x0000b6) ("MIDDLE DOT" . #x0000b7) ("CEDILLA" . #x0000b8) ("SUPERSCRIPT ONE" . #x0000b9) ("MASCULINE ORDINAL INDICATOR" . #x0000ba) ("RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK" . #x0000bb) ("VULGAR FRACTION ONE QUARTER" . #x0000bc) ("VULGAR FRACTION ONE HALF" . #x0000bd) ("VULGAR FRACTION THREE QUARTERS" . #x0000be) ("INVERTED QUESTION MARK" . #x0000bf) ("LATIN CAPITAL LETTER A WITH GRAVE" . #x0000c0) ("LATIN CAPITAL LETTER A WITH ACUTE" . #x0000c1) ("LATIN CAPITAL LETTER A WITH CIRCUMFLEX" . #x0000c2) ("LATIN CAPITAL LETTER A WITH TILDE" . #x0000c3) ("LATIN CAPITAL LETTER A WITH DIAERESIS" . #x0000c4) ("LATIN CAPITAL LETTER A WITH RING ABOVE" . #x0000c5) ("LATIN CAPITAL LETTER AE" . #x0000c6) ("LATIN CAPITAL LETTER C WITH CEDILLA" . #x0000c7) ("LATIN CAPITAL LETTER E WITH GRAVE" . #x0000c8) ("LATIN CAPITAL LETTER E WITH ACUTE" . #x0000c9) ("LATIN CAPITAL LETTER E WITH CIRCUMFLEX" . #x0000ca) ("LATIN CAPITAL LETTER E WITH DIAERESIS" . #x0000cb) ("LATIN CAPITAL LETTER I WITH GRAVE" . #x0000cc) ("LATIN CAPITAL LETTER I WITH ACUTE" . #x0000cd) ("LATIN CAPITAL LETTER I WITH CIRCUMFLEX" . #x0000ce) ("LATIN CAPITAL LETTER I WITH DIAERESIS" . #x0000cf) ("LATIN CAPITAL LETTER ETH" . #x0000d0) ("LATIN CAPITAL LETTER N WITH TILDE" . #x0000d1) ("LATIN CAPITAL LETTER O WITH GRAVE" . #x0000d2) ("LATIN CAPITAL LETTER O WITH ACUTE" . #x0000d3) ("LATIN CAPITAL LETTER O WITH CIRCUMFLEX" . #x0000d4) ("LATIN CAPITAL LETTER O WITH TILDE" . #x0000d5) ("LATIN CAPITAL LETTER O WITH DIAERESIS" . #x0000d6) ("MULTIPLICATION SIGN" . #x0000d7) ("LATIN CAPITAL LETTER O WITH STROKE" . #x0000d8) ("LATIN CAPITAL LETTER U WITH GRAVE" . #x0000d9) ("LATIN CAPITAL LETTER U WITH ACUTE" . #x0000da) ("LATIN CAPITAL LETTER U WITH CIRCUMFLEX" . #x0000db) ("LATIN CAPITAL LETTER U WITH DIAERESIS" . #x0000dc) ("LATIN CAPITAL LETTER Y WITH ACUTE" . #x0000dd) ("LATIN CAPITAL LETTER THORN" . #x0000de) ("LATIN SMALL LETTER SHARP S" . #x0000df) ("LATIN SMALL LETTER A WITH GRAVE" . #x0000e0) ("LATIN SMALL LETTER A WITH ACUTE" . #x0000e1) ("LATIN SMALL LETTER A WITH CIRCUMFLEX" . #x0000e2) ("LATIN SMALL LETTER A WITH TILDE" . #x0000e3) ("LATIN SMALL LETTER A WITH DIAERESIS" . #x0000e4) ("LATIN SMALL LETTER A WITH RING ABOVE" . #x0000e5) ("LATIN SMALL LETTER AE" . #x0000e6) ("LATIN SMALL LETTER C WITH CEDILLA" . #x0000e7) ("LATIN SMALL LETTER E WITH GRAVE" . #x0000e8) ("LATIN SMALL LETTER E WITH ACUTE" . #x0000e9) ("LATIN SMALL LETTER E WITH CIRCUMFLEX" . #x0000ea) ("LATIN SMALL LETTER E WITH DIAERESIS" . #x0000eb) ("LATIN SMALL LETTER I WITH GRAVE" . #x0000ec) ("LATIN SMALL LETTER I WITH ACUTE" . #x0000ed) ("LATIN SMALL LETTER I WITH CIRCUMFLEX" . #x0000ee) ("LATIN SMALL LETTER I WITH DIAERESIS" . #x0000ef) ("LATIN SMALL LETTER ETH" . #x0000f0) ("LATIN SMALL LETTER N WITH TILDE" . #x0000f1) ("LATIN SMALL LETTER O WITH GRAVE" . #x0000f2) ("LATIN SMALL LETTER O WITH ACUTE" . #x0000f3) ("LATIN SMALL LETTER O WITH CIRCUMFLEX" . #x0000f4) ("LATIN SMALL LETTER O WITH TILDE" . #x0000f5) ("LATIN SMALL LETTER O WITH DIAERESIS" . #x0000f6) ("DIVISION SIGN" . #x0000f7) ("LATIN SMALL LETTER O WITH STROKE" . #x0000f8) ("LATIN SMALL LETTER U WITH GRAVE" . #x0000f9) ("LATIN SMALL LETTER U WITH ACUTE" . #x0000fa) ("LATIN SMALL LETTER U WITH CIRCUMFLEX" . #x0000fb) ("LATIN SMALL LETTER U WITH DIAERESIS" . #x0000fc) ("LATIN SMALL LETTER Y WITH ACUTE" . #x0000fd) ("LATIN SMALL LETTER THORN" . #x0000fe) ("LATIN SMALL LETTER Y WITH DIAERESIS" . #x0000ff) ("LATIN CAPITAL LETTER A WITH MACRON" . #x000100) ("LATIN SMALL LETTER A WITH MACRON" . #x000101) ("LATIN CAPITAL LETTER A WITH BREVE" . #x000102) ("LATIN SMALL LETTER A WITH BREVE" . #x000103) ("LATIN CAPITAL LETTER A WITH OGONEK" . #x000104) ("LATIN SMALL LETTER A WITH OGONEK" . #x000105) ("LATIN CAPITAL LETTER C WITH ACUTE" . #x000106) ("LATIN SMALL LETTER C WITH ACUTE" . #x000107) ("LATIN CAPITAL LETTER C WITH CIRCUMFLEX" . #x000108) ("LATIN SMALL LETTER C WITH CIRCUMFLEX" . #x000109) ("LATIN CAPITAL LETTER C WITH DOT ABOVE" . #x00010a) ("LATIN SMALL LETTER C WITH DOT ABOVE" . #x00010b) ("LATIN CAPITAL LETTER C WITH CARON" . #x00010c) ("LATIN SMALL LETTER C WITH CARON" . #x00010d) ("LATIN CAPITAL LETTER D WITH CARON" . #x00010e) ("LATIN SMALL LETTER D WITH CARON" . #x00010f) ("LATIN CAPITAL LETTER D WITH STROKE" . #x000110) ("LATIN SMALL LETTER D WITH STROKE" . #x000111) ("LATIN CAPITAL LETTER E WITH MACRON" . #x000112) ("LATIN SMALL LETTER E WITH MACRON" . #x000113) ("LATIN CAPITAL LETTER E WITH BREVE" . #x000114) ("LATIN SMALL LETTER E WITH BREVE" . #x000115) ("LATIN CAPITAL LETTER E WITH DOT ABOVE" . #x000116) ("LATIN SMALL LETTER E WITH DOT ABOVE" . #x000117) ("LATIN CAPITAL LETTER E WITH OGONEK" . #x000118) ("LATIN SMALL LETTER E WITH OGONEK" . #x000119) ("LATIN CAPITAL LETTER E WITH CARON" . #x00011a) ("LATIN SMALL LETTER E WITH CARON" . #x00011b) ("LATIN CAPITAL LETTER G WITH CIRCUMFLEX" . #x00011c) ("LATIN SMALL LETTER G WITH CIRCUMFLEX" . #x00011d) ("LATIN CAPITAL LETTER G WITH BREVE" . #x00011e) ("LATIN SMALL LETTER G WITH BREVE" . #x00011f) ("LATIN CAPITAL LETTER G WITH DOT ABOVE" . #x000120) ("LATIN SMALL LETTER G WITH DOT ABOVE" . #x000121) ("LATIN CAPITAL LETTER G WITH CEDILLA" . #x000122) ("LATIN SMALL LETTER G WITH CEDILLA" . #x000123) ("LATIN CAPITAL LETTER H WITH CIRCUMFLEX" . #x000124) ("LATIN SMALL LETTER H WITH CIRCUMFLEX" . #x000125) ("LATIN CAPITAL LETTER H WITH STROKE" . #x000126) ("LATIN SMALL LETTER H WITH STROKE" . #x000127) ("LATIN CAPITAL LETTER I WITH TILDE" . #x000128) ("LATIN SMALL LETTER I WITH TILDE" . #x000129) ("LATIN CAPITAL LETTER I WITH MACRON" . #x00012a) ("LATIN SMALL LETTER I WITH MACRON" . #x00012b) ("LATIN CAPITAL LETTER I WITH BREVE" . #x00012c) ("LATIN SMALL LETTER I WITH BREVE" . #x00012d) ("LATIN CAPITAL LETTER I WITH OGONEK" . #x00012e) ("LATIN SMALL LETTER I WITH OGONEK" . #x00012f) ("LATIN CAPITAL LETTER I WITH DOT ABOVE" . #x000130) ("LATIN SMALL LETTER DOTLESS I" . #x000131) ("LATIN CAPITAL LIGATURE IJ" . #x000132) ("LATIN SMALL LIGATURE IJ" . #x000133) ("LATIN CAPITAL LETTER J WITH CIRCUMFLEX" . #x000134) ("LATIN SMALL LETTER J WITH CIRCUMFLEX" . #x000135) ("LATIN CAPITAL LETTER K WITH CEDILLA" . #x000136) ("LATIN SMALL LETTER K WITH CEDILLA" . #x000137) ("LATIN SMALL LETTER KRA" . #x000138) ("LATIN CAPITAL LETTER L WITH ACUTE" . #x000139) ("LATIN SMALL LETTER L WITH ACUTE" . #x00013a) ("LATIN CAPITAL LETTER L WITH CEDILLA" . #x00013b) ("LATIN SMALL LETTER L WITH CEDILLA" . #x00013c) ("LATIN CAPITAL LETTER L WITH CARON" . #x00013d) ("LATIN SMALL LETTER L WITH CARON" . #x00013e) ("LATIN CAPITAL LETTER L WITH MIDDLE DOT" . #x00013f) ("LATIN SMALL LETTER L WITH MIDDLE DOT" . #x000140) ("LATIN CAPITAL LETTER L WITH STROKE" . #x000141) ("LATIN SMALL LETTER L WITH STROKE" . #x000142) ("LATIN CAPITAL LETTER N WITH ACUTE" . #x000143) ("LATIN SMALL LETTER N WITH ACUTE" . #x000144) ("LATIN CAPITAL LETTER N WITH CEDILLA" . #x000145) ("LATIN SMALL LETTER N WITH CEDILLA" . #x000146) ("LATIN CAPITAL LETTER N WITH CARON" . #x000147) ("LATIN SMALL LETTER N WITH CARON" . #x000148) ("LATIN SMALL LETTER N PRECEDED BY APOSTROPHE" . #x000149) ("LATIN CAPITAL LETTER ENG" . #x00014a) ("LATIN SMALL LETTER ENG" . #x00014b) ("LATIN CAPITAL LETTER O WITH MACRON" . #x00014c) ("LATIN SMALL LETTER O WITH MACRON" . #x00014d) ("LATIN CAPITAL LETTER O WITH BREVE" . #x00014e) ("LATIN SMALL LETTER O WITH BREVE" . #x00014f) ("LATIN CAPITAL LETTER O WITH DOUBLE ACUTE" . #x000150) ("LATIN SMALL LETTER O WITH DOUBLE ACUTE" . #x000151) ("LATIN CAPITAL LIGATURE OE" . #x000152) ("LATIN SMALL LIGATURE OE" . #x000153) ("LATIN CAPITAL LETTER R WITH ACUTE" . #x000154) ("LATIN SMALL LETTER R WITH ACUTE" . #x000155) ("LATIN CAPITAL LETTER R WITH CEDILLA" . #x000156) ("LATIN SMALL LETTER R WITH CEDILLA" . #x000157) ("LATIN CAPITAL LETTER R WITH CARON" . #x000158) ("LATIN SMALL LETTER R WITH CARON" . #x000159) ("LATIN CAPITAL LETTER S WITH ACUTE" . #x00015a) ("LATIN SMALL LETTER S WITH ACUTE" . #x00015b) ("LATIN CAPITAL LETTER S WITH CIRCUMFLEX" . #x00015c) ("LATIN SMALL LETTER S WITH CIRCUMFLEX" . #x00015d) ("LATIN CAPITAL LETTER S WITH CEDILLA" . #x00015e) ("LATIN SMALL LETTER S WITH CEDILLA" . #x00015f) ("LATIN CAPITAL LETTER S WITH CARON" . #x000160) ("LATIN SMALL LETTER S WITH CARON" . #x000161) ("LATIN CAPITAL LETTER T WITH CEDILLA" . #x000162) ("LATIN SMALL LETTER T WITH CEDILLA" . #x000163) ("LATIN CAPITAL LETTER T WITH CARON" . #x000164) ("LATIN SMALL LETTER T WITH CARON" . #x000165) ("LATIN CAPITAL LETTER T WITH STROKE" . #x000166) ("LATIN SMALL LETTER T WITH STROKE" . #x000167) ("LATIN CAPITAL LETTER U WITH TILDE" . #x000168) ("LATIN SMALL LETTER U WITH TILDE" . #x000169) ("LATIN CAPITAL LETTER U WITH MACRON" . #x00016a) ("LATIN SMALL LETTER U WITH MACRON" . #x00016b) ("LATIN CAPITAL LETTER U WITH BREVE" . #x00016c) ("LATIN SMALL LETTER U WITH BREVE" . #x00016d) ("LATIN CAPITAL LETTER U WITH RING ABOVE" . #x00016e) ("LATIN SMALL LETTER U WITH RING ABOVE" . #x00016f) ("LATIN CAPITAL LETTER U WITH DOUBLE ACUTE" . #x000170) ("LATIN SMALL LETTER U WITH DOUBLE ACUTE" . #x000171) ("LATIN CAPITAL LETTER U WITH OGONEK" . #x000172) ("LATIN SMALL LETTER U WITH OGONEK" . #x000173) ("LATIN CAPITAL LETTER W WITH CIRCUMFLEX" . #x000174) ("LATIN SMALL LETTER W WITH CIRCUMFLEX" . #x000175) ("LATIN CAPITAL LETTER Y WITH CIRCUMFLEX" . #x000176) ("LATIN SMALL LETTER Y WITH CIRCUMFLEX" . #x000177) ("LATIN CAPITAL LETTER Y WITH DIAERESIS" . #x000178) ("LATIN CAPITAL LETTER Z WITH ACUTE" . #x000179) ("LATIN SMALL LETTER Z WITH ACUTE" . #x00017a) ("LATIN CAPITAL LETTER Z WITH DOT ABOVE" . #x00017b) ("LATIN SMALL LETTER Z WITH DOT ABOVE" . #x00017c) ("LATIN CAPITAL LETTER Z WITH CARON" . #x00017d) ("LATIN SMALL LETTER Z WITH CARON" . #x00017e) ("LATIN SMALL LETTER LONG S" . #x00017f) ("LATIN SMALL LETTER B WITH STROKE" . #x000180) ("LATIN CAPITAL LETTER B WITH HOOK" . #x000181) ("LATIN CAPITAL LETTER B WITH TOPBAR" . #x000182) ("LATIN SMALL LETTER B WITH TOPBAR" . #x000183) ("LATIN CAPITAL LETTER TONE SIX" . #x000184) ("LATIN SMALL LETTER TONE SIX" . #x000185) ("LATIN CAPITAL LETTER OPEN O" . #x000186) ("LATIN CAPITAL LETTER C WITH HOOK" . #x000187) ("LATIN SMALL LETTER C WITH HOOK" . #x000188) ("LATIN CAPITAL LETTER AFRICAN D" . #x000189) ("LATIN CAPITAL LETTER D WITH HOOK" . #x00018a) ("LATIN CAPITAL LETTER D WITH TOPBAR" . #x00018b) ("LATIN SMALL LETTER D WITH TOPBAR" . #x00018c) ("LATIN SMALL LETTER TURNED DELTA" . #x00018d) ("LATIN CAPITAL LETTER REVERSED E" . #x00018e) ("LATIN CAPITAL LETTER SCHWA" . #x00018f) ("LATIN CAPITAL LETTER OPEN E" . #x000190) ("LATIN CAPITAL LETTER F WITH HOOK" . #x000191) ("LATIN SMALL LETTER F WITH HOOK" . #x000192) ("LATIN CAPITAL LETTER G WITH HOOK" . #x000193) ("LATIN CAPITAL LETTER GAMMA" . #x000194) ("LATIN SMALL LETTER HV" . #x000195) ("LATIN CAPITAL LETTER IOTA" . #x000196) ("LATIN CAPITAL LETTER I WITH STROKE" . #x000197) ("LATIN CAPITAL LETTER K WITH HOOK" . #x000198) ("LATIN SMALL LETTER K WITH HOOK" . #x000199) ("LATIN SMALL LETTER L WITH BAR" . #x00019a) ("LATIN SMALL LETTER LAMBDA WITH STROKE" . #x00019b) ("LATIN CAPITAL LETTER TURNED M" . #x00019c) ("LATIN CAPITAL LETTER N WITH LEFT HOOK" . #x00019d) ("LATIN SMALL LETTER N WITH LONG RIGHT LEG" . #x00019e) ("LATIN CAPITAL LETTER O WITH MIDDLE TILDE" . #x00019f) ("LATIN CAPITAL LETTER O WITH HORN" . #x0001a0) ("LATIN SMALL LETTER O WITH HORN" . #x0001a1) ("LATIN CAPITAL LETTER OI" . #x0001a2) ("LATIN SMALL LETTER OI" . #x0001a3) ("LATIN CAPITAL LETTER P WITH HOOK" . #x0001a4) ("LATIN SMALL LETTER P WITH HOOK" . #x0001a5) ("LATIN LETTER YR" . #x0001a6) ("LATIN CAPITAL LETTER TONE TWO" . #x0001a7) ("LATIN SMALL LETTER TONE TWO" . #x0001a8) ("LATIN CAPITAL LETTER ESH" . #x0001a9) ("LATIN LETTER REVERSED ESH LOOP" . #x0001aa) ("LATIN SMALL LETTER T WITH PALATAL HOOK" . #x0001ab) ("LATIN CAPITAL LETTER T WITH HOOK" . #x0001ac) ("LATIN SMALL LETTER T WITH HOOK" . #x0001ad) ("LATIN CAPITAL LETTER T WITH RETROFLEX HOOK" . #x0001ae) ("LATIN CAPITAL LETTER U WITH HORN" . #x0001af) ("LATIN SMALL LETTER U WITH HORN" . #x0001b0) ("LATIN CAPITAL LETTER UPSILON" . #x0001b1) ("LATIN CAPITAL LETTER V WITH HOOK" . #x0001b2) ("LATIN CAPITAL LETTER Y WITH HOOK" . #x0001b3) ("LATIN SMALL LETTER Y WITH HOOK" . #x0001b4) ("LATIN CAPITAL LETTER Z WITH STROKE" . #x0001b5) ("LATIN SMALL LETTER Z WITH STROKE" . #x0001b6) ("LATIN CAPITAL LETTER EZH" . #x0001b7) ("LATIN CAPITAL LETTER EZH REVERSED" . #x0001b8) ("LATIN SMALL LETTER EZH REVERSED" . #x0001b9) ("LATIN SMALL LETTER EZH WITH TAIL" . #x0001ba) ("LATIN LETTER TWO WITH STROKE" . #x0001bb) ("LATIN CAPITAL LETTER TONE FIVE" . #x0001bc) ("LATIN SMALL LETTER TONE FIVE" . #x0001bd) ("LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE" . #x0001be) ("LATIN LETTER WYNN" . #x0001bf) ("LATIN LETTER DENTAL CLICK" . #x0001c0) ("LATIN LETTER LATERAL CLICK" . #x0001c1) ("LATIN LETTER ALVEOLAR CLICK" . #x0001c2) ("LATIN LETTER RETROFLEX CLICK" . #x0001c3) ("LATIN CAPITAL LETTER DZ WITH CARON" . #x0001c4) ("LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON" . #x0001c5) ("LATIN SMALL LETTER DZ WITH CARON" . #x0001c6) ("LATIN CAPITAL LETTER LJ" . #x0001c7) ("LATIN CAPITAL LETTER L WITH SMALL LETTER J" . #x0001c8) ("LATIN SMALL LETTER LJ" . #x0001c9) ("LATIN CAPITAL LETTER NJ" . #x0001ca) ("LATIN CAPITAL LETTER N WITH SMALL LETTER J" . #x0001cb) ("LATIN SMALL LETTER NJ" . #x0001cc) ("LATIN CAPITAL LETTER A WITH CARON" . #x0001cd) ("LATIN SMALL LETTER A WITH CARON" . #x0001ce) ("LATIN CAPITAL LETTER I WITH CARON" . #x0001cf) ("LATIN SMALL LETTER I WITH CARON" . #x0001d0) ("LATIN CAPITAL LETTER O WITH CARON" . #x0001d1) ("LATIN SMALL LETTER O WITH CARON" . #x0001d2) ("LATIN CAPITAL LETTER U WITH CARON" . #x0001d3) ("LATIN SMALL LETTER U WITH CARON" . #x0001d4) ("LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON" . #x0001d5) ("LATIN SMALL LETTER U WITH DIAERESIS AND MACRON" . #x0001d6) ("LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE" . #x0001d7) ("LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE" . #x0001d8) ("LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON" . #x0001d9) ("LATIN SMALL LETTER U WITH DIAERESIS AND CARON" . #x0001da) ("LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE" . #x0001db) ("LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE" . #x0001dc) ("LATIN SMALL LETTER TURNED E" . #x0001dd) ("LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON" . #x0001de) ("LATIN SMALL LETTER A WITH DIAERESIS AND MACRON" . #x0001df) ("LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON" . #x0001e0) ("LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON" . #x0001e1) ("LATIN CAPITAL LETTER AE WITH MACRON" . #x0001e2) ("LATIN SMALL LETTER AE WITH MACRON" . #x0001e3) ("LATIN CAPITAL LETTER G WITH STROKE" . #x0001e4) ("LATIN SMALL LETTER G WITH STROKE" . #x0001e5) ("LATIN CAPITAL LETTER G WITH CARON" . #x0001e6) ("LATIN SMALL LETTER G WITH CARON" . #x0001e7) ("LATIN CAPITAL LETTER K WITH CARON" . #x0001e8) ("LATIN SMALL LETTER K WITH CARON" . #x0001e9) ("LATIN CAPITAL LETTER O WITH OGONEK" . #x0001ea) ("LATIN SMALL LETTER O WITH OGONEK" . #x0001eb) ("LATIN CAPITAL LETTER O WITH OGONEK AND MACRON" . #x0001ec) ("LATIN SMALL LETTER O WITH OGONEK AND MACRON" . #x0001ed) ("LATIN CAPITAL LETTER EZH WITH CARON" . #x0001ee) ("LATIN SMALL LETTER EZH WITH CARON" . #x0001ef) ("LATIN SMALL LETTER J WITH CARON" . #x0001f0) ("LATIN CAPITAL LETTER DZ" . #x0001f1) ("LATIN CAPITAL LETTER D WITH SMALL LETTER Z" . #x0001f2) ("LATIN SMALL LETTER DZ" . #x0001f3) ("LATIN CAPITAL LETTER G WITH ACUTE" . #x0001f4) ("LATIN SMALL LETTER G WITH ACUTE" . #x0001f5) ("LATIN CAPITAL LETTER HWAIR" . #x0001f6) ("LATIN CAPITAL LETTER WYNN" . #x0001f7) ("LATIN CAPITAL LETTER N WITH GRAVE" . #x0001f8) ("LATIN SMALL LETTER N WITH GRAVE" . #x0001f9) ("LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE" . #x0001fa) ("LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE" . #x0001fb) ("LATIN CAPITAL LETTER AE WITH ACUTE" . #x0001fc) ("LATIN SMALL LETTER AE WITH ACUTE" . #x0001fd) ("LATIN CAPITAL LETTER O WITH STROKE AND ACUTE" . #x0001fe) ("LATIN SMALL LETTER O WITH STROKE AND ACUTE" . #x0001ff) ("LATIN CAPITAL LETTER A WITH DOUBLE GRAVE" . #x000200) ("LATIN SMALL LETTER A WITH DOUBLE GRAVE" . #x000201) ("LATIN CAPITAL LETTER A WITH INVERTED BREVE" . #x000202) ("LATIN SMALL LETTER A WITH INVERTED BREVE" . #x000203) ("LATIN CAPITAL LETTER E WITH DOUBLE GRAVE" . #x000204) ("LATIN SMALL LETTER E WITH DOUBLE GRAVE" . #x000205) ("LATIN CAPITAL LETTER E WITH INVERTED BREVE" . #x000206) ("LATIN SMALL LETTER E WITH INVERTED BREVE" . #x000207) ("LATIN CAPITAL LETTER I WITH DOUBLE GRAVE" . #x000208) ("LATIN SMALL LETTER I WITH DOUBLE GRAVE" . #x000209) ("LATIN CAPITAL LETTER I WITH INVERTED BREVE" . #x00020a) ("LATIN SMALL LETTER I WITH INVERTED BREVE" . #x00020b) ("LATIN CAPITAL LETTER O WITH DOUBLE GRAVE" . #x00020c) ("LATIN SMALL LETTER O WITH DOUBLE GRAVE" . #x00020d) ("LATIN CAPITAL LETTER O WITH INVERTED BREVE" . #x00020e) ("LATIN SMALL LETTER O WITH INVERTED BREVE" . #x00020f) ("LATIN CAPITAL LETTER R WITH DOUBLE GRAVE" . #x000210) ("LATIN SMALL LETTER R WITH DOUBLE GRAVE" . #x000211) ("LATIN CAPITAL LETTER R WITH INVERTED BREVE" . #x000212) ("LATIN SMALL LETTER R WITH INVERTED BREVE" . #x000213) ("LATIN CAPITAL LETTER U WITH DOUBLE GRAVE" . #x000214) ("LATIN SMALL LETTER U WITH DOUBLE GRAVE" . #x000215) ("LATIN CAPITAL LETTER U WITH INVERTED BREVE" . #x000216) ("LATIN SMALL LETTER U WITH INVERTED BREVE" . #x000217) ("LATIN CAPITAL LETTER S WITH COMMA BELOW" . #x000218) ("LATIN SMALL LETTER S WITH COMMA BELOW" . #x000219) ("LATIN CAPITAL LETTER T WITH COMMA BELOW" . #x00021a) ("LATIN SMALL LETTER T WITH COMMA BELOW" . #x00021b) ("LATIN CAPITAL LETTER YOGH" . #x00021c) ("LATIN SMALL LETTER YOGH" . #x00021d) ("LATIN CAPITAL LETTER H WITH CARON" . #x00021e) ("LATIN SMALL LETTER H WITH CARON" . #x00021f) ("LATIN CAPITAL LETTER N WITH LONG RIGHT LEG" . #x000220) ("LATIN CAPITAL LETTER OU" . #x000222) ("LATIN SMALL LETTER OU" . #x000223) ("LATIN CAPITAL LETTER Z WITH HOOK" . #x000224) ("LATIN SMALL LETTER Z WITH HOOK" . #x000225) ("LATIN CAPITAL LETTER A WITH DOT ABOVE" . #x000226) ("LATIN SMALL LETTER A WITH DOT ABOVE" . #x000227) ("LATIN CAPITAL LETTER E WITH CEDILLA" . #x000228) ("LATIN SMALL LETTER E WITH CEDILLA" . #x000229) ("LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON" . #x00022a) ("LATIN SMALL LETTER O WITH DIAERESIS AND MACRON" . #x00022b) ("LATIN CAPITAL LETTER O WITH TILDE AND MACRON" . #x00022c) ("LATIN SMALL LETTER O WITH TILDE AND MACRON" . #x00022d) ("LATIN CAPITAL LETTER O WITH DOT ABOVE" . #x00022e) ("LATIN SMALL LETTER O WITH DOT ABOVE" . #x00022f) ("LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON" . #x000230) ("LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON" . #x000231) ("LATIN CAPITAL LETTER Y WITH MACRON" . #x000232) ("LATIN SMALL LETTER Y WITH MACRON" . #x000233) ("LATIN SMALL LETTER TURNED A" . #x000250) ("LATIN SMALL LETTER ALPHA" . #x000251) ("LATIN SMALL LETTER TURNED ALPHA" . #x000252) ("LATIN SMALL LETTER B WITH HOOK" . #x000253) ("LATIN SMALL LETTER OPEN O" . #x000254) ("LATIN SMALL LETTER C WITH CURL" . #x000255) ("LATIN SMALL LETTER D WITH TAIL" . #x000256) ("LATIN SMALL LETTER D WITH HOOK" . #x000257) ("LATIN SMALL LETTER REVERSED E" . #x000258) ("LATIN SMALL LETTER SCHWA" . #x000259) ("LATIN SMALL LETTER SCHWA WITH HOOK" . #x00025a) ("LATIN SMALL LETTER OPEN E" . #x00025b) ("LATIN SMALL LETTER REVERSED OPEN E" . #x00025c) ("LATIN SMALL LETTER REVERSED OPEN E WITH HOOK" . #x00025d) ("LATIN SMALL LETTER CLOSED REVERSED OPEN E" . #x00025e) ("LATIN SMALL LETTER DOTLESS J WITH STROKE" . #x00025f) ("LATIN SMALL LETTER G WITH HOOK" . #x000260) ("LATIN SMALL LETTER SCRIPT G" . #x000261) ("LATIN LETTER SMALL CAPITAL G" . #x000262) ("LATIN SMALL LETTER GAMMA" . #x000263) ("LATIN SMALL LETTER RAMS HORN" . #x000264) ("LATIN SMALL LETTER TURNED H" . #x000265) ("LATIN SMALL LETTER H WITH HOOK" . #x000266) ("LATIN SMALL LETTER HENG WITH HOOK" . #x000267) ("LATIN SMALL LETTER I WITH STROKE" . #x000268) ("LATIN SMALL LETTER IOTA" . #x000269) ("LATIN LETTER SMALL CAPITAL I" . #x00026a) ("LATIN SMALL LETTER L WITH MIDDLE TILDE" . #x00026b) ("LATIN SMALL LETTER L WITH BELT" . #x00026c) ("LATIN SMALL LETTER L WITH RETROFLEX HOOK" . #x00026d) ("LATIN SMALL LETTER LEZH" . #x00026e) ("LATIN SMALL LETTER TURNED M" . #x00026f) ("LATIN SMALL LETTER TURNED M WITH LONG LEG" . #x000270) ("LATIN SMALL LETTER M WITH HOOK" . #x000271) ("LATIN SMALL LETTER N WITH LEFT HOOK" . #x000272) ("LATIN SMALL LETTER N WITH RETROFLEX HOOK" . #x000273) ("LATIN LETTER SMALL CAPITAL N" . #x000274) ("LATIN SMALL LETTER BARRED O" . #x000275) ("LATIN LETTER SMALL CAPITAL OE" . #x000276) ("LATIN SMALL LETTER CLOSED OMEGA" . #x000277) ("LATIN SMALL LETTER PHI" . #x000278) ("LATIN SMALL LETTER TURNED R" . #x000279) ("LATIN SMALL LETTER TURNED R WITH LONG LEG" . #x00027a) ("LATIN SMALL LETTER TURNED R WITH HOOK" . #x00027b) ("LATIN SMALL LETTER R WITH LONG LEG" . #x00027c) ("LATIN SMALL LETTER R WITH TAIL" . #x00027d) ("LATIN SMALL LETTER R WITH FISHHOOK" . #x00027e) ("LATIN SMALL LETTER REVERSED R WITH FISHHOOK" . #x00027f) ("LATIN LETTER SMALL CAPITAL R" . #x000280) ("LATIN LETTER SMALL CAPITAL INVERTED R" . #x000281) ("LATIN SMALL LETTER S WITH HOOK" . #x000282) ("LATIN SMALL LETTER ESH" . #x000283) ("LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK" . #x000284) ("LATIN SMALL LETTER SQUAT REVERSED ESH" . #x000285) ("LATIN SMALL LETTER ESH WITH CURL" . #x000286) ("LATIN SMALL LETTER TURNED T" . #x000287) ("LATIN SMALL LETTER T WITH RETROFLEX HOOK" . #x000288) ("LATIN SMALL LETTER U BAR" . #x000289) ("LATIN SMALL LETTER UPSILON" . #x00028a) ("LATIN SMALL LETTER V WITH HOOK" . #x00028b) ("LATIN SMALL LETTER TURNED V" . #x00028c) ("LATIN SMALL LETTER TURNED W" . #x00028d) ("LATIN SMALL LETTER TURNED Y" . #x00028e) ("LATIN LETTER SMALL CAPITAL Y" . #x00028f) ("LATIN SMALL LETTER Z WITH RETROFLEX HOOK" . #x000290) ("LATIN SMALL LETTER Z WITH CURL" . #x000291) ("LATIN SMALL LETTER EZH" . #x000292) ("LATIN SMALL LETTER EZH WITH CURL" . #x000293) ("LATIN LETTER GLOTTAL STOP" . #x000294) ("LATIN LETTER PHARYNGEAL VOICED FRICATIVE" . #x000295) ("LATIN LETTER INVERTED GLOTTAL STOP" . #x000296) ("LATIN LETTER STRETCHED C" . #x000297) ("LATIN LETTER BILABIAL CLICK" . #x000298) ("LATIN LETTER SMALL CAPITAL B" . #x000299) ("LATIN SMALL LETTER CLOSED OPEN E" . #x00029a) ("LATIN LETTER SMALL CAPITAL G WITH HOOK" . #x00029b) ("LATIN LETTER SMALL CAPITAL H" . #x00029c) ("LATIN SMALL LETTER J WITH CROSSED-TAIL" . #x00029d) ("LATIN SMALL LETTER TURNED K" . #x00029e) ("LATIN LETTER SMALL CAPITAL L" . #x00029f) ("LATIN SMALL LETTER Q WITH HOOK" . #x0002a0) ("LATIN LETTER GLOTTAL STOP WITH STROKE" . #x0002a1) ("LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE" . #x0002a2) ("LATIN SMALL LETTER DZ DIGRAPH" . #x0002a3) ("LATIN SMALL LETTER DEZH DIGRAPH" . #x0002a4) ("LATIN SMALL LETTER DZ DIGRAPH WITH CURL" . #x0002a5) ("LATIN SMALL LETTER TS DIGRAPH" . #x0002a6) ("LATIN SMALL LETTER TESH DIGRAPH" . #x0002a7) ("LATIN SMALL LETTER TC DIGRAPH WITH CURL" . #x0002a8) ("LATIN SMALL LETTER FENG DIGRAPH" . #x0002a9) ("LATIN SMALL LETTER LS DIGRAPH" . #x0002aa) ("LATIN SMALL LETTER LZ DIGRAPH" . #x0002ab) ("LATIN LETTER BILABIAL PERCUSSIVE" . #x0002ac) ("LATIN LETTER BIDENTAL PERCUSSIVE" . #x0002ad) ("MODIFIER LETTER SMALL H" . #x0002b0) ("MODIFIER LETTER SMALL H WITH HOOK" . #x0002b1) ("MODIFIER LETTER SMALL J" . #x0002b2) ("MODIFIER LETTER SMALL R" . #x0002b3) ("MODIFIER LETTER SMALL TURNED R" . #x0002b4) ("MODIFIER LETTER SMALL TURNED R WITH HOOK" . #x0002b5) ("MODIFIER LETTER SMALL CAPITAL INVERTED R" . #x0002b6) ("MODIFIER LETTER SMALL W" . #x0002b7) ("MODIFIER LETTER SMALL Y" . #x0002b8) ("MODIFIER LETTER PRIME" . #x0002b9) ("MODIFIER LETTER DOUBLE PRIME" . #x0002ba) ("MODIFIER LETTER TURNED COMMA" . #x0002bb) ("MODIFIER LETTER APOSTROPHE" . #x0002bc) ("MODIFIER LETTER REVERSED COMMA" . #x0002bd) ("MODIFIER LETTER RIGHT HALF RING" . #x0002be) ("MODIFIER LETTER LEFT HALF RING" . #x0002bf) ("MODIFIER LETTER GLOTTAL STOP" . #x0002c0) ("MODIFIER LETTER REVERSED GLOTTAL STOP" . #x0002c1) ("MODIFIER LETTER LEFT ARROWHEAD" . #x0002c2) ("MODIFIER LETTER RIGHT ARROWHEAD" . #x0002c3) ("MODIFIER LETTER UP ARROWHEAD" . #x0002c4) ("MODIFIER LETTER DOWN ARROWHEAD" . #x0002c5) ("MODIFIER LETTER CIRCUMFLEX ACCENT" . #x0002c6) ("CARON" . #x0002c7) ("MODIFIER LETTER VERTICAL LINE" . #x0002c8) ("MODIFIER LETTER MACRON" . #x0002c9) ("MODIFIER LETTER ACUTE ACCENT" . #x0002ca) ("MODIFIER LETTER GRAVE ACCENT" . #x0002cb) ("MODIFIER LETTER LOW VERTICAL LINE" . #x0002cc) ("MODIFIER LETTER LOW MACRON" . #x0002cd) ("MODIFIER LETTER LOW GRAVE ACCENT" . #x0002ce) ("MODIFIER LETTER LOW ACUTE ACCENT" . #x0002cf) ("MODIFIER LETTER TRIANGULAR COLON" . #x0002d0) ("MODIFIER LETTER HALF TRIANGULAR COLON" . #x0002d1) ("MODIFIER LETTER CENTRED RIGHT HALF RING" . #x0002d2) ("MODIFIER LETTER CENTRED LEFT HALF RING" . #x0002d3) ("MODIFIER LETTER UP TACK" . #x0002d4) ("MODIFIER LETTER DOWN TACK" . #x0002d5) ("MODIFIER LETTER PLUS SIGN" . #x0002d6) ("MODIFIER LETTER MINUS SIGN" . #x0002d7) ("BREVE" . #x0002d8) ("DOT ABOVE" . #x0002d9) ("RING ABOVE" . #x0002da) ("OGONEK" . #x0002db) ("SMALL TILDE" . #x0002dc) ("DOUBLE ACUTE ACCENT" . #x0002dd) ("MODIFIER LETTER RHOTIC HOOK" . #x0002de) ("MODIFIER LETTER CROSS ACCENT" . #x0002df) ("MODIFIER LETTER SMALL GAMMA" . #x0002e0) ("MODIFIER LETTER SMALL L" . #x0002e1) ("MODIFIER LETTER SMALL S" . #x0002e2) ("MODIFIER LETTER SMALL X" . #x0002e3) ("MODIFIER LETTER SMALL REVERSED GLOTTAL STOP" . #x0002e4) ("MODIFIER LETTER EXTRA-HIGH TONE BAR" . #x0002e5) ("MODIFIER LETTER HIGH TONE BAR" . #x0002e6) ("MODIFIER LETTER MID TONE BAR" . #x0002e7) ("MODIFIER LETTER LOW TONE BAR" . #x0002e8) ("MODIFIER LETTER EXTRA-LOW TONE BAR" . #x0002e9) ("MODIFIER LETTER YIN DEPARTING TONE MARK" . #x0002ea) ("MODIFIER LETTER YANG DEPARTING TONE MARK" . #x0002eb) ("MODIFIER LETTER VOICING" . #x0002ec) ("MODIFIER LETTER UNASPIRATED" . #x0002ed) ("MODIFIER LETTER DOUBLE APOSTROPHE" . #x0002ee) ("COMBINING GRAVE ACCENT" . #x000300) ("COMBINING ACUTE ACCENT" . #x000301) ("COMBINING CIRCUMFLEX ACCENT" . #x000302) ("COMBINING TILDE" . #x000303) ("COMBINING MACRON" . #x000304) ("COMBINING OVERLINE" . #x000305) ("COMBINING BREVE" . #x000306) ("COMBINING DOT ABOVE" . #x000307) ("COMBINING DIAERESIS" . #x000308) ("COMBINING HOOK ABOVE" . #x000309) ("COMBINING RING ABOVE" . #x00030a) ("COMBINING DOUBLE ACUTE ACCENT" . #x00030b) ("COMBINING CARON" . #x00030c) ("COMBINING VERTICAL LINE ABOVE" . #x00030d) ("COMBINING DOUBLE VERTICAL LINE ABOVE" . #x00030e) ("COMBINING DOUBLE GRAVE ACCENT" . #x00030f) ("COMBINING CANDRABINDU" . #x000310) ("COMBINING INVERTED BREVE" . #x000311) ("COMBINING TURNED COMMA ABOVE" . #x000312) ("COMBINING COMMA ABOVE" . #x000313) ("COMBINING REVERSED COMMA ABOVE" . #x000314) ("COMBINING COMMA ABOVE RIGHT" . #x000315) ("COMBINING GRAVE ACCENT BELOW" . #x000316) ("COMBINING ACUTE ACCENT BELOW" . #x000317) ("COMBINING LEFT TACK BELOW" . #x000318) ("COMBINING RIGHT TACK BELOW" . #x000319) ("COMBINING LEFT ANGLE ABOVE" . #x00031a) ("COMBINING HORN" . #x00031b) ("COMBINING LEFT HALF RING BELOW" . #x00031c) ("COMBINING UP TACK BELOW" . #x00031d) ("COMBINING DOWN TACK BELOW" . #x00031e) ("COMBINING PLUS SIGN BELOW" . #x00031f) ("COMBINING MINUS SIGN BELOW" . #x000320) ("COMBINING PALATALIZED HOOK BELOW" . #x000321) ("COMBINING RETROFLEX HOOK BELOW" . #x000322) ("COMBINING DOT BELOW" . #x000323) ("COMBINING DIAERESIS BELOW" . #x000324) ("COMBINING RING BELOW" . #x000325) ("COMBINING COMMA BELOW" . #x000326) ("COMBINING CEDILLA" . #x000327) ("COMBINING OGONEK" . #x000328) ("COMBINING VERTICAL LINE BELOW" . #x000329) ("COMBINING BRIDGE BELOW" . #x00032a) ("COMBINING INVERTED DOUBLE ARCH BELOW" . #x00032b) ("COMBINING CARON BELOW" . #x00032c) ("COMBINING CIRCUMFLEX ACCENT BELOW" . #x00032d) ("COMBINING BREVE BELOW" . #x00032e) ("COMBINING INVERTED BREVE BELOW" . #x00032f) ("COMBINING TILDE BELOW" . #x000330) ("COMBINING MACRON BELOW" . #x000331) ("COMBINING LOW LINE" . #x000332) ("COMBINING DOUBLE LOW LINE" . #x000333) ("COMBINING TILDE OVERLAY" . #x000334) ("COMBINING SHORT STROKE OVERLAY" . #x000335) ("COMBINING LONG STROKE OVERLAY" . #x000336) ("COMBINING SHORT SOLIDUS OVERLAY" . #x000337) ("COMBINING LONG SOLIDUS OVERLAY" . #x000338) ("COMBINING RIGHT HALF RING BELOW" . #x000339) ("COMBINING INVERTED BRIDGE BELOW" . #x00033a) ("COMBINING SQUARE BELOW" . #x00033b) ("COMBINING SEAGULL BELOW" . #x00033c) ("COMBINING X ABOVE" . #x00033d) ("COMBINING VERTICAL TILDE" . #x00033e) ("COMBINING DOUBLE OVERLINE" . #x00033f) ("COMBINING GRAVE TONE MARK" . #x000340) ("COMBINING ACUTE TONE MARK" . #x000341) ("COMBINING GREEK PERISPOMENI" . #x000342) ("COMBINING GREEK KORONIS" . #x000343) ("COMBINING GREEK DIALYTIKA TONOS" . #x000344) ("COMBINING GREEK YPOGEGRAMMENI" . #x000345) ("COMBINING BRIDGE ABOVE" . #x000346) ("COMBINING EQUALS SIGN BELOW" . #x000347) ("COMBINING DOUBLE VERTICAL LINE BELOW" . #x000348) ("COMBINING LEFT ANGLE BELOW" . #x000349) ("COMBINING NOT TILDE ABOVE" . #x00034a) ("COMBINING HOMOTHETIC ABOVE" . #x00034b) ("COMBINING ALMOST EQUAL TO ABOVE" . #x00034c) ("COMBINING LEFT RIGHT ARROW BELOW" . #x00034d) ("COMBINING UPWARDS ARROW BELOW" . #x00034e) ("COMBINING GRAPHEME JOINER" . #x00034f) ("COMBINING DOUBLE TILDE" . #x000360) ("COMBINING DOUBLE INVERTED BREVE" . #x000361) ("COMBINING DOUBLE RIGHTWARDS ARROW BELOW" . #x000362) ("COMBINING LATIN SMALL LETTER A" . #x000363) ("COMBINING LATIN SMALL LETTER E" . #x000364) ("COMBINING LATIN SMALL LETTER I" . #x000365) ("COMBINING LATIN SMALL LETTER O" . #x000366) ("COMBINING LATIN SMALL LETTER U" . #x000367) ("COMBINING LATIN SMALL LETTER C" . #x000368) ("COMBINING LATIN SMALL LETTER D" . #x000369) ("COMBINING LATIN SMALL LETTER H" . #x00036a) ("COMBINING LATIN SMALL LETTER M" . #x00036b) ("COMBINING LATIN SMALL LETTER R" . #x00036c) ("COMBINING LATIN SMALL LETTER T" . #x00036d) ("COMBINING LATIN SMALL LETTER V" . #x00036e) ("COMBINING LATIN SMALL LETTER X" . #x00036f) ("GREEK NUMERAL SIGN" . #x000374) ("GREEK LOWER NUMERAL SIGN" . #x000375) ("GREEK YPOGEGRAMMENI" . #x00037a) ("GREEK QUESTION MARK" . #x00037e) ("GREEK TONOS" . #x000384) ("GREEK DIALYTIKA TONOS" . #x000385) ("GREEK CAPITAL LETTER ALPHA WITH TONOS" . #x000386) ("GREEK ANO TELEIA" . #x000387) ("GREEK CAPITAL LETTER EPSILON WITH TONOS" . #x000388) ("GREEK CAPITAL LETTER ETA WITH TONOS" . #x000389) ("GREEK CAPITAL LETTER IOTA WITH TONOS" . #x00038a) ("GREEK CAPITAL LETTER OMICRON WITH TONOS" . #x00038c) ("GREEK CAPITAL LETTER UPSILON WITH TONOS" . #x00038e) ("GREEK CAPITAL LETTER OMEGA WITH TONOS" . #x00038f) ("GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS" . #x000390) ("GREEK CAPITAL LETTER ALPHA" . #x000391) ("GREEK CAPITAL LETTER BETA" . #x000392) ("GREEK CAPITAL LETTER GAMMA" . #x000393) ("GREEK CAPITAL LETTER DELTA" . #x000394) ("GREEK CAPITAL LETTER EPSILON" . #x000395) ("GREEK CAPITAL LETTER ZETA" . #x000396) ("GREEK CAPITAL LETTER ETA" . #x000397) ("GREEK CAPITAL LETTER THETA" . #x000398) ("GREEK CAPITAL LETTER IOTA" . #x000399) ("GREEK CAPITAL LETTER KAPPA" . #x00039a) ("GREEK CAPITAL LETTER LAMDA" . #x00039b) ("GREEK CAPITAL LETTER MU" . #x00039c) ("GREEK CAPITAL LETTER NU" . #x00039d) ("GREEK CAPITAL LETTER XI" . #x00039e) ("GREEK CAPITAL LETTER OMICRON" . #x00039f) ("GREEK CAPITAL LETTER PI" . #x0003a0) ("GREEK CAPITAL LETTER RHO" . #x0003a1) ("GREEK CAPITAL LETTER SIGMA" . #x0003a3) ("GREEK CAPITAL LETTER TAU" . #x0003a4) ("GREEK CAPITAL LETTER UPSILON" . #x0003a5) ("GREEK CAPITAL LETTER PHI" . #x0003a6) ("GREEK CAPITAL LETTER CHI" . #x0003a7) ("GREEK CAPITAL LETTER PSI" . #x0003a8) ("GREEK CAPITAL LETTER OMEGA" . #x0003a9) ("GREEK CAPITAL LETTER IOTA WITH DIALYTIKA" . #x0003aa) ("GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA" . #x0003ab) ("GREEK SMALL LETTER ALPHA WITH TONOS" . #x0003ac) ("GREEK SMALL LETTER EPSILON WITH TONOS" . #x0003ad) ("GREEK SMALL LETTER ETA WITH TONOS" . #x0003ae) ("GREEK SMALL LETTER IOTA WITH TONOS" . #x0003af) ("GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS" . #x0003b0) ("GREEK SMALL LETTER ALPHA" . #x0003b1) ("GREEK SMALL LETTER BETA" . #x0003b2) ("GREEK SMALL LETTER GAMMA" . #x0003b3) ("GREEK SMALL LETTER DELTA" . #x0003b4) ("GREEK SMALL LETTER EPSILON" . #x0003b5) ("GREEK SMALL LETTER ZETA" . #x0003b6) ("GREEK SMALL LETTER ETA" . #x0003b7) ("GREEK SMALL LETTER THETA" . #x0003b8) ("GREEK SMALL LETTER IOTA" . #x0003b9) ("GREEK SMALL LETTER KAPPA" . #x0003ba) ("GREEK SMALL LETTER LAMDA" . #x0003bb) ("GREEK SMALL LETTER MU" . #x0003bc) ("GREEK SMALL LETTER NU" . #x0003bd) ("GREEK SMALL LETTER XI" . #x0003be) ("GREEK SMALL LETTER OMICRON" . #x0003bf) ("GREEK SMALL LETTER PI" . #x0003c0) ("GREEK SMALL LETTER RHO" . #x0003c1) ("GREEK SMALL LETTER FINAL SIGMA" . #x0003c2) ("GREEK SMALL LETTER SIGMA" . #x0003c3) ("GREEK SMALL LETTER TAU" . #x0003c4) ("GREEK SMALL LETTER UPSILON" . #x0003c5) ("GREEK SMALL LETTER PHI" . #x0003c6) ("GREEK SMALL LETTER CHI" . #x0003c7) ("GREEK SMALL LETTER PSI" . #x0003c8) ("GREEK SMALL LETTER OMEGA" . #x0003c9) ("GREEK SMALL LETTER IOTA WITH DIALYTIKA" . #x0003ca) ("GREEK SMALL LETTER UPSILON WITH DIALYTIKA" . #x0003cb) ("GREEK SMALL LETTER OMICRON WITH TONOS" . #x0003cc) ("GREEK SMALL LETTER UPSILON WITH TONOS" . #x0003cd) ("GREEK SMALL LETTER OMEGA WITH TONOS" . #x0003ce) ("GREEK BETA SYMBOL" . #x0003d0) ("GREEK THETA SYMBOL" . #x0003d1) ("GREEK UPSILON WITH HOOK SYMBOL" . #x0003d2) ("GREEK UPSILON WITH ACUTE AND HOOK SYMBOL" . #x0003d3) ("GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL" . #x0003d4) ("GREEK PHI SYMBOL" . #x0003d5) ("GREEK PI SYMBOL" . #x0003d6) ("GREEK KAI SYMBOL" . #x0003d7) ("GREEK LETTER ARCHAIC KOPPA" . #x0003d8) ("GREEK SMALL LETTER ARCHAIC KOPPA" . #x0003d9) ("GREEK LETTER STIGMA" . #x0003da) ("GREEK SMALL LETTER STIGMA" . #x0003db) ("GREEK LETTER DIGAMMA" . #x0003dc) ("GREEK SMALL LETTER DIGAMMA" . #x0003dd) ("GREEK LETTER KOPPA" . #x0003de) ("GREEK SMALL LETTER KOPPA" . #x0003df) ("GREEK LETTER SAMPI" . #x0003e0) ("GREEK SMALL LETTER SAMPI" . #x0003e1) ("COPTIC CAPITAL LETTER SHEI" . #x0003e2) ("COPTIC SMALL LETTER SHEI" . #x0003e3) ("COPTIC CAPITAL LETTER FEI" . #x0003e4) ("COPTIC SMALL LETTER FEI" . #x0003e5) ("COPTIC CAPITAL LETTER KHEI" . #x0003e6) ("COPTIC SMALL LETTER KHEI" . #x0003e7) ("COPTIC CAPITAL LETTER HORI" . #x0003e8) ("COPTIC SMALL LETTER HORI" . #x0003e9) ("COPTIC CAPITAL LETTER GANGIA" . #x0003ea) ("COPTIC SMALL LETTER GANGIA" . #x0003eb) ("COPTIC CAPITAL LETTER SHIMA" . #x0003ec) ("COPTIC SMALL LETTER SHIMA" . #x0003ed) ("COPTIC CAPITAL LETTER DEI" . #x0003ee) ("COPTIC SMALL LETTER DEI" . #x0003ef) ("GREEK KAPPA SYMBOL" . #x0003f0) ("GREEK RHO SYMBOL" . #x0003f1) ("GREEK LUNATE SIGMA SYMBOL" . #x0003f2) ("GREEK LETTER YOT" . #x0003f3) ("GREEK CAPITAL THETA SYMBOL" . #x0003f4) ("GREEK LUNATE EPSILON SYMBOL" . #x0003f5) ("GREEK REVERSED LUNATE EPSILON SYMBOL" . #x0003f6) ("CYRILLIC CAPITAL LETTER IE WITH GRAVE" . #x000400) ("CYRILLIC CAPITAL LETTER IO" . #x000401) ("CYRILLIC CAPITAL LETTER DJE" . #x000402) ("CYRILLIC CAPITAL LETTER GJE" . #x000403) ("CYRILLIC CAPITAL LETTER UKRAINIAN IE" . #x000404) ("CYRILLIC CAPITAL LETTER DZE" . #x000405) ("CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I" . #x000406) ("CYRILLIC CAPITAL LETTER YI" . #x000407) ("CYRILLIC CAPITAL LETTER JE" . #x000408) ("CYRILLIC CAPITAL LETTER LJE" . #x000409) ("CYRILLIC CAPITAL LETTER NJE" . #x00040a) ("CYRILLIC CAPITAL LETTER TSHE" . #x00040b) ("CYRILLIC CAPITAL LETTER KJE" . #x00040c) ("CYRILLIC CAPITAL LETTER I WITH GRAVE" . #x00040d) ("CYRILLIC CAPITAL LETTER SHORT U" . #x00040e) ("CYRILLIC CAPITAL LETTER DZHE" . #x00040f) ("CYRILLIC CAPITAL LETTER A" . #x000410) ("CYRILLIC CAPITAL LETTER BE" . #x000411) ("CYRILLIC CAPITAL LETTER VE" . #x000412) ("CYRILLIC CAPITAL LETTER GHE" . #x000413) ("CYRILLIC CAPITAL LETTER DE" . #x000414) ("CYRILLIC CAPITAL LETTER IE" . #x000415) ("CYRILLIC CAPITAL LETTER ZHE" . #x000416) ("CYRILLIC CAPITAL LETTER ZE" . #x000417) ("CYRILLIC CAPITAL LETTER I" . #x000418) ("CYRILLIC CAPITAL LETTER SHORT I" . #x000419) ("CYRILLIC CAPITAL LETTER KA" . #x00041a) ("CYRILLIC CAPITAL LETTER EL" . #x00041b) ("CYRILLIC CAPITAL LETTER EM" . #x00041c) ("CYRILLIC CAPITAL LETTER EN" . #x00041d) ("CYRILLIC CAPITAL LETTER O" . #x00041e) ("CYRILLIC CAPITAL LETTER PE" . #x00041f) ("CYRILLIC CAPITAL LETTER ER" . #x000420) ("CYRILLIC CAPITAL LETTER ES" . #x000421) ("CYRILLIC CAPITAL LETTER TE" . #x000422) ("CYRILLIC CAPITAL LETTER U" . #x000423) ("CYRILLIC CAPITAL LETTER EF" . #x000424) ("CYRILLIC CAPITAL LETTER HA" . #x000425) ("CYRILLIC CAPITAL LETTER TSE" . #x000426) ("CYRILLIC CAPITAL LETTER CHE" . #x000427) ("CYRILLIC CAPITAL LETTER SHA" . #x000428) ("CYRILLIC CAPITAL LETTER SHCHA" . #x000429) ("CYRILLIC CAPITAL LETTER HARD SIGN" . #x00042a) ("CYRILLIC CAPITAL LETTER YERU" . #x00042b) ("CYRILLIC CAPITAL LETTER SOFT SIGN" . #x00042c) ("CYRILLIC CAPITAL LETTER E" . #x00042d) ("CYRILLIC CAPITAL LETTER YU" . #x00042e) ("CYRILLIC CAPITAL LETTER YA" . #x00042f) ("CYRILLIC SMALL LETTER A" . #x000430) ("CYRILLIC SMALL LETTER BE" . #x000431) ("CYRILLIC SMALL LETTER VE" . #x000432) ("CYRILLIC SMALL LETTER GHE" . #x000433) ("CYRILLIC SMALL LETTER DE" . #x000434) ("CYRILLIC SMALL LETTER IE" . #x000435) ("CYRILLIC SMALL LETTER ZHE" . #x000436) ("CYRILLIC SMALL LETTER ZE" . #x000437) ("CYRILLIC SMALL LETTER I" . #x000438) ("CYRILLIC SMALL LETTER SHORT I" . #x000439) ("CYRILLIC SMALL LETTER KA" . #x00043a) ("CYRILLIC SMALL LETTER EL" . #x00043b) ("CYRILLIC SMALL LETTER EM" . #x00043c) ("CYRILLIC SMALL LETTER EN" . #x00043d) ("CYRILLIC SMALL LETTER O" . #x00043e) ("CYRILLIC SMALL LETTER PE" . #x00043f) ("CYRILLIC SMALL LETTER ER" . #x000440) ("CYRILLIC SMALL LETTER ES" . #x000441) ("CYRILLIC SMALL LETTER TE" . #x000442) ("CYRILLIC SMALL LETTER U" . #x000443) ("CYRILLIC SMALL LETTER EF" . #x000444) ("CYRILLIC SMALL LETTER HA" . #x000445) ("CYRILLIC SMALL LETTER TSE" . #x000446) ("CYRILLIC SMALL LETTER CHE" . #x000447) ("CYRILLIC SMALL LETTER SHA" . #x000448) ("CYRILLIC SMALL LETTER SHCHA" . #x000449) ("CYRILLIC SMALL LETTER HARD SIGN" . #x00044a) ("CYRILLIC SMALL LETTER YERU" . #x00044b) ("CYRILLIC SMALL LETTER SOFT SIGN" . #x00044c) ("CYRILLIC SMALL LETTER E" . #x00044d) ("CYRILLIC SMALL LETTER YU" . #x00044e) ("CYRILLIC SMALL LETTER YA" . #x00044f) ("CYRILLIC SMALL LETTER IE WITH GRAVE" . #x000450) ("CYRILLIC SMALL LETTER IO" . #x000451) ("CYRILLIC SMALL LETTER DJE" . #x000452) ("CYRILLIC SMALL LETTER GJE" . #x000453) ("CYRILLIC SMALL LETTER UKRAINIAN IE" . #x000454) ("CYRILLIC SMALL LETTER DZE" . #x000455) ("CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I" . #x000456) ("CYRILLIC SMALL LETTER YI" . #x000457) ("CYRILLIC SMALL LETTER JE" . #x000458) ("CYRILLIC SMALL LETTER LJE" . #x000459) ("CYRILLIC SMALL LETTER NJE" . #x00045a) ("CYRILLIC SMALL LETTER TSHE" . #x00045b) ("CYRILLIC SMALL LETTER KJE" . #x00045c) ("CYRILLIC SMALL LETTER I WITH GRAVE" . #x00045d) ("CYRILLIC SMALL LETTER SHORT U" . #x00045e) ("CYRILLIC SMALL LETTER DZHE" . #x00045f) ("CYRILLIC CAPITAL LETTER OMEGA" . #x000460) ("CYRILLIC SMALL LETTER OMEGA" . #x000461) ("CYRILLIC CAPITAL LETTER YAT" . #x000462) ("CYRILLIC SMALL LETTER YAT" . #x000463) ("CYRILLIC CAPITAL LETTER IOTIFIED E" . #x000464) ("CYRILLIC SMALL LETTER IOTIFIED E" . #x000465) ("CYRILLIC CAPITAL LETTER LITTLE YUS" . #x000466) ("CYRILLIC SMALL LETTER LITTLE YUS" . #x000467) ("CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS" . #x000468) ("CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS" . #x000469) ("CYRILLIC CAPITAL LETTER BIG YUS" . #x00046a) ("CYRILLIC SMALL LETTER BIG YUS" . #x00046b) ("CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS" . #x00046c) ("CYRILLIC SMALL LETTER IOTIFIED BIG YUS" . #x00046d) ("CYRILLIC CAPITAL LETTER KSI" . #x00046e) ("CYRILLIC SMALL LETTER KSI" . #x00046f) ("CYRILLIC CAPITAL LETTER PSI" . #x000470) ("CYRILLIC SMALL LETTER PSI" . #x000471) ("CYRILLIC CAPITAL LETTER FITA" . #x000472) ("CYRILLIC SMALL LETTER FITA" . #x000473) ("CYRILLIC CAPITAL LETTER IZHITSA" . #x000474) ("CYRILLIC SMALL LETTER IZHITSA" . #x000475) ("CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT" . #x000476) ("CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT" . #x000477) ("CYRILLIC CAPITAL LETTER UK" . #x000478) ("CYRILLIC SMALL LETTER UK" . #x000479) ("CYRILLIC CAPITAL LETTER ROUND OMEGA" . #x00047a) ("CYRILLIC SMALL LETTER ROUND OMEGA" . #x00047b) ("CYRILLIC CAPITAL LETTER OMEGA WITH TITLO" . #x00047c) ("CYRILLIC SMALL LETTER OMEGA WITH TITLO" . #x00047d) ("CYRILLIC CAPITAL LETTER OT" . #x00047e) ("CYRILLIC SMALL LETTER OT" . #x00047f) ("CYRILLIC CAPITAL LETTER KOPPA" . #x000480) ("CYRILLIC SMALL LETTER KOPPA" . #x000481) ("CYRILLIC THOUSANDS SIGN" . #x000482) ("COMBINING CYRILLIC TITLO" . #x000483) ("COMBINING CYRILLIC PALATALIZATION" . #x000484) ("COMBINING CYRILLIC DASIA PNEUMATA" . #x000485) ("COMBINING CYRILLIC PSILI PNEUMATA" . #x000486) ("COMBINING CYRILLIC HUNDRED THOUSANDS SIGN" . #x000488) ("COMBINING CYRILLIC MILLIONS SIGN" . #x000489) ("CYRILLIC CAPITAL LETTER SHORT I WITH TAIL" . #x00048a) ("CYRILLIC SMALL LETTER SHORT I WITH TAIL" . #x00048b) ("CYRILLIC CAPITAL LETTER SEMISOFT SIGN" . #x00048c) ("CYRILLIC SMALL LETTER SEMISOFT SIGN" . #x00048d) ("CYRILLIC CAPITAL LETTER ER WITH TICK" . #x00048e) ("CYRILLIC SMALL LETTER ER WITH TICK" . #x00048f) ("CYRILLIC CAPITAL LETTER GHE WITH UPTURN" . #x000490) ("CYRILLIC SMALL LETTER GHE WITH UPTURN" . #x000491) ("CYRILLIC CAPITAL LETTER GHE WITH STROKE" . #x000492) ("CYRILLIC SMALL LETTER GHE WITH STROKE" . #x000493) ("CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK" . #x000494) ("CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK" . #x000495) ("CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER" . #x000496) ("CYRILLIC SMALL LETTER ZHE WITH DESCENDER" . #x000497) ("CYRILLIC CAPITAL LETTER ZE WITH DESCENDER" . #x000498) ("CYRILLIC SMALL LETTER ZE WITH DESCENDER" . #x000499) ("CYRILLIC CAPITAL LETTER KA WITH DESCENDER" . #x00049a) ("CYRILLIC SMALL LETTER KA WITH DESCENDER" . #x00049b) ("CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE" . #x00049c) ("CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE" . #x00049d) ("CYRILLIC CAPITAL LETTER KA WITH STROKE" . #x00049e) ("CYRILLIC SMALL LETTER KA WITH STROKE" . #x00049f) ("CYRILLIC CAPITAL LETTER BASHKIR KA" . #x0004a0) ("CYRILLIC SMALL LETTER BASHKIR KA" . #x0004a1) ("CYRILLIC CAPITAL LETTER EN WITH DESCENDER" . #x0004a2) ("CYRILLIC SMALL LETTER EN WITH DESCENDER" . #x0004a3) ("CYRILLIC CAPITAL LIGATURE EN GHE" . #x0004a4) ("CYRILLIC SMALL LIGATURE EN GHE" . #x0004a5) ("CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK" . #x0004a6) ("CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK" . #x0004a7) ("CYRILLIC CAPITAL LETTER ABKHASIAN HA" . #x0004a8) ("CYRILLIC SMALL LETTER ABKHASIAN HA" . #x0004a9) ("CYRILLIC CAPITAL LETTER ES WITH DESCENDER" . #x0004aa) ("CYRILLIC SMALL LETTER ES WITH DESCENDER" . #x0004ab) ("CYRILLIC CAPITAL LETTER TE WITH DESCENDER" . #x0004ac) ("CYRILLIC SMALL LETTER TE WITH DESCENDER" . #x0004ad) ("CYRILLIC CAPITAL LETTER STRAIGHT U" . #x0004ae) ("CYRILLIC SMALL LETTER STRAIGHT U" . #x0004af) ("CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE" . #x0004b0) ("CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE" . #x0004b1) ("CYRILLIC CAPITAL LETTER HA WITH DESCENDER" . #x0004b2) ("CYRILLIC SMALL LETTER HA WITH DESCENDER" . #x0004b3) ("CYRILLIC CAPITAL LIGATURE TE TSE" . #x0004b4) ("CYRILLIC SMALL LIGATURE TE TSE" . #x0004b5) ("CYRILLIC CAPITAL LETTER CHE WITH DESCENDER" . #x0004b6) ("CYRILLIC SMALL LETTER CHE WITH DESCENDER" . #x0004b7) ("CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE" . #x0004b8) ("CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE" . #x0004b9) ("CYRILLIC CAPITAL LETTER SHHA" . #x0004ba) ("CYRILLIC SMALL LETTER SHHA" . #x0004bb) ("CYRILLIC CAPITAL LETTER ABKHASIAN CHE" . #x0004bc) ("CYRILLIC SMALL LETTER ABKHASIAN CHE" . #x0004bd) ("CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER" . #x0004be) ("CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER" . #x0004bf) ("CYRILLIC LETTER PALOCHKA" . #x0004c0) ("CYRILLIC CAPITAL LETTER ZHE WITH BREVE" . #x0004c1) ("CYRILLIC SMALL LETTER ZHE WITH BREVE" . #x0004c2) ("CYRILLIC CAPITAL LETTER KA WITH HOOK" . #x0004c3) ("CYRILLIC SMALL LETTER KA WITH HOOK" . #x0004c4) ("CYRILLIC CAPITAL LETTER EL WITH TAIL" . #x0004c5) ("CYRILLIC SMALL LETTER EL WITH TAIL" . #x0004c6) ("CYRILLIC CAPITAL LETTER EN WITH HOOK" . #x0004c7) ("CYRILLIC SMALL LETTER EN WITH HOOK" . #x0004c8) ("CYRILLIC CAPITAL LETTER EN WITH TAIL" . #x0004c9) ("CYRILLIC SMALL LETTER EN WITH TAIL" . #x0004ca) ("CYRILLIC CAPITAL LETTER KHAKASSIAN CHE" . #x0004cb) ("CYRILLIC SMALL LETTER KHAKASSIAN CHE" . #x0004cc) ("CYRILLIC CAPITAL LETTER EM WITH TAIL" . #x0004cd) ("CYRILLIC SMALL LETTER EM WITH TAIL" . #x0004ce) ("CYRILLIC CAPITAL LETTER A WITH BREVE" . #x0004d0) ("CYRILLIC SMALL LETTER A WITH BREVE" . #x0004d1) ("CYRILLIC CAPITAL LETTER A WITH DIAERESIS" . #x0004d2) ("CYRILLIC SMALL LETTER A WITH DIAERESIS" . #x0004d3) ("CYRILLIC CAPITAL LIGATURE A IE" . #x0004d4) ("CYRILLIC SMALL LIGATURE A IE" . #x0004d5) ("CYRILLIC CAPITAL LETTER IE WITH BREVE" . #x0004d6) ("CYRILLIC SMALL LETTER IE WITH BREVE" . #x0004d7) ("CYRILLIC CAPITAL LETTER SCHWA" . #x0004d8) ("CYRILLIC SMALL LETTER SCHWA" . #x0004d9) ("CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS" . #x0004da) ("CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS" . #x0004db) ("CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS" . #x0004dc) ("CYRILLIC SMALL LETTER ZHE WITH DIAERESIS" . #x0004dd) ("CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS" . #x0004de) ("CYRILLIC SMALL LETTER ZE WITH DIAERESIS" . #x0004df) ("CYRILLIC CAPITAL LETTER ABKHASIAN DZE" . #x0004e0) ("CYRILLIC SMALL LETTER ABKHASIAN DZE" . #x0004e1) ("CYRILLIC CAPITAL LETTER I WITH MACRON" . #x0004e2) ("CYRILLIC SMALL LETTER I WITH MACRON" . #x0004e3) ("CYRILLIC CAPITAL LETTER I WITH DIAERESIS" . #x0004e4) ("CYRILLIC SMALL LETTER I WITH DIAERESIS" . #x0004e5) ("CYRILLIC CAPITAL LETTER O WITH DIAERESIS" . #x0004e6) ("CYRILLIC SMALL LETTER O WITH DIAERESIS" . #x0004e7) ("CYRILLIC CAPITAL LETTER BARRED O" . #x0004e8) ("CYRILLIC SMALL LETTER BARRED O" . #x0004e9) ("CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS" . #x0004ea) ("CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS" . #x0004eb) ("CYRILLIC CAPITAL LETTER E WITH DIAERESIS" . #x0004ec) ("CYRILLIC SMALL LETTER E WITH DIAERESIS" . #x0004ed) ("CYRILLIC CAPITAL LETTER U WITH MACRON" . #x0004ee) ("CYRILLIC SMALL LETTER U WITH MACRON" . #x0004ef) ("CYRILLIC CAPITAL LETTER U WITH DIAERESIS" . #x0004f0) ("CYRILLIC SMALL LETTER U WITH DIAERESIS" . #x0004f1) ("CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE" . #x0004f2) ("CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE" . #x0004f3) ("CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS" . #x0004f4) ("CYRILLIC SMALL LETTER CHE WITH DIAERESIS" . #x0004f5) ("CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS" . #x0004f8) ("CYRILLIC SMALL LETTER YERU WITH DIAERESIS" . #x0004f9) ("EN QUAD" . #x002000) ("EM QUAD" . #x002001) ("EN SPACE" . #x002002) ("EM SPACE" . #x002003) ("THREE-PER-EM SPACE" . #x002004) ("FOUR-PER-EM SPACE" . #x002005) ("SIX-PER-EM SPACE" . #x002006) ("FIGURE SPACE" . #x002007) ("PUNCTUATION SPACE" . #x002008) ("THIN SPACE" . #x002009) ("HAIR SPACE" . #x00200a) ("ZERO WIDTH SPACE" . #x00200b) ("ZERO WIDTH NON-JOINER" . #x00200c) ("ZERO WIDTH JOINER" . #x00200d) ("LEFT-TO-RIGHT MARK" . #x00200e) ("RIGHT-TO-LEFT MARK" . #x00200f) ("HYPHEN" . #x002010) ("NON-BREAKING HYPHEN" . #x002011) ("FIGURE DASH" . #x002012) ("EN DASH" . #x002013) ("EM DASH" . #x002014) ("HORIZONTAL BAR" . #x002015) ("DOUBLE VERTICAL LINE" . #x002016) ("DOUBLE LOW LINE" . #x002017) ("LEFT SINGLE QUOTATION MARK" . #x002018) ("RIGHT SINGLE QUOTATION MARK" . #x002019) ("SINGLE LOW-9 QUOTATION MARK" . #x00201a) ("SINGLE HIGH-REVERSED-9 QUOTATION MARK" . #x00201b) ("LEFT DOUBLE QUOTATION MARK" . #x00201c) ("RIGHT DOUBLE QUOTATION MARK" . #x00201d) ("DOUBLE LOW-9 QUOTATION MARK" . #x00201e) ("DOUBLE HIGH-REVERSED-9 QUOTATION MARK" . #x00201f) ("DAGGER" . #x002020) ("DOUBLE DAGGER" . #x002021) ("BULLET" . #x002022) ("TRIANGULAR BULLET" . #x002023) ("ONE DOT LEADER" . #x002024) ("TWO DOT LEADER" . #x002025) ("HORIZONTAL ELLIPSIS" . #x002026) ("HYPHENATION POINT" . #x002027) ("LINE SEPARATOR" . #x002028) ("PARAGRAPH SEPARATOR" . #x002029) ("LEFT-TO-RIGHT EMBEDDING" . #x00202a) ("RIGHT-TO-LEFT EMBEDDING" . #x00202b) ("POP DIRECTIONAL FORMATTING" . #x00202c) ("LEFT-TO-RIGHT OVERRIDE" . #x00202d) ("RIGHT-TO-LEFT OVERRIDE" . #x00202e) ("NARROW NO-BREAK SPACE" . #x00202f) ("PER MILLE SIGN" . #x002030) ("PER TEN THOUSAND SIGN" . #x002031) ("PRIME" . #x002032) ("DOUBLE PRIME" . #x002033) ("TRIPLE PRIME" . #x002034) ("REVERSED PRIME" . #x002035) ("REVERSED DOUBLE PRIME" . #x002036) ("REVERSED TRIPLE PRIME" . #x002037) ("CARET" . #x002038) ("SINGLE LEFT-POINTING ANGLE QUOTATION MARK" . #x002039) ("SINGLE RIGHT-POINTING ANGLE QUOTATION MARK" . #x00203a) ("REFERENCE MARK" . #x00203b) ("DOUBLE EXCLAMATION MARK" . #x00203c) ("INTERROBANG" . #x00203d) ("OVERLINE" . #x00203e) ("UNDERTIE" . #x00203f) ("CHARACTER TIE" . #x002040) ("CARET INSERTION POINT" . #x002041) ("ASTERISM" . #x002042) ("HYPHEN BULLET" . #x002043) ("FRACTION SLASH" . #x002044) ("LEFT SQUARE BRACKET WITH QUILL" . #x002045) ("RIGHT SQUARE BRACKET WITH QUILL" . #x002046) ("DOUBLE QUESTION MARK" . #x002047) ("QUESTION EXCLAMATION MARK" . #x002048) ("EXCLAMATION QUESTION MARK" . #x002049) ("TIRONIAN SIGN ET" . #x00204a) ("REVERSED PILCROW SIGN" . #x00204b) ("BLACK LEFTWARDS BULLET" . #x00204c) ("BLACK RIGHTWARDS BULLET" . #x00204d) ("LOW ASTERISK" . #x00204e) ("REVERSED SEMICOLON" . #x00204f) ("CLOSE UP" . #x002050) ("TWO ASTERISKS ALIGNED VERTICALLY" . #x002051) ("COMMERCIAL MINUS SIGN" . #x002052) ("QUADRUPLE PRIME" . #x002057) ("MEDIUM MATHEMATICAL SPACE" . #x00205f) ("WORD JOINER" . #x002060) ("FUNCTION APPLICATION" . #x002061) ("INVISIBLE TIMES" . #x002062) ("INVISIBLE SEPARATOR" . #x002063) ("INHIBIT SYMMETRIC SWAPPING" . #x00206a) ("ACTIVATE SYMMETRIC SWAPPING" . #x00206b) ("INHIBIT ARABIC FORM SHAPING" . #x00206c) ("ACTIVATE ARABIC FORM SHAPING" . #x00206d) ("NATIONAL DIGIT SHAPES" . #x00206e) ("NOMINAL DIGIT SHAPES" . #x00206f) ("SUPERSCRIPT ZERO" . #x002070) ("SUPERSCRIPT LATIN SMALL LETTER I" . #x002071) ("SUPERSCRIPT FOUR" . #x002074) ("SUPERSCRIPT FIVE" . #x002075) ("SUPERSCRIPT SIX" . #x002076) ("SUPERSCRIPT SEVEN" . #x002077) ("SUPERSCRIPT EIGHT" . #x002078) ("SUPERSCRIPT NINE" . #x002079) ("SUPERSCRIPT PLUS SIGN" . #x00207a) ("SUPERSCRIPT MINUS" . #x00207b) ("SUPERSCRIPT EQUALS SIGN" . #x00207c) ("SUPERSCRIPT LEFT PARENTHESIS" . #x00207d) ("SUPERSCRIPT RIGHT PARENTHESIS" . #x00207e) ("SUPERSCRIPT LATIN SMALL LETTER N" . #x00207f) ("SUBSCRIPT ZERO" . #x002080) ("SUBSCRIPT ONE" . #x002081) ("SUBSCRIPT TWO" . #x002082) ("SUBSCRIPT THREE" . #x002083) ("SUBSCRIPT FOUR" . #x002084) ("SUBSCRIPT FIVE" . #x002085) ("SUBSCRIPT SIX" . #x002086) ("SUBSCRIPT SEVEN" . #x002087) ("SUBSCRIPT EIGHT" . #x002088) ("SUBSCRIPT NINE" . #x002089) ("SUBSCRIPT PLUS SIGN" . #x00208a) ("SUBSCRIPT MINUS" . #x00208b) ("SUBSCRIPT EQUALS SIGN" . #x00208c) ("SUBSCRIPT LEFT PARENTHESIS" . #x00208d) ("SUBSCRIPT RIGHT PARENTHESIS" . #x00208e) ("EURO-CURRENCY SIGN" . #x0020a0) ("COLON SIGN" . #x0020a1) ("CRUZEIRO SIGN" . #x0020a2) ("FRENCH FRANC SIGN" . #x0020a3) ("LIRA SIGN" . #x0020a4) ("MILL SIGN" . #x0020a5) ("NAIRA SIGN" . #x0020a6) ("PESETA SIGN" . #x0020a7) ("RUPEE SIGN" . #x0020a8) ("WON SIGN" . #x0020a9) ("NEW SHEQEL SIGN" . #x0020aa) ("DONG SIGN" . #x0020ab) ("EURO SIGN" . #x0020ac) ("KIP SIGN" . #x0020ad) ("TUGRIK SIGN" . #x0020ae) ("DRACHMA SIGN" . #x0020af) ("GERMAN PENNY SIGN" . #x0020b0) ("PESO SIGN" . #x0020b1) ("COMBINING LEFT HARPOON ABOVE" . #x0020d0) ("COMBINING RIGHT HARPOON ABOVE" . #x0020d1) ("COMBINING LONG VERTICAL LINE OVERLAY" . #x0020d2) ("COMBINING SHORT VERTICAL LINE OVERLAY" . #x0020d3) ("COMBINING ANTICLOCKWISE ARROW ABOVE" . #x0020d4) ("COMBINING CLOCKWISE ARROW ABOVE" . #x0020d5) ("COMBINING LEFT ARROW ABOVE" . #x0020d6) ("COMBINING RIGHT ARROW ABOVE" . #x0020d7) ("COMBINING RING OVERLAY" . #x0020d8) ("COMBINING CLOCKWISE RING OVERLAY" . #x0020d9) ("COMBINING ANTICLOCKWISE RING OVERLAY" . #x0020da) ("COMBINING THREE DOTS ABOVE" . #x0020db) ("COMBINING FOUR DOTS ABOVE" . #x0020dc) ("COMBINING ENCLOSING CIRCLE" . #x0020dd) ("COMBINING ENCLOSING SQUARE" . #x0020de) ("COMBINING ENCLOSING DIAMOND" . #x0020df) ("COMBINING ENCLOSING CIRCLE BACKSLASH" . #x0020e0) ("COMBINING LEFT RIGHT ARROW ABOVE" . #x0020e1) ("COMBINING ENCLOSING SCREEN" . #x0020e2) ("COMBINING ENCLOSING KEYCAP" . #x0020e3) ("COMBINING ENCLOSING UPWARD POINTING TRIANGLE" . #x0020e4) ("COMBINING REVERSE SOLIDUS OVERLAY" . #x0020e5) ("COMBINING DOUBLE VERTICAL STROKE OVERLAY" . #x0020e6) ("COMBINING ANNUITY SYMBOL" . #x0020e7) ("COMBINING TRIPLE UNDERDOT" . #x0020e8) ("COMBINING WIDE BRIDGE ABOVE" . #x0020e9) ("COMBINING LEFTWARDS ARROW OVERLAY" . #x0020ea) ("ACCOUNT OF" . #x002100) ("ADDRESSED TO THE SUBJECT" . #x002101) ("DOUBLE-STRUCK CAPITAL C" . #x002102) ("DEGREE CELSIUS" . #x002103) ("CENTRE LINE SYMBOL" . #x002104) ("CARE OF" . #x002105) ("CADA UNA" . #x002106) ("EULER CONSTANT" . #x002107) ("SCRUPLE" . #x002108) ("DEGREE FAHRENHEIT" . #x002109) ("SCRIPT SMALL G" . #x00210a) ("SCRIPT CAPITAL H" . #x00210b) ("BLACK-LETTER CAPITAL H" . #x00210c) ("DOUBLE-STRUCK CAPITAL H" . #x00210d) ("PLANCK CONSTANT" . #x00210e) ("PLANCK CONSTANT OVER TWO PI" . #x00210f) ("SCRIPT CAPITAL I" . #x002110) ("BLACK-LETTER CAPITAL I" . #x002111) ("SCRIPT CAPITAL L" . #x002112) ("SCRIPT SMALL L" . #x002113) ("L B BAR SYMBOL" . #x002114) ("DOUBLE-STRUCK CAPITAL N" . #x002115) ("NUMERO SIGN" . #x002116) ("SOUND RECORDING COPYRIGHT" . #x002117) ("SCRIPT CAPITAL P" . #x002118) ("DOUBLE-STRUCK CAPITAL P" . #x002119) ("DOUBLE-STRUCK CAPITAL Q" . #x00211a) ("SCRIPT CAPITAL R" . #x00211b) ("BLACK-LETTER CAPITAL R" . #x00211c) ("DOUBLE-STRUCK CAPITAL R" . #x00211d) ("PRESCRIPTION TAKE" . #x00211e) ("RESPONSE" . #x00211f) ("SERVICE MARK" . #x002120) ("TELEPHONE SIGN" . #x002121) ("TRADE MARK SIGN" . #x002122) ("VERSICLE" . #x002123) ("DOUBLE-STRUCK CAPITAL Z" . #x002124) ("OUNCE SIGN" . #x002125) ("OHM SIGN" . #x002126) ("INVERTED OHM SIGN" . #x002127) ("BLACK-LETTER CAPITAL Z" . #x002128) ("TURNED GREEK SMALL LETTER IOTA" . #x002129) ("KELVIN SIGN" . #x00212a) ("ANGSTROM SIGN" . #x00212b) ("SCRIPT CAPITAL B" . #x00212c) ("BLACK-LETTER CAPITAL C" . #x00212d) ("ESTIMATED SYMBOL" . #x00212e) ("SCRIPT SMALL E" . #x00212f) ("SCRIPT CAPITAL E" . #x002130) ("SCRIPT CAPITAL F" . #x002131) ("TURNED CAPITAL F" . #x002132) ("SCRIPT CAPITAL M" . #x002133) ("SCRIPT SMALL O" . #x002134) ("ALEF SYMBOL" . #x002135) ("BET SYMBOL" . #x002136) ("GIMEL SYMBOL" . #x002137) ("DALET SYMBOL" . #x002138) ("INFORMATION SOURCE" . #x002139) ("ROTATED CAPITAL Q" . #x00213a) ("DOUBLE-STRUCK SMALL GAMMA" . #x00213d) ("DOUBLE-STRUCK CAPITAL GAMMA" . #x00213e) ("DOUBLE-STRUCK CAPITAL PI" . #x00213f) ("DOUBLE-STRUCK N-ARY SUMMATION" . #x002140) ("TURNED SANS-SERIF CAPITAL G" . #x002141) ("TURNED SANS-SERIF CAPITAL L" . #x002142) ("REVERSED SANS-SERIF CAPITAL L" . #x002143) ("TURNED SANS-SERIF CAPITAL Y" . #x002144) ("DOUBLE-STRUCK ITALIC CAPITAL D" . #x002145) ("DOUBLE-STRUCK ITALIC SMALL D" . #x002146) ("DOUBLE-STRUCK ITALIC SMALL E" . #x002147) ("DOUBLE-STRUCK ITALIC SMALL I" . #x002148) ("DOUBLE-STRUCK ITALIC SMALL J" . #x002149) ("PROPERTY LINE" . #x00214a) ("TURNED AMPERSAND" . #x00214b) ("VULGAR FRACTION ONE THIRD" . #x002153) ("VULGAR FRACTION TWO THIRDS" . #x002154) ("VULGAR FRACTION ONE FIFTH" . #x002155) ("VULGAR FRACTION TWO FIFTHS" . #x002156) ("VULGAR FRACTION THREE FIFTHS" . #x002157) ("VULGAR FRACTION FOUR FIFTHS" . #x002158) ("VULGAR FRACTION ONE SIXTH" . #x002159) ("VULGAR FRACTION FIVE SIXTHS" . #x00215a) ("VULGAR FRACTION ONE EIGHTH" . #x00215b) ("VULGAR FRACTION THREE EIGHTHS" . #x00215c) ("VULGAR FRACTION FIVE EIGHTHS" . #x00215d) ("VULGAR FRACTION SEVEN EIGHTHS" . #x00215e) ("FRACTION NUMERATOR ONE" . #x00215f) ("ROMAN NUMERAL ONE" . #x002160) ("ROMAN NUMERAL TWO" . #x002161) ("ROMAN NUMERAL THREE" . #x002162) ("ROMAN NUMERAL FOUR" . #x002163) ("ROMAN NUMERAL FIVE" . #x002164) ("ROMAN NUMERAL SIX" . #x002165) ("ROMAN NUMERAL SEVEN" . #x002166) ("ROMAN NUMERAL EIGHT" . #x002167) ("ROMAN NUMERAL NINE" . #x002168) ("ROMAN NUMERAL TEN" . #x002169) ("ROMAN NUMERAL ELEVEN" . #x00216a) ("ROMAN NUMERAL TWELVE" . #x00216b) ("ROMAN NUMERAL FIFTY" . #x00216c) ("ROMAN NUMERAL ONE HUNDRED" . #x00216d) ("ROMAN NUMERAL FIVE HUNDRED" . #x00216e) ("ROMAN NUMERAL ONE THOUSAND" . #x00216f) ("SMALL ROMAN NUMERAL ONE" . #x002170) ("SMALL ROMAN NUMERAL TWO" . #x002171) ("SMALL ROMAN NUMERAL THREE" . #x002172) ("SMALL ROMAN NUMERAL FOUR" . #x002173) ("SMALL ROMAN NUMERAL FIVE" . #x002174) ("SMALL ROMAN NUMERAL SIX" . #x002175) ("SMALL ROMAN NUMERAL SEVEN" . #x002176) ("SMALL ROMAN NUMERAL EIGHT" . #x002177) ("SMALL ROMAN NUMERAL NINE" . #x002178) ("SMALL ROMAN NUMERAL TEN" . #x002179) ("SMALL ROMAN NUMERAL ELEVEN" . #x00217a) ("SMALL ROMAN NUMERAL TWELVE" . #x00217b) ("SMALL ROMAN NUMERAL FIFTY" . #x00217c) ("SMALL ROMAN NUMERAL ONE HUNDRED" . #x00217d) ("SMALL ROMAN NUMERAL FIVE HUNDRED" . #x00217e) ("SMALL ROMAN NUMERAL ONE THOUSAND" . #x00217f) ("ROMAN NUMERAL ONE THOUSAND C D" . #x002180) ("ROMAN NUMERAL FIVE THOUSAND" . #x002181) ("ROMAN NUMERAL TEN THOUSAND" . #x002182) ("ROMAN NUMERAL REVERSED ONE HUNDRED" . #x002183) ("LEFTWARDS ARROW" . #x002190) ("UPWARDS ARROW" . #x002191) ("RIGHTWARDS ARROW" . #x002192) ("DOWNWARDS ARROW" . #x002193) ("LEFT RIGHT ARROW" . #x002194) ("UP DOWN ARROW" . #x002195) ("NORTH WEST ARROW" . #x002196) ("NORTH EAST ARROW" . #x002197) ("SOUTH EAST ARROW" . #x002198) ("SOUTH WEST ARROW" . #x002199) ("LEFTWARDS ARROW WITH STROKE" . #x00219a) ("RIGHTWARDS ARROW WITH STROKE" . #x00219b) ("LEFTWARDS WAVE ARROW" . #x00219c) ("RIGHTWARDS WAVE ARROW" . #x00219d) ("LEFTWARDS TWO HEADED ARROW" . #x00219e) ("UPWARDS TWO HEADED ARROW" . #x00219f) ("RIGHTWARDS TWO HEADED ARROW" . #x0021a0) ("DOWNWARDS TWO HEADED ARROW" . #x0021a1) ("LEFTWARDS ARROW WITH TAIL" . #x0021a2) ("RIGHTWARDS ARROW WITH TAIL" . #x0021a3) ("LEFTWARDS ARROW FROM BAR" . #x0021a4) ("UPWARDS ARROW FROM BAR" . #x0021a5) ("RIGHTWARDS ARROW FROM BAR" . #x0021a6) ("DOWNWARDS ARROW FROM BAR" . #x0021a7) ("UP DOWN ARROW WITH BASE" . #x0021a8) ("LEFTWARDS ARROW WITH HOOK" . #x0021a9) ("RIGHTWARDS ARROW WITH HOOK" . #x0021aa) ("LEFTWARDS ARROW WITH LOOP" . #x0021ab) ("RIGHTWARDS ARROW WITH LOOP" . #x0021ac) ("LEFT RIGHT WAVE ARROW" . #x0021ad) ("LEFT RIGHT ARROW WITH STROKE" . #x0021ae) ("DOWNWARDS ZIGZAG ARROW" . #x0021af) ("UPWARDS ARROW WITH TIP LEFTWARDS" . #x0021b0) ("UPWARDS ARROW WITH TIP RIGHTWARDS" . #x0021b1) ("DOWNWARDS ARROW WITH TIP LEFTWARDS" . #x0021b2) ("DOWNWARDS ARROW WITH TIP RIGHTWARDS" . #x0021b3) ("RIGHTWARDS ARROW WITH CORNER DOWNWARDS" . #x0021b4) ("DOWNWARDS ARROW WITH CORNER LEFTWARDS" . #x0021b5) ("ANTICLOCKWISE TOP SEMICIRCLE ARROW" . #x0021b6) ("CLOCKWISE TOP SEMICIRCLE ARROW" . #x0021b7) ("NORTH WEST ARROW TO LONG BAR" . #x0021b8) ("LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR" . #x0021b9) ("ANTICLOCKWISE OPEN CIRCLE ARROW" . #x0021ba) ("CLOCKWISE OPEN CIRCLE ARROW" . #x0021bb) ("LEFTWARDS HARPOON WITH BARB UPWARDS" . #x0021bc) ("LEFTWARDS HARPOON WITH BARB DOWNWARDS" . #x0021bd) ("UPWARDS HARPOON WITH BARB RIGHTWARDS" . #x0021be) ("UPWARDS HARPOON WITH BARB LEFTWARDS" . #x0021bf) ("RIGHTWARDS HARPOON WITH BARB UPWARDS" . #x0021c0) ("RIGHTWARDS HARPOON WITH BARB DOWNWARDS" . #x0021c1) ("DOWNWARDS HARPOON WITH BARB RIGHTWARDS" . #x0021c2) ("DOWNWARDS HARPOON WITH BARB LEFTWARDS" . #x0021c3) ("RIGHTWARDS ARROW OVER LEFTWARDS ARROW" . #x0021c4) ("UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW" . #x0021c5) ("LEFTWARDS ARROW OVER RIGHTWARDS ARROW" . #x0021c6) ("LEFTWARDS PAIRED ARROWS" . #x0021c7) ("UPWARDS PAIRED ARROWS" . #x0021c8) ("RIGHTWARDS PAIRED ARROWS" . #x0021c9) ("DOWNWARDS PAIRED ARROWS" . #x0021ca) ("LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON" . #x0021cb) ("RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON" . #x0021cc) ("LEFTWARDS DOUBLE ARROW WITH STROKE" . #x0021cd) ("LEFT RIGHT DOUBLE ARROW WITH STROKE" . #x0021ce) ("RIGHTWARDS DOUBLE ARROW WITH STROKE" . #x0021cf) ("LEFTWARDS DOUBLE ARROW" . #x0021d0) ("UPWARDS DOUBLE ARROW" . #x0021d1) ("RIGHTWARDS DOUBLE ARROW" . #x0021d2) ("DOWNWARDS DOUBLE ARROW" . #x0021d3) ("LEFT RIGHT DOUBLE ARROW" . #x0021d4) ("UP DOWN DOUBLE ARROW" . #x0021d5) ("NORTH WEST DOUBLE ARROW" . #x0021d6) ("NORTH EAST DOUBLE ARROW" . #x0021d7) ("SOUTH EAST DOUBLE ARROW" . #x0021d8) ("SOUTH WEST DOUBLE ARROW" . #x0021d9) ("LEFTWARDS TRIPLE ARROW" . #x0021da) ("RIGHTWARDS TRIPLE ARROW" . #x0021db) ("LEFTWARDS SQUIGGLE ARROW" . #x0021dc) ("RIGHTWARDS SQUIGGLE ARROW" . #x0021dd) ("UPWARDS ARROW WITH DOUBLE STROKE" . #x0021de) ("DOWNWARDS ARROW WITH DOUBLE STROKE" . #x0021df) ("LEFTWARDS DASHED ARROW" . #x0021e0) ("UPWARDS DASHED ARROW" . #x0021e1) ("RIGHTWARDS DASHED ARROW" . #x0021e2) ("DOWNWARDS DASHED ARROW" . #x0021e3) ("LEFTWARDS ARROW TO BAR" . #x0021e4) ("RIGHTWARDS ARROW TO BAR" . #x0021e5) ("LEFTWARDS WHITE ARROW" . #x0021e6) ("UPWARDS WHITE ARROW" . #x0021e7) ("RIGHTWARDS WHITE ARROW" . #x0021e8) ("DOWNWARDS WHITE ARROW" . #x0021e9) ("UPWARDS WHITE ARROW FROM BAR" . #x0021ea) ("UPWARDS WHITE ARROW ON PEDESTAL" . #x0021eb) ("UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR" . #x0021ec) ("UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR" . #x0021ed) ("UPWARDS WHITE DOUBLE ARROW" . #x0021ee) ("UPWARDS WHITE DOUBLE ARROW ON PEDESTAL" . #x0021ef) ("RIGHTWARDS WHITE ARROW FROM WALL" . #x0021f0) ("NORTH WEST ARROW TO CORNER" . #x0021f1) ("SOUTH EAST ARROW TO CORNER" . #x0021f2) ("UP DOWN WHITE ARROW" . #x0021f3) ("RIGHT ARROW WITH SMALL CIRCLE" . #x0021f4) ("DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW" . #x0021f5) ("THREE RIGHTWARDS ARROWS" . #x0021f6) ("LEFTWARDS ARROW WITH VERTICAL STROKE" . #x0021f7) ("RIGHTWARDS ARROW WITH VERTICAL STROKE" . #x0021f8) ("LEFT RIGHT ARROW WITH VERTICAL STROKE" . #x0021f9) ("LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE" . #x0021fa) ("RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE" . #x0021fb) ("LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE" . #x0021fc) ("LEFTWARDS OPEN-HEADED ARROW" . #x0021fd) ("RIGHTWARDS OPEN-HEADED ARROW" . #x0021fe) ("LEFT RIGHT OPEN-HEADED ARROW" . #x0021ff) ("FOR ALL" . #x002200) ("COMPLEMENT" . #x002201) ("PARTIAL DIFFERENTIAL" . #x002202) ("THERE EXISTS" . #x002203) ("THERE DOES NOT EXIST" . #x002204) ("EMPTY SET" . #x002205) ("INCREMENT" . #x002206) ("NABLA" . #x002207) ("ELEMENT OF" . #x002208) ("NOT AN ELEMENT OF" . #x002209) ("SMALL ELEMENT OF" . #x00220a) ("CONTAINS AS MEMBER" . #x00220b) ("DOES NOT CONTAIN AS MEMBER" . #x00220c) ("SMALL CONTAINS AS MEMBER" . #x00220d) ("END OF PROOF" . #x00220e) ("N-ARY PRODUCT" . #x00220f) ("N-ARY COPRODUCT" . #x002210) ("N-ARY SUMMATION" . #x002211) ("MINUS SIGN" . #x002212) ("MINUS-OR-PLUS SIGN" . #x002213) ("DOT PLUS" . #x002214) ("DIVISION SLASH" . #x002215) ("SET MINUS" . #x002216) ("ASTERISK OPERATOR" . #x002217) ("RING OPERATOR" . #x002218) ("BULLET OPERATOR" . #x002219) ("SQUARE ROOT" . #x00221a) ("CUBE ROOT" . #x00221b) ("FOURTH ROOT" . #x00221c) ("PROPORTIONAL TO" . #x00221d) ("INFINITY" . #x00221e) ("RIGHT ANGLE" . #x00221f) ("ANGLE" . #x002220) ("MEASURED ANGLE" . #x002221) ("SPHERICAL ANGLE" . #x002222) ("DIVIDES" . #x002223) ("DOES NOT DIVIDE" . #x002224) ("PARALLEL TO" . #x002225) ("NOT PARALLEL TO" . #x002226) ("LOGICAL AND" . #x002227) ("LOGICAL OR" . #x002228) ("INTERSECTION" . #x002229) ("UNION" . #x00222a) ("INTEGRAL" . #x00222b) ("DOUBLE INTEGRAL" . #x00222c) ("TRIPLE INTEGRAL" . #x00222d) ("CONTOUR INTEGRAL" . #x00222e) ("SURFACE INTEGRAL" . #x00222f) ("VOLUME INTEGRAL" . #x002230) ("CLOCKWISE INTEGRAL" . #x002231) ("CLOCKWISE CONTOUR INTEGRAL" . #x002232) ("ANTICLOCKWISE CONTOUR INTEGRAL" . #x002233) ("THEREFORE" . #x002234) ("BECAUSE" . #x002235) ("RATIO" . #x002236) ("PROPORTION" . #x002237) ("DOT MINUS" . #x002238) ("EXCESS" . #x002239) ("GEOMETRIC PROPORTION" . #x00223a) ("HOMOTHETIC" . #x00223b) ("TILDE OPERATOR" . #x00223c) ("REVERSED TILDE" . #x00223d) ("INVERTED LAZY S" . #x00223e) ("SINE WAVE" . #x00223f) ("WREATH PRODUCT" . #x002240) ("NOT TILDE" . #x002241) ("MINUS TILDE" . #x002242) ("ASYMPTOTICALLY EQUAL TO" . #x002243) ("NOT ASYMPTOTICALLY EQUAL TO" . #x002244) ("APPROXIMATELY EQUAL TO" . #x002245) ("APPROXIMATELY BUT NOT ACTUALLY EQUAL TO" . #x002246) ("NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO" . #x002247) ("ALMOST EQUAL TO" . #x002248) ("NOT ALMOST EQUAL TO" . #x002249) ("ALMOST EQUAL OR EQUAL TO" . #x00224a) ("TRIPLE TILDE" . #x00224b) ("ALL EQUAL TO" . #x00224c) ("EQUIVALENT TO" . #x00224d) ("GEOMETRICALLY EQUIVALENT TO" . #x00224e) ("DIFFERENCE BETWEEN" . #x00224f) ("APPROACHES THE LIMIT" . #x002250) ("GEOMETRICALLY EQUAL TO" . #x002251) ("APPROXIMATELY EQUAL TO OR THE IMAGE OF" . #x002252) ("IMAGE OF OR APPROXIMATELY EQUAL TO" . #x002253) ("COLON EQUALS" . #x002254) ("EQUALS COLON" . #x002255) ("RING IN EQUAL TO" . #x002256) ("RING EQUAL TO" . #x002257) ("CORRESPONDS TO" . #x002258) ("ESTIMATES" . #x002259) ("EQUIANGULAR TO" . #x00225a) ("STAR EQUALS" . #x00225b) ("DELTA EQUAL TO" . #x00225c) ("EQUAL TO BY DEFINITION" . #x00225d) ("MEASURED BY" . #x00225e) ("QUESTIONED EQUAL TO" . #x00225f) ("NOT EQUAL TO" . #x002260) ("IDENTICAL TO" . #x002261) ("NOT IDENTICAL TO" . #x002262) ("STRICTLY EQUIVALENT TO" . #x002263) ("LESS-THAN OR EQUAL TO" . #x002264) ("GREATER-THAN OR EQUAL TO" . #x002265) ("LESS-THAN OVER EQUAL TO" . #x002266) ("GREATER-THAN OVER EQUAL TO" . #x002267) ("LESS-THAN BUT NOT EQUAL TO" . #x002268) ("GREATER-THAN BUT NOT EQUAL TO" . #x002269) ("MUCH LESS-THAN" . #x00226a) ("MUCH GREATER-THAN" . #x00226b) ("BETWEEN" . #x00226c) ("NOT EQUIVALENT TO" . #x00226d) ("NOT LESS-THAN" . #x00226e) ("NOT GREATER-THAN" . #x00226f) ("NEITHER LESS-THAN NOR EQUAL TO" . #x002270) ("NEITHER GREATER-THAN NOR EQUAL TO" . #x002271) ("LESS-THAN OR EQUIVALENT TO" . #x002272) ("GREATER-THAN OR EQUIVALENT TO" . #x002273) ("NEITHER LESS-THAN NOR EQUIVALENT TO" . #x002274) ("NEITHER GREATER-THAN NOR EQUIVALENT TO" . #x002275) ("LESS-THAN OR GREATER-THAN" . #x002276) ("GREATER-THAN OR LESS-THAN" . #x002277) ("NEITHER LESS-THAN NOR GREATER-THAN" . #x002278) ("NEITHER GREATER-THAN NOR LESS-THAN" . #x002279) ("PRECEDES" . #x00227a) ("SUCCEEDS" . #x00227b) ("PRECEDES OR EQUAL TO" . #x00227c) ("SUCCEEDS OR EQUAL TO" . #x00227d) ("PRECEDES OR EQUIVALENT TO" . #x00227e) ("SUCCEEDS OR EQUIVALENT TO" . #x00227f) ("DOES NOT PRECEDE" . #x002280) ("DOES NOT SUCCEED" . #x002281) ("SUBSET OF" . #x002282) ("SUPERSET OF" . #x002283) ("NOT A SUBSET OF" . #x002284) ("NOT A SUPERSET OF" . #x002285) ("SUBSET OF OR EQUAL TO" . #x002286) ("SUPERSET OF OR EQUAL TO" . #x002287) ("NEITHER A SUBSET OF NOR EQUAL TO" . #x002288) ("NEITHER A SUPERSET OF NOR EQUAL TO" . #x002289) ("SUBSET OF WITH NOT EQUAL TO" . #x00228a) ("SUPERSET OF WITH NOT EQUAL TO" . #x00228b) ("MULTISET" . #x00228c) ("MULTISET MULTIPLICATION" . #x00228d) ("MULTISET UNION" . #x00228e) ("SQUARE IMAGE OF" . #x00228f) ("SQUARE ORIGINAL OF" . #x002290) ("SQUARE IMAGE OF OR EQUAL TO" . #x002291) ("SQUARE ORIGINAL OF OR EQUAL TO" . #x002292) ("SQUARE CAP" . #x002293) ("SQUARE CUP" . #x002294) ("CIRCLED PLUS" . #x002295) ("CIRCLED MINUS" . #x002296) ("CIRCLED TIMES" . #x002297) ("CIRCLED DIVISION SLASH" . #x002298) ("CIRCLED DOT OPERATOR" . #x002299) ("CIRCLED RING OPERATOR" . #x00229a) ("CIRCLED ASTERISK OPERATOR" . #x00229b) ("CIRCLED EQUALS" . #x00229c) ("CIRCLED DASH" . #x00229d) ("SQUARED PLUS" . #x00229e) ("SQUARED MINUS" . #x00229f) ("SQUARED TIMES" . #x0022a0) ("SQUARED DOT OPERATOR" . #x0022a1) ("RIGHT TACK" . #x0022a2) ("LEFT TACK" . #x0022a3) ("DOWN TACK" . #x0022a4) ("UP TACK" . #x0022a5) ("ASSERTION" . #x0022a6) ("MODELS" . #x0022a7) ("TRUE" . #x0022a8) ("FORCES" . #x0022a9) ("TRIPLE VERTICAL BAR RIGHT TURNSTILE" . #x0022aa) ("DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE" . #x0022ab) ("DOES NOT PROVE" . #x0022ac) ("NOT TRUE" . #x0022ad) ("DOES NOT FORCE" . #x0022ae) ("NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE" . #x0022af) ("PRECEDES UNDER RELATION" . #x0022b0) ("SUCCEEDS UNDER RELATION" . #x0022b1) ("NORMAL SUBGROUP OF" . #x0022b2) ("CONTAINS AS NORMAL SUBGROUP" . #x0022b3) ("NORMAL SUBGROUP OF OR EQUAL TO" . #x0022b4) ("CONTAINS AS NORMAL SUBGROUP OR EQUAL TO" . #x0022b5) ("ORIGINAL OF" . #x0022b6) ("IMAGE OF" . #x0022b7) ("MULTIMAP" . #x0022b8) ("HERMITIAN CONJUGATE MATRIX" . #x0022b9) ("INTERCALATE" . #x0022ba) ("XOR" . #x0022bb) ("NAND" . #x0022bc) ("NOR" . #x0022bd) ("RIGHT ANGLE WITH ARC" . #x0022be) ("RIGHT TRIANGLE" . #x0022bf) ("N-ARY LOGICAL AND" . #x0022c0) ("N-ARY LOGICAL OR" . #x0022c1) ("N-ARY INTERSECTION" . #x0022c2) ("N-ARY UNION" . #x0022c3) ("DIAMOND OPERATOR" . #x0022c4) ("DOT OPERATOR" . #x0022c5) ("STAR OPERATOR" . #x0022c6) ("DIVISION TIMES" . #x0022c7) ("BOWTIE" . #x0022c8) ("LEFT NORMAL FACTOR SEMIDIRECT PRODUCT" . #x0022c9) ("RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT" . #x0022ca) ("LEFT SEMIDIRECT PRODUCT" . #x0022cb) ("RIGHT SEMIDIRECT PRODUCT" . #x0022cc) ("REVERSED TILDE EQUALS" . #x0022cd) ("CURLY LOGICAL OR" . #x0022ce) ("CURLY LOGICAL AND" . #x0022cf) ("DOUBLE SUBSET" . #x0022d0) ("DOUBLE SUPERSET" . #x0022d1) ("DOUBLE INTERSECTION" . #x0022d2) ("DOUBLE UNION" . #x0022d3) ("PITCHFORK" . #x0022d4) ("EQUAL AND PARALLEL TO" . #x0022d5) ("LESS-THAN WITH DOT" . #x0022d6) ("GREATER-THAN WITH DOT" . #x0022d7) ("VERY MUCH LESS-THAN" . #x0022d8) ("VERY MUCH GREATER-THAN" . #x0022d9) ("LESS-THAN EQUAL TO OR GREATER-THAN" . #x0022da) ("GREATER-THAN EQUAL TO OR LESS-THAN" . #x0022db) ("EQUAL TO OR LESS-THAN" . #x0022dc) ("EQUAL TO OR GREATER-THAN" . #x0022dd) ("EQUAL TO OR PRECEDES" . #x0022de) ("EQUAL TO OR SUCCEEDS" . #x0022df) ("DOES NOT PRECEDE OR EQUAL" . #x0022e0) ("DOES NOT SUCCEED OR EQUAL" . #x0022e1) ("NOT SQUARE IMAGE OF OR EQUAL TO" . #x0022e2) ("NOT SQUARE ORIGINAL OF OR EQUAL TO" . #x0022e3) ("SQUARE IMAGE OF OR NOT EQUAL TO" . #x0022e4) ("SQUARE ORIGINAL OF OR NOT EQUAL TO" . #x0022e5) ("LESS-THAN BUT NOT EQUIVALENT TO" . #x0022e6) ("GREATER-THAN BUT NOT EQUIVALENT TO" . #x0022e7) ("PRECEDES BUT NOT EQUIVALENT TO" . #x0022e8) ("SUCCEEDS BUT NOT EQUIVALENT TO" . #x0022e9) ("NOT NORMAL SUBGROUP OF" . #x0022ea) ("DOES NOT CONTAIN AS NORMAL SUBGROUP" . #x0022eb) ("NOT NORMAL SUBGROUP OF OR EQUAL TO" . #x0022ec) ("DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL" . #x0022ed) ("VERTICAL ELLIPSIS" . #x0022ee) ("MIDLINE HORIZONTAL ELLIPSIS" . #x0022ef) ("UP RIGHT DIAGONAL ELLIPSIS" . #x0022f0) ("DOWN RIGHT DIAGONAL ELLIPSIS" . #x0022f1) ("ELEMENT OF WITH LONG HORIZONTAL STROKE" . #x0022f2) ("ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE" . #x0022f3) ("SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE" . #x0022f4) ("ELEMENT OF WITH DOT ABOVE" . #x0022f5) ("ELEMENT OF WITH OVERBAR" . #x0022f6) ("SMALL ELEMENT OF WITH OVERBAR" . #x0022f7) ("ELEMENT OF WITH UNDERBAR" . #x0022f8) ("ELEMENT OF WITH TWO HORIZONTAL STROKES" . #x0022f9) ("CONTAINS WITH LONG HORIZONTAL STROKE" . #x0022fa) ("CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE" . #x0022fb) ("SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE" . #x0022fc) ("CONTAINS WITH OVERBAR" . #x0022fd) ("SMALL CONTAINS WITH OVERBAR" . #x0022fe) ("Z NOTATION BAG MEMBERSHIP" . #x0022ff) ("DIAMETER SIGN" . #x002300) ("ELECTRIC ARROW" . #x002301) ("HOUSE" . #x002302) ("UP ARROWHEAD" . #x002303) ("DOWN ARROWHEAD" . #x002304) ("PROJECTIVE" . #x002305) ("PERSPECTIVE" . #x002306) ("WAVY LINE" . #x002307) ("LEFT CEILING" . #x002308) ("RIGHT CEILING" . #x002309) ("LEFT FLOOR" . #x00230a) ("RIGHT FLOOR" . #x00230b) ("BOTTOM RIGHT CROP" . #x00230c) ("BOTTOM LEFT CROP" . #x00230d) ("TOP RIGHT CROP" . #x00230e) ("TOP LEFT CROP" . #x00230f) ("REVERSED NOT SIGN" . #x002310) ("SQUARE LOZENGE" . #x002311) ("ARC" . #x002312) ("SEGMENT" . #x002313) ("SECTOR" . #x002314) ("TELEPHONE RECORDER" . #x002315) ("POSITION INDICATOR" . #x002316) ("VIEWDATA SQUARE" . #x002317) ("PLACE OF INTEREST SIGN" . #x002318) ("TURNED NOT SIGN" . #x002319) ("WATCH" . #x00231a) ("HOURGLASS" . #x00231b) ("TOP LEFT CORNER" . #x00231c) ("TOP RIGHT CORNER" . #x00231d) ("BOTTOM LEFT CORNER" . #x00231e) ("BOTTOM RIGHT CORNER" . #x00231f) ("TOP HALF INTEGRAL" . #x002320) ("BOTTOM HALF INTEGRAL" . #x002321) ("FROWN" . #x002322) ("SMILE" . #x002323) ("UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS" . #x002324) ("OPTION KEY" . #x002325) ("ERASE TO THE RIGHT" . #x002326) ("X IN A RECTANGLE BOX" . #x002327) ("KEYBOARD" . #x002328) ("LEFT-POINTING ANGLE BRACKET" . #x002329) ("RIGHT-POINTING ANGLE BRACKET" . #x00232a) ("ERASE TO THE LEFT" . #x00232b) ("BENZENE RING" . #x00232c) ("CYLINDRICITY" . #x00232d) ("ALL AROUND-PROFILE" . #x00232e) ("SYMMETRY" . #x00232f) ("TOTAL RUNOUT" . #x002330) ("DIMENSION ORIGIN" . #x002331) ("CONICAL TAPER" . #x002332) ("SLOPE" . #x002333) ("COUNTERBORE" . #x002334) ("COUNTERSINK" . #x002335) ("APL FUNCTIONAL SYMBOL I-BEAM" . #x002336) ("APL FUNCTIONAL SYMBOL SQUISH QUAD" . #x002337) ("APL FUNCTIONAL SYMBOL QUAD EQUAL" . #x002338) ("APL FUNCTIONAL SYMBOL QUAD DIVIDE" . #x002339) ("APL FUNCTIONAL SYMBOL QUAD DIAMOND" . #x00233a) ("APL FUNCTIONAL SYMBOL QUAD JOT" . #x00233b) ("APL FUNCTIONAL SYMBOL QUAD CIRCLE" . #x00233c) ("APL FUNCTIONAL SYMBOL CIRCLE STILE" . #x00233d) ("APL FUNCTIONAL SYMBOL CIRCLE JOT" . #x00233e) ("APL FUNCTIONAL SYMBOL SLASH BAR" . #x00233f) ("APL FUNCTIONAL SYMBOL BACKSLASH BAR" . #x002340) ("APL FUNCTIONAL SYMBOL QUAD SLASH" . #x002341) ("APL FUNCTIONAL SYMBOL QUAD BACKSLASH" . #x002342) ("APL FUNCTIONAL SYMBOL QUAD LESS-THAN" . #x002343) ("APL FUNCTIONAL SYMBOL QUAD GREATER-THAN" . #x002344) ("APL FUNCTIONAL SYMBOL LEFTWARDS VANE" . #x002345) ("APL FUNCTIONAL SYMBOL RIGHTWARDS VANE" . #x002346) ("APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW" . #x002347) ("APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW" . #x002348) ("APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH" . #x002349) ("APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR" . #x00234a) ("APL FUNCTIONAL SYMBOL DELTA STILE" . #x00234b) ("APL FUNCTIONAL SYMBOL QUAD DOWN CARET" . #x00234c) ("APL FUNCTIONAL SYMBOL QUAD DELTA" . #x00234d) ("APL FUNCTIONAL SYMBOL DOWN TACK JOT" . #x00234e) ("APL FUNCTIONAL SYMBOL UPWARDS VANE" . #x00234f) ("APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW" . #x002350) ("APL FUNCTIONAL SYMBOL UP TACK OVERBAR" . #x002351) ("APL FUNCTIONAL SYMBOL DEL STILE" . #x002352) ("APL FUNCTIONAL SYMBOL QUAD UP CARET" . #x002353) ("APL FUNCTIONAL SYMBOL QUAD DEL" . #x002354) ("APL FUNCTIONAL SYMBOL UP TACK JOT" . #x002355) ("APL FUNCTIONAL SYMBOL DOWNWARDS VANE" . #x002356) ("APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW" . #x002357) ("APL FUNCTIONAL SYMBOL QUOTE UNDERBAR" . #x002358) ("APL FUNCTIONAL SYMBOL DELTA UNDERBAR" . #x002359) ("APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR" . #x00235a) ("APL FUNCTIONAL SYMBOL JOT UNDERBAR" . #x00235b) ("APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR" . #x00235c) ("APL FUNCTIONAL SYMBOL UP SHOE JOT" . #x00235d) ("APL FUNCTIONAL SYMBOL QUOTE QUAD" . #x00235e) ("APL FUNCTIONAL SYMBOL CIRCLE STAR" . #x00235f) ("APL FUNCTIONAL SYMBOL QUAD COLON" . #x002360) ("APL FUNCTIONAL SYMBOL UP TACK DIAERESIS" . #x002361) ("APL FUNCTIONAL SYMBOL DEL DIAERESIS" . #x002362) ("APL FUNCTIONAL SYMBOL STAR DIAERESIS" . #x002363) ("APL FUNCTIONAL SYMBOL JOT DIAERESIS" . #x002364) ("APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS" . #x002365) ("APL FUNCTIONAL SYMBOL DOWN SHOE STILE" . #x002366) ("APL FUNCTIONAL SYMBOL LEFT SHOE STILE" . #x002367) ("APL FUNCTIONAL SYMBOL TILDE DIAERESIS" . #x002368) ("APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS" . #x002369) ("APL FUNCTIONAL SYMBOL COMMA BAR" . #x00236a) ("APL FUNCTIONAL SYMBOL DEL TILDE" . #x00236b) ("APL FUNCTIONAL SYMBOL ZILDE" . #x00236c) ("APL FUNCTIONAL SYMBOL STILE TILDE" . #x00236d) ("APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR" . #x00236e) ("APL FUNCTIONAL SYMBOL QUAD NOT EQUAL" . #x00236f) ("APL FUNCTIONAL SYMBOL QUAD QUESTION" . #x002370) ("APL FUNCTIONAL SYMBOL DOWN CARET TILDE" . #x002371) ("APL FUNCTIONAL SYMBOL UP CARET TILDE" . #x002372) ("APL FUNCTIONAL SYMBOL IOTA" . #x002373) ("APL FUNCTIONAL SYMBOL RHO" . #x002374) ("APL FUNCTIONAL SYMBOL OMEGA" . #x002375) ("APL FUNCTIONAL SYMBOL ALPHA UNDERBAR" . #x002376) ("APL FUNCTIONAL SYMBOL EPSILON UNDERBAR" . #x002377) ("APL FUNCTIONAL SYMBOL IOTA UNDERBAR" . #x002378) ("APL FUNCTIONAL SYMBOL OMEGA UNDERBAR" . #x002379) ("APL FUNCTIONAL SYMBOL ALPHA" . #x00237a) ("NOT CHECK MARK" . #x00237b) ("RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW" . #x00237c) ("SHOULDERED OPEN BOX" . #x00237d) ("BELL SYMBOL" . #x00237e) ("VERTICAL LINE WITH MIDDLE DOT" . #x00237f) ("INSERTION SYMBOL" . #x002380) ("CONTINUOUS UNDERLINE SYMBOL" . #x002381) ("DISCONTINUOUS UNDERLINE SYMBOL" . #x002382) ("EMPHASIS SYMBOL" . #x002383) ("COMPOSITION SYMBOL" . #x002384) ("WHITE SQUARE WITH CENTRE VERTICAL LINE" . #x002385) ("ENTER SYMBOL" . #x002386) ("ALTERNATIVE KEY SYMBOL" . #x002387) ("HELM SYMBOL" . #x002388) ("CIRCLED HORIZONTAL BAR WITH NOTCH" . #x002389) ("CIRCLED TRIANGLE DOWN" . #x00238a) ("BROKEN CIRCLE WITH NORTHWEST ARROW" . #x00238b) ("UNDO SYMBOL" . #x00238c) ("MONOSTABLE SYMBOL" . #x00238d) ("HYSTERESIS SYMBOL" . #x00238e) ("OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL" . #x00238f) ("OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL" . #x002390) ("PASSIVE-PULL-DOWN-OUTPUT SYMBOL" . #x002391) ("PASSIVE-PULL-UP-OUTPUT SYMBOL" . #x002392) ("DIRECT CURRENT SYMBOL FORM TWO" . #x002393) ("SOFTWARE-FUNCTION SYMBOL" . #x002394) ("APL FUNCTIONAL SYMBOL QUAD" . #x002395) ("DECIMAL SEPARATOR KEY SYMBOL" . #x002396) ("PREVIOUS PAGE" . #x002397) ("NEXT PAGE" . #x002398) ("PRINT SCREEN SYMBOL" . #x002399) ("CLEAR SCREEN SYMBOL" . #x00239a) ("LEFT PARENTHESIS UPPER HOOK" . #x00239b) ("LEFT PARENTHESIS EXTENSION" . #x00239c) ("LEFT PARENTHESIS LOWER HOOK" . #x00239d) ("RIGHT PARENTHESIS UPPER HOOK" . #x00239e) ("RIGHT PARENTHESIS EXTENSION" . #x00239f) ("RIGHT PARENTHESIS LOWER HOOK" . #x0023a0) ("LEFT SQUARE BRACKET UPPER CORNER" . #x0023a1) ("LEFT SQUARE BRACKET EXTENSION" . #x0023a2) ("LEFT SQUARE BRACKET LOWER CORNER" . #x0023a3) ("RIGHT SQUARE BRACKET UPPER CORNER" . #x0023a4) ("RIGHT SQUARE BRACKET EXTENSION" . #x0023a5) ("RIGHT SQUARE BRACKET LOWER CORNER" . #x0023a6) ("LEFT CURLY BRACKET UPPER HOOK" . #x0023a7) ("LEFT CURLY BRACKET MIDDLE PIECE" . #x0023a8) ("LEFT CURLY BRACKET LOWER HOOK" . #x0023a9) ("CURLY BRACKET EXTENSION" . #x0023aa) ("RIGHT CURLY BRACKET UPPER HOOK" . #x0023ab) ("RIGHT CURLY BRACKET MIDDLE PIECE" . #x0023ac) ("RIGHT CURLY BRACKET LOWER HOOK" . #x0023ad) ("INTEGRAL EXTENSION" . #x0023ae) ("HORIZONTAL LINE EXTENSION" . #x0023af) ("UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION" . #x0023b0) ("UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION" . #x0023b1) ("SUMMATION TOP" . #x0023b2) ("SUMMATION BOTTOM" . #x0023b3) ("TOP SQUARE BRACKET" . #x0023b4) ("BOTTOM SQUARE BRACKET" . #x0023b5) ("BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET" . #x0023b6) ("RADICAL SYMBOL BOTTOM" . #x0023b7) ("LEFT VERTICAL BOX LINE" . #x0023b8) ("RIGHT VERTICAL BOX LINE" . #x0023b9) ("HORIZONTAL SCAN LINE-1" . #x0023ba) ("HORIZONTAL SCAN LINE-3" . #x0023bb) ("HORIZONTAL SCAN LINE-7" . #x0023bc) ("HORIZONTAL SCAN LINE-9" . #x0023bd) ("DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT" . #x0023be) ("DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT" . #x0023bf) ("DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE" . #x0023c0) ("DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE" . #x0023c1) ("DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE" . #x0023c2) ("DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE" . #x0023c3) ("DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE" . #x0023c4) ("DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE" . #x0023c5) ("DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE" . #x0023c6) ("DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE" . #x0023c7) ("DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE" . #x0023c8) ("DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL" . #x0023c9) ("DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL" . #x0023ca) ("DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT" . #x0023cb) ("DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT" . #x0023cc) ("SQUARE FOOT" . #x0023cd) ("RETURN SYMBOL" . #x0023ce) ("SYMBOL FOR NULL" . #x002400) ("SYMBOL FOR START OF HEADING" . #x002401) ("SYMBOL FOR START OF TEXT" . #x002402) ("SYMBOL FOR END OF TEXT" . #x002403) ("SYMBOL FOR END OF TRANSMISSION" . #x002404) ("SYMBOL FOR ENQUIRY" . #x002405) ("SYMBOL FOR ACKNOWLEDGE" . #x002406) ("SYMBOL FOR BELL" . #x002407) ("SYMBOL FOR BACKSPACE" . #x002408) ("SYMBOL FOR HORIZONTAL TABULATION" . #x002409) ("SYMBOL FOR LINE FEED" . #x00240a) ("SYMBOL FOR VERTICAL TABULATION" . #x00240b) ("SYMBOL FOR FORM FEED" . #x00240c) ("SYMBOL FOR CARRIAGE RETURN" . #x00240d) ("SYMBOL FOR SHIFT OUT" . #x00240e) ("SYMBOL FOR SHIFT IN" . #x00240f) ("SYMBOL FOR DATA LINK ESCAPE" . #x002410) ("SYMBOL FOR DEVICE CONTROL ONE" . #x002411) ("SYMBOL FOR DEVICE CONTROL TWO" . #x002412) ("SYMBOL FOR DEVICE CONTROL THREE" . #x002413) ("SYMBOL FOR DEVICE CONTROL FOUR" . #x002414) ("SYMBOL FOR NEGATIVE ACKNOWLEDGE" . #x002415) ("SYMBOL FOR SYNCHRONOUS IDLE" . #x002416) ("SYMBOL FOR END OF TRANSMISSION BLOCK" . #x002417) ("SYMBOL FOR CANCEL" . #x002418) ("SYMBOL FOR END OF MEDIUM" . #x002419) ("SYMBOL FOR SUBSTITUTE" . #x00241a) ("SYMBOL FOR ESCAPE" . #x00241b) ("SYMBOL FOR FILE SEPARATOR" . #x00241c) ("SYMBOL FOR GROUP SEPARATOR" . #x00241d) ("SYMBOL FOR RECORD SEPARATOR" . #x00241e) ("SYMBOL FOR UNIT SEPARATOR" . #x00241f) ("SYMBOL FOR SPACE" . #x002420) ("SYMBOL FOR DELETE" . #x002421) ("BLANK SYMBOL" . #x002422) ("OPEN BOX" . #x002423) ("SYMBOL FOR NEWLINE" . #x002424) ("SYMBOL FOR DELETE FORM TWO" . #x002425) ("SYMBOL FOR SUBSTITUTE FORM TWO" . #x002426) ("OCR HOOK" . #x002440) ("OCR CHAIR" . #x002441) ("OCR FORK" . #x002442) ("OCR INVERTED FORK" . #x002443) ("OCR BELT BUCKLE" . #x002444) ("OCR BOW TIE" . #x002445) ("OCR BRANCH BANK IDENTIFICATION" . #x002446) ("OCR AMOUNT OF CHECK" . #x002447) ("OCR DASH" . #x002448) ("OCR CUSTOMER ACCOUNT NUMBER" . #x002449) ("OCR DOUBLE BACKSLASH" . #x00244a) ("CIRCLED DIGIT ONE" . #x002460) ("CIRCLED DIGIT TWO" . #x002461) ("CIRCLED DIGIT THREE" . #x002462) ("CIRCLED DIGIT FOUR" . #x002463) ("CIRCLED DIGIT FIVE" . #x002464) ("CIRCLED DIGIT SIX" . #x002465) ("CIRCLED DIGIT SEVEN" . #x002466) ("CIRCLED DIGIT EIGHT" . #x002467) ("CIRCLED DIGIT NINE" . #x002468) ("CIRCLED NUMBER TEN" . #x002469) ("CIRCLED NUMBER ELEVEN" . #x00246a) ("CIRCLED NUMBER TWELVE" . #x00246b) ("CIRCLED NUMBER THIRTEEN" . #x00246c) ("CIRCLED NUMBER FOURTEEN" . #x00246d) ("CIRCLED NUMBER FIFTEEN" . #x00246e) ("CIRCLED NUMBER SIXTEEN" . #x00246f) ("CIRCLED NUMBER SEVENTEEN" . #x002470) ("CIRCLED NUMBER EIGHTEEN" . #x002471) ("CIRCLED NUMBER NINETEEN" . #x002472) ("CIRCLED NUMBER TWENTY" . #x002473) ("PARENTHESIZED DIGIT ONE" . #x002474) ("PARENTHESIZED DIGIT TWO" . #x002475) ("PARENTHESIZED DIGIT THREE" . #x002476) ("PARENTHESIZED DIGIT FOUR" . #x002477) ("PARENTHESIZED DIGIT FIVE" . #x002478) ("PARENTHESIZED DIGIT SIX" . #x002479) ("PARENTHESIZED DIGIT SEVEN" . #x00247a) ("PARENTHESIZED DIGIT EIGHT" . #x00247b) ("PARENTHESIZED DIGIT NINE" . #x00247c) ("PARENTHESIZED NUMBER TEN" . #x00247d) ("PARENTHESIZED NUMBER ELEVEN" . #x00247e) ("PARENTHESIZED NUMBER TWELVE" . #x00247f) ("PARENTHESIZED NUMBER THIRTEEN" . #x002480) ("PARENTHESIZED NUMBER FOURTEEN" . #x002481) ("PARENTHESIZED NUMBER FIFTEEN" . #x002482) ("PARENTHESIZED NUMBER SIXTEEN" . #x002483) ("PARENTHESIZED NUMBER SEVENTEEN" . #x002484) ("PARENTHESIZED NUMBER EIGHTEEN" . #x002485) ("PARENTHESIZED NUMBER NINETEEN" . #x002486) ("PARENTHESIZED NUMBER TWENTY" . #x002487) ("DIGIT ONE FULL STOP" . #x002488) ("DIGIT TWO FULL STOP" . #x002489) ("DIGIT THREE FULL STOP" . #x00248a) ("DIGIT FOUR FULL STOP" . #x00248b) ("DIGIT FIVE FULL STOP" . #x00248c) ("DIGIT SIX FULL STOP" . #x00248d) ("DIGIT SEVEN FULL STOP" . #x00248e) ("DIGIT EIGHT FULL STOP" . #x00248f) ("DIGIT NINE FULL STOP" . #x002490) ("NUMBER TEN FULL STOP" . #x002491) ("NUMBER ELEVEN FULL STOP" . #x002492) ("NUMBER TWELVE FULL STOP" . #x002493) ("NUMBER THIRTEEN FULL STOP" . #x002494) ("NUMBER FOURTEEN FULL STOP" . #x002495) ("NUMBER FIFTEEN FULL STOP" . #x002496) ("NUMBER SIXTEEN FULL STOP" . #x002497) ("NUMBER SEVENTEEN FULL STOP" . #x002498) ("NUMBER EIGHTEEN FULL STOP" . #x002499) ("NUMBER NINETEEN FULL STOP" . #x00249a) ("NUMBER TWENTY FULL STOP" . #x00249b) ("PARENTHESIZED LATIN SMALL LETTER A" . #x00249c) ("PARENTHESIZED LATIN SMALL LETTER B" . #x00249d) ("PARENTHESIZED LATIN SMALL LETTER C" . #x00249e) ("PARENTHESIZED LATIN SMALL LETTER D" . #x00249f) ("PARENTHESIZED LATIN SMALL LETTER E" . #x0024a0) ("PARENTHESIZED LATIN SMALL LETTER F" . #x0024a1) ("PARENTHESIZED LATIN SMALL LETTER G" . #x0024a2) ("PARENTHESIZED LATIN SMALL LETTER H" . #x0024a3) ("PARENTHESIZED LATIN SMALL LETTER I" . #x0024a4) ("PARENTHESIZED LATIN SMALL LETTER J" . #x0024a5) ("PARENTHESIZED LATIN SMALL LETTER K" . #x0024a6) ("PARENTHESIZED LATIN SMALL LETTER L" . #x0024a7) ("PARENTHESIZED LATIN SMALL LETTER M" . #x0024a8) ("PARENTHESIZED LATIN SMALL LETTER N" . #x0024a9) ("PARENTHESIZED LATIN SMALL LETTER O" . #x0024aa) ("PARENTHESIZED LATIN SMALL LETTER P" . #x0024ab) ("PARENTHESIZED LATIN SMALL LETTER Q" . #x0024ac) ("PARENTHESIZED LATIN SMALL LETTER R" . #x0024ad) ("PARENTHESIZED LATIN SMALL LETTER S" . #x0024ae) ("PARENTHESIZED LATIN SMALL LETTER T" . #x0024af) ("PARENTHESIZED LATIN SMALL LETTER U" . #x0024b0) ("PARENTHESIZED LATIN SMALL LETTER V" . #x0024b1) ("PARENTHESIZED LATIN SMALL LETTER W" . #x0024b2) ("PARENTHESIZED LATIN SMALL LETTER X" . #x0024b3) ("PARENTHESIZED LATIN SMALL LETTER Y" . #x0024b4) ("PARENTHESIZED LATIN SMALL LETTER Z" . #x0024b5) ("CIRCLED LATIN CAPITAL LETTER A" . #x0024b6) ("CIRCLED LATIN CAPITAL LETTER B" . #x0024b7) ("CIRCLED LATIN CAPITAL LETTER C" . #x0024b8) ("CIRCLED LATIN CAPITAL LETTER D" . #x0024b9) ("CIRCLED LATIN CAPITAL LETTER E" . #x0024ba) ("CIRCLED LATIN CAPITAL LETTER F" . #x0024bb) ("CIRCLED LATIN CAPITAL LETTER G" . #x0024bc) ("CIRCLED LATIN CAPITAL LETTER H" . #x0024bd) ("CIRCLED LATIN CAPITAL LETTER I" . #x0024be) ("CIRCLED LATIN CAPITAL LETTER J" . #x0024bf) ("CIRCLED LATIN CAPITAL LETTER K" . #x0024c0) ("CIRCLED LATIN CAPITAL LETTER L" . #x0024c1) ("CIRCLED LATIN CAPITAL LETTER M" . #x0024c2) ("CIRCLED LATIN CAPITAL LETTER N" . #x0024c3) ("CIRCLED LATIN CAPITAL LETTER O" . #x0024c4) ("CIRCLED LATIN CAPITAL LETTER P" . #x0024c5) ("CIRCLED LATIN CAPITAL LETTER Q" . #x0024c6) ("CIRCLED LATIN CAPITAL LETTER R" . #x0024c7) ("CIRCLED LATIN CAPITAL LETTER S" . #x0024c8) ("CIRCLED LATIN CAPITAL LETTER T" . #x0024c9) ("CIRCLED LATIN CAPITAL LETTER U" . #x0024ca) ("CIRCLED LATIN CAPITAL LETTER V" . #x0024cb) ("CIRCLED LATIN CAPITAL LETTER W" . #x0024cc) ("CIRCLED LATIN CAPITAL LETTER X" . #x0024cd) ("CIRCLED LATIN CAPITAL LETTER Y" . #x0024ce) ("CIRCLED LATIN CAPITAL LETTER Z" . #x0024cf) ("CIRCLED LATIN SMALL LETTER A" . #x0024d0) ("CIRCLED LATIN SMALL LETTER B" . #x0024d1) ("CIRCLED LATIN SMALL LETTER C" . #x0024d2) ("CIRCLED LATIN SMALL LETTER D" . #x0024d3) ("CIRCLED LATIN SMALL LETTER E" . #x0024d4) ("CIRCLED LATIN SMALL LETTER F" . #x0024d5) ("CIRCLED LATIN SMALL LETTER G" . #x0024d6) ("CIRCLED LATIN SMALL LETTER H" . #x0024d7) ("CIRCLED LATIN SMALL LETTER I" . #x0024d8) ("CIRCLED LATIN SMALL LETTER J" . #x0024d9) ("CIRCLED LATIN SMALL LETTER K" . #x0024da) ("CIRCLED LATIN SMALL LETTER L" . #x0024db) ("CIRCLED LATIN SMALL LETTER M" . #x0024dc) ("CIRCLED LATIN SMALL LETTER N" . #x0024dd) ("CIRCLED LATIN SMALL LETTER O" . #x0024de) ("CIRCLED LATIN SMALL LETTER P" . #x0024df) ("CIRCLED LATIN SMALL LETTER Q" . #x0024e0) ("CIRCLED LATIN SMALL LETTER R" . #x0024e1) ("CIRCLED LATIN SMALL LETTER S" . #x0024e2) ("CIRCLED LATIN SMALL LETTER T" . #x0024e3) ("CIRCLED LATIN SMALL LETTER U" . #x0024e4) ("CIRCLED LATIN SMALL LETTER V" . #x0024e5) ("CIRCLED LATIN SMALL LETTER W" . #x0024e6) ("CIRCLED LATIN SMALL LETTER X" . #x0024e7) ("CIRCLED LATIN SMALL LETTER Y" . #x0024e8) ("CIRCLED LATIN SMALL LETTER Z" . #x0024e9) ("CIRCLED DIGIT ZERO" . #x0024ea) ("NEGATIVE CIRCLED NUMBER ELEVEN" . #x0024eb) ("NEGATIVE CIRCLED NUMBER TWELVE" . #x0024ec) ("NEGATIVE CIRCLED NUMBER THIRTEEN" . #x0024ed) ("NEGATIVE CIRCLED NUMBER FOURTEEN" . #x0024ee) ("NEGATIVE CIRCLED NUMBER FIFTEEN" . #x0024ef) ("NEGATIVE CIRCLED NUMBER SIXTEEN" . #x0024f0) ("NEGATIVE CIRCLED NUMBER SEVENTEEN" . #x0024f1) ("NEGATIVE CIRCLED NUMBER EIGHTEEN" . #x0024f2) ("NEGATIVE CIRCLED NUMBER NINETEEN" . #x0024f3) ("NEGATIVE CIRCLED NUMBER TWENTY" . #x0024f4) ("DOUBLE CIRCLED DIGIT ONE" . #x0024f5) ("DOUBLE CIRCLED DIGIT TWO" . #x0024f6) ("DOUBLE CIRCLED DIGIT THREE" . #x0024f7) ("DOUBLE CIRCLED DIGIT FOUR" . #x0024f8) ("DOUBLE CIRCLED DIGIT FIVE" . #x0024f9) ("DOUBLE CIRCLED DIGIT SIX" . #x0024fa) ("DOUBLE CIRCLED DIGIT SEVEN" . #x0024fb) ("DOUBLE CIRCLED DIGIT EIGHT" . #x0024fc) ("DOUBLE CIRCLED DIGIT NINE" . #x0024fd) ("DOUBLE CIRCLED NUMBER TEN" . #x0024fe) ("BOX DRAWINGS LIGHT HORIZONTAL" . #x002500) ("BOX DRAWINGS HEAVY HORIZONTAL" . #x002501) ("BOX DRAWINGS LIGHT VERTICAL" . #x002502) ("BOX DRAWINGS HEAVY VERTICAL" . #x002503) ("BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL" . #x002504) ("BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL" . #x002505) ("BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL" . #x002506) ("BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL" . #x002507) ("BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL" . #x002508) ("BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL" . #x002509) ("BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL" . #x00250a) ("BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL" . #x00250b) ("BOX DRAWINGS LIGHT DOWN AND RIGHT" . #x00250c) ("BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY" . #x00250d) ("BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT" . #x00250e) ("BOX DRAWINGS HEAVY DOWN AND RIGHT" . #x00250f) ("BOX DRAWINGS LIGHT DOWN AND LEFT" . #x002510) ("BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY" . #x002511) ("BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT" . #x002512) ("BOX DRAWINGS HEAVY DOWN AND LEFT" . #x002513) ("BOX DRAWINGS LIGHT UP AND RIGHT" . #x002514) ("BOX DRAWINGS UP LIGHT AND RIGHT HEAVY" . #x002515) ("BOX DRAWINGS UP HEAVY AND RIGHT LIGHT" . #x002516) ("BOX DRAWINGS HEAVY UP AND RIGHT" . #x002517) ("BOX DRAWINGS LIGHT UP AND LEFT" . #x002518) ("BOX DRAWINGS UP LIGHT AND LEFT HEAVY" . #x002519) ("BOX DRAWINGS UP HEAVY AND LEFT LIGHT" . #x00251a) ("BOX DRAWINGS HEAVY UP AND LEFT" . #x00251b) ("BOX DRAWINGS LIGHT VERTICAL AND RIGHT" . #x00251c) ("BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY" . #x00251d) ("BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT" . #x00251e) ("BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT" . #x00251f) ("BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT" . #x002520) ("BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY" . #x002521) ("BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY" . #x002522) ("BOX DRAWINGS HEAVY VERTICAL AND RIGHT" . #x002523) ("BOX DRAWINGS LIGHT VERTICAL AND LEFT" . #x002524) ("BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY" . #x002525) ("BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT" . #x002526) ("BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT" . #x002527) ("BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT" . #x002528) ("BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY" . #x002529) ("BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY" . #x00252a) ("BOX DRAWINGS HEAVY VERTICAL AND LEFT" . #x00252b) ("BOX DRAWINGS LIGHT DOWN AND HORIZONTAL" . #x00252c) ("BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT" . #x00252d) ("BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT" . #x00252e) ("BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY" . #x00252f) ("BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT" . #x002530) ("BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY" . #x002531) ("BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY" . #x002532) ("BOX DRAWINGS HEAVY DOWN AND HORIZONTAL" . #x002533) ("BOX DRAWINGS LIGHT UP AND HORIZONTAL" . #x002534) ("BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT" . #x002535) ("BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT" . #x002536) ("BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY" . #x002537) ("BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT" . #x002538) ("BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY" . #x002539) ("BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY" . #x00253a) ("BOX DRAWINGS HEAVY UP AND HORIZONTAL" . #x00253b) ("BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL" . #x00253c) ("BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT" . #x00253d) ("BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT" . #x00253e) ("BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY" . #x00253f) ("BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT" . #x002540) ("BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT" . #x002541) ("BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT" . #x002542) ("BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT" . #x002543) ("BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT" . #x002544) ("BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT" . #x002545) ("BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT" . #x002546) ("BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY" . #x002547) ("BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY" . #x002548) ("BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY" . #x002549) ("BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY" . #x00254a) ("BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL" . #x00254b) ("BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL" . #x00254c) ("BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL" . #x00254d) ("BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL" . #x00254e) ("BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL" . #x00254f) ("BOX DRAWINGS DOUBLE HORIZONTAL" . #x002550) ("BOX DRAWINGS DOUBLE VERTICAL" . #x002551) ("BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE" . #x002552) ("BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE" . #x002553) ("BOX DRAWINGS DOUBLE DOWN AND RIGHT" . #x002554) ("BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE" . #x002555) ("BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE" . #x002556) ("BOX DRAWINGS DOUBLE DOWN AND LEFT" . #x002557) ("BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE" . #x002558) ("BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE" . #x002559) ("BOX DRAWINGS DOUBLE UP AND RIGHT" . #x00255a) ("BOX DRAWINGS UP SINGLE AND LEFT DOUBLE" . #x00255b) ("BOX DRAWINGS UP DOUBLE AND LEFT SINGLE" . #x00255c) ("BOX DRAWINGS DOUBLE UP AND LEFT" . #x00255d) ("BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE" . #x00255e) ("BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE" . #x00255f) ("BOX DRAWINGS DOUBLE VERTICAL AND RIGHT" . #x002560) ("BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE" . #x002561) ("BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE" . #x002562) ("BOX DRAWINGS DOUBLE VERTICAL AND LEFT" . #x002563) ("BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE" . #x002564) ("BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE" . #x002565) ("BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL" . #x002566) ("BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE" . #x002567) ("BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE" . #x002568) ("BOX DRAWINGS DOUBLE UP AND HORIZONTAL" . #x002569) ("BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE" . #x00256a) ("BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE" . #x00256b) ("BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL" . #x00256c) ("BOX DRAWINGS LIGHT ARC DOWN AND RIGHT" . #x00256d) ("BOX DRAWINGS LIGHT ARC DOWN AND LEFT" . #x00256e) ("BOX DRAWINGS LIGHT ARC UP AND LEFT" . #x00256f) ("BOX DRAWINGS LIGHT ARC UP AND RIGHT" . #x002570) ("BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT" . #x002571) ("BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT" . #x002572) ("BOX DRAWINGS LIGHT DIAGONAL CROSS" . #x002573) ("BOX DRAWINGS LIGHT LEFT" . #x002574) ("BOX DRAWINGS LIGHT UP" . #x002575) ("BOX DRAWINGS LIGHT RIGHT" . #x002576) ("BOX DRAWINGS LIGHT DOWN" . #x002577) ("BOX DRAWINGS HEAVY LEFT" . #x002578) ("BOX DRAWINGS HEAVY UP" . #x002579) ("BOX DRAWINGS HEAVY RIGHT" . #x00257a) ("BOX DRAWINGS HEAVY DOWN" . #x00257b) ("BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT" . #x00257c) ("BOX DRAWINGS LIGHT UP AND HEAVY DOWN" . #x00257d) ("BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT" . #x00257e) ("BOX DRAWINGS HEAVY UP AND LIGHT DOWN" . #x00257f) ("UPPER HALF BLOCK" . #x002580) ("LOWER ONE EIGHTH BLOCK" . #x002581) ("LOWER ONE QUARTER BLOCK" . #x002582) ("LOWER THREE EIGHTHS BLOCK" . #x002583) ("LOWER HALF BLOCK" . #x002584) ("LOWER FIVE EIGHTHS BLOCK" . #x002585) ("LOWER THREE QUARTERS BLOCK" . #x002586) ("LOWER SEVEN EIGHTHS BLOCK" . #x002587) ("FULL BLOCK" . #x002588) ("LEFT SEVEN EIGHTHS BLOCK" . #x002589) ("LEFT THREE QUARTERS BLOCK" . #x00258a) ("LEFT FIVE EIGHTHS BLOCK" . #x00258b) ("LEFT HALF BLOCK" . #x00258c) ("LEFT THREE EIGHTHS BLOCK" . #x00258d) ("LEFT ONE QUARTER BLOCK" . #x00258e) ("LEFT ONE EIGHTH BLOCK" . #x00258f) ("RIGHT HALF BLOCK" . #x002590) ("LIGHT SHADE" . #x002591) ("MEDIUM SHADE" . #x002592) ("DARK SHADE" . #x002593) ("UPPER ONE EIGHTH BLOCK" . #x002594) ("RIGHT ONE EIGHTH BLOCK" . #x002595) ("QUADRANT LOWER LEFT" . #x002596) ("QUADRANT LOWER RIGHT" . #x002597) ("QUADRANT UPPER LEFT" . #x002598) ("QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT" . #x002599) ("QUADRANT UPPER LEFT AND LOWER RIGHT" . #x00259a) ("QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT" . #x00259b) ("QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT" . #x00259c) ("QUADRANT UPPER RIGHT" . #x00259d) ("QUADRANT UPPER RIGHT AND LOWER LEFT" . #x00259e) ("QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT" . #x00259f) ("BLACK SQUARE" . #x0025a0) ("WHITE SQUARE" . #x0025a1) ("WHITE SQUARE WITH ROUNDED CORNERS" . #x0025a2) ("WHITE SQUARE CONTAINING BLACK SMALL SQUARE" . #x0025a3) ("SQUARE WITH HORIZONTAL FILL" . #x0025a4) ("SQUARE WITH VERTICAL FILL" . #x0025a5) ("SQUARE WITH ORTHOGONAL CROSSHATCH FILL" . #x0025a6) ("SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL" . #x0025a7) ("SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL" . #x0025a8) ("SQUARE WITH DIAGONAL CROSSHATCH FILL" . #x0025a9) ("BLACK SMALL SQUARE" . #x0025aa) ("WHITE SMALL SQUARE" . #x0025ab) ("BLACK RECTANGLE" . #x0025ac) ("WHITE RECTANGLE" . #x0025ad) ("BLACK VERTICAL RECTANGLE" . #x0025ae) ("WHITE VERTICAL RECTANGLE" . #x0025af) ("BLACK PARALLELOGRAM" . #x0025b0) ("WHITE PARALLELOGRAM" . #x0025b1) ("BLACK UP-POINTING TRIANGLE" . #x0025b2) ("WHITE UP-POINTING TRIANGLE" . #x0025b3) ("BLACK UP-POINTING SMALL TRIANGLE" . #x0025b4) ("WHITE UP-POINTING SMALL TRIANGLE" . #x0025b5) ("BLACK RIGHT-POINTING TRIANGLE" . #x0025b6) ("WHITE RIGHT-POINTING TRIANGLE" . #x0025b7) ("BLACK RIGHT-POINTING SMALL TRIANGLE" . #x0025b8) ("WHITE RIGHT-POINTING SMALL TRIANGLE" . #x0025b9) ("BLACK RIGHT-POINTING POINTER" . #x0025ba) ("WHITE RIGHT-POINTING POINTER" . #x0025bb) ("BLACK DOWN-POINTING TRIANGLE" . #x0025bc) ("WHITE DOWN-POINTING TRIANGLE" . #x0025bd) ("BLACK DOWN-POINTING SMALL TRIANGLE" . #x0025be) ("WHITE DOWN-POINTING SMALL TRIANGLE" . #x0025bf) ("BLACK LEFT-POINTING TRIANGLE" . #x0025c0) ("WHITE LEFT-POINTING TRIANGLE" . #x0025c1) ("BLACK LEFT-POINTING SMALL TRIANGLE" . #x0025c2) ("WHITE LEFT-POINTING SMALL TRIANGLE" . #x0025c3) ("BLACK LEFT-POINTING POINTER" . #x0025c4) ("WHITE LEFT-POINTING POINTER" . #x0025c5) ("BLACK DIAMOND" . #x0025c6) ("WHITE DIAMOND" . #x0025c7) ("WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND" . #x0025c8) ("FISHEYE" . #x0025c9) ("LOZENGE" . #x0025ca) ("WHITE CIRCLE" . #x0025cb) ("DOTTED CIRCLE" . #x0025cc) ("CIRCLE WITH VERTICAL FILL" . #x0025cd) ("BULLSEYE" . #x0025ce) ("BLACK CIRCLE" . #x0025cf) ("CIRCLE WITH LEFT HALF BLACK" . #x0025d0) ("CIRCLE WITH RIGHT HALF BLACK" . #x0025d1) ("CIRCLE WITH LOWER HALF BLACK" . #x0025d2) ("CIRCLE WITH UPPER HALF BLACK" . #x0025d3) ("CIRCLE WITH UPPER RIGHT QUADRANT BLACK" . #x0025d4) ("CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK" . #x0025d5) ("LEFT HALF BLACK CIRCLE" . #x0025d6) ("RIGHT HALF BLACK CIRCLE" . #x0025d7) ("INVERSE BULLET" . #x0025d8) ("INVERSE WHITE CIRCLE" . #x0025d9) ("UPPER HALF INVERSE WHITE CIRCLE" . #x0025da) ("LOWER HALF INVERSE WHITE CIRCLE" . #x0025db) ("UPPER LEFT QUADRANT CIRCULAR ARC" . #x0025dc) ("UPPER RIGHT QUADRANT CIRCULAR ARC" . #x0025dd) ("LOWER RIGHT QUADRANT CIRCULAR ARC" . #x0025de) ("LOWER LEFT QUADRANT CIRCULAR ARC" . #x0025df) ("UPPER HALF CIRCLE" . #x0025e0) ("LOWER HALF CIRCLE" . #x0025e1) ("BLACK LOWER RIGHT TRIANGLE" . #x0025e2) ("BLACK LOWER LEFT TRIANGLE" . #x0025e3) ("BLACK UPPER LEFT TRIANGLE" . #x0025e4) ("BLACK UPPER RIGHT TRIANGLE" . #x0025e5) ("WHITE BULLET" . #x0025e6) ("SQUARE WITH LEFT HALF BLACK" . #x0025e7) ("SQUARE WITH RIGHT HALF BLACK" . #x0025e8) ("SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK" . #x0025e9) ("SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK" . #x0025ea) ("WHITE SQUARE WITH VERTICAL BISECTING LINE" . #x0025eb) ("WHITE UP-POINTING TRIANGLE WITH DOT" . #x0025ec) ("UP-POINTING TRIANGLE WITH LEFT HALF BLACK" . #x0025ed) ("UP-POINTING TRIANGLE WITH RIGHT HALF BLACK" . #x0025ee) ("LARGE CIRCLE" . #x0025ef) ("WHITE SQUARE WITH UPPER LEFT QUADRANT" . #x0025f0) ("WHITE SQUARE WITH LOWER LEFT QUADRANT" . #x0025f1) ("WHITE SQUARE WITH LOWER RIGHT QUADRANT" . #x0025f2) ("WHITE SQUARE WITH UPPER RIGHT QUADRANT" . #x0025f3) ("WHITE CIRCLE WITH UPPER LEFT QUADRANT" . #x0025f4) ("WHITE CIRCLE WITH LOWER LEFT QUADRANT" . #x0025f5) ("WHITE CIRCLE WITH LOWER RIGHT QUADRANT" . #x0025f6) ("WHITE CIRCLE WITH UPPER RIGHT QUADRANT" . #x0025f7) ("UPPER LEFT TRIANGLE" . #x0025f8) ("UPPER RIGHT TRIANGLE" . #x0025f9) ("LOWER LEFT TRIANGLE" . #x0025fa) ("WHITE MEDIUM SQUARE" . #x0025fb) ("BLACK MEDIUM SQUARE" . #x0025fc) ("WHITE MEDIUM SMALL SQUARE" . #x0025fd) ("BLACK MEDIUM SMALL SQUARE" . #x0025fe) ("LOWER RIGHT TRIANGLE" . #x0025ff) ("BLACK SUN WITH RAYS" . #x002600) ("CLOUD" . #x002601) ("UMBRELLA" . #x002602) ("SNOWMAN" . #x002603) ("COMET" . #x002604) ("BLACK STAR" . #x002605) ("WHITE STAR" . #x002606) ("LIGHTNING" . #x002607) ("THUNDERSTORM" . #x002608) ("SUN" . #x002609) ("ASCENDING NODE" . #x00260a) ("DESCENDING NODE" . #x00260b) ("CONJUNCTION" . #x00260c) ("OPPOSITION" . #x00260d) ("BLACK TELEPHONE" . #x00260e) ("WHITE TELEPHONE" . #x00260f) ("BALLOT BOX" . #x002610) ("BALLOT BOX WITH CHECK" . #x002611) ("BALLOT BOX WITH X" . #x002612) ("SALTIRE" . #x002613) ("WHITE SHOGI PIECE" . #x002616) ("BLACK SHOGI PIECE" . #x002617) ("REVERSED ROTATED FLORAL HEART BULLET" . #x002619) ("BLACK LEFT POINTING INDEX" . #x00261a) ("BLACK RIGHT POINTING INDEX" . #x00261b) ("WHITE LEFT POINTING INDEX" . #x00261c) ("WHITE UP POINTING INDEX" . #x00261d) ("WHITE RIGHT POINTING INDEX" . #x00261e) ("WHITE DOWN POINTING INDEX" . #x00261f) ("SKULL AND CROSSBONES" . #x002620) ("CAUTION SIGN" . #x002621) ("RADIOACTIVE SIGN" . #x002622) ("BIOHAZARD SIGN" . #x002623) ("CADUCEUS" . #x002624) ("ANKH" . #x002625) ("ORTHODOX CROSS" . #x002626) ("CHI RHO" . #x002627) ("CROSS OF LORRAINE" . #x002628) ("CROSS OF JERUSALEM" . #x002629) ("STAR AND CRESCENT" . #x00262a) ("FARSI SYMBOL" . #x00262b) ("ADI SHAKTI" . #x00262c) ("HAMMER AND SICKLE" . #x00262d) ("PEACE SYMBOL" . #x00262e) ("YIN YANG" . #x00262f) ("TRIGRAM FOR HEAVEN" . #x002630) ("TRIGRAM FOR LAKE" . #x002631) ("TRIGRAM FOR FIRE" . #x002632) ("TRIGRAM FOR THUNDER" . #x002633) ("TRIGRAM FOR WIND" . #x002634) ("TRIGRAM FOR WATER" . #x002635) ("TRIGRAM FOR MOUNTAIN" . #x002636) ("TRIGRAM FOR EARTH" . #x002637) ("WHEEL OF DHARMA" . #x002638) ("WHITE FROWNING FACE" . #x002639) ("WHITE SMILING FACE" . #x00263a) ("BLACK SMILING FACE" . #x00263b) ("WHITE SUN WITH RAYS" . #x00263c) ("FIRST QUARTER MOON" . #x00263d) ("LAST QUARTER MOON" . #x00263e) ("MERCURY" . #x00263f) ("FEMALE SIGN" . #x002640) ("EARTH" . #x002641) ("MALE SIGN" . #x002642) ("JUPITER" . #x002643) ("SATURN" . #x002644) ("URANUS" . #x002645) ("NEPTUNE" . #x002646) ("PLUTO" . #x002647) ("ARIES" . #x002648) ("TAURUS" . #x002649) ("GEMINI" . #x00264a) ("CANCER" . #x00264b) ("LEO" . #x00264c) ("VIRGO" . #x00264d) ("LIBRA" . #x00264e) ("SCORPIUS" . #x00264f) ("SAGITTARIUS" . #x002650) ("CAPRICORN" . #x002651) ("AQUARIUS" . #x002652) ("PISCES" . #x002653) ("WHITE CHESS KING" . #x002654) ("WHITE CHESS QUEEN" . #x002655) ("WHITE CHESS ROOK" . #x002656) ("WHITE CHESS BISHOP" . #x002657) ("WHITE CHESS KNIGHT" . #x002658) ("WHITE CHESS PAWN" . #x002659) ("BLACK CHESS KING" . #x00265a) ("BLACK CHESS QUEEN" . #x00265b) ("BLACK CHESS ROOK" . #x00265c) ("BLACK CHESS BISHOP" . #x00265d) ("BLACK CHESS KNIGHT" . #x00265e) ("BLACK CHESS PAWN" . #x00265f) ("BLACK SPADE SUIT" . #x002660) ("WHITE HEART SUIT" . #x002661) ("WHITE DIAMOND SUIT" . #x002662) ("BLACK CLUB SUIT" . #x002663) ("WHITE SPADE SUIT" . #x002664) ("BLACK HEART SUIT" . #x002665) ("BLACK DIAMOND SUIT" . #x002666) ("WHITE CLUB SUIT" . #x002667) ("HOT SPRINGS" . #x002668) ("QUARTER NOTE" . #x002669) ("EIGHTH NOTE" . #x00266a) ("BEAMED EIGHTH NOTES" . #x00266b) ("BEAMED SIXTEENTH NOTES" . #x00266c) ("MUSIC FLAT SIGN" . #x00266d) ("MUSIC NATURAL SIGN" . #x00266e) ("MUSIC SHARP SIGN" . #x00266f) ("WEST SYRIAC CROSS" . #x002670) ("EAST SYRIAC CROSS" . #x002671) ("UNIVERSAL RECYCLING SYMBOL" . #x002672) ("RECYCLING SYMBOL FOR TYPE-1 PLASTICS" . #x002673) ("RECYCLING SYMBOL FOR TYPE-2 PLASTICS" . #x002674) ("RECYCLING SYMBOL FOR TYPE-3 PLASTICS" . #x002675) ("RECYCLING SYMBOL FOR TYPE-4 PLASTICS" . #x002676) ("RECYCLING SYMBOL FOR TYPE-5 PLASTICS" . #x002677) ("RECYCLING SYMBOL FOR TYPE-6 PLASTICS" . #x002678) ("RECYCLING SYMBOL FOR TYPE-7 PLASTICS" . #x002679) ("RECYCLING SYMBOL FOR GENERIC MATERIALS" . #x00267a) ("BLACK UNIVERSAL RECYCLING SYMBOL" . #x00267b) ("RECYCLED PAPER SYMBOL" . #x00267c) ("PARTIALLY-RECYCLED PAPER SYMBOL" . #x00267d) ("DIE FACE-1" . #x002680) ("DIE FACE-2" . #x002681) ("DIE FACE-3" . #x002682) ("DIE FACE-4" . #x002683) ("DIE FACE-5" . #x002684) ("DIE FACE-6" . #x002685) ("WHITE CIRCLE WITH DOT RIGHT" . #x002686) ("WHITE CIRCLE WITH TWO DOTS" . #x002687) ("BLACK CIRCLE WITH WHITE DOT RIGHT" . #x002688) ("BLACK CIRCLE WITH TWO WHITE DOTS" . #x002689) ("UPPER BLADE SCISSORS" . #x002701) ("BLACK SCISSORS" . #x002702) ("LOWER BLADE SCISSORS" . #x002703) ("WHITE SCISSORS" . #x002704) ("TELEPHONE LOCATION SIGN" . #x002706) ("TAPE DRIVE" . #x002707) ("AIRPLANE" . #x002708) ("ENVELOPE" . #x002709) ("VICTORY HAND" . #x00270c) ("WRITING HAND" . #x00270d) ("LOWER RIGHT PENCIL" . #x00270e) ("PENCIL" . #x00270f) ("UPPER RIGHT PENCIL" . #x002710) ("WHITE NIB" . #x002711) ("BLACK NIB" . #x002712) ("CHECK MARK" . #x002713) ("HEAVY CHECK MARK" . #x002714) ("MULTIPLICATION X" . #x002715) ("HEAVY MULTIPLICATION X" . #x002716) ("BALLOT X" . #x002717) ("HEAVY BALLOT X" . #x002718) ("OUTLINED GREEK CROSS" . #x002719) ("HEAVY GREEK CROSS" . #x00271a) ("OPEN CENTRE CROSS" . #x00271b) ("HEAVY OPEN CENTRE CROSS" . #x00271c) ("LATIN CROSS" . #x00271d) ("SHADOWED WHITE LATIN CROSS" . #x00271e) ("OUTLINED LATIN CROSS" . #x00271f) ("MALTESE CROSS" . #x002720) ("STAR OF DAVID" . #x002721) ("FOUR TEARDROP-SPOKED ASTERISK" . #x002722) ("FOUR BALLOON-SPOKED ASTERISK" . #x002723) ("HEAVY FOUR BALLOON-SPOKED ASTERISK" . #x002724) ("FOUR CLUB-SPOKED ASTERISK" . #x002725) ("BLACK FOUR POINTED STAR" . #x002726) ("WHITE FOUR POINTED STAR" . #x002727) ("STRESS OUTLINED WHITE STAR" . #x002729) ("CIRCLED WHITE STAR" . #x00272a) ("OPEN CENTRE BLACK STAR" . #x00272b) ("BLACK CENTRE WHITE STAR" . #x00272c) ("OUTLINED BLACK STAR" . #x00272d) ("HEAVY OUTLINED BLACK STAR" . #x00272e) ("PINWHEEL STAR" . #x00272f) ("SHADOWED WHITE STAR" . #x002730) ("HEAVY ASTERISK" . #x002731) ("OPEN CENTRE ASTERISK" . #x002732) ("EIGHT SPOKED ASTERISK" . #x002733) ("EIGHT POINTED BLACK STAR" . #x002734) ("EIGHT POINTED PINWHEEL STAR" . #x002735) ("SIX POINTED BLACK STAR" . #x002736) ("EIGHT POINTED RECTILINEAR BLACK STAR" . #x002737) ("HEAVY EIGHT POINTED RECTILINEAR BLACK STAR" . #x002738) ("TWELVE POINTED BLACK STAR" . #x002739) ("SIXTEEN POINTED ASTERISK" . #x00273a) ("TEARDROP-SPOKED ASTERISK" . #x00273b) ("OPEN CENTRE TEARDROP-SPOKED ASTERISK" . #x00273c) ("HEAVY TEARDROP-SPOKED ASTERISK" . #x00273d) ("SIX PETALLED BLACK AND WHITE FLORETTE" . #x00273e) ("BLACK FLORETTE" . #x00273f) ("WHITE FLORETTE" . #x002740) ("EIGHT PETALLED OUTLINED BLACK FLORETTE" . #x002741) ("CIRCLED OPEN CENTRE EIGHT POINTED STAR" . #x002742) ("HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK" . #x002743) ("SNOWFLAKE" . #x002744) ("TIGHT TRIFOLIATE SNOWFLAKE" . #x002745) ("HEAVY CHEVRON SNOWFLAKE" . #x002746) ("SPARKLE" . #x002747) ("HEAVY SPARKLE" . #x002748) ("BALLOON-SPOKED ASTERISK" . #x002749) ("EIGHT TEARDROP-SPOKED PROPELLER ASTERISK" . #x00274a) ("HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK" . #x00274b) ("SHADOWED WHITE CIRCLE" . #x00274d) ("LOWER RIGHT DROP-SHADOWED WHITE SQUARE" . #x00274f) ("UPPER RIGHT DROP-SHADOWED WHITE SQUARE" . #x002750) ("LOWER RIGHT SHADOWED WHITE SQUARE" . #x002751) ("UPPER RIGHT SHADOWED WHITE SQUARE" . #x002752) ("BLACK DIAMOND MINUS WHITE X" . #x002756) ("LIGHT VERTICAL BAR" . #x002758) ("MEDIUM VERTICAL BAR" . #x002759) ("HEAVY VERTICAL BAR" . #x00275a) ("HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT" . #x00275b) ("HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT" . #x00275c) ("HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT" . #x00275d) ("HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT" . #x00275e) ("CURVED STEM PARAGRAPH SIGN ORNAMENT" . #x002761) ("HEAVY EXCLAMATION MARK ORNAMENT" . #x002762) ("HEAVY HEART EXCLAMATION MARK ORNAMENT" . #x002763) ("HEAVY BLACK HEART" . #x002764) ("ROTATED HEAVY BLACK HEART BULLET" . #x002765) ("FLORAL HEART" . #x002766) ("ROTATED FLORAL HEART BULLET" . #x002767) ("MEDIUM LEFT PARENTHESIS ORNAMENT" . #x002768) ("MEDIUM RIGHT PARENTHESIS ORNAMENT" . #x002769) ("MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT" . #x00276a) ("MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT" . #x00276b) ("MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT" . #x00276c) ("MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT" . #x00276d) ("HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT" . #x00276e) ("HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT" . #x00276f) ("HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT" . #x002770) ("HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT" . #x002771) ("LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT" . #x002772) ("LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT" . #x002773) ("MEDIUM LEFT CURLY BRACKET ORNAMENT" . #x002774) ("MEDIUM RIGHT CURLY BRACKET ORNAMENT" . #x002775) ("DINGBAT NEGATIVE CIRCLED DIGIT ONE" . #x002776) ("DINGBAT NEGATIVE CIRCLED DIGIT TWO" . #x002777) ("DINGBAT NEGATIVE CIRCLED DIGIT THREE" . #x002778) ("DINGBAT NEGATIVE CIRCLED DIGIT FOUR" . #x002779) ("DINGBAT NEGATIVE CIRCLED DIGIT FIVE" . #x00277a) ("DINGBAT NEGATIVE CIRCLED DIGIT SIX" . #x00277b) ("DINGBAT NEGATIVE CIRCLED DIGIT SEVEN" . #x00277c) ("DINGBAT NEGATIVE CIRCLED DIGIT EIGHT" . #x00277d) ("DINGBAT NEGATIVE CIRCLED DIGIT NINE" . #x00277e) ("DINGBAT NEGATIVE CIRCLED NUMBER TEN" . #x00277f) ("DINGBAT CIRCLED SANS-SERIF DIGIT ONE" . #x002780) ("DINGBAT CIRCLED SANS-SERIF DIGIT TWO" . #x002781) ("DINGBAT CIRCLED SANS-SERIF DIGIT THREE" . #x002782) ("DINGBAT CIRCLED SANS-SERIF DIGIT FOUR" . #x002783) ("DINGBAT CIRCLED SANS-SERIF DIGIT FIVE" . #x002784) ("DINGBAT CIRCLED SANS-SERIF DIGIT SIX" . #x002785) ("DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN" . #x002786) ("DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT" . #x002787) ("DINGBAT CIRCLED SANS-SERIF DIGIT NINE" . #x002788) ("DINGBAT CIRCLED SANS-SERIF NUMBER TEN" . #x002789) ("DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE" . #x00278a) ("DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO" . #x00278b) ("DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE" . #x00278c) ("DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR" . #x00278d) ("DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE" . #x00278e) ("DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX" . #x00278f) ("DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN" . #x002790) ("DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT" . #x002791) ("DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE" . #x002792) ("DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN" . #x002793) ("HEAVY WIDE-HEADED RIGHTWARDS ARROW" . #x002794) ("HEAVY SOUTH EAST ARROW" . #x002798) ("HEAVY RIGHTWARDS ARROW" . #x002799) ("HEAVY NORTH EAST ARROW" . #x00279a) ("DRAFTING POINT RIGHTWARDS ARROW" . #x00279b) ("HEAVY ROUND-TIPPED RIGHTWARDS ARROW" . #x00279c) ("TRIANGLE-HEADED RIGHTWARDS ARROW" . #x00279d) ("HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW" . #x00279e) ("DASHED TRIANGLE-HEADED RIGHTWARDS ARROW" . #x00279f) ("HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW" . #x0027a0) ("BLACK RIGHTWARDS ARROW" . #x0027a1) ("THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD" . #x0027a2) ("THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD" . #x0027a3) ("BLACK RIGHTWARDS ARROWHEAD" . #x0027a4) ("HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW" . #x0027a5) ("HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW" . #x0027a6) ("SQUAT BLACK RIGHTWARDS ARROW" . #x0027a7) ("HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW" . #x0027a8) ("RIGHT-SHADED WHITE RIGHTWARDS ARROW" . #x0027a9) ("LEFT-SHADED WHITE RIGHTWARDS ARROW" . #x0027aa) ("BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW" . #x0027ab) ("FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW" . #x0027ac) ("HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW" . #x0027ad) ("HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW" . #x0027ae) ("NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW" . #x0027af) ("NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW" . #x0027b1) ("CIRCLED HEAVY WHITE RIGHTWARDS ARROW" . #x0027b2) ("WHITE-FEATHERED RIGHTWARDS ARROW" . #x0027b3) ("BLACK-FEATHERED SOUTH EAST ARROW" . #x0027b4) ("BLACK-FEATHERED RIGHTWARDS ARROW" . #x0027b5) ("BLACK-FEATHERED NORTH EAST ARROW" . #x0027b6) ("HEAVY BLACK-FEATHERED SOUTH EAST ARROW" . #x0027b7) ("HEAVY BLACK-FEATHERED RIGHTWARDS ARROW" . #x0027b8) ("HEAVY BLACK-FEATHERED NORTH EAST ARROW" . #x0027b9) ("TEARDROP-BARBED RIGHTWARDS ARROW" . #x0027ba) ("HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW" . #x0027bb) ("WEDGE-TAILED RIGHTWARDS ARROW" . #x0027bc) ("HEAVY WEDGE-TAILED RIGHTWARDS ARROW" . #x0027bd) ("OPEN-OUTLINED RIGHTWARDS ARROW" . #x0027be) ("WHITE DIAMOND WITH CENTRED DOT" . #x0027d0) ("AND WITH DOT" . #x0027d1) ("ELEMENT OF OPENING UPWARDS" . #x0027d2) ("LOWER RIGHT CORNER WITH DOT" . #x0027d3) ("UPPER LEFT CORNER WITH DOT" . #x0027d4) ("LEFT OUTER JOIN" . #x0027d5) ("RIGHT OUTER JOIN" . #x0027d6) ("FULL OUTER JOIN" . #x0027d7) ("LARGE UP TACK" . #x0027d8) ("LARGE DOWN TACK" . #x0027d9) ("LEFT AND RIGHT DOUBLE TURNSTILE" . #x0027da) ("LEFT AND RIGHT TACK" . #x0027db) ("LEFT MULTIMAP" . #x0027dc) ("LONG RIGHT TACK" . #x0027dd) ("LONG LEFT TACK" . #x0027de) ("UP TACK WITH CIRCLE ABOVE" . #x0027df) ("LOZENGE DIVIDED BY HORIZONTAL RULE" . #x0027e0) ("WHITE CONCAVE-SIDED DIAMOND" . #x0027e1) ("WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK" . #x0027e2) ("WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK" . #x0027e3) ("WHITE SQUARE WITH LEFTWARDS TICK" . #x0027e4) ("WHITE SQUARE WITH RIGHTWARDS TICK" . #x0027e5) ("MATHEMATICAL LEFT WHITE SQUARE BRACKET" . #x0027e6) ("MATHEMATICAL RIGHT WHITE SQUARE BRACKET" . #x0027e7) ("MATHEMATICAL LEFT ANGLE BRACKET" . #x0027e8) ("MATHEMATICAL RIGHT ANGLE BRACKET" . #x0027e9) ("MATHEMATICAL LEFT DOUBLE ANGLE BRACKET" . #x0027ea) ("MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET" . #x0027eb) ("UPWARDS QUADRUPLE ARROW" . #x0027f0) ("DOWNWARDS QUADRUPLE ARROW" . #x0027f1) ("ANTICLOCKWISE GAPPED CIRCLE ARROW" . #x0027f2) ("CLOCKWISE GAPPED CIRCLE ARROW" . #x0027f3) ("RIGHT ARROW WITH CIRCLED PLUS" . #x0027f4) ("LONG LEFTWARDS ARROW" . #x0027f5) ("LONG RIGHTWARDS ARROW" . #x0027f6) ("LONG LEFT RIGHT ARROW" . #x0027f7) ("LONG LEFTWARDS DOUBLE ARROW" . #x0027f8) ("LONG RIGHTWARDS DOUBLE ARROW" . #x0027f9) ("LONG LEFT RIGHT DOUBLE ARROW" . #x0027fa) ("LONG LEFTWARDS ARROW FROM BAR" . #x0027fb) ("LONG RIGHTWARDS ARROW FROM BAR" . #x0027fc) ("LONG LEFTWARDS DOUBLE ARROW FROM BAR" . #x0027fd) ("LONG RIGHTWARDS DOUBLE ARROW FROM BAR" . #x0027fe) ("LONG RIGHTWARDS SQUIGGLE ARROW" . #x0027ff) ("RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE" . #x002900) ("RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE" . #x002901) ("LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE" . #x002902) ("RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE" . #x002903) ("LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE" . #x002904) ("RIGHTWARDS TWO-HEADED ARROW FROM BAR" . #x002905) ("LEFTWARDS DOUBLE ARROW FROM BAR" . #x002906) ("RIGHTWARDS DOUBLE ARROW FROM BAR" . #x002907) ("DOWNWARDS ARROW WITH HORIZONTAL STROKE" . #x002908) ("UPWARDS ARROW WITH HORIZONTAL STROKE" . #x002909) ("UPWARDS TRIPLE ARROW" . #x00290a) ("DOWNWARDS TRIPLE ARROW" . #x00290b) ("LEFTWARDS DOUBLE DASH ARROW" . #x00290c) ("RIGHTWARDS DOUBLE DASH ARROW" . #x00290d) ("LEFTWARDS TRIPLE DASH ARROW" . #x00290e) ("RIGHTWARDS TRIPLE DASH ARROW" . #x00290f) ("RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW" . #x002910) ("RIGHTWARDS ARROW WITH DOTTED STEM" . #x002911) ("UPWARDS ARROW TO BAR" . #x002912) ("DOWNWARDS ARROW TO BAR" . #x002913) ("RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE" . #x002914) ("RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE" . #x002915) ("RIGHTWARDS TWO-HEADED ARROW WITH TAIL" . #x002916) ("RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE" . #x002917) ("RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE" . #x002918) ("LEFTWARDS ARROW-TAIL" . #x002919) ("RIGHTWARDS ARROW-TAIL" . #x00291a) ("LEFTWARDS DOUBLE ARROW-TAIL" . #x00291b) ("RIGHTWARDS DOUBLE ARROW-TAIL" . #x00291c) ("LEFTWARDS ARROW TO BLACK DIAMOND" . #x00291d) ("RIGHTWARDS ARROW TO BLACK DIAMOND" . #x00291e) ("LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND" . #x00291f) ("RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND" . #x002920) ("NORTH WEST AND SOUTH EAST ARROW" . #x002921) ("NORTH EAST AND SOUTH WEST ARROW" . #x002922) ("NORTH WEST ARROW WITH HOOK" . #x002923) ("NORTH EAST ARROW WITH HOOK" . #x002924) ("SOUTH EAST ARROW WITH HOOK" . #x002925) ("SOUTH WEST ARROW WITH HOOK" . #x002926) ("NORTH WEST ARROW AND NORTH EAST ARROW" . #x002927) ("NORTH EAST ARROW AND SOUTH EAST ARROW" . #x002928) ("SOUTH EAST ARROW AND SOUTH WEST ARROW" . #x002929) ("SOUTH WEST ARROW AND NORTH WEST ARROW" . #x00292a) ("RISING DIAGONAL CROSSING FALLING DIAGONAL" . #x00292b) ("FALLING DIAGONAL CROSSING RISING DIAGONAL" . #x00292c) ("SOUTH EAST ARROW CROSSING NORTH EAST ARROW" . #x00292d) ("NORTH EAST ARROW CROSSING SOUTH EAST ARROW" . #x00292e) ("FALLING DIAGONAL CROSSING NORTH EAST ARROW" . #x00292f) ("RISING DIAGONAL CROSSING SOUTH EAST ARROW" . #x002930) ("NORTH EAST ARROW CROSSING NORTH WEST ARROW" . #x002931) ("NORTH WEST ARROW CROSSING NORTH EAST ARROW" . #x002932) ("WAVE ARROW POINTING DIRECTLY RIGHT" . #x002933) ("ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS" . #x002934) ("ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS" . #x002935) ("ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS" . #x002936) ("ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS" . #x002937) ("RIGHT-SIDE ARC CLOCKWISE ARROW" . #x002938) ("LEFT-SIDE ARC ANTICLOCKWISE ARROW" . #x002939) ("TOP ARC ANTICLOCKWISE ARROW" . #x00293a) ("BOTTOM ARC ANTICLOCKWISE ARROW" . #x00293b) ("TOP ARC CLOCKWISE ARROW WITH MINUS" . #x00293c) ("TOP ARC ANTICLOCKWISE ARROW WITH PLUS" . #x00293d) ("LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW" . #x00293e) ("LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW" . #x00293f) ("ANTICLOCKWISE CLOSED CIRCLE ARROW" . #x002940) ("CLOCKWISE CLOSED CIRCLE ARROW" . #x002941) ("RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW" . #x002942) ("LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW" . #x002943) ("SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW" . #x002944) ("RIGHTWARDS ARROW WITH PLUS BELOW" . #x002945) ("LEFTWARDS ARROW WITH PLUS BELOW" . #x002946) ("RIGHTWARDS ARROW THROUGH X" . #x002947) ("LEFT RIGHT ARROW THROUGH SMALL CIRCLE" . #x002948) ("UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE" . #x002949) ("LEFT BARB UP RIGHT BARB DOWN HARPOON" . #x00294a) ("LEFT BARB DOWN RIGHT BARB UP HARPOON" . #x00294b) ("UP BARB RIGHT DOWN BARB LEFT HARPOON" . #x00294c) ("UP BARB LEFT DOWN BARB RIGHT HARPOON" . #x00294d) ("LEFT BARB UP RIGHT BARB UP HARPOON" . #x00294e) ("UP BARB RIGHT DOWN BARB RIGHT HARPOON" . #x00294f) ("LEFT BARB DOWN RIGHT BARB DOWN HARPOON" . #x002950) ("UP BARB LEFT DOWN BARB LEFT HARPOON" . #x002951) ("LEFTWARDS HARPOON WITH BARB UP TO BAR" . #x002952) ("RIGHTWARDS HARPOON WITH BARB UP TO BAR" . #x002953) ("UPWARDS HARPOON WITH BARB RIGHT TO BAR" . #x002954) ("DOWNWARDS HARPOON WITH BARB RIGHT TO BAR" . #x002955) ("LEFTWARDS HARPOON WITH BARB DOWN TO BAR" . #x002956) ("RIGHTWARDS HARPOON WITH BARB DOWN TO BAR" . #x002957) ("UPWARDS HARPOON WITH BARB LEFT TO BAR" . #x002958) ("DOWNWARDS HARPOON WITH BARB LEFT TO BAR" . #x002959) ("LEFTWARDS HARPOON WITH BARB UP FROM BAR" . #x00295a) ("RIGHTWARDS HARPOON WITH BARB UP FROM BAR" . #x00295b) ("UPWARDS HARPOON WITH BARB RIGHT FROM BAR" . #x00295c) ("DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR" . #x00295d) ("LEFTWARDS HARPOON WITH BARB DOWN FROM BAR" . #x00295e) ("RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR" . #x00295f) ("UPWARDS HARPOON WITH BARB LEFT FROM BAR" . #x002960) ("DOWNWARDS HARPOON WITH BARB LEFT FROM BAR" . #x002961) ("LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN" . #x002962) ("UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT" . #x002963) ("RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN" . #x002964) ("DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT" . #x002965) ("LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP" . #x002966) ("LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN" . #x002967) ("RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP" . #x002968) ("RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN" . #x002969) ("LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH" . #x00296a) ("LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH" . #x00296b) ("RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH" . #x00296c) ("RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH" . #x00296d) ("UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT" . #x00296e) ("DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT" . #x00296f) ("RIGHT DOUBLE ARROW WITH ROUNDED HEAD" . #x002970) ("EQUALS SIGN ABOVE RIGHTWARDS ARROW" . #x002971) ("TILDE OPERATOR ABOVE RIGHTWARDS ARROW" . #x002972) ("LEFTWARDS ARROW ABOVE TILDE OPERATOR" . #x002973) ("RIGHTWARDS ARROW ABOVE TILDE OPERATOR" . #x002974) ("RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO" . #x002975) ("LESS-THAN ABOVE LEFTWARDS ARROW" . #x002976) ("LEFTWARDS ARROW THROUGH LESS-THAN" . #x002977) ("GREATER-THAN ABOVE RIGHTWARDS ARROW" . #x002978) ("SUBSET ABOVE RIGHTWARDS ARROW" . #x002979) ("LEFTWARDS ARROW THROUGH SUBSET" . #x00297a) ("SUPERSET ABOVE LEFTWARDS ARROW" . #x00297b) ("LEFT FISH TAIL" . #x00297c) ("RIGHT FISH TAIL" . #x00297d) ("UP FISH TAIL" . #x00297e) ("DOWN FISH TAIL" . #x00297f) ("TRIPLE VERTICAL BAR DELIMITER" . #x002980) ("Z NOTATION SPOT" . #x002981) ("Z NOTATION TYPE COLON" . #x002982) ("LEFT WHITE CURLY BRACKET" . #x002983) ("RIGHT WHITE CURLY BRACKET" . #x002984) ("LEFT WHITE PARENTHESIS" . #x002985) ("RIGHT WHITE PARENTHESIS" . #x002986) ("Z NOTATION LEFT IMAGE BRACKET" . #x002987) ("Z NOTATION RIGHT IMAGE BRACKET" . #x002988) ("Z NOTATION LEFT BINDING BRACKET" . #x002989) ("Z NOTATION RIGHT BINDING BRACKET" . #x00298a) ("LEFT SQUARE BRACKET WITH UNDERBAR" . #x00298b) ("RIGHT SQUARE BRACKET WITH UNDERBAR" . #x00298c) ("LEFT SQUARE BRACKET WITH TICK IN TOP CORNER" . #x00298d) ("RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER" . #x00298e) ("LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER" . #x00298f) ("RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER" . #x002990) ("LEFT ANGLE BRACKET WITH DOT" . #x002991) ("RIGHT ANGLE BRACKET WITH DOT" . #x002992) ("LEFT ARC LESS-THAN BRACKET" . #x002993) ("RIGHT ARC GREATER-THAN BRACKET" . #x002994) ("DOUBLE LEFT ARC GREATER-THAN BRACKET" . #x002995) ("DOUBLE RIGHT ARC LESS-THAN BRACKET" . #x002996) ("LEFT BLACK TORTOISE SHELL BRACKET" . #x002997) ("RIGHT BLACK TORTOISE SHELL BRACKET" . #x002998) ("DOTTED FENCE" . #x002999) ("VERTICAL ZIGZAG LINE" . #x00299a) ("MEASURED ANGLE OPENING LEFT" . #x00299b) ("RIGHT ANGLE VARIANT WITH SQUARE" . #x00299c) ("MEASURED RIGHT ANGLE WITH DOT" . #x00299d) ("ANGLE WITH S INSIDE" . #x00299e) ("ACUTE ANGLE" . #x00299f) ("SPHERICAL ANGLE OPENING LEFT" . #x0029a0) ("SPHERICAL ANGLE OPENING UP" . #x0029a1) ("TURNED ANGLE" . #x0029a2) ("REVERSED ANGLE" . #x0029a3) ("ANGLE WITH UNDERBAR" . #x0029a4) ("REVERSED ANGLE WITH UNDERBAR" . #x0029a5) ("OBLIQUE ANGLE OPENING UP" . #x0029a6) ("OBLIQUE ANGLE OPENING DOWN" . #x0029a7) ("MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT" . #x0029a8) ("MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT" . #x0029a9) ("MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT" . #x0029aa) ("MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT" . #x0029ab) ("MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP" . #x0029ac) ("MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP" . #x0029ad) ("MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN" . #x0029ae) ("MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN" . #x0029af) ("REVERSED EMPTY SET" . #x0029b0) ("EMPTY SET WITH OVERBAR" . #x0029b1) ("EMPTY SET WITH SMALL CIRCLE ABOVE" . #x0029b2) ("EMPTY SET WITH RIGHT ARROW ABOVE" . #x0029b3) ("EMPTY SET WITH LEFT ARROW ABOVE" . #x0029b4) ("CIRCLE WITH HORIZONTAL BAR" . #x0029b5) ("CIRCLED VERTICAL BAR" . #x0029b6) ("CIRCLED PARALLEL" . #x0029b7) ("CIRCLED REVERSE SOLIDUS" . #x0029b8) ("CIRCLED PERPENDICULAR" . #x0029b9) ("CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR" . #x0029ba) ("CIRCLE WITH SUPERIMPOSED X" . #x0029bb) ("CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN" . #x0029bc) ("UP ARROW THROUGH CIRCLE" . #x0029bd) ("CIRCLED WHITE BULLET" . #x0029be) ("CIRCLED BULLET" . #x0029bf) ("CIRCLED LESS-THAN" . #x0029c0) ("CIRCLED GREATER-THAN" . #x0029c1) ("CIRCLE WITH SMALL CIRCLE TO THE RIGHT" . #x0029c2) ("CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT" . #x0029c3) ("SQUARED RISING DIAGONAL SLASH" . #x0029c4) ("SQUARED FALLING DIAGONAL SLASH" . #x0029c5) ("SQUARED ASTERISK" . #x0029c6) ("SQUARED SMALL CIRCLE" . #x0029c7) ("SQUARED SQUARE" . #x0029c8) ("TWO JOINED SQUARES" . #x0029c9) ("TRIANGLE WITH DOT ABOVE" . #x0029ca) ("TRIANGLE WITH UNDERBAR" . #x0029cb) ("S IN TRIANGLE" . #x0029cc) ("TRIANGLE WITH SERIFS AT BOTTOM" . #x0029cd) ("RIGHT TRIANGLE ABOVE LEFT TRIANGLE" . #x0029ce) ("LEFT TRIANGLE BESIDE VERTICAL BAR" . #x0029cf) ("VERTICAL BAR BESIDE RIGHT TRIANGLE" . #x0029d0) ("BOWTIE WITH LEFT HALF BLACK" . #x0029d1) ("BOWTIE WITH RIGHT HALF BLACK" . #x0029d2) ("BLACK BOWTIE" . #x0029d3) ("TIMES WITH LEFT HALF BLACK" . #x0029d4) ("TIMES WITH RIGHT HALF BLACK" . #x0029d5) ("WHITE HOURGLASS" . #x0029d6) ("BLACK HOURGLASS" . #x0029d7) ("LEFT WIGGLY FENCE" . #x0029d8) ("RIGHT WIGGLY FENCE" . #x0029d9) ("LEFT DOUBLE WIGGLY FENCE" . #x0029da) ("RIGHT DOUBLE WIGGLY FENCE" . #x0029db) ("INCOMPLETE INFINITY" . #x0029dc) ("TIE OVER INFINITY" . #x0029dd) ("INFINITY NEGATED WITH VERTICAL BAR" . #x0029de) ("DOUBLE-ENDED MULTIMAP" . #x0029df) ("SQUARE WITH CONTOURED OUTLINE" . #x0029e0) ("INCREASES AS" . #x0029e1) ("SHUFFLE PRODUCT" . #x0029e2) ("EQUALS SIGN AND SLANTED PARALLEL" . #x0029e3) ("EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE" . #x0029e4) ("IDENTICAL TO AND SLANTED PARALLEL" . #x0029e5) ("GLEICH STARK" . #x0029e6) ("THERMODYNAMIC" . #x0029e7) ("DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK" . #x0029e8) ("DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK" . #x0029e9) ("BLACK DIAMOND WITH DOWN ARROW" . #x0029ea) ("BLACK LOZENGE" . #x0029eb) ("WHITE CIRCLE WITH DOWN ARROW" . #x0029ec) ("BLACK CIRCLE WITH DOWN ARROW" . #x0029ed) ("ERROR-BARRED WHITE SQUARE" . #x0029ee) ("ERROR-BARRED BLACK SQUARE" . #x0029ef) ("ERROR-BARRED WHITE DIAMOND" . #x0029f0) ("ERROR-BARRED BLACK DIAMOND" . #x0029f1) ("ERROR-BARRED WHITE CIRCLE" . #x0029f2) ("ERROR-BARRED BLACK CIRCLE" . #x0029f3) ("RULE-DELAYED" . #x0029f4) ("REVERSE SOLIDUS OPERATOR" . #x0029f5) ("SOLIDUS WITH OVERBAR" . #x0029f6) ("REVERSE SOLIDUS WITH HORIZONTAL STROKE" . #x0029f7) ("BIG SOLIDUS" . #x0029f8) ("BIG REVERSE SOLIDUS" . #x0029f9) ("DOUBLE PLUS" . #x0029fa) ("TRIPLE PLUS" . #x0029fb) ("LEFT-POINTING CURVED ANGLE BRACKET" . #x0029fc) ("RIGHT-POINTING CURVED ANGLE BRACKET" . #x0029fd) ("TINY" . #x0029fe) ("MINY" . #x0029ff) ("N-ARY CIRCLED DOT OPERATOR" . #x002a00) ("N-ARY CIRCLED PLUS OPERATOR" . #x002a01) ("N-ARY CIRCLED TIMES OPERATOR" . #x002a02) ("N-ARY UNION OPERATOR WITH DOT" . #x002a03) ("N-ARY UNION OPERATOR WITH PLUS" . #x002a04) ("N-ARY SQUARE INTERSECTION OPERATOR" . #x002a05) ("N-ARY SQUARE UNION OPERATOR" . #x002a06) ("TWO LOGICAL AND OPERATOR" . #x002a07) ("TWO LOGICAL OR OPERATOR" . #x002a08) ("N-ARY TIMES OPERATOR" . #x002a09) ("MODULO TWO SUM" . #x002a0a) ("SUMMATION WITH INTEGRAL" . #x002a0b) ("QUADRUPLE INTEGRAL OPERATOR" . #x002a0c) ("FINITE PART INTEGRAL" . #x002a0d) ("INTEGRAL WITH DOUBLE STROKE" . #x002a0e) ("INTEGRAL AVERAGE WITH SLASH" . #x002a0f) ("CIRCULATION FUNCTION" . #x002a10) ("ANTICLOCKWISE INTEGRATION" . #x002a11) ("LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE" . #x002a12) ("LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE" . #x002a13) ("LINE INTEGRATION NOT INCLUDING THE POLE" . #x002a14) ("INTEGRAL AROUND A POINT OPERATOR" . #x002a15) ("QUATERNION INTEGRAL OPERATOR" . #x002a16) ("INTEGRAL WITH LEFTWARDS ARROW WITH HOOK" . #x002a17) ("INTEGRAL WITH TIMES SIGN" . #x002a18) ("INTEGRAL WITH INTERSECTION" . #x002a19) ("INTEGRAL WITH UNION" . #x002a1a) ("INTEGRAL WITH OVERBAR" . #x002a1b) ("INTEGRAL WITH UNDERBAR" . #x002a1c) ("JOIN" . #x002a1d) ("LARGE LEFT TRIANGLE OPERATOR" . #x002a1e) ("Z NOTATION SCHEMA COMPOSITION" . #x002a1f) ("Z NOTATION SCHEMA PIPING" . #x002a20) ("Z NOTATION SCHEMA PROJECTION" . #x002a21) ("PLUS SIGN WITH SMALL CIRCLE ABOVE" . #x002a22) ("PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE" . #x002a23) ("PLUS SIGN WITH TILDE ABOVE" . #x002a24) ("PLUS SIGN WITH DOT BELOW" . #x002a25) ("PLUS SIGN WITH TILDE BELOW" . #x002a26) ("PLUS SIGN WITH SUBSCRIPT TWO" . #x002a27) ("PLUS SIGN WITH BLACK TRIANGLE" . #x002a28) ("MINUS SIGN WITH COMMA ABOVE" . #x002a29) ("MINUS SIGN WITH DOT BELOW" . #x002a2a) ("MINUS SIGN WITH FALLING DOTS" . #x002a2b) ("MINUS SIGN WITH RISING DOTS" . #x002a2c) ("PLUS SIGN IN LEFT HALF CIRCLE" . #x002a2d) ("PLUS SIGN IN RIGHT HALF CIRCLE" . #x002a2e) ("VECTOR OR CROSS PRODUCT" . #x002a2f) ("MULTIPLICATION SIGN WITH DOT ABOVE" . #x002a30) ("MULTIPLICATION SIGN WITH UNDERBAR" . #x002a31) ("SEMIDIRECT PRODUCT WITH BOTTOM CLOSED" . #x002a32) ("SMASH PRODUCT" . #x002a33) ("MULTIPLICATION SIGN IN LEFT HALF CIRCLE" . #x002a34) ("MULTIPLICATION SIGN IN RIGHT HALF CIRCLE" . #x002a35) ("CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT" . #x002a36) ("MULTIPLICATION SIGN IN DOUBLE CIRCLE" . #x002a37) ("CIRCLED DIVISION SIGN" . #x002a38) ("PLUS SIGN IN TRIANGLE" . #x002a39) ("MINUS SIGN IN TRIANGLE" . #x002a3a) ("MULTIPLICATION SIGN IN TRIANGLE" . #x002a3b) ("INTERIOR PRODUCT" . #x002a3c) ("RIGHTHAND INTERIOR PRODUCT" . #x002a3d) ("Z NOTATION RELATIONAL COMPOSITION" . #x002a3e) ("AMALGAMATION OR COPRODUCT" . #x002a3f) ("INTERSECTION WITH DOT" . #x002a40) ("UNION WITH MINUS SIGN" . #x002a41) ("UNION WITH OVERBAR" . #x002a42) ("INTERSECTION WITH OVERBAR" . #x002a43) ("INTERSECTION WITH LOGICAL AND" . #x002a44) ("UNION WITH LOGICAL OR" . #x002a45) ("UNION ABOVE INTERSECTION" . #x002a46) ("INTERSECTION ABOVE UNION" . #x002a47) ("UNION ABOVE BAR ABOVE INTERSECTION" . #x002a48) ("INTERSECTION ABOVE BAR ABOVE UNION" . #x002a49) ("UNION BESIDE AND JOINED WITH UNION" . #x002a4a) ("INTERSECTION BESIDE AND JOINED WITH INTERSECTION" . #x002a4b) ("CLOSED UNION WITH SERIFS" . #x002a4c) ("CLOSED INTERSECTION WITH SERIFS" . #x002a4d) ("DOUBLE SQUARE INTERSECTION" . #x002a4e) ("DOUBLE SQUARE UNION" . #x002a4f) ("CLOSED UNION WITH SERIFS AND SMASH PRODUCT" . #x002a50) ("LOGICAL AND WITH DOT ABOVE" . #x002a51) ("LOGICAL OR WITH DOT ABOVE" . #x002a52) ("DOUBLE LOGICAL AND" . #x002a53) ("DOUBLE LOGICAL OR" . #x002a54) ("TWO INTERSECTING LOGICAL AND" . #x002a55) ("TWO INTERSECTING LOGICAL OR" . #x002a56) ("SLOPING LARGE OR" . #x002a57) ("SLOPING LARGE AND" . #x002a58) ("LOGICAL OR OVERLAPPING LOGICAL AND" . #x002a59) ("LOGICAL AND WITH MIDDLE STEM" . #x002a5a) ("LOGICAL OR WITH MIDDLE STEM" . #x002a5b) ("LOGICAL AND WITH HORIZONTAL DASH" . #x002a5c) ("LOGICAL OR WITH HORIZONTAL DASH" . #x002a5d) ("LOGICAL AND WITH DOUBLE OVERBAR" . #x002a5e) ("LOGICAL AND WITH UNDERBAR" . #x002a5f) ("LOGICAL AND WITH DOUBLE UNDERBAR" . #x002a60) ("SMALL VEE WITH UNDERBAR" . #x002a61) ("LOGICAL OR WITH DOUBLE OVERBAR" . #x002a62) ("LOGICAL OR WITH DOUBLE UNDERBAR" . #x002a63) ("Z NOTATION DOMAIN ANTIRESTRICTION" . #x002a64) ("Z NOTATION RANGE ANTIRESTRICTION" . #x002a65) ("EQUALS SIGN WITH DOT BELOW" . #x002a66) ("IDENTICAL WITH DOT ABOVE" . #x002a67) ("TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE" . #x002a68) ("TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE" . #x002a69) ("TILDE OPERATOR WITH DOT ABOVE" . #x002a6a) ("TILDE OPERATOR WITH RISING DOTS" . #x002a6b) ("SIMILAR MINUS SIMILAR" . #x002a6c) ("CONGRUENT WITH DOT ABOVE" . #x002a6d) ("EQUALS WITH ASTERISK" . #x002a6e) ("ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT" . #x002a6f) ("APPROXIMATELY EQUAL OR EQUAL TO" . #x002a70) ("EQUALS SIGN ABOVE PLUS SIGN" . #x002a71) ("PLUS SIGN ABOVE EQUALS SIGN" . #x002a72) ("EQUALS SIGN ABOVE TILDE OPERATOR" . #x002a73) ("DOUBLE COLON EQUAL" . #x002a74) ("TWO CONSECUTIVE EQUALS SIGNS" . #x002a75) ("THREE CONSECUTIVE EQUALS SIGNS" . #x002a76) ("EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW" . #x002a77) ("EQUIVALENT WITH FOUR DOTS ABOVE" . #x002a78) ("LESS-THAN WITH CIRCLE INSIDE" . #x002a79) ("GREATER-THAN WITH CIRCLE INSIDE" . #x002a7a) ("LESS-THAN WITH QUESTION MARK ABOVE" . #x002a7b) ("GREATER-THAN WITH QUESTION MARK ABOVE" . #x002a7c) ("LESS-THAN OR SLANTED EQUAL TO" . #x002a7d) ("GREATER-THAN OR SLANTED EQUAL TO" . #x002a7e) ("LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE" . #x002a7f) ("GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE" . #x002a80) ("LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE" . #x002a81) ("GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE" . #x002a82) ("LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT" . #x002a83) ("GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT" . #x002a84) ("LESS-THAN OR APPROXIMATE" . #x002a85) ("GREATER-THAN OR APPROXIMATE" . #x002a86) ("LESS-THAN AND SINGLE-LINE NOT EQUAL TO" . #x002a87) ("GREATER-THAN AND SINGLE-LINE NOT EQUAL TO" . #x002a88) ("LESS-THAN AND NOT APPROXIMATE" . #x002a89) ("GREATER-THAN AND NOT APPROXIMATE" . #x002a8a) ("LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN" . #x002a8b) ("GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN" . #x002a8c) ("LESS-THAN ABOVE SIMILAR OR EQUAL" . #x002a8d) ("GREATER-THAN ABOVE SIMILAR OR EQUAL" . #x002a8e) ("LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN" . #x002a8f) ("GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN" . #x002a90) ("LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL" . #x002a91) ("GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL" . #x002a92) ("LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL" . #x002a93) ("GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL" . #x002a94) ("SLANTED EQUAL TO OR LESS-THAN" . #x002a95) ("SLANTED EQUAL TO OR GREATER-THAN" . #x002a96) ("SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE" . #x002a97) ("SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE" . #x002a98) ("DOUBLE-LINE EQUAL TO OR LESS-THAN" . #x002a99) ("DOUBLE-LINE EQUAL TO OR GREATER-THAN" . #x002a9a) ("DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN" . #x002a9b) ("DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN" . #x002a9c) ("SIMILAR OR LESS-THAN" . #x002a9d) ("SIMILAR OR GREATER-THAN" . #x002a9e) ("SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN" . #x002a9f) ("SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN" . #x002aa0) ("DOUBLE NESTED LESS-THAN" . #x002aa1) ("DOUBLE NESTED GREATER-THAN" . #x002aa2) ("DOUBLE NESTED LESS-THAN WITH UNDERBAR" . #x002aa3) ("GREATER-THAN OVERLAPPING LESS-THAN" . #x002aa4) ("GREATER-THAN BESIDE LESS-THAN" . #x002aa5) ("LESS-THAN CLOSED BY CURVE" . #x002aa6) ("GREATER-THAN CLOSED BY CURVE" . #x002aa7) ("LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL" . #x002aa8) ("GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL" . #x002aa9) ("SMALLER THAN" . #x002aaa) ("LARGER THAN" . #x002aab) ("SMALLER THAN OR EQUAL TO" . #x002aac) ("LARGER THAN OR EQUAL TO" . #x002aad) ("EQUALS SIGN WITH BUMPY ABOVE" . #x002aae) ("PRECEDES ABOVE SINGLE-LINE EQUALS SIGN" . #x002aaf) ("SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN" . #x002ab0) ("PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO" . #x002ab1) ("SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO" . #x002ab2) ("PRECEDES ABOVE EQUALS SIGN" . #x002ab3) ("SUCCEEDS ABOVE EQUALS SIGN" . #x002ab4) ("PRECEDES ABOVE NOT EQUAL TO" . #x002ab5) ("SUCCEEDS ABOVE NOT EQUAL TO" . #x002ab6) ("PRECEDES ABOVE ALMOST EQUAL TO" . #x002ab7) ("SUCCEEDS ABOVE ALMOST EQUAL TO" . #x002ab8) ("PRECEDES ABOVE NOT ALMOST EQUAL TO" . #x002ab9) ("SUCCEEDS ABOVE NOT ALMOST EQUAL TO" . #x002aba) ("DOUBLE PRECEDES" . #x002abb) ("DOUBLE SUCCEEDS" . #x002abc) ("SUBSET WITH DOT" . #x002abd) ("SUPERSET WITH DOT" . #x002abe) ("SUBSET WITH PLUS SIGN BELOW" . #x002abf) ("SUPERSET WITH PLUS SIGN BELOW" . #x002ac0) ("SUBSET WITH MULTIPLICATION SIGN BELOW" . #x002ac1) ("SUPERSET WITH MULTIPLICATION SIGN BELOW" . #x002ac2) ("SUBSET OF OR EQUAL TO WITH DOT ABOVE" . #x002ac3) ("SUPERSET OF OR EQUAL TO WITH DOT ABOVE" . #x002ac4) ("SUBSET OF ABOVE EQUALS SIGN" . #x002ac5) ("SUPERSET OF ABOVE EQUALS SIGN" . #x002ac6) ("SUBSET OF ABOVE TILDE OPERATOR" . #x002ac7) ("SUPERSET OF ABOVE TILDE OPERATOR" . #x002ac8) ("SUBSET OF ABOVE ALMOST EQUAL TO" . #x002ac9) ("SUPERSET OF ABOVE ALMOST EQUAL TO" . #x002aca) ("SUBSET OF ABOVE NOT EQUAL TO" . #x002acb) ("SUPERSET OF ABOVE NOT EQUAL TO" . #x002acc) ("SQUARE LEFT OPEN BOX OPERATOR" . #x002acd) ("SQUARE RIGHT OPEN BOX OPERATOR" . #x002ace) ("CLOSED SUBSET" . #x002acf) ("CLOSED SUPERSET" . #x002ad0) ("CLOSED SUBSET OR EQUAL TO" . #x002ad1) ("CLOSED SUPERSET OR EQUAL TO" . #x002ad2) ("SUBSET ABOVE SUPERSET" . #x002ad3) ("SUPERSET ABOVE SUBSET" . #x002ad4) ("SUBSET ABOVE SUBSET" . #x002ad5) ("SUPERSET ABOVE SUPERSET" . #x002ad6) ("SUPERSET BESIDE SUBSET" . #x002ad7) ("SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET" . #x002ad8) ("ELEMENT OF OPENING DOWNWARDS" . #x002ad9) ("PITCHFORK WITH TEE TOP" . #x002ada) ("TRANSVERSAL INTERSECTION" . #x002adb) ("FORKING" . #x002adc) ("NONFORKING" . #x002add) ("SHORT LEFT TACK" . #x002ade) ("SHORT DOWN TACK" . #x002adf) ("SHORT UP TACK" . #x002ae0) ("PERPENDICULAR WITH S" . #x002ae1) ("VERTICAL BAR TRIPLE RIGHT TURNSTILE" . #x002ae2) ("DOUBLE VERTICAL BAR LEFT TURNSTILE" . #x002ae3) ("VERTICAL BAR DOUBLE LEFT TURNSTILE" . #x002ae4) ("DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE" . #x002ae5) ("LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL" . #x002ae6) ("SHORT DOWN TACK WITH OVERBAR" . #x002ae7) ("SHORT UP TACK WITH UNDERBAR" . #x002ae8) ("SHORT UP TACK ABOVE SHORT DOWN TACK" . #x002ae9) ("DOUBLE DOWN TACK" . #x002aea) ("DOUBLE UP TACK" . #x002aeb) ("DOUBLE STROKE NOT SIGN" . #x002aec) ("REVERSED DOUBLE STROKE NOT SIGN" . #x002aed) ("DOES NOT DIVIDE WITH REVERSED NEGATION SLASH" . #x002aee) ("VERTICAL LINE WITH CIRCLE ABOVE" . #x002aef) ("VERTICAL LINE WITH CIRCLE BELOW" . #x002af0) ("DOWN TACK WITH CIRCLE BELOW" . #x002af1) ("PARALLEL WITH HORIZONTAL STROKE" . #x002af2) ("PARALLEL WITH TILDE OPERATOR" . #x002af3) ("TRIPLE VERTICAL BAR BINARY RELATION" . #x002af4) ("TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE" . #x002af5) ("TRIPLE COLON OPERATOR" . #x002af6) ("TRIPLE NESTED LESS-THAN" . #x002af7) ("TRIPLE NESTED GREATER-THAN" . #x002af8) ("DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO" . #x002af9) ("DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO" . #x002afa) ("TRIPLE SOLIDUS BINARY RELATION" . #x002afb) ("LARGE TRIPLE VERTICAL BAR OPERATOR" . #x002afc) ("DOUBLE SOLIDUS OPERATOR" . #x002afd) ("WHITE VERTICAL BAR" . #x002afe) ("N-ARY WHITE VERTICAL BAR" . #x002aff) ("IDEOGRAPHIC SPACE" . #x003000) ("IDEOGRAPHIC COMMA" . #x003001) ("IDEOGRAPHIC FULL STOP" . #x003002) ("DITTO MARK" . #x003003) ("JAPANESE INDUSTRIAL STANDARD SYMBOL" . #x003004) ("IDEOGRAPHIC ITERATION MARK" . #x003005) ("IDEOGRAPHIC CLOSING MARK" . #x003006) ("IDEOGRAPHIC NUMBER ZERO" . #x003007) ("LEFT ANGLE BRACKET" . #x003008) ("RIGHT ANGLE BRACKET" . #x003009) ("LEFT DOUBLE ANGLE BRACKET" . #x00300a) ("RIGHT DOUBLE ANGLE BRACKET" . #x00300b) ("LEFT CORNER BRACKET" . #x00300c) ("RIGHT CORNER BRACKET" . #x00300d) ("LEFT WHITE CORNER BRACKET" . #x00300e) ("RIGHT WHITE CORNER BRACKET" . #x00300f) ("LEFT BLACK LENTICULAR BRACKET" . #x003010) ("RIGHT BLACK LENTICULAR BRACKET" . #x003011) ("POSTAL MARK" . #x003012) ("GETA MARK" . #x003013) ("LEFT TORTOISE SHELL BRACKET" . #x003014) ("RIGHT TORTOISE SHELL BRACKET" . #x003015) ("LEFT WHITE LENTICULAR BRACKET" . #x003016) ("RIGHT WHITE LENTICULAR BRACKET" . #x003017) ("LEFT WHITE TORTOISE SHELL BRACKET" . #x003018) ("RIGHT WHITE TORTOISE SHELL BRACKET" . #x003019) ("LEFT WHITE SQUARE BRACKET" . #x00301a) ("RIGHT WHITE SQUARE BRACKET" . #x00301b) ("WAVE DASH" . #x00301c) ("REVERSED DOUBLE PRIME QUOTATION MARK" . #x00301d) ("DOUBLE PRIME QUOTATION MARK" . #x00301e) ("LOW DOUBLE PRIME QUOTATION MARK" . #x00301f) ("POSTAL MARK FACE" . #x003020) ("HANGZHOU NUMERAL ONE" . #x003021) ("HANGZHOU NUMERAL TWO" . #x003022) ("HANGZHOU NUMERAL THREE" . #x003023) ("HANGZHOU NUMERAL FOUR" . #x003024) ("HANGZHOU NUMERAL FIVE" . #x003025) ("HANGZHOU NUMERAL SIX" . #x003026) ("HANGZHOU NUMERAL SEVEN" . #x003027) ("HANGZHOU NUMERAL EIGHT" . #x003028) ("HANGZHOU NUMERAL NINE" . #x003029) ("IDEOGRAPHIC LEVEL TONE MARK" . #x00302a) ("IDEOGRAPHIC RISING TONE MARK" . #x00302b) ("IDEOGRAPHIC DEPARTING TONE MARK" . #x00302c) ("IDEOGRAPHIC ENTERING TONE MARK" . #x00302d) ("HANGUL SINGLE DOT TONE MARK" . #x00302e) ("HANGUL DOUBLE DOT TONE MARK" . #x00302f) ("WAVY DASH" . #x003030) ("VERTICAL KANA REPEAT MARK" . #x003031) ("VERTICAL KANA REPEAT WITH VOICED SOUND MARK" . #x003032) ("VERTICAL KANA REPEAT MARK UPPER HALF" . #x003033) ("VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF" . #x003034) ("VERTICAL KANA REPEAT MARK LOWER HALF" . #x003035) ("CIRCLED POSTAL MARK" . #x003036) ("IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL" . #x003037) ("HANGZHOU NUMERAL TEN" . #x003038) ("HANGZHOU NUMERAL TWENTY" . #x003039) ("HANGZHOU NUMERAL THIRTY" . #x00303a) ("VERTICAL IDEOGRAPHIC ITERATION MARK" . #x00303b) ("MASU MARK" . #x00303c) ("PART ALTERNATION MARK" . #x00303d) ("IDEOGRAPHIC VARIATION INDICATOR" . #x00303e) ("IDEOGRAPHIC HALF FILL SPACE" . #x00303f) ("HIRAGANA LETTER SMALL A" . #x003041) ("HIRAGANA LETTER A" . #x003042) ("HIRAGANA LETTER SMALL I" . #x003043) ("HIRAGANA LETTER I" . #x003044) ("HIRAGANA LETTER SMALL U" . #x003045) ("HIRAGANA LETTER U" . #x003046) ("HIRAGANA LETTER SMALL E" . #x003047) ("HIRAGANA LETTER E" . #x003048) ("HIRAGANA LETTER SMALL O" . #x003049) ("HIRAGANA LETTER O" . #x00304a) ("HIRAGANA LETTER KA" . #x00304b) ("HIRAGANA LETTER GA" . #x00304c) ("HIRAGANA LETTER KI" . #x00304d) ("HIRAGANA LETTER GI" . #x00304e) ("HIRAGANA LETTER KU" . #x00304f) ("HIRAGANA LETTER GU" . #x003050) ("HIRAGANA LETTER KE" . #x003051) ("HIRAGANA LETTER GE" . #x003052) ("HIRAGANA LETTER KO" . #x003053) ("HIRAGANA LETTER GO" . #x003054) ("HIRAGANA LETTER SA" . #x003055) ("HIRAGANA LETTER ZA" . #x003056) ("HIRAGANA LETTER SI" . #x003057) ("HIRAGANA LETTER ZI" . #x003058) ("HIRAGANA LETTER SU" . #x003059) ("HIRAGANA LETTER ZU" . #x00305a) ("HIRAGANA LETTER SE" . #x00305b) ("HIRAGANA LETTER ZE" . #x00305c) ("HIRAGANA LETTER SO" . #x00305d) ("HIRAGANA LETTER ZO" . #x00305e) ("HIRAGANA LETTER TA" . #x00305f) ("HIRAGANA LETTER DA" . #x003060) ("HIRAGANA LETTER TI" . #x003061) ("HIRAGANA LETTER DI" . #x003062) ("HIRAGANA LETTER SMALL TU" . #x003063) ("HIRAGANA LETTER TU" . #x003064) ("HIRAGANA LETTER DU" . #x003065) ("HIRAGANA LETTER TE" . #x003066) ("HIRAGANA LETTER DE" . #x003067) ("HIRAGANA LETTER TO" . #x003068) ("HIRAGANA LETTER DO" . #x003069) ("HIRAGANA LETTER NA" . #x00306a) ("HIRAGANA LETTER NI" . #x00306b) ("HIRAGANA LETTER NU" . #x00306c) ("HIRAGANA LETTER NE" . #x00306d) ("HIRAGANA LETTER NO" . #x00306e) ("HIRAGANA LETTER HA" . #x00306f) ("HIRAGANA LETTER BA" . #x003070) ("HIRAGANA LETTER PA" . #x003071) ("HIRAGANA LETTER HI" . #x003072) ("HIRAGANA LETTER BI" . #x003073) ("HIRAGANA LETTER PI" . #x003074) ("HIRAGANA LETTER HU" . #x003075) ("HIRAGANA LETTER BU" . #x003076) ("HIRAGANA LETTER PU" . #x003077) ("HIRAGANA LETTER HE" . #x003078) ("HIRAGANA LETTER BE" . #x003079) ("HIRAGANA LETTER PE" . #x00307a) ("HIRAGANA LETTER HO" . #x00307b) ("HIRAGANA LETTER BO" . #x00307c) ("HIRAGANA LETTER PO" . #x00307d) ("HIRAGANA LETTER MA" . #x00307e) ("HIRAGANA LETTER MI" . #x00307f) ("HIRAGANA LETTER MU" . #x003080) ("HIRAGANA LETTER ME" . #x003081) ("HIRAGANA LETTER MO" . #x003082) ("HIRAGANA LETTER SMALL YA" . #x003083) ("HIRAGANA LETTER YA" . #x003084) ("HIRAGANA LETTER SMALL YU" . #x003085) ("HIRAGANA LETTER YU" . #x003086) ("HIRAGANA LETTER SMALL YO" . #x003087) ("HIRAGANA LETTER YO" . #x003088) ("HIRAGANA LETTER RA" . #x003089) ("HIRAGANA LETTER RI" . #x00308a) ("HIRAGANA LETTER RU" . #x00308b) ("HIRAGANA LETTER RE" . #x00308c) ("HIRAGANA LETTER RO" . #x00308d) ("HIRAGANA LETTER SMALL WA" . #x00308e) ("HIRAGANA LETTER WA" . #x00308f) ("HIRAGANA LETTER WI" . #x003090) ("HIRAGANA LETTER WE" . #x003091) ("HIRAGANA LETTER WO" . #x003092) ("HIRAGANA LETTER N" . #x003093) ("HIRAGANA LETTER VU" . #x003094) ("HIRAGANA LETTER SMALL KA" . #x003095) ("HIRAGANA LETTER SMALL KE" . #x003096) ("COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK" . #x003099) ("COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK" . #x00309a) ("KATAKANA-HIRAGANA VOICED SOUND MARK" . #x00309b) ("KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK" . #x00309c) ("HIRAGANA ITERATION MARK" . #x00309d) ("HIRAGANA VOICED ITERATION MARK" . #x00309e) ("HIRAGANA DIGRAPH YORI" . #x00309f) ("KATAKANA-HIRAGANA DOUBLE HYPHEN" . #x0030a0) ("KATAKANA LETTER SMALL A" . #x0030a1) ("KATAKANA LETTER A" . #x0030a2) ("KATAKANA LETTER SMALL I" . #x0030a3) ("KATAKANA LETTER I" . #x0030a4) ("KATAKANA LETTER SMALL U" . #x0030a5) ("KATAKANA LETTER U" . #x0030a6) ("KATAKANA LETTER SMALL E" . #x0030a7) ("KATAKANA LETTER E" . #x0030a8) ("KATAKANA LETTER SMALL O" . #x0030a9) ("KATAKANA LETTER O" . #x0030aa) ("KATAKANA LETTER KA" . #x0030ab) ("KATAKANA LETTER GA" . #x0030ac) ("KATAKANA LETTER KI" . #x0030ad) ("KATAKANA LETTER GI" . #x0030ae) ("KATAKANA LETTER KU" . #x0030af) ("KATAKANA LETTER GU" . #x0030b0) ("KATAKANA LETTER KE" . #x0030b1) ("KATAKANA LETTER GE" . #x0030b2) ("KATAKANA LETTER KO" . #x0030b3) ("KATAKANA LETTER GO" . #x0030b4) ("KATAKANA LETTER SA" . #x0030b5) ("KATAKANA LETTER ZA" . #x0030b6) ("KATAKANA LETTER SI" . #x0030b7) ("KATAKANA LETTER ZI" . #x0030b8) ("KATAKANA LETTER SU" . #x0030b9) ("KATAKANA LETTER ZU" . #x0030ba) ("KATAKANA LETTER SE" . #x0030bb) ("KATAKANA LETTER ZE" . #x0030bc) ("KATAKANA LETTER SO" . #x0030bd) ("KATAKANA LETTER ZO" . #x0030be) ("KATAKANA LETTER TA" . #x0030bf) ("KATAKANA LETTER DA" . #x0030c0) ("KATAKANA LETTER TI" . #x0030c1) ("KATAKANA LETTER DI" . #x0030c2) ("KATAKANA LETTER SMALL TU" . #x0030c3) ("KATAKANA LETTER TU" . #x0030c4) ("KATAKANA LETTER DU" . #x0030c5) ("KATAKANA LETTER TE" . #x0030c6) ("KATAKANA LETTER DE" . #x0030c7) ("KATAKANA LETTER TO" . #x0030c8) ("KATAKANA LETTER DO" . #x0030c9) ("KATAKANA LETTER NA" . #x0030ca) ("KATAKANA LETTER NI" . #x0030cb) ("KATAKANA LETTER NU" . #x0030cc) ("KATAKANA LETTER NE" . #x0030cd) ("KATAKANA LETTER NO" . #x0030ce) ("KATAKANA LETTER HA" . #x0030cf) ("KATAKANA LETTER BA" . #x0030d0) ("KATAKANA LETTER PA" . #x0030d1) ("KATAKANA LETTER HI" . #x0030d2) ("KATAKANA LETTER BI" . #x0030d3) ("KATAKANA LETTER PI" . #x0030d4) ("KATAKANA LETTER HU" . #x0030d5) ("KATAKANA LETTER BU" . #x0030d6) ("KATAKANA LETTER PU" . #x0030d7) ("KATAKANA LETTER HE" . #x0030d8) ("KATAKANA LETTER BE" . #x0030d9) ("KATAKANA LETTER PE" . #x0030da) ("KATAKANA LETTER HO" . #x0030db) ("KATAKANA LETTER BO" . #x0030dc) ("KATAKANA LETTER PO" . #x0030dd) ("KATAKANA LETTER MA" . #x0030de) ("KATAKANA LETTER MI" . #x0030df) ("KATAKANA LETTER MU" . #x0030e0) ("KATAKANA LETTER ME" . #x0030e1) ("KATAKANA LETTER MO" . #x0030e2) ("KATAKANA LETTER SMALL YA" . #x0030e3) ("KATAKANA LETTER YA" . #x0030e4) ("KATAKANA LETTER SMALL YU" . #x0030e5) ("KATAKANA LETTER YU" . #x0030e6) ("KATAKANA LETTER SMALL YO" . #x0030e7) ("KATAKANA LETTER YO" . #x0030e8) ("KATAKANA LETTER RA" . #x0030e9) ("KATAKANA LETTER RI" . #x0030ea) ("KATAKANA LETTER RU" . #x0030eb) ("KATAKANA LETTER RE" . #x0030ec) ("KATAKANA LETTER RO" . #x0030ed) ("KATAKANA LETTER SMALL WA" . #x0030ee) ("KATAKANA LETTER WA" . #x0030ef) ("KATAKANA LETTER WI" . #x0030f0) ("KATAKANA LETTER WE" . #x0030f1) ("KATAKANA LETTER WO" . #x0030f2) ("KATAKANA LETTER N" . #x0030f3) ("KATAKANA LETTER VU" . #x0030f4) ("KATAKANA LETTER SMALL KA" . #x0030f5) ("KATAKANA LETTER SMALL KE" . #x0030f6) ("KATAKANA LETTER VA" . #x0030f7) ("KATAKANA LETTER VI" . #x0030f8) ("KATAKANA LETTER VE" . #x0030f9) ("KATAKANA LETTER VO" . #x0030fa) ("KATAKANA MIDDLE DOT" . #x0030fb) ("KATAKANA-HIRAGANA PROLONGED SOUND MARK" . #x0030fc) ("KATAKANA ITERATION MARK" . #x0030fd) ("KATAKANA VOICED ITERATION MARK" . #x0030fe) ("KATAKANA DIGRAPH KOTO" . #x0030ff) ("LATIN SMALL LIGATURE FF" . #x00fb00) ("LATIN SMALL LIGATURE FI" . #x00fb01) ("LATIN SMALL LIGATURE FL" . #x00fb02) ("LATIN SMALL LIGATURE FFI" . #x00fb03) ("LATIN SMALL LIGATURE FFL" . #x00fb04) ("LATIN SMALL LIGATURE LONG S T" . #x00fb05) ("LATIN SMALL LIGATURE ST" . #x00fb06) ("ARMENIAN SMALL LIGATURE MEN NOW" . #x00fb13) ("ARMENIAN SMALL LIGATURE MEN ECH" . #x00fb14) ("ARMENIAN SMALL LIGATURE MEN INI" . #x00fb15) ("ARMENIAN SMALL LIGATURE VEW NOW" . #x00fb16) ("ARMENIAN SMALL LIGATURE MEN XEH" . #x00fb17) ("HEBREW LETTER YOD WITH HIRIQ" . #x00fb1d) ("HEBREW POINT JUDEO-SPANISH VARIKA" . #x00fb1e) ("HEBREW LIGATURE YIDDISH YOD YOD PATAH" . #x00fb1f) ("HEBREW LETTER ALTERNATIVE AYIN" . #x00fb20) ("HEBREW LETTER WIDE ALEF" . #x00fb21) ("HEBREW LETTER WIDE DALET" . #x00fb22) ("HEBREW LETTER WIDE HE" . #x00fb23) ("HEBREW LETTER WIDE KAF" . #x00fb24) ("HEBREW LETTER WIDE LAMED" . #x00fb25) ("HEBREW LETTER WIDE FINAL MEM" . #x00fb26) ("HEBREW LETTER WIDE RESH" . #x00fb27) ("HEBREW LETTER WIDE TAV" . #x00fb28) ("HEBREW LETTER ALTERNATIVE PLUS SIGN" . #x00fb29) ("HEBREW LETTER SHIN WITH SHIN DOT" . #x00fb2a) ("HEBREW LETTER SHIN WITH SIN DOT" . #x00fb2b) ("HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT" . #x00fb2c) ("HEBREW LETTER SHIN WITH DAGESH AND SIN DOT" . #x00fb2d) ("HEBREW LETTER ALEF WITH PATAH" . #x00fb2e) ("HEBREW LETTER ALEF WITH QAMATS" . #x00fb2f) ("HEBREW LETTER ALEF WITH MAPIQ" . #x00fb30) ("HEBREW LETTER BET WITH DAGESH" . #x00fb31) ("HEBREW LETTER GIMEL WITH DAGESH" . #x00fb32) ("HEBREW LETTER DALET WITH DAGESH" . #x00fb33) ("HEBREW LETTER HE WITH MAPIQ" . #x00fb34) ("HEBREW LETTER VAV WITH DAGESH" . #x00fb35) ("HEBREW LETTER ZAYIN WITH DAGESH" . #x00fb36) ("HEBREW LETTER TET WITH DAGESH" . #x00fb38) ("HEBREW LETTER YOD WITH DAGESH" . #x00fb39) ("HEBREW LETTER FINAL KAF WITH DAGESH" . #x00fb3a) ("HEBREW LETTER KAF WITH DAGESH" . #x00fb3b) ("HEBREW LETTER LAMED WITH DAGESH" . #x00fb3c) ("HEBREW LETTER MEM WITH DAGESH" . #x00fb3e) ("HEBREW LETTER NUN WITH DAGESH" . #x00fb40) ("HEBREW LETTER SAMEKH WITH DAGESH" . #x00fb41) ("HEBREW LETTER FINAL PE WITH DAGESH" . #x00fb43) ("HEBREW LETTER PE WITH DAGESH" . #x00fb44) ("HEBREW LETTER TSADI WITH DAGESH" . #x00fb46) ("HEBREW LETTER QOF WITH DAGESH" . #x00fb47) ("HEBREW LETTER RESH WITH DAGESH" . #x00fb48) ("HEBREW LETTER SHIN WITH DAGESH" . #x00fb49) ("HEBREW LETTER TAV WITH DAGESH" . #x00fb4a) ("HEBREW LETTER VAV WITH HOLAM" . #x00fb4b) ("HEBREW LETTER BET WITH RAFE" . #x00fb4c) ("HEBREW LETTER KAF WITH RAFE" . #x00fb4d) ("HEBREW LETTER PE WITH RAFE" . #x00fb4e) ("HEBREW LIGATURE ALEF LAMED" . #x00fb4f) ("ARABIC LETTER ALEF WASLA ISOLATED FORM" . #x00fb50) ("ARABIC LETTER ALEF WASLA FINAL FORM" . #x00fb51) ("ARABIC LETTER BEEH ISOLATED FORM" . #x00fb52) ("ARABIC LETTER BEEH FINAL FORM" . #x00fb53) ("ARABIC LETTER BEEH INITIAL FORM" . #x00fb54) ("ARABIC LETTER BEEH MEDIAL FORM" . #x00fb55) ("ARABIC LETTER PEH ISOLATED FORM" . #x00fb56) ("ARABIC LETTER PEH FINAL FORM" . #x00fb57) ("ARABIC LETTER PEH INITIAL FORM" . #x00fb58) ("ARABIC LETTER PEH MEDIAL FORM" . #x00fb59) ("ARABIC LETTER BEHEH ISOLATED FORM" . #x00fb5a) ("ARABIC LETTER BEHEH FINAL FORM" . #x00fb5b) ("ARABIC LETTER BEHEH INITIAL FORM" . #x00fb5c) ("ARABIC LETTER BEHEH MEDIAL FORM" . #x00fb5d) ("ARABIC LETTER TTEHEH ISOLATED FORM" . #x00fb5e) ("ARABIC LETTER TTEHEH FINAL FORM" . #x00fb5f) ("ARABIC LETTER TTEHEH INITIAL FORM" . #x00fb60) ("ARABIC LETTER TTEHEH MEDIAL FORM" . #x00fb61) ("ARABIC LETTER TEHEH ISOLATED FORM" . #x00fb62) ("ARABIC LETTER TEHEH FINAL FORM" . #x00fb63) ("ARABIC LETTER TEHEH INITIAL FORM" . #x00fb64) ("ARABIC LETTER TEHEH MEDIAL FORM" . #x00fb65) ("ARABIC LETTER TTEH ISOLATED FORM" . #x00fb66) ("ARABIC LETTER TTEH FINAL FORM" . #x00fb67) ("ARABIC LETTER TTEH INITIAL FORM" . #x00fb68) ("ARABIC LETTER TTEH MEDIAL FORM" . #x00fb69) ("ARABIC LETTER VEH ISOLATED FORM" . #x00fb6a) ("ARABIC LETTER VEH FINAL FORM" . #x00fb6b) ("ARABIC LETTER VEH INITIAL FORM" . #x00fb6c) ("ARABIC LETTER VEH MEDIAL FORM" . #x00fb6d) ("ARABIC LETTER PEHEH ISOLATED FORM" . #x00fb6e) ("ARABIC LETTER PEHEH FINAL FORM" . #x00fb6f) ("ARABIC LETTER PEHEH INITIAL FORM" . #x00fb70) ("ARABIC LETTER PEHEH MEDIAL FORM" . #x00fb71) ("ARABIC LETTER DYEH ISOLATED FORM" . #x00fb72) ("ARABIC LETTER DYEH FINAL FORM" . #x00fb73) ("ARABIC LETTER DYEH INITIAL FORM" . #x00fb74) ("ARABIC LETTER DYEH MEDIAL FORM" . #x00fb75) ("ARABIC LETTER NYEH ISOLATED FORM" . #x00fb76) ("ARABIC LETTER NYEH FINAL FORM" . #x00fb77) ("ARABIC LETTER NYEH INITIAL FORM" . #x00fb78) ("ARABIC LETTER NYEH MEDIAL FORM" . #x00fb79) ("ARABIC LETTER TCHEH ISOLATED FORM" . #x00fb7a) ("ARABIC LETTER TCHEH FINAL FORM" . #x00fb7b) ("ARABIC LETTER TCHEH INITIAL FORM" . #x00fb7c) ("ARABIC LETTER TCHEH MEDIAL FORM" . #x00fb7d) ("ARABIC LETTER TCHEHEH ISOLATED FORM" . #x00fb7e) ("ARABIC LETTER TCHEHEH FINAL FORM" . #x00fb7f) ("ARABIC LETTER TCHEHEH INITIAL FORM" . #x00fb80) ("ARABIC LETTER TCHEHEH MEDIAL FORM" . #x00fb81) ("ARABIC LETTER DDAHAL ISOLATED FORM" . #x00fb82) ("ARABIC LETTER DDAHAL FINAL FORM" . #x00fb83) ("ARABIC LETTER DAHAL ISOLATED FORM" . #x00fb84) ("ARABIC LETTER DAHAL FINAL FORM" . #x00fb85) ("ARABIC LETTER DUL ISOLATED FORM" . #x00fb86) ("ARABIC LETTER DUL FINAL FORM" . #x00fb87) ("ARABIC LETTER DDAL ISOLATED FORM" . #x00fb88) ("ARABIC LETTER DDAL FINAL FORM" . #x00fb89) ("ARABIC LETTER JEH ISOLATED FORM" . #x00fb8a) ("ARABIC LETTER JEH FINAL FORM" . #x00fb8b) ("ARABIC LETTER RREH ISOLATED FORM" . #x00fb8c) ("ARABIC LETTER RREH FINAL FORM" . #x00fb8d) ("ARABIC LETTER KEHEH ISOLATED FORM" . #x00fb8e) ("ARABIC LETTER KEHEH FINAL FORM" . #x00fb8f) ("ARABIC LETTER KEHEH INITIAL FORM" . #x00fb90) ("ARABIC LETTER KEHEH MEDIAL FORM" . #x00fb91) ("ARABIC LETTER GAF ISOLATED FORM" . #x00fb92) ("ARABIC LETTER GAF FINAL FORM" . #x00fb93) ("ARABIC LETTER GAF INITIAL FORM" . #x00fb94) ("ARABIC LETTER GAF MEDIAL FORM" . #x00fb95) ("ARABIC LETTER GUEH ISOLATED FORM" . #x00fb96) ("ARABIC LETTER GUEH FINAL FORM" . #x00fb97) ("ARABIC LETTER GUEH INITIAL FORM" . #x00fb98) ("ARABIC LETTER GUEH MEDIAL FORM" . #x00fb99) ("ARABIC LETTER NGOEH ISOLATED FORM" . #x00fb9a) ("ARABIC LETTER NGOEH FINAL FORM" . #x00fb9b) ("ARABIC LETTER NGOEH INITIAL FORM" . #x00fb9c) ("ARABIC LETTER NGOEH MEDIAL FORM" . #x00fb9d) ("ARABIC LETTER NOON GHUNNA ISOLATED FORM" . #x00fb9e) ("ARABIC LETTER NOON GHUNNA FINAL FORM" . #x00fb9f) ("ARABIC LETTER RNOON ISOLATED FORM" . #x00fba0) ("ARABIC LETTER RNOON FINAL FORM" . #x00fba1) ("ARABIC LETTER RNOON INITIAL FORM" . #x00fba2) ("ARABIC LETTER RNOON MEDIAL FORM" . #x00fba3) ("ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM" . #x00fba4) ("ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM" . #x00fba5) ("ARABIC LETTER HEH GOAL ISOLATED FORM" . #x00fba6) ("ARABIC LETTER HEH GOAL FINAL FORM" . #x00fba7) ("ARABIC LETTER HEH GOAL INITIAL FORM" . #x00fba8) ("ARABIC LETTER HEH GOAL MEDIAL FORM" . #x00fba9) ("ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM" . #x00fbaa) ("ARABIC LETTER HEH DOACHASHMEE FINAL FORM" . #x00fbab) ("ARABIC LETTER HEH DOACHASHMEE INITIAL FORM" . #x00fbac) ("ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM" . #x00fbad) ("ARABIC LETTER YEH BARREE ISOLATED FORM" . #x00fbae) ("ARABIC LETTER YEH BARREE FINAL FORM" . #x00fbaf) ("ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM" . #x00fbb0) ("ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM" . #x00fbb1) ("ARABIC LETTER NG ISOLATED FORM" . #x00fbd3) ("ARABIC LETTER NG FINAL FORM" . #x00fbd4) ("ARABIC LETTER NG INITIAL FORM" . #x00fbd5) ("ARABIC LETTER NG MEDIAL FORM" . #x00fbd6) ("ARABIC LETTER U ISOLATED FORM" . #x00fbd7) ("ARABIC LETTER U FINAL FORM" . #x00fbd8) ("ARABIC LETTER OE ISOLATED FORM" . #x00fbd9) ("ARABIC LETTER OE FINAL FORM" . #x00fbda) ("ARABIC LETTER YU ISOLATED FORM" . #x00fbdb) ("ARABIC LETTER YU FINAL FORM" . #x00fbdc) ("ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM" . #x00fbdd) ("ARABIC LETTER VE ISOLATED FORM" . #x00fbde) ("ARABIC LETTER VE FINAL FORM" . #x00fbdf) ("ARABIC LETTER KIRGHIZ OE ISOLATED FORM" . #x00fbe0) ("ARABIC LETTER KIRGHIZ OE FINAL FORM" . #x00fbe1) ("ARABIC LETTER KIRGHIZ YU ISOLATED FORM" . #x00fbe2) ("ARABIC LETTER KIRGHIZ YU FINAL FORM" . #x00fbe3) ("ARABIC LETTER E ISOLATED FORM" . #x00fbe4) ("ARABIC LETTER E FINAL FORM" . #x00fbe5) ("ARABIC LETTER E INITIAL FORM" . #x00fbe6) ("ARABIC LETTER E MEDIAL FORM" . #x00fbe7) ("ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM" . #x00fbe8) ("ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM" . #x00fbe9) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM" . #x00fbea) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM" . #x00fbeb) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM" . #x00fbec) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM" . #x00fbed) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM" . #x00fbee) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM" . #x00fbef) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM" . #x00fbf0) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM" . #x00fbf1) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM" . #x00fbf2) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM" . #x00fbf3) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM" . #x00fbf4) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM" . #x00fbf5) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM" . #x00fbf6) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM" . #x00fbf7) ("ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM" . #x00fbf8) ("ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM" . #x00fbf9) ("ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM" . #x00fbfa) ("ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM" . #x00fbfb) ("ARABIC LETTER FARSI YEH ISOLATED FORM" . #x00fbfc) ("ARABIC LETTER FARSI YEH FINAL FORM" . #x00fbfd) ("ARABIC LETTER FARSI YEH INITIAL FORM" . #x00fbfe) ("ARABIC LETTER FARSI YEH MEDIAL FORM" . #x00fbff) ("VARIATION SELECTOR-1" . #x00fe00) ("VARIATION SELECTOR-2" . #x00fe01) ("VARIATION SELECTOR-3" . #x00fe02) ("VARIATION SELECTOR-4" . #x00fe03) ("VARIATION SELECTOR-5" . #x00fe04) ("VARIATION SELECTOR-6" . #x00fe05) ("VARIATION SELECTOR-7" . #x00fe06) ("VARIATION SELECTOR-8" . #x00fe07) ("VARIATION SELECTOR-9" . #x00fe08) ("VARIATION SELECTOR-10" . #x00fe09) ("VARIATION SELECTOR-11" . #x00fe0a) ("VARIATION SELECTOR-12" . #x00fe0b) ("VARIATION SELECTOR-13" . #x00fe0c) ("VARIATION SELECTOR-14" . #x00fe0d) ("VARIATION SELECTOR-15" . #x00fe0e) ("VARIATION SELECTOR-16" . #x00fe0f) ("COMBINING LIGATURE LEFT HALF" . #x00fe20) ("COMBINING LIGATURE RIGHT HALF" . #x00fe21) ("COMBINING DOUBLE TILDE LEFT HALF" . #x00fe22) ("COMBINING DOUBLE TILDE RIGHT HALF" . #x00fe23) ("PRESENTATION FORM FOR VERTICAL TWO DOT LEADER" . #x00fe30) ("PRESENTATION FORM FOR VERTICAL EM DASH" . #x00fe31) ("PRESENTATION FORM FOR VERTICAL EN DASH" . #x00fe32) ("PRESENTATION FORM FOR VERTICAL LOW LINE" . #x00fe33) ("PRESENTATION FORM FOR VERTICAL WAVY LOW LINE" . #x00fe34) ("PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS" . #x00fe35) ("PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS" . #x00fe36) ("PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET" . #x00fe37) ("PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET" . #x00fe38) ("PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET" . #x00fe39) ("PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET" . #x00fe3a) ("PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET" . #x00fe3b) ("PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET" . #x00fe3c) ("PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET" . #x00fe3d) ("PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET" . #x00fe3e) ("PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET" . #x00fe3f) ("PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET" . #x00fe40) ("PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET" . #x00fe41) ("PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET" . #x00fe42) ("PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET" . #x00fe43) ("PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET" . #x00fe44) ("SESAME DOT" . #x00fe45) ("WHITE SESAME DOT" . #x00fe46) ("DASHED OVERLINE" . #x00fe49) ("CENTRELINE OVERLINE" . #x00fe4a) ("WAVY OVERLINE" . #x00fe4b) ("DOUBLE WAVY OVERLINE" . #x00fe4c) ("DASHED LOW LINE" . #x00fe4d) ("CENTRELINE LOW LINE" . #x00fe4e) ("WAVY LOW LINE" . #x00fe4f) ("SMALL COMMA" . #x00fe50) ("SMALL IDEOGRAPHIC COMMA" . #x00fe51) ("SMALL FULL STOP" . #x00fe52) ("SMALL SEMICOLON" . #x00fe54) ("SMALL COLON" . #x00fe55) ("SMALL QUESTION MARK" . #x00fe56) ("SMALL EXCLAMATION MARK" . #x00fe57) ("SMALL EM DASH" . #x00fe58) ("SMALL LEFT PARENTHESIS" . #x00fe59) ("SMALL RIGHT PARENTHESIS" . #x00fe5a) ("SMALL LEFT CURLY BRACKET" . #x00fe5b) ("SMALL RIGHT CURLY BRACKET" . #x00fe5c) ("SMALL LEFT TORTOISE SHELL BRACKET" . #x00fe5d) ("SMALL RIGHT TORTOISE SHELL BRACKET" . #x00fe5e) ("SMALL NUMBER SIGN" . #x00fe5f) ("SMALL AMPERSAND" . #x00fe60) ("SMALL ASTERISK" . #x00fe61) ("SMALL PLUS SIGN" . #x00fe62) ("SMALL HYPHEN-MINUS" . #x00fe63) ("SMALL LESS-THAN SIGN" . #x00fe64) ("SMALL GREATER-THAN SIGN" . #x00fe65) ("SMALL EQUALS SIGN" . #x00fe66) ("SMALL REVERSE SOLIDUS" . #x00fe68) ("SMALL DOLLAR SIGN" . #x00fe69) ("SMALL PERCENT SIGN" . #x00fe6a) ("SMALL COMMERCIAL AT" . #x00fe6b) ("ARABIC FATHATAN ISOLATED FORM" . #x00fe70) ("ARABIC TATWEEL WITH FATHATAN ABOVE" . #x00fe71) ("ARABIC DAMMATAN ISOLATED FORM" . #x00fe72) ("ARABIC TAIL FRAGMENT" . #x00fe73) ("ARABIC KASRATAN ISOLATED FORM" . #x00fe74) ("ARABIC FATHA ISOLATED FORM" . #x00fe76) ("ARABIC FATHA MEDIAL FORM" . #x00fe77) ("ARABIC DAMMA ISOLATED FORM" . #x00fe78) ("ARABIC DAMMA MEDIAL FORM" . #x00fe79) ("ARABIC KASRA ISOLATED FORM" . #x00fe7a) ("ARABIC KASRA MEDIAL FORM" . #x00fe7b) ("ARABIC SHADDA ISOLATED FORM" . #x00fe7c) ("ARABIC SHADDA MEDIAL FORM" . #x00fe7d) ("ARABIC SUKUN ISOLATED FORM" . #x00fe7e) ("ARABIC SUKUN MEDIAL FORM" . #x00fe7f) ("ARABIC LETTER HAMZA ISOLATED FORM" . #x00fe80) ("ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM" . #x00fe81) ("ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM" . #x00fe82) ("ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM" . #x00fe83) ("ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM" . #x00fe84) ("ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM" . #x00fe85) ("ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM" . #x00fe86) ("ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM" . #x00fe87) ("ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM" . #x00fe88) ("ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM" . #x00fe89) ("ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM" . #x00fe8a) ("ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM" . #x00fe8b) ("ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM" . #x00fe8c) ("ARABIC LETTER ALEF ISOLATED FORM" . #x00fe8d) ("ARABIC LETTER ALEF FINAL FORM" . #x00fe8e) ("ARABIC LETTER BEH ISOLATED FORM" . #x00fe8f) ("ARABIC LETTER BEH FINAL FORM" . #x00fe90) ("ARABIC LETTER BEH INITIAL FORM" . #x00fe91) ("ARABIC LETTER BEH MEDIAL FORM" . #x00fe92) ("ARABIC LETTER TEH MARBUTA ISOLATED FORM" . #x00fe93) ("ARABIC LETTER TEH MARBUTA FINAL FORM" . #x00fe94) ("ARABIC LETTER TEH ISOLATED FORM" . #x00fe95) ("ARABIC LETTER TEH FINAL FORM" . #x00fe96) ("ARABIC LETTER TEH INITIAL FORM" . #x00fe97) ("ARABIC LETTER TEH MEDIAL FORM" . #x00fe98) ("ARABIC LETTER THEH ISOLATED FORM" . #x00fe99) ("ARABIC LETTER THEH FINAL FORM" . #x00fe9a) ("ARABIC LETTER THEH INITIAL FORM" . #x00fe9b) ("ARABIC LETTER THEH MEDIAL FORM" . #x00fe9c) ("ARABIC LETTER JEEM ISOLATED FORM" . #x00fe9d) ("ARABIC LETTER JEEM FINAL FORM" . #x00fe9e) ("ARABIC LETTER JEEM INITIAL FORM" . #x00fe9f) ("ARABIC LETTER JEEM MEDIAL FORM" . #x00fea0) ("ARABIC LETTER HAH ISOLATED FORM" . #x00fea1) ("ARABIC LETTER HAH FINAL FORM" . #x00fea2) ("ARABIC LETTER HAH INITIAL FORM" . #x00fea3) ("ARABIC LETTER HAH MEDIAL FORM" . #x00fea4) ("ARABIC LETTER KHAH ISOLATED FORM" . #x00fea5) ("ARABIC LETTER KHAH FINAL FORM" . #x00fea6) ("ARABIC LETTER KHAH INITIAL FORM" . #x00fea7) ("ARABIC LETTER KHAH MEDIAL FORM" . #x00fea8) ("ARABIC LETTER DAL ISOLATED FORM" . #x00fea9) ("ARABIC LETTER DAL FINAL FORM" . #x00feaa) ("ARABIC LETTER THAL ISOLATED FORM" . #x00feab) ("ARABIC LETTER THAL FINAL FORM" . #x00feac) ("ARABIC LETTER REH ISOLATED FORM" . #x00fead) ("ARABIC LETTER REH FINAL FORM" . #x00feae) ("ARABIC LETTER ZAIN ISOLATED FORM" . #x00feaf) ("ARABIC LETTER ZAIN FINAL FORM" . #x00feb0) ("ARABIC LETTER SEEN ISOLATED FORM" . #x00feb1) ("ARABIC LETTER SEEN FINAL FORM" . #x00feb2) ("ARABIC LETTER SEEN INITIAL FORM" . #x00feb3) ("ARABIC LETTER SEEN MEDIAL FORM" . #x00feb4) ("ARABIC LETTER SHEEN ISOLATED FORM" . #x00feb5) ("ARABIC LETTER SHEEN FINAL FORM" . #x00feb6) ("ARABIC LETTER SHEEN INITIAL FORM" . #x00feb7) ("ARABIC LETTER SHEEN MEDIAL FORM" . #x00feb8) ("ARABIC LETTER SAD ISOLATED FORM" . #x00feb9) ("ARABIC LETTER SAD FINAL FORM" . #x00feba) ("ARABIC LETTER SAD INITIAL FORM" . #x00febb) ("ARABIC LETTER SAD MEDIAL FORM" . #x00febc) ("ARABIC LETTER DAD ISOLATED FORM" . #x00febd) ("ARABIC LETTER DAD FINAL FORM" . #x00febe) ("ARABIC LETTER DAD INITIAL FORM" . #x00febf) ("ARABIC LETTER DAD MEDIAL FORM" . #x00fec0) ("ARABIC LETTER TAH ISOLATED FORM" . #x00fec1) ("ARABIC LETTER TAH FINAL FORM" . #x00fec2) ("ARABIC LETTER TAH INITIAL FORM" . #x00fec3) ("ARABIC LETTER TAH MEDIAL FORM" . #x00fec4) ("ARABIC LETTER ZAH ISOLATED FORM" . #x00fec5) ("ARABIC LETTER ZAH FINAL FORM" . #x00fec6) ("ARABIC LETTER ZAH INITIAL FORM" . #x00fec7) ("ARABIC LETTER ZAH MEDIAL FORM" . #x00fec8) ("ARABIC LETTER AIN ISOLATED FORM" . #x00fec9) ("ARABIC LETTER AIN FINAL FORM" . #x00feca) ("ARABIC LETTER AIN INITIAL FORM" . #x00fecb) ("ARABIC LETTER AIN MEDIAL FORM" . #x00fecc) ("ARABIC LETTER GHAIN ISOLATED FORM" . #x00fecd) ("ARABIC LETTER GHAIN FINAL FORM" . #x00fece) ("ARABIC LETTER GHAIN INITIAL FORM" . #x00fecf) ("ARABIC LETTER GHAIN MEDIAL FORM" . #x00fed0) ("ARABIC LETTER FEH ISOLATED FORM" . #x00fed1) ("ARABIC LETTER FEH FINAL FORM" . #x00fed2) ("ARABIC LETTER FEH INITIAL FORM" . #x00fed3) ("ARABIC LETTER FEH MEDIAL FORM" . #x00fed4) ("ARABIC LETTER QAF ISOLATED FORM" . #x00fed5) ("ARABIC LETTER QAF FINAL FORM" . #x00fed6) ("ARABIC LETTER QAF INITIAL FORM" . #x00fed7) ("ARABIC LETTER QAF MEDIAL FORM" . #x00fed8) ("ARABIC LETTER KAF ISOLATED FORM" . #x00fed9) ("ARABIC LETTER KAF FINAL FORM" . #x00feda) ("ARABIC LETTER KAF INITIAL FORM" . #x00fedb) ("ARABIC LETTER KAF MEDIAL FORM" . #x00fedc) ("ARABIC LETTER LAM ISOLATED FORM" . #x00fedd) ("ARABIC LETTER LAM FINAL FORM" . #x00fede) ("ARABIC LETTER LAM INITIAL FORM" . #x00fedf) ("ARABIC LETTER LAM MEDIAL FORM" . #x00fee0) ("ARABIC LETTER MEEM ISOLATED FORM" . #x00fee1) ("ARABIC LETTER MEEM FINAL FORM" . #x00fee2) ("ARABIC LETTER MEEM INITIAL FORM" . #x00fee3) ("ARABIC LETTER MEEM MEDIAL FORM" . #x00fee4) ("ARABIC LETTER NOON ISOLATED FORM" . #x00fee5) ("ARABIC LETTER NOON FINAL FORM" . #x00fee6) ("ARABIC LETTER NOON INITIAL FORM" . #x00fee7) ("ARABIC LETTER NOON MEDIAL FORM" . #x00fee8) ("ARABIC LETTER HEH ISOLATED FORM" . #x00fee9) ("ARABIC LETTER HEH FINAL FORM" . #x00feea) ("ARABIC LETTER HEH INITIAL FORM" . #x00feeb) ("ARABIC LETTER HEH MEDIAL FORM" . #x00feec) ("ARABIC LETTER WAW ISOLATED FORM" . #x00feed) ("ARABIC LETTER WAW FINAL FORM" . #x00feee) ("ARABIC LETTER ALEF MAKSURA ISOLATED FORM" . #x00feef) ("ARABIC LETTER ALEF MAKSURA FINAL FORM" . #x00fef0) ("ARABIC LETTER YEH ISOLATED FORM" . #x00fef1) ("ARABIC LETTER YEH FINAL FORM" . #x00fef2) ("ARABIC LETTER YEH INITIAL FORM" . #x00fef3) ("ARABIC LETTER YEH MEDIAL FORM" . #x00fef4) ("ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM" . #x00fef5) ("ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM" . #x00fef6) ("ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM" . #x00fef7) ("ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM" . #x00fef8) ("ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM" . #x00fef9) ("ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM" . #x00fefa) ("ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM" . #x00fefb) ("ARABIC LIGATURE LAM WITH ALEF FINAL FORM" . #x00fefc) ("ZERO WIDTH NO-BREAK SPACE" . #x00feff) ("REPLACEMENT CHARACTER" . #x00fffd) ("MATHEMATICAL BOLD CAPITAL A" . #x01d400) ("MATHEMATICAL BOLD CAPITAL B" . #x01d401) ("MATHEMATICAL BOLD CAPITAL C" . #x01d402) ("MATHEMATICAL BOLD CAPITAL D" . #x01d403) ("MATHEMATICAL BOLD CAPITAL E" . #x01d404) ("MATHEMATICAL BOLD CAPITAL F" . #x01d405) ("MATHEMATICAL BOLD CAPITAL G" . #x01d406) ("MATHEMATICAL BOLD CAPITAL H" . #x01d407) ("MATHEMATICAL BOLD CAPITAL I" . #x01d408) ("MATHEMATICAL BOLD CAPITAL J" . #x01d409) ("MATHEMATICAL BOLD CAPITAL K" . #x01d40a) ("MATHEMATICAL BOLD CAPITAL L" . #x01d40b) ("MATHEMATICAL BOLD CAPITAL M" . #x01d40c) ("MATHEMATICAL BOLD CAPITAL N" . #x01d40d) ("MATHEMATICAL BOLD CAPITAL O" . #x01d40e) ("MATHEMATICAL BOLD CAPITAL P" . #x01d40f) ("MATHEMATICAL BOLD CAPITAL Q" . #x01d410) ("MATHEMATICAL BOLD CAPITAL R" . #x01d411) ("MATHEMATICAL BOLD CAPITAL S" . #x01d412) ("MATHEMATICAL BOLD CAPITAL T" . #x01d413) ("MATHEMATICAL BOLD CAPITAL U" . #x01d414) ("MATHEMATICAL BOLD CAPITAL V" . #x01d415) ("MATHEMATICAL BOLD CAPITAL W" . #x01d416) ("MATHEMATICAL BOLD CAPITAL X" . #x01d417) ("MATHEMATICAL BOLD CAPITAL Y" . #x01d418) ("MATHEMATICAL BOLD CAPITAL Z" . #x01d419) ("MATHEMATICAL BOLD SMALL A" . #x01d41a) ("MATHEMATICAL BOLD SMALL B" . #x01d41b) ("MATHEMATICAL BOLD SMALL C" . #x01d41c) ("MATHEMATICAL BOLD SMALL D" . #x01d41d) ("MATHEMATICAL BOLD SMALL E" . #x01d41e) ("MATHEMATICAL BOLD SMALL F" . #x01d41f) ("MATHEMATICAL BOLD SMALL G" . #x01d420) ("MATHEMATICAL BOLD SMALL H" . #x01d421) ("MATHEMATICAL BOLD SMALL I" . #x01d422) ("MATHEMATICAL BOLD SMALL J" . #x01d423) ("MATHEMATICAL BOLD SMALL K" . #x01d424) ("MATHEMATICAL BOLD SMALL L" . #x01d425) ("MATHEMATICAL BOLD SMALL M" . #x01d426) ("MATHEMATICAL BOLD SMALL N" . #x01d427) ("MATHEMATICAL BOLD SMALL O" . #x01d428) ("MATHEMATICAL BOLD SMALL P" . #x01d429) ("MATHEMATICAL BOLD SMALL Q" . #x01d42a) ("MATHEMATICAL BOLD SMALL R" . #x01d42b) ("MATHEMATICAL BOLD SMALL S" . #x01d42c) ("MATHEMATICAL BOLD SMALL T" . #x01d42d) ("MATHEMATICAL BOLD SMALL U" . #x01d42e) ("MATHEMATICAL BOLD SMALL V" . #x01d42f) ("MATHEMATICAL BOLD SMALL W" . #x01d430) ("MATHEMATICAL BOLD SMALL X" . #x01d431) ("MATHEMATICAL BOLD SMALL Y" . #x01d432) ("MATHEMATICAL BOLD SMALL Z" . #x01d433) ("MATHEMATICAL ITALIC CAPITAL A" . #x01d434) ("MATHEMATICAL ITALIC CAPITAL B" . #x01d435) ("MATHEMATICAL ITALIC CAPITAL C" . #x01d436) ("MATHEMATICAL ITALIC CAPITAL D" . #x01d437) ("MATHEMATICAL ITALIC CAPITAL E" . #x01d438) ("MATHEMATICAL ITALIC CAPITAL F" . #x01d439) ("MATHEMATICAL ITALIC CAPITAL G" . #x01d43a) ("MATHEMATICAL ITALIC CAPITAL H" . #x01d43b) ("MATHEMATICAL ITALIC CAPITAL I" . #x01d43c) ("MATHEMATICAL ITALIC CAPITAL J" . #x01d43d) ("MATHEMATICAL ITALIC CAPITAL K" . #x01d43e) ("MATHEMATICAL ITALIC CAPITAL L" . #x01d43f) ("MATHEMATICAL ITALIC CAPITAL M" . #x01d440) ("MATHEMATICAL ITALIC CAPITAL N" . #x01d441) ("MATHEMATICAL ITALIC CAPITAL O" . #x01d442) ("MATHEMATICAL ITALIC CAPITAL P" . #x01d443) ("MATHEMATICAL ITALIC CAPITAL Q" . #x01d444) ("MATHEMATICAL ITALIC CAPITAL R" . #x01d445) ("MATHEMATICAL ITALIC CAPITAL S" . #x01d446) ("MATHEMATICAL ITALIC CAPITAL T" . #x01d447) ("MATHEMATICAL ITALIC CAPITAL U" . #x01d448) ("MATHEMATICAL ITALIC CAPITAL V" . #x01d449) ("MATHEMATICAL ITALIC CAPITAL W" . #x01d44a) ("MATHEMATICAL ITALIC CAPITAL X" . #x01d44b) ("MATHEMATICAL ITALIC CAPITAL Y" . #x01d44c) ("MATHEMATICAL ITALIC CAPITAL Z" . #x01d44d) ("MATHEMATICAL ITALIC SMALL A" . #x01d44e) ("MATHEMATICAL ITALIC SMALL B" . #x01d44f) ("MATHEMATICAL ITALIC SMALL C" . #x01d450) ("MATHEMATICAL ITALIC SMALL D" . #x01d451) ("MATHEMATICAL ITALIC SMALL E" . #x01d452) ("MATHEMATICAL ITALIC SMALL F" . #x01d453) ("MATHEMATICAL ITALIC SMALL G" . #x01d454) ("MATHEMATICAL ITALIC SMALL I" . #x01d456) ("MATHEMATICAL ITALIC SMALL J" . #x01d457) ("MATHEMATICAL ITALIC SMALL K" . #x01d458) ("MATHEMATICAL ITALIC SMALL L" . #x01d459) ("MATHEMATICAL ITALIC SMALL M" . #x01d45a) ("MATHEMATICAL ITALIC SMALL N" . #x01d45b) ("MATHEMATICAL ITALIC SMALL O" . #x01d45c) ("MATHEMATICAL ITALIC SMALL P" . #x01d45d) ("MATHEMATICAL ITALIC SMALL Q" . #x01d45e) ("MATHEMATICAL ITALIC SMALL R" . #x01d45f) ("MATHEMATICAL ITALIC SMALL S" . #x01d460) ("MATHEMATICAL ITALIC SMALL T" . #x01d461) ("MATHEMATICAL ITALIC SMALL U" . #x01d462) ("MATHEMATICAL ITALIC SMALL V" . #x01d463) ("MATHEMATICAL ITALIC SMALL W" . #x01d464) ("MATHEMATICAL ITALIC SMALL X" . #x01d465) ("MATHEMATICAL ITALIC SMALL Y" . #x01d466) ("MATHEMATICAL ITALIC SMALL Z" . #x01d467) ("MATHEMATICAL BOLD ITALIC CAPITAL A" . #x01d468) ("MATHEMATICAL BOLD ITALIC CAPITAL B" . #x01d469) ("MATHEMATICAL BOLD ITALIC CAPITAL C" . #x01d46a) ("MATHEMATICAL BOLD ITALIC CAPITAL D" . #x01d46b) ("MATHEMATICAL BOLD ITALIC CAPITAL E" . #x01d46c) ("MATHEMATICAL BOLD ITALIC CAPITAL F" . #x01d46d) ("MATHEMATICAL BOLD ITALIC CAPITAL G" . #x01d46e) ("MATHEMATICAL BOLD ITALIC CAPITAL H" . #x01d46f) ("MATHEMATICAL BOLD ITALIC CAPITAL I" . #x01d470) ("MATHEMATICAL BOLD ITALIC CAPITAL J" . #x01d471) ("MATHEMATICAL BOLD ITALIC CAPITAL K" . #x01d472) ("MATHEMATICAL BOLD ITALIC CAPITAL L" . #x01d473) ("MATHEMATICAL BOLD ITALIC CAPITAL M" . #x01d474) ("MATHEMATICAL BOLD ITALIC CAPITAL N" . #x01d475) ("MATHEMATICAL BOLD ITALIC CAPITAL O" . #x01d476) ("MATHEMATICAL BOLD ITALIC CAPITAL P" . #x01d477) ("MATHEMATICAL BOLD ITALIC CAPITAL Q" . #x01d478) ("MATHEMATICAL BOLD ITALIC CAPITAL R" . #x01d479) ("MATHEMATICAL BOLD ITALIC CAPITAL S" . #x01d47a) ("MATHEMATICAL BOLD ITALIC CAPITAL T" . #x01d47b) ("MATHEMATICAL BOLD ITALIC CAPITAL U" . #x01d47c) ("MATHEMATICAL BOLD ITALIC CAPITAL V" . #x01d47d) ("MATHEMATICAL BOLD ITALIC CAPITAL W" . #x01d47e) ("MATHEMATICAL BOLD ITALIC CAPITAL X" . #x01d47f) ("MATHEMATICAL BOLD ITALIC CAPITAL Y" . #x01d480) ("MATHEMATICAL BOLD ITALIC CAPITAL Z" . #x01d481) ("MATHEMATICAL BOLD ITALIC SMALL A" . #x01d482) ("MATHEMATICAL BOLD ITALIC SMALL B" . #x01d483) ("MATHEMATICAL BOLD ITALIC SMALL C" . #x01d484) ("MATHEMATICAL BOLD ITALIC SMALL D" . #x01d485) ("MATHEMATICAL BOLD ITALIC SMALL E" . #x01d486) ("MATHEMATICAL BOLD ITALIC SMALL F" . #x01d487) ("MATHEMATICAL BOLD ITALIC SMALL G" . #x01d488) ("MATHEMATICAL BOLD ITALIC SMALL H" . #x01d489) ("MATHEMATICAL BOLD ITALIC SMALL I" . #x01d48a) ("MATHEMATICAL BOLD ITALIC SMALL J" . #x01d48b) ("MATHEMATICAL BOLD ITALIC SMALL K" . #x01d48c) ("MATHEMATICAL BOLD ITALIC SMALL L" . #x01d48d) ("MATHEMATICAL BOLD ITALIC SMALL M" . #x01d48e) ("MATHEMATICAL BOLD ITALIC SMALL N" . #x01d48f) ("MATHEMATICAL BOLD ITALIC SMALL O" . #x01d490) ("MATHEMATICAL BOLD ITALIC SMALL P" . #x01d491) ("MATHEMATICAL BOLD ITALIC SMALL Q" . #x01d492) ("MATHEMATICAL BOLD ITALIC SMALL R" . #x01d493) ("MATHEMATICAL BOLD ITALIC SMALL S" . #x01d494) ("MATHEMATICAL BOLD ITALIC SMALL T" . #x01d495) ("MATHEMATICAL BOLD ITALIC SMALL U" . #x01d496) ("MATHEMATICAL BOLD ITALIC SMALL V" . #x01d497) ("MATHEMATICAL BOLD ITALIC SMALL W" . #x01d498) ("MATHEMATICAL BOLD ITALIC SMALL X" . #x01d499) ("MATHEMATICAL BOLD ITALIC SMALL Y" . #x01d49a) ("MATHEMATICAL BOLD ITALIC SMALL Z" . #x01d49b) ("MATHEMATICAL SCRIPT CAPITAL A" . #x01d49c) ("MATHEMATICAL SCRIPT CAPITAL C" . #x01d49e) ("MATHEMATICAL SCRIPT CAPITAL D" . #x01d49f) ("MATHEMATICAL SCRIPT CAPITAL G" . #x01d4a2) ("MATHEMATICAL SCRIPT CAPITAL J" . #x01d4a5) ("MATHEMATICAL SCRIPT CAPITAL K" . #x01d4a6) ("MATHEMATICAL SCRIPT CAPITAL N" . #x01d4a9) ("MATHEMATICAL SCRIPT CAPITAL O" . #x01d4aa) ("MATHEMATICAL SCRIPT CAPITAL P" . #x01d4ab) ("MATHEMATICAL SCRIPT CAPITAL Q" . #x01d4ac) ("MATHEMATICAL SCRIPT CAPITAL S" . #x01d4ae) ("MATHEMATICAL SCRIPT CAPITAL T" . #x01d4af) ("MATHEMATICAL SCRIPT CAPITAL U" . #x01d4b0) ("MATHEMATICAL SCRIPT CAPITAL V" . #x01d4b1) ("MATHEMATICAL SCRIPT CAPITAL W" . #x01d4b2) ("MATHEMATICAL SCRIPT CAPITAL X" . #x01d4b3) ("MATHEMATICAL SCRIPT CAPITAL Y" . #x01d4b4) ("MATHEMATICAL SCRIPT CAPITAL Z" . #x01d4b5) ("MATHEMATICAL SCRIPT SMALL A" . #x01d4b6) ("MATHEMATICAL SCRIPT SMALL B" . #x01d4b7) ("MATHEMATICAL SCRIPT SMALL C" . #x01d4b8) ("MATHEMATICAL SCRIPT SMALL D" . #x01d4b9) ("MATHEMATICAL SCRIPT SMALL F" . #x01d4bb) ("MATHEMATICAL SCRIPT SMALL H" . #x01d4bd) ("MATHEMATICAL SCRIPT SMALL I" . #x01d4be) ("MATHEMATICAL SCRIPT SMALL J" . #x01d4bf) ("MATHEMATICAL SCRIPT SMALL K" . #x01d4c0) ("MATHEMATICAL SCRIPT SMALL L" . #x01d4c1) ("MATHEMATICAL SCRIPT SMALL M" . #x01d4c2) ("MATHEMATICAL SCRIPT SMALL N" . #x01d4c3) ("MATHEMATICAL SCRIPT SMALL P" . #x01d4c5) ("MATHEMATICAL SCRIPT SMALL Q" . #x01d4c6) ("MATHEMATICAL SCRIPT SMALL R" . #x01d4c7) ("MATHEMATICAL SCRIPT SMALL S" . #x01d4c8) ("MATHEMATICAL SCRIPT SMALL T" . #x01d4c9) ("MATHEMATICAL SCRIPT SMALL U" . #x01d4ca) ("MATHEMATICAL SCRIPT SMALL V" . #x01d4cb) ("MATHEMATICAL SCRIPT SMALL W" . #x01d4cc) ("MATHEMATICAL SCRIPT SMALL X" . #x01d4cd) ("MATHEMATICAL SCRIPT SMALL Y" . #x01d4ce) ("MATHEMATICAL SCRIPT SMALL Z" . #x01d4cf) ("MATHEMATICAL BOLD SCRIPT CAPITAL A" . #x01d4d0) ("MATHEMATICAL BOLD SCRIPT CAPITAL B" . #x01d4d1) ("MATHEMATICAL BOLD SCRIPT CAPITAL C" . #x01d4d2) ("MATHEMATICAL BOLD SCRIPT CAPITAL D" . #x01d4d3) ("MATHEMATICAL BOLD SCRIPT CAPITAL E" . #x01d4d4) ("MATHEMATICAL BOLD SCRIPT CAPITAL F" . #x01d4d5) ("MATHEMATICAL BOLD SCRIPT CAPITAL G" . #x01d4d6) ("MATHEMATICAL BOLD SCRIPT CAPITAL H" . #x01d4d7) ("MATHEMATICAL BOLD SCRIPT CAPITAL I" . #x01d4d8) ("MATHEMATICAL BOLD SCRIPT CAPITAL J" . #x01d4d9) ("MATHEMATICAL BOLD SCRIPT CAPITAL K" . #x01d4da) ("MATHEMATICAL BOLD SCRIPT CAPITAL L" . #x01d4db) ("MATHEMATICAL BOLD SCRIPT CAPITAL M" . #x01d4dc) ("MATHEMATICAL BOLD SCRIPT CAPITAL N" . #x01d4dd) ("MATHEMATICAL BOLD SCRIPT CAPITAL O" . #x01d4de) ("MATHEMATICAL BOLD SCRIPT CAPITAL P" . #x01d4df) ("MATHEMATICAL BOLD SCRIPT CAPITAL Q" . #x01d4e0) ("MATHEMATICAL BOLD SCRIPT CAPITAL R" . #x01d4e1) ("MATHEMATICAL BOLD SCRIPT CAPITAL S" . #x01d4e2) ("MATHEMATICAL BOLD SCRIPT CAPITAL T" . #x01d4e3) ("MATHEMATICAL BOLD SCRIPT CAPITAL U" . #x01d4e4) ("MATHEMATICAL BOLD SCRIPT CAPITAL V" . #x01d4e5) ("MATHEMATICAL BOLD SCRIPT CAPITAL W" . #x01d4e6) ("MATHEMATICAL BOLD SCRIPT CAPITAL X" . #x01d4e7) ("MATHEMATICAL BOLD SCRIPT CAPITAL Y" . #x01d4e8) ("MATHEMATICAL BOLD SCRIPT CAPITAL Z" . #x01d4e9) ("MATHEMATICAL BOLD SCRIPT SMALL A" . #x01d4ea) ("MATHEMATICAL BOLD SCRIPT SMALL B" . #x01d4eb) ("MATHEMATICAL BOLD SCRIPT SMALL C" . #x01d4ec) ("MATHEMATICAL BOLD SCRIPT SMALL D" . #x01d4ed) ("MATHEMATICAL BOLD SCRIPT SMALL E" . #x01d4ee) ("MATHEMATICAL BOLD SCRIPT SMALL F" . #x01d4ef) ("MATHEMATICAL BOLD SCRIPT SMALL G" . #x01d4f0) ("MATHEMATICAL BOLD SCRIPT SMALL H" . #x01d4f1) ("MATHEMATICAL BOLD SCRIPT SMALL I" . #x01d4f2) ("MATHEMATICAL BOLD SCRIPT SMALL J" . #x01d4f3) ("MATHEMATICAL BOLD SCRIPT SMALL K" . #x01d4f4) ("MATHEMATICAL BOLD SCRIPT SMALL L" . #x01d4f5) ("MATHEMATICAL BOLD SCRIPT SMALL M" . #x01d4f6) ("MATHEMATICAL BOLD SCRIPT SMALL N" . #x01d4f7) ("MATHEMATICAL BOLD SCRIPT SMALL O" . #x01d4f8) ("MATHEMATICAL BOLD SCRIPT SMALL P" . #x01d4f9) ("MATHEMATICAL BOLD SCRIPT SMALL Q" . #x01d4fa) ("MATHEMATICAL BOLD SCRIPT SMALL R" . #x01d4fb) ("MATHEMATICAL BOLD SCRIPT SMALL S" . #x01d4fc) ("MATHEMATICAL BOLD SCRIPT SMALL T" . #x01d4fd) ("MATHEMATICAL BOLD SCRIPT SMALL U" . #x01d4fe) ("MATHEMATICAL BOLD SCRIPT SMALL V" . #x01d4ff) ("MATHEMATICAL BOLD SCRIPT SMALL W" . #x01d500) ("MATHEMATICAL BOLD SCRIPT SMALL X" . #x01d501) ("MATHEMATICAL BOLD SCRIPT SMALL Y" . #x01d502) ("MATHEMATICAL BOLD SCRIPT SMALL Z" . #x01d503) ("MATHEMATICAL FRAKTUR CAPITAL A" . #x01d504) ("MATHEMATICAL FRAKTUR CAPITAL B" . #x01d505) ("MATHEMATICAL FRAKTUR CAPITAL D" . #x01d507) ("MATHEMATICAL FRAKTUR CAPITAL E" . #x01d508) ("MATHEMATICAL FRAKTUR CAPITAL F" . #x01d509) ("MATHEMATICAL FRAKTUR CAPITAL G" . #x01d50a) ("MATHEMATICAL FRAKTUR CAPITAL J" . #x01d50d) ("MATHEMATICAL FRAKTUR CAPITAL K" . #x01d50e) ("MATHEMATICAL FRAKTUR CAPITAL L" . #x01d50f) ("MATHEMATICAL FRAKTUR CAPITAL M" . #x01d510) ("MATHEMATICAL FRAKTUR CAPITAL N" . #x01d511) ("MATHEMATICAL FRAKTUR CAPITAL O" . #x01d512) ("MATHEMATICAL FRAKTUR CAPITAL P" . #x01d513) ("MATHEMATICAL FRAKTUR CAPITAL Q" . #x01d514) ("MATHEMATICAL FRAKTUR CAPITAL S" . #x01d516) ("MATHEMATICAL FRAKTUR CAPITAL T" . #x01d517) ("MATHEMATICAL FRAKTUR CAPITAL U" . #x01d518) ("MATHEMATICAL FRAKTUR CAPITAL V" . #x01d519) ("MATHEMATICAL FRAKTUR CAPITAL W" . #x01d51a) ("MATHEMATICAL FRAKTUR CAPITAL X" . #x01d51b) ("MATHEMATICAL FRAKTUR CAPITAL Y" . #x01d51c) ("MATHEMATICAL FRAKTUR SMALL A" . #x01d51e) ("MATHEMATICAL FRAKTUR SMALL B" . #x01d51f) ("MATHEMATICAL FRAKTUR SMALL C" . #x01d520) ("MATHEMATICAL FRAKTUR SMALL D" . #x01d521) ("MATHEMATICAL FRAKTUR SMALL E" . #x01d522) ("MATHEMATICAL FRAKTUR SMALL F" . #x01d523) ("MATHEMATICAL FRAKTUR SMALL G" . #x01d524) ("MATHEMATICAL FRAKTUR SMALL H" . #x01d525) ("MATHEMATICAL FRAKTUR SMALL I" . #x01d526) ("MATHEMATICAL FRAKTUR SMALL J" . #x01d527) ("MATHEMATICAL FRAKTUR SMALL K" . #x01d528) ("MATHEMATICAL FRAKTUR SMALL L" . #x01d529) ("MATHEMATICAL FRAKTUR SMALL M" . #x01d52a) ("MATHEMATICAL FRAKTUR SMALL N" . #x01d52b) ("MATHEMATICAL FRAKTUR SMALL O" . #x01d52c) ("MATHEMATICAL FRAKTUR SMALL P" . #x01d52d) ("MATHEMATICAL FRAKTUR SMALL Q" . #x01d52e) ("MATHEMATICAL FRAKTUR SMALL R" . #x01d52f) ("MATHEMATICAL FRAKTUR SMALL S" . #x01d530) ("MATHEMATICAL FRAKTUR SMALL T" . #x01d531) ("MATHEMATICAL FRAKTUR SMALL U" . #x01d532) ("MATHEMATICAL FRAKTUR SMALL V" . #x01d533) ("MATHEMATICAL FRAKTUR SMALL W" . #x01d534) ("MATHEMATICAL FRAKTUR SMALL X" . #x01d535) ("MATHEMATICAL FRAKTUR SMALL Y" . #x01d536) ("MATHEMATICAL FRAKTUR SMALL Z" . #x01d537) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL A" . #x01d538) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL B" . #x01d539) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL D" . #x01d53b) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL E" . #x01d53c) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL F" . #x01d53d) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL G" . #x01d53e) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL I" . #x01d540) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL J" . #x01d541) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL K" . #x01d542) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL L" . #x01d543) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL M" . #x01d544) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL O" . #x01d546) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL S" . #x01d54a) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL T" . #x01d54b) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL U" . #x01d54c) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL V" . #x01d54d) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL W" . #x01d54e) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL X" . #x01d54f) ("MATHEMATICAL DOUBLE-STRUCK CAPITAL Y" . #x01d550) ("MATHEMATICAL DOUBLE-STRUCK SMALL A" . #x01d552) ("MATHEMATICAL DOUBLE-STRUCK SMALL B" . #x01d553) ("MATHEMATICAL DOUBLE-STRUCK SMALL C" . #x01d554) ("MATHEMATICAL DOUBLE-STRUCK SMALL D" . #x01d555) ("MATHEMATICAL DOUBLE-STRUCK SMALL E" . #x01d556) ("MATHEMATICAL DOUBLE-STRUCK SMALL F" . #x01d557) ("MATHEMATICAL DOUBLE-STRUCK SMALL G" . #x01d558) ("MATHEMATICAL DOUBLE-STRUCK SMALL H" . #x01d559) ("MATHEMATICAL DOUBLE-STRUCK SMALL I" . #x01d55a) ("MATHEMATICAL DOUBLE-STRUCK SMALL J" . #x01d55b) ("MATHEMATICAL DOUBLE-STRUCK SMALL K" . #x01d55c) ("MATHEMATICAL DOUBLE-STRUCK SMALL L" . #x01d55d) ("MATHEMATICAL DOUBLE-STRUCK SMALL M" . #x01d55e) ("MATHEMATICAL DOUBLE-STRUCK SMALL N" . #x01d55f) ("MATHEMATICAL DOUBLE-STRUCK SMALL O" . #x01d560) ("MATHEMATICAL DOUBLE-STRUCK SMALL P" . #x01d561) ("MATHEMATICAL DOUBLE-STRUCK SMALL Q" . #x01d562) ("MATHEMATICAL DOUBLE-STRUCK SMALL R" . #x01d563) ("MATHEMATICAL DOUBLE-STRUCK SMALL S" . #x01d564) ("MATHEMATICAL DOUBLE-STRUCK SMALL T" . #x01d565) ("MATHEMATICAL DOUBLE-STRUCK SMALL U" . #x01d566) ("MATHEMATICAL DOUBLE-STRUCK SMALL V" . #x01d567) ("MATHEMATICAL DOUBLE-STRUCK SMALL W" . #x01d568) ("MATHEMATICAL DOUBLE-STRUCK SMALL X" . #x01d569) ("MATHEMATICAL DOUBLE-STRUCK SMALL Y" . #x01d56a) ("MATHEMATICAL DOUBLE-STRUCK SMALL Z" . #x01d56b) ("MATHEMATICAL BOLD FRAKTUR CAPITAL A" . #x01d56c) ("MATHEMATICAL BOLD FRAKTUR CAPITAL B" . #x01d56d) ("MATHEMATICAL BOLD FRAKTUR CAPITAL C" . #x01d56e) ("MATHEMATICAL BOLD FRAKTUR CAPITAL D" . #x01d56f) ("MATHEMATICAL BOLD FRAKTUR CAPITAL E" . #x01d570) ("MATHEMATICAL BOLD FRAKTUR CAPITAL F" . #x01d571) ("MATHEMATICAL BOLD FRAKTUR CAPITAL G" . #x01d572) ("MATHEMATICAL BOLD FRAKTUR CAPITAL H" . #x01d573) ("MATHEMATICAL BOLD FRAKTUR CAPITAL I" . #x01d574) ("MATHEMATICAL BOLD FRAKTUR CAPITAL J" . #x01d575) ("MATHEMATICAL BOLD FRAKTUR CAPITAL K" . #x01d576) ("MATHEMATICAL BOLD FRAKTUR CAPITAL L" . #x01d577) ("MATHEMATICAL BOLD FRAKTUR CAPITAL M" . #x01d578) ("MATHEMATICAL BOLD FRAKTUR CAPITAL N" . #x01d579) ("MATHEMATICAL BOLD FRAKTUR CAPITAL O" . #x01d57a) ("MATHEMATICAL BOLD FRAKTUR CAPITAL P" . #x01d57b) ("MATHEMATICAL BOLD FRAKTUR CAPITAL Q" . #x01d57c) ("MATHEMATICAL BOLD FRAKTUR CAPITAL R" . #x01d57d) ("MATHEMATICAL BOLD FRAKTUR CAPITAL S" . #x01d57e) ("MATHEMATICAL BOLD FRAKTUR CAPITAL T" . #x01d57f) ("MATHEMATICAL BOLD FRAKTUR CAPITAL U" . #x01d580) ("MATHEMATICAL BOLD FRAKTUR CAPITAL V" . #x01d581) ("MATHEMATICAL BOLD FRAKTUR CAPITAL W" . #x01d582) ("MATHEMATICAL BOLD FRAKTUR CAPITAL X" . #x01d583) ("MATHEMATICAL BOLD FRAKTUR CAPITAL Y" . #x01d584) ("MATHEMATICAL BOLD FRAKTUR CAPITAL Z" . #x01d585) ("MATHEMATICAL BOLD FRAKTUR SMALL A" . #x01d586) ("MATHEMATICAL BOLD FRAKTUR SMALL B" . #x01d587) ("MATHEMATICAL BOLD FRAKTUR SMALL C" . #x01d588) ("MATHEMATICAL BOLD FRAKTUR SMALL D" . #x01d589) ("MATHEMATICAL BOLD FRAKTUR SMALL E" . #x01d58a) ("MATHEMATICAL BOLD FRAKTUR SMALL F" . #x01d58b) ("MATHEMATICAL BOLD FRAKTUR SMALL G" . #x01d58c) ("MATHEMATICAL BOLD FRAKTUR SMALL H" . #x01d58d) ("MATHEMATICAL BOLD FRAKTUR SMALL I" . #x01d58e) ("MATHEMATICAL BOLD FRAKTUR SMALL J" . #x01d58f) ("MATHEMATICAL BOLD FRAKTUR SMALL K" . #x01d590) ("MATHEMATICAL BOLD FRAKTUR SMALL L" . #x01d591) ("MATHEMATICAL BOLD FRAKTUR SMALL M" . #x01d592) ("MATHEMATICAL BOLD FRAKTUR SMALL N" . #x01d593) ("MATHEMATICAL BOLD FRAKTUR SMALL O" . #x01d594) ("MATHEMATICAL BOLD FRAKTUR SMALL P" . #x01d595) ("MATHEMATICAL BOLD FRAKTUR SMALL Q" . #x01d596) ("MATHEMATICAL BOLD FRAKTUR SMALL R" . #x01d597) ("MATHEMATICAL BOLD FRAKTUR SMALL S" . #x01d598) ("MATHEMATICAL BOLD FRAKTUR SMALL T" . #x01d599) ("MATHEMATICAL BOLD FRAKTUR SMALL U" . #x01d59a) ("MATHEMATICAL BOLD FRAKTUR SMALL V" . #x01d59b) ("MATHEMATICAL BOLD FRAKTUR SMALL W" . #x01d59c) ("MATHEMATICAL BOLD FRAKTUR SMALL X" . #x01d59d) ("MATHEMATICAL BOLD FRAKTUR SMALL Y" . #x01d59e) ("MATHEMATICAL BOLD FRAKTUR SMALL Z" . #x01d59f) ("MATHEMATICAL SANS-SERIF CAPITAL A" . #x01d5a0) ("MATHEMATICAL SANS-SERIF CAPITAL B" . #x01d5a1) ("MATHEMATICAL SANS-SERIF CAPITAL C" . #x01d5a2) ("MATHEMATICAL SANS-SERIF CAPITAL D" . #x01d5a3) ("MATHEMATICAL SANS-SERIF CAPITAL E" . #x01d5a4) ("MATHEMATICAL SANS-SERIF CAPITAL F" . #x01d5a5) ("MATHEMATICAL SANS-SERIF CAPITAL G" . #x01d5a6) ("MATHEMATICAL SANS-SERIF CAPITAL H" . #x01d5a7) ("MATHEMATICAL SANS-SERIF CAPITAL I" . #x01d5a8) ("MATHEMATICAL SANS-SERIF CAPITAL J" . #x01d5a9) ("MATHEMATICAL SANS-SERIF CAPITAL K" . #x01d5aa) ("MATHEMATICAL SANS-SERIF CAPITAL L" . #x01d5ab) ("MATHEMATICAL SANS-SERIF CAPITAL M" . #x01d5ac) ("MATHEMATICAL SANS-SERIF CAPITAL N" . #x01d5ad) ("MATHEMATICAL SANS-SERIF CAPITAL O" . #x01d5ae) ("MATHEMATICAL SANS-SERIF CAPITAL P" . #x01d5af) ("MATHEMATICAL SANS-SERIF CAPITAL Q" . #x01d5b0) ("MATHEMATICAL SANS-SERIF CAPITAL R" . #x01d5b1) ("MATHEMATICAL SANS-SERIF CAPITAL S" . #x01d5b2) ("MATHEMATICAL SANS-SERIF CAPITAL T" . #x01d5b3) ("MATHEMATICAL SANS-SERIF CAPITAL U" . #x01d5b4) ("MATHEMATICAL SANS-SERIF CAPITAL V" . #x01d5b5) ("MATHEMATICAL SANS-SERIF CAPITAL W" . #x01d5b6) ("MATHEMATICAL SANS-SERIF CAPITAL X" . #x01d5b7) ("MATHEMATICAL SANS-SERIF CAPITAL Y" . #x01d5b8) ("MATHEMATICAL SANS-SERIF CAPITAL Z" . #x01d5b9) ("MATHEMATICAL SANS-SERIF SMALL A" . #x01d5ba) ("MATHEMATICAL SANS-SERIF SMALL B" . #x01d5bb) ("MATHEMATICAL SANS-SERIF SMALL C" . #x01d5bc) ("MATHEMATICAL SANS-SERIF SMALL D" . #x01d5bd) ("MATHEMATICAL SANS-SERIF SMALL E" . #x01d5be) ("MATHEMATICAL SANS-SERIF SMALL F" . #x01d5bf) ("MATHEMATICAL SANS-SERIF SMALL G" . #x01d5c0) ("MATHEMATICAL SANS-SERIF SMALL H" . #x01d5c1) ("MATHEMATICAL SANS-SERIF SMALL I" . #x01d5c2) ("MATHEMATICAL SANS-SERIF SMALL J" . #x01d5c3) ("MATHEMATICAL SANS-SERIF SMALL K" . #x01d5c4) ("MATHEMATICAL SANS-SERIF SMALL L" . #x01d5c5) ("MATHEMATICAL SANS-SERIF SMALL M" . #x01d5c6) ("MATHEMATICAL SANS-SERIF SMALL N" . #x01d5c7) ("MATHEMATICAL SANS-SERIF SMALL O" . #x01d5c8) ("MATHEMATICAL SANS-SERIF SMALL P" . #x01d5c9) ("MATHEMATICAL SANS-SERIF SMALL Q" . #x01d5ca) ("MATHEMATICAL SANS-SERIF SMALL R" . #x01d5cb) ("MATHEMATICAL SANS-SERIF SMALL S" . #x01d5cc) ("MATHEMATICAL SANS-SERIF SMALL T" . #x01d5cd) ("MATHEMATICAL SANS-SERIF SMALL U" . #x01d5ce) ("MATHEMATICAL SANS-SERIF SMALL V" . #x01d5cf) ("MATHEMATICAL SANS-SERIF SMALL W" . #x01d5d0) ("MATHEMATICAL SANS-SERIF SMALL X" . #x01d5d1) ("MATHEMATICAL SANS-SERIF SMALL Y" . #x01d5d2) ("MATHEMATICAL SANS-SERIF SMALL Z" . #x01d5d3) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL A" . #x01d5d4) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL B" . #x01d5d5) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL C" . #x01d5d6) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL D" . #x01d5d7) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL E" . #x01d5d8) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL F" . #x01d5d9) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL G" . #x01d5da) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL H" . #x01d5db) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL I" . #x01d5dc) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL J" . #x01d5dd) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL K" . #x01d5de) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL L" . #x01d5df) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL M" . #x01d5e0) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL N" . #x01d5e1) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL O" . #x01d5e2) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL P" . #x01d5e3) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL Q" . #x01d5e4) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL R" . #x01d5e5) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL S" . #x01d5e6) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL T" . #x01d5e7) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL U" . #x01d5e8) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL V" . #x01d5e9) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL W" . #x01d5ea) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL X" . #x01d5eb) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL Y" . #x01d5ec) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL Z" . #x01d5ed) ("MATHEMATICAL SANS-SERIF BOLD SMALL A" . #x01d5ee) ("MATHEMATICAL SANS-SERIF BOLD SMALL B" . #x01d5ef) ("MATHEMATICAL SANS-SERIF BOLD SMALL C" . #x01d5f0) ("MATHEMATICAL SANS-SERIF BOLD SMALL D" . #x01d5f1) ("MATHEMATICAL SANS-SERIF BOLD SMALL E" . #x01d5f2) ("MATHEMATICAL SANS-SERIF BOLD SMALL F" . #x01d5f3) ("MATHEMATICAL SANS-SERIF BOLD SMALL G" . #x01d5f4) ("MATHEMATICAL SANS-SERIF BOLD SMALL H" . #x01d5f5) ("MATHEMATICAL SANS-SERIF BOLD SMALL I" . #x01d5f6) ("MATHEMATICAL SANS-SERIF BOLD SMALL J" . #x01d5f7) ("MATHEMATICAL SANS-SERIF BOLD SMALL K" . #x01d5f8) ("MATHEMATICAL SANS-SERIF BOLD SMALL L" . #x01d5f9) ("MATHEMATICAL SANS-SERIF BOLD SMALL M" . #x01d5fa) ("MATHEMATICAL SANS-SERIF BOLD SMALL N" . #x01d5fb) ("MATHEMATICAL SANS-SERIF BOLD SMALL O" . #x01d5fc) ("MATHEMATICAL SANS-SERIF BOLD SMALL P" . #x01d5fd) ("MATHEMATICAL SANS-SERIF BOLD SMALL Q" . #x01d5fe) ("MATHEMATICAL SANS-SERIF BOLD SMALL R" . #x01d5ff) ("MATHEMATICAL SANS-SERIF BOLD SMALL S" . #x01d600) ("MATHEMATICAL SANS-SERIF BOLD SMALL T" . #x01d601) ("MATHEMATICAL SANS-SERIF BOLD SMALL U" . #x01d602) ("MATHEMATICAL SANS-SERIF BOLD SMALL V" . #x01d603) ("MATHEMATICAL SANS-SERIF BOLD SMALL W" . #x01d604) ("MATHEMATICAL SANS-SERIF BOLD SMALL X" . #x01d605) ("MATHEMATICAL SANS-SERIF BOLD SMALL Y" . #x01d606) ("MATHEMATICAL SANS-SERIF BOLD SMALL Z" . #x01d607) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL A" . #x01d608) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL B" . #x01d609) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL C" . #x01d60a) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL D" . #x01d60b) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL E" . #x01d60c) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL F" . #x01d60d) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL G" . #x01d60e) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL H" . #x01d60f) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL I" . #x01d610) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL J" . #x01d611) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL K" . #x01d612) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL L" . #x01d613) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL M" . #x01d614) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL N" . #x01d615) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL O" . #x01d616) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL P" . #x01d617) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q" . #x01d618) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL R" . #x01d619) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL S" . #x01d61a) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL T" . #x01d61b) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL U" . #x01d61c) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL V" . #x01d61d) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL W" . #x01d61e) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL X" . #x01d61f) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y" . #x01d620) ("MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z" . #x01d621) ("MATHEMATICAL SANS-SERIF ITALIC SMALL A" . #x01d622) ("MATHEMATICAL SANS-SERIF ITALIC SMALL B" . #x01d623) ("MATHEMATICAL SANS-SERIF ITALIC SMALL C" . #x01d624) ("MATHEMATICAL SANS-SERIF ITALIC SMALL D" . #x01d625) ("MATHEMATICAL SANS-SERIF ITALIC SMALL E" . #x01d626) ("MATHEMATICAL SANS-SERIF ITALIC SMALL F" . #x01d627) ("MATHEMATICAL SANS-SERIF ITALIC SMALL G" . #x01d628) ("MATHEMATICAL SANS-SERIF ITALIC SMALL H" . #x01d629) ("MATHEMATICAL SANS-SERIF ITALIC SMALL I" . #x01d62a) ("MATHEMATICAL SANS-SERIF ITALIC SMALL J" . #x01d62b) ("MATHEMATICAL SANS-SERIF ITALIC SMALL K" . #x01d62c) ("MATHEMATICAL SANS-SERIF ITALIC SMALL L" . #x01d62d) ("MATHEMATICAL SANS-SERIF ITALIC SMALL M" . #x01d62e) ("MATHEMATICAL SANS-SERIF ITALIC SMALL N" . #x01d62f) ("MATHEMATICAL SANS-SERIF ITALIC SMALL O" . #x01d630) ("MATHEMATICAL SANS-SERIF ITALIC SMALL P" . #x01d631) ("MATHEMATICAL SANS-SERIF ITALIC SMALL Q" . #x01d632) ("MATHEMATICAL SANS-SERIF ITALIC SMALL R" . #x01d633) ("MATHEMATICAL SANS-SERIF ITALIC SMALL S" . #x01d634) ("MATHEMATICAL SANS-SERIF ITALIC SMALL T" . #x01d635) ("MATHEMATICAL SANS-SERIF ITALIC SMALL U" . #x01d636) ("MATHEMATICAL SANS-SERIF ITALIC SMALL V" . #x01d637) ("MATHEMATICAL SANS-SERIF ITALIC SMALL W" . #x01d638) ("MATHEMATICAL SANS-SERIF ITALIC SMALL X" . #x01d639) ("MATHEMATICAL SANS-SERIF ITALIC SMALL Y" . #x01d63a) ("MATHEMATICAL SANS-SERIF ITALIC SMALL Z" . #x01d63b) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A" . #x01d63c) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B" . #x01d63d) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C" . #x01d63e) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D" . #x01d63f) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E" . #x01d640) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F" . #x01d641) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G" . #x01d642) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H" . #x01d643) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I" . #x01d644) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J" . #x01d645) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K" . #x01d646) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L" . #x01d647) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M" . #x01d648) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N" . #x01d649) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O" . #x01d64a) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P" . #x01d64b) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q" . #x01d64c) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R" . #x01d64d) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S" . #x01d64e) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T" . #x01d64f) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U" . #x01d650) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V" . #x01d651) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W" . #x01d652) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X" . #x01d653) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y" . #x01d654) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z" . #x01d655) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A" . #x01d656) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B" . #x01d657) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C" . #x01d658) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D" . #x01d659) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E" . #x01d65a) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F" . #x01d65b) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G" . #x01d65c) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H" . #x01d65d) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I" . #x01d65e) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J" . #x01d65f) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K" . #x01d660) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L" . #x01d661) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M" . #x01d662) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N" . #x01d663) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O" . #x01d664) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P" . #x01d665) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q" . #x01d666) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R" . #x01d667) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S" . #x01d668) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T" . #x01d669) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U" . #x01d66a) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V" . #x01d66b) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W" . #x01d66c) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X" . #x01d66d) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y" . #x01d66e) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z" . #x01d66f) ("MATHEMATICAL MONOSPACE CAPITAL A" . #x01d670) ("MATHEMATICAL MONOSPACE CAPITAL B" . #x01d671) ("MATHEMATICAL MONOSPACE CAPITAL C" . #x01d672) ("MATHEMATICAL MONOSPACE CAPITAL D" . #x01d673) ("MATHEMATICAL MONOSPACE CAPITAL E" . #x01d674) ("MATHEMATICAL MONOSPACE CAPITAL F" . #x01d675) ("MATHEMATICAL MONOSPACE CAPITAL G" . #x01d676) ("MATHEMATICAL MONOSPACE CAPITAL H" . #x01d677) ("MATHEMATICAL MONOSPACE CAPITAL I" . #x01d678) ("MATHEMATICAL MONOSPACE CAPITAL J" . #x01d679) ("MATHEMATICAL MONOSPACE CAPITAL K" . #x01d67a) ("MATHEMATICAL MONOSPACE CAPITAL L" . #x01d67b) ("MATHEMATICAL MONOSPACE CAPITAL M" . #x01d67c) ("MATHEMATICAL MONOSPACE CAPITAL N" . #x01d67d) ("MATHEMATICAL MONOSPACE CAPITAL O" . #x01d67e) ("MATHEMATICAL MONOSPACE CAPITAL P" . #x01d67f) ("MATHEMATICAL MONOSPACE CAPITAL Q" . #x01d680) ("MATHEMATICAL MONOSPACE CAPITAL R" . #x01d681) ("MATHEMATICAL MONOSPACE CAPITAL S" . #x01d682) ("MATHEMATICAL MONOSPACE CAPITAL T" . #x01d683) ("MATHEMATICAL MONOSPACE CAPITAL U" . #x01d684) ("MATHEMATICAL MONOSPACE CAPITAL V" . #x01d685) ("MATHEMATICAL MONOSPACE CAPITAL W" . #x01d686) ("MATHEMATICAL MONOSPACE CAPITAL X" . #x01d687) ("MATHEMATICAL MONOSPACE CAPITAL Y" . #x01d688) ("MATHEMATICAL MONOSPACE CAPITAL Z" . #x01d689) ("MATHEMATICAL MONOSPACE SMALL A" . #x01d68a) ("MATHEMATICAL MONOSPACE SMALL B" . #x01d68b) ("MATHEMATICAL MONOSPACE SMALL C" . #x01d68c) ("MATHEMATICAL MONOSPACE SMALL D" . #x01d68d) ("MATHEMATICAL MONOSPACE SMALL E" . #x01d68e) ("MATHEMATICAL MONOSPACE SMALL F" . #x01d68f) ("MATHEMATICAL MONOSPACE SMALL G" . #x01d690) ("MATHEMATICAL MONOSPACE SMALL H" . #x01d691) ("MATHEMATICAL MONOSPACE SMALL I" . #x01d692) ("MATHEMATICAL MONOSPACE SMALL J" . #x01d693) ("MATHEMATICAL MONOSPACE SMALL K" . #x01d694) ("MATHEMATICAL MONOSPACE SMALL L" . #x01d695) ("MATHEMATICAL MONOSPACE SMALL M" . #x01d696) ("MATHEMATICAL MONOSPACE SMALL N" . #x01d697) ("MATHEMATICAL MONOSPACE SMALL O" . #x01d698) ("MATHEMATICAL MONOSPACE SMALL P" . #x01d699) ("MATHEMATICAL MONOSPACE SMALL Q" . #x01d69a) ("MATHEMATICAL MONOSPACE SMALL R" . #x01d69b) ("MATHEMATICAL MONOSPACE SMALL S" . #x01d69c) ("MATHEMATICAL MONOSPACE SMALL T" . #x01d69d) ("MATHEMATICAL MONOSPACE SMALL U" . #x01d69e) ("MATHEMATICAL MONOSPACE SMALL V" . #x01d69f) ("MATHEMATICAL MONOSPACE SMALL W" . #x01d6a0) ("MATHEMATICAL MONOSPACE SMALL X" . #x01d6a1) ("MATHEMATICAL MONOSPACE SMALL Y" . #x01d6a2) ("MATHEMATICAL MONOSPACE SMALL Z" . #x01d6a3) ("MATHEMATICAL BOLD CAPITAL ALPHA" . #x01d6a8) ("MATHEMATICAL BOLD CAPITAL BETA" . #x01d6a9) ("MATHEMATICAL BOLD CAPITAL GAMMA" . #x01d6aa) ("MATHEMATICAL BOLD CAPITAL DELTA" . #x01d6ab) ("MATHEMATICAL BOLD CAPITAL EPSILON" . #x01d6ac) ("MATHEMATICAL BOLD CAPITAL ZETA" . #x01d6ad) ("MATHEMATICAL BOLD CAPITAL ETA" . #x01d6ae) ("MATHEMATICAL BOLD CAPITAL THETA" . #x01d6af) ("MATHEMATICAL BOLD CAPITAL IOTA" . #x01d6b0) ("MATHEMATICAL BOLD CAPITAL KAPPA" . #x01d6b1) ("MATHEMATICAL BOLD CAPITAL LAMDA" . #x01d6b2) ("MATHEMATICAL BOLD CAPITAL MU" . #x01d6b3) ("MATHEMATICAL BOLD CAPITAL NU" . #x01d6b4) ("MATHEMATICAL BOLD CAPITAL XI" . #x01d6b5) ("MATHEMATICAL BOLD CAPITAL OMICRON" . #x01d6b6) ("MATHEMATICAL BOLD CAPITAL PI" . #x01d6b7) ("MATHEMATICAL BOLD CAPITAL RHO" . #x01d6b8) ("MATHEMATICAL BOLD CAPITAL THETA SYMBOL" . #x01d6b9) ("MATHEMATICAL BOLD CAPITAL SIGMA" . #x01d6ba) ("MATHEMATICAL BOLD CAPITAL TAU" . #x01d6bb) ("MATHEMATICAL BOLD CAPITAL UPSILON" . #x01d6bc) ("MATHEMATICAL BOLD CAPITAL PHI" . #x01d6bd) ("MATHEMATICAL BOLD CAPITAL CHI" . #x01d6be) ("MATHEMATICAL BOLD CAPITAL PSI" . #x01d6bf) ("MATHEMATICAL BOLD CAPITAL OMEGA" . #x01d6c0) ("MATHEMATICAL BOLD NABLA" . #x01d6c1) ("MATHEMATICAL BOLD SMALL ALPHA" . #x01d6c2) ("MATHEMATICAL BOLD SMALL BETA" . #x01d6c3) ("MATHEMATICAL BOLD SMALL GAMMA" . #x01d6c4) ("MATHEMATICAL BOLD SMALL DELTA" . #x01d6c5) ("MATHEMATICAL BOLD SMALL EPSILON" . #x01d6c6) ("MATHEMATICAL BOLD SMALL ZETA" . #x01d6c7) ("MATHEMATICAL BOLD SMALL ETA" . #x01d6c8) ("MATHEMATICAL BOLD SMALL THETA" . #x01d6c9) ("MATHEMATICAL BOLD SMALL IOTA" . #x01d6ca) ("MATHEMATICAL BOLD SMALL KAPPA" . #x01d6cb) ("MATHEMATICAL BOLD SMALL LAMDA" . #x01d6cc) ("MATHEMATICAL BOLD SMALL MU" . #x01d6cd) ("MATHEMATICAL BOLD SMALL NU" . #x01d6ce) ("MATHEMATICAL BOLD SMALL XI" . #x01d6cf) ("MATHEMATICAL BOLD SMALL OMICRON" . #x01d6d0) ("MATHEMATICAL BOLD SMALL PI" . #x01d6d1) ("MATHEMATICAL BOLD SMALL RHO" . #x01d6d2) ("MATHEMATICAL BOLD SMALL FINAL SIGMA" . #x01d6d3) ("MATHEMATICAL BOLD SMALL SIGMA" . #x01d6d4) ("MATHEMATICAL BOLD SMALL TAU" . #x01d6d5) ("MATHEMATICAL BOLD SMALL UPSILON" . #x01d6d6) ("MATHEMATICAL BOLD SMALL PHI" . #x01d6d7) ("MATHEMATICAL BOLD SMALL CHI" . #x01d6d8) ("MATHEMATICAL BOLD SMALL PSI" . #x01d6d9) ("MATHEMATICAL BOLD SMALL OMEGA" . #x01d6da) ("MATHEMATICAL BOLD PARTIAL DIFFERENTIAL" . #x01d6db) ("MATHEMATICAL BOLD EPSILON SYMBOL" . #x01d6dc) ("MATHEMATICAL BOLD THETA SYMBOL" . #x01d6dd) ("MATHEMATICAL BOLD KAPPA SYMBOL" . #x01d6de) ("MATHEMATICAL BOLD PHI SYMBOL" . #x01d6df) ("MATHEMATICAL BOLD RHO SYMBOL" . #x01d6e0) ("MATHEMATICAL BOLD PI SYMBOL" . #x01d6e1) ("MATHEMATICAL ITALIC CAPITAL ALPHA" . #x01d6e2) ("MATHEMATICAL ITALIC CAPITAL BETA" . #x01d6e3) ("MATHEMATICAL ITALIC CAPITAL GAMMA" . #x01d6e4) ("MATHEMATICAL ITALIC CAPITAL DELTA" . #x01d6e5) ("MATHEMATICAL ITALIC CAPITAL EPSILON" . #x01d6e6) ("MATHEMATICAL ITALIC CAPITAL ZETA" . #x01d6e7) ("MATHEMATICAL ITALIC CAPITAL ETA" . #x01d6e8) ("MATHEMATICAL ITALIC CAPITAL THETA" . #x01d6e9) ("MATHEMATICAL ITALIC CAPITAL IOTA" . #x01d6ea) ("MATHEMATICAL ITALIC CAPITAL KAPPA" . #x01d6eb) ("MATHEMATICAL ITALIC CAPITAL LAMDA" . #x01d6ec) ("MATHEMATICAL ITALIC CAPITAL MU" . #x01d6ed) ("MATHEMATICAL ITALIC CAPITAL NU" . #x01d6ee) ("MATHEMATICAL ITALIC CAPITAL XI" . #x01d6ef) ("MATHEMATICAL ITALIC CAPITAL OMICRON" . #x01d6f0) ("MATHEMATICAL ITALIC CAPITAL PI" . #x01d6f1) ("MATHEMATICAL ITALIC CAPITAL RHO" . #x01d6f2) ("MATHEMATICAL ITALIC CAPITAL THETA SYMBOL" . #x01d6f3) ("MATHEMATICAL ITALIC CAPITAL SIGMA" . #x01d6f4) ("MATHEMATICAL ITALIC CAPITAL TAU" . #x01d6f5) ("MATHEMATICAL ITALIC CAPITAL UPSILON" . #x01d6f6) ("MATHEMATICAL ITALIC CAPITAL PHI" . #x01d6f7) ("MATHEMATICAL ITALIC CAPITAL CHI" . #x01d6f8) ("MATHEMATICAL ITALIC CAPITAL PSI" . #x01d6f9) ("MATHEMATICAL ITALIC CAPITAL OMEGA" . #x01d6fa) ("MATHEMATICAL ITALIC NABLA" . #x01d6fb) ("MATHEMATICAL ITALIC SMALL ALPHA" . #x01d6fc) ("MATHEMATICAL ITALIC SMALL BETA" . #x01d6fd) ("MATHEMATICAL ITALIC SMALL GAMMA" . #x01d6fe) ("MATHEMATICAL ITALIC SMALL DELTA" . #x01d6ff) ("MATHEMATICAL ITALIC SMALL EPSILON" . #x01d700) ("MATHEMATICAL ITALIC SMALL ZETA" . #x01d701) ("MATHEMATICAL ITALIC SMALL ETA" . #x01d702) ("MATHEMATICAL ITALIC SMALL THETA" . #x01d703) ("MATHEMATICAL ITALIC SMALL IOTA" . #x01d704) ("MATHEMATICAL ITALIC SMALL KAPPA" . #x01d705) ("MATHEMATICAL ITALIC SMALL LAMDA" . #x01d706) ("MATHEMATICAL ITALIC SMALL MU" . #x01d707) ("MATHEMATICAL ITALIC SMALL NU" . #x01d708) ("MATHEMATICAL ITALIC SMALL XI" . #x01d709) ("MATHEMATICAL ITALIC SMALL OMICRON" . #x01d70a) ("MATHEMATICAL ITALIC SMALL PI" . #x01d70b) ("MATHEMATICAL ITALIC SMALL RHO" . #x01d70c) ("MATHEMATICAL ITALIC SMALL FINAL SIGMA" . #x01d70d) ("MATHEMATICAL ITALIC SMALL SIGMA" . #x01d70e) ("MATHEMATICAL ITALIC SMALL TAU" . #x01d70f) ("MATHEMATICAL ITALIC SMALL UPSILON" . #x01d710) ("MATHEMATICAL ITALIC SMALL PHI" . #x01d711) ("MATHEMATICAL ITALIC SMALL CHI" . #x01d712) ("MATHEMATICAL ITALIC SMALL PSI" . #x01d713) ("MATHEMATICAL ITALIC SMALL OMEGA" . #x01d714) ("MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL" . #x01d715) ("MATHEMATICAL ITALIC EPSILON SYMBOL" . #x01d716) ("MATHEMATICAL ITALIC THETA SYMBOL" . #x01d717) ("MATHEMATICAL ITALIC KAPPA SYMBOL" . #x01d718) ("MATHEMATICAL ITALIC PHI SYMBOL" . #x01d719) ("MATHEMATICAL ITALIC RHO SYMBOL" . #x01d71a) ("MATHEMATICAL ITALIC PI SYMBOL" . #x01d71b) ("MATHEMATICAL BOLD ITALIC CAPITAL ALPHA" . #x01d71c) ("MATHEMATICAL BOLD ITALIC CAPITAL BETA" . #x01d71d) ("MATHEMATICAL BOLD ITALIC CAPITAL GAMMA" . #x01d71e) ("MATHEMATICAL BOLD ITALIC CAPITAL DELTA" . #x01d71f) ("MATHEMATICAL BOLD ITALIC CAPITAL EPSILON" . #x01d720) ("MATHEMATICAL BOLD ITALIC CAPITAL ZETA" . #x01d721) ("MATHEMATICAL BOLD ITALIC CAPITAL ETA" . #x01d722) ("MATHEMATICAL BOLD ITALIC CAPITAL THETA" . #x01d723) ("MATHEMATICAL BOLD ITALIC CAPITAL IOTA" . #x01d724) ("MATHEMATICAL BOLD ITALIC CAPITAL KAPPA" . #x01d725) ("MATHEMATICAL BOLD ITALIC CAPITAL LAMDA" . #x01d726) ("MATHEMATICAL BOLD ITALIC CAPITAL MU" . #x01d727) ("MATHEMATICAL BOLD ITALIC CAPITAL NU" . #x01d728) ("MATHEMATICAL BOLD ITALIC CAPITAL XI" . #x01d729) ("MATHEMATICAL BOLD ITALIC CAPITAL OMICRON" . #x01d72a) ("MATHEMATICAL BOLD ITALIC CAPITAL PI" . #x01d72b) ("MATHEMATICAL BOLD ITALIC CAPITAL RHO" . #x01d72c) ("MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL" . #x01d72d) ("MATHEMATICAL BOLD ITALIC CAPITAL SIGMA" . #x01d72e) ("MATHEMATICAL BOLD ITALIC CAPITAL TAU" . #x01d72f) ("MATHEMATICAL BOLD ITALIC CAPITAL UPSILON" . #x01d730) ("MATHEMATICAL BOLD ITALIC CAPITAL PHI" . #x01d731) ("MATHEMATICAL BOLD ITALIC CAPITAL CHI" . #x01d732) ("MATHEMATICAL BOLD ITALIC CAPITAL PSI" . #x01d733) ("MATHEMATICAL BOLD ITALIC CAPITAL OMEGA" . #x01d734) ("MATHEMATICAL BOLD ITALIC NABLA" . #x01d735) ("MATHEMATICAL BOLD ITALIC SMALL ALPHA" . #x01d736) ("MATHEMATICAL BOLD ITALIC SMALL BETA" . #x01d737) ("MATHEMATICAL BOLD ITALIC SMALL GAMMA" . #x01d738) ("MATHEMATICAL BOLD ITALIC SMALL DELTA" . #x01d739) ("MATHEMATICAL BOLD ITALIC SMALL EPSILON" . #x01d73a) ("MATHEMATICAL BOLD ITALIC SMALL ZETA" . #x01d73b) ("MATHEMATICAL BOLD ITALIC SMALL ETA" . #x01d73c) ("MATHEMATICAL BOLD ITALIC SMALL THETA" . #x01d73d) ("MATHEMATICAL BOLD ITALIC SMALL IOTA" . #x01d73e) ("MATHEMATICAL BOLD ITALIC SMALL KAPPA" . #x01d73f) ("MATHEMATICAL BOLD ITALIC SMALL LAMDA" . #x01d740) ("MATHEMATICAL BOLD ITALIC SMALL MU" . #x01d741) ("MATHEMATICAL BOLD ITALIC SMALL NU" . #x01d742) ("MATHEMATICAL BOLD ITALIC SMALL XI" . #x01d743) ("MATHEMATICAL BOLD ITALIC SMALL OMICRON" . #x01d744) ("MATHEMATICAL BOLD ITALIC SMALL PI" . #x01d745) ("MATHEMATICAL BOLD ITALIC SMALL RHO" . #x01d746) ("MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA" . #x01d747) ("MATHEMATICAL BOLD ITALIC SMALL SIGMA" . #x01d748) ("MATHEMATICAL BOLD ITALIC SMALL TAU" . #x01d749) ("MATHEMATICAL BOLD ITALIC SMALL UPSILON" . #x01d74a) ("MATHEMATICAL BOLD ITALIC SMALL PHI" . #x01d74b) ("MATHEMATICAL BOLD ITALIC SMALL CHI" . #x01d74c) ("MATHEMATICAL BOLD ITALIC SMALL PSI" . #x01d74d) ("MATHEMATICAL BOLD ITALIC SMALL OMEGA" . #x01d74e) ("MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL" . #x01d74f) ("MATHEMATICAL BOLD ITALIC EPSILON SYMBOL" . #x01d750) ("MATHEMATICAL BOLD ITALIC THETA SYMBOL" . #x01d751) ("MATHEMATICAL BOLD ITALIC KAPPA SYMBOL" . #x01d752) ("MATHEMATICAL BOLD ITALIC PHI SYMBOL" . #x01d753) ("MATHEMATICAL BOLD ITALIC RHO SYMBOL" . #x01d754) ("MATHEMATICAL BOLD ITALIC PI SYMBOL" . #x01d755) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA" . #x01d756) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA" . #x01d757) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA" . #x01d758) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA" . #x01d759) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON" . #x01d75a) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA" . #x01d75b) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA" . #x01d75c) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA" . #x01d75d) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA" . #x01d75e) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA" . #x01d75f) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA" . #x01d760) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL MU" . #x01d761) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL NU" . #x01d762) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL XI" . #x01d763) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON" . #x01d764) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL PI" . #x01d765) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO" . #x01d766) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL" . #x01d767) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA" . #x01d768) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU" . #x01d769) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON" . #x01d76a) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI" . #x01d76b) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI" . #x01d76c) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI" . #x01d76d) ("MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA" . #x01d76e) ("MATHEMATICAL SANS-SERIF BOLD NABLA" . #x01d76f) ("MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA" . #x01d770) ("MATHEMATICAL SANS-SERIF BOLD SMALL BETA" . #x01d771) ("MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA" . #x01d772) ("MATHEMATICAL SANS-SERIF BOLD SMALL DELTA" . #x01d773) ("MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON" . #x01d774) ("MATHEMATICAL SANS-SERIF BOLD SMALL ZETA" . #x01d775) ("MATHEMATICAL SANS-SERIF BOLD SMALL ETA" . #x01d776) ("MATHEMATICAL SANS-SERIF BOLD SMALL THETA" . #x01d777) ("MATHEMATICAL SANS-SERIF BOLD SMALL IOTA" . #x01d778) ("MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA" . #x01d779) ("MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA" . #x01d77a) ("MATHEMATICAL SANS-SERIF BOLD SMALL MU" . #x01d77b) ("MATHEMATICAL SANS-SERIF BOLD SMALL NU" . #x01d77c) ("MATHEMATICAL SANS-SERIF BOLD SMALL XI" . #x01d77d) ("MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON" . #x01d77e) ("MATHEMATICAL SANS-SERIF BOLD SMALL PI" . #x01d77f) ("MATHEMATICAL SANS-SERIF BOLD SMALL RHO" . #x01d780) ("MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA" . #x01d781) ("MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA" . #x01d782) ("MATHEMATICAL SANS-SERIF BOLD SMALL TAU" . #x01d783) ("MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON" . #x01d784) ("MATHEMATICAL SANS-SERIF BOLD SMALL PHI" . #x01d785) ("MATHEMATICAL SANS-SERIF BOLD SMALL CHI" . #x01d786) ("MATHEMATICAL SANS-SERIF BOLD SMALL PSI" . #x01d787) ("MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA" . #x01d788) ("MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL" . #x01d789) ("MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL" . #x01d78a) ("MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL" . #x01d78b) ("MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL" . #x01d78c) ("MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL" . #x01d78d) ("MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL" . #x01d78e) ("MATHEMATICAL SANS-SERIF BOLD PI SYMBOL" . #x01d78f) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA" . #x01d790) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA" . #x01d791) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA" . #x01d792) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA" . #x01d793) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON" . #x01d794) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA" . #x01d795) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA" . #x01d796) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA" . #x01d797) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA" . #x01d798) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA" . #x01d799) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA" . #x01d79a) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU" . #x01d79b) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU" . #x01d79c) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI" . #x01d79d) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON" . #x01d79e) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI" . #x01d79f) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO" . #x01d7a0) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL" . #x01d7a1) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA" . #x01d7a2) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU" . #x01d7a3) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON" . #x01d7a4) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI" . #x01d7a5) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI" . #x01d7a6) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI" . #x01d7a7) ("MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA" . #x01d7a8) ("MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA" . #x01d7a9) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA" . #x01d7aa) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA" . #x01d7ab) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA" . #x01d7ac) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA" . #x01d7ad) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON" . #x01d7ae) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA" . #x01d7af) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA" . #x01d7b0) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA" . #x01d7b1) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA" . #x01d7b2) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA" . #x01d7b3) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA" . #x01d7b4) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU" . #x01d7b5) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU" . #x01d7b6) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI" . #x01d7b7) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON" . #x01d7b8) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI" . #x01d7b9) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO" . #x01d7ba) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA" . #x01d7bb) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA" . #x01d7bc) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU" . #x01d7bd) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON" . #x01d7be) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI" . #x01d7bf) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI" . #x01d7c0) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI" . #x01d7c1) ("MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA" . #x01d7c2) ("MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL" . #x01d7c3) ("MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL" . #x01d7c4) ("MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL" . #x01d7c5) ("MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL" . #x01d7c6) ("MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL" . #x01d7c7) ("MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL" . #x01d7c8) ("MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL" . #x01d7c9) ("MATHEMATICAL BOLD DIGIT ZERO" . #x01d7ce) ("MATHEMATICAL BOLD DIGIT ONE" . #x01d7cf) ("MATHEMATICAL BOLD DIGIT TWO" . #x01d7d0) ("MATHEMATICAL BOLD DIGIT THREE" . #x01d7d1) ("MATHEMATICAL BOLD DIGIT FOUR" . #x01d7d2) ("MATHEMATICAL BOLD DIGIT FIVE" . #x01d7d3) ("MATHEMATICAL BOLD DIGIT SIX" . #x01d7d4) ("MATHEMATICAL BOLD DIGIT SEVEN" . #x01d7d5) ("MATHEMATICAL BOLD DIGIT EIGHT" . #x01d7d6) ("MATHEMATICAL BOLD DIGIT NINE" . #x01d7d7) ("MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO" . #x01d7d8) ("MATHEMATICAL DOUBLE-STRUCK DIGIT ONE" . #x01d7d9) ("MATHEMATICAL DOUBLE-STRUCK DIGIT TWO" . #x01d7da) ("MATHEMATICAL DOUBLE-STRUCK DIGIT THREE" . #x01d7db) ("MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR" . #x01d7dc) ("MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE" . #x01d7dd) ("MATHEMATICAL DOUBLE-STRUCK DIGIT SIX" . #x01d7de) ("MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN" . #x01d7df) ("MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT" . #x01d7e0) ("MATHEMATICAL DOUBLE-STRUCK DIGIT NINE" . #x01d7e1) ("MATHEMATICAL SANS-SERIF DIGIT ZERO" . #x01d7e2) ("MATHEMATICAL SANS-SERIF DIGIT ONE" . #x01d7e3) ("MATHEMATICAL SANS-SERIF DIGIT TWO" . #x01d7e4) ("MATHEMATICAL SANS-SERIF DIGIT THREE" . #x01d7e5) ("MATHEMATICAL SANS-SERIF DIGIT FOUR" . #x01d7e6) ("MATHEMATICAL SANS-SERIF DIGIT FIVE" . #x01d7e7) ("MATHEMATICAL SANS-SERIF DIGIT SIX" . #x01d7e8) ("MATHEMATICAL SANS-SERIF DIGIT SEVEN" . #x01d7e9) ("MATHEMATICAL SANS-SERIF DIGIT EIGHT" . #x01d7ea) ("MATHEMATICAL SANS-SERIF DIGIT NINE" . #x01d7eb) ("MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO" . #x01d7ec) ("MATHEMATICAL SANS-SERIF BOLD DIGIT ONE" . #x01d7ed) ("MATHEMATICAL SANS-SERIF BOLD DIGIT TWO" . #x01d7ee) ("MATHEMATICAL SANS-SERIF BOLD DIGIT THREE" . #x01d7ef) ("MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR" . #x01d7f0) ("MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE" . #x01d7f1) ("MATHEMATICAL SANS-SERIF BOLD DIGIT SIX" . #x01d7f2) ("MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN" . #x01d7f3) ("MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT" . #x01d7f4) ("MATHEMATICAL SANS-SERIF BOLD DIGIT NINE" . #x01d7f5) ("MATHEMATICAL MONOSPACE DIGIT ZERO" . #x01d7f6) ("MATHEMATICAL MONOSPACE DIGIT ONE" . #x01d7f7) ("MATHEMATICAL MONOSPACE DIGIT TWO" . #x01d7f8) ("MATHEMATICAL MONOSPACE DIGIT THREE" . #x01d7f9) ("MATHEMATICAL MONOSPACE DIGIT FOUR" . #x01d7fa) ("MATHEMATICAL MONOSPACE DIGIT FIVE" . #x01d7fb) ("MATHEMATICAL MONOSPACE DIGIT SIX" . #x01d7fc) ("MATHEMATICAL MONOSPACE DIGIT SEVEN" . #x01d7fd) ("MATHEMATICAL MONOSPACE DIGIT EIGHT" . #x01d7fe) ("MATHEMATICAL MONOSPACE DIGIT NINE" . #x01d7ff))) ;; taken from xmlunicode.el, also by Norman Walsh. ;; Modified a bit by me to use its own help-style buffer ;;;###autoload (defun unicode-chars-list-chars () "Insert each Unicode character into a buffer. Lets you see which characters are available for literal display in your emacs font." (interactive) (pop-to-buffer "*unicode-chars*") (let ((chars unicode-chars-alist) char codept name) (while chars (setq char (car chars)) (setq chars (cdr chars)) (setq name (car char)) (setq codept (cdr char)) (if (< codept #xffff) (progn (insert (format "#x%06x " codept)) (insert-char codept 1) (insert (format " %s\n" name))))))) (provide 'unicode-chars) proofgeneral-4.3~pre130510/lib/unicode-tokens.el000066400000000000000000001506471214562307500214630ustar00rootroot00000000000000;;; unicode-tokens.el --- Support for control and symbol tokens ;; ;; Copyright(C) 2008-2010 David Aspinall / LFCS Edinburgh ;; Author: David Aspinall ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; ;; $Id: unicode-tokens.el,v 12.3 2012/09/04 20:57:54 da Exp $ ;; ;; This 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. ;; This software is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; ;; This is a replacement for X-Symbol for Proof General. ;; ;; Functions to display tokens that represent Unicode characters and ;; control code sequences for changing the layout. Tokens are useful ;; for programs that do not understand a Unicode encoding. ;; ;; Desirable improvements/enhancements ;; ;; -- insert tokens via numeric code (extra format string), cf HTML ;; -- simplify: unify region and control settings? ;; -- simplify/optimise property handling ;; -- support multiple modes with mode-local configs at once ;; ;;; Code: ;; (require 'cl) (require 'quail) (eval-when-compile (require 'maths-menu) ; nuke compile warnings ;; Emacs <24 compatibility (when (and (fboundp 'flet) (not (get 'flet 'byte-obsolete-info))) (defalias 'cl-flet 'flet))) ;; ;; Customizable user options ;; (defgroup unicode-tokens-options nil "User options for Unicode Tokens mode." :group 'faces :prefix "unicode-tokens-") (defcustom unicode-tokens-add-help-echo t "If non-nil, add mouse hover (or minibuffer messages) to show tokens." :type 'boolean :group 'unicode-tokens-options) (defun unicode-tokens-toggle-add-help-echo () (interactive) (customize-set-variable 'unicode-tokens-add-help-echo (not unicode-tokens-add-help-echo)) ;; NB: approximate, should refontify all... (font-lock-fontify-buffer)) ;; ;; Variables that should be set by client modes ;; ;; Each variable may be set directly or indirectly; see ;; `unicode-tokens-copy-configuration-variables' below. ;; (defvar unicode-tokens-token-symbol-map nil "Mapping of token names to compositions. A list, each element of which is a list (TOKNAME COMPOSITION FONTSYMB ...) A composition is typically a single Unicode character string, but can be more complex: see documentation of `compose-region'. TOKNAMEs may be repeated. The first one with a usable composition according to `unicode-tokens-usable-composition', if any. The sequence of FONTSYMB are optional. Each FONTSYMB is a symbol indicating a set of additional text properties, looked up in `unicode-tokens-fontsymb-properties'. By default, tokens are displayed in `unicode-tokens-symbol-font-face'.") (defvar unicode-tokens-token-format "%s" "Format string for formatting token a name into a token. Will be regexp quoted for matching. Not used for matching if `unicode-tokens-token-variant-format-regexp' is set. Also used to format shortcuts.") (defvar unicode-tokens-token-variant-format-regexp nil "A regular expression which matches a token variant. Will not be regexp quoted, and will be formatted with a nested regexp that matches any token. An example would be: \\\\(%s\\\\)\\\\(:?\\w+\\\\) which matches plain token strings optionally followed by a colon and variant name. Once set, (match-string 1) should be the name of the token whereas (match-string 0) matches the longer text, if any. If set, this variable is used instead of `unicode-tokens-token-format'.") (defvar unicode-tokens-shortcut-alist nil "An alist of keyboard shortcuts to unicode strings. The alist is added to the input mode for tokens. The shortcuts are only used for input convenience; no reverse mapping back to shortucts is performed. Behaviour is like abbrev.") (defvar unicode-tokens-shortcut-replacement-alist nil "Overrides `unicode-tokens-shortcut-alist' for `unicode-tokens-replace-shortcuts'.") ;; ;; Variables that may optionally be set in client modes ;; (defvar unicode-tokens-control-region-format-regexp nil "A regexp for control regions, with up to two %s placeholders. When fomatted with arguments START END, results in a regexp that matches a control region. There should be three delimited subexpressions: (match-string 1) and (match-string 3) are hidden, and (match-string 2) has the display control applied.") (defvar unicode-tokens-control-char-format-regexp nil "A format string for control characters, possibly with a %s placeholder. When fomatted with arguments STRING, results in a regexp that matches a control character sequence. There should be two delimited subexpressions: (match-string 1) is hidden and (match-string 2) has the display control applied.") (defvar unicode-tokens-control-regions nil "A list of control regions.") (defvar unicode-tokens-control-characters nil "A list of control characters.") (defvar unicode-tokens-control-char-format nil "A format string for inserting a control character sequence.") (defvar unicode-tokens-control-region-format-start nil "A format string for begining a control region sequence.") (defvar unicode-tokens-control-region-format-end nil "A format string for ending a control region sequence.") (defvar unicode-tokens-tokens-customizable-variables nil "A list of lists (NAME VAR) of variables for a customize submenu.") ;; ;; A list of the above variables ;; (defconst unicode-tokens-configuration-variables '(token-symbol-map token-format token-variant-format-regexp shortcut-alist shortcut-replacement-alist control-region-format-regexp control-region-format-start control-region-format-end control-char-format-regexp control-char-format control-regions control-characters tokens-customizable-variables)) (defun unicode-tokens-config (sym) "Construct the symbol name `unicode-tokens-SYM'." (intern (concat "unicode-tokens-" (symbol-name sym)))) (defun unicode-tokens-config-var (sym) "Construct the symbol name `unicode-tokens-SYM-variable'." (intern (concat "unicode-tokens-" (symbol-name sym) "-variable"))) (dolist (sym unicode-tokens-configuration-variables) (lambda (sym) (eval `(defvar ,(unicode-tokens-config-var sym) nil ,(format "Name of a variable used to configure %s.\nValue should be a symbol." (symbol-name (unicode-tokens-config sym))))))) (defun unicode-tokens-copy-configuration-variables () "Initialise the configuration variables by copying from variable names. Each configuration variable may be set directly or indirectly by client; modes an indirect setting is made by this function from a variable named -variable, e.g., `unicode-tokens-token-symbol-map' will be initialised from `unicode-tokens-token-symbol-map-variable', if it is bound; it should be the name of a variable." (dolist (sym unicode-tokens-configuration-variables) (let ((var (unicode-tokens-config-var sym))) (if (and (boundp var) (not (null (symbol-value var)))) (set (unicode-tokens-config sym) (symbol-value (symbol-value (unicode-tokens-config-var sym))))))) (unless unicode-tokens-shortcut-replacement-alist (setq unicode-tokens-shortcut-replacement-alist unicode-tokens-shortcut-alist)) (unless unicode-tokens-tokens-customizable-variables (setq unicode-tokens-tokens-customizable-variables (list (list "Token Map" (symbol-value (unicode-tokens-config-var 'token-symbol-map))) (list "Shortcut List" (symbol-value (unicode-tokens-config-var 'shortcut-alist))))))) ;; ;; Variables set in the mode ;; (defvar unicode-tokens-token-list nil "List of usable token names in order from `unicode-tokens-token-symbol-map'.") (defvar unicode-tokens-hash-table nil "Hash table mapping token names (strings) to composition and properties.") (defvar unicode-tokens-token-match-regexp nil "Regular expression used by font-lock to match known tokens. The match should span the whole token; (match-string 1) should span the token name, if that is shorter. The value is calculated by `unicode-tokens-calculate-token-match'.") (defvar unicode-tokens-uchar-hash-table nil "Hash table mapping unicode strings to symbolic token names. This is used for an approximate reverse mapping, see `unicode-tokens-paste'.") (defvar unicode-tokens-uchar-regexp nil "Regular expression matching converted tokens. This is used for an approximate reverse mapping, see `unicode-tokens-paste'.") ;; ;; Faces ;; (defgroup unicode-tokens-faces nil "The faces used in Unicode Tokens mode." :group 'faces) ;; ;; This is a fallback for when fontconfig is not used/available. ;; ;; NB: even with fontconfig, name aliasing has undesirable effects ;; (e.g., can end up with version of font without anti-aliasing) ;; (defconst unicode-tokens-font-family-alternatives '(("STIXGeneral" "DejaVu Sans Mono" "DejaVuLGC Sans Mono" "Lucida Grande" "Lucida Sans Unicode" "Apple Symbols") ("Script" "Lucida Calligraphy" "URW Chancery L" "Zapf Chancery") ("Fraktur" "Lucida Blackletter" "Isabella" "URW Bookman L"))) (if (boundp 'face-font-family-alternatives) (custom-set-default 'face-font-family-alternatives (append face-font-family-alternatives unicode-tokens-font-family-alternatives))) (defface unicode-tokens-symbol-font-face '((t :family "STIXGeneral")) ;; best, but needs installation/config ; '((t :family "DejaVu Sans Mono")) ;; more reliable default on Ubuntu "The default font used for symbols. Only :family and :slant attributes are used." :group 'unicode-tokens-faces) ;; (defface unicode-tokens-large-symbol-font-face ;; '((t :family "STIXSizeThreeSym")) ;; "The font used for large symbols." ;; :group 'unicode-tokens-faces) (defface unicode-tokens-script-font-face '((t :family "URW Chancery L" :slant italic)) "Script font face." :group 'unicode-tokens-faces) (defface unicode-tokens-fraktur-font-face '((t :family "Fraktur")) "Fraktur font face." :group 'unicode-tokens-faces) (defface unicode-tokens-serif-font-face '((t :family "Times New Roman")) "Serif (roman) font face." :group 'unicode-tokens-faces) (defface unicode-tokens-sans-font-face '((t :family "Sans")) "Sans serif font face." :group 'unicode-tokens-faces) (defface unicode-tokens-highlight-face '((((min-colors 88) (background dark)) (:background "yellow1" :foreground "black")) (((background dark)) (:background "yellow" :foreground "black")) (((min-colors 88)) (:background "yellow1")) (t (:background "yellow"))) "Face used for highlighting in Unicode tokens." :group 'unicode-tokens-faces) (defconst unicode-tokens-fonts '(symbol script fraktur serif sans) ; large-symbol "A list of the faces used for setting fonts for Unicode Tokens.") ;; ;; Standard text properties used to build fontification ;; (defconst unicode-tokens-fontsymb-properties '((sub "Lower" (display (raise -0.4))) (sup "Raise" (display (raise 0.4))) (bold "Bold" (face (:weight bold))) (italic "Italic" (face (:slant italic))) (big "Bigger" (face (:height 1.5))) (small "Smaller" (face (:height 0.75))) (underline "Underline" (face (:underline t))) (overline "Overline" (face (:overline t))) ;; NB: symbols for fonts need to be as in unicode-tokens-fonts (script "Script font" (face unicode-tokens-script-font-face)) (frakt "Frakt font" (face unicode-tokens-fraktur-font-face)) (serif "Serif font" (face unicode-tokens-serif-font-face)) (sans "Sans font" (face unicode-tokens-sans-font-face)) ; (large-symbol "Large Symbol font" ; (face unicode-tokens-large-symbol-font-face)) (keyword "Keyword face" (face font-lock-keyword-face)) (function "Function name face" (face font-lock-function-name-face)) (type "Type face" (face font-lock-type-face)) (preprocessor "Preprocessor face" (face font-lock-preprocessor-face)) (doc "Documentation face" (face font-lock-preprocessor-face)) (builtin "Builtin face" (face font-lock-builtin-face)) (tacticals "Tacticals face" (face proof-tacticals-name-face))) "Association list mapping a symbol to a name and list of text properties. Used in `unicode-tokens-token-symbol-map', `unicode-tokens-control-regions', and `unicode-tokens-control-characters'. Several symbols can be used at once, in `unicode-tokens-token-symbol-map'.") (define-widget 'unicode-tokens-token-symbol-map 'lazy "Type for customize variables used to set `unicode-tokens-token-symbol-map'." :offset 4 :tag "Token symbol map" :type ;; TODO: improve this so customize editing is more pleasant. (list 'repeat :tag "Map entries" (append '(list :tag "Mapping" (string :tag "Token name") (sexp :tag "Composition")) (list (append '(set :tag "Text property styles" :inline t) (mapcar (lambda (fsp) (list 'const :tag (cadr fsp) (car fsp))) unicode-tokens-fontsymb-properties)))))) (define-widget 'unicode-tokens-shortcut-alist 'lazy "Type for customize variables used to set `unicode-tokens-shortcut-alist'." :offset 4 :tag "Shortcut list" :type '(repeat :tag "Shortcut list" (cons (string :tag "Shortcut sequence") (string :tag "Buffer string")))) ;; ;; Calculating font-lock-keywords ;; (defconst unicode-tokens-font-lock-extra-managed-props '(composition help-echo display invisible) "Value for `font-lock-extra-managed-props' here.") (defun unicode-tokens-font-lock-keywords () "Calculate and return value for `font-lock-keywords'. This function also initialises the important tables for the mode." ;; Credit to Stefan Monnier for much slimmer original version (let ((hash (make-hash-table :test 'equal)) (ucharhash (make-hash-table :test 'equal)) toks uchars) (dolist (x unicode-tokens-token-symbol-map) (let ((tok (car x)) (comp (cadr x))) (when (unicode-tokens-usable-composition comp) (unless (gethash tok hash) (puthash tok (cdr x) hash) (push tok toks) (if (stringp comp) ;; reverse map only for string comps (unless (or (gethash comp ucharhash) ;; ignore plain chars for reverse map (string-match "[a-zA-Z0-9]+" comp)) (push comp uchars) (puthash comp tok ucharhash))))))) (when toks (setq unicode-tokens-hash-table hash) (setq unicode-tokens-uchar-hash-table ucharhash) (setq unicode-tokens-uchar-regexp (regexp-opt uchars)) (setq unicode-tokens-token-match-regexp (unicode-tokens-calculate-token-match toks)) (setq unicode-tokens-token-list (nreverse toks)) (cons `(,unicode-tokens-token-match-regexp (0 (unicode-tokens-help-echo) prepend) (0 (unicode-tokens-font-lock-compose-symbol 1) prepend)) (unicode-tokens-control-font-lock-keywords))))) (defun unicode-tokens-calculate-token-match (toks) "Calculate value for `unicode-tokens-token-match-regexp'." ; (with-syntax-table (standard-syntax-table) ;; hairy logic based on Coq-style vs Isabelle-style configs (if (string= "" (format unicode-tokens-token-format "")) ;; no special token format, parse separate words/symbols (let* ((optoks (remove* "^\\(?:\\sw\\|\\s_\\)+$" toks :test 'string-match)) (idtoks (set-difference toks optoks)) (idorop (concat "\\(\\_<" (regexp-opt idtoks) "\\_>\\|\\(?:\\B" (regexp-opt optoks) "\\B\\)\\)"))) (if unicode-tokens-token-variant-format-regexp (format unicode-tokens-token-variant-format-regexp idorop) idorop)) ;; otherwise, assumption is that token syntax delimits tokens (if unicode-tokens-token-variant-format-regexp (format unicode-tokens-token-variant-format-regexp (regexp-opt toks)) (regexp-opt (mapcar (lambda (tok) (format unicode-tokens-token-format tok)) toks)))));) (defun unicode-tokens-usable-composition (comp) "Return non-nil if the composition COMP seems to be usable. The check is with `char-displayable-p'." (cond ((stringp comp) (reduce (lambda (x y) (and x (char-displayable-p y))) comp :initial-value t)) ((characterp comp) (char-displayable-p comp)) (comp ;; assume any other non-null is OK t))) (defun unicode-tokens-help-echo () "Return a help-echo text property to display the contents of match string." (if unicode-tokens-add-help-echo (list 'face nil 'help-echo (match-string 0)))) (defvar unicode-tokens-show-symbols nil "Non-nil to reveal symbol (composed) tokens instead of compositions.") (defun unicode-tokens-interpret-composition (comp) "Turn the composition string COMP into an argument for `compose-region'." (cond ((and (stringp comp) (= 1 (length comp))) comp) ((stringp comp) ;; change a longer string into a sequence placing glyphs left-to-right. (let ((chars (nreverse (string-to-list comp))) (sep '(5 . 3)) res) (while chars (setq res (cons (car chars) res)) (if (setq chars (cdr chars)) (setq res (cons sep res)))) res)) (t comp))) (defun unicode-tokens-font-lock-compose-symbol (match) "Compose a sequence of chars into a symbol. Regexp match data number MATCH selects the token name, while match number 1 matches the text to be replaced. Token name from MATCH is searched for in `unicode-tokens-hash-table'. The face property is set to the :family and :slant attriubutes taken from `unicode-tokens-symbol-font-face'." (let* ((start (match-beginning 0)) (end (match-end 0)) (compps (gethash (match-string match) unicode-tokens-hash-table)) (propsyms (cdr-safe compps)) (comp (car-safe compps))) (if (and comp (not unicode-tokens-show-symbols)) (compose-region start end (unicode-tokens-interpret-composition comp))) (if propsyms (let ((props (unicode-tokens-symbs-to-props propsyms))) (while props (font-lock-append-text-property start end (car props) (cadr props)) (setq props (cddr props))))) (unless (or unicode-tokens-show-symbols (intersection unicode-tokens-fonts propsyms)) (font-lock-append-text-property start end 'face ;; just use family and slant to enhance merging with other faces (list :family (face-attribute 'unicode-tokens-symbol-font-face :family))) (if (face-attribute 'unicode-tokens-symbol-font-face :slant) (font-lock-append-text-property start end 'face (list :slant (face-attribute 'unicode-tokens-symbol-font-face :slant)))) ) ;; [returning face property here seems to have no effect?] nil)) (defun unicode-tokens-prepend-text-properties-in-match (props matchno) (let ((start (match-beginning matchno)) (end (match-end matchno))) (while props (unicode-tokens-prepend-text-property start end (car props) (cadr props)) (setq props (cddr props))) nil)) ;; this is adapted from font-lock-prepend-text-property, which ;; currently fails to merge property values for 'face property properly. ;; e.g., it makes (:slant italic (:weight bold font-lock-string-face)) ;; rather than (:slant italic :weight bold font-lock-string-face) ;; (defun unicode-tokens-prepend-text-property (start end prop value &optional object) "Prepend to one property of the text from START to END. Arguments PROP and VALUE specify the property and value to append to the value already in place. The resulting property values are always lists. Optional argument OBJECT is the string or buffer containing the text." (let ((val (if (listp value) value (list value))) next prev) (while (/= start end) (setq next (next-single-property-change start prop object end) prev (get-text-property start prop object)) ;; Canonicalize old forms of face property. (and (memq prop '(face font-lock-face)) (listp prev) (or (keywordp (car prev)) (memq (car prev) '(foreground-color background-color))) (setq prev (list prev))) (setq prev (if (listp prev) prev (list prev))) ;; hack to flatten erroneously nested face property lists (if (and (memq prop '(face font-lock-face)) (listp (car prev)) (null (cdr prev))) (setq prev (car prev))) (put-text-property start next prop (append prev val) object) (setq start next)))) (defun unicode-tokens-show-symbols (&optional arg) "Toggle variable `unicode-tokens-show-symbols'. With ARG, turn on iff positive." (interactive "P") (setq unicode-tokens-show-symbols (if (null arg) (not unicode-tokens-show-symbols) (> (prefix-numeric-value arg) 0))) (font-lock-fontify-buffer)) (defun unicode-tokens-symbs-to-props (symbs &optional facenil) "Turn the property name list SYMBS into a list of text properties. Symbols are looked up in `unicode-tokens-fontsymb-properties'. Optional argument FACENIL means set the face property to nil, unless 'face is in the property list." (let (props ps) (dolist (s symbs) (setq ps (cdr-safe (cdr-safe (assoc s unicode-tokens-fontsymb-properties)))) (dolist (p ps) (setq props (append p props)))) (if (and facenil (not (memq 'face props))) (setq props (append '(face nil) props))) props)) ;; ;; Control tokens: as "characters" CTRL ;; and regions BEGINCTRL ENDCTRL ;; (defvar unicode-tokens-show-controls nil "Non-nil supresses hiding of control tokens.") (defun unicode-tokens-show-controls (&optional arg) "Toggle variable `unicode-tokens-show-controls'. With ARG, turn on iff positive." (interactive "P") (setq unicode-tokens-show-controls (if (null arg) (not unicode-tokens-show-controls) (> (prefix-numeric-value arg) 0))) (when unicode-tokens-show-controls (remove-from-invisibility-spec 'unicode-tokens-show-controls)) (when (not unicode-tokens-show-controls) (add-to-invisibility-spec 'unicode-tokens-show-controls)) (redraw-display)) (defun unicode-tokens-control-char (name s &rest props) `(,(format unicode-tokens-control-char-format-regexp (regexp-quote s)) (1 '(face nil invisible unicode-tokens-show-controls) prepend) ;; simpler but buggy with font-lock-prepend-text-property: ;; (2 ',(unicode-tokens-symbs-to-props props t) prepend) (2 (unicode-tokens-prepend-text-properties-in-match ',(unicode-tokens-symbs-to-props props t) 2) prepend) )) (defun unicode-tokens-control-region (name start end &rest props) `(,(format unicode-tokens-control-region-format-regexp (regexp-quote start) (regexp-quote end)) (1 '(face nil invisible unicode-tokens-show-controls) prepend) ;; simpler but buggy with font-lock-prepend-text-property: ;; (2 ',(unicode-tokens-symbs-to-props props t) prepend) (2 (unicode-tokens-prepend-text-properties-in-match ',(unicode-tokens-symbs-to-props props t) 2) prepend) (3 '(face nil invisible unicode-tokens-show-controls) prepend) )) (defun unicode-tokens-control-font-lock-keywords () (append (mapcar (lambda (args) (apply 'unicode-tokens-control-char args)) unicode-tokens-control-characters) (mapcar (lambda (args) (apply 'unicode-tokens-control-region args)) unicode-tokens-control-regions))) ;; ;; Shortcuts for typing, using quail ;; (defvar unicode-tokens-use-shortcuts t "Non-nil means use `unicode-tokens-shortcut-alist' if set.") (defun unicode-tokens-use-shortcuts (&optional arg) "Toggle variable `unicode-tokens-use-shortcuts'. With ARG, turn on iff positive." (interactive "P") (setq unicode-tokens-use-shortcuts (if (null arg) (not unicode-tokens-use-shortcuts) (> (prefix-numeric-value arg) 0))) (if unicode-tokens-use-shortcuts (set-input-method "Unicode tokens") (set-input-method nil))) (quail-define-package "Unicode tokens" "UTF-8" "u" t "Input method for tokens or unicode characters, application specific short-cuts" nil t nil nil nil nil nil ; max shortest, could try t nil nil nil t) (defun unicode-tokens-map-ordering (s1 s2) "Ordering on (car S1, car S2): order longer strings first." (>= (length (car s1)) (length (car s2)))) ; core dump caused when quail active, but not by quail. ;(defun unicode-tokens-shortcut-will-crash-emacs (ustring) ; "Work around a nasty Emacs bug that causes a core dump." ; (> 1 (length ustring))) (defun unicode-tokens-quail-define-rules () "Define the token and shortcut input rules. Calculated from `unicode-tokens-token-name-alist' and `unicode-tokens-shortcut-alist'." (let ((unicode-tokens-quail-define-rules (list 'quail-define-rules))) (let ((ulist (copy-list unicode-tokens-shortcut-alist)) ustring shortcut) (setq ulist (sort ulist 'unicode-tokens-map-ordering)) (while ulist (setq shortcut (caar ulist)) (setq ustring (cdar ulist)) (nconc unicode-tokens-quail-define-rules (list (list shortcut (vector ustring)))) (setq ulist (cdr ulist)))) (eval unicode-tokens-quail-define-rules))) ;; ;; User-level functions ;; (defun unicode-tokens-insert-token (tok) "Insert symbolic token named TOK, giving a message." (interactive (list (completing-read "Insert token: " unicode-tokens-hash-table))) (let ((ins (format unicode-tokens-token-format tok))) (insert ins) (message "Inserted %s" ins))) (defun unicode-tokens-annotate-region (name) "Annotate region with region markup tokens for scheme NAME. Available annotations chosen from `unicode-tokens-control-regions'." (interactive (let ((completion-ignore-case t)) (list (completing-read "Annotate region with: " unicode-tokens-control-regions nil 'requirematch)))) (assert (assoc name unicode-tokens-control-regions)) (let* ((entry (assoc name unicode-tokens-control-regions)) (beg (region-beginning)) (end (region-end)) (begtok (format unicode-tokens-control-region-format-start (nth 1 entry))) (endtok (format unicode-tokens-control-region-format-end (nth 2 entry)))) (when (> beg end) (setq beg end) (setq end (region-beginning))) (goto-char beg) (insert begtok) (goto-char (+ end (- (point) beg))) (insert endtok))) (defun unicode-tokens-insert-control (name) "Insert a control symbol sequence. NAME is from `unicode-tokens-control-characters'." (interactive (list (completing-read "Insert control symbol: " unicode-tokens-control-characters nil 'requirematch))) (assert (assoc name unicode-tokens-control-characters)) (insert (format unicode-tokens-control-char-format (cadr (assoc name unicode-tokens-control-characters))))) (defun unicode-tokens-insert-uchar-as-token (char) "Insert CHAR as a symbolic token, if possible." (let ((tok (gethash char unicode-tokens-uchar-hash-table))) (when tok (unicode-tokens-insert-token tok)))) (defun unicode-tokens-delete-token-near-point () "Delete the token near point; try first before point, then after." (interactive) (if (or (re-search-backward unicode-tokens-token-match-regexp (save-excursion (beginning-of-line) (point)) t) (re-search-forward unicode-tokens-token-match-regexp (save-excursion (end-of-line) (point)) t)) (kill-region (match-beginning 0) (match-end 0)))) (defun unicode-tokens-delete-backward-char (&optional arg) "Delete the last ARG visually presented characters. This accounts for tokens having a single character presentation but multiple characters in the underlying buffer." (interactive "p") (if arg (while (> arg 0) (unicode-tokens-delete-backward-1) (setq arg (1- arg))) (unicode-tokens-delete-backward-1))) (defun unicode-tokens-delete-char (&optional arg) "Delete the next ARG visually presented characters. This accounts for tokens having a single character presentation but multiple characters in the underlying buffer." (interactive "p") (if arg (while (> arg 0) (unicode-tokens-delete-1) (setq arg (1- arg))) (unicode-tokens-delete-1))) (defun unicode-tokens-delete-backward-1 () "Delete the last visually presented character. This accounts for tokens having a single character presentation but multiple characters in the underlying buffer." (let (tokst tokend) (save-match-data (save-excursion (setq tokst (re-search-backward unicode-tokens-token-match-regexp (save-excursion (beginning-of-line) (point)) t)) (setq tokend (match-end 0)))) ;(message "End is: %d and point is: %d" tokend (point)) (if (and tokst (= (point) tokend)) (delete-region tokst tokend) (delete-char -1)))) (defun unicode-tokens-delete-1 () "Delete the following visually presented character. This accounts for tokens having a single character presentation but multiple characters in the underlying buffer." (let (tokend) (save-match-data (save-excursion (if (looking-at unicode-tokens-token-match-regexp) (setq tokend (match-end 0))))) (if tokend (delete-region (point) tokend) (delete-char 1)))) ;; TODO: behaviour with unknown tokens not good. Should ;; use separate regexp for matching tokens known or not known. (defun unicode-tokens-prev-token () "Return the token before point, matching with `unicode-tokens-token-match-regexp'." (let ((match (re-search-backward unicode-tokens-token-match-regexp (save-excursion (beginning-of-line 0) (point)) t))) (if match (match-string 1)))) (defun unicode-tokens-rotate-token-forward (&optional n) "Rotate the token before point by N steps in the table." (interactive "p") (if (> (point) (point-min)) (save-match-data (let ((pos (point)) (token (unicode-tokens-prev-token))) (when (not token) (goto-char (point)) (error "Cannot find token before point")) (when token (let* ((tokennumber (search (list token) unicode-tokens-token-list :test 'equal)) (numtoks (hash-table-count unicode-tokens-hash-table)) (newtok (if tokennumber (nth (mod (+ tokennumber (or n 1)) numtoks) unicode-tokens-token-list)))) (when newtok (delete-region (match-beginning 0) (match-end 0)) (insert (format unicode-tokens-token-format newtok))) (when (not newtok) ;; FIXME: currently impossible case (message "Token not in tables: %s" token)))))))) (defun unicode-tokens-rotate-token-backward (&optional n) "Rotate the token before point, by -N steps in the token list." (interactive "p") (unicode-tokens-rotate-token-forward (if n (- n) -1))) (defun unicode-tokens-replace-shortcut-match (&rest ignore) "Subroutine for `unicode-tokens-replace-shortcuts'." (let* ((match (match-string-no-properties 0)) (repl (if match (cdr-safe (assoc match unicode-tokens-shortcut-replacement-alist))))) (if repl (regexp-quote repl)))) ;; handy for legacy Isabelle files, probably not useful in general. (defun unicode-tokens-replace-shortcuts () "Query-replace shortcuts in the buffer with compositions they expand to. Starts from point." (interactive) (let ((shortcut-regexp (regexp-opt (mapcar 'car unicode-tokens-shortcut-replacement-alist)))) ;; override the display of the regexp because it's huge! ;; (doesn't help with C-h: need way to programmatically show string) (cl-flet ((query-replace-descr (str) (if (eq str shortcut-regexp) "shortcut" str))) (perform-replace shortcut-regexp (cons 'unicode-tokens-replace-shortcut-match nil) t t nil)))) (defun unicode-tokens-replace-unicode-match (&rest ignore) "Subroutine for `unicode-tokens-replace-unicode'." (let* ((useq (match-string-no-properties 0)) (token (gethash useq unicode-tokens-uchar-hash-table))) (if token (regexp-quote (format unicode-tokens-token-format token))))) (defun unicode-tokens-replace-unicode () "Query-replace unicode sequences in the buffer with tokens having same appearance. Starts from point." (interactive) (let ((uchar-regexp unicode-tokens-uchar-regexp)) ;; override the display of the regexp because it's huge! ;; (doesn't help with C-h: need way to programmatically show string) (cl-flet ((query-replace-descr (str) (if (eq str uchar-regexp) "unicode presentation" str))) (perform-replace uchar-regexp (cons 'unicode-tokens-replace-unicode-match nil) t t nil)))) ;; ;; Token and shortcut tables ;; (defun unicode-tokens-copy-token (tokname) "Copy the token TOKNAME into the kill ring." (interactive "s") (kill-new (format unicode-tokens-token-format tokname) (eq last-command 'unicode-tokens-copy-token))) (define-button-type 'unicode-tokens-list 'help-echo "mouse-2, RET: copy this character" 'face nil 'action #'(lambda (button) (unicode-tokens-copy-token (button-get button 'unicode-token)))) (defun unicode-tokens-list-tokens () "Show a buffer of all tokens." (interactive) (with-output-to-temp-buffer "*Unicode Tokens List*" (with-current-buffer standard-output (make-local-variable 'unicode-tokens-show-symbols) (setq unicode-tokens-show-symbols nil) (unicode-tokens-mode) (setq tab-width 7) (insert "Hover to see token. Mouse-2 or RET to copy into kill ring.\n") (let ((count 10) (toks unicode-tokens-token-list) tok) ;; display in originally given order (while (or (/= 1 (mod count 10)) toks) (unless (null toks) (setq tok (car toks))) (if (/= 0 (mod count 10)) (insert "\t") (insert "\n") (unless (null toks) (insert (format "%4d. " (/ count 10)))) (if (= 0 (mod count 20)) (overlay-put (make-overlay (save-excursion (forward-line -1) (point)) (point)) 'face '(background-color . "gray90"))) (insert " ")) (incf count) (if (null toks) (insert " ") (insert-text-button (format unicode-tokens-token-format tok) :type 'unicode-tokens-list 'unicode-token tok) (setq toks (cdr toks)))))))) (defun unicode-tokens-list-shortcuts () "Show a buffer of all the shortcuts available." (interactive) (with-output-to-temp-buffer "*Unicode Tokens Shortcuts*" (with-current-buffer standard-output (make-local-variable 'unicode-tokens-show-symbols) (setq unicode-tokens-show-symbols nil) (unicode-tokens-mode) (let (grey start) (dolist (short unicode-tokens-shortcut-alist) (setq start (point)) (insert "Typing " (car short) "\tinserts \t" (cdr short) "\n") (if (setq grey (not grey)) (overlay-put (make-overlay start (point)) 'face '(background-color . "gray90")))))))) (defalias 'unicode-tokens-list-unicode-chars 'unicode-chars-list-chars) (defun unicode-tokens-encode-in-temp-buffer (str fn) "Call FN on encoded version of STR." (with-temp-buffer (insert str) (goto-char (point-min)) (while (re-search-forward unicode-tokens-token-match-regexp nil t) ;; TODO: interpret more exotic compositions here (let* ((tstart (match-beginning 0)) (tend (match-end 0)) (comp (car-safe (gethash (match-string 1) unicode-tokens-hash-table)))) (when comp (delete-region tstart tend) ;; TODO: improve this: interpret vector, strip tabs (insert comp)))) ;; gross approximation to compose-region (funcall fn (point-min) (point-max)))) (defun unicode-tokens-encode (beg end) "Return a unicode encoded version of the presentation in region BEG..END." (unicode-tokens-encode-in-temp-buffer (buffer-substring-no-properties beg end) 'buffer-substring)) ;;;###autoload (defun unicode-tokens-encode-str (str) "Return a unicode encoded version presentation of STR." (unicode-tokens-encode-in-temp-buffer str 'buffer-substring)) (defun unicode-tokens-copy (beg end) "Copy presentation of region between BEG and END. This is an approximation; it makes assumptions about the behaviour of symbol compositions, and will lose layout information." (interactive "r") ;; cf kill-ring-save, uncode-tokens-font-lock-compose-symbol (unicode-tokens-encode-in-temp-buffer (buffer-substring-no-properties beg end) 'copy-region-as-kill)) (defun unicode-tokens-paste () "Paste text from clipboard, converting Unicode to tokens where possible." (interactive) (let ((start (point)) end) ;; da: notice bug in Emacs 23 snapshot (at least) on Ubuntu 9.04 ;; that gives wrong default to x-select-enable-clipboard ;; need: (setq x-select-enable-clipboard t) (clipboard-yank) (setq end (point-marker)) (while (re-search-backward unicode-tokens-uchar-regexp start t) (let* ((useq (match-string 0)) (token (gethash useq unicode-tokens-uchar-hash-table)) (pos (point))) (when token (replace-match (format unicode-tokens-token-format token) t t) (goto-char pos)))) (goto-char end) (set-marker end nil))) (defvar unicode-tokens-highlight-unicode nil "Non-nil to highlight Unicode characters.") (defconst unicode-tokens-unicode-highlight-patterns '(("[^\000-\177]" (0 'unicode-tokens-highlight-face t))) "Font lock patterns for highlighting Unicode tokens.") (defun unicode-tokens-highlight-unicode () "Hilight Unicode characters in the buffer. Toggles highlighting of Unicode characters used in the buffer beyond the legacy 8-bit character set codes. This is useful to manually determine if a buffer contains Unicode or tokenised symbols." (interactive) (setq unicode-tokens-highlight-unicode (not unicode-tokens-highlight-unicode)) (unicode-tokens-highlight-unicode-setkeywords) (font-lock-fontify-buffer)) (defun unicode-tokens-highlight-unicode-setkeywords () "Adjust font lock keywords according to variable `unicode-tokens-highlight-unicode'." (if unicode-tokens-highlight-unicode (font-lock-add-keywords nil unicode-tokens-unicode-highlight-patterns) (font-lock-remove-keywords nil unicode-tokens-unicode-highlight-patterns))) ;; ;; Minor mode ;; (defun unicode-tokens-initialise () "Perform initialisation for Unicode Tokens minor mode. This function calculates `font-lock-keywords' and other configuration variables." (interactive) (unicode-tokens-copy-configuration-variables) (let ((flks (unicode-tokens-font-lock-keywords))) (put 'unicode-tokens-font-lock-keywords major-mode flks) (unicode-tokens-quail-define-rules) (unicode-tokens-define-menu) flks)) ;; not as expected ;; (defun unicode-tokens-restart () ;; (interactive) ;; (unicode-tokens-mode 0) ;; (put 'unicode-tokens-font-lock-keywords major-mode nil) ;; (setq font-lock-set-defaults nil) ;; (unicode-tokens-mode 1)) (defvar unicode-tokens-mode-map (make-sparse-keymap) "Key map used for Unicode Tokens mode.") (defvar unicode-tokens-display-table (let ((disptab (make-display-table))) (set-display-table-slot disptab 'selective-display (vector ?\ #x0022ef ?\ )) disptab) "Display table for Unicode Tokens mode. Alters ellipsis character.") (define-minor-mode unicode-tokens-mode "Toggle Tokens mode for current buffer. With optional argument ARG, turn Tokens mode on if ARG is positive, otherwise turn it off. In Unicode Tokens mode (Utoks appears in the modeline), a sequence of characters in the buffer (a token) may be presented instead as a Unicode character. The underlying buffer contents is not changed, only what is presented on the display. Other tokens may be used to control layout, for example, enabling sub/super scripts, bold and italic fonts, etc. Keyboard shortcut sequences for entering tokens quickly can be defined. Tokens mode needs configuration with a set of tokens, their presentation forms, and keyboard shortcuts. See documentation in `unicode-tokens.el' for more information. Commands available are: \\{unicode-tokens-mode-map}" :keymap unicode-tokens-mode-map :init-value nil :lighter " Utoks" :group 'unicode-tokens (let ((flks (get 'unicode-tokens-font-lock-keywords major-mode))) (when unicode-tokens-mode (unless flks (setq flks (unicode-tokens-initialise))) ;; make sure buffer can display 16 bit chars (if (and (fboundp 'set-buffer-multibyte) (not (buffer-base-buffer))) (set-buffer-multibyte t)) (make-local-variable 'font-lock-extra-managed-props) (when (not unicode-tokens-show-controls) (add-to-invisibility-spec 'unicode-tokens-show-controls)) (make-local-variable 'unicode-tokens-highlight-unicode) ;; a convention: ;; - set default for font-lock-extra-managed-props ;; as property on major mode symbol (ordinarily nil). (font-lock-add-keywords nil flks) (setq font-lock-extra-managed-props (get 'font-lock-extra-managed-props major-mode)) (mapc (lambda (p) (add-to-list 'font-lock-extra-managed-props p)) unicode-tokens-font-lock-extra-managed-props) (unicode-tokens-highlight-unicode-setkeywords) (font-lock-fontify-buffer) ;; experimental: this may be rude for non-nil standard tables (setq buffer-display-table unicode-tokens-display-table) (if unicode-tokens-use-shortcuts (set-input-method "Unicode tokens")) ;; adjust maths menu to insert tokens (set (make-local-variable 'maths-menu-filter-predicate) (lambda (uchar) (gethash (char-to-string uchar) unicode-tokens-uchar-hash-table))) (set (make-local-variable 'maths-menu-tokenise-insert) (lambda (uchar) (unicode-tokens-insert-token (gethash (char-to-string uchar) unicode-tokens-uchar-hash-table))))) (when (not unicode-tokens-mode) (remove-from-invisibility-spec 'unicode-tokens-show-controls) (when flks (font-lock-unfontify-buffer) (setq font-lock-extra-managed-props (get 'font-lock-extra-managed-props major-mode)) (setq font-lock-set-defaults nil) ; force font-lock-set-defaults to reinit (font-lock-fontify-buffer) (set-input-method nil)) ;; experimental: this may be rude for non-nil standard tables (setq buffer-display-table nil) ;; Remove hooks from maths menu (kill-local-variable 'maths-menu-filter-predicate) (kill-local-variable 'maths-menu-tokenise-insert)))) ;; ;; Font selection ;; (when (fboundp 'ns-respond-to-change-font) ;; A nasty hack to ns-win.el for Mac OS X support ;; Tricky because we get a callback on font changes, but not when ;; the window is closed. How do we know when user is finished? (when (not (fboundp 'old-ns-respond-to-change-font)) (fset 'old-ns-respond-to-change-font (symbol-function 'ns-respond-to-change-font))) (when (not (fboundp 'old-ns-popup-font-panel)) (fset 'old-ns-popup-font-panel (symbol-function 'ns-popup-font-panel))) (defvar unicode-tokens-respond-to-change-font nil) (defun ns-respond-to-change-font (&rest args) (interactive) (cond (unicode-tokens-respond-to-change-font (unicode-tokens-set-font-var-aux unicode-tokens-respond-to-change-font (with-no-warnings ns-input-font))) (t (apply 'old-ns-respond-to-change-font args)))) (defun ns-popup-font-panel (&rest args) (setq unicode-tokens-respond-to-change-font nil) (with-no-warnings (apply 'old-ns-popup-font-panel args))) (defun unicode-tokens-popup-font-panel (fontvar) (setq unicode-tokens-respond-to-change-font fontvar) (with-no-warnings (old-ns-popup-font-panel))) ) ;; parameterised version of function from menu-bar.el (Emacs 23.1) ;; this now copes with Emacs 23.1, Emacs 22, Mac OS X Emacs 23.1. (defun unicode-tokens-set-font-var (fontvar) "Interactively select a font for FONTVAR." (interactive) (let (font spec) (if (fboundp 'ns-popup-font-panel) (with-no-warnings (unicode-tokens-popup-font-panel fontvar)) (cond ((fboundp 'x-select-font) (setq font (x-select-font))) ((fboundp 'mouse-select-font) (setq font (mouse-select-font))) (t (setq font (unicode-tokens-mouse-set-font)))) (unicode-tokens-set-font-var-aux fontvar font)))) (defun unicode-tokens-set-font-var-aux (fontvar font) "A subroutine of `unicode-tokens-set-font-var'." (when font ;; Trac #311 - sometimes (on Linux/xft) :font doesn't work but ;; :family does. (condition-case nil (set-face-attribute fontvar (selected-frame) ;; da: don't try to reset these for token fonts. ;; :weight 'normal :slant 'normal :width 'normal :font font) (error (set-face-attribute fontvar (selected-frame) :width 'normal :family font))) (let ((font-object (face-attribute fontvar :font)) spec) (set-face-attribute fontvar t :font font-object) (setq spec (list (list t (face-attr-construct fontvar)))) (put fontvar 'customized-face spec) (custom-push-theme 'theme-face fontvar 'user 'set spec) (put fontvar 'face-modified nil)) ;; da: add this to make sure fonts set by font lock are altered (dolist (f (frame-list)) (and (display-graphic-p f) (dolist (w (window-list f)) (with-current-buffer (window-buffer w) (when font-lock-mode (font-lock-fontify-buffer)))))))) ;; based on mouse-set-font from mouse.el in Emacs 22.2.1 (defun unicode-tokens-mouse-set-font () "Select an Emacs font from a list of known good fonts and fontsets." (unless (display-multi-font-p) (error "Cannot change fonts on this display")) (car-safe ; just choose first ; (original cycles through trying set-default-font (x-popup-menu (if (listp last-nonmenu-event) last-nonmenu-event (list '(0 0) (selected-window))) ;; Append list of fontsets currently defined. (append x-fixed-font-alist (list (generate-fontset-menu)))))) (defsubst unicode-tokens-face-font-sym (fontsym) "Return the symbol unicode-tokens-FONTSYM-font-face." (intern (concat "unicode-tokens-" (symbol-name fontsym) "-font-face"))) (defun unicode-tokens-set-font-restart (fontsym) "Open a dialog to set the font for FONTSYM, and reinitialise." (let ((facevar (unicode-tokens-face-font-sym fontsym))) (unicode-tokens-set-font-var facevar) (unicode-tokens-initialise) (font-lock-fontify-buffer))) ;; ;; interface to custom ;; (defun unicode-tokens-save-fonts () "Save the customized font variables." ;; save all customized faces (tricky to do less) (interactive) (apply 'unicode-tokens-custom-save-faces (mapcar 'unicode-tokens-face-font-sym unicode-tokens-fonts))) (defun unicode-tokens-custom-save-faces (&rest faces) "Save custom faces FACES." (dolist (symbol faces) (let ((face (get symbol 'customized-face))) ;; See customize-save-customized; adjust properties so ;; that custom-save-all will save the face. (when face (put symbol 'saved-face face) (custom-push-theme 'theme-value symbol 'user 'set face) (put symbol 'customized-face nil)))) (custom-save-all)) ;; ;; Key bindings ;; (define-key unicode-tokens-mode-map [remap delete-backward-char] 'unicode-tokens-delete-backward-char) (define-key unicode-tokens-mode-map [remap delete-char] 'unicode-tokens-delete-char) ;; support delete selection mode (put 'unicode-tokens-delete-backward-char 'delete-selection 'supersede) (put 'unicode-tokens-delete-char 'delete-selection 'supersede) (defvar unicode-tokens-quail-translation-keymap (let ((quail-current-package (assoc "Unicode tokens" quail-package-alist))) (quail-translation-keymap))) ;; FIXME: does this work? (define-key unicode-tokens-quail-translation-keymap [remap quail-delete-last-char] 'unicode-tokens-quail-delete-last-char) (defun unicode-tokens-quail-delete-last-char () (interactive) (if unicode-tokens-mode (if (= (length quail-current-key) 1) (progn (quail-abort-translation) (unicode-tokens-delete-backward-char)) (quail-delete-last-char)) (quail-delete-last-char))) ; (setq quail-current-key (substring quail-current-key 0 -1)) ; (quail-delete-region) ; (quail-update-translation (quail-translate-key)))) (define-key unicode-tokens-mode-map [(control ?,)] 'unicode-tokens-rotate-token-backward) (define-key unicode-tokens-mode-map [(control ?.)] 'unicode-tokens-rotate-token-forward) (define-key unicode-tokens-mode-map [(control c) (control t) (control t)] 'unicode-tokens-insert-token) (define-key unicode-tokens-mode-map [(control c) (control backspace)] 'unicode-tokens-delete-token-near-point) (define-key unicode-tokens-mode-map [(control c) (control t) (control r)] 'unicode-tokens-annotate-region) (define-key unicode-tokens-mode-map [(control c) (control t) (control e)] 'unicode-tokens-insert-control) (define-key unicode-tokens-mode-map [(control c) (control t) (control z)] 'unicode-tokens-show-symbols) (define-key unicode-tokens-mode-map [(control c) (control t) (control t)] 'unicode-tokens-show-controls) ;; ;; Menu ;; (defun unicode-tokens-customize-submenu () (mapcar (lambda (cv) (vector (car cv) `(lambda () (interactive) (customize-variable (quote ,(cadr cv)))))) unicode-tokens-tokens-customizable-variables)) (defun unicode-tokens-define-menu () "Define Tokens menu." (easy-menu-define unicode-tokens-menu unicode-tokens-mode-map "Tokens menu" (cons "Tokens" (list ["Insert Token..." unicode-tokens-insert-token] ["Next Token" unicode-tokens-rotate-token-forward] ["Prev Token" unicode-tokens-rotate-token-backward] ["Delete Token" unicode-tokens-delete-token-near-point] (cons "Format Char" (mapcar (lambda (fmt) (vector (car fmt) `(lambda () (interactive) (funcall 'unicode-tokens-insert-control ',(car fmt))) :help (concat "Format next item as " (downcase (car fmt))))) unicode-tokens-control-characters)) (cons "Format Region" (mapcar (lambda (fmt) (vector (car fmt) `(lambda () (interactive) (funcall 'unicode-tokens-annotate-region ',(car fmt))) :help (concat "Format region as " (downcase (car fmt))) :active 'mark-active)) unicode-tokens-control-regions)) "---" ["List Tokens" unicode-tokens-list-tokens] ["List Shortcuts" unicode-tokens-list-shortcuts] ["List Unicode Characters" unicode-tokens-list-unicode-chars] "---" ["Copy As Unicode" unicode-tokens-copy :active 'mark-active :help "Copy presentation form of text from buffer, converting tokens to Unicode"] ["Paste From Unicode" unicode-tokens-paste :active (and kill-ring (not buffer-read-only)) :help "Paste from clipboard, converting Unicode to tokens where possible"] ["Replace Shortcuts" unicode-tokens-replace-shortcuts :help "Query-replace shortcut sequences with compositions they stand for, starting from point"] ["Replace Unicode" unicode-tokens-replace-unicode :help "Query-replace Unicode characters with tokens where possible, starting from point"] "---" ["Reveal Control Tokens" unicode-tokens-show-controls :style toggle :selected unicode-tokens-show-controls :active (or unicode-tokens-control-region-format-regexp unicode-tokens-control-char-format-regexp) :help "Prevent hiding of control tokens"] ["Reveal Symbol Tokens" unicode-tokens-show-symbols :style toggle :selected unicode-tokens-show-symbols :help "Show tokens for symbols"] ["Highlight Real Unicode Chars" unicode-tokens-highlight-unicode :style toggle :selected unicode-tokens-highlight-unicode :help "Hightlight non-8bit characters in buffer which are saved as Unicode"] ["Enable Shortcuts" unicode-tokens-use-shortcuts :style toggle :selected unicode-tokens-use-shortcuts :active unicode-tokens-shortcut-alist :help "Use short cuts for typing tokens"] ["Add Token Hovers" unicode-tokens-toggle-add-help-echo :style toggle :selected unicode-tokens-add-help-echo :help "Use hover popups (or minibuffer messages) to show underlying tokens"] "---" (cons "Customize" (unicode-tokens-customize-submenu)) (cons "Set Font" (append (mapcar (lambda (var) (vector (upcase-initials (symbol-name var)) `(lambda () (interactive) (funcall 'unicode-tokens-set-font-restart ',var)) :help (concat "Set the " (symbol-name var) " font"))) unicode-tokens-fonts) (list "----" ["Save Fonts" unicode-tokens-save-fonts :help "Save the customized font choices"] ["Make Fontsets" (lambda () (interactive) (require 'pg-fontsets)) :active (not (featurep 'pg-fontsets)) :help "Define fontsets (for Options->Set fontsets)" :visible (< emacs-major-version 23) ; not useful on 23, ;; at least when font menu provided. Drawback: this ;; is done too late: displayable tokens have already been ;; chosen now, before fontsets generated. ;; Never mind: non-issue with platform fonts menu. ]))))))) (provide 'unicode-tokens) ;;; unicode-tokens.el ends here proofgeneral-4.3~pre130510/obsolete/000077500000000000000000000000001214562307500172435ustar00rootroot00000000000000proofgeneral-4.3~pre130510/obsolete/demoisa/000077500000000000000000000000001214562307500206645ustar00rootroot00000000000000proofgeneral-4.3~pre130510/obsolete/demoisa/README000066400000000000000000000036471214562307500215560ustar00rootroot00000000000000Example Proof General instance for Isabelle Written by David Aspinall. Status: demonstration, only works for obsolete Isabelle versions ======================================== "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: README,v 12.0 2011/10/13 10:54:51 da Exp $ proofgeneral-4.3~pre130510/obsolete/demoisa/demoisa-easy.el000066400000000000000000000047441214562307500235770ustar00rootroot00000000000000;; demoisa-easy.el --- Example Proof General instance for Isabelle ;; ;; Copyright (C) 1999 LFCS Edinburgh. ;; ;; Author: David Aspinall ;; ;; $Id: demoisa-easy.el,v 12.0 2011/10/13 10:54:51 da Exp $ ;; ;; This is an alternative version of demoisa.el which uses the ;; proof-easy-config macro to do most of the work. ;; ;; This mechanism is 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 ;; using alternative architectures. It is still easy to augment ;; with additional elisp functions and other settings. ;; ;; The most important setting is `proof-shell-annotated-prompt-regexp' ;; used to recognize prompt texts from the prover. ;; ;; See demoisa.el and the Adapting Proof General manual for more ;; documentation. Please do read the documentation of the variables ;; to understand how things work. ;; ;; To test this file you must rename it demoisa.el. ;; (eval-and-compile (require 'proof-site) ; compilation for demoisa (proof-ready-for-assistant 'demoisa)) (require 'proof) (require 'proof-easy-config) ; easy configure mechanism (proof-easy-config 'demoisa "Isabelle Demo" proof-prog-name "isabelle" proof-terminal-string ";" proof-script-comment-start "(*" proof-script-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-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) ;;; demoisa-easy.el ends here proofgeneral-4.3~pre130510/obsolete/demoisa/demoisa.el000066400000000000000000000107241214562307500226330ustar00rootroot00000000000000;; demoisa.el Example Proof General instance for Isabelle ;; ;; Copyright (C) 1999 LFCS Edinburgh. ;; ;; Author: David Aspinall ;; ;; $Id: demoisa.el,v 12.0 2011/10/13 10:54:51 da Exp $ ;; ;; ================================================================= ;; ;; See README in this directory for an introduction. ;; ;; NEW INSTANCES: please use demoisa-easy.el as a basis instead. ;; ;; 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 (require 'pg-goals) (require 'pg-response) ;; ======== 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-string ";" proof-script-comment-start "(*" proof-script-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-prog-name isabelledemo-prog-name 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-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 derived modes set the variables, then call the ;; -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)) ;; 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. (provide 'demoisa) proofgeneral-4.3~pre130510/obsolete/lclam/000077500000000000000000000000001214562307500203335ustar00rootroot00000000000000proofgeneral-4.3~pre130510/obsolete/lclam/README000066400000000000000000000005341214562307500212150ustar00rootroot00000000000000Lambda-CLAM Proof General Written by James Brotherston . Status: supported Maintainer: James Brotherston Lambda-CLAM version: ?? Lambda-CLAM homepage: http://dream.dai.ed.ac.uk/software/systems/lambda-clam/ ======================================== $Id: README,v 12.0 2011/10/13 10:54:51 da Exp $ proofgeneral-4.3~pre130510/obsolete/lclam/example.lcm000066400000000000000000000015171214562307500224670ustar00rootroot00000000000000/* File name: example.lcm */ /* Description: Tutorial walkthrough from LClam manual */ /* Author: James Brotherston */ /* Last modified: 20th August 2001 */ query_top_goal X assp. set_spypoint (induction_top normal_ind). set_spypoint sym_eval. silent_output on. pds_plan (induction_top normal_ind) assp. continue. continue. continue. add_theory_to_induction_scheme_list arithmetic. add_theory_to_sym_eval_list arithmetic. set_wave_rule_to_sym_eval. add_to_sym_eval_list [idty]. set_wave_rule_to_sym_eval. remove_spypoint (induction_top normal_ind). remove_spypoint sym_eval. pds_plan (induction_top normal_ind) assp. step_by_step on. pds_plan (induction_top normal_ind) assp. continue. backtrack. try ind_strat. continue. plan_node (2::1::nil). abandon. proofgeneral-4.3~pre130510/obsolete/lclam/lclam.el000066400000000000000000000151061214562307500217500ustar00rootroot00000000000000;; File name: lclam.el ;; Description: Proof General instance for Lambda-CLAM ;; Author: James Brotherston ;; Last modified: 23 October 2001 ;; ;; $Id: lclam.el,v 12.0 2011/10/13 10:54:51 da Exp $ (require 'proof) ; load generic parts (require 'proof-syntax) ;; ;; =========== User settings for Lambda-CLAM ============ ;; (defcustom lclam-prog-name ; "~/lambda-clam-teyjus/bin/lclam" "lclam" "*Name of program to run Lambda-CLAM" :type 'file :group 'lclam) (defcustom lclam-web-page "http://dream.dai.ed.ac.uk/software/systems/lambda-clam/" "URL of web page for Lambda-CLAM" :type 'string :group 'lclam-config) ;; ;; =========== Configuration of generic modes ============ ;; (defun lclam-config () "Configure Proof General scripting for Lambda-CLAM." (setq proof-terminal-string "." proof-script-comment-start "/*" proof-script-comment-end "*/" proof-goal-command-regexp "^pds_plan" proof-save-command-regexp nil proof-goal-with-hole-regexp nil proof-save-with-hole-regexp nil proof-non-undoables-regexp nil proof-undo-n-times-cmd nil proof-showproof-command nil proof-goal-command "^pds_plan %s." proof-save-command nil proof-kill-goal-command nil proof-assistant-home-page lclam-web-page proof-auto-multiple-files nil )) (defun lclam-shell-config () "Configure Proof General shell for Lambda-CLAM" (setq proof-shell-annotated-prompt-regexp "^lclam:" proof-shell-cd-cmd nil proof-shell-interrupt-regexp nil proof-shell-error-regexp nil proof-shell-start-goals-regexp nil proof-shell-end-goals-regexp nil proof-shell-proof-completed-regexp "^Plan Succeeded" proof-shell-init-cmd nil proof-shell-quit-cmd "halt." proof-shell-eager-annotation-start nil )) ;; ;; =========== Defining the derived modes ================ ;; (define-derived-mode lclam-proofscript-mode proof-mode "Lambda-CLAM script" nil (lclam-config) (proof-config-done)) (define-derived-mode lclam-shell-mode proof-shell-mode "Lambda-CLAM shell" nil (lclam-shell-config) (proof-shell-config-done)) (define-derived-mode lclam-response-mode proof-response-mode "Lambda-CLAM response" nil (proof-response-config-done)) (define-derived-mode lclam-goals-mode proof-goals-mode "Lambda-CLAM goals" nil (proof-goals-config-done)) ;; Automatic selection of theory file or proof script mode ;; .lcm -> proof script mode ;; .def -> theory file mode (defun lclam-mode () (interactive) (cond ((proof-string-match "\\.def$" (buffer-file-name)) (thy-mode)) (t (lclam-proofscript-mode))) ) ;; Hook which configures settings to get the proof shell running (add-hook 'proof-pre-shell-start-hook 'lclam-pre-shell-start) (defun lclam-pre-shell-start () (setq proof-prog-name lclam-prog-name) (setq proof-mode-for-shell 'lclam-shell-mode) (setq proof-mode-for-response 'lclam-response-mode) (setq proof-mode-for-goals 'lclam-goals-mode) (setq proof-shell-process-connection-type t)) ;; ;; ============ Extra bits and pieces - JB ============ ;; ;; Open .def files in theory mode from now on (setq auto-mode-alist (cons '("\\.def$" . thy-mode) auto-mode-alist)) ;; Remove redundant toolbar buttons (eval-after-load "pg-custom" '(progn (setq lclam-toolbar-entries (remassoc 'state lclam-toolbar-entries)) (setq lclam-toolbar-entries (remassoc 'context lclam-toolbar-entries)) (setq lclam-toolbar-entries (remassoc 'undo lclam-toolbar-entries)) (setq lclam-toolbar-entries (remassoc 'retract lclam-toolbar-entries)) (setq lclam-toolbar-entries (remassoc 'qed lclam-toolbar-entries)))) ;; ;; ============ Theory file mode ============== ;; (define-derived-mode thy-mode fundamental-mode "Lambda-CLAM theory file mode" (thy-add-menus)) (defvar thy-mode-map nil) (defun thy-add-menus () "Add Lambda-CLAM menu to current menu bar." (require 'proof-script) (require 'proof-x-symbol) (easy-menu-define thy-mode-pg-menu thy-mode-map "PG Menu for Lambda-CLAM 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]) (list proof-buffer-menu) (list proof-help-menu)))) (easy-menu-define thy-mode-lclam-menu thy-mode-map "Menu for Lambda-CLAM 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] ; da: commented out this, function is incomplete ; ["Include definitions" match-and-assert-defs ; :active (proof-locked-region-empty-p)] ["Process theory" process-thy-file :active (proof-locked-region-empty-p)] ; da: commented out this, there's no retract function provided ; ["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-lclam-menu thy-mode-map) ) (defun process-thy-file (file) "Process the theory file FILE. If interactive, use buffer-file-name." (interactive (list buffer-file-name)) (save-some-buffers) (update-thy-only file nil nil)) (defun update-thy-only (file try wait) "Process the theory file FILE." ;; 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 "use_thy \"%s%%r\"." (if try "try_" "")) (file-name-nondirectory file)) wait)) ;(defun match-and-assert-defs ; "Interactively process and assert definitions in theory file" ;) (provide 'lclam) proofgeneral-4.3~pre130510/obsolete/plastic/000077500000000000000000000000001214562307500207025ustar00rootroot00000000000000proofgeneral-4.3~pre130510/obsolete/plastic/README000066400000000000000000000004271214562307500215650ustar00rootroot00000000000000Plastic Proof General Written by Paul Callaghan Status: under development together with Plastic Maintainer: Paul Callaghan Plastic homepage: http://www.dur.ac.uk/CARG/plastic.html ======================================== $Id: README,v 12.0 2011/10/13 10:54:51 da Exp $ proofgeneral-4.3~pre130510/obsolete/plastic/plastic-syntax.el000066400000000000000000000106261214562307500242140ustar00rootroot00000000000000;; plastic-syntax.el - Syntax of Plastic ;; Author: Paul Callaghan ;; Maintainer: ;; plastic-syntax.el,v 6.0 2001/09/03 12:11:56 da Exp ;; 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 ;; ;; 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" "Return" "ReturnAll" "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 "\\\\|\\ ;; ;; $Id: plastic.el,v 12.1 2012/08/30 14:30:23 monnier Exp $ ;; NOTES: ;; remember to prefix all potential cmds with plastic-lit-string ;; alternative is to fix the filtering (require 'proof) (eval-when-compile (require 'cl) (require 'span) (require 'proof-syntax) (require 'outline) (defvar plastic-keymap nil)) (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) (eval-and-compile (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-handle-output (lambda (cmd string) (when (proof-string-match "^Module" cmd) ;; prevent output and just give a minibuffer message (setq proof-shell-last-output-kind 'systemspecific) (message "Imports 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-cd (concat plastic-lit-string " &S ECHO no cd ;\n") "*Command of the inferior process to change the directory.") (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 script" "Major mode for Plastic proof scripts. \\{plastic-mode-map}" (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 (tl (length proof-terminal-string))) (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 (string-equal (substring string i (+ i tl)) proof-terminal-string) (incf ct)) (setq i (+ 1 i))))) (setq span (next-span span 'type))) (list (concat plastic-lit-string " &S Undo x" (int-to-string ct) proof-terminal-string)))) (defun plastic-goal-command-p (span) "Decide whether argument is a goal or not" ;; NEED CHG. (proof-string-match plastic-goal-command-regexp (or (span-property span 'cmd) ""))) (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 ;; FIXME da: should probably ignore comments/proverproc here? (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)) ; da: put this instead of XEmacs code (message "Can't Undo imports yet! You must exit Plastic for this!") ; (popup-dialog-box ; (list (concat "Can't Undo imports yet\n" ; "You have to exit Plastic for this\n") ; ["ok, I'll do this" (lambda () t) t])) (return) ) ;; warn the user that undo of imports not yet working. (t (incf spans)) ) (setq span (next-span span 'type)) ) (list (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 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (eval-after-load "plastic" ;; da: so that plastic-lit-string can be changed '(progn (eval `(proof-defshortcut plastic-Intros ,(concat plastic-lit-string "Intros ") [(control i)])) (eval `(proof-defshortcut plastic-Refine ,(concat plastic-lit-string "Refine ") [(control r)])) (eval `(proof-defshortcut plastic-ReturnAll ,(concat plastic-lit-string "ReturnAll ") [(control u)])))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 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 (proof-shell-live-buffer) (proof-with-current-buffer-if-exists 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 t)))) (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))) ))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Configuring proof mode and setting up various utilities ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun plastic-mode-config () (setq proof-terminal-string ";") (setq proof-script-comment-start "(*") ;; these still active (setq proof-script-comment-end "*)") (setq proof-prog-name (concat plastic-prog-name "")) (setenv "PROOF_GENERAL" "") ;; signal to plastic, use annotations (setq proof-assistant-home-page plastic-www-home-page) (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 pg-topterm-goalhyplit-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 (set proof-script-font-lock-keywords plastic-font-lock-keywords-1) (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))) (set (make-local-variable 'blink-matching-paren-dont-ignore-comments) t) ;; hooks and callbacks (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 (regexp-quote 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 () "Function to update `proof-included-files list'. Value for `proof-shell-compute-new-files-list', which see. For Plastic, we assume that module identifiers coincide with file names." (let ((module (match-string 1))) (cdr (member-if (lambda (filename) (plastic-equal-module-filename module filename)) proof-included-files-list)))) (defun plastic-shell-mode-config () (setq proof-shell-cd-cmd plastic-shell-cd 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-start-goals-regexp plastic-goal-regexp pg-subterm-first-special-char ?\360 pg-subterm-start-char ?\372 pg-subterm-sep-char ?\373 pg-subterm-end-char ?\374 pg-topterm-regexp "\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 pg-subterm-anns-use-stack nil proof-shell-handle-output-system-specific plastic-shell-handle-output plastic-shell-current-line-width nil proof-shell-process-file (cons "Creating mark \"\\(.*\\)\" \\[\\(.*\\)\\]" (lambda () (let ((match (match-string 2))) (if (equal match "") match (concat (file-name-sans-extension match) ".lf"))))) proof-shell-retract-files-regexp "forgot back through Mark \"\\(.*\\)\"" ;; DEAD: proof-shell-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 pg-goals-change-goal "Next %s;" pg-goals-error-regexp plastic-error-regexp) (setq proof-goals-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 () ;; NB: dynamic scoping of string "clear comments and remove literate marks (ie, \\n> ) - acts on var string" (with-no-warnings ;; 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. (x (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-regexp-in-string " +" " " string)) (setq string (replace-regexp-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." (interactive (list (read-string "Command: " nil 'proof-minibuffer-history))) (print "hello") (plastic-reset-error) (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)) (define-key plastic-keymap [(control s)] 'plastic-small-bar) (define-key plastic-keymap [(control l)] 'plastic-large-bar) (define-key plastic-keymap [(control c)] 'plastic-all-ctxt) (define-key plastic-keymap [(control v)] 'plastic-minibuf) (define-key plastic-keymap [(control o)] 'plastic-synchro) (define-key plastic-keymap [(control p)] 'plastic-show-shell) ;; original end. ;;;;;;;;;;;;;;;;; ;; hacky overriding of the toolbar command and C-c C-v action ;; my version handles literate characters. ;; (should do better for long-term though) (defalias 'proof-toolbar-command 'plastic-minibuf) (defalias 'proof-minibuffer-cmd 'plastic-minibuf) ;; the latter doesn't seem to work (pcc, 05aug02) ;;; (provide 'plastic) proofgeneral-4.3~pre130510/obsolete/plastic/test.lf000066400000000000000000000022421214562307500222040ustar00rootroot00000000000000EXAMPLE 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; proofgeneral-4.3~pre130510/pghaskell/000077500000000000000000000000001214562307500174015ustar00rootroot00000000000000proofgeneral-4.3~pre130510/pghaskell/pghashell.el000066400000000000000000000026341214562307500216770ustar00rootroot00000000000000;; pgocaml.el - Proof General for Haskell scripts. ;; ;; David Aspinall. $Id: pghashell.el,v 1.1 2012/02/07 11:19:42 da Exp $ ;; ;; This instance of PG is handy just for using script management to ;; cut-and-paste into a buffer running Haskell (ghci) ;; ;; I'm providing this so that tool demonstrators may use it instead of ;; tediously doing cut-and-paste of commands from a file. No history ;; management, and nothing to do with theorem proving really! ;; ;; To use this instance of PG, visit a file with the ".pghci" extension ;; or type ;; ;; M-x pgocaml-mode ;; ;; in an ordinary .ml file. (Check that you have enabled the instance ;; in proof-site.el). ;; (require 'proof-easy-config) (require 'proof-syntax) (proof-easy-config 'pgocaml "PG-OCaml" proof-prog-name "ocaml" proof-terminal-string ";;" proof-script-comment-start "(*" proof-script-comment-end "*)" proof-shell-annotated-prompt-regexp "^# " ;; matches interpreter prompts ;; Syntax table suitable for OCaml; see Elisp documentation of `modify-syntax-entry' proof-script-syntax-table-entries '(?\` "\"" ?\$ "." ?\/ "." ?\\ "." ?+ "." ?- "." ?= "." ?% "." ?< "." ?> "." ?\& "." ?. "w" ?_ "w" ?\' "w" ?\| "." ?\* ". 23n" ?\( "()1" ?\) ")(4") ;; next setting is just to prevent warning proof-save-command-regexp proof-no-regexp ) (provide 'pgocaml) proofgeneral-4.3~pre130510/pghaskell/pghaskell.el000066400000000000000000000026761214562307500217100ustar00rootroot00000000000000;; pgocaml.el - Proof General for Haskell scripts. ;; ;; David Aspinall. $Id: pghaskell.el,v 1.2 2012/08/09 11:43:02 da Exp $ ;; ;; This instance of PG is handy just for using script management to ;; cut-and-paste into a buffer running Haskell (ghci) ;; ;; I'm providing this so that tool demonstrators may use it instead of ;; tediously doing cut-and-paste of commands from a file. No history ;; management, and nothing to do with theorem proving really! ;; ;; To use this instance of PG, visit a file with the ".pghci" extension ;; or type ;; ;; M-x pghaskell-mode ;; ;; in an ordinary .h file. (Check that you have enabled the instance ;; in proof-site.el). ;; (require 'proof-easy-config) (require 'proof-syntax) (proof-easy-config 'pghaskell "PG-Haskell" proof-prog-name "ghci" ;; BELOW HERE TO COMPLETE proof-terminal-string ";;" proof-script-comment-start "(*" proof-script-comment-end "*)" proof-shell-annotated-prompt-regexp "^# " ;; matches interpreter prompts ;; Syntax table suitable for OCaml; see Elisp documentation of `modify-syntax-entry' proof-script-syntax-table-entries '(?\` "\"" ?\$ "." ?\/ "." ?\\ "." ?+ "." ?- "." ?= "." ?% "." ?< "." ?> "." ?\& "." ?. "w" ?_ "w" ?\' "w" ?\| "." ?\* ". 23n" ?\( "()1" ?\) ")(4") ;; next setting is just to prevent warning proof-save-command-regexp proof-no-regexp ) (provide 'pghaskell) proofgeneral-4.3~pre130510/pgocaml/000077500000000000000000000000001214562307500170515ustar00rootroot00000000000000proofgeneral-4.3~pre130510/pgocaml/pgocaml.el000066400000000000000000000026161214562307500210220ustar00rootroot00000000000000;; pgocaml.el - Proof General for OCaml scripts. ;; ;; David Aspinall. $Id: pgocaml.el,v 1.1 2012/02/07 11:19:42 da Exp $ ;; ;; This instance of PG is handy just for using script management to ;; cut-and-paste into a buffer running OCaml ;; ;; I'm providing this so that tool demonstrators may use it instead of ;; tediously doing cut-and-paste of commands from a file. No history ;; management, and nothing to do with theorem proving really! ;; ;; To use this instance of PG, visit a file with the ".pgml" extension ;; or type ;; ;; M-x pgocaml-mode ;; ;; in an ordinary .ml file. (Check that you have enabled the instance ;; in proof-site.el). ;; (require 'proof-easy-config) (require 'proof-syntax) (proof-easy-config 'pgocaml "PG-OCaml" proof-prog-name "ocaml" proof-terminal-string ";;" proof-script-comment-start "(*" proof-script-comment-end "*)" proof-shell-annotated-prompt-regexp "^# " ;; matches interpreter prompts ;; Syntax table suitable for OCaml; see Elisp documentation of `modify-syntax-entry' proof-script-syntax-table-entries '(?\` "\"" ?\$ "." ?\/ "." ?\\ "." ?+ "." ?- "." ?= "." ?% "." ?< "." ?> "." ?\& "." ?. "w" ?_ "w" ?\' "w" ?\| "." ?\* ". 23n" ?\( "()1" ?\) ")(4") ;; next setting is just to prevent warning proof-save-command-regexp proof-no-regexp ) (provide 'pgocaml) proofgeneral-4.3~pre130510/pgshell/000077500000000000000000000000001214562307500170655ustar00rootroot00000000000000proofgeneral-4.3~pre130510/pgshell/README000066400000000000000000000013211214562307500177420ustar00rootroot00000000000000Proof General for shell scripts/simple command interpreters. Author: David Aspinall Status: Supported; experimental ==================================================================== This instance of PG is handy just for using script management to cut-and-paste into a buffer running an ordinary shell of some kind. I'm providing this so that tool demonstrators may use it instead of tediously doing cut-and-paste of commands from a file. No history management, and nothing to do with theorem proving really! To use this instance of PG, visit a file with the ".pgsh" extension. You can modify the settings in pgshell.el to suit your application (e.g. run some program other than the shell). Feedback welcome. proofgeneral-4.3~pre130510/pgshell/example.pgsh000066400000000000000000000012741214562307500214070ustar00rootroot00000000000000# This is an example shell script for processing # with the script management of Proof General. # # It demonstrates the usefulness of PG simply for # sending a pre-defined sequence of commands to # some command-line interpreter, here /bin/sh. # # To adjust this for your needs, edit pgshell.el # (or copy and rename it). # # $Id: example.pgsh,v 12.0 2011/10/13 10:54:51 da Exp $ # # What time is it? date; # What machine am I on? uname -a; # What files are here? ls -lt; # Notes: # # * Commands have to be terminated by ';'. Alternative is to write # your own scanner to recognize the start of the next command. # # * Undo has no effect, of course, it just navigates in the file. # proofgeneral-4.3~pre130510/pgshell/pgshell.el000066400000000000000000000023631214562307500210510ustar00rootroot00000000000000;; pgshell.el - Proof General for shell scripts. ;; ;; David Aspinall. $Id: pgshell.el,v 12.0 2011/10/13 10:54:51 da Exp $ ;; ;; This instance of PG is handy just for using script management to ;; cut-and-paste into a buffer running an ordinary shell of some kind. ;; ;; I'm providing this so that tool demonstrators may use it instead of ;; tediously doing cut-and-paste of commands from a file. No history ;; management, and nothing to do with theorem proving really! ;; ;; To use this instance of PG, visit a file with the ".pgsh" extension. ;; ;; Feedback welcome. (require 'proof-easy-config) (require 'proof-syntax) (proof-easy-config 'pgshell "PG-Shell" proof-prog-name "/bin/sh" ;; or your program proof-terminal-string ";" ;; end of commands proof-script-comment-start "\#" ;; comments proof-shell-annotated-prompt-regexp "^.*[$] $" ;; matches prompts proof-script-fly-past-comments t ;; nice for single-line ;; Syntax table gets font-locking and editing features for comments. ;; see Elisp documentation of `modify-syntax-entry' proof-script-syntax-table-entries '(?\# "<" ?\n ">") ;; next setting is just to prevent warning proof-save-command-regexp proof-no-regexp ) (provide 'pgshell) proofgeneral-4.3~pre130510/phox/000077500000000000000000000000001214562307500164055ustar00rootroot00000000000000proofgeneral-4.3~pre130510/phox/.cvsignore000066400000000000000000000001201214562307500203760ustar00rootroot00000000000000config config.dos *~ #*# *.o *.a *.cmo *.cmi *.cmx *.pho *.phi *.pht *.math.tex proofgeneral-4.3~pre130510/phox/README000066400000000000000000000007651214562307500172750ustar00rootroot00000000000000PhoX Proof General, for Phox. Written by Christophe Raffalli and others Status: supported Maintainer: Christophe Raffalli PhoX version: 0.8 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: README,v 12.0 2011/10/13 10:54:51 da Exp $ proofgeneral-4.3~pre130510/phox/README.pbrpm000066400000000000000000000011641214562307500204060ustar00rootroot00000000000000**** Projet PhoX : Proof By Rules Popup Menu (PBRPM) ***** ----- Fichiers concernés : ProofGeneral/generic/pg-goals.el ProofGeneral/generic/pg-pbrpm.el ProofGeneral/phox/phox.el ProofGeneral/phox/phox-pbrpm.el - Dans pg-goals.el - (l. 58-59) inclusion de pg-pbrpm.el déclaration du 'CTRL + Click Droit' associé à pg-pbrpm-button-action (dans pg-pbrpm.el) - Dans pg-pbrpm.el - Fonctions indépendantes de PhoX implémentant le PBRPM. - Dans phox.el - (l. 86) inclus phox-pbrpm.el (l. 103-104) ajoute le menu de gestion du buffer de selections dans le menu de PhoX - Dans phox-pbrpm.el - Fonctions spécifiques à PhoX.proofgeneral-4.3~pre130510/phox/example.phx000066400000000000000000000004631214562307500205640ustar00rootroot00000000000000(* Example proof script for PhoX Proof General $Id: example.phx,v 12.0 2011/10/13 10:54:51 da Exp $ *) (* 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. proofgeneral-4.3~pre130510/phox/phox-extraction.el000066400000000000000000000126631214562307500220730ustar00rootroot00000000000000;; $State: Exp $ $Date: 2011/10/13 10:54:51 $ $Revision: 12.0 $ ;;--------------------------------------------------------------------------;; ;;--------------------------------------------------------------------------;; ;; program extraction. ;; ;; note : program extraction is still experimental This file is very ;; dependant of the actual state of program extraction in phox. ;;--------------------------------------------------------------------------;; (require 'cl) (eval-when (compile) (defvar phox-prog-name nil)) (declare-function proof-shell-invisible-command "proof-shell" (str)) ;; 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) proofgeneral-4.3~pre130510/phox/phox-font.el000066400000000000000000000066631214562307500206640ustar00rootroot00000000000000(defvar phox-sym-lock-enabled nil) ; da: for clean compile (defvar phox-sym-lock-color nil) ; da: for clean compile (defvar phox-sym-lock-keywords nil) ; da: for clean compile (declare-function phox-sym-lock "phox-sym-lock") ;;--------------------------------------------------------------------------;; ;;--------------------------------------------------------------------------;; ;; 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\\|e\\(lim\\|quation\\)\\|rewrite\\)\\|" "a\\(dd_path\\|uthor\\)\\|" "c\\(l\\(aim\\|ose_def\\)\\|or\\(ollary\\)?\\)\\|" "d\\(e\\(f\\(\\(_thlist\\|rec\\)\\)?\\|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\\|ype\\)" "\\)[ \t\n\r.]") '(0 'font-lock-keyword-face t)) ;proof command (cons (concat "\\([ \t]\\|^\\)\\(" "a\\(bort\\|fter\\|nd\\|pply\\|ssume\\|xiom\\)\\|" "by\\(_absurd\\)?\\|" "constraints\\|" "elim\\|" "deduce\\|" "evaluate\\(_hyp\\)?\\|" "from\\|" "goals\\|" "in\\(tros?\\|stance\\)\\|" "l\\(oc\\(al\\|k\\)\\|e\\(t\\|fts?\\)\\)\\|" "next\\|" "of\\|" "prove\\|" "r\\(e\\(write\\(_hyp\\)?\\|name\\)\\|mh\\)\\|" "s\\(elect\\|how\\|lh\\)\\|" "t\\(hen\\|rivial\\)\\|" "u\\(se\\|n\\(do\\|fold\\(_hyp\\)?\\|lock\\)\\)\\|" "with" "\\)[ \t.]") '(0 'font-lock-type-face t)))) ;;--------------------------------------------------------------------------;; ;;--------------------------------------------------------------------------;; ;; phox-sym-lock tables ;;--------------------------------------------------------------------------;; (if (featurep '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) ("\\" 0 3 218) ("\\" 0 3 206) ("\\" 0 4 207) ("\\" 0 3 199) ("\\" 0 3 200) ("\\" 0 3 45) ("&" 0 1 217) ("<->" 0 1 171) ("=>" 0 1 222) ("\\" 0 4 204) ("->" 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-enabled) (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) proofgeneral-4.3~pre130510/phox/phox-fun.el000066400000000000000000000305371214562307500205030ustar00rootroot00000000000000;; $State: Exp $ $Date: 2011/10/13 10:54:51 $ $Revision: 12.0 $ ;; syntax (require 'span) (require 'proof-syntax) (require 'proof-script) (eval-when-compile (require 'proof-utils)) (defconst phox-forget-id-command "del %s.\n") (defconst phox-forget-proof-command "del_proof %s.\n") (defconst phox-forget-new-elim-command "edel elim %s.\n") (defconst phox-forget-new-intro-command "edel intro %s.\n") (defconst phox-forget-new-equation-command "edel equation %s.\n") (defconst phox-forget-close-def-command "edel closed %s.\n") ; phox-comments-regexp : a sequence of comments and white spaces (defconst phox-comments-regexp "[ \n\t\r]*\\((\\*\\([^*]\\|\\(\\*[^)]\\)\\)*\\*)[ \n\t\r]*\\)*") ; phox-strict-comments-regexp : a not empty sequence of comments and white spaces (defconst phox-strict-comments-regexp "\\([ \n\t\r]+\\((\\*\\([^*]\\|\\(\\*[^)]\\)\\)*\\*)[ \n\t\r]*\\)*\\|\\((\\*\\([^*]\\|\\(\\*[^)]\\)\\)*\\*)[ \n\t\r]*\\)+\\)") (defconst phox-ident-regexp "\\(\\([^() \n\t\r=\\[.]\\|\\(\\.[^() \n\t\r]\\)\\)+\\)") (defconst phox-inductive-option "\\(\\[[^]]*]\\)?") (defconst phox-spaces-regexp "[ \n\t\r]*") (defconst phox-sy-definition-regexp (concat "\\(Cst\\|\\(def\\(rec\\)?\\)\\)" phox-comments-regexp "\\(\\(rInfix\\|lInfix\\|Infix\\|Prefix\\|Postfix\\)[^\"]+\"\\([^\"]+\\)\\)")) (defconst phox-sy-inductive-regexp (concat "Inductive" phox-comments-regexp phox-inductive-option phox-comments-regexp "\\(\\(rInfix\\|lInfix\\|Infix\\|Prefix\\|Postfix\\)[^\"]+\"\\([^\"]+\\)\\)")) (defconst phox-inductive-regexp (concat "Inductive" phox-comments-regexp phox-inductive-option phox-comments-regexp phox-ident-regexp)) (defconst phox-data-regexp (concat "\\(Data\\|type\\)" phox-comments-regexp phox-inductive-option phox-comments-regexp phox-ident-regexp)) (defconst phox-definition-regexp (concat "\\(Cst\\|def\\(_thlist\\|rec\\)?\\|claim\\|Sort\\)" phox-comments-regexp phox-ident-regexp)) (defconst phox-prove-claim-regexp (concat "prove_claim" phox-comments-regexp phox-ident-regexp)) (defconst phox-new-elim-regexp (concat "new_elim\\([^.]\\|\\(\\.[^ \n\t\r]\\)\\)*[ \n\t\r)]" phox-ident-regexp)) (defconst phox-new-intro-regexp (concat "new_intro\\([^.]\\|\\(\\.[^ \n\t\r]\\)\\)*[ \n\t\r)]" phox-ident-regexp)) (defconst phox-new-rewrite-regexp (concat "new_rewrite\\([^.]\\|\\(\\.[^ \n\t\r]\\)\\)*[ \n\t\r)]" phox-ident-regexp)) (defconst phox-new-equation-regexp (concat "new_equation\\([^.]\\|\\(\\.[^ \n\t\r]\\)\\)*[ \n\t\r)]" phox-ident-regexp)) (defconst 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_equation" "new_rewrite" "Data" "type" "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) name sname) ;; da: added name,sname. are tmp/lsp not used? (while span (setq str (span-property span 'cmd)) (cond ((eq (span-property span 'type) 'comment)) ((eq (span-property span 'type) 'proverproc)) ((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) ; deprecated (setq ans (concat (format phox-forget-new-equation-command (match-string 3 str)) ans))) ((proof-string-match phox-new-equation-regexp str) (setq ans (concat (format phox-forget-new-equation-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))) (when ans (list ans)))) ; was (or ans proof-no-command) ;; ;; Doing commands ;; (defalias 'phox-assert-next-command-interactive 'proof-assert-next-command-interactive) ;; da: might be able to achieve commented out effect with proof-electric-terminator-noterminator ;; "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 ;; (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 : equation (the list of equations added to unification introduced by the new_equation 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) proofgeneral-4.3~pre130510/phox/phox-lang.el000066400000000000000000000034271214562307500206320ustar00rootroot00000000000000;; $State: Exp $ $Date: 2012/04/06 07:05:41 $ $Revision: 12.1 $ ;;--------------------------------------------------------------------------;; ;;--------------------------------------------------------------------------;; ;; messages in various languages (provide 'phox-lang) (require 'cl) ; for case (defvar phox-lang (let* ((s (or (getenv "LC_ALL") (getenv "LANG") (getenv "LANGUAGE"))) (loc (and s (> (length s) 1) (substring s 0 2)))) (cond ((or (string= loc "en") (string= loc "us")) 'en) ((string= loc "fr") 'fr) (t 'en)))) (defun phox-lang-absurd () (case phox-lang (en "By absurd") (fr "Par l'absurde"))) (defun phox-lang-suppress (s) (case phox-lang (en (concat "Remove hypothesis " s " (if it became useless)")) (fr (concat "Supprimer l'hypothèse " s " (si elle est devenue inutile)")))) (defun phox-lang-opendef () (case phox-lang (en "Expand the definition: ") (fr "Ouvre la définition : "))) (defun phox-lang-instance (s) (case phox-lang (en (concat "Choose " s " = ")) (fr (concat "Choisissons " s " = ")))) (defun phox-lang-open-instance (s) (case phox-lang (en (concat "Choose " s " = \\[ \\]")) (fr (concat "Choisissons " s " = \\[ \\]")))) (defun phox-lang-lock (s) (case phox-lang (en (concat "Lock variable " s)) (fr (concat "Vérouille la variable " s)))) (defun phox-lang-unlock (s) (case phox-lang (en (concat "Unlock variable " s)) (fr (concat "Dévérouille la variable " s)))) (defun phox-lang-prove (s) (case phox-lang (en (concat "Let us prove \\[" s "\\]")) (fr (concat "Prouvons \\[" s "\\]")))) (defun phox-lang-let (s) (case phox-lang (en (concat "Let \\[ \\] = \\[" s "\\]")) (fr (concat "Définissons \\[ \\] = \\[" s "\\]")))) proofgeneral-4.3~pre130510/phox/phox-outline.el000066400000000000000000000046221214562307500213660ustar00rootroot00000000000000;;--------------------------------------------------------------------------;; ;;--------------------------------------------------------------------------;; ;; PARAMÉTRAGE du MODE outline ;;--------------------------------------------------------------------------;; (require 'outline) (declare-function phox-lang-absurd "nofile") (declare-function phox-lang-suppress "nofile") (declare-function phox-lang-instance "nofile") (declare-function phox-lang-open-instance "nofile") (declare-function phox-lang-opendef "nofile") (declare-function phox-lang-unlock "nofile") (declare-function phox-lang-lock "nofile") (declare-function phox-lang-prove "nofile") (declare-function phox-lang-let "nofile") (defconst phox-outline-title-regexp "\\((\\*[ \t\n]*title =\\)") (defconst phox-outline-section-regexp "\\((\\*\\*+\\)") (defconst phox-outline-save-regexp "\\((\\*#\\)") (defconst phox-outline-theo-regexp "\\((\\*lem\\)\\|\\((\\*prop\\)\\|\\((\\*fact\\)\\|\\((\\*theo\\)\\|\\((\\*def\\)\\|\\((\\*cst\\)") (defconst phox-outline-theo2-regexp "\\(lem\\)\\|\\(prop\\)\\|\\(fact\\)\\|\\(theo\\)\\|\\(def\\)\\|\\(cst\\)\\|\\(claim\\)\\|\\(new_\\)") (defconst phox-outline-regexp (concat phox-outline-title-regexp "\\|" phox-outline-section-regexp "\\|" phox-outline-save-regexp "\\|" phox-outline-theo-regexp "\\|" phox-outline-theo2-regexp)) (defconst 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) proofgeneral-4.3~pre130510/phox/phox-pbrpm.el000066400000000000000000000267321214562307500210350ustar00rootroot00000000000000;; $State: Exp $ $Date: 2011/10/13 10:54:51 $ $Revision: 12.0 $ ;;--------------------------------------------------------------------------;; ;;--------------------------------------------------------------------------;; ;; the proof by rules popup menu part ;; ;; Note : program extraction is still experimental This file is very ;; dependant of the actual state of our developments ;;--------------------------------------------------------------------------;; (require 'pg-pbrpm) (declare-function phox-lang-absurd "nofile") (declare-function phox-lang-suppress "nofile") (declare-function phox-lang-instance "nofile") (declare-function phox-lang-open-instance "nofile") (declare-function phox-lang-opendef "nofile") (declare-function phox-lang-unlock "nofile") (declare-function phox-lang-lock "nofile") (declare-function phox-lang-prove "nofile") (declare-function phox-lang-let "nofile") (declare-function int-char "nofile") (declare-function char= "nofile") ;;--------------------------------------------------------------------------;; ;; Syntactic functions ;;--------------------------------------------------------------------------;; (setq pg-pbrpm-start-goal-regexp "^goal \\([0-9]+\\)/[0-9]+\\( (new)\\)?$" pg-pbrpm-start-goal-regexp-par-num 1 pg-pbrpm-end-goal-regexp "^$" pg-pbrpm-start-hyp-regexp "^\\([A-Za-z0-9_.']+\\) := " pg-pbrpm-start-hyp-regexp-par-num 1 pg-pbrpm-start-concl-regexp "^ *|- " pg-pbrpm-auto-select-regexp "\\(\\(\\(['a-zA-Z0-9]+\\)\\|\\([][><=/~&+*^%!{}:-]+\\)\\)\\(_+\\(\\(['a-zA-Z0-9]+\\)\\|\\([][><=/~&+*^%!{}:-]+\\)\\)\\)*\\)\\|\\(\\?[0-9]+\\)" ) ; TODO : deal with future invisible parentheses (french guillemots) (defun phox-pbrpm-left-paren-p (char) "Retrun t if the character is a left parenthesis : '(' or a french guillemot '<<'" (or (char-equal char (int-char 40)) (char-equal char (int-char 171))) ) (defun phox-pbrpm-right-paren-p (char) "Retrun t if the character is a right parenthesis ')' or a french guillemot '>>'" (or (char-equal char (int-char 41)) (char-equal char (int-char 187))) ) (defun phox-pbrpm-menu-from-string (order str) "build a menu from a string send by phox" (setq str (proof-shell-invisible-cmd-get-result str)) (if (string= str "") nil (mapcar (lambda (s) (append (list order) (split-string s "\\\\-") (list 'phox-pbrpm-rename-in-cmd))) (split-string str "\\\\\\\\")))) (defun phox-pbrpm-rename-in-cmd (cmd spans) (let ((modified nil) (prev 0)) (mapc (lambda (span) (if (not (string= (span-property span 'original-text) (span-string span))) (setq modified (cons span modified)))) spans) (setq modified (reverse modified)) (if modified (progn (if (= 0 (span-property (car modified) 'goalnum)) (progn (while (and modified (= 0 (span-property (car modified) 'goalnum))) (let ((span (pop modified))) (setq cmd (concat cmd ";; rename " (span-property span 'original-text) " " (span-string span))))) (if modified (setq cmd (concat "(" cmd ")"))))) (if modified (setq cmd (concat cmd ";; "))) (while modified (let* ((span (pop modified)) (goalnum (span-property span 'goalnum))) (while (< (+ prev 1) goalnum) (setq cmd (concat cmd "idt @+@ ")) (setq prev (+ prev 1))) (setq cmd (concat cmd "(rename " (span-property span 'original-text) " " (span-string span))) (setq prev goalnum) (if (or (not modified) (< goalnum (span-property (car modified) 'goalnum))) (setq cmd (concat cmd ") @+@ ")) (setq cmd (concat cmd ";; "))))) (if (> prev 0) (setq cmd (concat cmd "idt")))))) cmd) (defun phox-pbrpm-get-region-name (region-info) (if (= (nth 0 region-info) 1) (nth 1 region-info) (nth 2 region-info))) (defun phox-pbrpm-escape-string (str) "add escape char '\'" (concat "\"" (replace-regexp-in-string "\\\\" "\\\\\\\\" str) "\"")) (defun phox-pbrpm-generate-menu (click-infos region-infos) "Use informations to build a list of (name , rule)" ;click-infos = (goal-number, "whole"/hyp-name/"none", expression, depth-tree-list) ;region-infos = idem if in the goal buffer, (0, "none", expression, nil ) if in another buffer, do not display if no region available. (let ((pbrpm-rules-list nil) (goal-prefix (if (= (nth 0 click-infos) 1) "" (concat "[" (int-to-string (nth 0 click-infos)) "] ")))) ; the first goal is the selected one by default, so we prefer not to display it. ; if clicking in a conclusion with no selection (if (and (string= (nth 1 click-infos) "none") (not region-infos)) (setq pbrpm-rules-list (append pbrpm-rules-list (list (list 4 (phox-lang-absurd) (concat goal-prefix "by_absurd;; elim False"))) (phox-pbrpm-menu-from-string 0 (concat "menu_intro " (int-to-string (nth 0 click-infos)))) (phox-pbrpm-menu-from-string 0 (concat "menu_evaluate " (int-to-string (nth 0 click-infos)))) ); end append );end setq );end if ; if clicking a conclusion with a selection (if (and (string= (nth 1 click-infos) "none") region-infos) (setq pbrpm-rules-list (append pbrpm-rules-list (phox-pbrpm-menu-from-string 0 (concat "menu_intro " (int-to-string (nth 0 click-infos)) (let ((tmp "")) (mapc (lambda (region-info) (setq tmp (concat tmp " " (phox-pbrpm-escape-string (nth 2 region-info))))) region-infos) tmp))) (phox-pbrpm-menu-from-string 1 (concat "menu_rewrite " (int-to-string (nth 0 click-infos)) " " (let ((tmp "")) (mapc (lambda (region-info) (setq tmp (concat tmp " " (phox-pbrpm-escape-string (phox-pbrpm-get-region-name region-info))))) region-infos) tmp)))))) ; if clicking in an hypothesis with no selection (if (and (not (or (string= (nth 1 click-infos) "none") (string= (nth 1 click-infos) "whole"))) (or (string= "" (nth 2 click-infos)) (not (char= (string-to-char (nth 2 click-infos)) ??))) (not region-infos)) (let ((r (proof-shell-invisible-cmd-get-result (concat "is_hypothesis " (int-to-string (nth 0 click-infos)) " " (phox-pbrpm-escape-string (nth 1 click-infos)))))) (setq pbrpm-rules-list (append pbrpm-rules-list (if (char= (string-to-char r) ?t) (list (list 9 (phox-lang-suppress (nth 1 click-infos)) (concat "[" (int-to-string (nth 0 click-infos)) "] " "rmh " (nth 1 click-infos)))) nil) (phox-pbrpm-menu-from-string 1 (concat "menu_elim " (int-to-string (nth 0 click-infos)) " " (nth 1 click-infos))) (phox-pbrpm-menu-from-string 1 (concat "menu_evaluate_hyp " (int-to-string (nth 0 click-infos)) " " (nth 1 click-infos))) (phox-pbrpm-menu-from-string 0 (concat "menu_left " (int-to-string (nth 0 click-infos)) " " (nth 1 click-infos))))))) ; if clicking on an hypothesis with a selection (if (and (not (or (string= (nth 1 click-infos) "none") (string= (nth 1 click-infos) "whole"))) region-infos) (setq pbrpm-rules-list (append pbrpm-rules-list (phox-pbrpm-menu-from-string 1 (concat "menu_apply " (int-to-string (nth 0 click-infos)) " " (nth 1 click-infos) (let ((tmp "")) (mapc (lambda (region-info) (setq tmp (concat tmp " " (phox-pbrpm-escape-string (nth 2 region-info))))) region-infos) tmp))) (phox-pbrpm-menu-from-string 1 (concat "menu_rewrite_hyp " (int-to-string (nth 0 click-infos)) " " (nth 1 click-infos) (let ((tmp "")) (mapc (lambda (region-info) (setq tmp (concat tmp " " (phox-pbrpm-escape-string (phox-pbrpm-get-region-name region-info))))) region-infos) tmp)))))) (if (and (not (string= "" (nth 2 click-infos))) (char= (string-to-char (nth 2 click-infos)) ??) region-infos (not (cdr region-infos))) (setq pbrpm-rules-list (append pbrpm-rules-list (list (list 0 (concat (phox-lang-instance (nth 2 click-infos)) (nth 2 (car region-infos))) (concat "instance " (nth 2 click-infos) " " (nth 2 (car region-infos)))))))) (if (and (not (string= "" (nth 2 click-infos))) (char= (string-to-char (nth 2 click-infos)) ??) (not region-infos)) (setq pbrpm-rules-list (append pbrpm-rules-list (list (list 0 (concat (phox-lang-open-instance (nth 2 click-infos))) (concat "instance " (nth 2 click-infos) " ") (lambda (cmd spans) (let ((span (pop spans))) (concat cmd " " (span-string span))))))))) ; is clicking on a token with no selection (if (and (not region-infos) (not (string= (nth 2 click-infos) ""))) (let ((r (proof-shell-invisible-cmd-get-result (concat "is_definition " (int-to-string (nth 0 click-infos)) " " (phox-pbrpm-escape-string (nth 2 click-infos))))) (ri (proof-shell-invisible-cmd-get-result (concat "is_definition " (int-to-string (nth 0 click-infos)) " " (phox-pbrpm-escape-string (concat "$" (nth 2 click-infos))))))) (if (or (char= (string-to-char r) ?t) (char= (string-to-char ri) ?t)) (setq pbrpm-rules-list (append pbrpm-rules-list (list (list 1 (concat (phox-lang-opendef) (nth 2 click-infos)) (concat goal-prefix (if (or (string= (nth 1 click-infos) "none") (string= (nth 1 click-infos) "whole")) "unfold -ortho " (concat "unfold_hyp " (nth 1 click-infos) " -ortho ")) "$" (nth 2 click-infos)))))) (if (and (not (string= "" (nth 2 click-infos))) (char= (string-to-char (nth 2 click-infos)) ??)) (let ((r (proof-shell-invisible-cmd-get-result (concat "is_locked " (nth 2 click-infos))))) (if (char= (string-to-char r) ?t) (setq pbrpm-rules-list (append pbrpm-rules-list (list (list 0 (phox-lang-unlock (nth 2 click-infos)) (concat goal-prefix "unlock " (nth 2 click-infos)))))) (setq pbrpm-rules-list (append pbrpm-rules-list (list (list 0 (phox-lang-lock (nth 2 click-infos)) (concat goal-prefix "lock " (nth 2 click-infos)))))))))))) (let ((arg (if (and region-infos (not (cdr region-infos))) (nth 2 (car region-infos)) " "))) (setq pbrpm-rules-list (append pbrpm-rules-list (list (list 10 "Trivial ?" (concat goal-prefix "trivial")) (list 10 (phox-lang-prove arg) (concat goal-prefix "prove") (lambda (cmd spans) (let ((span (pop spans))) (concat cmd " " (span-string span))))) (list 10 (phox-lang-let arg) (concat goal-prefix "local") (lambda (cmd spans) (let ((span1 (pop spans)) (span2 (pop spans))) (concat cmd " " (span-string span1) " = "(span-string span2))))))))) pbrpm-rules-list )) ;;--------------------------------------------------------------------------;; ;; phox specific functions ;;--------------------------------------------------------------------------;; (defalias 'proof-pbrpm-generate-menu 'phox-pbrpm-generate-menu) (defalias 'proof-pbrpm-left-paren-p 'phox-pbrpm-left-paren-p) (defalias 'proof-pbrpm-right-paren-p 'phox-pbrpm-right-paren-p) ;;--------------------------------------------------------------------------;; (require 'phox-lang) (provide 'phox-pbrpm) ;; phox-pbrpm ends here proofgeneral-4.3~pre130510/phox/phox-sym-lock.el000066400000000000000000000360541214562307500214510ustar00rootroot00000000000000;; 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. (require 'proof-compat) ; avoid compile warnings (defcustom phox-sym-lock-enabled t "*Whether to use yum symbol or not." :type 'boolean :group 'phox) ;; DA: I have crudely hacked this file so that it compiles cleanly. ;; It won't work now, but I hope we can use Unicode Tokens instead. (declare-function map-extents "nofile") (declare-function extent-face "nofile") (declare-function face-property "nofile") (declare-function set-extent-endpoints "nofile") (declare-function extent-start-position "nofile") (declare-function extent-end-position "nofile") (declare-function set-extent-property "nofile") (declare-function face-font-name "nofile") (declare-function font-name "nofile") (declare-function char-int "nofile") (declare-function obj "nofile") (declare-function set-face-property "nofile") (declare-function add-menu-button "nofile") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; History ;; ;; first prototype by wg 5-96 ;; tweaked by Steve Dunham 5-96 ;; rewritten and enhanced by Albert Cohen 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) (if (featurep 'xemacs) (require 'atomic-extents)) ;; not available on GNU Emacs (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 (and (fboundp 'list-fonts) ; da: what is this function? not defined (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) ; DA: DISABLED THIS top level form (PG 4.0) ;; (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 ;; ;; DA PG 3.7: above line doesn't work on XEmacs 21.5b28, gives ;; ;; Character set already defined for this DIMENSION/CHARS/FINAL/DIRECTION combo (indian-is13194) ;; ;; DA: Will 55 work? ;; 'final 55 ;; '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 ;; ;; DA: removed next line, it breaks "make magic" in doc ;; ;; '(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)))) (with-no-warnings ;; da: dynamic scope obj (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"))) (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"))) (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 () ;; da: XEmacs isms ;; (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) (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) (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) ;; da: font-lock has changed: ;; (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) proofgeneral-4.3~pre130510/phox/phox-tags.el000066400000000000000000000054451214562307500206510ustar00rootroot00000000000000;; $State: Exp $ $Date: 2011/10/13 10:54:51 $ $Revision: 12.0 $ ;;--------------------------------------------------------------------------;; ;;--------------------------------------------------------------------------;; ;; 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) (eval-when-compile (defvar phox-doc-dir nil) (defvar phox-lib-dir nil) (defvar phox-etags nil)) (defun phox-tags-add-table(table) "add tags table" (interactive "D directory, location of a file named TAGS to add : ") (if (not (boundp 'tags-table-list)) (setq tags-table-list nil)) (if (member table tags-table-list) (message "%s already loaded." table) ;; (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) (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." (interactive) (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" ) (provide 'phox-tags) proofgeneral-4.3~pre130510/phox/phox.el000066400000000000000000000156021214562307500177110ustar00rootroot00000000000000;; $State: Exp $ $Date: 2011/10/13 10:54:51 $ $Revision: 12.0 $ (require 'proof) ; load generic parts ;; Adjust toolbar entries. (Must be done before proof-toolbar is ;; loaded). (eval-after-load "pg-custom" '(setq phox-toolbar-entries (assq-delete-all '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-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) (require 'phox-pbrpm) ;; default for tags [da: moved here to fix compilation 15/02/03] (if phox-tags-doc (add-hook 'phox-mode-hook 'phox-tags-add-doc-table)) ;; ----- PhoX specific menu (defpgdefault menu-entries (cons phox-state-menu (cons phox-tags-menu (cons phox-extraction-menu nil))) ) ;; ;; ======== Configuration of generic modes ======== ;; (defun phox-config () "Configure Proof General scripting for PhoX." (if phox-sym-lock-enabled (phox-sym-lock-start)) (setq proof-prog-name phox-prog-name proof-prog-name-guess t proof-prog-name-ask nil proof-terminal-string "." ; ends every command proof-script-command-end-regexp "[.]\\([ \t\n\r]\\)" proof-script-comment-start "(*" proof-script-comment-end "*)" proof-goal-command-regexp "\\`\\(Local[ \t\n\r]+\\)?\\(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 "\\`\\(Local[ \t\n\r]+\\)?\\(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 16 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\\|menu_\\|is_\\)" 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) (setq pbp-goal-command "intro %s;") (setq pbp-hyp-command "elim %s;")) (defun phox-shell-config () "Configure Proof General shell for PhoX." (setq ;proof-shell-cd-cmd "cd \"%s\"" proof-shell-annotated-prompt-regexp "\\(>phox> \\)\\|\\(%phox% \\)" proof-shell-interrupt-regexp "Interrupt" proof-shell-start-goals-regexp "^\\(Here \\(are\\|is\\) the goal\\)\\|\\([0-9]+ new goals?\\)\\|\\([0-9]+ goals? possibly instanced\\)" proof-shell-end-goals-regexp "^End of goals." proof-shell-quit-cmd "quit." proof-shell-restart-cmd "restart." proof-shell-proof-completed-regexp "^.*^proved" )) ;; ;; ======== Defining the derived modes ======== ;; ;; The name of the script mode is always -script, ;; but the others can be whatever you like. ;; ;; The derived modes set the variables, then call the ;; -config-done function to complete configuration. (define-derived-mode phox-mode proof-mode "PhoX script" "Major mode for PhoX proofs. \\{phox-mode-map}" (phox-config) (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 proof-response-font-lock-keywords phox-font-lock-keywords) (phox-sym-lock-start) (if (and (featurep 'phox-sym-lock) phox-sym-lock-enabled) (add-hook 'proof-shell-handle-delayed-output-hook 'phox-sym-lock-font-lock-hook) ) (proof-response-config-done)) (define-derived-mode phox-goals-mode proof-goals-mode "PhoX goals" nil (setq font-lock-keywords phox-font-lock-keywords) (phox-sym-lock-start) (if (and (featurep 'phox-sym-lock) phox-sym-lock-enabled) (add-hook 'pg-before-fontify-output-hook 'phox-sym-lock-font-lock-hook) ) (proof-goals-config-done)) ;; 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. ; 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) proofgeneral-4.3~pre130510/phox/square-root-2.phx000066400000000000000000000170121214562307500215470ustar00rootroot00000000000000tex title = "Proof that square root of 2 is not rational" author = "Christophe Raffalli, Paul Rozière" institute = "LAMA, Universit\\'e de Savoie, PPS, Universit\\'e Paris VII" documents = math . Import nat. flag auto_lvl 1. (* Cette preuve est à peu près celle envoyée à F. Wiedijk -- Nijmegen -- The Fifteen Provers of the World -- http://www.cs.kun.nl/~freek/comparison/index.html Voir une preuve plus simple : sqrt2.phx *) (*! math \section{The library:} The theorem used \underline{explicitely} from the library are \begin{itemize} \item \verb#demorganl# a set of rewrite rules for Demorgan's law. \item \verb#calcul.N# a set of rewrite rules for natural numbers. \item \verb#well_founded.N#: \[ $$well_founded.N \]. \item \verb#odd_or_even.N#: \[ $$odd_or_even.N \]. \item \verb#lesseq.case1.N#: \[ $$lesseq.case1.N \]. \item \verb#neq.less_or_sup.N#: \[ $$neq.less_or_sup.N \]. \item \verb#not.lesseq.imply.less.N#: \[ $$not.lesseq.imply.less.N \]. \item \verb#lesseq.imply.not.greater.N#: \[ $$lesseq.imply.not.greater.N \]. \end{itemize} Comments: The first four are natural to use explicitely. The last two could probably be removed by adding some \verb#new_intro# or \verb#new_elim# in the library. \verb#lesseq.case1.N# and \verb#neq.less_or_sup.N# are more problematic, they would require to extend the system with some kind of binary elimination rule (with two principal premices ?). \section{Some basic lemmas.} They should be included in the library ? *) theorem minimal.element /\X (\/n:N X n -> \/n:N (X n & /\p:N (X p -> n <= p))). (*! math \begin{lemma}\label{minimal.element} Every non empty subset \[ X \] of \[ N \] admits a minimal element: $$ \[ $0 \] $$ \end{lemma} *) intro 2. by_absurd. rewrite_hyp H0 demorganl. (*! math \begin{proof} We assume \[ $$H \] and \[ $$H0 \] ( \[ H0 \] ). *) use /\n:N ~ X n. (*! math We get a contradiction from \[ $$G \] which is proven by well founded induction: *) trivial. intros. elim well_founded.N with H1. intros. (*! math we assume \[ $$H3 \] and must prove \[ $0 \]. *) intro. apply H0 with H4. lefts G $& $\/. (*! math Assuming \[ $$H4 \] and using ( \[ H0 \] ) we get an integer \[ x \] such that \[ $$H6 \] and \[ $$H7 \]. This gives a contradiction with \[ $$H3 \]. \end{proof} *) elim H3 with H5. elim not.lesseq.imply.less.N. save. theorem not_odd_and_even.N /\x,y,z:N (~ (x = N2 * y & x = N1 + N2 * z)). (*! math \begin{lemma}\label{not_odd_and_even.N} An integer can not be odd and even: $$ \[ $0 \] $$ \end{lemma} \begin{proof} By induction over \[ x \]. \end{proof} *) intro 2. elim H. trivial 6. intros. intro. left H4. elim H2 with [case]. trivial =H0 H4 H6. elim H1. axiom H3. axiom H6. intro. rmh H4. left H5. rmh H5. rewrite_hyp H4 H7 calcul.N. left H4. axiom H4. save. theorem sum_square.N /\x,y:N (x + y)^N2 = x^N2 + N2*x*y + y^N2. (*! math \begin{lemma}\label{sum_square.N} $$ \[ $0 \] $$ \end{lemma} \begin{proof} Easy. \end{proof} *) intros. rewrite calcul.N mul.left.distributive.N mul.right.distributive.N add.associative.N. intro. save. fact less.exp.N /\n,x,y:N( x <= y -> x^n <= y^n). (*! math \begin{lemma}\label{less.exp.N} $$ \[ $0 \] $$ \end{lemma} \begin{proof} By induction on \[ n \]. \end{proof} *) intros. elim H. trivial. rewrite calcul.N. trivial. save. fact less_r.exp.N /\n,x,y:N( x^n < y^n -> x < y). (*! math \begin{lemma}\label{less_r.exp.N} $$ \[ $0 \] $$ \end{lemma} \begin{proof} Follows from lemma \ref{less.exp.N}. \end{proof} *) intros. elim lesseq.case1.N with y and x. apply less.exp.N with n and H3. elim lesseq.imply.not.greater.N with y^n and x^n ;; Try intros. save. fact less.ladd.N /\x,y:N (N0 < y -> x < x + y). (*! math \begin{lemma}\label{less.ladd.N} $$ \[ $0 \] $$ \end{lemma} \begin{proof} Easy induction over \[ x \]. \end{proof} *) intros. elim H. rewrite calcul.N. trivial. save. (*! math \section{The proof itself} *) theorem n.square.pair /\n:N (\/p:N n^N2=N2*p -> \/q:N n=N2*q). (*! math \begin{lemma}\label{n.square.pair} If the square of \[ n \] is even then \[ n \] is even: $$ \[ $0 \] $$ \end{lemma} \begin{proof} *) intros. lefts H0 $\/ $&. apply odd_or_even.N with H. lefts G $\/ $& $or. (*! math We assume \[ $$H1 \] ( \[ H1 \] ). We distinguish two cases. If \[ n \] is even we get what we want. *) trivial. (*! math If \[ n \] is odd we have \[ $$H3 \] *) prove n^N2 = N2*(N2*y^N2+N2*y) + N1. (*! math which implies \[ $0 \] *) rewrite H3 sum_square.N. rewrite add.associative.N mul.associative.N mul.left.distributive.N. from N1 + N4 * y + (N2 * y) ^ N2 = N1 + N4 * y + N4 * y ^ N2. intro. (*! math and this gives a contradiction by lemma \ref{not_odd_and_even.N} using ( \[ H1 \] ) \end{proof} *) elim not_odd_and_even.N with N (n^N2). intros. select 3. intro. axiom H1. axiom G. axiom H0. intros. save. lem decrease /\m,n : N (m^ N2 = N2 * n^ N2 -> N0 < n -> n < m). (*! math \begin{lemma}\label{decrease} $$ \[ $0 \] $$ \end{lemma} \begin{proof} Using lemma \ref{less_r.exp.N} and lemma \ref{less.ladd.N} \end{proof} *) intros. elim less_r.exp.N with N2 ;; Try intros. prove m^N2 = n^N2 + n^N2. axiom H1. elim less.ladd.N ;; Try intros. trivial. trivial. trivial =H0 H2. save. lem sup_zero /\m,n : N (m^ N2 = N2 * n^ N2 -> N0 < m -> N0 < n). (*! math \begin{lemma}\label{sup_zero} $$ \[ $0 \] $$ \end{lemma} \begin{proof} Using lemma \[ $$ neq.less_or_sup.N \] from the library. \end{proof} *) intros. elim neq.less_or_sup.N with N0 and n ;; Try intros. rewrite_hyp H1 H3 calcul.N. trivial. trivial. save. def Q m = m > N0 & \/n:N (m^ N2 = N2 * n^ N2). (*! math \begin{definition} We define \[ Q m = $$Q m \]. \end{definition} *) lem dec /\m:N (Q m -> \/m':N (Q m' & m' < m)). (*! math \begin{lemma}\label{dec} $$ \[ $0 \] $$ \end{lemma} \begin{proof} *) intros. lefts H0 $Q $\/ $&. (*! math We assume that \[ $$H0 \] and \[ $$H2 \] (\[ H2 \]) and we must prove \[ $0 \]. *) apply sup_zero with H2 and H0. (*! math By lemma \ref{sup_zero} we get \[ $$G \]. We show that \[ n \] is the integer we are looking for. *) intro. instance ?1 n. intros. intros. trivial. (*! math We just need to prove \[ $0 \] and \[1 $0 \]. *) prove \/p:N (m ^ N2 = N2 * p). intro. instance ?2 n^N2. trivial. apply n.square.pair with G0. lefts G1 $& $\/. (*! math Using lemma \ref{n.square.pair} we get \[ q \] such that \[ $$H4 \] *) prove n ^N2 = N2 * q ^N2. rewrite_hyp H2 H4. prove N2 * (N2 * q ^N2) = N2 * n ^ N2. from H2. left G1. intro. (*! math and then \[ $$G1 \]. *) trivial =H3 G1. (*! math Finally \[ $0 \] follows from lemma \ref{decrease}. \end{proof} *) elim decrease. save. lem sq2_irrat /\m:N ~Q m. (*! math \begin{lemma}\label{sq2_irrat} $$ \[ $0 \] $$ \end{lemma} \begin{proof} Follows from the previous lemma by selecting the minimal element in \[ Q \] (using lemme \ref{minimal.element}) and getting a contradiction. \end{proof} *) intros. intro. elim minimal.element with Q. intros $\/ $&. axiom H. axiom H0. lefts H1. elim dec with H2. lefts H4. apply H3 with H5. elim lesseq.imply.not.greater.N with n and m'. save. theorem square2_irrat /\m,n : N (m^ N2 = N2 * n^ N2 -> m = N0 & n = N0). (*! math \begin{theorem} The square-root of 2 is irrational. For this we just need to prove the following: $$ \[ $0 \] $$ \end{theorem} \begin{proof} *) intros. apply sq2_irrat with H. (*! math We assume \[ $$H1 \]. By the previous lemma we have \[ $$G \]. *) elim H with [case]. intro. intro. (*! math If \[ $$H2 \] we easely get \[ $0 \]. *) elim H0 with [case]. intro. rewrite_hyp H1 H2 H4 calcul.N. left H1;; intros. prove Q m. (*! math If \[ m > N0 \] then we have \[ Q m \] and a contradiction. \end{proof} *) intros $Q $\/ $&. trivial. select 2. axiom H1. trivial. elim G. save. proofgeneral-4.3~pre130510/twelf/000077500000000000000000000000001214562307500165505ustar00rootroot00000000000000proofgeneral-4.3~pre130510/twelf/README000066400000000000000000000015151214562307500174320ustar00rootroot00000000000000Twelf 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: README,v 12.0 2011/10/13 10:54:51 da Exp $ proofgeneral-4.3~pre130510/twelf/example.elf000066400000000000000000000027661214562307500207060ustar00rootroot00000000000000%%% %%% Example script for Twelf Proof General. %%% %%% $Id: example.elf,v 12.0 2011/10/13 10:54:51 da Exp $ %%% %%% 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. proofgeneral-4.3~pre130510/twelf/twelf-font.el000066400000000000000000000400101214562307500211520ustar00rootroot00000000000000;; 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 ;; ;; $Id: twelf-font.el,v 12.0 2011/10/13 10:54:51 da Exp $ ;; ;; (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. ("\\(\\<<-\\>\\|\\<->\\>\\|\\\\|\\<=\\>\\|\\<_\\>\\)" ;; for LLF, no punctuation marks ;;"\\(\\<<-\\>\\|\\<->\\>\\|\\\\|\\<-o\\>\\|\\<\\>\\|\\<&\\>\\|\\^\\|()\\|\\\\|\\\\)" ;; for LLF, with punctuation marks ;;"\\([][:.(){},]\\|\\<<-\\>\\|\\<->\\>\\|\\\\|\\<-o\\>\\|\\<\\>\\|\\<&\\>\\|\\^\\|()\\|\\\\|\\\\)" ;; for Elf, no punction marks ;;"\\(\\<<-\\>\\|\\<->\\>\\|\\\\|\\\\)" ;; for Elf, including punctuation marks ;;"\\([][:.(){}]\\|\\<<-\\>\\|\\<->\\>\\|\\\\|\\\\)" . 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) proofgeneral-4.3~pre130510/twelf/twelf-old.el000066400000000000000000003137411214562307500210000ustar00rootroot00000000000000;; twelf-old.el Port of old Twelf Emacs mode ;; ;; Author: Frank Pfenning ;; Adapted for Proof General by David Aspinall ;; ;; $Id: twelf-old.el,v 12.0 2011/10/13 10:54:51 da Exp $ ;; ;; ;; 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 'easymenu) ;;;---------------------------------------------------------------------- ;;; 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} \\ 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-number 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 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-number (looked-at-string input 1)))) ;;((string-match "^set\\s +trace\\s +\\([0-9]\\)+" input) ;; (setq twelf-trace (string-to-number (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-number 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-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-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) proofgeneral-4.3~pre130510/twelf/twelf.el000066400000000000000000000152631214562307500202220ustar00rootroot00000000000000;; twelf.el Proof General instance for Twelf ;; ;; Copyright (C) 2000 LFCS Edinburgh. ;; License: GPL (GNU GENERAL PUBLIC LICENSE) ;; Author: David Aspinall ;; ;; $Id: twelf.el,v 12.0 2011/10/13 10:54:51 da Exp $ ;; ;; ;; TODO: ;; 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-terminal-char ?\. proof-script-comment-start "%" ;; for inserting comments proof-script-comment-end "" proof-script-comment-start-regexp "%[%{ \t\n\f]" ;; recognizing proof-script-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-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" ;; next setting is just to prevent warning proof-save-command-regexp proof-no-regexp) ;; 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)