Initial commit
This commit is contained in:
commit
1ab1e012c3
|
@ -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.
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -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 ";
|
||||
$)
|
|
@ -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
|
|
@ -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
|
||||
$.
|
||||
|
|
@ -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 .
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -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 $.
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_*/
|
|
@ -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 */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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>
|
|
@ -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.) */
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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_ */
|
|
@ -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"));
|
||||
}
|
||||
|
||||
*/
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_ */
|
|
@ -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 '<'; 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 " " /* Either "" or " " 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_ */
|
|
@ -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: $)
|
Loading…
Reference in New Issue