Initial commit

This commit is contained in:
Greg Shuflin 2022-05-03 20:09:32 -07:00
commit 1ab1e012c3
47 changed files with 985611 additions and 0 deletions

340
LICENSE.TXT Normal file
View File

@ -0,0 +1,340 @@
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
<signature of Ty Coon>, 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.

53
Makefile.am Normal file
View File

@ -0,0 +1,53 @@
bin_PROGRAMS = metamath
noinst_HEADERS = \
mmcmdl.h \
mmcmds.h \
mmdata.h \
mmhlpa.h \
mmhlpb.h \
mminou.h \
mmmaci.h \
mmpars.h \
mmpfas.h \
mmunif.h \
mmutil.h \
mmveri.h \
mmvstr.h \
mmword.h \
mmwtex.h
metamath_SOURCES = \
metamath.c \
mmcmdl.c \
mmcmds.c \
mmdata.c \
mmhlpa.c \
mmhlpb.c \
mminou.c \
mmmaci.c \
mmpars.c \
mmpfas.c \
mmunif.c \
mmutil.c \
mmveri.c \
mmvstr.c \
mmword.c \
mmwtex.c \
$(noinst_HEADERS)
dist_pkgdata_DATA = \
big-unifier.mm \
demo0.mm \
miu.mm \
peano.mm \
ql.mm \
set.mm
EXTRA_DIST = \
LICENSE.TXT \
README.TXT \
__README.TXT
man_MANS = metamath.1

155
README.TXT Normal file
View File

@ -0,0 +1,155 @@
This package contains the metamath program and several Metamath
databases.
Copyright
---------
The metamath program is copyright under the terms of the GNU GPL license
version 2 or later. See the file LICENSE.TXT in this directory.
Individual databases (*.mm files) are either public domain or under
the GNU GPL, as indicated by comments in their headers.
See http://us.metamath.org/copyright.html for further license and
copyright information that applies to the content of this package.
Instructions
------------
For Windows, click on "metamath.exe" and type "read set.mm".
For Unix/Linux/Cygwin/MacOSX using the gcc compiler, compile with the
command "gcc m*.c -o metamath", then type "./metamath set.mm" to run.
As an alternative, if you have autoconf, automake, and a C compiler, you
can compile with the command "autoreconf -i && ./configure && make".
This "autoconf" approach automatically finds your compiler and its
options, and configure takes the usual options (e.g., "--prefix=/usr").
The resulting executable will typically be faster because it will check for
and enable available optimizations; tests found that the "improve"
command ran 28% faster on gcc when using an autoconf-generated "configure".
You can again type "./metamath set.mm" to run. After "make" you may
install it elsewhere using "sudo make install" (note that this installs
".mm" files in the pkgdata directory, by default
"/usr/local/share/metamath/"). If you install it this way, you can then
run metamath as "metamath /usr/share/metamath/set.mm", copy set.mm
locally (cp /usr/share/metamath/set.mm . ; metamath set.mm), or run
metamath and type: read "/usr/share/metamath/set.mm" (note that inside
metamath, filenames containing "/" must be quoted).
Man page
--------
There is a man page for the Metamath program on Linux systems. It is
automatically installed if you use "autoreconf" as described above. To
install it manually, copy the file metamath.1 to the appropriate folder,
using the command "sudo cp metamath.1 /usr/local/share/man/man1/" and
update the man database with the command "sudo mandb". You can then
simply type "man metamath" to access the man page.
Optional enhancements
---------------------
For optimized performance under gcc, you can compile as follows:
gcc m*.c -o metamath -O3 -funroll-loops -finline-functions \
-fomit-frame-pointer -Wall -pedantic
If your compiler supports it, you can also add the option -DINLINE=inline
to achieve the 28% performance increase described above.
On Linux/MacOSX/Unix, the Metamath program will be more pleasant to use
if you run it inside of rlwrap http://utopia.knoware.nl/~hlub/rlwrap/
(checked 3-Jun-2015) which provides up-arrow command history and other
command-line editing features. After you install rlwrap per its
instructions, invoke the Metamath program with "rlwrap ./metamath
set.mm".
In some Linux distributions (such as Debian Woody), if the Backspace
key doesn't delete characters typed after the "MM>" prompt, try adding
this line to your ~/.bash_profile file:
stty echoe echok echoctl echoke
Using rlwrap as described above will also solve this problem.
Additional MacOSX information
-----------------------------
On MacOSX, select the Terminal application from Applications/Utilities
to get to the command line. On recent versions of MacOSX, you need to
install gcc separately. Typing "whereis gcc" will return "/usr/bin/gcc"
if it is installed. The XCode package is typically used to install it,
but it can also be installed without XCode; see
https://github.com/kennethreitz/osx-gcc-installer/ (checked 15-Feb-2014)
Optional rlwrap user interface enhancement
------------------------------------------
On Linux/MacOSX/Unix, the Metamath program will be more pleasant to use
if you run it inside of rlwrap:
http://utopia.knoware.nl/~hlub/uck/rlwrap/ (checked 15-Feb-2014)
which provides up-arrow command history and other command-line editing
features. After you install rlwrap per its instructions, invoke the
Metamath program with "rlwrap ./metamath set.mm".
(The Windows version of the Metamath program was compiled with lcc,
which has similar features built-in.)
Windows Compilation
-------------------
To reproduce the included metamath.exe for Windows, use lcc-win32
version 3.8, with the following command:
lc -O m*.c -o metamath.exe
Further suggestions
-------------------
Once in the program, use the "help" command to guide you. For more
information, see the Metamath book available at http://metamath.org .
To uninstall
------------
To uninstall, just delete the "metamath" directory - nothing else
(Registry, etc.) is touched in your system.
If you used autoconf's "make install" to install it in system locations,
you can use "make uninstall" to remove it.
List of databases
-----------------
The data base files included are:
set.mm - logic and set theory database (see Ch. 3 of the Metamath book).
The Metamath Proof Explorer pages were generated from this database.
nf.mm - logic and set theory database for Quine's New Foundations set
theory.
iset.mm - intuitionistic logic and set theory database.
hol.mm - higher order logic (simple type theory) database.
ql.mm - quantum logic database. The Quantum Logic Explorer pages were
generated from this database.
demo0.mm - demo of simple formal system (see Ch. 2 of the Metamath book)
miu.mm - Hofstadter's MIU-system (see Appendix D of the Metamath book)
big-unifier.mm - A unification stress test (see comments in the file).
peano.mm - A nicely commented presentation of Peano arithmetic, written
by Robert Solovay (unlike the ones above, this database is NOT public
domain but is copyright under the terms of the GNU GPL license)

155
__README.TXT Normal file
View File

@ -0,0 +1,155 @@
This package contains the metamath program and several Metamath-e
databases.-e
-e
-e
Copyright-e
----------e
-e
The metamath program is copyright under the terms of the GNU GPL license-e
version 2 or later. See the file LICENSE.TXT in this directory.-e
-e
Individual databases (*.mm files) are either public domain or under-e
the GNU GPL, as indicated by comments in their headers.-e
-e
See http://us.metamath.org/copyright.html for further license and-e
copyright information that applies to the content of this package.-e
-e
-e
Instructions-e
-------------e
-e
For Windows, click on "metamath.exe" and type "read set.mm".-e
-e
For Unix/Linux/Cygwin/MacOSX using the gcc compiler, compile with the-e
command "gcc m*.c -o metamath", then type "./metamath set.mm" to run.-e
-e
As an alternative, if you have autoconf, automake, and a C compiler, you-e
can compile with the command "autoreconf -i && ./configure && make".-e
This "autoconf" approach automatically finds your compiler and its-e
options, and configure takes the usual options (e.g., "--prefix=/usr").-e
The resulting executable will typically be faster because it will check for-e
and enable available optimizations; tests found that the "improve"-e
command ran 28% faster on gcc when using an autoconf-generated "configure".-e
You can again type "./metamath set.mm" to run. After "make" you may-e
install it elsewhere using "sudo make install" (note that this installs-e
".mm" files in the pkgdata directory, by default-e
"/usr/local/share/metamath/"). If you install it this way, you can then-e
run metamath as "metamath /usr/share/metamath/set.mm", copy set.mm-e
locally (cp /usr/share/metamath/set.mm . ; metamath set.mm), or run-e
metamath and type: read "/usr/share/metamath/set.mm" (note that inside-e
metamath, filenames containing "/" must be quoted).-e
-e
-e
Man page-e
---------e
-e
There is a man page for the Metamath program on Linux systems. It is-e
automatically installed if you use "autoreconf" as described above. To-e
install it manually, copy the file metamath.1 to the appropriate folder,-e
using the command "sudo cp metamath.1 /usr/local/share/man/man1/" and-e
update the man database with the command "sudo mandb". You can then-e
simply type "man metamath" to access the man page.-e
-e
-e
Optional enhancements-e
----------------------e
-e
For optimized performance under gcc, you can compile as follows:-e
-e
gcc m*.c -o metamath -O3 -funroll-loops -finline-functions \-e
-fomit-frame-pointer -Wall -pedantic-e
-e
If your compiler supports it, you can also add the option -DINLINE=inline-e
to achieve the 28% performance increase described above.-e
-e
-e
On Linux/MacOSX/Unix, the Metamath program will be more pleasant to use-e
if you run it inside of rlwrap http://utopia.knoware.nl/~hlub/rlwrap/-e
(checked 3-Jun-2015) which provides up-arrow command history and other-e
command-line editing features. After you install rlwrap per its-e
instructions, invoke the Metamath program with "rlwrap ./metamath-e
set.mm".-e
-e
-e
In some Linux distributions (such as Debian Woody), if the Backspace-e
key doesn't delete characters typed after the "MM>" prompt, try adding-e
this line to your ~/.bash_profile file:-e
-e
stty echoe echok echoctl echoke-e
-e
Using rlwrap as described above will also solve this problem.-e
-e
-e
Additional MacOSX information-e
------------------------------e
-e
On MacOSX, select the Terminal application from Applications/Utilities-e
to get to the command line. On recent versions of MacOSX, you need to-e
install gcc separately. Typing "whereis gcc" will return "/usr/bin/gcc"-e
if it is installed. The XCode package is typically used to install it,-e
but it can also be installed without XCode; see-e
-e
https://github.com/kennethreitz/osx-gcc-installer/ (checked 15-Feb-2014)-e
-e
-e
Optional rlwrap user interface enhancement-e
-------------------------------------------e
-e
On Linux/MacOSX/Unix, the Metamath program will be more pleasant to use-e
if you run it inside of rlwrap:-e
-e
http://utopia.knoware.nl/~hlub/uck/rlwrap/ (checked 15-Feb-2014)-e
-e
which provides up-arrow command history and other command-line editing-e
features. After you install rlwrap per its instructions, invoke the-e
Metamath program with "rlwrap ./metamath set.mm".-e
-e
(The Windows version of the Metamath program was compiled with lcc,-e
which has similar features built-in.)-e
-e
-e
Windows Compilation-e
--------------------e
-e
To reproduce the included metamath.exe for Windows, use lcc-win32-e
version 3.8, with the following command:-e
-e
lc -O m*.c -o metamath.exe-e
-e
-e
Further suggestions-e
--------------------e
-e
Once in the program, use the "help" command to guide you. For more-e
information, see the Metamath book available at http://metamath.org .-e
-e
-e
To uninstall-e
-------------e
-e
To uninstall, just delete the "metamath" directory - nothing else-e
(Registry, etc.) is touched in your system.-e
-e
If you used autoconf's "make install" to install it in system locations,-e
you can use "make uninstall" to remove it.-e
-e
-e
List of databases-e
------------------e
-e
The data base files included are:-e
-e
set.mm - logic and set theory database (see Ch. 3 of the Metamath book).-e
The Metamath Proof Explorer pages were generated from this database.-e
nf.mm - logic and set theory database for Quine's New Foundations set-e
theory.-e
iset.mm - intuitionistic logic and set theory database.-e
hol.mm - higher order logic (simple type theory) database.-e
ql.mm - quantum logic database. The Quantum Logic Explorer pages were-e
generated from this database.-e
demo0.mm - demo of simple formal system (see Ch. 2 of the Metamath book)-e
miu.mm - Hofstadter's MIU-system (see Appendix D of the Metamath book)-e
big-unifier.mm - A unification stress test (see comments in the file).-e
peano.mm - A nicely commented presentation of Peano arithmetic, written-e
by Robert Solovay (unlike the ones above, this database is NOT public-e
domain but is copyright under the terms of the GNU GPL license)-e

336
big-unifier.mm Normal file
View File

@ -0,0 +1,336 @@
$( big-unifier.mm - Version of 30-Aug-2008
~~ PUBLIC DOMAIN ~~
This work is waived of all rights, including copyright, according to the CC0
Public Domain Dedication. http://creativecommons.org/publicdomain/zero/1.0/
Norman Megill - http://metamath.org $)
$(
This file (big-unifier.mm) is a unification and substitution test for
Metamath verifiers, where small input expressions blow up to thousands
of symbols. It is a translation of William McCune's "big-unifier.in"
for the OTTER theorem prover:
http://www-unix.mcs.anl.gov/AR/award-2003/big-unifier.in
http://www-unix.mcs.anl.gov/AR/award-2003/big-unifier.out
Description: "Examples of complicated substitutions in condensed
detachment. These occur in Larry Wos's proofs that XCB is a single
axiom for EC."
$)
$c wff |- e ( , ) $.
$v x y z w v u v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 $.
wx $f wff x $. wy $f wff y $. wz $f wff z $. ww $f wff w $.
wv $f wff v $. wu $f wff u $. wv1 $f wff v1 $. wv2 $f wff v2 $.
wv3 $f wff v3 $. wv4 $f wff v4 $. wv5 $f wff v5 $. wv6 $f wff v6 $.
wv7 $f wff v7 $. wv8 $f wff v8 $. wv9 $f wff v9 $. wv10 $f wff v10 $.
wv11 $f wff v11 $.
$( The binary connective of the language "EC". $)
wi $a wff e ( x , y ) $.
${
ax-mp.1 $e |- x $.
ax-mp.2 $e |- e ( x , y ) $.
$( The inference rule. $)
ax-mp $a |- y $.
$}
$( The first axiom. $)
ax-maj $a |- e ( e ( e ( e ( e ( x , e ( y , e ( e ( e ( e ( e ( z , e (
e ( e ( z , u ) , e ( v , u ) ) , v ) ) , e ( e ( w , e ( e ( e ( w , v6
) , e ( v7 , v6 ) ) , v7 ) ) , y ) ) , v8 ) , e ( v9 , v8 ) ) , v9 ) ) )
, x ) , v10 ) , e ( v11 , v10 ) ) , v11 ) $.
$( The second axiom. $)
ax-min $a |- e ( e ( e ( e ( e ( e ( x , e ( e ( y , e ( e ( e ( y , z )
, e ( u , z ) ) , u ) ) , x ) ) , e ( v , e ( e ( e ( v , w ) , e ( v6 ,
w ) ) , v6 ) ) ) , v7 ) , v8 ) , e ( v7 , v8 ) ) , e ( v9 , e ( e ( e (
v9 , v10 ) , e ( v11 , v10 ) ) , v11 ) ) ) $.
$( A 3-step proof that applies ~ ax-mp to the two axioms. The proof was
saved in compressed format with "save proof theorem1 /compressed" in
the metamath program. $)
theorem1 $p |- e ( e ( e ( x , e ( y , e ( e ( e ( y , z ) , e ( u , z ) )
, u ) ) ) , v ) , e ( x , v ) ) $=
( wi ax-min ax-maj ax-mp ) ABBCFECFFEFFZFZKDFADFFZAFZFJMFFZKNJFFNFZFAO
FFZMPAFFZFPFQPFZFLRFFLNKMJAJNQPLAPGPMKBADCEOARLHI $.
$( This is the same as ~ theorem1 , except that the proof is saved in
uncompressed format with "save proof theorem1u /normal" in the metamath
program. Note the size difference in the compressed vs. uncompressed
proofs. $)
theorem1u $p |- e ( e ( e ( x , e ( y , e ( e ( e ( y , z ) , e ( u , z ) )
, u ) ) ) , v ) , e ( x , v ) ) $=
wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz
wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi
wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi
wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy
wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi
wx wv wi wi wx wi wi wi wi wi wx wx wy wy wz wi wu wz wi wi wu wi wi wi wx
wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi
wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi
wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wx
wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wx wy wy wz wi wu wz
wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi
wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy
wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx
wv wi wi wx wi wi wi wi wi wx wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy
wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv
wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi
wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz
wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi
wi wi wx wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy
wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx
wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi
wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wx wx wy wy wz wi wu wz wi
wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz
wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wy
wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz
wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wi wi wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi
wx wv wi wi wx wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy
wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx
wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi
wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wx wx wy wy wz wi wu wz wi
wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz
wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wy
wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz
wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wi wi wi wi wi wx wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz
wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi
wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu
wi wi wi wv wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi
wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy
wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wx wx wy
wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx
wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi
wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi
wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz
wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi
wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi
wi wi wv wi wx wv wi wi wx wi wi wi wi wi wi wi wi wx wy wy wz wi wu wz wi
wi wu wi wi wi wv wi wx wv wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv
wi wx wv wi wi wx wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi
wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy
wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi
wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz
wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx
wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi
wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wx wx wy wy wz wi wu wz
wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi
wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy
wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx
wv wi wi wx wi wi wi wi wi wi wx wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy
wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx
wv wi wi wx wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi
wu wi wi wi wv wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu
wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy
wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wx wx
wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz
wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi
wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu
wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wi wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wv wi wx wv wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy
wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx
wv wi wi wx wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wy wy wz wi wu wz wi wi wu
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy
wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi
wx wv wi wi wx wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi
wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wx wy
wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx
wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi
wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi
wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz
wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi
wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi
wi wi wv wi wx wv wi wi wx wi wi wi wi wi wx wx wy wy wz wi wu wz wi wi wu
wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi
wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx
wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wy wy wz
wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy
wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu
wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi
wx wi wi wi wi wi wi wx wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy
wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu
wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi
wx wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi
wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx
wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wv wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx
wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wx wx wy wy wz
wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy
wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz
wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx
wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi
wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi
wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wv wi wx wv wi wi wx wi wi wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wv wi wx wv wi wi wx wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz
wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi
wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu
wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi
wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv
wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy
wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi
wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz
wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wx wx wy wy wz wi wu
wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi
wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi
wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy
wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi
wx wv wi wi wx wi wi wi wi wi wi ax-min wx wy wy wz wi wu wz wi wi wu wi wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy
wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx
wv wi wi wx wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi
wu wi wi wi wv wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu
wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy
wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wx wx
wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz
wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi
wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu
wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wi wx wy wy wz wi wu wz wi wi
wu wi wi wi wv wi wx wv wi wi wx wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wy wx wv wz wu wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz
wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi
wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi
wi wi wv wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz
wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wx wx wy wy wz
wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wx wy wy wz wi wu wz wi
wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx
wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi
wi wv wi wx wv wi wi wx wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx
wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi
wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi
wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi
wi wi wx wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi
wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi
wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wv wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu wi wi wi wi wx wy
wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv
wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi wi wx wi wi wx wy
wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv
wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu
wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wx wy wy wz wi wu wz wi
wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz
wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi
wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wy
wy wz wi wu wz wi wi wu wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz
wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv
wi wi wx wi wi wi wi wi wx wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy
wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi
wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi wx wy wy wz wi wu wz
wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wy wy wz wi wu wz wi wi wu
wi wi wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wx wy wy wz wi wu wz wi
wi wu wi wi wi wv wi wx wv wi wi wx wi wi wy wy wz wi wu wz wi wi wu wi wi
wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi wx wi wi wi wi wi
wi wi wx wy wy wz wi wu wz wi wi wu wi wi wi wv wi wx wv wi wi ax-maj ax-mp
$.
$(
This comment holds a simple typesetting definition file so that HTML
pages can be created with "show statement theorem1/html" in the
metamath program.
$t
htmldef "(" as " ( ";
htmldef ")" as " ) ";
htmldef "e" as " e ";
htmldef "wff" as " wff ";
htmldef "|-" as " |- ";
htmldef "," as " , ";
htmldef "x" as " x ";
htmldef "y" as " y ";
htmldef "z" as " z ";
htmldef "w" as " w ";
htmldef "v" as " v ";
htmldef "u" as " u ";
htmldef "v1" as " v1 ";
htmldef "v2" as " v2 ";
htmldef "v3" as " v3 ";
htmldef "v4" as " v4 ";
htmldef "v5" as " v5 ";
htmldef "v6" as " v6 ";
htmldef "v7" as " v7 ";
htmldef "v8" as " v8 ";
htmldef "v9" as " v9 ";
htmldef "v10" as " v10 ";
htmldef "v11" as " v11 ";
$)

86
configure.ac Normal file
View File

@ -0,0 +1,86 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.65])
AC_INIT([metamath], [0.114], [nm.NOSPAM@alum.mit.edu])
AC_CONFIG_SRCDIR([metamath.c])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_FILES([Makefile])
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([limits.h stdlib.h string.h])
AC_HEADER_STDBOOL
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([strchr strcspn strstr])
# Enable gcc warning flags, but only if they seem to work
new_CFLAGS="-Wall -Wextra"
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $new_CFLAGS"
AC_MSG_CHECKING([[for gcc warning flags]])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
int f() {
return 0;
}
]])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AM_CFLAGS="$AM_CFLAGS $new_CFLAGS"])
# Try to optimize.
AC_MSG_CHECKING([[for optimization flags]])
new_CFLAGS="-O3 -funroll-loops -finline-functions -fomit-frame-pointer"
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $new_CFLAGS"
# Remove any existing "-O2", or it will override what we're doing.
CFLAGS=$( printf "%s" "$CFLAGS" | sed -e 's/ -O2/ /' )
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
int f() {
return 0;
}
]])],
[AC_MSG_RESULT([yes])
CFLAGS="$saved_CFLAGS"
CFLAGS=$( printf "%s" "$CFLAGS" | sed -e 's/ -O2/ /' )
AM_CFLAGS="$AM_CFLAGS $new_CFLAGS"],
[AC_MSG_RESULT([no])
CFLAGS="$saved_CFLAGS"])
# Can we use "inline"? We don't use AC_C _INLINE because metamath.c
# does not include the autoconf-generated file.
AC_MSG_CHECKING([[for 'inline' support]])
new_CFLAGS="-DINLINE=inline"
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $new_CFLAGS"
AC_COMPILE_IFELSE(
[AC_LANG_SOURCE([[
inline int f(void) {}
]])],
[AC_MSG_RESULT([yes])
AM_CFLAGS="$AM_CFLAGS $new_CFLAGS"],
[AC_MSG_RESULT([no])])
CFLAGS="$saved_CFLAGS"
echo "CFLAGS=$CFLAGS"
AC_SUBST([AM_CFLAGS])
AC_SUBST([CFLAGS])
AC_OUTPUT

51
demo0.mm Normal file
View File

@ -0,0 +1,51 @@
$( demo0.mm 1-Jan-04 $)
$(
~~ PUBLIC DOMAIN ~~
This work is waived of all rights, including copyright, according to the CC0
Public Domain Dedication. http://creativecommons.org/publicdomain/zero/1.0/
Norman Megill - email: nm at alum.mit.edu
$)
$( This file is the introductory formal system example described
in Chapter 2 of the Meamath book. $)
$( Declare the constant symbols we will use $)
$c 0 + = -> ( ) term wff |- $.
$( Declare the metavariables we will use $)
$v t r s P Q $.
$( Specify properties of the metavariables $)
tt $f term t $.
tr $f term r $.
ts $f term s $.
wp $f wff P $.
wq $f wff Q $.
$( Define "term" (part 1) $)
tze $a term 0 $.
$( Define "term" (part 2) $)
tpl $a term ( t + r ) $.
$( Define "wff" (part 1) $)
weq $a wff t = r $.
$( Define "wff" (part 2) $)
wim $a wff ( P -> Q ) $.
$( State axiom a1 $)
a1 $a |- ( t = r -> ( t = s -> r = s ) ) $.
$( State axiom a2 $)
a2 $a |- ( t + 0 ) = t $.
${
min $e |- P $.
maj $e |- ( P -> Q ) $.
$( Define the modus ponens inference rule $)
mp $a |- Q $.
$}
$( Prove a theorem $)
th1 $p |- t = t $=
$( Here is its proof: $)
tt tze tpl tt weq tt tt weq tt a2 tt tze tpl
tt weq tt tze tpl tt weq tt tt weq wim tt a2
tt tze tpl tt tt a1 mp mp
$.

2249
hol.mm Normal file

File diff suppressed because it is too large Load Diff

116203
iset.mm Normal file

File diff suppressed because it is too large Load Diff

126
metamath.1 Normal file
View File

@ -0,0 +1,126 @@
.\" t -*- coding: UTF-8 -*-
.\" Man page for metamath
.\"
.\" Copyright (C) 2018 Aaron Puchert.
.\"
.\" 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
.\"
.TH metamath 1 "2018-02-04" Metamath "User Manuals"
.SH NAME
metamath \- Formal proof verifier and proof assistant
.SH SYNOPSIS
.BI "metamath [ " "commands" " | " "file" " ]"
.SH DESCRIPTION
.B metamath
is a formal proof verifier and proof assistant for the Metamath language.
It can be initialized via a series of
.I commands
or with a data base
.IR file ,
which can then be explored interactively.
.PP
For details about the Metamath language and the command-line interface, type
.B help
into the command prompt, or read the Metamath book [1], which should have been
installed along with the package.
.SH LANGUAGE
A Metamath database consists of a sequence of three kinds of tokens
separated by white space (which is any sequence of one or more white
space characters). The set of keyword tokens is
.BR ${ ", " $} ", " $c ", " $v ", " $f ", " $e ", " $d ", " $a ", " $p ", "
.BR $. ", " $= ", " $( ", " $) ", " $[ ", and " $] .
The latter four are called auxiliary or preprocessing keywords. A
.I label
token consists of any combination of letters, digits, and the characters hyphen,
underscore, and period.
The label of an assertion is used to refer to it in a proof.
A math
.I symbol
token may consist of any combination of the 93 printable
.BR ascii (7)
characters other than
.BR $ .
All tokens are case-sensitive.
.TP
.BI $( " comment " $)
Comments are ignored.
.TP
.BI $[ " file " $]
Include the contents of a
.IR file .
.TP
.BI ${ " statements " $}
Scoped block of statements. A math symbol becomes active when declared and
stays active until the end of the block in which it is declared.
.TP
.BI $v " symbols " $.
Declare
.I symbols
as variables. A variable may not be declared a second time while it is active,
but it may be declared again (as a variable, but not as a constant) after it
becomes inactive.
.TP
.BI $c " symbols " $.
Declare
.I symbols
as constants. A constant must be declared in the outermost block and may not be
declared a second time.
.TP
.IB "label " $f " constant variable " $.
Variable-type hypothesis to specify the nature or type of a variable (such as
`let x be an integer.'). A variable must have its type specified in a
.B $f
statement before it may be used in a
.BR $e ", " $a ", or " $p
statement. There may not be two active
.B $f
statements containing the same variable.
.TP
.IB "label " $e " constant symbols " $.
Logical hypothesis, expressing a logical truth (such as `assume x is prime')
that must be established in order for an assertion requiring it to also be true.
.TP
.BI $d " variables " $.
Disjoint variable restriction. For distinct active
.IR variables ,
it forbids the substitution of one variable with another.
.TP
.IB "label " $a " constant symbols " $.
Axiomatic assertion.
.TP
.IB "label " $p " constant symbols " $= " proof " $.
Provable assertion. The
.I proof
is a sequence of statement
.IR label s.
This label sequence serves as a set of instructions that the Metamath program
uses to construct a series of math symbol sequences. The construction must
ultimately result in the math symbol sequence contained between the
.BR $p " and " $=
keywords of the
.B $p
statement. For details, see section 4.3 in [1].
Proofs are most easily written using the interactive prompt in
.BR metamath .
.SH FILES
.I /usr/share/metamath
.RS
Data base files for several formal theories.
.SH SEE ALSO
.B "[1]"
Norman Megill:
.UR http://us.metamath.org/downloads/metamath.pdf
Metamath, A Computer Language for Pure Mathematics
.UE .

8102
metamath.c Normal file

File diff suppressed because it is too large Load Diff

BIN
metamath.exe Executable file

Binary file not shown.

130
miu.mm Normal file
View File

@ -0,0 +1,130 @@
$( miu.mm 20-Oct-2008 $)
$(
~~ PUBLIC DOMAIN ~~
This work is waived of all rights, including copyright, according to the CC0
Public Domain Dedication. http://creativecommons.org/publicdomain/zero/1.0/
Norman Megill - email: nm at alum.mit.edu
$)
$( The MIU-system: A simple formal system $)
$( Note: This formal system is unusual in that it allows empty wffs.
To work with a proof, you must type SET EMPTY_SUBSTITUTION ON before
using the PROVE command. By default this is OFF in order to reduce the
number of ambiguous unification possibilities that have to be selected
during the construction of a proof. $)
$(
Hofstadter's MIU-system is a simple example of a formal
system that illustrates some concepts of Metamath. See
Douglas R. Hofstadter, "G\"{o}del, Escher, Bach: An Eternal
Golden Braid" (Vintage Books, New York, 1979), pp. 33ff. for
a description of the MIU-system.
The system has 3 constant symbols, M, I, and U. The sole
axiom of the system is MI. There are 4 rules:
Rule I: If you possess a string whose last letter is I,
you can add on a U at the end.
Rule II: Suppose you have Mx. Then you may add Mxx to
your collection.
Rule III: If III occurs in one of the strings in your
collection, you may make a new string with U in place
of III.
Rule IV: If UU occurs inside one of your strings, you
can drop it.
Note: The following comment applied to an old version of the Metamath
spec that didn't require $f (variable type) hypotheses for variables and
is no longer applicable. The current spec was made stricter primarily
to reduce the likelihood of inconsistent toy axiom systems, effectively
requiring the concept of an "MIU wff" anyway. However, I am keeping the
comment for historical reasons, if only to point out an intrinsic
difference in Rules III and IV that might have relevance to other proof
systems.
Old comment, obsolete: "Unfortunately, Rules III and IV do not have
unique results: strings could have more than one occurrence of III or
UU. This requires that we introduce the concept of an "MIU well-formed
formula" or wff, which allows us to construct unique symbol sequences to
which Rules III and IV can be applied."
Under the old Metamath spec, the problem this caused was that without
the construction of specific wffs to substitute for their variables,
Rules III and IV would sometimes not have unique unifications (as
required by the spec) during a proof, making proofs more difficult or
even impossible.
$)
$( First, we declare the constant symbols of the language.
Note that we need two symbols to distinguish the assertion
that a sequence is a wff from the assertion that it is a
theorem; we have arbitrarily chosen "wff" and "|-". $)
$c M I U |- wff $. $( Declare constants $)
$( Next, we declare some variables. $)
$v x y $.
$( Throughout our theory, we shall assume that these
variables represent wffs. $)
wx $f wff x $.
wy $f wff y $.
$( Define MIU-wffs. We allow the empty sequence to be a
wff. $)
$( The empty sequence is a wff. $)
we $a wff $.
$( "M" after any wff is a wff. $)
wM $a wff x M $.
$( "I" after any wff is a wff. $)
wI $a wff x I $.
$( "U" after any wff is a wff. $)
wU $a wff x U $.
$( If "x" and "y" are wffs, so is "x y". This allows the conclusion of
` IV ` to be provable as a wff before substitutions into it, for those
parsers requiring it. (Added per suggestion of Mel O'Cat 4-Dec-04.) $)
wxy $a wff x y $.
$( Assert the axiom. $)
ax $a |- M I $.
$( Assert the rules. $)
${
Ia $e |- x I $.
$( Given any theorem ending with "I", it remains a theorem
if "U" is added after it. (We distinguish the label I_
from the math symbol I to conform to the 24-Jun-2006
Metamath spec change.) $)
I_ $a |- x I U $.
$}
${
IIa $e |- M x $.
$( Given any theorem starting with "M", it remains a theorem
if the part after the "M" is added again after it. $)
II $a |- M x x $.
$}
${
IIIa $e |- x I I I y $.
$( Given any theorem with "III" in the middle, it remains a
theorem if the "III" is replace with "U". $)
III $a |- x U y $.
$}
${
IVa $e |- x U U y $.
$( Given any theorem with "UU" in the middle, it remains a
theorem if the "UU" is deleted. $)
IV $a |- x y $.
$}
$( Now we prove the theorem MUIIU. You may be interested in
comparing this proof with that of Hofstadter (pp. 35 - 36). $)
theorem1 $p |- M U I I U $=
we wM wU wI we wI wU we wU wI wU we wM we wI wU we wM
wI wI wI we wI wI we wI ax II II I_ III II IV $.

2480
mmcmdl.c Normal file

File diff suppressed because it is too large Load Diff

50
mmcmdl.h Normal file
View File

@ -0,0 +1,50 @@
/*****************************************************************************/
/* Copyright (C) 2018 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMCMDL_H_
#define METAMATH_MMCMDL_H_
#include "mmvstr.h"
#include "mmdata.h"
flag processCommandLine(void);
flag getFullArg(long arg, vstring cmdList);
void parseCommandLine(vstring line);
flag lastArgMatches(vstring argString);
flag cmdMatches(vstring cmdString);
long switchPos(vstring swString);
void printCommandError(vstring line, long arg, vstring errorMsg);
void freeCommandLine(void); /* 4-May-2017 Ari Ferrera */
#define DEFAULT_COLUMN 16
extern pntrString *g_rawArgPntr;
extern nmbrString *g_rawArgNmbr;
extern long g_rawArgs;
extern pntrString *g_fullArg;
extern vstring g_fullArgString; /* 1-Nov-2013 nm g_fullArg as one string */
extern vstring g_commandPrompt;
extern vstring g_commandLine;
extern long g_showStatement;
extern vstring g_logFileName;
extern vstring g_texFileName;
extern flag g_PFASmode; /* Proof assistant mode, invoked by PROVE command */
/* 15-Aug-2020 nm g_queryMode is global only within mmcmdl.c */
/* extern flag g_queryMode; */ /* If 1, explicit questions will be asked even if
a field in the input command line is optional */
extern flag g_sourceChanged; /* Flag that user made some change to the source
file*/
extern flag g_proofChanged; /* Flag that user made some change to proof in
progress*/
extern flag g_commandEcho; /* Echo full command */
extern flag g_memoryStatus; /* Always show memory */
/* 31-Dec-2017 nm */
extern flag g_sourceHasBeenRead; /* 1 if a source file has been read in */
/* 31-Dec-2017 nm */
extern vstring g_rootDirectory; /* Directory to use for included files */
#endif /* METAMATH_MMCMDL_H_ */

7007
mmcmds.c Normal file

File diff suppressed because it is too large Load Diff

158
mmcmds.h Normal file
View File

@ -0,0 +1,158 @@
/*****************************************************************************/
/* Copyright (C) 2020 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMCMDS_H_
#define METAMATH_MMCMDS_H_
#include "mmvstr.h"
#include "mmdata.h"
/* Type (i.e. print) a statement */
void typeStatement(long statemNum,
flag briefFlag,
flag commentOnlyFlag,
flag texFlag,
flag htmlFlg);
/* Type (i.e. print) a proof */
void typeProof(long statemNum,
flag pipFlag, /* Type proofInProgress instead of source file proof */
long startStep, long endStep,
long endIndent,
flag essentialFlag,
flag renumberFlag,
flag unknownFlag,
flag notUnifiedFlag,
flag reverseFlag,
flag noIndentFlag,
long startColumn,
flag skipRepeatedSteps, /* 28-Jun-2013 nm Added */
flag texFlag,
flag htmlFlg);
/* Show details of step */
void showDetailStep(long statemNum, long detailStep);
/* Summary of statements in proof */
void proofStmtSumm(long statemNum, flag essentialFlag, flag texFlag);
/* Traces back the statements used by a proof, recursively. */
flag traceProof(long statemNum,
flag essentialFlag,
flag axiomFlag,
vstring matchList, /* 19-May-2013 nm */
vstring traceToList, /* 18-Jul-2015 nm */
flag testOnlyFlag /* 20-May-2013 nm */);
void traceProofWork(long statemNum,
flag essentialFlag,
vstring traceToList, /* 18-Jul-2015 nm */
vstring *statementUsedFlagsP, /* 'y'/'n' flag that statement is used */
nmbrString **unprovedListP);
/* Traces back the statements used by a proof, recursively, with tree display.*/
void traceProofTree(long statemNum,
flag essentialFlag, long endIndent);
void traceProofTreeRec(long statemNum,
flag essentialFlag, long endIndent, long recursDepth);
/* Counts the number of steps a completely exploded proof would require */
/* (Recursive) */
/* 0 is returned if some assertions have incomplete proofs. */
double countSteps(long statemNum, flag essentialFlag);
/* Traces what statements require the use of a given statement */
vstring traceUsage(long statemNum,
flag recursiveFlag,
long cutoffStmt /* if nonzero, stop scan there */ /* 18-Jul-2015 nm */);
vstring htmlDummyVars(long showStmt); /* 12-Aug-2017 nm */
vstring htmlAllowedSubst(long showStmt); /* 4-Jan-2014 nm */
void readInput(void);
/* WRITE SOURCE command */
void writeSource(/* flag cleanFlag, 3-May-2017 */ /* 1 = "/ CLEAN" qualifier was chosen */
flag reformatFlag /* 1 = "/ FORMAT", 2 = "/REWRAP" */,
/* 31-Dec-2017 nm */
flag splitFlag, /* /SPLIT - write out separate $[ $] includes */
flag noVersioningFlag, /* /NO_VERSIONING - no ~1 backup */
flag keepSplitsFlag, /* /KEEP_SPLITS - don't delete included files
when /SPIT is not specified */
vstring extractLabels /* "" means write everything */
);
/* 24-Aug-2020 nm */
/* Get info for WRITE SOURCE ... / EXTRACT */
void writeExtractedSource(vstring extractLabels, /* EXTRACT argument provided by user */
vstring fullOutput_fn, flag noVersioningFlag);
void fixUndefinedLabels(vstring extractNeeded, vstring *buf);
void writeDict(void);
void eraseSource(void);
void verifyProofs(vstring labelMatch, flag verifyFlag);
/* 7-Nov-2015 nm Added this function for date consistency */
/* If checkFiles = 0, do not open external files.
If checkFiles = 1, check mm*.html, presence of gifs, etc. */
void verifyMarkup(vstring labelMatch, flag dateSkip, flag topDateSkip,
flag fileSkip,
flag underscoreSkip, /* 25-Jun-2020 nm */
flag mathboxSkip, /* 17-Jul-2020 nm */
flag verboseMode); /* 26-Dec-2016 nm */
/* 10-Dec-2018 nm Added */
void processMarkup(vstring inputFileName, vstring outputFileName,
flag processCss, long actionBits);
/* 3-May-2016 nm */
/* List "discouraged" statements with "(Proof modification is discouraged."
and "(New usage is discourged.)" comment markup tags. */
void showDiscouraged(void);
/* 14-Sep-2012 nm */
/* Take a relative step FIRST, LAST, +nn, -nn (relative to the unknown
essential steps) or ALL, and return the actual step for use by ASSIGN,
IMPROVE, REPLACE, LET (or 0 in case of ALL, used by IMPROVE). In case
stepStr is an unsigned integer nn, it is assumed to already be an actual
step and is returned as is. If format is illegal, -1 is returned. */
long getStepNum(vstring relStep, /* User's argument */
nmbrString *pfInProgress, /* proofInProgress.proof */
flag allFlag /* 1 = "ALL" is permissable */);
/* 22-Apr-2015 nm */
/* Convert the actual step numbers of an unassigned step to the relative
-1, -2, etc. offset for SHOW NEW_PROOF ... /UNKNOWN, to make it easier
for the user to ASSIGN the relative step number. A 0 is returned
for the last unknown step. The step numbers of known steps are
unchanged. */
/* The caller must deallocate the returned nmbrString. */
nmbrString *getRelStepNums(nmbrString *pfInProgress);
/* 19-Sep-2012 nm */
/* This procedure finds the next statement number whose label matches
stmtName. Wildcards are allowed. If uniqueFlag is 1,
there must be exactly one match, otherwise an error message is printed,
and -1 is returned. If uniqueFlag is 0, the next match is
returned, or -1 if there are no more matches. No error messages are
printed when uniqueFlag is 0, except for the special case of
startStmt=1. For use by PROVE, REPLACE, ASSIGN. */
long getStatementNum(vstring stmtName, /* Possibly with wildcards */
long startStmt, /* Starting statement number (1 for full scan) */
long maxStmt, /* Must be LESS THAN this statement number */
flag aAllowed, /* 1 means $a is allowed */
flag pAllowed, /* 1 means $p is allowed */
flag eAllowed, /* 1 means $e is allowed */
flag fAllowed, /* 1 means $f is allowed */
flag efOnlyForMaxStmt, /* If 1, $e and $f must belong to maxStmt */
flag uniqueFlag); /* If 1, match must be unique */
/*extern vstring mainFileName;*/ /* 15-Aug-2020 nm Obsolete on 28-Dec-05 */
/* For HELP processing */
extern flag g_printHelp;
void H(vstring helpLine);
/* For MIDI files - added 8/28/00 */
extern flag g_midiFlag; /* Set to 1 if typeProof() is to output MIDI file */
extern vstring g_midiParam; /* Parameter string for MIDI file */
void outputMidi(long plen, nmbrString *indentationLevels,
nmbrString *logicalFlags, vstring g_midiParameter, vstring statementLabel);
#endif /* METAMATH_MMCMDS_H_ */

4169
mmdata.c Normal file

File diff suppressed because it is too large Load Diff

524
mmdata.h Normal file
View File

@ -0,0 +1,524 @@
/*****************************************************************************/
/* Copyright (C) 2020 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
/* mmdata.h - includes for some principal data structures and data-string
handling */
#ifndef METAMATH_MMDATA_H_
#define METAMATH_MMDATA_H_
#include "mmvstr.h"
/*E*/extern long db,db0,db1,db2,db3,db4,db5,db6,db7,db8,db9;/* debugging flags & variables */
typedef char flag; /* A "flag" is simply a character intended for use as a
yes/no logical Boolean; 0 = no and 1 = yes */
extern flag g_listMode; /* 0 = metamath, 1 = list utility */
extern flag g_toolsMode; /* In metamath mode: 0 = metamath, 1 = tools */
typedef long nmbrString; /* String of numbers */
typedef void* pntrString; /* String of pointers */
enum mTokenType { var_, con_ };
#define lb_ '{' /* ${ */
#define rb_ '}' /* $} */
#define v_ 'v' /* $v */
#define c_ 'c' /* $c */
#define a_ 'a' /* $a */
#define d_ 'd' /* $d */
#define e_ 'e' /* $e */
#define f_ 'f' /* $f */
#define p_ 'p' /* $p */
#define eq_ '=' /* $= */
#define sc_ '.' /* $. (historically, used to be $; (semicolon) ) */
#define illegal_ '?' /* anything else */
/* Global variables related to current statement */
extern int g_currentScope;
/*extern long beginScopeStmtNum;*/ /* 15-Aug-2020 nm changed to local in mmpars.c */
struct statement_struct { /* Array index is statement number, starting at 1 */
long lineNum; /* Line number in file; 0 means not yet determined */
vstring fileName; /* File statement is in; "" means not yet determined */
vstring labelName; /* Label of statement */
flag uniqueLabel; /* Flag that label is unique (future implementations may
allow duplicate labels on hypotheses) */
char type; /* 2nd character of keyword, e.g. 'e' for $e */
int scope; /* Block scope level, increased by ${ and decreased by $};
${ has scope _before_ the increase; $} has scope _before_ the decrease */
long beginScopeStatementNum; /* statement of previous ${ ; 0 if we're in
outermost block */
long endScopeStatementNum; /* statement of next $} (populated for opening
${ only, 0 otherwise); g_statements+1 if
we're in outermost block */ /* 24-Aug-2020 nm */
vstring statementPtr; /* Pointer to end of (unmodified) label section used
to determine file and line number for error or info messages about
the statement */
vstring labelSectionPtr; /* Source code before statement keyword
- will be updated if labelSection changed */
long labelSectionLen;
/* 3-May-2017 nm Added labelSectionChanged */
char labelSectionChanged; /* Default is 0; if 1, labelSectionPtr points to an
allocated vstring that must be freed by ERASE */
vstring mathSectionPtr; /* Source code between keyword and $= or $. */
long mathSectionLen;
/* 3-May-2017 nm Added mathSectionChanged */
char mathSectionChanged; /* Default is 0; if 1, mathSectionPtr points to an
allocated vstring that must be freed by ERASE */
vstring proofSectionPtr; /* Source code between $= and $. */
long proofSectionLen;
/* 3-May-2017 nm Added proofSectionChanged */
char proofSectionChanged; /* Default is 0; if 1, proofSectionPtr points to an
allocated vstring that must be freed by ERASE */
nmbrString *mathString; /* Parsed mathSection */
long mathStringLen;
nmbrString *proofString; /* Parsed proofSection (used by $p's only */
nmbrString *reqHypList; /* Required hypotheses (excluding $d's) */
nmbrString *optHypList; /* Optional hypotheses (excluding $d's) */
long numReqHyp; /* Number of required hypotheses */
nmbrString *reqVarList; /* Required variables */
nmbrString *optVarList; /* Optional variables */
nmbrString *reqDisjVarsA; /* Required disjoint variables, 1st of pair */
nmbrString *reqDisjVarsB; /* Required disjoint variables, 2nd of pair */
nmbrString *reqDisjVarsStmt; /* Req disjoint variables, statem number */
nmbrString *optDisjVarsA; /* Optional disjoint variables, 1st of pair */
nmbrString *optDisjVarsB; /* Optional disjoint variables, 2nd of pair */
nmbrString *optDisjVarsStmt; /* Opt disjoint variables, statem number */
long pinkNumber; /* 25-Oct-02 The $a/$p sequence number for web pages */
/* 18-Dec-2016 nm */
long headerStartStmt; /* # of stmt following previous $a, $p */
};
/* Sort keys for statement labels (allocated by parseLabels) */
extern long *g_labelKey;
struct includeCall_struct {
/* This structure holds all information related to $[ $] (include) statements
in the input source files, for error message processing. */
vstring source_fn; /* Name of the file where the
inclusion source is located (= parent file for $( Begin $[... etc.) */
vstring included_fn; /* Name of the file in the
inclusion statement e.g. "$( Begin $[ included_fn..." */
long current_offset; /* This is the starting
character position of the included file w.r.t entire source buffer */
long current_line; /* The line number
of the start of the included file (=1) or the continuation line of
the parent file */
flag pushOrPop; /* 0 means included file, 1 means continuation of parent */
vstring current_includeSource; /* (Currently) assigned
only if we may need it for a later Begin comparison */
long current_includeLength; /* Length of the file
to be included (0 if the file was previously included) */
};
struct mathToken_struct {
vstring tokenName; /* may be used more than once at different scopes */
long length; /* to speed up parsing scans */
char tokenType; /* variable or constant - (char)var_ or (char)con_ */
flag active; /* 1 if token is recognized in current scope */
int scope; /* scope level token was declared at */
long tmp; /* Temporary field use to speed up certain functions */
long statement; /* Statement declared in */
long endStatement; /* Statement of end of scope it was declared in */
};
/* Sort keys for math tokens (allocated by parseMathDecl) */
extern long *g_mathKey;
extern long g_MAX_STATEMENTS;
extern long g_MAX_MATHTOKENS;
extern struct statement_struct *g_Statement;
/*Obs*/ /*extern struct label_struct *label;*/
/* Warning: mathToken[i] is 0-based, not 1-based! */
extern struct mathToken_struct *g_MathToken;
extern long g_statements, /*labels,*/ g_mathTokens;
/*extern long maxMathTokenLength;*/ /* 15-Aug-2020 nm Not used */
extern long g_MAX_INCLUDECALLS;
extern struct includeCall_struct *g_IncludeCall;
extern long g_includeCalls;
extern char *g_sourcePtr; /* Pointer to buffer in memory with input source */
extern long g_sourceLen; /* Number of chars. in all inputs files combined (after includes)*/
/* 4-May-2016 nm */
/* For use by getMarkupFlag() */
#define PROOF_DISCOURAGED_MARKUP "(Proof modification is discouraged.)"
#define USAGE_DISCOURAGED_MARKUP "(New usage is discouraged.)"
/* Mode argument for getMarkupFlag() */
#define PROOF_DISCOURAGED 1
#define USAGE_DISCOURAGED 2
#define RESET 0
/* Mode argument for getContrib() */
#define GC_RESET 0
#define GC_RESET_STMT 10
#define CONTRIBUTOR 1
#define CONTRIB_DATE 2
#define REVISER 3
#define REVISE_DATE 4
#define SHORTENER 5
#define SHORTEN_DATE 6
#define MOST_RECENT_DATE 7
#define GC_ERROR_CHECK_SILENT 8
#define GC_ERROR_CHECK_PRINT 9
/* 12-May-2017 nm */
/* DATE_BELOW_PROOF, if defined, causes generation and error-checking of
the date below the proof (which some day will be obsolete). Comment
it out when this checking is no longer needed. */
/*#define DATE_BELOW_PROOF*/
/* 14-May-2017 nm */
/* TODO: someday we should create structures to hold global vars, and
clear their string components in eraseSource() */
extern vstring g_contributorName;
#define DEFAULT_CONTRIBUTOR "?who?"
extern vstring g_proofDiscouragedMarkup;
extern vstring g_usageDiscouragedMarkup;
extern flag g_globalDiscouragement; /* SET DISCOURAGEMENT */
/* Allocation and deallocation in memory pool */
void *poolFixedMalloc(long size /* bytes */);
void *poolMalloc(long size /* bytes */);
void poolFree(void *ptr);
void addToUsedPool(void *ptr);
/* Purges reset memory pool usage */
void memFreePoolPurge(flag untilOK);
/* Statistics */
void getPoolStats(long *freeAlloc, long *usedAlloc, long *usedActual);
/* Initial memory allocation */
void initBigArrays(void);
/* Find the number of free memory bytes */
long getFreeSpace(long max);
/* Fatal memory allocation error */
void outOfMemory(vstring msg);
/* Bug check error */
void bug(int bugNum);
/* Null nmbrString -- -1 flags the end of a nmbrString */
struct nullNmbrStruct {
long poolLoc;
long allocSize;
long actualSize;
nmbrString nullElement; };
extern struct nullNmbrStruct g_NmbrNull;
#define NULL_NMBRSTRING &(g_NmbrNull.nullElement)
/* Null pntrString -- NULL flags the end of a pntrString */
struct nullPntrStruct {
long poolLoc;
long allocSize;
long actualSize;
pntrString nullElement; };
extern struct nullPntrStruct g_PntrNull;
#define NULL_PNTRSTRING &(g_PntrNull.nullElement)
/* 26-Apr-2008 nm Added */
/* This function returns a 1 if any entry in a comma-separated list
matches using the matches() function. */
flag matchesList(vstring testString, vstring pattern, char wildCard,
char oneCharWildCard);
/* This function returns a 1 if the first argument matches the pattern of
the second argument. The second argument may have 0-or-more and
exactly-1 character match wildcards, typically '*' and '?'.*/
/* 30-Jan-06 nm Added single-character-match argument */
flag matches(vstring testString, vstring pattern, char wildCard,
char oneCharWildCard);
/*******************************************************************/
/*********** Number string functions *******************************/
/*******************************************************************/
/******* Special pupose routines for better
memory allocation (use with caution) *******/
extern long g_nmbrTempAllocStackTop; /* Top of stack for nmbrTempAlloc funct */
extern long g_nmbrStartTempAllocStack; /* Where to start freeing temporary
allocation when nmbrLet() is called (normally 0, except for nested
nmbrString functions) */
/* Make string have temporary allocation to be released by next nmbrLet() */
/* Warning: after nmbrMakeTempAlloc() is called, the nmbrString may NOT be
assigned again with nmbrLet() */
void nmbrMakeTempAlloc(nmbrString *s);
/* Make string have temporary allocation to be
released by next nmbrLet() */
/**************************************************/
/* String assignment - MUST be used to assign vstrings */
void nmbrLet(nmbrString **target,nmbrString *source);
/* String concatenation - last argument MUST be NULL */
nmbrString *nmbrCat(nmbrString *string1,...);
/* Emulation of nmbrString functions similar to BASIC string functions */
nmbrString *nmbrSeg(nmbrString *sin, long p1, long p2);
nmbrString *nmbrMid(nmbrString *sin, long p, long l);
nmbrString *nmbrLeft(nmbrString *sin, long n);
nmbrString *nmbrRight(nmbrString *sin, long n);
/* Allocate and return an "empty" string n "characters" long */
nmbrString *nmbrSpace(long n);
long nmbrLen(nmbrString *s);
long nmbrAllocLen(nmbrString *s);
void nmbrZapLen(nmbrString *s, long length);
/* Search for string2 in string 1 starting at start_position */
long nmbrInstr(long start, nmbrString *sin, nmbrString *s);
/* Search for string2 in string 1 in reverse starting at start_position */
/* (Reverse nmbrInstr) */
long nmbrRevInstr(long start_position,nmbrString *string1,
nmbrString *string2);
/* 1 if strings are equal, 0 otherwise */
int nmbrEq(nmbrString *sout,nmbrString *sin);
/* Converts mString to a vstring with one space between tokens */
vstring nmbrCvtMToVString(nmbrString *s);
/* Converts rString to a vstring with one space between tokens */
/* 25-Jan-2016 nm Added explicitFormat, statemNum */
vstring nmbrCvtRToVString(nmbrString *s,
flag explicitTargets, /* 25-Jan-2016 */
long statemNum); /* 25-Jan-2016 */
/* Get step numbers in an rString - needed by cvtRToVString & elsewhere */
nmbrString *nmbrGetProofStepNumbs(nmbrString *reason);
/* Converts any nmbrString to an ASCII string of numbers corresponding
to the .tokenNum field -- used for debugging only. */
vstring nmbrCvtAnyToVString(nmbrString *s);
/* Extract variables from a math token string */
nmbrString *nmbrExtractVars(nmbrString *m);
/* Determine if an element is in a nmbrString; return position if it is */
long nmbrElementIn(long start, nmbrString *g, long element);
/* Add a single number to end of a nmbrString - faster than nmbrCat */
nmbrString *nmbrAddElement(nmbrString *g, long element);
/* Get the set union of two math token strings (presumably
variable lists) */
nmbrString *nmbrUnion(nmbrString *m1,nmbrString *m2);
/* Get the set intersection of two math token strings (presumably
variable lists) */
nmbrString *nmbrIntersection(nmbrString *m1,nmbrString *m2);
/* Get the set difference m1-m2 of two math token strings (presumably
variable lists) */
nmbrString *nmbrSetMinus(nmbrString *m1,nmbrString *m2);
/* This is a utility function that returns the length of a subproof that
ends at step */
long nmbrGetSubproofLen(nmbrString *proof, long step);
/* This function returns a "squished" proof, putting in {} references
to previous subproofs. */
nmbrString *nmbrSquishProof(nmbrString *proof);
/* This function unsquishes a "squished" proof, replacing {} references
to previous subproofs by the subproofs themselvs. The returned nmbrString
must be deallocated by the caller. */
nmbrString *nmbrUnsquishProof(nmbrString *proof);
/* This function returns the indentation level vs. step number of a proof
string. This information is used for formatting proof displays. The
function calls itself recursively, but the first call should be with
startingLevel = 0. The caller is responsible for deallocating the
result. */
nmbrString *nmbrGetIndentation(nmbrString *proof,
long startingLevel);
/* This function returns essential (1) or floating (0) vs. step number of a
proof string. This information is used for formatting proof displays. The
function calls itself recursively, but the first call should be with
startingLevel = 0. The caller is responsible for deallocating the
result. */
nmbrString *nmbrGetEssential(nmbrString *proof);
/* This function returns the target hypothesis vs. step number of a proof
string. This information is used for formatting proof displays. The
function calls itself recursively. The caller is responsible for
deallocating the result. statemNum is the statement being proved. */
nmbrString *nmbrGetTargetHyp(nmbrString *proof, long statemNum);
/* Converts a proof string to a compressed-proof-format ASCII string.
Normally, the proof string would be compacted with squishProof first,
although it's not a requirement. */
/* The statement number is needed because required hypotheses are
implicit in the compressed proof. */
vstring compressProof(nmbrString *proof, long statemNum,
flag oldCompressionAlgorithm);
/* Gets length of the ASCII form of a compressed proof */
long compressedProofSize(nmbrString *proof, long statemNum);
/*******************************************************************/
/*********** Pointer string functions ******************************/
/*******************************************************************/
/******* Special pupose routines for better
memory allocation (use with caution) *******/
extern long g_pntrTempAllocStackTop; /* Top of stack for pntrTempAlloc funct */
extern long g_pntrStartTempAllocStack; /* Where to start freeing temporary
allocation when pntrLet() is called (normally 0, except for nested
pntrString functions) */
/* Make string have temporary allocation to be released by next pntrLet() */
/* Warning: after pntrMakeTempAlloc() is called, the pntrString may NOT be
assigned again with pntrLet() */
void pntrMakeTempAlloc(pntrString *s);
/* Make string have temporary allocation to be
released by next pntrLet() */
/**************************************************/
/* String assignment - MUST be used to assign vstrings */
void pntrLet(pntrString **target,pntrString *source);
/* String concatenation - last argument MUST be NULL */
pntrString *pntrCat(pntrString *string1,...);
/* Emulation of pntrString functions similar to BASIC string functions */
pntrString *pntrSeg(pntrString *sin, long p1, long p2);
pntrString *pntrMid(pntrString *sin, long p, long length);
pntrString *pntrLeft(pntrString *sin, long n);
pntrString *pntrRight(pntrString *sin, long n);
/* Allocate and return an "empty" string n "characters" long */
pntrString *pntrSpace(long n);
/* Allocate and return an "empty" string n "characters" long
initialized to nmbrStrings instead of vStrings */
pntrString *pntrNSpace(long n);
/* Allocate and return an "empty" string n "characters" long
initialized to pntrStrings instead of vStrings */
pntrString *pntrPSpace(long n);
long pntrLen(pntrString *s);
long pntrAllocLen(pntrString *s);
void pntrZapLen(pntrString *s, long length);
/* Search for string2 in string 1 starting at start_position */
long pntrInstr(long start, pntrString *sin, pntrString *s);
/* Search for string2 in string 1 in reverse starting at start_position */
/* (Reverse pntrInstr) */
long pntrRevInstr(long start_position,pntrString *string1,
pntrString *string2);
/* 1 if strings are equal, 0 otherwise */
int pntrEq(pntrString *sout,pntrString *sin);
/* Add a single null string element to a pntrString - faster than pntrCat */
pntrString *pntrAddElement(pntrString *g);
/* Add a single null pntrString element to a pntrString - faster than pntrCat */
pntrString *pntrAddGElement(pntrString *g);
/* Utility functions */
/* 0/1 knapsack algorithm */
long knapsack01(long items, long *size, long *worth, long maxSize,
char *itemIncluded /* output: 1 = item included, 0 = not included */);
/* 2D matrix allocation and deallocation */
long **alloc2DMatrix(size_t xsize, size_t ysize);
void free2DMatrix(long **matrix, size_t xsize /*, size_t ysize*/);
/* Returns the amount of indentation of a statement label. Used to
determine how much to indent a saved proof. */
long getSourceIndentation(long statemNum);
/* Returns any comment (description) that occurs just before a statement */
vstring getDescription(long statemNum);
/* Returns the label section of a statement with all comments except the
last removed. */
vstring getDescriptionAndLabel(long statemNum);
/* Reconstruct the full header from the strings returned by
getSectionHeadings() */
/*** deleted 12-Sep-2020
vstring buildHeader(vstring header, vstring hdrComment, vstring decoration);
***/
/* Returns 1 if comment has an "is discouraged" markup tag */
flag getMarkupFlag(long statemNum, char mode);
/***** deleted 3-May-2017
/@ Extract any contributors and dates from statement description.
If missing, the corresponding return strings are blank. @/
flag getContrib(long stmtNum,
vstring @contributor, vstring @contribDate,
vstring @revisor, vstring @reviseDate,
vstring @shortener, vstring @shortenDate,
vstring @mostRecentDate,
flag printErrorsFlag,
flag mode /@ 0 == RESET = reset, 1 = normal @/);
************/
/* Extract any contributors and dates from statement description.
If missing, the corresponding return string is blank.
See GC_RESET etc. modes above. Caller must deallocate returned
string. */
vstring getContrib(long stmtNum, char mode);
/*#ifdef DATE_BELOW_PROOF*/ /* 12-May-2017 nm */
/* 14-May-2017 nm - re-enabled for purpose of converting old .mm's */
/* Extract up to 2 dates after a statement's proof. If no date is present,
date1 will be blank. If no 2nd date is present, date2 will be blank. */
void getProofDate(long stmtNum, vstring *date1, vstring *date2);
/*#endif*/
/* Get date, month, year fields from a dd-mmm-yyyy date string,
where dd may be 1 or 2 digits, mmm is 1st 3 letters of month,
and yyyy is 2 or 4 digits. A 1 is returned if an error was detected. */
flag parseDate(vstring dateStr, long *dd, long *mmm, long *yyyy);
/* Build date from numeric fields. mmm should be a number from 1 to 12. */
void buildDate(long dd, long mmm, long yyyy, vstring *dateStr);
/* Compare two dates in the form dd-mmm-yyyy. -1 = date1 < date2,
0 = date1 = date2, 1 = date1 > date2. There is no error checking. */
flag compareDates(vstring date1, vstring date2);
/* 17-Nov-2015 nm */
extern vstring g_qsortKey;
/* Used by qsortStringCmp; pointer only, do not deallocate */
/* Comparison function for qsort */
int qsortStringCmp(const void *p1, const void *p2);
/* 4-May-2017 Ari Ferrera */
/* Call on exit to free memory */
void freeData(void);
#endif /* METAMATH_MMDATA_H_ */

1181
mmhlpa.c Normal file

File diff suppressed because it is too large Load Diff

15
mmhlpa.h Normal file
View File

@ -0,0 +1,15 @@
/*****************************************************************************/
/* Copyright (C) 2005 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMHLPA_H_
#define METAMATH_MMHLPA_H_
#include "mmvstr.h"
void help0(vstring helpCmd);
void help1(vstring helpCmd);
#endif /* METAMATH_MMHLPA_H_ */

1479
mmhlpb.c Normal file

File diff suppressed because it is too large Load Diff

15
mmhlpb.h Normal file
View File

@ -0,0 +1,15 @@
/*****************************************************************************/
/* Copyright (C) 2015 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMHLPB_H_
#define METAMATH_MMHLPB_H_
#include "mmvstr.h"
void help2(vstring helpCmd);
void help3(vstring helpCmd);
#endif /* METAMATH_MMHLPB_H_ */

1593
mminou.c Normal file

File diff suppressed because it is too large Load Diff

96
mminou.h Normal file
View File

@ -0,0 +1,96 @@
/*****************************************************************************/
/* Copyright (C) 2020 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMINOU_H_
#define METAMATH_MMINOU_H_
#include <stdio.h>
#include "mmvstr.h"
#include "mmdata.h"
extern int g_errorCount; /* Total error count */
/* Global variables used by print2() */
extern flag g_logFileOpenFlag;
extern FILE *g_logFilePtr;
extern FILE *g_listFile_fp;
/* Global variables used by print2() */
extern flag g_outputToString;
extern vstring g_printString;
/* Global variables used by cmdInput() */
#define MAX_COMMAND_FILE_NESTING 10
extern long g_commandFileNestingLevel;
extern FILE *g_commandFilePtr[MAX_COMMAND_FILE_NESTING + 1];
extern vstring g_commandFileName[MAX_COMMAND_FILE_NESTING + 1];
extern flag g_commandFileSilent[MAX_COMMAND_FILE_NESTING + 1];
extern flag g_commandFileSilentFlag;
/* 23-Oct-2006 nm For SUBMIT ... /SILENT */
extern FILE /* *inputDef_fp,*/ *g_input_fp /*,*g_output_fp*/; /* File pointers */
/* 31-Dec-2017 nm g_output_fp deleted */
extern vstring /* inputDef_fn,*/ g_input_fn, g_output_fn; /* File names */
/* 19-Jun-2020 nm No longer needed since printBuffer is now dynamically
allocated. */
/*****************************
/@ PRINTBUFFERSIZE should be at least as long as the longest string we
expect (an unfortunate, dangerous limitation of C?) - although if >79
chars are output on a line bug #1505 warning will occur @/
#define PRINTBUFFERSIZE 10001
**********************************/
/* Warning: never call print2 with string longer than PRINTBUFFERSIZE - 1 */
/* print2 returns 0 if the user has quit the printout. */
flag print2(char* fmt,...);
extern long g_screenHeight; /* Height of screen */ /* 18-Nov-05 nm Added */
extern long g_screenWidth; /* Width of screen */
#define MAX_LEN 79 /* Default width of screen */
#define SCREEN_HEIGHT 23 /* Lines on screen, minus 1 to account for prompt */
extern flag g_scrollMode; /* Flag for continuous or prompted scroll */
extern flag g_quitPrint; /* Flag that user typed 'q' to last scrolling prompt */
/* printLongLine automatically puts a newline \n in the output line. */
void printLongLine(vstring line, vstring startNextLine, vstring breakMatch);
vstring cmdInput(FILE *stream,vstring ask);
vstring cmdInput1(vstring ask);
enum severity {notice_,warning_,error_,fatal_};
void errorMessage(vstring line, long lineNum, long column, long tokenLength,
vstring error, vstring fileName, long statementNum, flag warnFlag);
/* Opens files with error message; opens output files with
backup of previous version. Mode must be "r" or "w". */
FILE *fSafeOpen(vstring fileName, vstring mode, flag noVersioningFlag);
/* Renames a file with backup of previous version. If non-zero
is returned, there was an error. */
int fSafeRename(vstring oldFileName, vstring newFileName);
/* Finds the name of the first file of the form filePrefix +
nnn + ".tmp" that does not exist. THE CALLER MUST DEALLOCATE
THE RETURNED STRING. */
vstring fGetTmpName(vstring filePrefix);
/* This function returns a character string containing the entire contents of
an ASCII file, or Unicode file with only ASCII characters. On some
systems it is faster than reading the file line by line. THE CALLER
MUST DEALLOCATE THE RETURNED STRING. If a NULL is returned, the file
could not be opened or had a non-ASCII Unicode character or some other
problem. If verbose is 0, error and warning messages are suppressed. */
/* 31-Dec-2017 nm Add charCount return argument */
vstring readFileToString(vstring fileName, char verbose, long *charCount);
/* 16-Aug-2016 nm */
/* Returns total elapsed time in seconds since starting session (for the
lcc compiler) or the CPU time used (for the gcc compiler). The
argument is assigned the time since the last call to this function. */
double getRunTime(double *timeSinceLastCall);
/* Call before exiting to free memory allocated by this module */
void freeInOu(void); /* 4-May-2017 Ari Ferrera */
#endif /* METAMATH_MMINOU_H_*/

87
mmmaci.c Normal file
View File

@ -0,0 +1,87 @@
/*****************************************************************************/
/* Copyright (C) 2005 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#include <string.h>
/***********************************/
/* Macintosh interface functions */
/***********************************/
#ifdef THINK_C
#include "mmmaci.h"
#define kBaseResID 128
#define kMoveToFront (WindowPtr)-1L
#define kHorizontalPixel 30
#define kVerticalPixel 50
/* Macintosh tool box initialization */
void ToolBoxInit(void)
{
InitGraf(&thePort); /*??? Crashes console interface */
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(nil);
InitCursor();
}
/* Macintosh window initialization */
void WindowInit(void)
{
WindowPtr window;
window = GetNewWindow(kBaseResID, nil, kMoveToFront);
if (window == nil)
{
SysBeep(10); /* Couldn't load the WIND resource!!! */
ExitToShell();
}
ShowWindow(window);
SetPort(window);
/* MoveTo(kHorizontalPixel, kVerticalPixel); */
/* DrawString("\pHello, world!"); */
}
/* Draw the opening window */
void DrawMyPicture(void)
{
Rect pictureRect;
WindowPtr window;
PicHandle picture;
window = FrontWindow();
pictureRect = window->portRect;
picture = GetPicture(kBaseResID);
if (picture == nil) {
SysBeep(10); /* Couldn't load the PICT resource!!! */
ExitToShell();
}
CenterPict(picture, &pictureRect);
DrawPicture(picture, &pictureRect);
}
/* Center picture */
void CenterPict(PicHandle picture, Rect *destRectPtr)
{
Rect windRect, pictRect;
windRect = *destRectPtr;
pictRect = (**(picture)).picFrame;
OffsetRect(&pictRect, windRect.left - pictRect.left,
windRect.top - pictRect.top);
OffsetRect(&pictRect, (windRect.right - pictRect.right)/2,
(windRect.bottom - pictRect.bottom)/2);
*destRectPtr = pictRect;
}
#endif /* end ifdef THINK_C */

20
mmmaci.h Normal file
View File

@ -0,0 +1,20 @@
/*****************************************************************************/
/* Copyright (C) 2005 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
/***********************************/
/* Macintosh interface functions */
/***********************************/
#ifndef METAMATH_MMMACI_H_
#define METAMATH_MMMACI_H_
void ToolBoxInit(void);
void WindowInit(void);
void DrawMyPicture(void);
void CenterPict(PicHandle picture, Rect *destRectPtr);
#endif /* METAMATH_MMMACI_H_ */

6741
mmpars.c Normal file

File diff suppressed because it is too large Load Diff

214
mmpars.h Normal file
View File

@ -0,0 +1,214 @@
/*****************************************************************************/
/* Copyright (C) 2018 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMPARS_H_
#define METAMATH_MMPARS_H_
#include "mmvstr.h"
#include "mmdata.h"
char *readRawSource(/*vstring inputFn,*/ /* 2-Feb-2018 nm Unused argument */
vstring inputBuf, long *size);
void parseKeywords(void);
void parseLabels(void);
void parseMathDecl(void);
void parseStatements(void);
char parseProof(long statemNum);
char parseCompressedProof(long statemNum);
nmbrString *getProof(long statemNum, flag printFlag);
void rawSourceError(char *startFile, char *ptr, long tokenLen,
/*long lineNum,*/ /* 2-Feb-2018 nm */
/*vstring fileName,*/ vstring errMsg); /* 2-Feb-2018 nm */
void sourceError(char *ptr, long tokenLen, long stmtNum, vstring errMsg);
void mathTokenError(long tokenNum /* 0 is 1st one */,
nmbrString *tokenList, long stmtNum, vstring errMsg);
vstring shortDumpRPNStack(void);
/* Label comparison for qsort */
int labelSortCmp(const void *key1, const void *key2);
/* Label comparison for bsearch */
int labelSrchCmp(const void *key, const void *data);
/* Math token comparison for qsort */
int mathSortCmp(const void *key1, const void *key2);
/* Math token label comparison for bsearch */
int mathSrchCmp(const void *key, const void *data);
/* Hypothesis and local label comparison for qsort */
int hypAndLocSortCmp(const void *key1, const void *key2);
/* Hypothesis and local label comparison for bsearch */
int hypAndLocSrchCmp(const void *key, const void *data);
/* This function returns the length of the white space starting at ptr.
Comments are considered white space. ptr should point to the first character
of the white space. If ptr does not point to a white space character, 0
is returned. If ptr points to a null character, 0 is returned. */
long whiteSpaceLen(char *ptr);
/* 31-Dec-2017 nm For .mm file splitting */
/* Like whiteSpaceLen except comments are not whitespace */
long rawWhiteSpaceLen(char *ptr);
/* This function returns the length of the token (non-white-space) starting at
ptr. Comments are considered white space. ptr should point to the first
character of the token. If ptr points to a white space character, 0
is returned. If ptr points to a null character, 0 is returned. If ptr
points to a keyword, 0 is returned. A keyword ends a token. */
long tokenLen(char *ptr);
/* Unlike tokenLen(), keywords are not treated as special. In particular:
if ptr points to a keyword, 0 is NOT returned (instead, 2 is returned),
and a keyword does NOT end a token (which is a relic of days before
whitespace surrounding a token was part of the spec, but still serves
a useful purpose in token() for friendlier error detection). */
long rawTokenLen(char *ptr);
/* This function returns the length of the proof token starting at
ptr. Comments are considered white space. ptr should point to the first
character of the token. If ptr points to a white space character, 0
is returned. If ptr points to a null character, 0 is returned. If ptr
points to a keyword, 0 is returned. A keyword ends a token.
":" is considered a token. */
long proofTokenLen(char *ptr);
/* 9-Jan-2018 nm */
/* Counts the number of \n between start for length chars.
If length = -1, then use end-of-string 0 to stop.
If length >= 0, then scan at most length chars, but stop
if end-of-string 0 is found. */
long countLines(vstring start, long length);
/* Array with sort keys for all possible labels, including the ones for
hypotheses (which may not always be active) */
/* This array is used to see if any label is used anywhere, and is used
to make sure there are no conflicts when local labels inside of compact
proofs are generated. */
extern long *g_allLabelKeyBase;
extern long g_numAllLabelKeys;
/* Working structure for parsing proofs */
/* This structure should be deallocated by the ERASE command. */
extern long g_wrkProofMaxSize; /* Maximum size so far - it may grow */
struct sortHypAndLoc { /* Used for sorting hypAndLocLabel field */
long labelTokenNum;
void *labelName;
};
struct wrkProof_struct {
long numTokens; /* Number of tokens in proof */
long numSteps; /* Number of steps in proof */
long numLocalLabels; /* Number of local labels */
long numHypAndLoc; /* Number of active hypotheses and local labels */
char *localLabelPoolPtr; /* Next free location in local label pool */
long RPNStackPtr; /* Offset of end of RPNStack */
long errorCount; /* Errors in proof - used to suppress too many error msgs */
flag errorSeverity; /* 0 = OK, 1 = unk step, 2 = error, 3 = severe error,
4 = not a $p statement */
/* The following pointers will always be allocated with g_wrkProofMaxSize
entries. If a function needs more than g_wrkProofMaxSize, it must
reallocate all of these and increase g_wrkProofMaxSize. */
nmbrString *tokenSrcPtrNmbr; /* Source parsed into tokens vs. token number
- token size */
pntrString *tokenSrcPtrPntr; /* Source parsed into tokens vs. token number
- token src ptrs */
nmbrString *stepSrcPtrNmbr; /* Pointer to label token in source file
vs. step number - label size */
pntrString *stepSrcPtrPntr; /* Pointer to label token in source file
vs. step number - label src ptrs */
flag *localLabelFlag; /* 1 means step has a local label declaration */
struct sortHypAndLoc *hypAndLocLabel;
/* Sorted ptrs to hyp and local label names + token# */
char *localLabelPool; /* String pool to hold local labels */
nmbrString *proofString; /* The proof in RPN - statement # if > 0
or -(step # + 1000) of local label decl if < -1 */
pntrString *mathStringPtrs; /* Ptr to math string vs. each step */
/* (Allocated in verifyProof() as needed by nmbrLet()) */
nmbrString *RPNStack; /* Stack for RPN parsing */
/* For compressed proof parsing */
nmbrString *compressedPfLabelMap; /* Map from compressed label to actual */
long compressedPfNumLabels; /* Number of compressed labels */
};
extern struct wrkProof_struct g_WrkProof;
/* Converts an ASCII string to a nmbrString of math symbols. statemNum
provides the context for the parse (to get correct active symbols) */
nmbrString *parseMathTokens(vstring userText, long statemNum);
/* 12-Jun-2011 nm Added reformatFlag */
vstring outputStatement(long stmt, /*flag cleanFlag,*/ flag reformatFlag);
/* 12-Jun-2011 nm */
/* Caller must deallocate return string */
vstring rewrapComment(vstring comment);
/* 10/10/02 */
/* Lookup $a or $p label and return statement number.
Return -1 if not found. */
long lookupLabel(vstring label);
/* 31-Dec-2017 nm For file splitting */
/* Get the next real $[...$] or virtual $( Begin $[... inclusion */
void getNextInclusion(char *fileBuf, long startOffset, /* inputs */
/* outputs: */
long *cmdPos1, long *cmdPos2,
long *endPos1, long *endPos2,
char *cmdType, /* 'B' = "$( Begin [$..." through "$( End [$...",
'I' = "[$...",
'S' = "$( Skip [$...",
'E' = Start missing matched End
'N' = no include found */
vstring *fileName /* name of included file */
);
/* This function transfers the content of the statement[] array
to a linear buffer in preparation for creating the output file. */
vstring writeSourceToBuffer(void);
/* 31-Dec-2017 nm */
/* This function creates split files containing $[ $] inclusions, from
a nonsplit source with $( Begin $[... etc. inclusions */
/* Note that *fileBuf is assigned to the empty string upon return, to
conserve memory */
void writeSplitSource(vstring *fileBuf, vstring fileName,
flag noVersioningFlag, flag noDeleteFlag);
/* When "write source" does not have the "/split" qualifier, by default
(i.e. without "/no_delete") the included modules are "deleted" (renamed
to ~1) since their content will be in the main output file. */
void deleteSplits(vstring *fileBuf, flag noVersioningFlag);
/* 9-Jan-2018 nm */
/* Get file name and line number given a pointer into the read buffer */
/* The user must deallocate the returned string (file name) */
/* The globals includeCall structure and includeCalls are used */
vstring getFileAndLineNum(vstring buffPtr/*start of read buffer*/,
vstring currentPtr/*place at which to get file name and line no*/,
long *lineNum/*return argument*/);
/* 9-Jan-2018 nm */
/* statement[stmtNum].fileName and .lineNum are initialized to "" and 0.
To save CPU time, they aren't normally assigned until needed, but once
assigned they can be reused without looking them up again. This function
will assign them if they haven't been assigned yet. It just returns if
they have already been assigned. */
/* The globals statement[] and sourcePtr are used */
void assignStmtFileAndLineNum(long stmtNum);
/* Initial read of source file */
vstring readSourceAndIncludes(vstring inputFn, long *size);
/* Recursively expand the source of an included file */
char *readInclude(vstring fileBuf, long fileBufOffset,
/*vstring inclFileName,*/ vstring sourceFileName,
long *size, long parentLineNum, flag *errorFlag);
#endif /* METAMATH_MMPARS_H_ */

3707
mmpfas.c Normal file

File diff suppressed because it is too large Load Diff

217
mmpfas.h Normal file
View File

@ -0,0 +1,217 @@
/*****************************************************************************/
/* Copyright (C) 2020 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMPFAS_H_
#define METAMATH_MMPFAS_H_
#include "mmvstr.h"
#include "mmdata.h"
extern long g_proveStatement; /* The statement to be proved */
extern flag g_proofChangedFlag; /* Flag to push 'undo' stack */
extern long g_userMaxProveFloat; /* Upper limit for proveFloating */
extern long g_dummyVars; /* The number of dummy variables currently declared */
extern long g_pipDummyVars; /* Number of dummy vars used by proof in progress */
/* Structure for holding a proof in progress. */
/* This structure should be deallocated after use. */
struct pip_struct {
nmbrString *proof; /* The proof itself */
pntrString *target; /* Left hand side of = in display */
pntrString *source; /* Right hand side of = in display */
pntrString *user; /* User-specified math string assignments to step */
};
extern struct pip_struct g_ProofInProgress;
/* Interactively select statement assignments that match */
/* maxEssential is the maximum number of essential hypotheses that a
statement may have in order to be included in the matched list. */
void interactiveMatch(long step, long maxEssential);
/* Assign a statement to an unknown proof step */
void assignStatement(long statemNum, long step);
/* Find proof of formula by using the replaceStatement() algorithm i.e.
see if any statement matches current step AND each of its hypotheses
matches a proof in progress hypothesis or some step already in the proof.
If a proof is found, it is returned, otherwise an empty (length 0) proof is
returned. */
/* The caller must deallocate the returned nmbrString. */
nmbrString *proveByReplacement(long prfStmt,
long prfStep, /* 0 means step 1 */
flag noDistinct, /* 1 means don't try statements with $d's */
flag dummyVarFlag, /* 0 means no dummy vars are in prfStmt */
flag searchMethod, /* 1 means to try proveFloating on $e's also */
long improveDepth,
flag overrideFlag, /* 1 means to override usage locks */ /* 3-May-2016 nm */
flag mathboxFlag /* 1 means allow mathboxes */ /* 5-Aug-2020 nm */
);
nmbrString *replaceStatement(long replStatemNum,
long prfStep,
long provStmtNum,
flag subProofFlag, /* If 1, then scan only subproof at prfStep to look for
matches, instead of whole proof, for faster speed (used by MINIMIZE_WITH) */
flag noDistinct, /* 1 means don't try statements with $d's */
flag searchMethod, /* 1 means to try proveFloating on $e's also */
long improveDepth,
flag overrideFlag, /* 1 means to override usage locks */ /* 3-May-2016 nm */
flag mathboxFlag /* 1 means allow mathboxes */ /* 5-Aug-2020 nm */
);
/* 22-Aug-2012 nm Added this function */
/* This function identifies all steps in the proof in progress that (1) are
independent of step refStep, (2) have no dummy variables, (3) are
not $f's or $e's, and (4) have subproofs that are complete
(no unassigned steps). A "Y" is returned for each such step,
and "N" is returned for all other steps. The "Y" steps can be used
for scanning for useful subproofs outside of the subProof of refStep.
Note: The caller must deallocate the returned vstring. */
vstring getIndepKnownSteps(long proofStmt, long refStep);
/* 22-Aug-2012 nm Added this function */
/* This function classifies each proof step in g_ProofInProgress.proof
as known or unknown ('K' or 'U' in the returned string) depending
on whether the step has a completely known subproof.
Note: The caller must deallocate the returned vstring. */
vstring getKnownSubProofs(void);
/* Add a subproof in place of an unknown step to g_ProofInProgress. The
.target, .source, and .user fields are initialized to empty (except
.target of the deleted unknown step is retained). */
void addSubProof(nmbrString *subProof, long step);
/* 11-Sep-2016 nm */
/* This function eliminates any occurrences of statement sourceStmtNum in the
targetProof by substituting it with the proof of sourceStmtNum. An empty
nmbrString is returned if there was an error. */
/* Normally, targetProof is the global g_ProofInProgress.proof. However,
we make it an argument in case in the future we'd like to do this
outside of the proof assistant. */
nmbrString *expandProof(nmbrString *targetProof,
long sourceStmtNum /*, long targetStmtNum*/);
/* Delete a subproof starting (in reverse from) step. The step is replaced
with an unknown step, and its .target field is retained. */
void deleteSubProof(long step);
/* Check to see if a statement will match the g_ProofInProgress.target (or .user)
of an unknown step. Returns 1 if match, 0 if not, 2 if unification
timed out. */
char checkStmtMatch(long statemNum, long step);
/* Check to see if a (user-specified) math string will match the
g_ProofInProgress.target (or .user) of an step. Returns 1 if match, 0 if
not, 2 if unification timed out. */
char checkMStringMatch(nmbrString *mString, long step);
/* Find proof of formula or simple theorem (no new vars in $e's) */
/* maxEDepth is the maximum depth at which statements with $e hypotheses are
considered. A value of 0 means none are considered. */
nmbrString *proveFloating(nmbrString *mString, long statemNum, long maxEDepth,
long step, flag noDistinct,
/* 3-May-2016 nm */
flag overrideFlag, /* 0 means respect usage locks
1 means to override usage locks
2 means override silently */
flag mathboxFlag /* 1 means allow mathboxes */ /* 5-Aug-2020 nm */
);
/* 22-Aug-2012 nm Added this function */
/* This function does quick check for some common conditions that prevent
a trial statement (scheme) from being unified with a given instance.
Return value 0 means it can't be unified, 1 means it might be unifiable. */
char quickMatchFilter(long trialStmt, nmbrString *mString,
long dummyVarFlag /* 0 if no dummy vars in mString */);
/* Shorten proof by using specified statement. */
void minimizeProof(long repStatemNum, long prvStatemNum, flag
allowGrowthFlag);
/* Initialize g_ProofInProgress.source of the step, and .target of all
hypotheses, to schemes using new dummy variables. */
void initStep(long step);
/* Look for completely known subproofs in g_ProofInProgress.proof and
assign g_ProofInProgress.target and .source. Calls assignKnownSteps(). */
void assignKnownSubProofs(void);
/* This function assigns math strings to all steps (g_ProofInProgress.target and
.source fields) in a subproof with all known steps. */
void assignKnownSteps(long startStep, long sbProofLen);
/* Interactive unify a step. Calls interactiveUnify(). */
/* If messageFlag is 1, a message will be issued if the
step is already unified. If messageFlag is 0, show the step #
being unified. If messageFlag is 2, don't print step #, and do nothing
if step is already unified. */
void interactiveUnifyStep(long step, char messageFlag);
/* Interactively select one of several possible unifications */
/* Returns: 0 = no unification possible
1 = unification was selected; held in stateVector
2 = unification timed out
3 = no unification was selected */
char interactiveUnify(nmbrString *schemeA, nmbrString *schemeB,
pntrString **stateVector);
/* Automatically unify steps with unique unification */
void autoUnify(flag congrats);
/* Make stateVector substitutions in all steps. The stateVector must
contain the result of a valid unification. */
void makeSubstAll(pntrString *stateVector);
/* Replace a dummy variable with a user-specified math string */
void replaceDummyVar(long dummyVar, nmbrString *mString);
/* Get subproof length of a proof, starting at endStep and going backwards */
long subproofLen(nmbrString *proof, long endStep);
/* 25-Aug-2012 nm Added this function */
/* If testStep has no dummy variables, return 0;
if testStep has isolated dummy variables (that don't affect rest of
proof), return 1;
if testStep has dummy variables used elsewhere in proof, return 2 */
char checkDummyVarIsolation(long testStep); /* 0=1st step, 1=2nd, etc. */
/* 25-Aug-2012 nm Added this function */
/* Given a starting step, find its parent (the step it is a hypothesis of) */
/* If the starting step is the last proof step, just return it */
long getParentStep(long startStep); /* 0=1st step, 1=2nd, etc. */
/* Adds a dummy variable to end of mathToken array */
/* (Note: it now grows forever, but purging it might worsen fragmentation) */
void declareDummyVars(long numNewVars);
/* Copies the Proof Assistant proof state */
void copyProofStruct(struct pip_struct *outProofStruct,
struct pip_struct inProofStruct);
/* Initiailizes the Proof Assistant proof state */
void initProofStruct(struct pip_struct *proofStruct, nmbrString *proof,
long proveStatement);
/* Clears the Proof Assistant proof state */
void deallocProofStruct(struct pip_struct *proofStruct);
/* Actions for processUndoStack() */
#define PUS_INIT 1
#define PUS_PUSH 2
#define PUS_UNDO 3
#define PUS_REDO 4
#define PUS_NEW_SIZE 5
#define PUS_GET_SIZE 6
#define PUS_GET_STATUS 7
/* Handle the PUSH, UNDO, and REDO commands */
long processUndoStack(struct pip_struct *proofStruct,
char action,
vstring info, /* Info to print upon UNDO or REDO */
long newStackSize); /* Used only by NEW_SIZE */
#endif /* METAMATH_MMPFAS_H_ */

1734
mmunif.c Normal file

File diff suppressed because it is too large Load Diff

104
mmunif.h Normal file
View File

@ -0,0 +1,104 @@
/*****************************************************************************/
/* Copyright (C) 2020 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMUNIF_H_
#define METAMATH_MMUNIF_H_
#include "mmdata.h"
extern long g_minSubstLen; /* User-settable value - 0 or 1 */
extern long g_userMaxUnifTrials;
/* User-defined upper limit (# backtracks) for unification trials */
extern long g_unifTrialCount;
/* 0 means don't time out; 1 means start counting trials */
extern long g_unifTimeouts; /* Number of timeouts so far for this command */
extern flag g_hentyFilter; /* Turns Henty filter on or off */
/* 26-Sep-2010 nm */
extern flag g_bracketMatchInit; /* So eraseSource() (mmcmds.c) can clr it */
/* 1-Oct-2017 nm Made this global so eraseSource() (mmcmds.c) can clr it */
extern nmbrString *g_firstConst;
/* 2-Oct-2017 nm Made these global so eraseSource() (mmcmds.c) can clr them */
extern nmbrString *g_lastConst;
extern nmbrString *g_oneConst;
nmbrString *makeSubstUnif(flag *newVarFlag,
nmbrString *trialScheme, pntrString *stateVector);
char unify(
nmbrString *schemeA,
nmbrString *schemeB,
/* nmbrString **unifiedScheme, */ /* stateVector[8] holds this */
pntrString **stateVector,
long reEntryFlag);
/* This function unifies two math token strings, schemeA and
schemeB. The result is contained in unifiedScheme.
0 is returned if no assignment is possible.
If reEntryFlag is 1, the next possible set of assignments, if any,
is returned. 2 is returned if the unification times out.
(*stateVector) contains the state of the previous
call. It is the caller's responsibility to deallocate the
contents of (*stateVector) when done, UNLESS a 0 is returned.
The caller must assign (*stateVector) to a legal pntrString
(e.g. NULL_PNTRSTRING) before calling.
All variables with a tokenNum > saveMathTokens are assumed
to be "unknown" variables that can be assigned; all other
variables are treated like constants in the unification
algorithm.
The "unknown" variable assignments are contained in (*stateVector)
(which is a complex structure, described below). Some "unknown"
variables may have no assignment, in which case they will
remain "unknown", and others may have assignments which include
"unknown" variables.
*/
/* oneDirUnif() is like unify(), except that when reEntryFlag is 1,
a new unification is returned ONLY if the assignments to the
variables in schemeA have changed. This is used to speed up the
program. */
flag oneDirUnif(
nmbrString *schemeA,
nmbrString *schemeB,
pntrString **stateVector,
long reEntryFlag);
/* uniqueUnif() is like unify(), but there is no reEntryFlag, and 3 possible
values are returned:
0: no unification was possible.
1: exactly one unification was possible, and stateVector is valid.
2: unification timed out.
3: more than one unification was possible. */
char uniqueUnif(
nmbrString *schemeA,
nmbrString *schemeB,
pntrString **stateVector);
/* unifyH() is like unify(), except that when reEntryFlag is 1,
a new unification is returned ONLY if the normalized unification
does not previously exist in the "Henty filter". This reduces
ambiguous unifications. The values returned are the same as
those returned by unify(). (The elimination of equivalent
unifications was suggested by Jeremy Henty.) */
char unifyH(
nmbrString *schemeA,
nmbrString *schemeB,
pntrString **stateVector,
long reEntryFlag);
/* Cleans out a stateVector if not empty */
void purgeStateVector(pntrString **stateVector);
/* Prints the substitutions determined by unify for debugging purposes */
void printSubst(pntrString *stateVector);
#endif /* METAMATH_MMUNIF_H_ */

15
mmutil.c Normal file
View File

@ -0,0 +1,15 @@
/*****************************************************************************/
/* Copyright (C) 2005 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
/******************************************************************************
*
* This is a collection of useful functions
*
******************************************************************************/
/* (This file is currently empty.) */
/* The include makes file non-empty for ANSI compliance. */
#include <stdio.h>

7
mmutil.h Normal file
View File

@ -0,0 +1,7 @@
/*****************************************************************************/
/* Copyright (C) 2005 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
/* (This file is currently empty.) */

895
mmveri.c Normal file
View File

@ -0,0 +1,895 @@
/*****************************************************************************/
/* Copyright (C) 2017 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <setjmp.h>
#include "mmvstr.h"
#include "mmdata.h"
#include "mminou.h"
#include "mmpars.h"
#include "mmveri.h"
/* Global structure used for getting information about a step */
/* If getStep.stepNum is nonzero, we should get info about that step. */
struct getStep_struct getStep = {0, 0, 0, 0, 0,
NULL_NMBRSTRING, NULL_NMBRSTRING, NULL_PNTRSTRING, NULL_NMBRSTRING,
NULL_PNTRSTRING};
/* Verify proof of one statement in source file. Uses wrkProof structure.
Assumes that parseProof() has just been called for this statement. */
/* Returns 0 if proof is OK; 1 if proof is incomplete (has '?' tokens);
returns 2 if error found; returns 3 if not severe error
found; returns 4 if not a $p statement */
char verifyProof(long statemNum)
{
long stmt; /* Contents of proof string location */
long i, j, step;
char type;
char *fbPtr;
long tokenLength;
long numReqHyp;
char returnFlag = 0;
nmbrString *nmbrTmpPtr;
nmbrString *nmbrHypPtr;
nmbrString *bigSubstSchemeHyp = NULL_NMBRSTRING;
nmbrString *bigSubstInstHyp = NULL_NMBRSTRING;
flag unkHypFlag;
nmbrString *nmbrTmp = NULL_NMBRSTRING; /* Used to force tmp stack dealloc */
if (g_Statement[statemNum].type != p_) return (4); /* Do nothing if not $p */
/* Initialize pointers to math strings in RPN stack and vs. statement. */
/* (Must be initialized, even if severe error, to prevent crashes later.) */
for (i = 0; i < g_WrkProof.numSteps; i++) {
g_WrkProof.mathStringPtrs[i] = NULL_NMBRSTRING;
}
if (g_WrkProof.errorSeverity > 2) return (g_WrkProof.errorSeverity);
/* Error too severe to check here */
g_WrkProof.RPNStackPtr = 0;
if (g_WrkProof.numSteps == 0) return (2);
/* Empty proof caused by error found by in parseProof */
for (step = 0; step < g_WrkProof.numSteps; step++) {
stmt = g_WrkProof.proofString[step];
/* Handle unknown proof steps */
if (stmt == -(long)'?') {
if (returnFlag < 1) returnFlag = 1;
/* Flag that proof is partially unknown */
/* Treat "?" like a hypothesis - push stack and continue */
g_WrkProof.RPNStack[g_WrkProof.RPNStackPtr] = step;
g_WrkProof.RPNStackPtr++;
/* Leave the step's math string empty and continue */
continue;
}
/* See if the proof token is a local label ref. */
if (stmt < 0) {
/* It's a local label reference */
if (stmt > -1000) bug(2101);
i = -1000 - stmt; /* Get the step number it refers to */
/* Push the stack */
g_WrkProof.RPNStack[g_WrkProof.RPNStackPtr] = step;
g_WrkProof.RPNStackPtr++;
/* Assign a math string to the step (must not be deallocated by
cleanWrkProof()!) */
g_WrkProof.mathStringPtrs[step] =
g_WrkProof.mathStringPtrs[i];
continue;
}
type = g_Statement[stmt].type;
/* See if the proof token is a hypothesis */
if (type == e_ || type == f_) {
/* It's a hypothesis reference */
/* Push the stack */
g_WrkProof.RPNStack[g_WrkProof.RPNStackPtr] = step;
g_WrkProof.RPNStackPtr++;
/* Assign a math string to the step (must not be deallocated by
cleanWrkProof()!) */
g_WrkProof.mathStringPtrs[step] =
g_Statement[stmt].mathString;
continue;
}
/* The proof token must be an assertion */
if (type != a_ && type != p_) bug(2102);
/* It's an valid assertion. */
numReqHyp = g_Statement[stmt].numReqHyp;
nmbrHypPtr = g_Statement[stmt].reqHypList;
/* Assemble the hypotheses into two big math strings for unification */
/* Use a "dummy" token, the top of g_mathTokens array, to separate them. */
/* This is already done by the source parsing routines:
g_MathToken[g_mathTokens].tokenType = (char)con_;
g_MathToken[g_mathTokens].tokenName = "$|$"; */ /* Don't deallocate! */
nmbrLet(&bigSubstSchemeHyp, nmbrAddElement(NULL_NMBRSTRING, g_mathTokens));
nmbrLet(&bigSubstInstHyp, nmbrAddElement(NULL_NMBRSTRING, g_mathTokens));
unkHypFlag = 0; /* Flag that there are unknown hypotheses */
j = 0;
for (i = g_WrkProof.RPNStackPtr - numReqHyp; i < g_WrkProof.RPNStackPtr; i++) {
nmbrTmpPtr = g_WrkProof.mathStringPtrs[
g_WrkProof.RPNStack[i]];
if (nmbrTmpPtr[0] == -1) { /* If length is zero, hyp is unknown */
unkHypFlag = 1;
/* Assign scheme to empty nmbrString so it will always match instance */
nmbrLet(&bigSubstSchemeHyp,
nmbrCat(bigSubstSchemeHyp,
nmbrAddElement(nmbrTmpPtr, g_mathTokens), NULL));
} else {
nmbrLet(&bigSubstSchemeHyp,
nmbrCat(bigSubstSchemeHyp,
nmbrAddElement(g_Statement[nmbrHypPtr[j]].mathString,
g_mathTokens), NULL));
}
nmbrLet(&bigSubstInstHyp,
nmbrCat(bigSubstInstHyp,
nmbrAddElement(nmbrTmpPtr, g_mathTokens), NULL));
j++;
/* Get information about the step if requested */
if (getStep.stepNum) { /* If non-zero, step info is requested */
if (g_WrkProof.RPNStack[i] == getStep.stepNum - 1) {
/* Get parent of target if this is one of its hyp's */
getStep.targetParentStep = step + 1;
getStep.targetParentStmt = stmt;
}
if (step == getStep.stepNum - 1) {
/* Add to source hypothesis list */
nmbrLet(&getStep.sourceHyps, nmbrAddElement(getStep.sourceHyps,
g_WrkProof.RPNStack[i]));
}
} /* End of if (getStep.stepNum) */
}
/*E*/if(db7)printLongLine(cat("step ", str((double)step+1), " sch ",
/*E*/ nmbrCvtMToVString(bigSubstSchemeHyp), NULL), "", " ");
/*E*/if(db7)printLongLine(cat("step ", str((double)step+1), " ins ",
/*E*/ nmbrCvtMToVString(bigSubstInstHyp), NULL), "", " ");
/* Unify the hypotheses of the scheme with their instances and assign
the variables of the scheme. If some of the hypotheses are unknown
(due to proof being debugged or previous error) we will try to unify
anyway; if the result is unique, we will use it. */
nmbrTmpPtr = assignVar(bigSubstSchemeHyp,
bigSubstInstHyp, stmt, statemNum, step, unkHypFlag);
/*E*/if(db7)printLongLine(cat("step ", str((double)step+1), " res ",
/*E*/ nmbrCvtMToVString(nmbrTmpPtr), NULL), "", " ");
/* Deallocate stack built up if there are many $d violations */
nmbrLet(&nmbrTmp, NULL_NMBRSTRING);
/* Assign the substituted assertion (must be deallocated by
cleanWrkProof()!) */
g_WrkProof.mathStringPtrs[step] = nmbrTmpPtr;
if (nmbrTmpPtr[0] == -1) {
if (!unkHypFlag) {
returnFlag = 2; /* An error occurred (assignVar printed it) */
}
}
/* Pop the stack */
g_WrkProof.RPNStackPtr = g_WrkProof.RPNStackPtr - numReqHyp;
g_WrkProof.RPNStack[g_WrkProof.RPNStackPtr] = step;
g_WrkProof.RPNStackPtr++;
} /* Next step */
/* If there was a stack error, the verifier should have never been
called. */
if (g_WrkProof.RPNStackPtr != 1) bug(2108);
/* See if the result matches the statement to be proved */
if (returnFlag == 0) {
if (!nmbrEq(g_Statement[statemNum].mathString,
g_WrkProof.mathStringPtrs[g_WrkProof.numSteps - 1])) {
if (!g_WrkProof.errorCount) {
fbPtr = g_WrkProof.stepSrcPtrPntr[g_WrkProof.numSteps - 1];
tokenLength = g_WrkProof.stepSrcPtrNmbr[g_WrkProof.numSteps - 1];
/*??? Make sure suggested commands are correct. */
sourceError(fbPtr, tokenLength, statemNum, cat(
"The result of the proof (step ", str((double)(g_WrkProof.numSteps)),
") does not match the statement being proved. The result is \"",
nmbrCvtMToVString(
g_WrkProof.mathStringPtrs[g_WrkProof.numSteps - 1]),
"\" but the statement is \"",
nmbrCvtMToVString(g_Statement[statemNum].mathString),
"\". Type \"SHOW PROOF ",g_Statement[statemNum].labelName,
"\" to see the proof attempt.",NULL));
}
g_WrkProof.errorCount++;
}
}
nmbrLet(&bigSubstSchemeHyp, NULL_NMBRSTRING);
nmbrLet(&bigSubstInstHyp, NULL_NMBRSTRING);
return (returnFlag);
} /* verifyProof */
/* assignVar() finds an assignment to substScheme variables that match
the assumptions specified in the reason string */
nmbrString *assignVar(nmbrString *bigSubstSchemeAss,
nmbrString *bigSubstInstAss, long substScheme,
/* For error messages: */
long statementNum, long step, flag unkHypFlag)
{
nmbrString *bigSubstSchemeVars = NULL_NMBRSTRING;
nmbrString *substSchemeFrstVarOcc = NULL_NMBRSTRING;
nmbrString *varAssLen = NULL_NMBRSTRING;
nmbrString *substInstFrstVarOcc = NULL_NMBRSTRING;
nmbrString *result = NULL_NMBRSTRING; /* value returned */
long bigSubstSchemeLen,bigSubstInstLen,bigSubstSchemeVarLen,substSchemeLen,
resultLen;
long i,v,v1,p,q,tokenNum;
flag breakFlag, contFlag;
vstring tmpStr = "";
vstring tmpStr2 = "";
flag ambiguityCheckFlag = 0;
nmbrString *saveResult = NULL_NMBRSTRING;
/* Variables for disjoint variable ($d) check */
nmbrString *nmbrTmpPtrAS;
nmbrString *nmbrTmpPtrBS;
nmbrString *nmbrTmpPtrAIR;
nmbrString *nmbrTmpPtrBIR;
nmbrString *nmbrTmpPtrAIO;
nmbrString *nmbrTmpPtrBIO;
long dLen, pos, substAPos, substALen, instAPos, substBPos, substBLen,
instBPos, a, b, aToken, bToken, aToken2, bToken2, dILenR, dILenO,
optStart, reqStart;
flag foundFlag;
/* Variables for getting step info */
long j,k,m;
long numReqHyp;
nmbrString *nmbrHypPtr;
nmbrString *nmbrTmp = NULL_NMBRSTRING; /* Used to force tmp stack dealloc */
long nmbrSaveTempAllocStack;
/* Initialization to avoid compiler warnings (should not be theoretically
necessary) */
dILenR = 0;
dILenO = 0;
optStart = 0;
reqStart = 0;
nmbrTmpPtrAIR = NULL_NMBRSTRING;
nmbrTmpPtrBIR = NULL_NMBRSTRING;
nmbrTmpPtrAIO = NULL_NMBRSTRING;
nmbrTmpPtrBIO = NULL_NMBRSTRING;
nmbrSaveTempAllocStack = g_nmbrStartTempAllocStack;
g_nmbrStartTempAllocStack = g_nmbrTempAllocStackTop; /* For nmbrLet() stack cleanup*/
bigSubstSchemeLen = nmbrLen(bigSubstSchemeAss);
bigSubstInstLen = nmbrLen(bigSubstInstAss);
nmbrLet(&bigSubstSchemeVars,nmbrExtractVars(bigSubstSchemeAss));
bigSubstSchemeVarLen = nmbrLen(bigSubstSchemeVars);
/* If there are no variables in the hypotheses, there won't be any in the
assertion (unless there was a previously detected error). In this case,
the unification is just the assertion itself. */
if (!bigSubstSchemeVarLen) {
if (!nmbrLen(g_Statement[substScheme].reqVarList)) {
nmbrLet(&result,g_Statement[substScheme].mathString);
} else {
/* There must have been a previous error; let result remain empty */
if (!unkHypFlag) bug(2109);
}
goto returnPoint;
}
/* Allocate nmbrStrings used only to hold extra data for bigSubstSchemeAss;
don't use further nmbrString functions on them! */
/* substSchemeFrstVarOcc[] is the 1st occurrence of the variable
in bigSubstSchemeAss */
/* varAssLen[] is the length of the
assignment to the variable */
/* substInstFrstVarOcc[] is the 1st occurrence of the variable
in bigSubstInstAss */
nmbrLet(&substSchemeFrstVarOcc,nmbrSpace(bigSubstSchemeVarLen));
nmbrLet(&varAssLen,substSchemeFrstVarOcc);
nmbrLet(&substInstFrstVarOcc,substSchemeFrstVarOcc);
if (bigSubstSchemeVarLen != nmbrLen(g_Statement[substScheme].reqVarList)) {
if (unkHypFlag) {
/* If there are unknown hypotheses and all variables aren't present,
give up here */
goto returnPoint;
} else {
/* Actually, this could happen if there was a previous error,
which would have already been reported. */
if (!g_WrkProof.errorCount) bug(2103); /* There must have been an error */
goto returnPoint;
}
}
for (i = 0; i < bigSubstSchemeVarLen; i++) {
substSchemeFrstVarOcc[i] = -1; /* Initialize */
/* (varAssLen[], substInstFrstVarOcc[], are
all initialized to 0 by nmbrSpace().) */
}
/* Use the .tmp field of g_MathToken[]. to hold position of variable in
bigSubstSchemeVars for quicker lookup */
for (i = 0; i < bigSubstSchemeVarLen; i++) {
g_MathToken[bigSubstSchemeVars[i]].tmp = i;
}
/* Scan bigSubstSchemeAss to get substSchemeFrstVarOcc[] (1st var
occurrence) */
for (i = 0; i < bigSubstSchemeLen; i++) {
if (g_MathToken[bigSubstSchemeAss[i]].tokenType ==
(char)var_) {
if (substSchemeFrstVarOcc[g_MathToken[bigSubstSchemeAss[
i]].tmp] == -1) {
substSchemeFrstVarOcc[g_MathToken[bigSubstSchemeAss[
i]].tmp] = i;
}
}
}
/* Do the scan */
v = -1; /* Position in bigSubstSchemeVars */
p = 0; /* Position in bigSubstSchemeAss */
q = 0; /* Position in bigSubstInstAss */
ambiguityCheck: /* Re-entry point to see if unification is unique */
while (p != bigSubstSchemeLen-1 || q != bigSubstInstLen-1) {
/*E*/if(db7&&v>=0)printLongLine(cat("p ", str((double)p), " q ", str((double)q), " VAR ",str((double)v),
/*E*/ " ASSIGNED ", nmbrCvtMToVString(
/*E*/ nmbrMid(bigSubstInstAss,substInstFrstVarOcc[v]+1,
/*E*/ varAssLen[v])), NULL), "", " ");
/*E*/if(db7)nmbrLet(&bigSubstInstAss,bigSubstInstAss);
/*E*/if(db7){print2("Enter scan: v=%ld,p=%ld,q=%ld\n",v,p,q); let(&tmpStr,"");}
tokenNum = bigSubstSchemeAss[p];
if (g_MathToken[tokenNum].tokenType == (char)con_) {
/* Constants must match in both substScheme and definiendum assumptions */
if (tokenNum == bigSubstInstAss[q]) {
p++;
q++;
/*E*/if(db7)print2(" Exit, c ok: v=%ld,p=%ld,q=%ld\n",v,p,q);
continue;
} else {
/* Backtrack to last variable assigned and add 1 to its length */
breakFlag = 0;
contFlag = 1;
while (contFlag) {
if (v < 0) {
breakFlag = 1;
break; /* Error - possibilities exhausted */
}
varAssLen[v]++;
p = substSchemeFrstVarOcc[v] + 1;
q = substInstFrstVarOcc[v] + varAssLen[v];
contFlag = 0;
if (bigSubstInstAss[q-1] == g_mathTokens) {
/* It ran into the dummy token separating the assumptions.
A variable cannot be assigned this dummy token. Therefore,
we must pop back a variable. (This test speeds up
the program; theoretically, it is not needed.) */
/*E*/if(db7){print2("GOT TO DUMMY TOKEN1\n");}
v--;
contFlag = 1;
continue;
}
if (q >= bigSubstInstLen) {
/* It overflowed the end of bigSubstInstAss; pop back a variable */
v--;
contFlag = 1;
bug(2104); /* Should be trapped above */
}
} /* end while */
if (breakFlag) {
/*E*/if(db7)print2(" Exit, c bktrk bad: v=%ld,p=%ld,q=%ld\n",v,p,q);
break;
}
/*E*/if(db7)print2(" Exit, c bktrk ok: v=%ld,p=%ld,q=%ld\n",v,p,q);
}
} else {
/* It's a variable. If its the first occurrence, init length to 0 */
v1 = g_MathToken[tokenNum].tmp;
if (v1 > v) {
if (v1 != v + 1) bug(2105);
v = v1;
varAssLen[v] = 0; /* variable length */
substInstFrstVarOcc[v] = q; /* variable start in bigSubstInstAss */
p++;
/*E*/if(db7)print2(" Exit, v new: v=%ld,p=%ld,q=%ld\n",v,p,q);
continue;
} else { /* It's not the first occurrence; check that it matches */
breakFlag = 0;
for (i = 0; i < varAssLen[v1]; i++) {
if (q + i >= bigSubstInstLen) {
/* It overflowed the end of bigSubstInstAss */
breakFlag = 1;
break;
}
if (bigSubstInstAss[substInstFrstVarOcc[v1] + i] !=
bigSubstInstAss[q + i]) {
/* The variable assignment mismatched */
breakFlag = 1;
break;
}
}
if (breakFlag) {
/* Backtrack to last variable assigned and add 1 to its length */
breakFlag = 0;
contFlag = 1;
while (contFlag) {
if (v < 0) {
breakFlag = 1;
break; /* Error - possibilities exhausted */
}
varAssLen[v]++;
p = substSchemeFrstVarOcc[v] + 1;
q = substInstFrstVarOcc[v] + varAssLen[v];
contFlag = 0;
if (bigSubstInstAss[q-1] == g_mathTokens) {
/* It ran into the dummy token separating the assumptions.
A variable cannot be assigned this dummy token. Therefore,
we must pop back a variable. (This test speeds up
the program; theoretically, it is not needed.) */
/*E*/if(db7)print2("GOT TO DUMMY TOKEN\n");
v--;
contFlag = 1;
continue; /* 24-Sep-2010 nm Added missing trap to fix bug(2106) */
}
if (q >= bigSubstInstLen) {
/* It overflowed the end of bigSubstInstAss; pop back a variable */
v--;
contFlag = 1;
bug(2106); /* Should be trapped above */
}
}
if (breakFlag) {
/*E*/if(db7){print2(" Exit, vold bck bad: v=%ld,p=%ld,q=%ld\n",v,p,q);}
break;
}
/*E*/if(db7)print2(" Exit, vold bck ok: v=%ld,p=%ld,q=%ld\n",v,p,q);
continue;
} else {
p++;
q = q + varAssLen[v1];
/*E*/if(db7)print2(" Exit, vold ok: v=%ld,p=%ld,q=%ld\n",v,p,q);
continue;
}
} /* end if first occurrence */
} /* end if constant */
} /* end while */
/*E*/if(db7)printLongLine(cat("BIGVR ", nmbrCvtMToVString(bigSubstSchemeVars),
/*E*/ NULL), "", " ");
/*E*/if(db7)print2(
/*E*/"p=%ld,bigSubstSchemeLen=%ld;q=%ld,bigSubstInstLen=%ld;v=%ld,bigSubstSchemeVarLen=%ld\n",
/*E*/ p,bigSubstSchemeLen,q,bigSubstInstLen,v,bigSubstSchemeVarLen);
/* See if the assignment completed normally */
if (v == -1) {
if (ambiguityCheckFlag) {
/* This is what we wanted to see -- no further unification possible */
goto returnPoint;
}
if (!g_WrkProof.errorCount) {
let(&tmpStr, "");
j = g_Statement[substScheme].numReqHyp;
for (i = 0; i < j; i++) {
k = g_WrkProof.RPNStack[g_WrkProof.RPNStackPtr - j + i]; /* Step */
let(&tmpStr2, nmbrCvtMToVString(g_WrkProof.mathStringPtrs[k]));
if (tmpStr2[0] == 0) let(&tmpStr2,
"? (Unknown step or previous error; unification ignored)");
let(&tmpStr, cat(tmpStr, "\n Hypothesis ", str((double)i + 1), ": ",
nmbrCvtMToVString(
g_Statement[g_Statement[substScheme].reqHypList[i]].mathString),
"\n Step ", str((double)k + 1),
": ", tmpStr2, NULL));
} /* Next i */
/* tmpStr = shortDumpRPNStack(); */ /* Old version */
sourceError(g_WrkProof.stepSrcPtrPntr[step],
g_WrkProof.stepSrcPtrNmbr[step],
statementNum, cat(
"The hypotheses of statement \"", g_Statement[substScheme].labelName,
"\" at proof step ", str((double)step + 1),
" cannot be unified.", tmpStr, NULL));
/* sourceError(g_WrkProof.stepSrcPtrPntr[step],
g_WrkProof.stepSrcPtrNmbr[step],
statementNum, cat(
"The hypotheses of the statement at proof step ",
str(step + 1),
" cannot be unified. The statement \"",
g_Statement[substScheme].labelName,
"\" requires ",
str(g_Statement[substScheme].numReqHyp),
" hypotheses. The ",tmpStr,
". Type \"SHOW PROOF ",g_Statement[statementNum].labelName,
"\" to see the proof attempt.",NULL)); */ /* Old version */
let(&tmpStr, "");
let(&tmpStr2, "");
}
g_WrkProof.errorCount++;
goto returnPoint;
}
if (p != bigSubstSchemeLen - 1 || q != bigSubstInstLen - 1
|| v != bigSubstSchemeVarLen - 1) bug(2107);
/* If a second unification was possible, save the first result for the
error message */
if (ambiguityCheckFlag) {
if (unkHypFlag) {
/* If a hypothesis was unknown, the fact that the unification is ambiguous
doesn't matter, so just return with an empty (unknown) answer. */
nmbrLet(&result,NULL_NMBRSTRING);
goto returnPoint;
}
nmbrLet(&saveResult, result);
nmbrLet(&result, NULL_NMBRSTRING);
}
/***** Get step information if requested *****/
if (!ambiguityCheckFlag) { /* This is the real (first) unification */
if (getStep.stepNum) {
/* See if this step is the requested step; if so get source substitutions */
if (step + 1 == getStep.stepNum) {
nmbrLet(&getStep.sourceSubstsNmbr, nmbrExtractVars(
g_Statement[substScheme].mathString));
k = nmbrLen(getStep.sourceSubstsNmbr);
pntrLet(&getStep.sourceSubstsPntr,
pntrNSpace(k));
for (m = 0; m < k; m++) {
pos = g_MathToken[getStep.sourceSubstsNmbr[m]].tmp; /* Subst pos */
nmbrLet((nmbrString **)(&getStep.sourceSubstsPntr[m]),
nmbrMid(bigSubstInstAss,
substInstFrstVarOcc[pos] + 1, /* Subst pos */
varAssLen[pos]) /* Subst length */ );
}
}
/* See if this step is a target hyp; if so get target substitutions */
j = 0;
numReqHyp = g_Statement[substScheme].numReqHyp;
nmbrHypPtr = g_Statement[substScheme].reqHypList;
for (i = g_WrkProof.RPNStackPtr - numReqHyp; i < g_WrkProof.RPNStackPtr; i++) {
if (g_WrkProof.RPNStack[i] == getStep.stepNum - 1) {
/* This is parent of target; get hyp's variable substitutions */
nmbrLet(&getStep.targetSubstsNmbr, nmbrExtractVars(
g_Statement[nmbrHypPtr[j]].mathString));
k = nmbrLen(getStep.targetSubstsNmbr);
pntrLet(&getStep.targetSubstsPntr, pntrNSpace(k));
for (m = 0; m < k; m++) {
pos = g_MathToken[getStep.targetSubstsNmbr[m]].tmp;
/* Substitution position */
nmbrLet((nmbrString **)(&getStep.targetSubstsPntr[m]),
nmbrMid(bigSubstInstAss,
substInstFrstVarOcc[pos] + 1, /* Subst pos */
varAssLen[pos]) /* Subst length */ );
} /* Next m */
} /* End if (g_WrkProof.RPNStack[i] == getStep.stepNum - 1) */
j++;
} /* Next i */
} /* End if (getStep.stepNum) */
} /* End if (!ambiguityCheckFlag) */
/***** End of getting step information *****/
/***** Check for $d violations *****/
if (!ambiguityCheckFlag) { /* This is the real (first) unification */
nmbrTmpPtrAS = g_Statement[substScheme].reqDisjVarsA;
nmbrTmpPtrBS = g_Statement[substScheme].reqDisjVarsB;
dLen = nmbrLen(nmbrTmpPtrAS); /* Number of disjoint variable pairs */
if (dLen) { /* There is a disjoint variable requirement */
/* (Speedup) Save pointers and lengths for statement being proved */
nmbrTmpPtrAIR = g_Statement[statementNum].reqDisjVarsA;
nmbrTmpPtrBIR = g_Statement[statementNum].reqDisjVarsB;
dILenR = nmbrLen(nmbrTmpPtrAIR); /* Number of disj hypotheses */
nmbrTmpPtrAIO = g_Statement[statementNum].optDisjVarsA;
nmbrTmpPtrBIO = g_Statement[statementNum].optDisjVarsB;
dILenO = nmbrLen(nmbrTmpPtrAIO); /* Number of disj hypotheses */
}
for (pos = 0; pos < dLen; pos++) { /* Scan the disj var pairs */
substAPos = g_MathToken[nmbrTmpPtrAS[pos]].tmp;
substALen = varAssLen[substAPos];
instAPos = substInstFrstVarOcc[substAPos];
substBPos = g_MathToken[nmbrTmpPtrBS[pos]].tmp;
substBLen = varAssLen[substBPos];
instBPos = substInstFrstVarOcc[substBPos];
for (a = 0; a < substALen; a++) { /* Scan subst of 1st var in disj pair */
aToken = bigSubstInstAss[instAPos + a];
if (g_MathToken[aToken].tokenType == (char)con_) continue; /* Ignore */
/* Speed up: find the 1st occurrence of aToken in the disjoint variable
list of the statement being proved. */
/* To bypass speedup, we would do this:
reqStart = 0;
optStart = 0; */
/* First, see if the variable is in the required list. */
foundFlag = 0;
for (i = 0; i < dILenR; i++) {
if (nmbrTmpPtrAIR[i] == aToken
|| nmbrTmpPtrBIR[i] == aToken) {
foundFlag = 1;
reqStart = i;
break;
}
}
/* If not, see if it is in the optional list. */
if (!foundFlag) {
reqStart = dILenR; /* Force skipping required scan */
foundFlag = 0;
for (i = 0; i < dILenO; i++) {
if (nmbrTmpPtrAIO[i] == aToken
|| nmbrTmpPtrBIO[i] == aToken) {
foundFlag = 1;
optStart = i;
break;
}
}
if (!foundFlag) optStart = dILenO; /* Force skipping optional scan */
} else {
optStart = 0;
} /* (End if (!foundFlag)) */
/* (End of speedup section) */
for (b = 0; b < substBLen; b++) { /* Scan subst of 2nd var in pair */
bToken = bigSubstInstAss[instBPos + b];
if (g_MathToken[bToken].tokenType == (char)con_) continue; /* Ignore */
if (aToken == bToken) {
if (!g_WrkProof.errorCount) { /* No previous errors in this proof */
sourceError(g_WrkProof.stepSrcPtrPntr[step], /* source ptr */
g_WrkProof.stepSrcPtrNmbr[step], /* size of token */
statementNum, cat(
"There is a disjoint variable ($d) violation at proof step ",
str((double)step + 1),". Assertion \"",
g_Statement[substScheme].labelName,
"\" requires that variables \"",
g_MathToken[nmbrTmpPtrAS[pos]].tokenName,
"\" and \"",
g_MathToken[nmbrTmpPtrBS[pos]].tokenName,
"\" be disjoint. But \"",
g_MathToken[nmbrTmpPtrAS[pos]].tokenName,
"\" was substituted with \"",
nmbrCvtMToVString(nmbrMid(bigSubstInstAss,instAPos + 1,
substALen)),
"\" and \"",
g_MathToken[nmbrTmpPtrBS[pos]].tokenName,
"\" was substituted with \"",
nmbrCvtMToVString(nmbrMid(bigSubstInstAss,instBPos + 1,
substBLen)),
"\". These substitutions have variable \"",
g_MathToken[aToken].tokenName,
"\" in common.",
NULL));
let(&tmpStr, ""); /* Force tmp string stack dealloc */
nmbrLet(&nmbrTmp,NULL_NMBRSTRING); /* Force tmp stack dealloc */
} /* (End if (!g_WrkProof.errorCount) ) */
} else { /* aToken != bToken */
/* The variables are different. We're still not done though: We
must make sure that the $d's of the statement being proved
guarantee that they will be disjoint. */
/*???Future: use bsearch for speedup? Must modify main READ
parsing to produce sorted disj var lists; this would slow down
the main READ. */
/* Make sure that the variables are in the right order for lookup.*/
if (aToken > bToken) {
aToken2 = bToken;
bToken2 = aToken;
} else {
aToken2 = aToken;
bToken2 = bToken;
}
/* Scan the required disjoint variable hypotheses to see if they're
in it. */
/* First, see if both variables are in the required list. */
foundFlag = 0;
for (i = reqStart; i < dILenR; i++) {
if (nmbrTmpPtrAIR[i] == aToken2) {
if (nmbrTmpPtrBIR[i] == bToken2) {
foundFlag = 1;
break;
}
}
}
/* If not, see if they are in the optional list. */
if (!foundFlag) {
foundFlag = 0;
for (i = optStart; i < dILenO; i++) {
if (nmbrTmpPtrAIO[i] == aToken2) {
if (nmbrTmpPtrBIO[i] == bToken2) {
foundFlag = 1;
break;
}
}
}
} /* (End if (!foundFlag)) */
/* If they were in neither place, we have a violation. */
if (!foundFlag) {
if (!g_WrkProof.errorCount) { /* No previous errors in this proof */
sourceError(g_WrkProof.stepSrcPtrPntr[step], /* source */
g_WrkProof.stepSrcPtrNmbr[step], /* size of token */
statementNum, cat(
"There is a disjoint variable ($d) violation at proof step ",
str((double)step + 1), ". Assertion \"",
g_Statement[substScheme].labelName,
"\" requires that variables \"",
g_MathToken[nmbrTmpPtrAS[pos]].tokenName,
"\" and \"",
g_MathToken[nmbrTmpPtrBS[pos]].tokenName,
"\" be disjoint. But \"",
g_MathToken[nmbrTmpPtrAS[pos]].tokenName,
"\" was substituted with \"",
nmbrCvtMToVString(nmbrMid(bigSubstInstAss, instAPos + 1,
substALen)),
"\" and \"",
g_MathToken[nmbrTmpPtrBS[pos]].tokenName,
"\" was substituted with \"",
nmbrCvtMToVString(nmbrMid(bigSubstInstAss, instBPos + 1,
substBLen)),
"\".", NULL));
/* Put missing $d requirement in new line so grep can find
them easily in log file */
printLongLine(cat("Variables \"",
/* 30-Apr-04 nm Put in alphabetic order for easier use if
user sorts the list of errors */
/* strcmp returns <0 if 1st<2nd */
(strcmp(g_MathToken[aToken].tokenName,
g_MathToken[bToken].tokenName) < 0)
? g_MathToken[aToken].tokenName
: g_MathToken[bToken].tokenName,
"\" and \"",
(strcmp(g_MathToken[aToken].tokenName,
g_MathToken[bToken].tokenName) < 0)
? g_MathToken[bToken].tokenName
: g_MathToken[aToken].tokenName,
"\" do not have a disjoint variable requirement in the ",
"assertion being proved, \"",
g_Statement[statementNum].labelName,
"\".", NULL), "", " ");
let(&tmpStr, ""); /* Force tmp string stack dealloc */
nmbrLet(&nmbrTmp,NULL_NMBRSTRING); /* Force tmp stack dealloc */
} /* (End if (!g_WrkProof.errorCount) ) */
} /* (End if (!foundFlag)) */
} /* (End if (aToken == bToken)) */
} /* (Next b) */
} /* (Next a) */
} /* (Next pos) */
} /* (End if (!ambiguityCheck)) */
/***** (End of $d violation check) *****/
/* Assemble the final result */
substSchemeLen = nmbrLen(g_Statement[substScheme].mathString);
/* Calculate the length of the final result */
q = 0;
for (p = 0; p < substSchemeLen; p++) {
tokenNum = g_Statement[substScheme].mathString[p];
if (g_MathToken[tokenNum].tokenType == (char)con_) {
q++;
} else {
q = q + varAssLen[g_MathToken[tokenNum].tmp];
}
}
/* Allocate space for the final result */
resultLen = q;
nmbrLet(&result,nmbrSpace(resultLen));
/* Assign the final result */
q = 0;
for (p = 0; p < substSchemeLen; p++) {
tokenNum = g_Statement[substScheme].mathString[p];
if (g_MathToken[tokenNum].tokenType == (char)con_) {
result[q] = tokenNum;
q++;
} else {
for (i = 0; i < varAssLen[g_MathToken[tokenNum].tmp]; i++){
result[q + i] = bigSubstInstAss[i +
substInstFrstVarOcc[g_MathToken[tokenNum].tmp]];
}
q = q + i;
}
}
/*E*/if(db7)printLongLine(cat("result ", nmbrCvtMToVString(result), NULL),""," ");
if (ambiguityCheckFlag) {
if (!g_WrkProof.errorCount) {
/*??? Make sure suggested commands are correct. */
sourceError(g_WrkProof.stepSrcPtrPntr[step],
g_WrkProof.stepSrcPtrNmbr[step],
statementNum, cat(
"The unification with the hypotheses of the statement at proof step ",
str((double)step + 1),
" is not unique. Two possible results at this step are \"",
nmbrCvtMToVString(saveResult),
"\" and \"",nmbrCvtMToVString(result),
"\". Type \"SHOW PROOF ",g_Statement[statementNum].labelName,
"\" to see the proof attempt.",NULL));
}
g_WrkProof.errorCount++;
goto returnPoint;
} else {
/* Prepare to see if the unification is unique */
while (1) {
v--;
if (v < 0) {
goto returnPoint; /* It's unique */
}
varAssLen[v]++;
p = substSchemeFrstVarOcc[v] + 1;
q = substInstFrstVarOcc[v] + varAssLen[v];
if (bigSubstInstAss[q - 1] != g_mathTokens) break;
if (q >= bigSubstInstLen) bug(2110);
}
ambiguityCheckFlag = 1;
goto ambiguityCheck;
}
returnPoint:
/* Free up all allocated nmbrString space */
for (i = 0; i < bigSubstSchemeVarLen; i++) {
/* Make the data-holding structures legal nmbrStrings before nmbrLet() */
/*???Make more efficient by deallocating directly*/
substSchemeFrstVarOcc[i] = 0;
varAssLen[i] = 0;
substInstFrstVarOcc[i] = 0;
}
nmbrLet(&bigSubstSchemeVars,NULL_NMBRSTRING);
nmbrLet(&substSchemeFrstVarOcc,NULL_NMBRSTRING);
nmbrLet(&varAssLen,NULL_NMBRSTRING);
nmbrLet(&substInstFrstVarOcc,NULL_NMBRSTRING);
nmbrLet(&saveResult,NULL_NMBRSTRING);
g_nmbrStartTempAllocStack = nmbrSaveTempAllocStack;
return(result);
}
/* Deallocate the math symbol strings assigned in wrkProof structure during
proof verification. This should be called after verifyProof() and after the
math symbol strings have been used for proof printouts, etc. */
/* Note that this does NOT free the other allocations in g_WrkProof. The
ERASE command will do this. */
void cleanWrkProof(void) {
long step;
char type;
for (step = 0; step < g_WrkProof.numSteps; step++) {
if (g_WrkProof.proofString[step] > 0) {
type = g_Statement[g_WrkProof.proofString[step]].type;
if (type == a_ || type == p_) {
/* Allocation was only done if: (1) it's not a local label reference
and (2) it's not a hypothesis. In this case, deallocate. */
nmbrLet((nmbrString **)(&g_WrkProof.mathStringPtrs[step]),
NULL_NMBRSTRING);
}
}
}
}

45
mmveri.h Normal file
View File

@ -0,0 +1,45 @@
/*****************************************************************************/
/* Copyright (C) 2005 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMVERI_H_
#define METAMATH_MMVERI_H_
#include "mmdata.h"
char verifyProof(long statemNum);
/* assignVar() finds an assignment to substScheme variables that match
the assumptions specified in the reason string */
nmbrString *assignVar(nmbrString *bigSubstSchemeAss,
nmbrString *bigSubstInstAss, long substScheme,
/* For error messages: */
long statementNum, long step, flag unkHypFlag);
/* Deallocate the math symbol strings assigned in g_WrkProof structure during
proof verification. This should be called after verifyProof() and after the
math symbol strings have been used for proof printouts, etc. */
/* Note that this does NOT free the other allocations in g_WrkProof. The
ERASE command will do this. */
void cleanWrkProof(void);
/* Structure for getting info about a step for SHOW PROOF/STEP command */
/* If getStep.stepNum is nonzero, we should get info about that step. */
/* This structure should be deallocated after use. */
struct getStep_struct {
long stepNum; /* Step # to get info about */
long sourceStmt; /* Right side of = in proof display */
long targetStmt; /* Left side of = in proof display */
long targetParentStep; /* Step # of target's parent */
long targetParentStmt; /* Statement # of target's parent */
nmbrString *sourceHyps; /* List of step #'s */
nmbrString *sourceSubstsNmbr; /* List of vars w/ ptr to subst math tokens */
pntrString *sourceSubstsPntr; /* List of vars w/ ptr to subst math tokens */
nmbrString *targetSubstsNmbr; /* List of vars w/ ptr to subst math tokens */
pntrString *targetSubstsPntr; /* List of vars w/ ptr to subst math tokens */
};
extern struct getStep_struct getStep;
#endif /* METAMATH_MMVERI_H_ */

997
mmvstr.c Normal file
View File

@ -0,0 +1,997 @@
/*****************************************************************************/
/* Copyright (C) 2019 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
/*
mmvstr.c - VMS-BASIC variable length string library routines header
This is an emulation of the string functions available in VMS BASIC.
*/
/*** See the comments in mmvstr.h for an explanation of these functions ******/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include "mmvstr.h"
/*E*/ /*Next line is need to declare "db" for debugging*/
#include "mmdata.h"
/* 1-Dec-05 nm
mmdata.h is also used to declare the bug() function that is called in
several places by mmvstr.c. To make mmvstr.c and mmvstr.h completely
independent of the other programs, for use with another project, do the
following:
(1) Remove all lines beginning with the "/ *E* /" comment.
(2) Remove all calls to the bug() function (4 places).
To see an example of stand-alone usage of the mmvstr.c functions, see
the program lattice.c and several others included in
http://us.metamath.org/downloads/quantum-logic.tar.gz
*/
/*E*/long db1=0;
#ifdef NDEBUG
# define INCDB1(x)
#else
# define INCDB1(x) db1 += (x)
#endif
#define MAX_ALLOC_STACK 100
long g_tempAllocStackTop = 0; /* Top of stack for tempAlloc functon */
long g_startTempAllocStack = 0; /* Where to start freeing temporary allocation
when let() is called (normally 0, except in
special nested vstring functions) */
void *tempAllocStack[MAX_ALLOC_STACK];
static void freeTempAlloc(void)
{
/* All memory previously allocated with tempAlloc is deallocated. */
/* EXCEPT: When g_startTempAllocStack != 0, the freeing will start at
g_startTempAllocStack. */
long i;
for (i = g_startTempAllocStack; i < g_tempAllocStackTop; i++) {
/*E*/INCDB1(-1 - (long)strlen(tempAllocStack[i]));
/*E* /printf("%ld removing [%s]\n", db1, tempAllocStack[i]);*/
free(tempAllocStack[i]);
}
g_tempAllocStackTop = g_startTempAllocStack;
} /* freeTempAlloc */
static void pushTempAlloc(void *mem)
{
if (g_tempAllocStackTop >= (MAX_ALLOC_STACK-1)) {
printf("*** FATAL ERROR *** Temporary string stack overflow\n");
#if __STDC__
fflush(stdout);
#endif
bug(2201);
}
tempAllocStack[g_tempAllocStackTop++] = mem;
} /* pushTempAlloc */
static void* tempAlloc(long size) /* String memory allocation/deallocation */
{
void* memptr = malloc((size_t)size);
if (!memptr || size == 0) {
printf("*** FATAL ERROR *** Temporary string allocation failed\n");
#if __STDC__
fflush(stdout);
#endif
bug(2202);
}
pushTempAlloc(memptr);
/*E*/INCDB1(size);
/*E* /printf("%ld adding\n",db1);*/
return memptr;
} /* tempAlloc */
/* Make string have temporary allocation to be released by next let() */
/* Warning: after makeTempAlloc() is called, the vstring may NOT be
assigned again with let() */
void makeTempAlloc(vstring s)
{
pushTempAlloc(s);
/*E*/INCDB1((long)strlen(s) + 1);
/*E*/db-=(long)strlen(s) + 1;
/*E* /printf("%ld temping[%s]\n", db1, s);*/
} /* makeTempAlloc */
/* 8-Jul-2013 Wolf Lammen - rewritten to simplify it */
void let(vstring *target, vstring source) /* String assignment */
/* This function must ALWAYS be called to make assignment to */
/* a vstring in order for the memory cleanup routines, etc. */
/* to work properly. If a vstring has never been assigned before, */
/* it is the user's responsibility to initialize it to "" (the */
/* null string). */
{
size_t sourceLength = strlen(source); /* Save its length */
size_t targetLength = strlen(*target); /* Save its length */
/*E*/if (targetLength) {
/*E*/ db -= (long)targetLength+1;
/*E*/ /* printf("%ld Deleting %s\n",db,*target); */
/*E*/}
/*E*/if (sourceLength) {
/*E*/ db += (long)sourceLength+1;
/*E*/ /* printf("%ld Adding %s\n",db,source); */
/*E*/}
if (targetLength < sourceLength) { /* Old string has not enough room for new one */
/* Free old string space and allocate new space */
if (targetLength)
free(*target); /* Free old space */
*target = malloc(sourceLength + 1); /* Allocate new space */
if (!*target) {
printf("*** FATAL ERROR *** String memory couldn't be allocated\n");
#if __STDC__
fflush(stdout);
#endif
bug(2204);
}
}
if (sourceLength) {
strcpy(*target, source);
} else {
/* Empty strings could still be temporaries, so always assign a constant */
if (targetLength) {
free(*target);
}
*target= "";
}
freeTempAlloc(); /* Free up temporary strings used in expression computation */
} /* let */
vstring cat(vstring string1,...) /* String concatenation */
#define MAX_CAT_ARGS 50
{
va_list ap; /* Declare list incrementer */
vstring arg[MAX_CAT_ARGS]; /* Array to store arguments */
size_t argPos[MAX_CAT_ARGS]; /* Array of argument positions in result */
vstring result;
int i;
int numArgs = 0; /* Define "last argument" */
size_t pos = 0;
char* curArg = string1;
va_start(ap, string1); /* Begin the session */
do {
/* User-provided argument list must terminate with 0 */
if (numArgs >= MAX_CAT_ARGS) {
printf("*** FATAL ERROR *** Too many cat() arguments\n");
#if __STDC__
fflush(stdout);
#endif
bug(2206);
}
arg[numArgs] = curArg;
argPos[numArgs] = pos;
pos += strlen(curArg);
} while (++numArgs, (curArg = va_arg(ap,char *)) != 0);
va_end(ap); /* End var args session */
/* Allocate the memory for it */
result = tempAlloc((long)pos+1);
/* Move the strings into the newly allocated area */
for (i = 0; i < numArgs; ++i)
strcpy(result + argPos[i], arg[i]);
return result;
} /* cat */
/* 20-Oct-2013 Wolf Lammen - allow unlimited input line lengths */
/* Input a line from the user or from a file */
/* Returns 1 if a (possibly empty) line was successfully read, 0 if EOF */
int linput(FILE *stream, const char* ask, vstring *target)
{ /* Note: "vstring *target" means "char **target" */
/*
BASIC: linput "what"; a$
c: linput(NULL, "what?", &a);
BASIC: linput #1, a$ (error trap on EOF)
c: if (!linput(file1, NULL, &a)) break; (break on EOF)
*/
/* This function prints a prompt (if 'ask' is not NULL), gets a line from
the stream, and assigns it to target using the let(&...) function.
0 is returned when end-of-file is encountered. The vstring
*target MUST be initialized to "" or previously assigned by let(&...)
before using it in linput. */
char f[10001]; /* Read in chunks up to 10000 characters */
int result = 0;
int eol_found = 0;
if (ask) {
printf("%s", ask);
#if __STDC__
fflush(stdout);
#endif
}
if (stream == NULL) stream = stdin;
while (!eol_found && fgets(f, sizeof(f), stream))
{
size_t endpos = strlen(f) - 1;
eol_found = (f[endpos] == '\n');
/* If the last line in the file has no newline, eol_found will be 0 here.
The fgets() above will return 0 and prevent another loop iteration. */
if (eol_found)
f[endpos] = 0; /* The return string will have any newline stripped. */
if (result)
/* Append additional parts of the line to *target */
/* The let() reallocates *target and copies the concatenation of the
old *target and the additional input f[] to it */
let(target /* = &(*target) */, cat(*target, f, NULL));
else
/* This is the first time through the loop, and normally
the only one unless the input line overflows f[] */
let(target, f); /* Allocate *target and copy f to it */
result = 1;
}
return result;
} /* linput */
/* Find out the length of a string */
long len(vstring s)
{
return ((long)strlen(s));
} /* len */
/* Extract sin from character position start to stop into sout */
vstring seg(vstring sin, long start, long stop)
{
if (start < 1) start = 1;
return mid(sin, start, stop - start + 1);
} /* seg */
/* Extract sin from character position start for length len */
vstring mid(vstring sin, long start, long length)
{
vstring sout;
if (start < 1) start = 1;
if (length < 0) length = 0;
sout=tempAlloc(length + 1);
strncpy(sout,sin + start - 1, (size_t)length);
/*E*/ /*??? Should db be subtracted from if length > end of string? */
sout[length] = 0;
return (sout);
} /* mid */
/* Extract leftmost n characters */
vstring left(vstring sin,long n)
{
return mid(sin, 1, n);
} /* left */
/* Extract after character n */
vstring right(vstring sin, long n)
{
return seg(sin, n, (long)(strlen(sin)));
} /* right */
/* Emulate VMS BASIC edit$ command */
vstring edit(vstring sin,long control)
#define isblank_(c) ((c == ' ') || (c == '\t'))
/* 11-Sep-2009 nm Added _ to fix '"isblank" redefined' compiler warning */
#define isblankorlf_(c) ((c == ' ') || (c == '\t') || (c == '\n'))
/* 8-May-2015 nm added isblankorlf_ */
{
/* EDIT$ (from VMS BASIC manual)
Syntax: str-vbl = EDIT$(str-exp, int-exp)
Values Effect
1 Trim parity bits
2 Discard all spaces and tabs
4 Discard characters: CR, LF, FF, ESC, RUBOUT, and NULL
8 Discard leading spaces and tabs
16 Reduce spaces and tabs to one space
32 Convert lowercase to uppercase
64 Convert [ to ( and ] to )
128 Discard trailing spaces and tabs
256 Do not alter characters inside quotes
(non-BASIC extensions)
512 Convert uppercase to lowercase
1024 Tab the line (convert spaces to equivalent tabs)
2048 Untab the line (convert tabs to equivalent spaces)
4096 Convert VT220 screen print frame graphics to -,|,+ characters
(Added 10/24/03:)
8192 Discard CR only (to assist DOS-to-Unix conversion)
(Added 8-May-2015 nm:)
16384 Discard trailing spaces, tabs, and LFs
*/
vstring sout;
long i, j, k, m;
int last_char_is_blank;
int trim_flag, discardctrl_flag, bracket_flag, quote_flag, case_flag;
int alldiscard_flag, leaddiscard_flag, traildiscard_flag,
traildiscardLF_flag, reduce_flag;
int processing_inside_quote=0;
int lowercase_flag, tab_flag, untab_flag, screen_flag, discardcr_flag;
unsigned char graphicsChar;
/* Set up the flags */
trim_flag = control & 1;
alldiscard_flag = control & 2;
discardctrl_flag = control & 4;
leaddiscard_flag = control & 8;
reduce_flag = control & 16;
case_flag = control & 32;
bracket_flag = control & 64;
traildiscard_flag = control & 128;
traildiscardLF_flag = control & 16384;
quote_flag = control & 256;
/* Non-BASIC extensions */
lowercase_flag = control & 512;
tab_flag = control & 1024;
untab_flag = control & 2048;
screen_flag = control & 4096; /* Convert VT220 screen prints to |,-,+
format */
discardcr_flag = control & 8192; /* Discard CR's */
/* Copy string */
i = (long)strlen(sin) + 1;
if (untab_flag) i = i * 7; /* Allow for max possible length */
sout=tempAlloc(i);
strcpy(sout,sin);
/* Discard leading space/tab */
i=0;
if (leaddiscard_flag)
while ((sout[i] != 0) && isblank_(sout[i]))
sout[i++] = 0;
/* Main processing loop */
while (sout[i] != 0) {
/* Alter characters inside quotes ? */
if (quote_flag && ((sout[i] == '"') || (sout[i] == '\'')))
processing_inside_quote = ~ processing_inside_quote;
if (processing_inside_quote) {
/* Skip the rest of the code and continue to process next character */
i++; continue;
}
/* Discard all space/tab */
if ((alldiscard_flag) && isblank_(sout[i]))
sout[i] = 0;
/* Trim parity (eighth?) bit */
if (trim_flag)
sout[i] = sout[i] & 0x7F;
/* Discard CR,LF,FF,ESC,BS */
if ((discardctrl_flag) && (
(sout[i] == '\015') || /* CR */
(sout[i] == '\012') || /* LF */
(sout[i] == '\014') || /* FF */
(sout[i] == '\033') || /* ESC */
/*(sout[i] == '\032') ||*/ /* ^Z */ /* DIFFERENCE won't work w/ this */
(sout[i] == '\010'))) /* BS */
sout[i] = 0;
/* Discard CR */
if ((discardcr_flag) && (
(sout[i] == '\015'))) /* CR */
sout[i] = 0;
/* Convert lowercase to uppercase */
/*
if ((case_flag) && (islower(sout[i])))
sout[i] = toupper(sout[i]);
*/
/* 13-Jun-2009 nm The upper/lower case C functions have odd behavior
with characters > 127, at least in lcc. So this was rewritten to
not use them. */
if ((case_flag) && (sout[i] >= 'a' && sout[i] <= 'z'))
sout[i] = (char)(sout[i] - ('a' - 'A'));
/* Convert [] to () */
if ((bracket_flag) && (sout[i] == '['))
sout[i] = '(';
if ((bracket_flag) && (sout[i] == ']'))
sout[i] = ')';
/* Convert uppercase to lowercase */
/*
if ((lowercase_flag) && (isupper(sout[i])))
sout[i] = tolower(sout[i]);
*/
/* 13-Jun-2009 nm The upper/lower case C functions have odd behavior
with characters > 127, at least in lcc. So this was rewritten to
not use them. */
if ((lowercase_flag) && (sout[i] >= 'A' && sout[i] <= 'Z'))
sout[i] = (char)(sout[i] + ('a' - 'A'));
/* Convert VT220 screen print frame graphics to +,|,- */
if (screen_flag) {
graphicsChar = (unsigned char)sout[i]; /* Need unsigned char for >127 */
/* vt220 */
if (graphicsChar >= 234 && graphicsChar <= 237) sout[i] = '+';
if (graphicsChar == 241) sout[i] = '-';
if (graphicsChar == 248) sout[i] = '|';
if (graphicsChar == 166) sout[i] = '|';
/* vt100 */
if (graphicsChar == 218 /*up left*/ || graphicsChar == 217 /*lo r*/
|| graphicsChar == 191 /*up r*/ || graphicsChar == 192 /*lo l*/)
sout[i] = '+';
if (graphicsChar == 196) sout[i] = '-';
if (graphicsChar == 179) sout[i] = '|';
}
/* Process next character */
i++;
}
/* sout[i]=0 is the last character at this point */
/* Clean up the deleted characters */
for (j = 0, k = 0; j <= i; j++)
if (sout[j]!=0) sout[k++]=sout[j];
sout[k] = 0;
/* sout[k] = 0 is the last character at this point */
/* Discard trailing space/tab */
if (traildiscard_flag) {
--k;
while ((k >= 0) && isblank_(sout[k])) --k;
sout[++k] = 0;
}
/* 8-May-2015 nm */
/* Discard trailing space/tab and LF */
if (traildiscardLF_flag) {
--k;
while ((k >= 0) && isblankorlf_(sout[k])) --k;
sout[++k] = 0;
}
/* Reduce multiple space/tab to a single space */
if (reduce_flag) {
i = j = last_char_is_blank = 0;
while (i <= k - 1) {
if (!isblank_(sout[i])) {
sout[j++] = sout[i++];
last_char_is_blank = 0;
} else {
if (!last_char_is_blank)
sout[j++]=' '; /* Insert a space at the first occurrence of a blank */
last_char_is_blank = 1; /* Register that a blank is found */
i++; /* Process next character */
}
}
sout[j] = 0;
}
/* Untab the line */
if (untab_flag || tab_flag) {
/*
DEF FNUNTAB$(L$) ! UNTAB LINE L$
I9%=1%
I9%=INSTR(I9%,L$,CHR$(9%))
WHILE I9%
L$=LEFT(L$,I9%-1%)+SPACE$(8%-((I9%-1%) AND 7%))+RIGHT(L$,I9%+1%)
I9%=INSTR(I9%,L$,CHR$(9%))
NEXT
FNUNTAB$=L$
FNEND
*/
/***** old code (doesn't handle multiple lines)
k = (long)strlen(sout);
for (i = 1; i <= k; i++) {
if (sout[i - 1] != '\t') continue;
for (j = k; j >= i; j--) {
sout[j + 8 - ((i - 1) & 7) - 1] = sout[j];
}
for (j = i; j < i + 8 - ((i - 1) & 7); j++) {
sout[j - 1] = ' ';
}
k = k + 8 - ((i - 1) & 7);
}
*****/
/* Untab string containing multiple lines */ /* 9-Jul-2011 nm */
/* (Currently this is needed by outputStatement() in mmpars.c) */
k = (long)strlen(sout);
m = 0; /* Position on line relative to last '\n' */
for (i = 1; i <= k; i++) {
if (sout[i - 1] == '\n') {
m = 0;
continue;
}
m++; /* Should equal i for one-line string */
if (sout[i - 1] != '\t') continue;
for (j = k; j >= i; j--) {
sout[j + 8 - ((m - 1) & 7) - 1] = sout[j];
}
for (j = i; j < i + 8 - ((m - 1) & 7); j++) {
sout[j - 1] = ' ';
}
k = k + 8 - ((m - 1) & 7);
}
}
/* Tab the line */
/* (Note that this does not [yet?] handle string with multiple lines) */
if (tab_flag) {
/*
DEF FNTAB$(L$) ! TAB LINE L$
I9%=0%
FOR I9%=8% STEP 8% WHILE I9%<LEN(L$)
J9%=I9%
J9%=J9%-1% UNTIL ASCII(MID(L$,J9%,1%))<>32% OR J9%=I9%-8%
IF J9%<=I9%-2% THEN
L$=LEFT(L$,J9%)+CHR$(9%)+RIGHT(L$,I9%+1%)
I9%=J9%+1%
END IF
NEXT I9%
FNTAB$=L$
FNEND
*/
k = (long)strlen(sout);
for (i = 8; i < k; i = i + 8) {
j = i;
/* 25-May-2016 nm */
/* gcc m*.c -o metamath.exe -O2 -Wall was giving:
mmvstr.c:285:9: warning: assuming signed overflow does not occur
when assuming that (X - c) <= X is always true [-Wstrict-overflow]
Here we trick gcc into turning off this optimization by moving
the computation of i - 2 here, then referencing m instead of i - 2
below. Note that if "m = i - 2" is moved _after_ the "while", the
error message returns. */
m = i - 2;
while (sout[j - 1] == ' ' && j > i - 8) j--;
/*if (j <= i - 2) {*/
if (j <= m) { /* 25-May-2016 nm */
sout[j] = '\t';
j = i;
while (sout[j - 1] == ' ' && j > i - 8 + 1) {
sout[j - 1] = 0;
j--;
}
}
}
i = k;
/* sout[i]=0 is the last character at this point */
/* Clean up the deleted characters */
for (j = 0, k = 0; j <= i; j++)
if (sout[j] != 0) sout[k++] = sout[j];
sout[k] = 0;
/* sout[k] = 0 is the last character at this point */
}
return (sout);
} /* edit */
/* Return a string of the same character */
vstring string(long n, char c)
{
vstring sout;
long j = 0;
if (n < 0) n = 0;
sout=tempAlloc(n + 1);
while (j < n) sout[j++] = c;
sout[j] = 0;
return (sout);
} /* string */
/* Return a string of spaces */
vstring space(long n)
{
return (string(n, ' '));
} /* space */
/* Return a character given its ASCII value */
vstring chr(long n)
{
vstring sout;
sout = tempAlloc(2);
sout[0] = (char)(n & 0xFF);
sout[1] = 0;
return(sout);
} /* chr */
/* Search for string2 in string1 starting at start_position */
/* If there is no match, 0 is returned */
/* If string2 is "", (length of the string) + 1 is returned */
long instr(long start_position, vstring string1, vstring string2)
{
char *sp1, *sp2;
long ls1, ls2;
long found = 0;
if (start_position < 1) start_position = 1;
ls1 = (long)strlen(string1);
ls2 = (long)strlen(string2);
if (start_position > ls1) start_position = ls1 + 1;
sp1 = string1 + start_position - 1;
while ((sp2 = strchr(sp1, string2[0])) != 0) {
if (strncmp(sp2, string2, (size_t)ls2) == 0) {
found = sp2 - string1 + 1;
break;
} else
sp1 = sp2 + 1;
}
return (found);
} /* instr */
/* 12-Jun-2011 nm Added rinstr */
/* Search for _last_ occurrence of string2 in string1 */
/* 1 = 1st string character; 0 = not found */
/* ??? Future - this could be made more efficient by searching directly,
backwards from end of string1 */
long rinstr(vstring string1, vstring string2)
{
long pos = 0;
long savePos = 0;
while (1) { /* Scan until substring no longer found */
pos = instr(pos + 1, string1, string2);
if (!pos) break;
savePos = pos;
}
return (savePos);
} /* rinstr */
/* Translate string in sin to sout based on table.
Table must be 256 characters long!! <- not true anymore? */
vstring xlate(vstring sin,vstring table)
{
vstring sout;
long len_table, len_sin;
long i, j;
long table_entry;
char m;
len_sin = (long)strlen(sin);
len_table = (long)strlen(table);
sout = tempAlloc(len_sin+1);
for (i = j = 0; i < len_sin; i++)
{
table_entry = 0x000000FF & (long)sin[i];
if (table_entry < len_table)
if ((m = table[table_entry])!='\0')
sout[j++] = m;
}
sout[j]='\0';
return (sout);
} /* xlate */
/* Returns the ascii value of a character */
long ascii_(vstring c)
{
return ((long)c[0]);
} /* ascii_ */
/* Returns the floating-point value of a numeric string */
double val(vstring s)
{
double v = 0;
char signFound = 0;
double power = 1.0;
long i;
for (i = (long)strlen(s); i >= 0; i--) {
switch (s[i]) {
case '.':
v = v / power;
power = 1.0;
break;
case '-':
signFound = 1;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
v = v + ((double)(s[i] - '0')) * power;
power = 10.0 * power;
break;
}
}
if (signFound) v = - v;
return v;
/*
return (atof(s));
*/
} /* val */
/* Returns current date as an ASCII string */
vstring date()
{
vstring sout;
struct tm *time_structure;
time_t time_val;
char *month[12];
/* (Aggregrate initialization is not portable) */
/* (It must be done explicitly for portability) */
month[0] = "Jan";
month[1] = "Feb";
month[2] = "Mar";
month[3] = "Apr";
month[4] = "May";
month[5] = "Jun";
month[6] = "Jul";
month[7] = "Aug";
month[8] = "Sep";
month[9] = "Oct";
month[10] = "Nov";
month[11] = "Dec";
time(&time_val); /* Retrieve time */
time_structure = localtime(&time_val); /* Translate to time structure */
sout = tempAlloc(15); /* 8-Mar-2019 nm Changed from 12 to 15 to prevent
gcc 8.3 warning (patch provided by David Starner) */
/* "%02d" means leading zeros with min. field width of 2 */
/* sprintf(sout,"%d-%s-%02d", */
sprintf(sout,"%d-%s-%04d", /* 10-Apr-06 nm 4-digit year */
time_structure->tm_mday,
month[time_structure->tm_mon],
/* time_structure->tm_year); */ /* old */
/* (int)((time_structure->tm_year) % 100)); */ /* Y2K */
(int)((time_structure->tm_year) + 1900)); /* 10-Apr-06 nm 4-digit yr */
return(sout);
} /* date */
/* Return current time as an ASCII string */
vstring time_()
{
vstring sout;
struct tm *time_structure;
time_t time_val;
int i;
char *format;
char *format1 = "%d:%d %s";
char *format2 = "%d:0%d %s";
char *am_pm[2];
/* (Aggregrate initialization is not portable) */
/* (It must be done explicitly for portability) */
am_pm[0] = "AM";
am_pm[1] = "PM";
time(&time_val); /* Retrieve time */
time_structure = localtime(&time_val); /* Translate to time structure */
if (time_structure->tm_hour >= 12)
i = 1;
else
i = 0;
if (time_structure->tm_hour > 12)
time_structure->tm_hour -= 12;
if (time_structure->tm_hour == 0)
time_structure->tm_hour = 12;
sout = tempAlloc(12);
if (time_structure->tm_min >= 10)
format = format1;
else
format = format2;
sprintf(sout,format,
time_structure->tm_hour,
time_structure->tm_min,
am_pm[i]);
return(sout);
} /* time */
/* Return a number as an ASCII string */
vstring str(double f)
{
/* This function converts a floating point number to a string in the */
/* same way that %f in printf does, except that trailing zeroes after */
/* the one after the decimal point are stripped; e.g., it returns 7 */
/* instead of 7.000000000000000. */
vstring s;
long i;
s = tempAlloc(50);
sprintf(s,"%f", f);
if (strchr(s, '.') != 0) { /* The string has a period in it */
for (i = (long)strlen(s) - 1; i > 0; i--) { /* Scan string backwards */
if (s[i] != '0') break; /* 1st non-zero digit */
s[i] = 0; /* Delete the trailing 0 */
}
if (s[i] == '.') s[i] = 0; /* Delete trailing period */
/*E*/INCDB1(-(49 - (long)strlen(s)));
}
return (s);
} /* str */
/* Return a number as an ASCII string */
/* (This may have differed slightly from str() in BASIC but I forgot how.
It should be considered deprecated.) */
vstring num1(double f)
{
return (str(f));
} /* num1 */
/* Return a number as an ASCII string surrounded by spaces */
/* (This should be considered deprecated.) */
vstring num(double f)
{
return (cat(" ",str(f)," ",NULL));
} /* num */
/*** NEW FUNCTIONS ADDED 11/25/98 ***/
/* Emulate PROGRESS "entry" and related string functions */
/* (PROGRESS is a 4-GL database language) */
/* A "list" is a string of comma-separated elements. Example:
"a,b,c" has 3 elements. "a,b,c," has 4 elements; the last element is
an empty string. ",," has 3 elements; each is an empty string.
In "a,b,c", the entry numbers of the elements are 1, 2 and 3 (i.e.
the entry numbers start a 1, not 0). */
/* Returns a character string entry from a comma-separated
list based on an integer position. */
/* If element is less than 1 or greater than number of elements
in the list, a null string is returned. */
vstring entry(long element, vstring list)
{
vstring sout;
long commaCount, lastComma, i, length;
if (element < 1) return ("");
lastComma = -1;
commaCount = 0;
i = 0;
while (list[i] != 0) {
if (list[i] == ',') {
commaCount++;
if (commaCount == element) {
break;
}
lastComma = i;
}
i++;
}
if (list[i] == 0) commaCount++;
if (element > commaCount) return ("");
length = i - lastComma - 1;
if (length < 1) return ("");
sout = tempAlloc(length + 1);
strncpy(sout, list + lastComma + 1, (size_t)length);
sout[length] = 0;
return (sout);
}
/* Emulate PROGRESS lookup function */
/* Returns an integer giving the first position of an expression
in a comma-separated list. Returns a 0 if the expression
is not in the list. */
long lookup(vstring expression, vstring list)
{
long i, exprNum, exprPos;
char match;
match = 1;
i = 0;
exprNum = 0;
exprPos = 0;
while (list[i] != 0) {
if (list[i] == ',') {
exprNum++;
if (match) {
if (expression[exprPos] == 0) return exprNum;
}
exprPos = 0;
match = 1;
i++;
continue;
}
if (match) {
if (expression[exprPos] != list[i]) match = 0;
}
i++;
exprPos++;
}
exprNum++;
if (match) {
if (expression[exprPos] == 0) return exprNum;
}
return 0;
}
/* Emulate PROGRESS num-entries function */
/* Returns the number of items in a comma-separated list. If the
list is the empty string, return 0. */
long numEntries(vstring list)
{
long i, commaCount;
if (list[0] == 0) {
commaCount = -1; /* 26-Apr-2006 nm Return 0 if list empty */
} else {
commaCount = 0;
i = 0;
while (list[i] != 0) {
if (list[i] == ',') commaCount++;
i++;
}
}
return (commaCount + 1);
}
/* Returns the character position of the start of the
element in a list - useful for manipulating
the list string directly. 1 means the first string
character. */
/* If element is less than 1 or greater than number of elements
in the list, a 0 is returned. If entry is null, a 0 is
returned. */
long entryPosition(long element, vstring list)
{
long commaCount, lastComma, i;
if (element < 1) return 0;
lastComma = -1;
commaCount = 0;
i = 0;
while (list[i] != 0) {
if (list[i] == ',') {
commaCount++;
if (commaCount == element) {
break;
}
lastComma = i;
}
i++;
}
if (list[i] == 0) {
if (i == 0) return 0;
if (list[i - 1] == ',') return 0;
commaCount++;
}
if (element > commaCount) return (0);
if (list[lastComma + 1] == ',') return 0;
return (lastComma + 2);
}
/* For debugging */
/*
int main(void)
{
vstringdef(s);
vstringdef(t);
printf("Hello\n");
let(&t,edit(" x y z ",2));
let(&s,cat(right("abc",2),left("def",len(right("xxx",2))),"ghi",t,NULL));
printf("%s\n",s);
printf("num %s\n",num(5));
printf("str %s\n",str(5.02));
printf("num1 %s\n",num1(5.02));
printf("time_ %s\n",time_());
printf("date %s\n",date());
printf("val %f\n",val("6.77"));
}
*/

199
mmvstr.h Normal file
View File

@ -0,0 +1,199 @@
/*****************************************************************************/
/* Copyright (C) 2011 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
/*
mmvstr.h - VMS-BASIC variable length string library routines header
This is an emulation of the string functions available in VMS BASIC.
*/
/******************************************************************************
Variable-length string handler
------------------------------
This collection of string-handling functions emulate most of the
string functions of VMS BASIC. The objects manipulated by these
functions are strings of a special type called 'vstring' which have no
pre-defined upper length limit but are dynamically allocated and
deallocated as needed. To use the vstring functions within a program,
all vstrings must be initially set to the null string when declared or
before first used, for example:
vstring string1 = "";
vstring stringArray[] = {"", "", ""};
vstring bigArray[100][10]; /- Must be initialized before using -/
int i, j;
for (i = 0; i < 100; i++)
for (j = 0; j < 10; j++)
bigArray[i][j] = ""; /- Initialize -/
After initialization, vstrings should be assigned with the 'let(&'
function only; for example the statements
let(&string1, "abc");
let(&string1, string2);
let(&string1, left(string2, 3));
all assign the second argument to 'string1'. The 'let(&' function must
_not_ be used to initialize a vstring the first time.
Any local vstrings in a function must be deallocated before returning
from the function, otherwise there will be memory leakage and eventual
memory overflow. To deallocate, assign the vstring to "" with 'let(&':
void abc(void) {
vstring xyz = "";
...
let(&xyz, "");
}
The 'cat' function emulates the '+' concatenation operator in BASIC.
It has a variable number of arguments, and the last argument should always
be NULL. For example,
let(&string1,cat("abc","def",NULL));
assigns "abcdef" to 'string1'. Warning: 0 will work instead of NULL on the
VAX but not on the Macintosh, so always use NULL.
All other functions are generally used exactly like their BASIC
equivalents. For example, the BASIC statement
let string1$=left$("def",len(right$("xxx",2)))+"ghi"+string2$
is emulated in c as
let(&string1,cat(left("def",len(right("xxx",2))),"ghi",string2,NULL));
Note that ANSII c does not allow "$" as part of an identifier
name, so the names in c have had the "$" suffix removed.
The string arguments of the vstring functions may be either standard c
strings or vstrings (except that the first argument of the 'let(&' function
must be a vstring). The standard c string functions may use vstrings or
vstring functions as their string arguments, as long as the vstring variable
itself (which is a char * pointer) is not modified and no attempt is made to
increase the length of a vstring. Caution must be excercised when
assigning standard c string pointers to vstrings or the results of
vstring functions, as the memory space may be deallocated when the
'let(&' function is next executed. For example,
char *stdstr; /- A standard c string pointer -/
...
stdstr=left("abc",2);
will assign "ab" to 'stdstr', but this assignment will be lost when the
next 'let(&' function is executed. To be safe, use 'strcpy':
char stdstr1[80]; /- A fixed length standard c string -/
...
strcpy(stdstr1,left("abc",2));
Here, of course, the user must ensure that the string copied to 'stdstr1'
does not exceed 79 characters in length.
The vstring functions allocate temporary memory whenever they are called.
This temporary memory is deallocated whenever a 'let(&' assignment is
made. The user should be aware of this when using vstring functions
outside of 'let(&' assignments; for example
for (i=0; i<10000; i++)
print2("%s\n",left(string1,70));
will allocate another 70 bytes or so of memory each pass through the loop.
If necessary, dummy 'let(&' assignments can be made periodically to clear
this temporary memory:
for (i=0; i<10000; i++)
{
print2("%s\n",left(string1,70));
let(&dummy,"");
}
It should be noted that the 'linput' function assigns its target string
with 'let(&' and thus has the same effect as 'let(&'.
******************************************************************************/
#ifndef METAMATH_MMVSTR_H_
#define METAMATH_MMVSTR_H_
typedef char* vstring;
#define vstringdef(x) vstring x = ""
/* Emulation of BASIC string assignment */
/* 'let' MUST be used to assign vstrings, e.g. 'let(&abc, "Hello"); */
/* Empty string deallocates memory, e.g. 'let(&abc, ""); */
void let(vstring *target, vstring source);
/* Emulation of BASIC string concatenation - last argument MUST be NULL */
/* vstring cat(vstring string1, ..., stringN, NULL); */
/* e.g. 'let(&abc, cat("Hello", " ", left("worldx", 5), "!", NULL);' */
vstring cat(vstring string1,...);
/* Emulation of BASIC linput (line input) statement; returns NULL if EOF */
/* Note that linput assigns target string with let(&target,...) */
/*
BASIC: linput "what";a$
c: linput(NULL,"what?",&a);
BASIC: linput #1,a$ (error trap on EOF)
c: if (!linput(file1,NULL,&a)) break; (break on EOF)
*/
/* returns whether a (possibly empty) line was successfully read */
int linput(FILE *stream,const char* ask,vstring *target);
/* Emulation of BASIC string functions */
/* Indices are 1-based */
vstring seg(vstring sin, long p1, long p2);
vstring mid(vstring sin, long p, long l);
vstring left(vstring sin, long n);
vstring right(vstring sin, long n);
vstring edit(vstring sin, long control);
vstring space(long n);
vstring string(long n, char c);
vstring chr(long n);
vstring xlate(vstring sin, vstring control);
vstring date(void);
vstring time_(void);
vstring num(double x);
vstring num1(double x);
vstring str(double x);
long len(vstring s);
long instr(long start, vstring sin, vstring s);
long rinstr(vstring string1, vstring string2);
long ascii_(vstring c);
double val(vstring s);
/* Emulation of Progress 4GL string functions, added 11/25/98 */
vstring entry(long element, vstring list);
long lookup(vstring expression, vstring list);
long numEntries(vstring list);
long entryPosition(long element, vstring list);
/* Routines may/may not be written (lowest priority):
vstring place$(vstring sout);
vstring prod$(vstring sout);
vstring quo$(vstring sout);
*/
/******* Special purpose routines for better
memory allocation (use with caution) *******/
extern long g_tempAllocStackTop; /* Top of stack for tempAlloc functon */
extern long g_startTempAllocStack; /* Where to start freeing temporary allocation
when let() is called (normally 0, except for nested vstring functions) */
/* Make string have temporary allocation to be released by next let() */
/* Warning: after makeTempAlloc() is called, the vstring may NOT be
assigned again with let() */
void makeTempAlloc(vstring s); /* Make string have temporary allocation to be
released by next let() */
#endif /* METAMATH_MMVSTR_H_ */

612
mmword.c Normal file
View File

@ -0,0 +1,612 @@
/*****************************************************************************/
/* Copyright (C) 2012 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
/* This file implements the UPDATE command of the TOOLS utility. revise() is
the main external call; see the comments preceding it. */
/* The UPDATE command of TOOLS (mmword.c) was custom-written in accordance
with the version control requirements of a company that used it. It
documents the differences between two versions of a program as C-style
comments embedded in the newer version. The best way to determine whether
it suits your similar needs is just to run it and look at its output. */
/* Very old history: this was called mmword.c because it was intended to
produce RTF output for Word, analogous to the existing LaTeX output.
Microsoft never responded to a request for the RTF specification, as they
promised in the circa 1990 manual accompanying Word. Thus it remained an
empty shell. When the need for UPDATE arose, the mmword.c shell was used in
order to avoid the nuisance of changing some compilation setups and scripts
existing at that time. */
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <setjmp.h>
#include "mmvstr.h"
#include "mmdata.h"
#include "mminou.h"
#include "mmword.h"
/* Set to 79, 80, etc. - length of line after tag is added */
#define LINE_LENGTH 80
/* 7000 ! ***** "DIFF" Option ***** from DO LIST */
/* gosub_7000(f1_name, f2_name, f3_name, &f3_fp, m); */
char strcmpe(vstring s1, vstring s2);
vstring stripAndTag(vstring line, vstring tag, flag tagBlankLines);
long r0,r1,r2,i0,i1_,i2_,d,t,i9;
FILE *f1_fp_;
FILE *f2_fp_;
FILE *f3_fp_;
char eof1, eof2;
vstring ctlz_ = "";
vstring l1_ = "";
vstring l2_ = "";
vstring tmp_ = "";
vstring tmpLine = "";
vstring addTag_ = "";
vstring delStartTag_ = "";
vstring delEndTag_ = "";
flag printedAtLeastOne;
/* Declare input and save buffers */
#define MAX_LINES 10000
#define MAX_BUF 1000
vstring line1_[MAX_LINES];
vstring line2_[MAX_LINES];
vstring reserve1_[MAX_BUF];
vstring reserve2_[MAX_BUF];
/* revise() is called by the UPDATE command of TOOLs. The idea is to
keep all past history of a file in the file itself, in the form of
comments. In mmcmds.c, see the parsing of the UPDATE command for a
partial explanation of its arguments. UPDATE was written for a
proprietary language with C-style comments (where nested comments were
allowed) and it may not be generally useful without some modification. */
void revise(FILE *f1_fp, FILE *f2_fp, FILE *f3_fp, vstring addTag, long m)
{
/******** Figure out the differences (DO LIST subroutine) ******/
vstring blanksPrefix = "";
long tmpi;
long i, j;
f1_fp_ = f1_fp;
f2_fp_ = f2_fp;
f3_fp_ = f3_fp;
let(&addTag_, addTag);
let(&delStartTag_, "/******* Start of deleted section *******");
let(&delEndTag_, "******* End of deleted section *******/");
/* Initialize vstring arrays */
for (i = 0; i < MAX_LINES; i++) {
line1_[i] = "";
line2_[i] = "";
}
for (i = 0; i < MAX_BUF; i++) {
reserve1_[i] = "";
reserve2_[i] = "";
}
if (m < 1) m = 1;
r0=r1=r2=i0=i1_=i2_=d=t=i=j=i9=0;
let(&ctlz_,chr(26)); /* End-of-file character */
let(&l1_,ctlz_);
let(&l2_,ctlz_);
eof1=eof2=0; /* End-of-file flags */
d=0;
l7100: /*
Lines 7100 through 7300 are a modified version of the compare loop
In DEC's FILCOM.BAS program.
*/
if (!strcmpe(l1_,l2_)) { /* The lines are the same */
if (strcmpe(l2_,ctlz_)) {
fprintf(f3_fp_, "%s\n", l2_); /* Use edited version
of line when they are the same */
}
gosub_7320();
gosub_7330();
if (strcmpe(l1_,ctlz_) || strcmpe(l2_,ctlz_) ) {
goto l7100;
} else {
fclose(f1_fp_);
fclose(f2_fp_);
fclose(f3_fp_);
/* Deallocate string memory */
for (i = 0; i < MAX_LINES; i++) {
let(&(line1_[i]), "");
let(&(line2_[i]), "");
}
for (i = 0; i < MAX_BUF; i++) {
let(&(reserve1_[i]), "");
let(&(reserve2_[i]), "");
}
let(&ctlz_, "");
let(&l1_, "");
let(&l2_, "");
let(&tmp_, "");
let(&tmpLine, "");
let(&addTag_, "");
let(&delStartTag_, "");
let(&delEndTag_, "");
let(&blanksPrefix, "");
return;
}
}
d=d+1; /* Number of difference sections found so far
(For user information only) */
i1_=i2_=m-1;
let(&line1_[0],l1_);
let(&line2_[0],l2_);
for (i0 = 1; i0 < m; i0++) {
gosub_7320();
let(&line1_[i0],l1_);
}
for (i0 = 1; i0 < m; i0++) {
gosub_7330();
let(&line2_[i0],l2_);
}
l7130: gosub_7320();
i1_=i1_+1;
if (i1_ >= MAX_LINES) {
printf("*** FATAL *** Overflow#1\n");
#if __STDC__
fflush(stdout);
#endif
exit(0);
}
let(&line1_[i1_],l1_);
t=0;
i=0;
l7140: if (strcmpe(line1_[i1_+t-m+1], line2_[i+t])) {
t=0;
} else {
/* If lines "match", ensure we use the EDITED version for the
final output */
let(&line1_[i1_+t-m+1], line2_[i+t]);
t=t+1;
if (t==m) {
goto l7200;
} else {
goto l7140;
}
}
i=i+1;
if (i<=i2_-m+1) {
goto l7140;
}
gosub_7330();
i2_=i2_+1;
if (i2_ >= MAX_LINES) {
printf("*** FATAL *** Overflow#2\n");
#if __STDC__
fflush(stdout);
#endif
exit(0);
}
let(&line2_[i2_],l2_);
t=0;
i=0;
l7170:
if (strcmpe(line1_[i+t], line2_[i2_+t-m+1])) {
t=0;
} else {
/* If lines "match", ensure we use the EDITED version for the
final output */
let(&line1_[i+t], line2_[i2_+t-m+1]);
t=t+1;
if (t==m) {
goto l7220;
} else {
goto l7170;
}
}
i=i+1;
if (i<=i1_-m+1) {
goto l7170;
}
goto l7130;
l7200: i=i+m-1;
if (r2) {
for (j=r2-1; j>=0; j--) {
let(&reserve2_[j+i2_-i],reserve2_[j]);
}
}
for (j=1; j<=i2_-i; j++) {
let(&reserve2_[j-1],line2_[j+i]);
}
r2=r2+i2_-i;
if (r2 >= MAX_BUF) {
printf("*** FATAL *** Overflow#3\n");
#if __STDC__
fflush(stdout);
#endif
exit(0);
}
i2_=i;
goto l7240;
l7220: i=i+m-1;
if (r1) {
for (j=r1-1; j>=0; j--) {
let(&reserve1_[j+i1_-i],reserve1_[j]);
}
}
for (j=1; j<=i1_-i; j++) {
let(&reserve1_[j-1],line1_[j+i]);
}
r1=r1+i1_-i;
if (r1 >= MAX_BUF) {
printf("*** FATAL *** Overflow#4\n");
#if __STDC__
fflush(stdout);
#endif
exit(0);
}
i1_=i;
goto l7240;
l7240: /* */
printedAtLeastOne = 0;
for (i=0; i<=i1_-m; i++) {
if (strcmpe(line1_[i],ctlz_)) {
if (!printedAtLeastOne) {
printedAtLeastOne = 1;
/* Put out any blank lines before delStartTag_ */
while (((vstring)(line1_[i]))[0] == '\n') {
fprintf(f3_fp_, "\n");
let(&(line1_[i]), right(line1_[i], 2));
}
/* Find the beginning blank space */
tmpi = 0;
while (((vstring)(line1_[i]))[tmpi] == ' ') tmpi++;
let(&blanksPrefix, space(tmpi));
let(&tmpLine, "");
tmpLine = stripAndTag(cat(blanksPrefix, delStartTag_, NULL),
addTag_, 0);
fprintf(f3_fp_, "%s\n", tmpLine);
}
fprintf(f3_fp_, "%s\n", line1_[i]);
/* Output original deleted lines */
/*let(&tmp_, "");*/ /* Clear vstring stack */
}
}
if (printedAtLeastOne) {
let(&tmpLine, "");
tmpLine = stripAndTag(cat(blanksPrefix, delEndTag_, NULL), addTag_
,0);
fprintf(f3_fp_, "%s\n", tmpLine);
}
for (i=0; i<=i1_-m; i++) {
if (i<=i2_-m) {
if (strcmpe(line2_[i],ctlz_)) {
let(&tmpLine, "");
if (i == 0) {
tmpLine = stripAndTag(line2_[i], addTag_, 0);
} else {
/* Put tags on blank lines *inside* of new section */
tmpLine = stripAndTag(line2_[i], addTag_, 1);
}
fprintf(f3_fp_, "%s\n", tmpLine);
/* Output tagged edited lines */
/*let(&tmp_, "");*/ /* Clear vstring stack */
}
}
}
for (i=i1_-m+1; i<=i2_-m; i++) {
if (strcmpe(line2_[i],ctlz_)) {
let(&tmpLine, "");
if (i == 0) {
tmpLine = stripAndTag(line2_[i], addTag_, 0);
} else {
/* Put tags on blank lines *inside* of new section */
tmpLine = stripAndTag(line2_[i], addTag_, 1);
}
fprintf(f3_fp_, "%s\n", tmpLine);
/* Print remaining edited lines */
/*let(&tmp_, "");*/ /* Clear vstring stack */
}
}
for (i=0; i<=m-1; i++) {
let(&l1_,line1_[i1_-m+1+i]);
if (strcmpe(l1_,ctlz_)) {
fprintf(f3_fp_,"%s\n",l1_); /* Print remaining matching lines */
}
}
let(&l1_,ctlz_);
let(&l2_,ctlz_);
goto l7100;
}
void gosub_7320()
{
/* Subroutine: get next L1_ from original file */
vstring tmpLin = "";
if (r1) { /* Get next line from save array */
let(&l1_,reserve1_[0]);
r1=r1-1;
for (i9=0; i9<=r1-1; i9++) {
let(&reserve1_[i9],reserve1_[i9+1]);
}
} else { /* Get next line from input file */
if (eof1) {
let(&l1_,ctlz_);
} else {
next_l1:
if (!linput(f1_fp_,NULL,&l1_)) { /*linput returns 0 if EOF */
eof1 = 1;
/* Note that we will discard any blank lines before EOF; this
should be OK though */
let(&l1_,ctlz_);
let(&tmpLin, ""); /* Deallocate */
return;
}
let(&l1_, edit(l1_, 4 + 128 + 2048)); /* Trim garb, trail space; untab */
if (!l1_[0]) { /* Ignore blank lines for comparison */
let(&tmpLin, cat(tmpLin, "\n", NULL)); /* Blank line */
goto next_l1;
}
}
}
let(&l1_, cat(tmpLin, l1_, NULL)); /* Add any blank lines */
let(&tmpLin, ""); /* Deallocate */
return;
}
void gosub_7330() {
/* Subroutine: get next L2_ from edited file */
vstring tmpLin = "";
vstring tmpStrPtr; /* pointer only */
flag stripDeletedSectionMode;
if (r2) { /* Get next line from save array */
let(&l2_,reserve2_[0]);
r2=r2-1;
for (i9 = 0; i9 < r2; i9++) {
let(&reserve2_[i9],reserve2_[i9+1]);
}
} else { /* Get next line from input file */
if (eof2) {
let(&l2_,ctlz_);
} else {
stripDeletedSectionMode = 0;
next_l2:
if (!linput(f2_fp_,NULL,&l2_)) { /* linput returns 0 if EOF */
eof2 = 1;
/* Note that we will discard any blank lines before EOF; this
should be OK though */
let(&l2_, ctlz_);
let(&tmpLin, ""); /* Deallocate */
return;
}
let(&l2_, edit(l2_, 4 + 128 + 2048)); /* Trim garb, trail space; untab */
if (!strcmp(edit(delStartTag_, 2), left(edit(l2_, 2 + 4),
(long)strlen(edit(delStartTag_, 2))))) {
if (getRevision(l2_) == getRevision(addTag_)) {
/* We should strip out deleted section from previous run */
/* (The diff algorithm will put them back from orig. file) */
stripDeletedSectionMode = 1;
goto next_l2;
}
}
if (stripDeletedSectionMode) {
if (!strcmp(edit(delEndTag_, 2), left(edit(l2_, 2 + 4),
(long)strlen(edit(delEndTag_, 2)))) &&
getRevision(l2_) == getRevision(addTag_) ) {
stripDeletedSectionMode = 0;
}
goto next_l2;
}
/* Strip off tags that match *this* revision (so previous out-of-sync
runs will be corrected) */
if (getRevision(l2_) == getRevision(addTag_)) {
tmpStrPtr = l2_;
l2_ = stripAndTag(l2_, "", 0);
let(&tmpStrPtr, ""); /* deallocate old l2_ */
}
if (!l2_[0]) { /* Ignore blank lines for comparison */
let(&tmpLin, cat(tmpLin, "\n", NULL)); /* Blank line */
goto next_l2;
}
}
}
let(&l2_, cat(tmpLin, l2_, NULL)); /* Add any blank lines */
let(&tmpLin, ""); /* Deallocate */
return;
}
/* Return 0 if difference lines are the same, non-zero otherwise */
char strcmpe(vstring s1, vstring s2)
{
flag cmpflag;
/* Option flags - make global if we want to use them */
flag ignoreSpaces = 1;
flag ignoreSameLineComments = 1;
vstring tmps1 = "";
vstring tmps2 = "";
long i;
long i2;
long i3;
let(&tmps1, s1);
let(&tmps2, s2);
if (ignoreSpaces) {
let(&tmps1, edit(tmps1, 2 + 4));
let(&tmps2, edit(tmps2, 2 + 4));
}
if (ignoreSameLineComments) {
while (1) {
i = instr(1, tmps1, "/*");
if (i == 0) break;
i2 = instr(i + 2, tmps1, "*/");
if (i2 == 0) break;
i3 = instr(i + 2, tmps1, "/*");
if (i3 != 0 && i3 < i2) break; /*i = i3;*/ /* Nested comment */
if (i2 - i > 7) break; /* only ignore short comments (tags) */
let(&tmps1, cat(left(tmps1, i - 1), right(tmps1, i2 + 2), NULL));
}
while (1) {
i = instr(1, tmps2, "/*");
if (i == 0) break;
i2 = instr(i + 2, tmps2, "*/");
if (i2 == 0) break;
i3 = instr(i + 2, tmps2, "/*");
if (i3 != 0 && i3 < i2) break; /*i = i3;*/ /* Nested comment */
if (i2 - i > 7) break; /* only ignore short comments (tags) */
let(&tmps2, cat(left(tmps2, i - 1), right(tmps2, i2 + 2), NULL));
}
}
cmpflag = !!strcmp(tmps1, tmps2);
let(&tmps1, ""); /* Deallocate string */
let(&tmps2, ""); /* Deallocate string */
return (cmpflag);
}
/* Strip any old tag from line and put new tag on it */
/* (Caller must deallocate returned string) */
vstring stripAndTag(vstring line, vstring tag, flag tagBlankLines)
{
long i, j, k, n;
vstring line1 = "", comment = "";
long lineLength = LINE_LENGTH;
flag validTag;
i = 0;
let(&line1, edit(line, 128 + 2048)); /* Trim trailing spaces and untab */
/* Get last comment on line */
while (1) {
j = instr(i + 1, line1, "/*");
if (j == 0) break;
i = j;
}
j = instr(i, line1, "*/");
if (i && j == (signed)(strlen(line1)) - 1) {
let(&comment, seg(line1, i + 2, j - 1));
validTag = 1;
for (k = 0; k < (signed)(strlen(comment)); k++) {
/* Check for valid characters that can appear in a tag */
if (instr(1, " 1234567890#", mid(comment, k + 1, 1))) continue;
validTag = 0;
break;
}
if (validTag) let(&line1, edit(left(line1, i - 1), 128));
let(&comment, ""); /* deallocate */
}
/* Count blank lines concatenated to the beginning of this line */
n = 0;
while (line1[n] == '\n') n++;
/* Add the tag */
if (tag[0]) { /* Non-blank tag */
if ((long)strlen(line1) - n < lineLength - 1 - (long)strlen(tag))
let(&line1, cat(line1,
space(lineLength - 1 - (long)strlen(tag) - (long)strlen(line1) + n),
NULL));
let(&line1, cat(line1, " ", tag, NULL));
if ((signed)(strlen(line1)) - n > lineLength) {
print2(
"Warning: The following line has > %ld characters after tag is added:\n",
lineLength);
print2("%s\n", line1);
}
}
/* Add tags to blank lines if tagBlankLines is set */
/* (Used for blank lines inside of new edited file sections) */
if (tagBlankLines && n > 0) {
let(&line1, right(line1, n + 1));
for (i = 1; i <= n; i++) {
let(&line1, cat(space(lineLength - (long)strlen(tag)), tag, "\n",
line1, NULL));
}
}
return line1;
}
/* Get the largest revision number tag in a file */
/* Tags are assumed to be of format nn or #nn in comment at end of line */
/* Used to determine default argument for tag question */
long highestRevision(vstring fileName)
{
vstring str1 = "";
long revision;
long largest = 0;
FILE *fp;
fp = fopen(fileName, "r");
if (!fp) return 0;
while (linput(fp, NULL, &str1)) {
revision = getRevision(str1);
if (revision > largest) largest = revision;
}
let(&str1, "");
fclose(fp);
return largest;
}
/* Get numeric revision from the tag on a line (returns 0 if none) */
/* Tags are assumed to be of format nn or #nn in comment at end of line */
long getRevision(vstring line)
{
vstring str1 = "";
vstring str2 = "";
vstring tag = "";
long revision;
if (instr(1, line, "/*") == 0) return 0; /* Speedup - no comment in line */
let(&str1, edit(line, 2)); /* This line has the tag not stripped */
let(&str2, "");
str2 = stripAndTag(str1, "", 0); /* Strip old tag & add dummy new one */
let(&str2, edit(str2, 2)); /* This line has the tag stripped */
if (!strcmp(str1, str2)) {
revision = 0; /* No tag */
} else {
let(&tag, edit(seg(str1, (long)strlen(str2) + 3,
(long)strlen(str1) - 2), 2));
if (tag[0] == '#') let(&tag, right(tag, 2)); /* Remove any # */
revision = (long)(val(tag));
}
let(&tag, "");
let(&str1, "");
let(&str2, "");
return revision;
}

33
mmword.h Normal file
View File

@ -0,0 +1,33 @@
/*****************************************************************************/
/* Copyright (C) 2012 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMWORD_H_
#define METAMATH_MMWORD_H_
#include "mmvstr.h"
/* Tag file changes with revision number tags */
void revise(FILE *f1_fp, FILE *f2_fp, FILE *f3_fp, vstring addTag, long m);
/* Get the largest revision number tag in a file */
/* Tags are assumed to be of format nn or #nn in comment at end of line */
/* Used to determine default argument for tag question */
long highestRevision(vstring fileName);
/* Get numeric revision from the tag on a line (returns 0 if none) */
/* Tags are assumed to be of format nn or #nn in comment at end of line */
long getRevision(vstring line);
/* These two functions emulate 2 GOSUBs in BASIC, that are part of a
translation of a very old BASIC program (by nm) that implemented a
difference algorithm (like Unix diff). */
void gosub_7320(void);
void gosub_7330(void);
#endif /* METAMATH_MMWORD_H_ */

7004
mmwtex.c Normal file

File diff suppressed because it is too large Load Diff

244
mmwtex.h Normal file
View File

@ -0,0 +1,244 @@
/*****************************************************************************/
/* Copyright (C) 2020 NORMAN MEGILL nm at alum.mit.edu */
/* License terms: GNU General Public License */
/*****************************************************************************/
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/
#ifndef METAMATH_MMWTEX_H_
#define METAMATH_MMWTEX_H_
#include "mmvstr.h"
#include "mmdata.h"
/* Colors for HTML pages. */
#define GREEN_TITLE_COLOR "\"#006633\""
#define MINT_BACKGROUND_COLOR "\"#EEFFFA\""
#define PINK_NUMBER_COLOR "\"#FA8072\"" /* =salmon; was FF6666 */
#define PURPLISH_BIBLIO_COLOR "\"#FAEEFF\""
/* 29-Jul-2008 nm Sandbox stuff */
#define SANDBOX_COLOR "\"#FFFFD9\""
/* TeX flags */
/* 14-Sep-2010 nm Removed simpleTexFlag; added g_oldTexFlag */
extern flag g_oldTexFlag; /* Use macros in output; obsolete; take out someday */
/* HTML flags */
extern flag g_htmlFlag; /* HTML flag: 0 = TeX, 1 = HTML */
extern flag g_altHtmlFlag; /* Use "althtmldef" instead of "htmldef". This is
intended to allow the generation of pages with the old Symbol font
instead of the individual GIF files. */
extern flag g_briefHtmlFlag; /* Output statement only, for statement display
in other HTML pages, such as the Proof Explorer home page */
extern long g_extHtmlStmt; /* At this statement and above, use the exthtmlxxx
variables for title, links, etc. This was put in to allow proper
generation of the Hilbert Space Explorer extension to the set.mm
database. */
extern vstring g_extHtmlTitle; /* Title of extended section if any; set by
by exthtmltitle command in special $t comment of database source */
extern vstring g_htmlVarColor; /* Set by htmlvarcolor commands */
/* Added 26-Aug-2017 nm for use by mmcmds.c */
extern vstring g_htmlHome; /* Set by htmlhome command */
/* Added 10/13/02 for use in metamath.c bibliography cross-reference */
extern vstring g_htmlBibliography; /* Optional; set by htmlbibliography command */
extern vstring g_extHtmlBibliography; /* Optional; set by exthtmlbibliography
command */
extern vstring g_htmlCSS; /* Set by htmlcss commands */ /* 14-Jan-2016 nm */
/* Added 14-Jan-2016 */
extern vstring g_htmlFont; /* Optional; set by g_htmlFont command */
void eraseTexDefs(void); /* Undo readTexDefs() */
/* TeX/HTML/ALT_HTML word-processor-specific routines */
/* Returns 2 if there were severe parsing errors, 1 if there were warnings but
no errors, 0 if no errors or warnings */
flag readTexDefs(
flag errorsOnly, /* 1 = supprees non-error messages */
flag noGifCheck /* 1 = don't check for missing GIFs */);
extern flag g_texDefsRead;
struct texDef_struct { /* 27-Oct-2012 nm Made global for "erase" */
vstring tokenName; /* ASCII token */
vstring texEquiv; /* Converted to TeX */
};
extern struct texDef_struct *g_TexDefs; /* 27-Oct-2012 nm Now glob for "erase" */
long texDefWhiteSpaceLen(char *ptr);
long texDefTokenLen(char *ptr);
/* Token comparison for qsort */
int texSortCmp(const void *key1, const void *key2);
/* Token comparison for bsearch */
int texSrchCmp(const void *key, const void *data);
/* Convert ascii to a string of \tt tex */
/* (The caller must surround it by {\tt }) */
vstring asciiToTt(vstring s);
vstring tokenToTex(vstring mtoken, long statemNum);
/* Converts a comment section in math mode to TeX. Each math token
MUST be separated by white space. TeX "$" does not surround the output. */
vstring asciiMathToTex(vstring mathComment, long statemNum);
/* Gets the next section of a comment that is in the current mode (text,
label, or math). If 1st char. is not "$", text mode is assumed.
mode = 0 means end of comment reached. srcptr is left at 1st char.
of start of next comment section. */
vstring getCommentModeSection(vstring *srcptr, char *mode);
void printTexHeader(flag texHeaderFlag);
/* Prints an embedded comment in TeX. The commentPtr must point to the first
character after the "$(" in the comment. The printout ends when the first
"$)" or null character is encountered. commentPtr must not be a temporary
allocation. htmlCenterFlag, if 1, means to center the HTML and add a
"Description:" prefix.*/
/* void printTexComment(vstring commentPtr, char htmlCenterFlag); */
/* 17-Nov-2015 nm Added 3rd & 4th arguments; returns 1 if error/warning */
flag printTexComment(vstring commentPtr, /* Sends result to g_texFilePtr */
flag htmlCenterFlag, /* 1 = htmlCenterFlag */
long actionBits, /* see indicators below */
flag noFileCheck /* 1 = noFileCheck */);
/* Indicators for actionBits */
#define ERRORS_ONLY 1
#define PROCESS_SYMBOLS 2
#define PROCESS_LABELS 4
#define ADD_COLORED_LABEL_NUMBER 8
#define PROCESS_BIBREFS 16
#define PROCESS_UNDERSCORES 32
/* CONVERT_TO_HTML means '<' to '&lt;'; unless <HTML> in comment (and strip it) */
#define CONVERT_TO_HTML 64
/* METAMATH_COMMENT means $) (as well as end-of-string) terminates string. */
#define METAMATH_COMMENT 128
/* PROCESS_ALL is for convenience */
#define PROCESS_EVERYTHING PROCESS_SYMBOLS + PROCESS_LABELS \
+ ADD_COLORED_LABEL_NUMBER + PROCESS_BIBREFS \
+ PROCESS_UNDERSCORES + CONVERT_TO_HTML + METAMATH_COMMENT
void printTexLongMath(nmbrString *proofStep, vstring startPrefix,
vstring contPrefix, long hypStmt, long indentationLevel);
void printTexTrailer(flag texHeaderFlag);
/* Added 4-Dec-03
Function implementing WRITE THEOREM_LIST / THEOREMS_PER_PAGE nn */
void writeTheoremList(long theoremsPerPage, flag showLemmas,
flag noVersioning);
#define HUGE_DECORATION "####"
#define BIG_DECORATION "#*#*"
#define SMALL_DECORATION "=-=-"
#define TINY_DECORATION "-.-."
/* 2-Aug-2009 nm - broke this function out from writeTheoremList() */
/* 20-Jun-2014 nm - added hugeHdrAddr */
/* 21-Aug-2017 nm - added tinyHdrAddr */
/* 6-Aug-2019 nm - changed return type from void to flag (=char) */
/* 24-Aug-2020 nm - added fineResolution */
/* 12-Sep-2020 nm - added fullComment */
flag getSectionHeadings(long stmt, vstring *hugeHdrTitle,
vstring *bigHdrTitle,
vstring *smallHdrTitle,
vstring *tinyHdrTitle,
/* Added 8-May-2015 nm */
vstring *hugeHdrComment,
vstring *bigHdrComment,
vstring *smallHdrComment,
vstring *tinyHdrComment,
/* Added 24-Aug-2020 nm */
flag fineResolution, /* 0 = consider just successive $a/$p, 1 = all stmts */
flag fullComment /* 1 = put $( + header + comment + $) into xxxHdrTitle */
);
/****** 15-Aug-2020 nm Obsolete
/@ TeX symbol dictionary @/
extern FILE @g_tex_dict_fp; /@ File pointers @/
extern vstring g_tex_dict_fn; /@ File names @/
******/
/* TeX normal output */
extern flag g_texFileOpenFlag;
extern FILE *g_texFilePtr;
/* Pink statement number for HTML pages */
/* 10/10/02 (This is no longer used?) */
/*
long pinkNumber(long statemNum);
*/
/* Pink statement number HTML code for HTML pages - added 10/10/02 */
/* Warning: caller must deallocate returned string */
vstring pinkHTML(long statemNum);
/* Pink statement number range HTML code for HTML pages, separated by a
"-" - added 24-Aug-04 */
/* Warning: caller must deallocate returned string */
vstring pinkRangeHTML(long statemNum1, long statemNum2);
#define PINK_NBSP "&nbsp;" /* Either "" or "&nbsp;" depending on taste, it is
the separator between a statement href and its pink number */
/* 30-Jan-04 nm Comment out the following line to go back to the pink-only
color for the little statement numbers on the HTML pages */
#define RAINBOW_OPTION /* "Rainbow" instead of pink color for little numbers */
#ifdef RAINBOW_OPTION
/* This function converts a "spectrum" color (1 to maxColor) to an
RBG value in hex notation for HTML. The caller must deallocate the
returned vstring. color = 1 (red) to maxColor (violet). */
/* ndm 10-Jan-04 */
vstring spectrumToRGB(long color, long maxColor);
#endif
#define INDENT_HTML_PROOFS /* nm 3-Feb-04 - indentation experiment */
/* Added 20-Sep-03 (broken out of printTexLongMath() for better
modularization) */
/* Returns the HTML code for GIFs (!g_altHtmlFlag) or Unicode (g_altHtmlFlag),
or LaTeX when !g_htmlFlag, for the math string (hypothesis or conclusion) that
is passed in. */
/* Warning: The caller must deallocate the returned vstring. */
vstring getTexLongMath(nmbrString *mathString, long statemNum);
/* Added 18-Sep-03 (transferred from metamath.c) */
/* Returns the TeX, or HTML code for GIFs (!g_altHtmlFlag) or Unicode
(g_altHtmlFlag), for a statement's hypotheses and assertion in the form
hyp & ... & hyp => assertion */
/* Warning: The caller must deallocate the returned vstring. */
/* 14-Sep-2010 nm Changed name from getHTMLHypAndAssertion() */
vstring getTexOrHtmlHypAndAssertion(long statemNum);
/* Added 17-Nov-2015 (broken out of metamath.c for better modularization) */
/* For WRITE BIBLIOGRAPHY command and error checking by VERIFY MARKUP */
/* Returns 0 if OK, 1 if error or warning found */
flag writeBibliography(vstring bibFile,
vstring labelMatch, /* Normally "*" except by verifyMarkup() */
flag errorsOnly, /* 1 = no output, just warning msgs if any */
flag noFileCheck); /* 1 = ignore missing external files (gifs, bib, etc.) */
/* 5-Aug-2020 nm */
/* Globals to hold mathbox information. They should be re-initialized
by the ERASE command (eraseSource()). g_mathboxStmt = 0 indicates
it and the other variables haven't been initialized. */
extern long g_mathboxStmt; /* stmt# of "mathbox" label; statements+1 if none */
extern long g_mathboxes; /* # of mathboxes */
/* The following 3 "strings" are 0-based e.g. g_mathboxStart[0] is for
mathbox #1 */
extern nmbrString *g_mathboxStart; /* Start stmt vs. mathbox # */
extern nmbrString *g_mathboxEnd; /* End stmt vs. mathbox # */
extern pntrString *g_mathboxUser; /* User name vs. mathbox # */
/* 5-Aug-2020 nm */
/* Returns 1 if statements are in different mathboxes */
flag inDiffMathboxes(long stmt1, long stmt2);
/* Returns the user of the mathbox that a statement is in, or ""
if the statement is not in a mathbox. */
/* Caller should NOT deallocate returned string (it points directly to
g_mathboxUser[] entry); use directly in print2() messages */
vstring getMathboxUser(long stmt);
/* Returns the mathbox number (starting at 1) that stmt is in, or 0 if not
in a mathbox */
long getMathboxNum(long stmt);
/* Populates mathbox information */
void assignMathboxInfo(void);
/* Creates lists of mathbox starts and user names */
long getMathboxLoc(nmbrString **mathboxStart, nmbrString **mathboxEnd,
pntrString **mathboxUser);
#endif /* METAMATH_MMWTEX_H_ */

63632
nf.mm Normal file

File diff suppressed because it is too large Load Diff

864
peano.mm Normal file
View File

@ -0,0 +1,864 @@
$(
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
Metamath source file: axioms for Peano arithmetic
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
$)
$( Copyright (GPL) 2004 Robert Solovay, PO Box 5949, Eugene OR, 97405 $)
$( Comments welcome; email to: solovay at gmail dot com $)
$( Version of 22-Jun-2021 $)
$( Replaces prior version of 13-July-04 $)
$( 22-Jun-2021 (Patrick Brosnan) - Add missing distinct variable constraints
to pa_ax7 $)
$( 7-Oct-2004 (N. Megill) - Minor fixes to conform to strict Metamath spec $)
$( 11-Oct-2004 (N. Megill) - "$a implies" --> "$a |- implies" at line 224 $)
$( 24-Jun-2006 (N. Megill) - Made label and math symbol names spaces
disjoint, as required by the 24-Jun-2006 modification of the Metamath
specification. Specifically, the labels binop, logbinop, binpred,
and quant were changed to binop_, logbinop_, binpred_, and quant_
respectively. $)
$( 11-Nov-2014 (N. Megill) - updated R. Solovay's email address $)
$( This file is a mixture of two sorts of things:
1) Formal metamath axioms and supporting material. [$f and $d
statements for example.]
2) Informal metamathematical arguments that show our axioms suffice to
"do Peano in metamath".
All our metamathematical arguments are quite constructive and
certainly could be formalized in Primitive Recursive Arithmetic. $)
$( We shall slightly deviate from the treatment in Appendix C of the
metamath book. We assume that for each constant c an infinite subset
of the variables is preassigned to that constant.
In particular we will have a constant var. Among our other constants
will be all the symbols of Peano arithmetic except the variables. The
variables of the formal language of Peano Arithmetic will be
identified with the variables attached to the constant symbol var. In
this way each well formed formula or term of PA will *be* a certan
metamath expression. $)
$(
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
Syntax
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
$)
$c |- wff term var $.
$( The next set of axioms will give the inductive definition of
terms. We will be using Polish notation in our formal development of
the syntax of PA. $)
$v s t u s0 s1 t0 t1 $.
ts $f term s $.
tt $f term t $.
tu $f term u $.
ts0 $f term s0 $.
ts1 $f term s1 $.
tt0 $f term t0 $.
tt1 $f term t1 $.
$v v x y z $.
varv $f var v $.
varx $f var x $.
vary $f var y $.
varz $f var z $.
$c 0 S + * $.
$( It is often possible to treat + and * in parallel. The following
device allows us to do this. $)
$c BINOP $.
$v binop $.
binop_ $f BINOP binop $.
binop_plus $a BINOP + $.
binop_times $a BINOP * $.
tvar $a term v $.
tzero $a term 0 $.
tsucc $a term S s $.
tbinop $a term binop s t $.
$( The next set of axioms will give the inductive definition of wff $)
$c not or and implies iff $.
$c LOGBINOP $.
$v logbinop $.
logbinop_ $f LOGBINOP logbinop $.
logbinopor $a LOGBINOP or $.
logbinopand $a LOGBINOP and $.
logbinopimplies $a LOGBINOP implies $.
logbinopiff $a LOGBINOP iff $.
$c = < $.
$c BINPRED $.
$v binpred $.
binpred_ $f BINPRED binpred $.
binpred_equals $a BINPRED = $.
binpred_less_than $a BINPRED < $.
$c forall exists $.
$c QUANT $.
$v quant $.
quant_ $f QUANT quant $.
quant_all $a QUANT forall $.
quant_ex $a QUANT exists $.
$v phi psi chi $.
wff_phi $f wff phi $.
wff_psi $f wff psi $.
wff-chi $f wff chi $.
wff_atom $a wff binpred s t $.
wff_not $a wff not psi $.
wff_logbinop $a wff logbinop psi phi $.
wff_quant $a wff quant v phi $.
$( This completes our description of the syntactic categories of wff
and term $)
$(
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
"Correct" axioms
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
$)
$( In the various sections of this file we will be adding various
axioms [$a statements]. The crucial correctness property that they
will have is the following:
Consider a substitution instance of the axiom such that the only
variables remaining in the instance [in either hypothesis or
conclusion] are of type var. Then if all the hypotheses [$e
statements] have the form
|- phi
[where phi is a theorem of PA] then the conclusion is also a
theorem of PA.
The verification that the various axioms we add are correct in
this sense will be "left to the reader". Usually the proof that I
have in mind is a semantic one based upon the consideration of
models of PA. $)
$( I will give a discussion at the end of this document as to why
sticking with this correctness condition on axioms suffices to
guarantee that only correct theorems of Peano arithmetic are
proved.
$)
$(
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
Propositional logic
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
$)
$( We follow closely the treatment in set.mm. We do have to change the
axioms "into Polish". $)
ax-1 $a |- implies phi implies psi phi $.
ax-2 $a |- implies
implies phi implies psi chi
implies
implies phi psi
implies phi chi $.
ax-3 $a |- implies
implies not phi not psi
implies psi phi $.
$( Modus ponens: $)
${
min $e |- phi $.
maj $e |- implies phi psi $.
ax-mp $a |- psi $.
$}
bi1 $a |- implies
iff phi psi
implies phi psi $.
bi2 $a |- implies
iff phi psi
implies psi phi $.
bi3 $a |- implies
implies phi psi
implies
implies psi phi
iff phi psi $.
df-an $a |- iff
and phi psi
not implies phi not psi $.
df-or $a |- iff
or phi psi
implies not phi psi $.
$( Equality axioms $)
$( From here on out, I won't make an effort to cordinate labels
between my axioms and those of set.mm $)
eq-refl $a |- = t t $.
eq-sym $a |- implies = s t = t s $.
eq-trans $a |- implies
and = s t = t u
= s u $.
eq-congr $a |- implies
and = s0 s1 = t0 t1
iff binpred s0 t0 binpred s1 t1 $.
$( The next two axioms were missing in the previous draft of
peano.mm. They are definitely needed. $)
eq-suc $a |- implies
= s t
= S s S t $.
eq-binop $a |- implies
and = s0 s1 = t0 t1
= binop s0 t0 binop s1 t1 $.
$( Lemma 1 $)
$( Lemma 1 of the 2004 version of this document was not needed in the
subsequent development and has been deleted. I decided not to change
the numbering of subsequent lemmas. $)
$(
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
Free and bound variables; alpha equivalence
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
$)
$( It will be useful to warm up with some familiar concepts. Let PHI
be a well-formed formula of Peano arithmetic. Then Phi is a finite
sequence of symbols, s_1 ... s_n.
Following Shoenfield's treatment in "Mathematical Logic" we use the
term "designator" for a sequence of symbols that is either a term
or a wff. A basic result says that each s_i is the initial symbol
of precisely one subsequence of s_1 ... s_n which is a designator.
Suppose that s_i is a variable. We say that s_i is bound in PHI if
there is a subformula of PHI containing s_i whose initial symbol is
a quantifier and whose second symbol is the same variable as s_i.
[Otherwise s_i is *free* in PHI.]
If s_i is a bound variable, then there is a shortest subformula of
PHI in which s_i is bound. The quantifier beginning this subformula
is the quantifier that *binds* s_i. $)
$( alpha equivalence $)
$( Let Phi_1 and Phi_2 be well-formed formulas of PA. Say Phi_1 is s_1
... s_n and Phi_2 is t_1 ... t_m.
We say that Phi_1 and Phi_2 are alpha-equialent if:
1) n = m.
2) Let 1 <= i <= n. Then s_i is a constant iff t_i is; in that case,
they are the *same* constant.
3) Let 1 <= i <= n. Suppose that s_i is a variable. [So t_i is a
variable as well.] Then s_i is free in Phi_1 iff t_i is free in
Phi_2. If s_i is free in Phi_1, then s_i = t_i.
4) Let 1 <= i <= n. Suppose that s_i is a variable that is bound in
Phi_1. [It follows that t_i is a variable that is bound in Phi_2.]
Let s_j be the quantifier that binds s_i. Then t_j is the
quantifier that binds t_i.
[This ends the definition of alpha-equivalence.]
It is indeed true that alpha-equivalence is an equivalence relation.
$)
$( Trim formulas $)
$( The following concept is non-standard. A well-formed formula of PA
is *trim* if:
1) No variable occurs both free and bound in Phi.
2) Distinct quantifiers bind distinct variables.
[So
exists x exists x = x x
is not trim since the two quantifiers both bind the variable x.]
Clearly every formula is alpha-equivalent to some trim
formula. Moreover, we can assume that the bound variables of this
trim equivalent avoid some specified finite set of variables.
$)
$( Here is the next Lemma we are heading toward. We can add a finite
number of correct axioms to our file so that once this is done, if
Phi_1 and Phi_2 are alpha-equivalent formulas then [subject to the
requirement that any pair of distinct variables appearing in Phi_1 or
Phi_2 is declared disjoint]
|- iff Phi_1 Phi_2
is a theorem of Metmath [i.e. follows from the given axioms].
In view of the remarks about trim formulas, we are reduced to the
following special case: Phi_2 is trim and no bound variable of Phi_2
appears [free or bound] in Phi_1.
We fix Phi_1 and Phi_2 subject to this restriction. We will develop
the axioms we need in the course of the proof. Of course, the reader
should verify that we could have specified them in advance. In
particular the additional axioms we list will not depend on Phi_1 or Phi_2. $)
$( Our proof strategy is as follows;
To each subformula Psi of Phi_1, we shall attach a claim C(Psi) [which
will also be a well-formed formula of PA]. We will prove in Metamath
the various claims C(Psi). The construction of these proofs will be an
inductive one [by induction on the length of the subformula,
say]. From the claim C(Phi_1), the desired equivalence of Phi_1 and
Phi_2 will easily follow. $)
$( Weak alpha-equivalence $)
$( Before describing the claims C(Psi), I need to introduce the notion
of weak alpha-equivalence. Let Psi_1 and Psi_2 be two well-formed
formulas of PA.
Say Psi_1 is s_1 ... s_m and Psi_2 is t_1 ... t_n.
Then Psi_1 and Psi_2 are weakly alpha equivalent iff:
1) m = n;
2) Let 1 <= i <= n. Then s_i is a constant iff t_i is; in that case,
they are the *same* constant.
3) Let 1 <= i <= n. Suppose that s_i is a variable. [So t_i is a
variable as well.] Then s_i is free in Psi_1 iff t_i is free in
Psi_2.
3a) Let 1 <= i < j <= n. Suppose that s_i and s_j are variables free
in Psi_1. [It follows that t_i and t_j are free variables in Psi_2.]
Then s_i = s_j iff t_i = t_j.
4) Let 1 <= i <= n. Suppose that s_i is a variable that is bound in
Psi_1. [It follows that t_i is a variable that is bound in Psi_2.]
Let s_j be the quantifier that binds s_i. Then t_j is the
quantifier that binds t_i.
[This ends the definition of weak alpha-equivalence.] $)
$( I need a pedantic fact:
Proposition 2.1. Let Phi_1 = s_1,..., s_m and Phi_2 = t_1...t_m be
as above. Let 1 <= i <= j <= m. Then s_i ... s_j is a term
[formula] iff t_i ... t_j is.
The proof is by induction on j - i and is straightforward. [It
splits into cases according to what s_i is.] $)
$( The following explains the importance of "weak alpha equivalence":
Proposition 2.2.
Let Psi_1 be a subformula of Phi_1, and Psi_2 the corresponding
subformula of Phi_2. (Cf. the "pedantic fact" just above.) Then
Psi_1 and Psi_2 are weakly alpha equivalent.
Only clause 3a) of the definition of weak alpha equivalence
requires discussion:
Say Psi_1 occupies positions i ... j of Phi_1. Let i <= a < b <= j
and let s_a and s_b be the same variable x. We suppose that s_a and
s_b are free in Psi_1. We shall show that t_a = t_b. {This will
prove one direction of the iff; the other direction is proved
similarly.}
If s_a and s_b are both free in Phi_1 then our claim is clear since
Phi_1 and Phi_2 are alpha equivalent. If not, let Theta_1 be the
smallest subformula of Phi_1 in which one of s_a and s_b is
bound. Then both s_a and s_b are bound by the quantifer that begins
Theta_1.
Let Theta_2 be the subformula of Phi_2 that corresponds to
Theta_1. Using the alpha equivalence of Phi_1 and Phi_2 we see that
both t_a and t_b are bound by the quantifer that begins
Theta_2. Hence t_a = t_b.
$)
$( We are now able to begin the definition of C(Psi_1) for Psi_1 a
subformula of Phi_1. It will have the form
implies H(Psi_1)
iff Psi_1 Psi_2
where Psi_2 is the subformula of Phi_2 that corresponds to Psi_1.
It remains to describe H(Psi_1):
Let w be a variable that does not appear [free or bound] in either
Phi_1 or Phi_2. Let x_1 ... x_r be the free variables appearing in
Psi_1 [listed without repetitions]. Because Psi_1 is weakly alpha
equivalent to Psi_2, we can define a bijection between the free
variables of Psi_1 and those of Psi_2 thus. If x_i appears freely in
position j of Psi_1 then the corresponding free variable of Psi_2,
say y_i, appears in position j of Psi_2.
H(Psi_1) is the conjunction of the following equalities:
1) = w w ;
2) = x_i y_i (for i = 1 ... r).
This completes our description of C(Psi_1). $)
$( Consider first C(Phi_1). Because Phi_1 is alpha equivalent to
Phi_2, H(Phi_1) is the conjunction of equalities of the form = a a .
Hence Metamath can prove H(Phi_1) and can see that C(Phi_1) is
equivalent to the equivalence:
iff Phi_1 Phi_2
$)
$( So it will be sufficient to see that Metamath [after enrichment with
some additional correct axioms] can prove C(Psi_1) for every
subformula Psi_1 of Phi_1. The proof of this proceeds by induction on
the length of Psi_1.
If Psi_1 is atomic, our claim is easily proved using the equality
axioms.
The cases when Psi_1 is built up from smaller formulas using propositional
connectives are easily handled since Metamath knows propositional
logic.
$)
$( It remains to consider the case when Psi_1 has the form Q x Chi_1
where Q is a quantifier.
It is clear that Psi_2 has the form Q y Chi_2 [where Chi_2 is the
subformula of Phi_2 that corresponds to Chi_1]. We will consider two
cases;
Case A: x = y;
Case B: x != y. $)
$( To handle Case A we adjoin the following axiom [which the reader
should verify is correct]. $)
${ $d phi x $.
alpha_hyp1 $e |- implies phi
iff psi chi $.
alpha_1 $a |- implies phi
iff quant x psi
quant x chi $. $}
$( We apply this axiom with H(Psi_1) in the role of phi and Q in the
role of quant. Chi_1 is in the role of psi and Chi_2 is in the role of
chi.
To see that the needed instance of alpha_hyp1 holds, note that
H(Chi_1) is either H(Psi_1) [up to a possible rearrangement of
conjuncts] or the conjunction of H(Psi_1) with the conjunct
= x x
So our needed instance follows from C(Chi_1), equality axioms and
propositional logic $)
$( We turn to case B. It is worthwhile to remind the reader that Phi_2
has been chosen so that no bound variable of Phi_2 appears either free
or bound in Phi_1.
Proposition 2.3. y does not appear [free or bound] in Psi_1. x does
not appear [free or bound] in Psi_2.
Proof: y appears bound in Psi_2. Hence it doesn't even appear [free or
bound] in Phi_1.
Suppose that x appears in Psi_2. Then this appearence must be free in
Phi_2. {Otherwise, x would not appear in Phi_1 but it is the second
symbol of Psi_1.} So at the same spot in Psi_1 x also appears, and
this occurrence is free in Phi_1. {This follows from the fact that
Phi_1 and Phi_2 are alpha equivalent.} But clearly this occurrence of
x in Psi_1 will be bound by the quantifier that starts
Psi_1. Contradiction! $)
$( Proposition 2.3 has the following immediate consequence:
Proposition 2.4: Neither of the variables x or y occurs in H(Psi_1).
Also it is easy to check that [up to propositional logic]
H(Chi_1) is either H(Psi_1) or the conjunction of H(Psi_1)
with
= x y
It follows that from C(Chi_1) one can deduce [using propositonal
logic] the following:
(A) implies H(Psi_1)
implies = x y
iff Chi_1 Chi_2 $)
$( Next we introduce the following Metamath axiom [which the reader
should verify is correct] $)
${ $d phi x $.
alpha_hyp2 $e |- implies phi chi $.
alpha_2 $a |- implies phi forall x chi $.
$}
$( Using this axiom we can deduce from (A) and Proposition 2.4
the following:
(B) implies H(Psi_1)
forall x forall y implies = x y
iff Chi_1 Chi_2
$)
$( We need to introduce another axiom [which the reader should verify
is correct] $)
${ $d phi y $.
$d psi x $.
$d x y $.
alpha_3 $a |- implies forall x forall y implies = x y
iff phi psi
iff quant x phi quant y psi $.
$}
$( From this axiom, (B) and Proposition 2.3 we easily deduce:
(C) implies H(Psi_1)
iff Psi_1 Psi_2
which is C(Psi_1) $)
$( The following lemma should now be clear to the reader:
Lemma 2. Let Phi and Phi* be alpha equivalent formulas of PA. Then
using the axioms so far introduced, we can prove in Metamath the
sequence
|- iff Phi_1 Phi_2
from the disjointness assumption that all the distinct variables
appearing in Phi_1 or Phi_2 are asserted to be distinct in a $d
assumption. $)
$(
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
Axioms and inference rules of predicate logic
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
$)
$( Our next task is to prove the rule of inference and the axiom
associated to the "forall" quantifier. $)
$( Let's start with the rule of inference. We have to show that if
|- implies phi chi
and phi does not contain x free then also
|- implies phi forall x chi.
But this is easy. In view of what we have just shown, it is ok to
replace phi by an alpha-equivalent formula that does not contain x
at all. {In both our hypothesis and conclusion.}
But then we just need to invoke the axiom alpha_2. $)
$( We now turn to the axiom of "forall elimination". To state it we
introduce the familiar notion of substituting a term for the free
occurrences of a variable. So let phi be a formula, x a variable and t
a term. By phi[t/x] we mean the formula obtained by simultaneously
replacing each free occurrence of x in phi by a copy of the term t. {A
more rigorous definition would proceed by induction on the structure
of phi.}
We say that t is substitutable for x at the free occurrence of x in
phi [or just "substitutable" if we are being terse] if no variable
occuring in t falls under the scope of any quantifer of
phi. {Again, I am presuming this notion known; otherwise, I'd be
more careful with this definition.}
The final group of axioms of predicate calculus that we need to
derive have the following form:
(*) implies
forall x phi
phi[t/x]
**where** t is substitutable for x in phi.
Our next step is to show that it suffices to prove the following
special case of this axiom. phi x and t satisfy the following three
conditions:
(1) The variable x does not appear in the term t.
(2) No bound variable of phi appears in t.
(3) The variable x does not appear bound in phi.
We can see this as follows. We can clearly find a formula
forall y psi
which is alpha equivalent to forall x phi such that:
(1') The variable y does not appear in the term t;
(2') No bound variable of psi appears in t;
(3') The variable y does not appear bound in psi.
Using the fact that t is substitutable for x in phi we easily see that
phi[t/x] is alpha equivalent to psi[t/y]. It follows that (*) is
alpha-equivalent to:
(**) implies
forall y psi
psi[t/y]
Hence Metamath can prove the equivalence of (*) and (**). But in view
of (1') through (3'), the instance (**) of for all elimination meets
our additional requirements (1) through (3).
In the remainder of our discussion we shall assume then that phi, x
and t meet the requirements (1) through (3). Note that it follows from
(2) that t is substitutable for x in phi.
[N.B. We cannot assume that the variables appearing in t do not appear
in phi.]
Here is the key idea of our approach: The formula phi[t/x] (under the
hypotheses (1) -- (3) just given) is equivalent to:
forall x implies
= x t
phi
$)
$( We start by adding the following [correct!] axiom $)
${ $d x t $.
all_elim $a |- implies
forall x phi
forall x implies
= x t
phi $.
$}
$( Using this axiom we can reduce our proof that Metamath proves all
instances of "all elimination" to the following lemma:
Lemma 3. Let t be a term of PA and phi a formula of PA. We assume:
1) The variable x does not occur in t;
2) No bound variable of phi appears in t.
3) The variable x does not occur bound in phi.
Then [after adding finitely many additional correct axioms whose
choice does not depend on phi] we can prove in Metamath:
|- iff
forall x implies
= x t
phi
phi[t/x]
$)
$( We shall need a preliminary result:
Proposition 3.1 Let phi t and x obey our standing hypotheses 1) --
3). Let psi be a subformula of phi.
Then [after adding finitely many additional correct axioms whose
choice does not depend on phi] we can prove in Metamath:
|- implies = x t
iff psi psi[t/x]
The construction of such proofs [like many previous arguments] is by
induction on the tree of subformulas of phi. $)
$( The first case is when psi is atomic. This case is easily handled
using the equality axioms.
The second case is when the principal connective of psi is a
propositional connective. This case follows easily using propositional
logic from our inductive hypotheses concerning the subformulas of psi.
$)
$( The final case is when the principal connective of psi is a
quantifier. This case is handled using the following axiom: $)
${ $d x y $.
$d y t $.
all_elim_hyp2 $e |- implies = x t
iff phi chi $.
all_elim2 $a |- implies = x t
iff quant y phi
quant y chi $.
$}
$( The proof of Proposition 3.1 is now complete. We apply it to phi
and get that Metamath proves:
|- implies = x t
iff phi phi[t/x]
Here phi and t stand for the particular wff and term of t under
discussion and are not literal metavariables of Metamath.
We also know at this point that Metamath proves:
|- implies forall x phi
forall x implies = x t
phi
We would be done if we could prove in Metamath:
|- implies forall x implies = x t
phi
phi[t/x]
But this will follow easily from the next axiom [which is inelegant
but correct].
$)
${
$d x chi $.
$d x t $.
all_elim3_hyp1 $e |- implies = x t
iff phi chi $.
all_elim3 $a |- implies forall x implies = x t
phi
chi $. $}
$( This completes our discussion of "forall-elimination". $)
$( It is time to introduce the definition of the
"exists" quantifier $)
exists_def $a |- iff
exists x phi
not forall x not phi $.
$( Of course, the axiom and rule of inference for "exists" follow from
this definition and the corresponding inference rule or axiom scheme
for "forall". $)
$(
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
The non-logical axioms of Peano Arithmetic
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
$)
$( At this point, we know that Metamath can prove any logically valid
wff of PA. It remains to add the axioms of PA. $)
$( First we give the particular axioms of PA. Then we discuss the
induction scheme $)
pa_ax1 $a |- not = 0 S x $.
pa_ax2 $a |- implies = S x S y
= x y $.
pa_ax3 $a |- = x
+ x 0 $.
pa_ax4 $a |- = S + x y
+ x S y $.
pa_ax5 $a |- = 0
* x 0 $.
pa_ax6 $a |- = + * x y x
* x S y $.
${
$d z x $. $d z y $.
pa_ax7 $a |- iff
< x y
exists z = y + x S z $.
$}
$( It suffices to give the induction axiom for the case when phi does
not contain x free. For the usual form of the axiom follows from this
special case by first order logic. $)
${
$d phi x $.
$d x y $.
induction $a
|- implies
and forall y implies = y 0 phi
forall x implies forall y implies = y x phi
forall y implies = y S x phi
forall x forall y implies = y x phi $.
$}
$(
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
Discussion of correctness
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
$)
$(
Let's agree that when I say "Metamath proves PHI" I mean "Metamath"
enriched with all the preceding axioms in this document.
The issue is the following. For what formulas Phi is there a proof in
Metamath from no $e type assumptions of the sequencce
|- Phi.
(Recall that I am identifying the well-formed formulas of Peano with
certain of the Metamath strings of symbols. This is done by
identifying the object variables of our language with the
metavariables of type var.)
The claim is that these are precisely those Phi which are theorems of
the usual formulation of Peano Arithmetic.
One direction should be clear by this point. We have developed the
first order predicate calculus within Metamath and included the usual
axioms of Peano arithmetic [or equivalents]. So any theorem of Peano
Arithmetic [as usually formulated] can be proved in Metamath.
To go in the other direction, suppose that there is a proof in
Metamath of |- Phi. So the final line of the proof contains only
variables of type var. But there might well be variables of other
kinds in the body of the proof. For example, there might be a variable
phi of kind wff.
The critical such variables are those that appear in lines of the
proof beginning with |-. What we do is replace such variables (of
kind different than var) [one by one] by sequences of constants of the
same type. (So phi might be replaced by the three symbol string "= 0
0".) It is not hard to see that after this substitution the result can
be massaged to a correct proof. There are two points to notice.
a) Since the string by which we replaced the variable contains no
variables itself the process converges and no disjointness
conditions [$d restrictions] are violated.
b) We may have to add a trivial few lines to prove the "type
assertion". In our example, the line "wff phi" will be replaced
by the line "wff = 0 0". This line is no longer immediate but
must be proved by a four line argument.
At the end, there results a proof where all the lines that begin with
"|-" contain only variables of type var. But now our correctness
assumptions allow us to verify step by step that each such line is a
theorem of Peano arithmetic.
$)
$( For Emacs $)
$( Local Variables: $)
$( eval:'(show-paren-mode t) $)
$( End: $)

12530
ql.mm Normal file

File diff suppressed because it is too large Load Diff

738957
set.mm Normal file

File diff suppressed because it is too large Load Diff