summaryrefslogtreecommitdiff
path: root/test/spass
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-03-03 12:34:43 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-03-03 12:34:43 +0000
commit6c196ec8a41d6ed506c133c8b33dba9684f9a7a6 (patch)
tree4e1422ea2a810520d0d9b0fbb78c0014ba9f8443 /test/spass
parent93d89c2b5e8497365be152fb53cb6cd4c5764d34 (diff)
Updated raytracer test. Added SPASS test.
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1271 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'test/spass')
-rw-r--r--test/spass/.depend130
-rw-r--r--test/spass/AUTHORS23
-rw-r--r--test/spass/COPYING340
-rw-r--r--test/spass/LICENSE.TXT1
-rw-r--r--test/spass/Makefile34
-rw-r--r--test/spass/Makefile.bak13
-rw-r--r--test/spass/README96
-rw-r--r--test/spass/VERSIONHISTORY135
-rw-r--r--test/spass/analyze.c774
-rw-r--r--test/spass/analyze.h121
-rw-r--r--test/spass/approx.h61
-rw-r--r--test/spass/clause.c5008
-rw-r--r--test/spass/clause.h1589
-rw-r--r--test/spass/clock.c215
-rw-r--r--test/spass/clock.h78
-rw-r--r--test/spass/closure.c441
-rw-r--r--test/spass/closure.h67
-rw-r--r--test/spass/cnf.c4787
-rw-r--r--test/spass/cnf.h120
-rw-r--r--test/spass/component.c266
-rw-r--r--test/spass/component.h151
-rw-r--r--test/spass/condensing.c100
-rw-r--r--test/spass/condensing.h64
-rw-r--r--test/spass/context.c636
-rw-r--r--test/spass/context.h1049
-rw-r--r--test/spass/defs.c1359
-rw-r--r--test/spass/defs.h205
-rw-r--r--test/spass/dfg.h86
-rw-r--r--test/spass/dfgparser.c3728
-rw-r--r--test/spass/dfgparser.h184
-rw-r--r--test/spass/dfgscanner.c5174
-rw-r--r--test/spass/doc-proof.c247
-rw-r--r--test/spass/doc-proof.h91
-rw-r--r--test/spass/flags.c810
-rw-r--r--test/spass/flags.h1117
-rw-r--r--test/spass/foldfg.c2444
-rw-r--r--test/spass/foldfg.h303
-rw-r--r--test/spass/graph.c318
-rw-r--r--test/spass/graph.h148
-rw-r--r--test/spass/hash.c115
-rw-r--r--test/spass/hash.h107
-rw-r--r--test/spass/hasharray.c138
-rw-r--r--test/spass/hasharray.h246
-rw-r--r--test/spass/ia.h58
-rw-r--r--test/spass/iaparser.c1773
-rw-r--r--test/spass/iaparser.h87
-rw-r--r--test/spass/iascanner.c1991
-rw-r--r--test/spass/kbo.c593
-rw-r--r--test/spass/kbo.h67
-rw-r--r--test/spass/list.c1660
-rw-r--r--test/spass/list.h433
-rw-r--r--test/spass/memory.c1595
-rw-r--r--test/spass/memory.h478
-rw-r--r--test/spass/misc.c147
-rw-r--r--test/spass/misc.h161
-rw-r--r--test/spass/options.c1889
-rw-r--r--test/spass/options.h127
-rw-r--r--test/spass/order.c516
-rw-r--r--test/spass/order.h147
-rw-r--r--test/spass/partition.c287
-rw-r--r--test/spass/partition.h127
-rw-r--r--test/spass/problem.dfg718
-rw-r--r--test/spass/proofcheck.c1391
-rw-r--r--test/spass/proofcheck.h82
-rw-r--r--test/spass/ras.h298
-rw-r--r--test/spass/renaming.c1508
-rw-r--r--test/spass/renaming.h168
-rw-r--r--test/spass/resolution.c178
-rw-r--r--test/spass/resolution.h73
-rw-r--r--test/spass/rpos.c521
-rw-r--r--test/spass/rpos.h82
-rw-r--r--test/spass/rules-inf.c4281
-rw-r--r--test/spass/rules-inf.h165
-rw-r--r--test/spass/rules-red.c4508
-rw-r--r--test/spass/rules-red.h111
-rw-r--r--test/spass/rules-sort.c1763
-rw-r--r--test/spass/rules-sort.h79
-rw-r--r--test/spass/rules-split.c460
-rw-r--r--test/spass/rules-split.h70
-rw-r--r--test/spass/rules-ur.c385
-rw-r--r--test/spass/rules-ur.h55
-rw-r--r--test/spass/search.c1271
-rw-r--r--test/spass/search.h522
-rw-r--r--test/spass/sharing.c1143
-rw-r--r--test/spass/sharing.h245
-rw-r--r--test/spass/small_problem.dfg154
-rw-r--r--test/spass/sort.c1974
-rw-r--r--test/spass/sort.h598
-rw-r--r--test/spass/st.c1691
-rw-r--r--test/spass/st.h305
-rw-r--r--test/spass/stack.c55
-rw-r--r--test/spass/stack.h155
-rw-r--r--test/spass/strings.c325
-rw-r--r--test/spass/stringsx.h88
-rw-r--r--test/spass/subst.c647
-rw-r--r--test/spass/subst.h219
-rw-r--r--test/spass/subsumption.c2041
-rw-r--r--test/spass/subsumption.h87
-rw-r--r--test/spass/symbol.c1020
-rw-r--r--test/spass/symbol.h786
-rw-r--r--test/spass/table.c553
-rw-r--r--test/spass/table.h101
-rw-r--r--test/spass/tableau.c880
-rw-r--r--test/spass/tableau.h292
-rw-r--r--test/spass/term.c2551
-rw-r--r--test/spass/term.h612
-rw-r--r--test/spass/terminator.c319
-rw-r--r--test/spass/terminator.h58
-rw-r--r--test/spass/top.c1648
-rw-r--r--test/spass/unify.c857
-rw-r--r--test/spass/unify.h119
-rw-r--r--test/spass/vector.c120
-rw-r--r--test/spass/vector.h188
113 files changed, 83775 insertions, 0 deletions
diff --git a/test/spass/.depend b/test/spass/.depend
new file mode 100644
index 0000000..5348867
--- /dev/null
+++ b/test/spass/.depend
@@ -0,0 +1,130 @@
+analyze.o: analyze.c analyze.h search.h clause.h sharing.h term.h \
+ symbol.h list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h \
+ flags.h unify.h context.h subst.h order.h sort.h hash.h subsumption.h \
+ component.h vector.h graph.h
+clause.o: clause.c clause.h sharing.h term.h symbol.h list.h memory.h \
+ misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h context.h \
+ subst.h order.h
+clock.o: clock.c clock.h misc.h
+closure.o: closure.c closure.h clause.h sharing.h term.h symbol.h list.h \
+ memory.h misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h \
+ context.h subst.h order.h table.h partition.h ras.h
+cnf.o: cnf.c cnf.h hasharray.h list.h memory.h misc.h renaming.h foldfg.h \
+ flags.h unify.h term.h symbol.h stringsx.h stack.h context.h subst.h \
+ vector.h resolution.h st.h subsumption.h component.h clause.h sharing.h \
+ order.h condensing.h search.h sort.h hash.h rules-inf.h rules-split.h \
+ rules-sort.h rules-ur.h defs.h rules-red.h doc-proof.h proofcheck.h \
+ options.h dfg.h tableau.h clock.h closure.h table.h partition.h ras.h
+component.o: component.c term.h symbol.h list.h memory.h misc.h \
+ stringsx.h stack.h component.h
+condensing.o: condensing.c subsumption.h misc.h unify.h term.h symbol.h \
+ list.h memory.h stringsx.h stack.h context.h subst.h component.h \
+ vector.h clause.h sharing.h st.h foldfg.h flags.h order.h condensing.h
+context.o: context.c context.h term.h symbol.h list.h memory.h misc.h \
+ stringsx.h stack.h
+defs.o: defs.c cnf.h hasharray.h list.h memory.h misc.h renaming.h \
+ foldfg.h flags.h unify.h term.h symbol.h stringsx.h stack.h context.h \
+ subst.h vector.h resolution.h st.h subsumption.h component.h clause.h \
+ sharing.h order.h condensing.h search.h sort.h hash.h defs.h
+dfgparser.o: dfgparser.c dfg.h list.h memory.h misc.h flags.h clause.h \
+ sharing.h term.h symbol.h stringsx.h stack.h st.h foldfg.h unify.h \
+ context.h subst.h order.h
+dfgscanner.o: dfgscanner.c misc.h memory.h symbol.h list.h stringsx.h \
+ term.h stack.h dfg.h flags.h clause.h sharing.h st.h foldfg.h unify.h \
+ context.h subst.h order.h dfgparser.h
+doc-proof.o: doc-proof.c doc-proof.h clause.h sharing.h term.h symbol.h \
+ list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h \
+ context.h subst.h order.h search.h sort.h hash.h subsumption.h \
+ component.h vector.h proofcheck.h options.h dfg.h tableau.h
+flags.o: flags.c flags.h memory.h misc.h stringsx.h
+foldfg.o: foldfg.c foldfg.h flags.h memory.h misc.h unify.h term.h \
+ symbol.h list.h stringsx.h stack.h context.h subst.h
+graph.o: graph.c graph.h list.h memory.h misc.h
+hash.o: hash.c hash.h list.h memory.h misc.h
+hasharray.o: hasharray.c hasharray.h list.h memory.h misc.h
+iaparser.o: iaparser.c flags.h memory.h misc.h ia.h list.h symbol.h \
+ stringsx.h term.h stack.h foldfg.h unify.h context.h subst.h clause.h \
+ sharing.h st.h order.h
+iascanner.o: iascanner.c misc.h memory.h symbol.h list.h stringsx.h \
+ term.h stack.h ia.h flags.h iaparser.h
+kbo.o: kbo.c kbo.h term.h symbol.h list.h memory.h misc.h stringsx.h \
+ stack.h context.h foldfg.h flags.h unify.h subst.h order.h
+list.o: list.c list.h memory.h misc.h
+memory.o: memory.c memory.h misc.h
+misc.o: misc.c misc.h
+options.o: options.c options.h flags.h memory.h misc.h list.h stringsx.h
+order.o: order.c flags.h memory.h misc.h order.h term.h symbol.h list.h \
+ stringsx.h stack.h context.h kbo.h foldfg.h unify.h subst.h rpos.h
+partition.o: partition.c partition.h memory.h misc.h
+proofcheck.o: proofcheck.c proofcheck.h options.h flags.h memory.h misc.h \
+ list.h vector.h dfg.h clause.h sharing.h term.h symbol.h stringsx.h \
+ stack.h st.h foldfg.h unify.h context.h subst.h order.h tableau.h \
+ search.h sort.h hash.h subsumption.h component.h
+renaming.o: renaming.c renaming.h misc.h foldfg.h flags.h memory.h \
+ unify.h term.h symbol.h list.h stringsx.h stack.h context.h subst.h \
+ vector.h
+resolution.o: resolution.c resolution.h misc.h unify.h term.h symbol.h \
+ list.h memory.h stringsx.h stack.h context.h subst.h foldfg.h flags.h \
+ st.h subsumption.h component.h vector.h clause.h sharing.h order.h \
+ condensing.h
+rpos.o: rpos.c rpos.h misc.h term.h symbol.h list.h memory.h stringsx.h \
+ stack.h order.h context.h flags.h
+rules-inf.o: rules-inf.c rules-inf.h search.h clause.h sharing.h term.h \
+ symbol.h list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h \
+ flags.h unify.h context.h subst.h order.h sort.h hash.h subsumption.h \
+ component.h vector.h rules-split.h rules-sort.h rules-ur.h defs.h
+rules-red.o: rules-red.c rules-red.h sort.h clause.h sharing.h term.h \
+ symbol.h list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h \
+ flags.h unify.h context.h subst.h order.h hash.h subsumption.h \
+ component.h vector.h condensing.h search.h rules-split.h rules-inf.h \
+ rules-sort.h rules-ur.h defs.h doc-proof.h proofcheck.h options.h dfg.h \
+ tableau.h clock.h closure.h table.h partition.h ras.h
+rules-sort.o: rules-sort.c rules-sort.h sort.h clause.h sharing.h term.h \
+ symbol.h list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h \
+ flags.h unify.h context.h subst.h order.h hash.h subsumption.h \
+ component.h vector.h
+rules-split.o: rules-split.c rules-split.h clause.h sharing.h term.h \
+ symbol.h list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h \
+ flags.h unify.h context.h subst.h order.h search.h sort.h hash.h \
+ subsumption.h component.h vector.h
+rules-ur.o: rules-ur.c rules-ur.h clause.h sharing.h term.h symbol.h \
+ list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h \
+ context.h subst.h order.h
+search.o: search.c search.h clause.h sharing.h term.h symbol.h list.h \
+ memory.h misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h \
+ context.h subst.h order.h sort.h hash.h subsumption.h component.h \
+ vector.h defs.h
+sharing.o: sharing.c sharing.h term.h symbol.h list.h memory.h misc.h \
+ stringsx.h stack.h st.h foldfg.h flags.h unify.h context.h subst.h
+sort.o: sort.c sort.h clause.h sharing.h term.h symbol.h list.h memory.h \
+ misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h context.h \
+ subst.h order.h hash.h subsumption.h component.h vector.h
+st.o: st.c st.h foldfg.h flags.h memory.h misc.h unify.h term.h symbol.h \
+ list.h stringsx.h stack.h context.h subst.h
+stack.o: stack.c stack.h misc.h
+strings.o: strings.c stringsx.h memory.h misc.h list.h
+subst.o: subst.c subst.h term.h symbol.h list.h memory.h misc.h \
+ stringsx.h stack.h unify.h context.h
+subsumption.o: subsumption.c subsumption.h misc.h unify.h term.h symbol.h \
+ list.h memory.h stringsx.h stack.h context.h subst.h component.h \
+ vector.h clause.h sharing.h st.h foldfg.h flags.h order.h
+symbol.o: symbol.c symbol.h list.h memory.h misc.h stringsx.h
+table.o: table.c table.h term.h symbol.h list.h memory.h misc.h \
+ stringsx.h stack.h partition.h
+tableau.o: tableau.c tableau.h list.h memory.h misc.h clause.h sharing.h \
+ term.h symbol.h stringsx.h stack.h st.h foldfg.h flags.h unify.h \
+ context.h subst.h order.h
+term.o: term.c term.h symbol.h list.h memory.h misc.h stringsx.h stack.h
+terminator.o: terminator.c terminator.h misc.h symbol.h list.h memory.h \
+ stringsx.h clause.h sharing.h term.h stack.h st.h foldfg.h flags.h \
+ unify.h context.h subst.h order.h
+top.o: top.c dfg.h list.h memory.h misc.h flags.h clause.h sharing.h \
+ term.h symbol.h stringsx.h stack.h st.h foldfg.h unify.h context.h \
+ subst.h order.h defs.h search.h sort.h hash.h subsumption.h component.h \
+ vector.h ia.h rules-inf.h rules-split.h rules-sort.h rules-ur.h \
+ terminator.h rules-red.h condensing.h doc-proof.h proofcheck.h \
+ options.h tableau.h clock.h closure.h table.h partition.h ras.h \
+ analyze.h graph.h cnf.h hasharray.h renaming.h resolution.h
+unify.o: unify.c unify.h term.h symbol.h list.h memory.h misc.h \
+ stringsx.h stack.h context.h subst.h
+vector.o: vector.c vector.h misc.h
diff --git a/test/spass/AUTHORS b/test/spass/AUTHORS
new file mode 100644
index 0000000..c373ede
--- /dev/null
+++ b/test/spass/AUTHORS
@@ -0,0 +1,23 @@
+Current:
+========
+
+Christoph Weidenbach <weidenb@mpi-sb.mpg.de>
+Uwe Brahm <brahm@mpi-sb.mpg.de>
+Thomas Hillenbrand <hillen@mpi-sb.mpg.de>
+Dalibor Topic <topic@mpi-sb.mpg.de>
+
+
+Former:
+=======
+
+Bijan Afshordel <afshorde@mpi-sb.mpg.de>
+Christof Brinker <chbr@mpi-sb.mpg.de>
+Christian Cohrs <cohrs@mpi-sb.mpg.de>
+Thorsten Engel <engel@mpi-sb.mpg.de>
+Bernd Gaede <gaede@mpi-sb.mpg.de>
+Peter Graf <graf@mpi-sb.mpg.de>
+Georg Jung <gjung@mpi-sb.mpg.de>
+Christoph Meyer <meyer@mpi-sb.mpg.de>
+Georg Rock <rock@mpi-sb.mpg.de>
+Christian Theobalt <theobalt@mpi-sb.mpg.de>
+
diff --git a/test/spass/COPYING b/test/spass/COPYING
new file mode 100644
index 0000000..eeb586b
--- /dev/null
+++ b/test/spass/COPYING
@@ -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) 19yy <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) 19yy 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.
diff --git a/test/spass/LICENSE.TXT b/test/spass/LICENSE.TXT
new file mode 100644
index 0000000..7271268
--- /dev/null
+++ b/test/spass/LICENSE.TXT
@@ -0,0 +1 @@
+see the file "COPYING"
diff --git a/test/spass/Makefile b/test/spass/Makefile
new file mode 100644
index 0000000..b964770
--- /dev/null
+++ b/test/spass/Makefile
@@ -0,0 +1,34 @@
+CC=../../ccomp
+CFLAGS=-stdlib ../../runtime -dparse -dclight -dasm -fstruct-passing -fstruct-assign
+
+SRCS=analyze.c clause.c clock.c closure.c cnf.c component.c \
+ condensing.c context.c defs.c dfgparser.c dfgscanner.c doc-proof.c \
+ flags.c foldfg.c graph.c hash.c hasharray.c iaparser.c iascanner.c \
+ kbo.c list.c memory.c misc.c options.c order.c partition.c \
+ proofcheck.c renaming.c resolution.c rpos.c rules-inf.c rules-red.c \
+ rules-sort.c rules-split.c rules-ur.c search.c sharing.c sort.c st.c \
+ stack.c strings.c subst.c subsumption.c symbol.c table.c tableau.c \
+ term.c terminator.c top.c unify.c vector.c
+
+all: spass
+
+spass: $(SRCS:.c=.o)
+ $(CC) $(CFLAGS) -o spass $(SRCS:.c=.o)
+
+clean:
+ rm -f spass
+ rm -f *.o *.s *.parsed.c *.light.c
+
+test:
+ ./spass small_problem.dfg | grep 'Proof found'
+
+TIME=xtime -o /dev/null # Xavier's hack
+#TIME=time >/dev/null # Otherwise
+
+bench:
+ $(TIME) ./spass problem.dfg
+
+depend:
+ gcc -MM $(SRCS) > .depend
+
+include .depend
diff --git a/test/spass/Makefile.bak b/test/spass/Makefile.bak
new file mode 100644
index 0000000..320f622
--- /dev/null
+++ b/test/spass/Makefile.bak
@@ -0,0 +1,13 @@
+LEVEL = ../../..
+PROG = SPASS
+
+CPPFLAGS = -DCLOCK_NO_TIMING -fno-strict-aliasing -w
+LDFLAGS = -lm
+
+ifdef SMALL_PROBLEM_SIZE
+RUN_OPTIONS="$(PROJ_SRC_DIR)/small_problem.dfg"
+else
+RUN_OPTIONS="$(PROJ_SRC_DIR)/problem.dfg"
+endif
+
+include ../../Makefile.multisrc
diff --git a/test/spass/README b/test/spass/README
new file mode 100644
index 0000000..efdfb84
--- /dev/null
+++ b/test/spass/README
@@ -0,0 +1,96 @@
+ Welcome to SPASS!
+ =================
+
+This is the generic README file for all SPASS distributions, so your downloaded
+package may only contain a subset of what is described here.
+
+
+ Important Files
+ ===============
+
+AUTHORS all authors that contributed to SPASS
+
+INSTALLATION for a guide to install the prover, man pages,
+ tools etc.; by default binaries are installed
+ in /usr/local/bin and man-pages in /usr/local/man;
+ use the prefix option of make install for a different
+ path
+
+COPYING for the licence agreement that you certify by
+ installation, its the GNU GENERAL PUBLIC LICENSE, Version 2
+
+VERSIONHISTORY changes starting from version 1.0.0
+
+README is this file
+
+
+
+
+ Programs
+ ========
+
+The distribution contains the following programs. Most
+of them give you a brief description if they are called
+without arguments. Most of the programs come with man-pages.
+
+SPASS is our prover for first-order logic with equality.
+
+FLOTTER translates first-order formulae into clauses; its
+ incorporated in SPASS and hence now only a link to
+ SPASS.
+
+pcs is our proof checker. NOTE that in its default settings
+ pcs needs an installation of otter for proof checking.
+ You can also employ SPASS itself for this purpose by the
+ -o option.
+
+pgen generates out of a SPASS proof file all subtasks needed
+ to guarantee the correctness of the proof.
+
+dfg2otter translates DFG-syntax input files into otter input files,
+ without any settings commands.
+
+dfg2otter.pl has the same functionality than dfg2otter but adds specific
+ settings that are useful if otter is employd as a proof checker
+ for SPASS.
+
+dfg2tptp translates DFG-syntax input files into TPTP input files.
+
+
+dfg2ascii provides an ASCII pretty print of DFG-syntax input files
+
+
+ Documentation
+ =============
+
+Besides the man pages, in the directory doc you'll find a description
+of our input syntax (spass-input-syntax.pdf), a small tutorial (tutorial.pdf)
+that is just a print out of our tutorial web page and the complete
+theory of SPASS (handbook-spass.pdf). Furthermore, there is a FAQ
+database (faq.txt).
+
+
+ Examples
+ ========
+
+In the examples directory you'll find some small examples. Further
+example collections can be downloaded from the SPASS homepage. By
+convention, files ending in ".dfg" are formula files and files ending
+in ".cnf" are files containing clauses.
+
+
+ WWW
+ ===
+
+Consider the SPASS homepage at
+
+ http://spass.mpi-sb.mpg.de/
+
+for recent developments, downloads etc.
+
+
+
+
+
+have SPASS
+ Christoph Weidenbach \ No newline at end of file
diff --git a/test/spass/VERSIONHISTORY b/test/spass/VERSIONHISTORY
new file mode 100644
index 0000000..448870c
--- /dev/null
+++ b/test/spass/VERSIONHISTORY
@@ -0,0 +1,135 @@
+Version: 1.0.1
+
+ - Fixed a bug in the atom definition support where it could happen
+ that variable dependencies between the atom definition and formulae
+ outside the definition are discarded.
+
+ - Fixed a bug in the renaming module, where in some cases a renaming
+ with non-zero benefit was not performed.
+
+Version: 1.0.2
+
+ - Fixed inconsistencies between the DFG proof format description in
+ dfgsyntax.ps and the actual implementation. Proof checking is more
+ more liberal, because the empty clause needs not to have the highest
+ clause number.
+
+Version: 1.0.3
+
+ - Sharpend renaming; it now potentially produces fewer clauses.
+
+Version: 1.0.4
+
+ - Changed some clause generation functions such that sequentially
+ applying FLOTTER, SPASS and just applying SPASS result in the
+ very same clause sets.
+
+ - Added the new tool dfg2dfg that supports transformations into
+ monadic clause classes and their further approximations.
+
+Version: 1.0.5
+
+ - Improved SPASS man pages: In particular, we added further detailed
+ explanations of inference rule flags and soft typing flags.
+
+ - Significantly improved modularity of the code by making the flagstore
+ object part of the proof search object; so there is no global flagstore
+ around anymore. These changes touched nearly all modules.
+
+ - Changed certain clause generation procedures such that now applying SPASS
+ directly to a formula or subsequent application of FLOTTER and SPASS produce
+ exactly the same ordering of a clause set (literlas). Since the behaviour of
+ SPASS is not independant from initial clause/literal orderings the changes
+ make SPASS results a little more robust/more predictable.
+ As all code was touched, we also included a code style review (comments,
+ prototypes, ...).
+
+ - Flag values given to SPASS are now checked and rejected if out of range.
+
+Version: 1.0.6
+
+ - Strengthened prototyping of functions in particular in the case of function
+ arguments. This resulted in specialized extra functions.
+
+ - Improved printing efficiency by replacing (f)printf calls with (f)puts calls
+ whenever possible.
+
+ - Removed the modul global precedence variable of the symbol modul and replaced
+ it by argument passing. The precedence is now stored in the proofsearch structure.
+ This affected huge parts of the SPASS code.
+
+ - Adjusted comments and code layout.
+
+ - Strengthened warnings for the gcc compiler.
+
+ - Increased usage of the string module.
+
+
+Version: 2.0.0
+
+ - Corrections to spellings, documentation.
+
+ - Added handbooks for SPASS and dfg2dfg.
+
+ - Added contextual rewriting.
+
+ - Added semantic tautology check.
+
+ - Fixed bugs in CNF translation: Renaming, Equation elimination rules.
+
+ - Improved splitting clause selection on the basis of reduction potential.
+
+ - Improved robustness of initial clause list ordering.
+
+ - Added the terminator module.
+
+ - Extended formula definition detection/expansion to so called guarded definitions.
+
+ - Improved determination of initial precedence such that as many as possible
+ equations in the input clause list can be oriented.
+
+ - Added mainloop without complete interreduction.
+
+ - Developed PROOFSEARCH data type enabling a modularization of the SPASS
+ source code on search engine level, such that several proof attempts can
+ now be run completely independantly at the same time within SPASS.
+
+ - Moved GUI to Qt 3.0. The GUI now also includes dfg2dfg and new even more
+ user friendly layout. The GUI runs on any platform where SPASS and Qt are
+ available.
+
+Version: 2.1
+
+ - Fixed a bug in the definition module. Formulae were not normalized before
+ application of the procedure, leading to wrong matchings of variables.
+
+ - Fixed a bug in the flag module. The subproof flagstore settings were not
+ complete: ordering flag and the weight flags were missing.
+
+ - Fixed a bug in dfgparser.y, where a missing semicolon with
+ bison version 1.75 now caused an error.
+
+ - Fixed a bug in cnf.c where the formula "equiv(false,false)" was
+ not properly treated in function cnf_RemoveTrivialAtoms.
+
+ - Fixed a bug in symbol_LowerSignature where capital 'A's and 'Z's were not
+ prefixed by a lowercase 'ss' due to their exclusion in the condition. This
+ caused problems in the result of dfg2tptp applied to dfg input files with
+ uppercase symbols starting with an 'A' or 'Z'.
+
+ - Now dfg2otter negates conjecture formulae of the SPASS input file
+ before printing the Otter usable list.
+
+ - Added man pages for dfg2ascii, dfg2otter and dfg2tptp.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/spass/analyze.c b/test/spass/analyze.c
new file mode 100644
index 0000000..dd47d0d
--- /dev/null
+++ b/test/spass/analyze.c
@@ -0,0 +1,774 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * ANALYSIS OF CLAUSE SETS * */
+/* * * */
+/* * $Module: ANALYZE * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include <stdio.h>
+
+#include "analyze.h"
+
+static LIST ana_CalculatePredicatePrecedence(LIST, LIST);
+static LIST ana_CalculateFunctionPrecedence(LIST, LIST, FLAGSTORE);
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+LIST ana_FINITEMONADICPREDICATES; /* List of monadic predicates with finite extension */
+
+BOOL ana_EQUATIONS; /* Problem contains any equations at all */
+static BOOL ana_PEQUATIONS; /* Problem contains positive equations */
+static BOOL ana_NEQUATIONS; /* Problem contains negative equations */
+static BOOL ana_FUNCTIONS; /* Problem contains non-constant function symbols */
+static BOOL ana_PROP; /* Problem contains propositional variables */
+static BOOL ana_GROUND; /* Problem contains non-propositional, non-equational ground atoms */
+static BOOL ana_NONUNIT; /* Problem contains non-unit clauses */
+static BOOL ana_MONADIC; /* Problem contains non-ground monadic predicates */
+static BOOL ana_NONMONADIC; /* Problem contains non-ground n-place predicates, n>1, not equality */
+BOOL ana_SORTRES; /* Problem contains literal not(S(x)) for some S */
+BOOL ana_USORTRES; /* Problem contains literal not(S(t)) for some S */
+static BOOL ana_FINDOMAIN; /* Problem contains clause implying a finite domain */
+static BOOL ana_NONTRIVDOMAIN; /* Problem contains clause implying a domain of size greater one */
+static BOOL ana_CONGROUND; /* Conjecture is ground */
+
+static BOOL ana_PUREEQUATIONAL; /* Problem is purely equational */
+static BOOL ana_PUREPROPOSITIONAL; /* Problem is purely propositional */
+
+BOOL ana_SORTDECEQUATIONS; /* True if all positive equations are sort decreasing with respect to
+ the static sort theory contained in the problem */
+static BOOL ana_SORTMANYEQUATIONS; /* True if all positive equations have the
+ same sort on left and right hand side with
+ respect to the static sort theory
+ contained in the problem */
+
+static NAT ana_AXIOMCLAUSES; /* Number of axiom clauses */
+static NAT ana_CONCLAUSES; /* Number of conjecture clauses */
+static NAT ana_NONHORNCLAUSES; /* Number of Non-Horn clauses */
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void ana_AnalyzeProblem(PROOFSEARCH Search, LIST Clauses)
+/**************************************************************
+ INPUT: A proofsearch object and a list of clauses.
+ RETURNS: Void.
+ EFFECT: Analyzes the clauses and sets the analyze variables.
+ Recomputes the weight for the clauses.
+ <Search> is modified according to clauses: non trivial domain number
+ is set
+***************************************************************/
+{
+ CLAUSE Clause;
+
+ ana_EQUATIONS = FALSE;
+ ana_PEQUATIONS = FALSE; /* Defaults for properties */
+ ana_NEQUATIONS = FALSE;
+ ana_FUNCTIONS = FALSE;
+ ana_FINDOMAIN = FALSE;
+ ana_NONTRIVDOMAIN = FALSE;
+ ana_MONADIC = FALSE;
+ ana_NONMONADIC = FALSE;
+ ana_PROP = FALSE;
+ ana_GROUND = FALSE;
+ ana_SORTRES = FALSE;
+ ana_USORTRES = FALSE;
+ ana_NONUNIT = FALSE;
+ ana_CONGROUND = TRUE;
+
+ ana_AXIOMCLAUSES = 0;
+ ana_CONCLAUSES = 0;
+ ana_NONHORNCLAUSES = 0;
+
+ list_Delete(ana_FINITEMONADICPREDICATES);
+ ana_FINITEMONADICPREDICATES = list_Nil();
+
+ if (list_Empty(Clauses))
+ return;
+
+ ana_FINITEMONADICPREDICATES = clause_FiniteMonadicPredicates(Clauses);
+
+ while (!list_Empty(Clauses)) {
+ Clause = (CLAUSE)list_Car(Clauses);
+ clause_UpdateWeight(Clause, prfs_Store(Search));
+
+ if (clause_GetFlag(Clause,CONCLAUSE))
+ ana_CONCLAUSES++;
+ else
+ ana_AXIOMCLAUSES++;
+
+ if (clause_NumOfSuccLits(Clause) > 1)
+ ana_NONHORNCLAUSES++;
+
+ if (ana_CONGROUND && clause_GetFlag(Clause,CONCLAUSE) &&
+ clause_MaxVar(Clause) != symbol_GetInitialStandardVarCounter())
+ ana_CONGROUND = FALSE;
+ if (!ana_PEQUATIONS && clause_ContainsPositiveEquations(Clause)) {
+ ana_PEQUATIONS = TRUE;
+ }
+ if (!ana_NEQUATIONS && clause_ContainsNegativeEquations(Clause)) {
+ ana_NEQUATIONS = TRUE;
+ }
+ if (!ana_MONADIC || !ana_NONMONADIC || !ana_PROP || !ana_GROUND)
+ clause_ContainsFolAtom(Clause,&ana_PROP,&ana_GROUND,&ana_MONADIC,&ana_NONMONADIC);
+
+ if (!ana_FUNCTIONS && clause_ContainsFunctions(Clause)) {
+ ana_FUNCTIONS = TRUE;
+ }
+ if (!ana_FINDOMAIN && clause_ImpliesFiniteDomain(Clause)) {
+ ana_FINDOMAIN = TRUE;
+ }
+ if (!ana_NONTRIVDOMAIN && clause_ImpliesNonTrivialDomain(Clause)) {
+ prfs_SetNonTrivClauseNumber(Search, clause_Number(Clause));
+ ana_NONTRIVDOMAIN = TRUE;
+ }
+ if (!ana_NONUNIT && clause_Length(Clause) > 1) {
+ ana_NONUNIT = TRUE;
+ }
+ if (!ana_SORTRES || !ana_USORTRES)
+ clause_ContainsSortRestriction(Clause,&ana_SORTRES,&ana_USORTRES);
+
+ Clauses = list_Cdr(Clauses);
+ }
+
+ ana_PUREEQUATIONAL = ((ana_PEQUATIONS || ana_NEQUATIONS) && !ana_MONADIC &&
+ !ana_NONMONADIC && !ana_PROP && !ana_GROUND);
+ ana_EQUATIONS = (ana_PEQUATIONS || ana_NEQUATIONS);
+ ana_PUREPROPOSITIONAL = (!ana_PEQUATIONS && !ana_NEQUATIONS &&!ana_MONADIC &&
+ !ana_NONMONADIC && ana_PROP);
+}
+
+
+void ana_AnalyzeSortStructure(LIST Clauses, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A list of clauses, a flag store and a precedence.
+ RETURNS: Nothing.
+ EFFECT: The sort structure with respect to equations is analyzed.
+ It is detected whether all equations are many sorted or
+ sort decreasing.
+***************************************************************/
+{
+ if (ana_PEQUATIONS && ana_SORTRES) {
+ STR Result;
+ Result = sort_AnalyzeSortStructure(Clauses,Flags,Precedence);
+ ana_SORTMANYEQUATIONS = (Result == SORTEQMANY);
+ ana_SORTDECEQUATIONS = (Result == SORTEQMANY || Result == SORTEQDECR);
+ }
+}
+
+
+void ana_Print(FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A flag store and a precedence.
+ RETURNS: Nothing.
+ EFFECT: The results of an analysis stored in the module variables
+ is printed to stdout.
+***************************************************************/
+{
+ const char* Horn;
+
+ if (ana_NONHORNCLAUSES == 0)
+ Horn = "Horn";
+ else
+ Horn = "Non-Horn";
+
+ if (ana_MONADIC && !ana_NONMONADIC) {
+ printf("\n This is a monadic %s problem",Horn);
+ if (ana_PEQUATIONS || ana_NEQUATIONS)
+ fputs(" with equality.", stdout);
+ else
+ fputs(" without equality.", stdout);
+ }
+ else
+ if (ana_PEQUATIONS || ana_NEQUATIONS) {
+ if (ana_NONMONADIC || ana_MONADIC || ana_PROP)
+ printf("\n This is a first-order %s problem containing equality.",Horn);
+ else
+ if (ana_NONUNIT)
+ printf("\n This is a pure equality %s problem.",Horn);
+ else
+ fputs("\n This is a unit equality problem.", stdout);
+ }
+ else
+ if (ana_NONMONADIC || ana_MONADIC)
+ printf("\n This is a first-order %s problem without equality.",Horn);
+
+ if (ana_PUREPROPOSITIONAL)
+ printf("\n This is a propositional %s problem.",Horn);
+ else
+ if (ana_FINDOMAIN || !ana_FUNCTIONS) {
+ fputs("\n This is a problem that has, if any, a finite domain model.",
+ stdout);
+ if (ana_FINDOMAIN)
+ fputs("\n There is a finite domain clause.", stdout);
+ if (!ana_FUNCTIONS)
+ fputs("\n There are no function symbols.", stdout);
+ }
+
+ if (ana_NONTRIVDOMAIN)
+ fputs("\n This is a problem that has, if any, a non-trivial domain model.",
+ stdout);
+
+
+ if (ana_SORTRES) {
+ fputs("\n This is a problem that contains sort information.", stdout);
+ if (ana_PEQUATIONS) {
+ if (ana_SORTMANYEQUATIONS)
+ fputs("\n All equations are many sorted.", stdout);
+ else {
+ if (ana_SORTDECEQUATIONS)
+ fputs("\n All equations are sort-decreasing.", stdout);
+ }
+ }
+ }
+
+ if (ana_CONCLAUSES > 0 && ana_CONGROUND && !ana_PUREPROPOSITIONAL)
+ fputs("\n The conjecture is ground.", stdout);
+
+ if (!list_Empty(ana_FINITEMONADICPREDICATES)) {
+ LIST Scan;
+ fputs("\n The following monadic predicates have finite extensions: ", stdout);
+ for (Scan=ana_FINITEMONADICPREDICATES;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ symbol_Print((SYMBOL)list_Car(Scan));
+ if (!list_Empty(list_Cdr(Scan)))
+ fputs(", ", stdout);
+ }
+ putchar('.');
+ }
+
+ printf("\n Axiom clauses: %d Conjecture clauses: %d",ana_AXIOMCLAUSES,ana_CONCLAUSES);
+
+ flag_PrintInferenceRules(Flags);
+ flag_PrintReductionRules(Flags);
+ fputs("\n Extras : ", stdout);
+ if (flag_GetFlagValue(Flags, flag_SATINPUT))
+ fputs("Input Saturation, ", stdout);
+ else
+ fputs("No Input Saturation, ", stdout);
+ if (flag_GetFlagValue(Flags, flag_SELECT) == flag_SELECTOFF)
+ fputs("No Selection, ", stdout);
+ else
+ if (flag_GetFlagValue(Flags, flag_SELECT) == flag_SELECTIFSEVERALMAXIMAL)
+ fputs("Dynamic Selection, ", stdout);
+ else
+ fputs("Always Selection, ", stdout);
+ if (flag_GetFlagValue(Flags, flag_SPLITS) == flag_SPLITSUNLIMITED)
+ fputs("Full Splitting, ", stdout);
+ else
+ if (flag_GetFlagValue(Flags, flag_SPLITS) == flag_SPLITSOFF)
+ fputs("No Splitting, ", stdout);
+ else
+ printf("Maximum of %d Splits, ",flag_GetFlagValue(Flags, flag_SPLITS));
+ if (flag_GetFlagValue(Flags, flag_FULLRED))
+ fputs("Full Reduction, ", stdout);
+ else
+ fputs("Lazy Reduction, ", stdout);
+ printf(" Ratio: %d, FuncWeight: %d, VarWeight: %d",
+ flag_GetFlagValue(Flags, flag_WDRATIO),
+ flag_GetFlagValue(Flags, flag_FUNCWEIGHT),
+ flag_GetFlagValue(Flags, flag_VARWEIGHT));
+ fputs("\n Precedence: ", stdout);
+ fol_PrintPrecedence(Precedence);
+ fputs("\n Ordering : ", stdout);
+ fputs(flag_GetFlagValue(Flags, flag_ORD) == flag_ORDKBO ? "KBO" : "RPOS",
+ stdout);
+}
+
+
+void ana_AutoConfiguration(LIST Clauses, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A list of clauses, a flag store and a precedence.
+ RETURNS: Nothing.
+ EFFECT: Based on the values of the ana analysis module, an appropriate
+ complete configuration of inference, reduction rules and other
+ settings is established.
+***************************************************************/
+{
+ LIST Scan, Functions, Predicates, Constants;
+
+ Functions = symbol_GetAllFunctions();
+ Predicates = fol_GetNonFOLPredicates();
+
+ /* Set precedence */
+ Predicates = ana_CalculatePredicatePrecedence(Predicates, Clauses);
+ Functions = ana_CalculateFunctionPrecedence(Functions, Clauses, Flags);
+ Constants = list_Nil();
+
+ for (Scan=Functions; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (symbol_IsConstant((SYMBOL)list_Car(Scan)))
+ Constants = list_Cons(list_Car(Scan),Constants);
+ Functions = list_NPointerDifference(Functions,Constants);
+ Constants = list_NReverse(Constants);
+
+ for ( ; !list_Empty(Functions); Functions = list_Pop(Functions))
+ symbol_SetIncreasedOrdering(Precedence, (SYMBOL)list_Car(Functions));
+ /* Predicates < Functions */
+ for ( ; !list_Empty(Predicates); Predicates = list_Pop(Predicates))
+ symbol_SetIncreasedOrdering(Precedence, (SYMBOL)list_Car(Predicates));
+ /* Constants < Predicates */
+ /* Predicates < Functions */
+ for ( ; !list_Empty(Constants); Constants = list_Pop(Constants))
+ symbol_SetIncreasedOrdering(Precedence, (SYMBOL)list_Car(Constants));
+
+ flag_ClearInferenceRules(Flags);
+ flag_ClearReductionRules(Flags);
+
+ flag_SetFlagValue(Flags, flag_ROBV, flag_ROBVON);
+ flag_SetFlagValue(Flags, flag_RTAUT, flag_RTAUTSYNTACTIC);
+ flag_SetFlagValue(Flags, flag_RFSUB, flag_RFSUBON);
+ flag_SetFlagValue(Flags, flag_RBSUB, flag_RBSUBON);
+ flag_SetFlagValue(Flags, flag_RFMRR, flag_RFMRRON);
+ flag_SetFlagValue(Flags, flag_RBMRR, flag_RBMRRON);
+ flag_SetFlagValue(Flags, flag_RUNC, flag_RUNCON);
+ flag_SetFlagValue(Flags, flag_FULLRED, flag_FULLREDON);
+ /*flag_SetFlagValue(Flags, flag_FUNCWEIGHT,1);
+ flag_SetFlagValue(Flags, flag_VARWEIGHT,1);*/
+ flag_SetFlagValue(Flags, flag_WDRATIO,5);
+
+ if (ana_NEQUATIONS) {
+ flag_SetFlagValue(Flags, flag_IEQR, flag_EQUALITYRESOLUTIONON);
+ if (ana_NONUNIT) {
+ if (ana_NONTRIVDOMAIN)
+ flag_SetFlagValue(Flags, flag_RAED, flag_RAEDPOTUNSOUND);
+ else
+ flag_SetFlagValue(Flags, flag_RAED, flag_RAEDSOUND);
+ }
+ }
+
+ if (ana_PEQUATIONS) {
+ flag_SetFlagValue(Flags, flag_ISPR, flag_SUPERPOSITIONRIGHTON);
+ flag_SetFlagValue(Flags, flag_ISPL, flag_SUPERPOSITIONLEFTON);
+ if (ana_NONHORNCLAUSES > 0)
+ flag_SetFlagValue(Flags, flag_IEQF, flag_EQUALITYFACTORINGON);
+ if (ana_NONUNIT)
+ flag_SetFlagValue(Flags, flag_RCON, flag_RCONON);
+ flag_SetFlagValue(Flags, flag_RFREW, flag_RFREWON);
+ flag_SetFlagValue(Flags, flag_RBREW, flag_RBREWON);
+ flag_SetFlagValue(Flags, flag_RFCRW, flag_RFCRWOFF); /* Here we could activate contextual rewriting */
+ flag_SetFlagValue(Flags, flag_RBCRW, flag_RBCRWOFF);
+ }
+
+ if (ana_SORTRES) {
+ flag_SetFlagValue(Flags, flag_SORTS, flag_SORTSMONADICWITHVARIABLE);
+ flag_SetFlagValue(Flags, flag_IEMS, flag_EMPTYSORTON);
+ flag_SetFlagValue(Flags, flag_ISOR, flag_SORTRESOLUTIONON);
+ flag_SetFlagValue(Flags, flag_RSSI, flag_RSSION);
+ if (!ana_PEQUATIONS || ana_SORTMANYEQUATIONS)
+ flag_SetFlagValue(Flags, flag_RSST, flag_RSSTON);
+ }
+ else
+ flag_SetFlagValue(Flags, flag_SORTS, flag_SORTSOFF);
+
+ if (ana_MONADIC || ana_NONMONADIC) { /* Problem contains real predicates */
+ flag_SetFlagValue(Flags, flag_IORE, flag_ORDEREDRESOLUTIONNOEQUATIONS);
+ if (ana_NONHORNCLAUSES > 0)
+ flag_SetFlagValue(Flags, flag_IOFC, flag_FACTORINGONLYRIGHT);
+ if (ana_NONUNIT)
+ flag_SetFlagValue(Flags, flag_RCON, flag_RCONON);
+ }
+
+
+ if (!ana_FUNCTIONS)
+ flag_SetFlagValue(Flags, flag_SELECT, flag_SELECTALWAYS);
+ else
+ if (ana_NONUNIT)
+ flag_SetFlagValue(Flags, flag_SELECT, flag_SELECTIFSEVERALMAXIMAL);
+ else
+ flag_SetFlagValue(Flags, flag_SELECT, flag_SELECTOFF);
+
+ if (ana_CONCLAUSES < ana_AXIOMCLAUSES || (ana_CONGROUND && !ana_PUREPROPOSITIONAL))
+ flag_SetFlagValue(Flags, flag_SATINPUT, flag_SATINPUTON);
+ else
+ flag_SetFlagValue(Flags, flag_SATINPUT, flag_SATINPUTOFF);
+
+ if (ana_NONHORNCLAUSES > 0)
+ flag_SetFlagValue(Flags, flag_SPLITS, flag_SPLITSUNLIMITED);
+ else
+ flag_SetFlagValue(Flags, flag_SPLITS, flag_SPLITSOFF);
+}
+
+
+void ana_ExploitSortAnalysis(FLAGSTORE Flags)
+/**************************************************************
+ INPUT: A flag store.
+ EFFECT: If all equations are many sorted and or no positive
+ equations occur at all and the problem contains sort
+ information, static soft typing is activated.
+***************************************************************/
+{
+ if (ana_SORTRES && (!ana_PEQUATIONS || ana_SORTMANYEQUATIONS))
+ flag_SetFlagValue(Flags, flag_RSST, flag_RSSTON);
+}
+
+
+static LIST ana_CalculatePredicatePrecedence(LIST Predicates, LIST Clauses)
+/**************************************************************
+ INPUT: A list of predicates and a list of clauses.
+ RETURNS: A list of predicate symbols, which should be used
+ for setting the symbol precedence. The list is sorted
+ in descending order, that means predicates with highest
+ precedence come first.
+ EFFECT: Analyze the clause list to build a directed graph G where
+ the predicates are vertices. There's an edge (P,Q) in
+ G iff a clause exists where P is a negative literal
+ and Q is a positive literal and P != Q. Apply DFS to
+ find the strongly connected components of this graph.
+ The <Predicates> list is deleted.
+ CAUTION: The predicate list must contain ALL predicates
+ occurring in the clause list!
+***************************************************************/
+{
+ GRAPH graph;
+ LIST result, scan;
+ int i, j;
+ NAT count;
+ SYMBOL s;
+
+ /* clause_ListPrint(Clauses); DBG */
+
+ if (list_Empty(Predicates)) {
+ return Predicates;
+ }
+
+ graph = graph_Create();
+
+ /* First create the nodes: one node for every predicate symbol. */
+ for ( ; !list_Empty(Predicates); Predicates = list_Pop(Predicates))
+ graph_AddNode(graph, symbol_Index((SYMBOL)list_Car(Predicates)));
+
+ /* Now scan the clause clause list to create the edges */
+ /* An edge (P,Q) means P is smaller than Q */
+ for (scan = Clauses; !list_Empty(scan); scan = list_Cdr(scan)) {
+ CLAUSE c = list_Car(scan);
+
+ for (i = clause_FirstLitIndex(); i < clause_FirstSuccedentLitIndex(c); i++) {
+ SYMBOL negPred = term_TopSymbol(clause_GetLiteralAtom(c, i));
+ if (!symbol_Equal(negPred, fol_Equality())) { /* negative predicate */
+ for (j = clause_FirstSuccedentLitIndex(c); j < clause_Length(c); j++) {
+ SYMBOL posPred = term_TopSymbol(clause_GetLiteralAtom(c, j));
+ if (!symbol_Equal(posPred, fol_Equality()) && /* positive predicate */
+ negPred != posPred) { /* No self loops! */
+ graph_AddEdge(graph_GetNode(graph, symbol_Index(negPred)),
+ graph_GetNode(graph, symbol_Index(posPred)));
+ }
+ }
+ }
+ }
+ }
+
+ /* graph_Print(graph); fflush(stdout); DBG */
+
+ /* Calculate the strongly connected components of the graph */
+ count = graph_StronglyConnectedComponents(graph);
+
+ /* Now create the precedence list by scanning the nodes. */
+ /* If there's a link between two strongly connected components */
+ /* c1 and c2 then component_num(c1) > component_num(c2), so the */
+ /* following code creates a valid precedence list in descending */
+ /* order. */
+ result = list_Nil();
+ for (i = count - 1; i >= 0; i--) {
+ for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+ GRAPHNODE n = list_Car(scan);
+ if (graph_NodeCompNum(n) == i) {
+ /* The symbol represented by the node <<n> belongs to component <i> */
+ s = symbol_GetSigSymbol(graph_NodeNumber(n));
+ result = list_Cons((POINTER)s, result);
+ }
+ }
+ }
+
+ /* putchar('\n');
+ for (scan = result; !list_Empty(scan); scan = list_Cdr(scan)) {
+ s = (SYMBOL) list_Car(scan);
+ symbol_Print(s);
+ putchar(' ');
+ }
+ putchar('\n'); fflush(stdout); DBG */
+
+ graph_Delete(graph);
+
+ return result;
+}
+
+
+/* We use the node info to store the degree of the node */
+static __inline__ NAT ana_NodeDegree(GRAPHNODE Node)
+{
+ return (NAT)graph_NodeInfo(Node);
+}
+
+
+static __inline__ void ana_IncNodeDegree(GRAPHNODE Node)
+{
+ graph_NodeSetInfo(Node, (POINTER)(ana_NodeDegree(Node)+1));
+}
+
+static BOOL ana_NodeGreater(GRAPHNODE N1, GRAPHNODE N2)
+/**************************************************************
+ INPUT: Two graph nodes.
+ RETURNS: TRUE, if N1 is greater than N2.
+ EFFECT: This function is used to sort the node list
+ of the graph in ana_CalculateFunctionPrecedence.
+***************************************************************/
+{
+ return (symbol_Arity(symbol_GetSigSymbol(graph_NodeNumber(N1))) >
+ symbol_Arity(symbol_GetSigSymbol(graph_NodeNumber(N2))));
+}
+
+
+static BOOL ana_BidirectionalDistributivity(LIST SymbolPairs)
+/**************************************************************
+ INPUT: A list of symbol pairs defining distributivity.
+ RETURNS: TRUE, if the list contains two pairs (s1, s2) and (s2, s1)
+ FALSE otherwise.
+ EFFECT: This function is used to detect symbols that are distributive
+ in both directions, logical OR and AND for example.
+***************************************************************/
+{
+ LIST scan, actPair, nextPair;
+
+ for ( ; !list_Empty(SymbolPairs); SymbolPairs = list_Cdr(SymbolPairs)) {
+ actPair = list_Car(SymbolPairs);
+ /* If actPair = (s1, s2), check whether there's a pair (s2, s1) in list */
+ for (scan = list_Cdr(SymbolPairs); !list_Empty(scan); scan = list_Cdr(scan)) {
+ nextPair = list_Car(scan);
+ if (symbol_Equal((SYMBOL)list_PairFirst(actPair),(SYMBOL)list_PairSecond(nextPair)) &&
+ symbol_Equal((SYMBOL)list_PairSecond(actPair),(SYMBOL)list_PairFirst(nextPair)))
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+static LIST ana_CalculateFunctionPrecedence(LIST Functions, LIST Clauses,
+ FLAGSTORE Flags)
+/**************************************************************
+ INPUT: A list of functions, a list of clauses and
+ a flag store.
+ RETURNS: A list of function symbols, which should be used
+ for setting the symbol precedence. The list is sorted
+ in descending order, that means function with highest
+ precedence come first.
+ EFFECT: Analyzes the clauses to build a directed graph G with
+ function symbol as nodes. An edge (f,g) or in G means
+ f should have lower precedence than g.
+ An edge (f,g) or (g,f) is created if there's an equation
+ equal(f(...), g(...)) in the clause list.
+ The direction of the edge depends on the degree of the
+ nodes and the symbol arity.
+ Then find the strongly connected components of this
+ graph.
+ The "Ordering" flag will be set in the flag store.
+ CAUTION: The value of "ana_PEQUATIONS" must be up to date.
+***************************************************************/
+{
+ GRAPH graph;
+ GRAPHNODE n1, n2;
+ LIST result, scan, scan2, distrPairs;
+ NAT i, j;
+ SYMBOL s, Add, Mult;
+
+ if (list_Empty(Functions))
+ return Functions; /* Problem contains no functions */
+ else if (!ana_PEQUATIONS) {
+ Functions = list_NumberSort(Functions, (NAT (*)(POINTER)) symbol_PositiveArity);
+ return Functions;
+ }
+
+ graph = graph_Create();
+ /* First create the nodes: one node for every function symbol. */
+ for (; !list_Empty(Functions); Functions = list_Pop(Functions))
+ graph_AddNode(graph, symbol_Index((SYMBOL)list_Car(Functions)));
+
+ /* Now sort the node list wrt descending symbol arity. */
+ graph_SortNodes(graph, ana_NodeGreater);
+
+ /* A list of pairs (add, multiply) of distributive symbols */
+ distrPairs = list_Nil();
+
+ /* Now add undirected edges: there's an undirected edge between */
+ /* two nodes if the symbols occur as top symbols in a positive */
+ /* equation. */
+ for (scan = Clauses; !list_Empty(scan); scan = list_Cdr(scan)) {
+ CLAUSE c = list_Car(scan);
+ for (i = clause_FirstSuccedentLitIndex(c);
+ i <= clause_LastSuccedentLitIndex(c); i++) {
+ if (clause_LiteralIsEquality(clause_GetLiteral(c, i))) {
+ /* Consider only positive equations */
+ TERM t1, t2;
+
+ if (fol_DistributiveEquation(clause_GetLiteralAtom(c,i), &Add, &Mult)) {
+ /* Add a pair (Add, Mult) to <distrTerms> */
+ distrPairs = list_Cons(list_PairCreate((POINTER)Add, (POINTER)Mult),
+ distrPairs);
+ /*fputs("\nDISTRIBUTIVITY: ", stdout);
+ term_PrintPrefix(clause_GetLiteralAtom(c,i));
+ fputs(" Add=", stdout); symbol_Print(Add);
+ fputs(" Mult=", stdout); symbol_Print(Mult); fflush(stdout); DBG */
+ }
+
+ t1 = term_FirstArgument(clause_GetLiteralAtom(c, i));
+ t2 = term_SecondArgument(clause_GetLiteralAtom(c, i));
+
+ if (!term_IsVariable(t1) && !term_IsVariable(t2) &&
+ !term_EqualTopSymbols(t1, t2) && /* No self loops! */
+ !term_HasSubterm(t1, t2) && /* No subterm property */
+ !term_HasSubterm(t2, t1)) {
+ n1 = graph_GetNode(graph, symbol_Index(term_TopSymbol(t1)));
+ n2 = graph_GetNode(graph, symbol_Index(term_TopSymbol(t2)));
+ /* Create an undirected edge by adding two directed edges */
+ graph_AddEdge(n1, n2);
+ graph_AddEdge(n2, n1);
+ /* Use the node info for the degree of the node */
+ ana_IncNodeDegree(n1);
+ ana_IncNodeDegree(n2);
+ }
+ }
+ }
+ }
+
+ /* putchar('\n');
+ for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+ n1 = list_Car(scan);
+ printf("(%s,%d,%u), ",
+ symbol_Name(symbol_GetSigSymbol(graph_NodeNumber(n1))),
+ graph_NodeNumber(n1), ana_NodeDegree(n1));
+ }
+ graph_Print(graph); fflush(stdout); DBG */
+
+ graph_DeleteDuplicateEdges(graph);
+
+ /* Transform the undirected graph into a directed graph. */
+ for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+ n1 = list_Car(scan);
+ result = list_Nil(); /* Collect edges from n1 that shall be deleted */
+ for (scan2 = graph_NodeNeighbors(n1); !list_Empty(scan2);
+ scan2 = list_Cdr(scan2)) {
+ int a1, a2;
+ n2 = list_Car(scan2);
+ /* Get the node degrees in the undirected graph with multiple edges */
+ i = ana_NodeDegree(n1);
+ j = ana_NodeDegree(n2);
+ a1 = symbol_Arity(symbol_GetSigSymbol(graph_NodeNumber(n1)));
+ a2 = symbol_Arity(symbol_GetSigSymbol(graph_NodeNumber(n2)));
+
+ if (i > j || (i==j && a1 >= a2)) {
+ /* symbol2 <= symbol1, so remove edge n1 -> n2 */
+ result = list_Cons(n2, result);
+ }
+ if (i < j || (i==j && a1 <= a2)) {
+ /* symbol1 <= symbol2, so remove edge n2 -> n1 */
+ graph_DeleteEdge(n2, n1);
+ }
+ /* NOTE: If (i==j && a1==a2) both edges are deleted! */
+ }
+ /* Now delete edges from n1 */
+ for ( ; !list_Empty(result); result = list_Pop(result))
+ graph_DeleteEdge(n1, list_Car(result));
+ }
+
+ if (!list_Empty(distrPairs) && !ana_BidirectionalDistributivity(distrPairs)) {
+ /* Enable RPO ordering, otherwise the default KBO will be used. */
+ flag_SetFlagValue(Flags, flag_ORD, flag_ORDRPOS);
+ }
+
+ /* Now examine the list of distribute symbols */
+ /* since they've highest priority. */
+ for ( ; !list_Empty(distrPairs); distrPairs = list_Pop(distrPairs)) {
+ scan = list_Car(distrPairs); /* A pair (Add, Mult) */
+ /* Addition */
+ n1 = graph_GetNode(graph,
+ symbol_Index((SYMBOL)list_PairFirst(scan)));
+ /* Multiplication */
+ n2 = graph_GetNode(graph,
+ symbol_Index((SYMBOL)list_PairSecond(scan)));
+ /* Remove any edges between n1 and n2 */
+ graph_DeleteEdge(n1, n2);
+ graph_DeleteEdge(n2, n1);
+ /* Add one edge Addition -> Multiplication */
+ graph_AddEdge(n1, n2);
+ list_PairFree(scan);
+ }
+
+ /* fputs("\n------------------------",stdout);
+ graph_Print(graph); fflush(stdout); DBG */
+
+ /* Calculate the strongly connected components of the graph. */
+ /* <i> is the number of SCCs. */
+ i = graph_StronglyConnectedComponents(graph);
+
+ /* Now create the precedence list by scanning the nodes. */
+ /* If there's a link between two strongly connected components */
+ /* c1 and c2 then component_num(c1) > component_num(c2), so the */
+ /* following code creates a valid precedence list in descending */
+ /* order. */
+ result = list_Nil();
+ while (i-- > 0) { /* for i = numberOfSCCs -1 dowto 0 */
+ for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+ n1 = list_Car(scan);
+ if (graph_NodeCompNum(n1) == i) {
+ /* The symbol represented by the node <n> belongs to component <i> */
+ s = symbol_GetSigSymbol(graph_NodeNumber(n1));
+ result = list_Cons((POINTER)s, result);
+ }
+ }
+ }
+
+ /* putchar('\n');
+ for (scan = result; !list_Empty(scan); scan = list_Cdr(scan)) {
+ s = (SYMBOL) list_Car(scan);
+ symbol_Print(s);
+ fputs(" > ", stdout);
+ }
+ putchar('\n'); fflush(stdout); DBG */
+
+ graph_Delete(graph);
+
+ return result;
+}
diff --git a/test/spass/analyze.h b/test/spass/analyze.h
new file mode 100644
index 0000000..a44c893
--- /dev/null
+++ b/test/spass/analyze.h
@@ -0,0 +1,121 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * ANALYSIS OF CLAUSE SETS * */
+/* * * */
+/* * $Module: ANALYZE * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _ANALYZE_
+#define _ANALYZE_
+
+#include "search.h"
+#include "clause.h"
+#include "sort.h"
+#include "list.h"
+#include "graph.h"
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+extern BOOL ana_EQUATIONS;
+extern BOOL ana_SORTRES;
+extern BOOL ana_USORTRES;
+extern BOOL ana_SORTDECEQUATIONS;
+
+extern LIST ana_FINITEMONADICPREDICATES;
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+static __inline__ BOOL ana_Equations(void)
+{
+ return ana_EQUATIONS;
+}
+
+static __inline__ BOOL ana_SortRestrictions(void)
+{
+ return ana_SORTRES;
+}
+
+static __inline__ BOOL ana_UnsolvedSortRestrictions(void)
+{
+ return ana_USORTRES;
+}
+
+static __inline__ BOOL ana_SortDecreasing(void)
+{
+ return ana_SORTDECEQUATIONS;
+}
+
+static __inline__ void ana_Init(void)
+{
+ ana_FINITEMONADICPREDICATES = list_Nil();
+}
+
+static __inline__ void ana_Free(void)
+{
+ list_Delete(ana_FINITEMONADICPREDICATES);
+}
+
+static __inline__ LIST ana_FinMonPredList(void)
+{
+ return ana_FINITEMONADICPREDICATES;
+}
+
+
+
+
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+void ana_AnalyzeProblem(PROOFSEARCH, LIST);
+void ana_AnalyzeSortStructure(LIST, FLAGSTORE, PRECEDENCE);
+void ana_AutoConfiguration(LIST, FLAGSTORE, PRECEDENCE);
+void ana_ExploitSortAnalysis(FLAGSTORE);
+void ana_Print(FLAGSTORE, PRECEDENCE);
+
+#endif
diff --git a/test/spass/approx.h b/test/spass/approx.h
new file mode 100644
index 0000000..5e50d39
--- /dev/null
+++ b/test/spass/approx.h
@@ -0,0 +1,61 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CLAUSE APPROXIMATION * */
+/* * * */
+/* * $Module: APPROX * */
+/* * * */
+/* * Copyright (C) 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+#ifndef _APPROX_
+#define _APPROX_
+
+#include "list.h"
+#include "clause.h"
+
+void approx_Init(void);
+
+LIST approx_MonadicByProjection(LIST, FLAGSTORE, PRECEDENCE);
+LIST approx_MonadicByTermEncoding(LIST, FLAGSTORE, PRECEDENCE);
+LIST approx_MonadicMakeLinear(LIST, FLAGSTORE, PRECEDENCE);
+LIST approx_HornMonadicFlattenHeads(CLAUSE, BOOL, BOOL, FLAGSTORE, PRECEDENCE);
+LIST approx_MakeHorn(CLAUSE, FLAGSTORE, PRECEDENCE);
+
+#endif
diff --git a/test/spass/clause.c b/test/spass/clause.c
new file mode 100644
index 0000000..6b2e3f6
--- /dev/null
+++ b/test/spass/clause.c
@@ -0,0 +1,5008 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CLAUSES * */
+/* * * */
+/* * $Module: CLAUSE * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "clause.h"
+
+/**************************************************************/
+/* Global variables and constants */
+/**************************************************************/
+
+/* Means weight of literal or clause is undefined */
+const NAT clause_WEIGHTUNDEFINED = NAT_MAX;
+
+int clause_CLAUSECOUNTER;
+NAT clause_STAMPID;
+
+/* The following array is used for bucket sort on clauses */
+#define clause_MAXWEIGHT 20
+LIST clause_SORT[clause_MAXWEIGHT+1];
+
+/**************************************************************/
+/* Inline functions */
+/**************************************************************/
+
+static __inline__ void clause_FreeLitArray(CLAUSE Clause)
+{
+ NAT Length = clause_Length(Clause);
+ if (Length > 0)
+ memory_Free(Clause->literals, sizeof(LITERAL) * Length);
+}
+
+
+/**************************************************************/
+/* Primitive literal functions */
+/**************************************************************/
+
+BOOL clause_LiteralIsLiteral(LITERAL Literal)
+/*********************************************************
+ INPUT: A literal.
+ RETURNS: TRUE, if 'Literal' is not NULL and has a predicate
+ symbol as its atoms top symbol.
+**********************************************************/
+{
+ return ((Literal != NULL) &&
+ symbol_IsPredicate(clause_LiteralPredicate(Literal)));
+}
+
+NAT clause_LiteralComputeWeight(LITERAL Literal, FLAGSTORE Flags)
+/*********************************************************
+ INPUT: A literal and a flag store.
+ RETURNS: The weight of the literal.
+ CAUTION: This function does not update the weight of the literal!
+**********************************************************/
+{
+ TERM Term;
+ int Bottom;
+ NAT Number;
+
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Literal)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralComputeWeight :");
+ misc_ErrorReport("Illegal Input. Input not a literal.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Term = clause_LiteralSignedAtom(Literal);
+ Bottom = stack_Bottom();
+ Number = 0;
+
+ do {
+ if (term_IsComplex(Term)) {
+ Number += flag_GetFlagValue(Flags, flag_FUNCWEIGHT);
+ stack_Push(term_ArgumentList(Term));
+ }
+ else
+ if (term_IsVariable(Term))
+ Number += flag_GetFlagValue(Flags, flag_VARWEIGHT);
+ else
+ Number += flag_GetFlagValue(Flags, flag_FUNCWEIGHT);
+
+ while (!stack_Empty(Bottom) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Bottom)) {
+ Term = (TERM) list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Bottom));
+
+ return Number;
+
+}
+
+LITERAL clause_LiteralCreate(TERM Atom, CLAUSE Clause)
+/**********************************************************
+ INPUT: A Pointer to a signed Predicate-Term and one to a
+ clause it shall belong to.
+ RETURNS: An appropriate literal where the other values
+ are set to default values.
+ MEMORY: A LITERAL_NODE is allocated.
+ CAUTION: The weight of the literal is not set correctly!
+***********************************************************/
+{
+ LITERAL Result;
+
+#ifdef CHECK
+ if (!term_IsTerm(Atom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralCreate:");
+ misc_ErrorReport("\n Illegal input. Input not a term.");
+ misc_FinishErrorReport();
+ }
+ if (!symbol_IsPredicate(term_TopSymbol(Atom)) &&
+ (term_TopSymbol(Atom) != fol_Not())) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralCreate:");
+ misc_ErrorReport("\n Illegal input. No predicate- or negated term.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = (LITERAL)memory_Malloc(sizeof(LITERAL_NODE));
+
+ Result->atomWithSign = Atom;
+ Result->oriented = FALSE;
+ Result->weight = clause_WEIGHTUNDEFINED;
+ Result->maxLit = 0;
+ Result->owningClause = Clause;
+
+ return Result;
+}
+
+
+LITERAL clause_LiteralCreateNegative(TERM Atom, CLAUSE Clause)
+/**********************************************************
+ INPUT: A Pointer to a unsigned Predicate-Term and one to a
+ clause it shall belong to.
+ RETURNS: An appropriate literal where the other values
+ are set to default values and the term gets a sign.
+ MEMORY: A LITERAL_NODE is allocated.
+ CAUTION: The weight of the literal is not set correctly!
+***********************************************************/
+{
+ LITERAL Result;
+
+#ifdef CHECK
+ if (!term_IsTerm(Atom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralCreateNegative:");
+ misc_ErrorReport("\n Illegal input. Input not an atom.");
+ misc_FinishErrorReport();
+ }
+ if (!symbol_IsPredicate(term_TopSymbol(Atom)) &&
+ (term_TopSymbol(Atom) != fol_Not())) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralCreateNegative:");
+ misc_ErrorReport("\n Illegal input. Input term not normalized.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = (LITERAL)memory_Malloc(sizeof(LITERAL_NODE));
+
+ term_RplacSupertermList(Atom, list_Nil());
+
+ Result->atomWithSign = term_Create(fol_Not(), list_List(Atom));
+ Result->oriented = FALSE;
+ Result->maxLit = 0;
+ Result->weight = clause_WEIGHTUNDEFINED;
+ Result->owningClause = Clause;
+
+ return Result;
+}
+
+
+void clause_LiteralDelete(LITERAL Literal)
+/*********************************************************
+ INPUT: A literal, which has an unshared Atom. For Shared
+ literals clause_LiteralDeleteFromSharing(Lit) is
+ available.
+ RETURNS: Nothing.
+ MEMORY: The Atom of 'Literal' is deleted and its memory
+ is freed as well as the LITERAL_NODE.
+**********************************************************/
+{
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Literal)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralDelete:");
+ misc_ErrorReport("\n Illegal input. Input not a literal.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_Delete(clause_LiteralSignedAtom(Literal));
+
+ clause_LiteralFree(Literal);
+}
+
+
+void clause_LiteralInsertIntoSharing(LITERAL Lit, SHARED_INDEX ShIndex)
+/**********************************************************
+ INPUT: A Literal with an unshared Atom and an Index.
+ RETURNS: The literal with a shared Atom inserted into the
+ 'Index'.
+ MEMORY: Allocates TERM_NODE memory needed to insert 'Lit'
+ into the sharing and frees the memory of the
+ unshared Atom.
+***********************************************************/
+{
+
+ TERM Atom;
+
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Lit)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralInsertIntoSharing:");
+ misc_ErrorReport("\n Illegal literal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Atom = clause_LiteralAtom(Lit);
+
+ clause_LiteralSetAtom(Lit, sharing_Insert(Lit, Atom, ShIndex));
+
+ term_Delete(Atom);
+}
+
+
+void clause_LiteralDeleteFromSharing(LITERAL Lit, SHARED_INDEX ShIndex)
+/**********************************************************
+ INPUT: A Literal and an 'Index'.
+ RETURNS: Nothing.
+ MEMORY: Deletes 'Lit' from Sharing, frees no more used
+ TERM memory and frees the LITERAL_NODE.
+********************************************************/
+{
+
+ TERM Atom;
+
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Lit)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralDeleteFromSharing:");
+ misc_ErrorReport("\n Illegal literal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Atom = clause_LiteralAtom(Lit);
+
+ if (clause_LiteralIsNegative(Lit)) {
+ list_Free(term_ArgumentList(clause_LiteralSignedAtom(Lit)));
+ term_Free(clause_LiteralSignedAtom(Lit));
+ }
+
+ sharing_Delete(Lit, Atom, ShIndex);
+
+ clause_LiteralFree(Lit);
+
+}
+
+
+static LIST clause_CopyLitInterval(CLAUSE Clause, int Start, int End)
+/**************************************************************
+ INPUT: A clause and two integers representing
+ literal indices.
+ RETURNS: Copies of all literals in <Clause> with index i and
+ in the interval [Start:End] are prepended to <List>.
+ MEMORY: All atoms are copied.
+***************************************************************/
+{
+ TERM Atom;
+ LIST List;
+
+ List = list_Nil();
+
+ for ( ; Start <= End; Start++) {
+ Atom = term_Copy(clause_GetLiteralAtom(Clause, Start));
+ List = list_Cons(Atom, List);
+ }
+
+ return List;
+}
+
+
+static LIST clause_CopyLitIntervalExcept(CLAUSE Clause, int Start, int End,
+ int i)
+/**************************************************************
+ INPUT: A clause and three integers representing
+ literal indeces.
+ RETURNS: A list of atoms from literals within the interval
+ [Start:End] except the literal at index <i>.
+ MEMORY: All atoms are copied.
+***************************************************************/
+{
+ TERM Atom;
+ LIST Result;
+
+ Result = list_Nil();
+ for ( ; End >= Start; End--)
+ if (End != i) {
+ Atom = term_Copy(clause_GetLiteralAtom(Clause, End));
+ Result = list_Cons(Atom, Result);
+ }
+ return Result;
+}
+
+
+LIST clause_CopyConstraint(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: The list of copied constraint literals from <Clause>.
+***************************************************************/
+{
+ return clause_CopyLitInterval(Clause,
+ clause_FirstConstraintLitIndex(Clause),
+ clause_LastConstraintLitIndex(Clause));
+}
+
+
+LIST clause_CopyAntecedentExcept(CLAUSE Clause, int i)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: A list containing copies of all antecedent literals
+ except <i>.
+***************************************************************/
+{
+ return clause_CopyLitIntervalExcept(Clause,
+ clause_FirstAntecedentLitIndex(Clause),
+ clause_LastAntecedentLitIndex(Clause),
+ i);
+}
+
+LIST clause_CopySuccedent(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: The list of copied succedent literals from <Clause>.
+***************************************************************/
+{
+ return clause_CopyLitInterval(Clause,
+ clause_FirstSuccedentLitIndex(Clause),
+ clause_LastSuccedentLitIndex(Clause));
+}
+
+
+LIST clause_CopySuccedentExcept(CLAUSE Clause, int i)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: A list containing copies of all succedent literals
+ except <i>.
+***************************************************************/
+{
+ return clause_CopyLitIntervalExcept(Clause,
+ clause_FirstSuccedentLitIndex(Clause),
+ clause_LastSuccedentLitIndex(Clause),
+ i);
+}
+
+
+/**************************************************************/
+/* Specials */
+/**************************************************************/
+
+BOOL clause_IsUnorderedClause(CLAUSE Clause)
+/*********************************************************
+ INPUT: A clause.
+ RETURNS: TRUE, if the invariants concerning splitting etc. hold
+ Invariants concerning maximality restrictions are not tested.
+**********************************************************/
+{
+ return ((Clause != NULL) &&
+ clause_CheckSplitLevel(Clause) &&
+ (clause_IsEmptyClause(Clause) ||
+ /* Check the first literal as a "random" sample */
+ clause_LiteralIsLiteral(clause_GetLiteral(Clause,clause_FirstLitIndex()))) &&
+ (clause_SplitLevel(Clause) == 0 || Clause->splitfield_length>0) &&
+ clause_DependsOnSplitLevel(Clause,clause_SplitLevel(Clause)));
+}
+
+
+BOOL clause_IsClause(CLAUSE Clause, FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/*********************************************************
+ INPUT: A clause, a flag store and a precedence.
+ RETURNS: TRUE, if literals are correctly ordered and the
+ invariants concerning splitting etc. hold
+**********************************************************/
+{
+ int i;
+ LITERAL ActLit;
+
+ if (!clause_IsUnorderedClause(Clause))
+ return FALSE;
+
+ for (i=clause_FirstAntecedentLitIndex(Clause);i<=clause_LastSuccedentLitIndex(Clause);i++) {
+ ActLit = clause_GetLiteral(Clause,i);
+ if (fol_IsEquality(clause_LiteralSignedAtom(ActLit))) {
+ ord_RESULT HelpRes;
+
+ HelpRes =
+ ord_Compare(term_FirstArgument(clause_LiteralSignedAtom(ActLit)),
+ term_SecondArgument(clause_LiteralSignedAtom(ActLit)),
+ FlagStore, Precedence);
+
+ if (ord_IsSmallerThan(HelpRes))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+BOOL clause_ContainsPositiveEquations(CLAUSE Clause)
+/*********************************************************
+ INPUT: A clause.
+ RETURNS: TRUE, if the clause contains a positive equality literal.
+**********************************************************/
+{
+ int i;
+
+ for (i = clause_FirstSuccedentLitIndex(Clause);
+ i < clause_Length(Clause);
+ i++)
+ if (clause_LiteralIsEquality(clause_GetLiteral(Clause, i)))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+BOOL clause_ContainsNegativeEquations(CLAUSE Clause)
+/*********************************************************
+ INPUT: A clause.
+ RETURNS: TRUE, if the clause contains a positive equality literal.
+**********************************************************/
+{
+ int i;
+
+ for (i = clause_FirstAntecedentLitIndex(Clause);
+ i < clause_FirstSuccedentLitIndex(Clause);
+ i++)
+ if (clause_LiteralIsEquality(clause_GetLiteral(Clause, i)))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+int clause_ContainsFolAtom(CLAUSE Clause, BOOL *Prop, BOOL *Grd, BOOL *Monadic,
+ BOOL *NonMonadic)
+/*********************************************************
+ INPUT: A clause.
+ RETURNS: The number of boolean variables changed.
+ If <*Prop> is FALSE and the clause contains a propositional
+ variable, it is changed to TRUE.
+ If <*Grd> is FALSE and the clause contains a non-propositional
+ ground atom, it is changed to TRUE.
+ If <*Monadic> is FALSE and the clause contains a monadic atom,
+ it is changed to TRUE.
+ If <*NonMonadic> is FALSE and the clause contains an at least
+ 2-place non-equality atom, it is changed to TRUE.
+**********************************************************/
+{
+ int i,Result,Arity;
+ BOOL Ground;
+
+ Result = 0;
+ i = clause_FirstLitIndex();
+
+ while (Result < 4 &&
+ i < clause_Length(Clause) &&
+ (!(*Prop) || !(*Monadic) || !(*NonMonadic))) {
+ Arity = symbol_Arity(term_TopSymbol(clause_GetLiteralAtom(Clause,i)));
+ Ground = term_IsGround(clause_GetLiteralAtom(Clause,i));
+ if (!(*Prop) && Arity == 0) {
+ Result++;
+ *Prop = TRUE;
+ }
+ if (!(*Grd) && Arity > 0 && Ground &&
+ !fol_IsEquality(clause_GetLiteralAtom(Clause,i))) {
+ Result++;
+ *Grd = TRUE;
+ }
+ if (!(*Monadic) && Arity == 1 && !Ground) {
+ Result++;
+ *Monadic = TRUE;
+ }
+ if (!(*NonMonadic) && Arity > 1 && !Ground &&
+ !fol_IsEquality(clause_GetLiteralAtom(Clause,i))) {
+ Result++;
+ *NonMonadic = TRUE;
+ }
+ i++;
+ }
+ return Result;
+}
+
+
+BOOL clause_ContainsVariables(CLAUSE Clause)
+/*********************************************************
+ INPUT: A clause.
+ RETURNS: TRUE, if the clause contains at least one variable
+**********************************************************/
+{
+ int i;
+ TERM Term;
+
+ for (i = clause_FirstLitIndex(); i < clause_Length(Clause); i++) {
+ Term = clause_GetLiteralAtom(Clause,i);
+ if (term_NumberOfVarOccs(Term)>0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+void clause_ContainsSortRestriction(CLAUSE Clause, BOOL *Sortres, BOOL *USortres)
+/*********************************************************
+ INPUT: A clause.
+ RETURNS: TRUE, if the clause contains a negative monadic atom with
+ a variable argument
+**********************************************************/
+{
+ int i;
+ TERM Term;
+
+ for (i = clause_FirstLitIndex();
+ i <= clause_LastAntecedentLitIndex(Clause) && (!*Sortres || !*USortres);
+ i++) {
+ Term = clause_GetLiteralAtom(Clause,i);
+ if (symbol_IsBaseSort(term_TopSymbol(Term))) {
+ *USortres = TRUE;
+ if (symbol_IsVariable(term_TopSymbol(term_FirstArgument(Term))))
+ *Sortres = TRUE;
+ }
+ }
+}
+
+BOOL clause_ContainsFunctions(CLAUSE Clause)
+/*********************************************************
+ INPUT: A clause.
+ RETURNS: TRUE, if the clause contains at least one function symbol
+**********************************************************/
+{
+ int i;
+ TERM Term;
+
+ for (i = clause_FirstLitIndex(); i < clause_Length(Clause); i++) {
+ Term = clause_GetLiteralAtom(Clause,i);
+ if (term_ContainsFunctions(Term))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL clause_ContainsSymbol(CLAUSE Clause, SYMBOL Symbol)
+/*********************************************************
+ INPUT: A clause and a symbol.
+ RETURNS: TRUE, if the clause contains the symbol
+**********************************************************/
+{
+ int i;
+
+ for (i = clause_FirstLitIndex(); i < clause_Length(Clause); i++)
+ if (term_ContainsSymbol(clause_GetLiteralAtom(Clause,i), Symbol))
+ return TRUE;
+ return FALSE;
+}
+
+NAT clause_NumberOfSymbolOccurrences(CLAUSE Clause, SYMBOL Symbol)
+/*********************************************************
+ INPUT: A clause and a symbol.
+ RETURNS: the number of occurrences of <Symbol> in <Clause>
+**********************************************************/
+{
+ int i;
+ NAT Result;
+
+ Result = 0;
+
+ for (i = clause_FirstLitIndex(); i < clause_Length(Clause); i++)
+ Result += term_NumberOfSymbolOccurrences(clause_GetLiteralAtom(Clause,i), Symbol);
+
+ return Result;
+}
+
+BOOL clause_ImpliesFiniteDomain(CLAUSE Clause)
+/*********************************************************
+ INPUT: A clause.
+ RETURNS: TRUE, if the clause consists of a positive disjunction
+ of equations, where each equation is of the form "x=t" for
+ some variable "x" and ground term "t"
+**********************************************************/
+{
+ int i;
+ TERM Term;
+
+ if (clause_FirstLitIndex() != clause_FirstSuccedentLitIndex(Clause))
+ return FALSE;
+
+ for (i = clause_FirstLitIndex(); i < clause_Length(Clause); i++) {
+ Term = clause_GetLiteralTerm(Clause,i);
+ if (!symbol_Equal(term_TopSymbol(Term),fol_Equality()) ||
+ (!symbol_IsVariable(term_TopSymbol(term_FirstArgument(Term))) &&
+ !symbol_IsVariable(term_TopSymbol(term_SecondArgument(Term)))) ||
+ (symbol_IsVariable(term_TopSymbol(term_FirstArgument(Term))) &&
+ !term_IsGround(term_SecondArgument(Term))) ||
+ (symbol_IsVariable(term_TopSymbol(term_SecondArgument(Term))) &&
+ !term_IsGround(term_FirstArgument(Term))))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL clause_ImpliesNonTrivialDomain(CLAUSE Clause)
+/*********************************************************
+ INPUT: A clause.
+ RETURNS: TRUE, if the clause consists of a negative equation
+ with two syntactically different arguments
+**********************************************************/
+{
+ if (clause_Length(Clause) == 1 &&
+ !clause_HasEmptyAntecedent(Clause) &&
+ clause_LiteralIsEquality(clause_FirstAntecedentLit(Clause)) &&
+ !term_Equal(term_FirstArgument(clause_LiteralAtom(clause_FirstAntecedentLit(Clause))),
+ term_SecondArgument(clause_LiteralAtom(clause_FirstAntecedentLit(Clause)))))
+ return TRUE;
+
+ return FALSE;
+}
+
+LIST clause_FiniteMonadicPredicates(LIST Clauses)
+/*********************************************************
+ INPUT: A list of clauses.
+ RETURNS: A list of all predicate symbols that are guaranteed
+ to have a finite extension in any minimal Herbrand model.
+ These predicates must only positively occur
+ in unit clauses and must have a ground term argument.
+**********************************************************/
+{
+ LIST Result, NonFinite, Scan;
+ CLAUSE Clause;
+ int i, n;
+ SYMBOL Pred;
+
+ Result = list_Nil();
+ NonFinite = list_Nil();
+
+ for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ n = clause_Length(Clause);
+ for (i=clause_FirstSuccedentLitIndex(Clause);i<n;i++) {
+ Pred = term_TopSymbol(clause_GetLiteralAtom(Clause,i));
+ if (symbol_Arity(Pred) == 1 &&
+ !list_PointerMember(NonFinite, (POINTER)Pred)) {
+ if (term_NumberOfVarOccs(clause_GetLiteralAtom(Clause,i)) > 0 ||
+ n > 1) {
+ NonFinite = list_Cons((POINTER)Pred, NonFinite);
+ Result = list_PointerDeleteElement(Result, (POINTER)Pred);
+ }
+ else {
+ if (!list_PointerMember(Result, (POINTER)Pred))
+ Result = list_Cons((POINTER)Pred, Result);
+ }
+ }
+ }
+ }
+ list_Delete(NonFinite);
+
+ Result = list_PointerDeleteElement(Result, (POINTER)fol_Equality());
+
+ return Result;
+}
+
+NAT clause_NumberOfVarOccs(CLAUSE Clause)
+/**************************************************************
+ INPUT: A Clause.
+ RETURNS: The number of variable occurrences in the clause.
+***************************************************************/
+{
+ int i,n;
+ NAT Result;
+
+ Result = 0;
+ n = clause_Length(Clause);
+
+ for (i = clause_FirstLitIndex(); i < n; i++)
+ Result += term_NumberOfVarOccs(clause_GetLiteralTerm(Clause,i));
+
+ return Result;
+}
+
+
+NAT clause_ComputeWeight(CLAUSE Clause, FLAGSTORE Flags)
+/**************************************************************
+ INPUT: A clause and a flag store.
+ RETURNS: The Weight of the literals in the clause,
+ up to now the number of variable symbols plus
+ twice the number of signature symbols.
+ EFFECT: The weight of the literals is updated, but not the
+ weight of the clause!
+***************************************************************/
+{
+ int i, n;
+ NAT Weight;
+ LITERAL Lit;
+
+ Weight = 0;
+ n = clause_Length(Clause);
+
+ for (i = clause_FirstLitIndex(); i < n; i++) {
+ Lit = clause_GetLiteral(Clause, i);
+ clause_UpdateLiteralWeight(Lit, Flags);
+ Weight += clause_LiteralWeight(Lit);
+ }
+ return Weight;
+}
+
+
+NAT clause_ComputeTermDepth(CLAUSE Clause)
+/**************************************************************
+ INPUT: A Clause.
+ RETURNS: Maximal depth of a literal in <Clause>.
+***************************************************************/
+{
+ int i,n;
+ NAT Depth,Help;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_ComputeTermDepth:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Depth = 0;
+ n = clause_Length(Clause);
+
+ for (i = clause_FirstLitIndex();i < n;i++) {
+ Help = term_Depth(clause_GetLiteralAtom(Clause,i));
+ if (Help > Depth)
+ Depth = Help;
+ }
+ return Depth;
+}
+
+NAT clause_MaxTermDepthClauseList(LIST Clauses)
+/**************************************************************
+ INPUT: A list of clauses.
+ RETURNS: Maximal depth of a clause in <Clauses>.
+***************************************************************/
+{
+ NAT Depth,Help;
+
+ Depth = 0;
+
+ while (!list_Empty(Clauses)) {
+ Help = clause_ComputeTermDepth(list_Car(Clauses));
+ if (Help > Depth)
+ Depth = Help;
+ Clauses = list_Cdr(Clauses);
+ }
+
+ return Depth;
+}
+
+
+NAT clause_ComputeSize(CLAUSE Clause)
+/**************************************************************
+ INPUT: A Clause.
+ RETURNS: The Size of the literals in the clause,
+ up to now the number of symbols.
+***************************************************************/
+{
+ int i,n;
+ NAT Size;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_ComputeSize:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Size = 0;
+ n = clause_Length(Clause);
+
+ for (i = clause_FirstLitIndex();i < n;i++)
+ Size += term_ComputeSize(clause_GetLiteralTerm(Clause,i));
+
+ return Size;
+}
+
+
+BOOL clause_WeightCorrect(CLAUSE Clause, FLAGSTORE Flags, PRECEDENCE Precedence)
+/*********************************************************
+ INPUT: A clause, a flag store and a precedence.
+ RETURNS: TRUE iff the weight fields of the clause and its
+ literals are correct.
+**********************************************************/
+{
+ int i, n;
+ NAT Weight, Help;
+ LITERAL Lit;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_WeightCorrect:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Weight = 0;
+ n = clause_Length(Clause);
+
+ for (i = clause_FirstLitIndex(); i < n; i++) {
+ Lit = clause_GetLiteral(Clause, i);
+ Help = clause_LiteralComputeWeight(Lit, Flags);
+ if (Help != clause_LiteralWeight(Lit))
+ return FALSE;
+ Weight += Help;
+ }
+
+ return (clause_Weight(Clause) == Weight);
+}
+
+
+LIST clause_InsertWeighed(CLAUSE Clause, LIST UsList, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/*********************************************************
+ INPUT: A clause, a list to insert the clause into,
+ a flag store and a precedence.
+ RETURNS: The list where the clause is inserted wrt its
+ weight (Weight(Car(list)) <= Weight(Car(Cdr(list)))).
+ MEMORY: A new listnode is allocated.
+**********************************************************/
+{
+ LIST Scan;
+ NAT Weight;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_InsertWeighted:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Weight = clause_Weight(Clause);
+
+ Scan = UsList;
+
+ if (list_Empty(Scan) ||
+ (clause_Weight(list_Car(Scan)) > Weight)) {
+ return list_Cons(Clause, Scan);
+
+ } else {
+ while (!list_Empty(list_Cdr(Scan)) &&
+ (clause_Weight(list_Car(list_Cdr(Scan))) <= Weight)) {
+ Scan = list_Cdr(Scan);
+ }
+ list_Rplacd(Scan, list_Cons(Clause, list_Cdr(Scan)));
+ return UsList;
+ }
+}
+
+
+LIST clause_ListSortWeighed(LIST Clauses)
+/*********************************************************
+ INPUT: A list of clauses.
+ RETURNS: The clause list sorted with respect to the weight
+ of clauses, minimal weight first.
+ EFFECT: The original list is destructively changed!
+ This function doesn't sort stable!
+ The function uses bucket sort for clauses with weight
+ smaller than clause_MAXWEIGHT, and the usual list sort
+ function for clauses with weight >= clause_MAXWEIGHT.
+ This implies the function uses time O(n-c + c*log c),
+ where n is the length of the list and c is the number
+ of clauses with weight >= clause_MAXWEIGHT.
+ For c=0 you get time O(n), for c=n you get time (n*log n).
+**********************************************************/
+{
+ int weight;
+ LIST Scan;
+
+ for (Scan=Clauses; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ weight = clause_Weight(list_Car(Scan));
+ if (weight < clause_MAXWEIGHT)
+ clause_SORT[weight] = list_Cons(list_Car(Scan),clause_SORT[weight]);
+ else
+ clause_SORT[clause_MAXWEIGHT] = list_Cons(list_Car(Scan),clause_SORT[clause_MAXWEIGHT]);
+ }
+ Scan = list_NumberSort(clause_SORT[clause_MAXWEIGHT],
+ (NAT (*)(POINTER)) clause_Weight);
+ clause_SORT[clause_MAXWEIGHT] = list_Nil();
+ for (weight = clause_MAXWEIGHT-1; weight >= 0; weight--) {
+ Scan = list_Nconc(clause_SORT[weight],Scan);
+ clause_SORT[weight] = list_Nil();
+ }
+ list_Delete(Clauses);
+ return Scan;
+}
+
+
+LITERAL clause_LiteralCopy(LITERAL Literal)
+/*********************************************************
+ INPUT: A literal.
+ RETURNS: An unshared copy of the literal, where the owning
+ clause-slot is set to NULL.
+ MEMORY: Memory for a new LITERAL_NODE and all its TERMs
+ subterms is allocated.
+**********************************************************/
+{
+
+ LITERAL Result;
+
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Literal)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralCopy:");
+ misc_ErrorReport("\n Illegal input. Input not a literal.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = (LITERAL)memory_Malloc(sizeof(LITERAL_NODE));
+
+ Result->atomWithSign = term_Copy(clause_LiteralSignedAtom(Literal));
+ Result->oriented = clause_LiteralIsOrientedEquality(Literal);
+
+ Result->maxLit = Literal->maxLit;
+ Result->weight = Literal->weight;
+ Result->owningClause = (POINTER)NULL;
+
+ return Result;
+}
+
+
+CLAUSE clause_Copy(CLAUSE Clause)
+/*********************************************************
+ INPUT: A Clause.
+ RETURNS: An unshared copy of the Clause.
+ MEMORY: Memory for a new CLAUSE_NODE, LITERAL_NODE and
+ all its TERMs subterms is allocated.
+**********************************************************/
+{
+
+ CLAUSE Result;
+ int i,c,a,s,l;
+
+ Result = (CLAUSE)memory_Malloc(sizeof(CLAUSE_NODE));
+
+ Result->clausenumber = clause_Number(Clause);
+ Result->maxVar = clause_MaxVar(Clause);
+ Result->flags = Clause->flags;
+ clause_InitSplitData(Result);
+ Result->validlevel = clause_SplitLevel(Clause);
+ clause_SetSplitField(Result, Clause->splitfield, Clause->splitfield_length);
+ Result->depth = clause_Depth(Clause);
+ Result->weight = Clause->weight;
+ Result->parentCls = list_Copy(clause_ParentClauses(Clause));
+ Result->parentLits = list_Copy(clause_ParentLiterals(Clause));
+ Result->origin = clause_Origin(Clause);
+
+ Result->c = (c = clause_NumOfConsLits(Clause));
+ Result->a = (a = clause_NumOfAnteLits(Clause));
+ Result->s = (s = clause_NumOfSuccLits(Clause));
+
+ l = c + a + s;
+ if (l != 0)
+ Result->literals = (LITERAL *)memory_Malloc(l * sizeof(LITERAL));
+
+ for (i = 0; i < l; i++) {
+ clause_SetLiteral(Result, i,
+ clause_LiteralCopy(clause_GetLiteral(Clause, i)));
+ clause_LiteralSetOwningClause((Result->literals[i]), Result);
+ }
+
+ return Result;
+}
+
+
+SYMBOL clause_LiteralMaxVar(LITERAL Literal)
+/*********************************************************
+ INPUT: A literal.
+ RETURNS: The maximal symbol of the literals variables,
+ if the literal is ground, symbol_GetInitialStandardVarCounter().
+**********************************************************/
+{
+
+ TERM Term;
+ int Bottom;
+ SYMBOL MaxSym,Help;
+
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Literal)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralMaxVar:");
+ misc_ErrorReport("\n Illegal input. Input not a literal.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Bottom = stack_Bottom();
+ MaxSym = symbol_GetInitialStandardVarCounter();
+ Term = clause_LiteralAtom(Literal);
+
+ do {
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+ else
+ if (term_IsVariable(Term))
+ MaxSym = ((MaxSym < (Help = term_TopSymbol(Term))) ?
+ Help : MaxSym);
+ while (!stack_Empty(Bottom) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Bottom)) {
+ Term = (TERM) list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Bottom));
+
+ return MaxSym;
+}
+
+
+SYMBOL clause_AtomMaxVar(TERM Term)
+/*********************************************************
+ INPUT: A term.
+ RETURNS: The maximal symbol of the lcontained variables,
+ if <Term> is ground, symbol_GetInitialStandardVarCounter().
+**********************************************************/
+{
+ int Bottom;
+ SYMBOL VarSym,Help;
+
+ Bottom = stack_Bottom();
+ VarSym = symbol_GetInitialStandardVarCounter();
+
+ do {
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+ else
+ if (term_IsVariable(Term))
+ VarSym = ((VarSym < (Help = term_TopSymbol(Term))) ?
+ Help : VarSym);
+ while (!stack_Empty(Bottom) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Bottom)) {
+ Term = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Bottom));
+
+ return VarSym;
+}
+
+
+void clause_SetMaxLitFlags(CLAUSE Clause, FLAGSTORE FlagStore,
+ PRECEDENCE Precedence)
+/**********************************************************
+ INPUT: A clause, a flag store and a precedence.
+ RETURNS: Nothing.
+ EFFECT: Sets the maxLit-flag for maximal literals.
+***********************************************************/
+{
+ int i,j,n,fa;
+ LITERAL ActLit,CompareLit;
+ BOOL Result, Twin;
+ ord_RESULT HelpRes;
+
+ n = clause_Length(Clause);
+ fa = clause_FirstAntecedentLitIndex(Clause);
+ clause_RemoveFlag(Clause,CLAUSESELECT);
+ for (i = clause_FirstLitIndex(); i < n; i++)
+ clause_LiteralFlagReset(clause_GetLiteral(Clause, i));
+ if (term_StampOverflow(clause_STAMPID))
+ for (i = clause_FirstLitIndex(); i < n; i++)
+ term_ResetTermStamp(clause_LiteralSignedAtom(clause_GetLiteral(Clause, i)));
+ term_StartStamp();
+
+ /*printf("\n Start: "); clause_Print(Clause);*/
+
+ for (i = fa; i < n; i++) {
+ ActLit = clause_GetLiteral(Clause, i);
+ if (!term_HasTermStamp(clause_LiteralSignedAtom(ActLit))) {
+ Result = TRUE;
+ Twin = FALSE;
+ for (j = fa; j < n && Result; j++)
+ if (i != j) {
+ CompareLit = clause_GetLiteral(Clause, j);
+ HelpRes = ord_LiteralCompare(clause_LiteralSignedAtom(ActLit),
+ clause_LiteralIsOrientedEquality(ActLit),
+ clause_LiteralSignedAtom(CompareLit),
+ clause_LiteralIsOrientedEquality(CompareLit),
+ FALSE, FlagStore, Precedence);
+
+ /*printf("\n\tWe compare: ");
+ fol_PrintDFG(clause_LiteralAtom(ActLit));
+ putchar(' ');
+ fol_PrintDFG(clause_LiteralAtom(CompareLit));
+ printf(" Result: "); ord_Print(HelpRes);*/
+
+ if (ord_IsEqual(HelpRes))
+ Twin = TRUE;
+ if (ord_IsSmallerThan(HelpRes))
+ Result = FALSE;
+ if (ord_IsGreaterThan(HelpRes))
+ term_SetTermStamp(clause_LiteralSignedAtom(CompareLit));
+ }
+ if (Result) {
+ clause_LiteralSetFlag(ActLit, MAXIMAL);
+ if (!Twin)
+ clause_LiteralSetFlag(ActLit, STRICTMAXIMAL);
+ }
+ }
+ }
+ term_StopStamp();
+ /*printf("\n End: "); clause_Print(Clause);*/
+}
+
+
+SYMBOL clause_SearchMaxVar(CLAUSE Clause)
+/**********************************************************
+ INPUT: A clause.
+ RETURNS: The maximal symbol of the clauses variables.
+ If the clause is ground, symbol_GetInitialStandardVarCounter().
+***********************************************************/
+{
+ int i, n;
+ SYMBOL Help, MaxSym;
+
+ n = clause_Length(Clause);
+
+ MaxSym = symbol_GetInitialStandardVarCounter();
+
+ for (i = 0; i < n; i++) {
+ Help = clause_LiteralMaxVar(clause_GetLiteral(Clause, i));
+ if (Help > MaxSym)
+ MaxSym = Help;
+ }
+ return MaxSym;
+}
+
+
+void clause_RenameVarsBiggerThan(CLAUSE Clause, SYMBOL MinVar)
+/**********************************************************
+ INPUT: A clause and a variable symbol.
+ RETURNS: The clause with variables renamed in a way, that
+ all vars are (excl.) bigger than MinVar.
+***********************************************************/
+{
+ int i,n;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_RenameVarsBiggerThan:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (MinVar != symbol_GetInitialStandardVarCounter()) {
+ n = clause_Length(Clause);
+
+ term_StartMaxRenaming(MinVar);
+
+ for (i = clause_FirstLitIndex(); i < n; i++)
+ term_Rename(clause_GetLiteralTerm(Clause, i));
+ }
+}
+
+void clause_Normalize(CLAUSE Clause)
+/**********************************************************
+ INPUT: A clause.
+ RETURNS: The term with normalized Variables, DESTRUCTIVE
+ on the variable subterms' topsymbols.
+***********************************************************/
+{
+ int i,n;
+
+ n = clause_Length(Clause);
+
+ term_StartMinRenaming();
+
+ for (i = clause_FirstLitIndex(); i < n; i++)
+ term_Rename(clause_GetLiteralTerm(Clause, i));
+}
+
+
+void clause_SubstApply(SUBST Subst, CLAUSE Clause)
+/**********************************************************
+ INPUT: A clause.
+ RETURNS: Nothing.
+ EFFECTS: Applies the substitution to the clause.
+***********************************************************/
+{
+ int i,n;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_SubstApply:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ n = clause_Length(Clause);
+
+ for (i=clause_FirstLitIndex(); i<n; i++)
+ clause_LiteralSetAtom(clause_GetLiteral(Clause, i),
+ subst_Apply(Subst,clause_GetLiteralAtom(Clause,i)));
+}
+
+
+void clause_ReplaceVariable(CLAUSE Clause, SYMBOL Var, TERM Term)
+/**********************************************************
+ INPUT: A clause, a variable symbol, and a term.
+ RETURNS: Nothing.
+ EFFECTS: All occurences of the variable <Var> in <Clause>
+ are replaced by copies if <Term>.
+ CAUTION: The maximum variable of the clause is not updated!
+***********************************************************/
+{
+ int i, li;
+
+#ifdef CHECK
+ if (!symbol_IsVariable(Var)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_ReplaceVariable: symbol is not a variable");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ li = clause_LastLitIndex(Clause);
+ for (i = clause_FirstLitIndex(); i <= li; i++)
+ term_ReplaceVariable(clause_GetLiteralAtom(Clause,i), Var, Term);
+}
+
+
+void clause_UpdateMaxVar(CLAUSE Clause)
+/**********************************************************
+ INPUT: A clause.
+ RETURNS: Nothing.
+ EFFECTS: Actualizes the MaxVar slot wrt the actual literals.
+***********************************************************/
+{
+ clause_SetMaxVar(Clause, clause_SearchMaxVar(Clause));
+}
+
+
+
+void clause_OrientEqualities(CLAUSE Clause, FLAGSTORE FlagStore,
+ PRECEDENCE Precedence)
+/**********************************************************
+ INPUT: An unshared clause, a flag store and a precedence.
+ RETURNS: Nothing.
+ EFFECTS: Reorders the arguments of equality literals
+ wrt. the ordering. Thus first arguments aren't smaller
+ after the application.
+***********************************************************/
+{
+ int i,length;
+ LITERAL EqLit;
+ ord_RESULT HelpRes;
+
+ /*printf("\n Clause: ");clause_Print(Clause);*/
+
+ length = clause_Length(Clause);
+
+ for (i = clause_FirstLitIndex(); i < length; i++) {
+ EqLit = clause_GetLiteral(Clause, i);
+
+ if (clause_LiteralIsEquality(EqLit)) {
+ HelpRes = ord_Compare(term_FirstArgument(clause_LiteralAtom(EqLit)),
+ term_SecondArgument(clause_LiteralAtom(EqLit)),
+ FlagStore, Precedence);
+
+ /*printf("\n\tWe compare: ");
+ fol_PrintDFG(term_FirstArgument(clause_LiteralAtom(EqLit)));
+ putchar(' ');
+ fol_PrintDFG(term_SecondArgument(clause_LiteralAtom(EqLit)));
+ printf("\nResult: "); ord_Print(HelpRes);*/
+
+ switch(HelpRes) {
+
+ case ord_SMALLER_THAN:
+ /* printf("\nSwapping: ");
+ term_Print(clause_LiteralAtom(EqLit)); DBG */
+ term_EqualitySwap(clause_LiteralAtom(EqLit));
+ clause_LiteralSetOrientedEquality(EqLit);
+ /* Swapped = TRUE; */
+ break;
+ case ord_GREATER_THAN:
+ clause_LiteralSetOrientedEquality(EqLit);
+ break;
+ default:
+ clause_LiteralSetNoOrientedEquality(EqLit);
+ break;
+ }
+ }
+ else
+ clause_LiteralSetNoOrientedEquality(EqLit);
+ }
+}
+
+
+void clause_InsertFlatIntoIndex(CLAUSE Clause, st_INDEX Index)
+/**********************************************************
+ INPUT: An unshared clause and an index.
+ EFFECT: The atoms of <Clause> are inserted into the index.
+ A link from the atom to its literal via the supertermlist
+ is established.
+***********************************************************/
+{
+ int i,n;
+ LITERAL Lit;
+ TERM Atom ;
+
+ n = clause_Length(Clause);
+
+ for (i=clause_FirstLitIndex();i<n;i++) {
+ Lit = clause_GetLiteral(Clause,i);
+ Atom = clause_LiteralAtom(Lit);
+ term_RplacSupertermList(Atom, list_List(Lit));
+ st_EntryCreate(Index, Atom, Atom, cont_LeftContext());
+ }
+}
+
+void clause_DeleteFlatFromIndex(CLAUSE Clause, st_INDEX Index)
+/**********************************************************
+ INPUT: An unshared clause and an index.
+ EFFECT: The clause is deleted from the index and deleted itself.
+***********************************************************/
+{
+ int i,n;
+ LITERAL Lit;
+ TERM Atom ;
+
+ n = clause_Length(Clause);
+
+ for (i=clause_FirstLitIndex();i<n;i++) {
+ Lit = clause_GetLiteral(Clause,i);
+ Atom = clause_LiteralAtom(Lit);
+ list_Delete(term_SupertermList(Atom));
+ term_RplacSupertermList(Atom, list_Nil());
+ st_EntryDelete(Index, Atom, Atom, cont_LeftContext());
+ }
+ clause_Delete(Clause);
+}
+
+
+void clause_DeleteClauseListFlatFromIndex(LIST Clauses, st_INDEX Index)
+/**********************************************************
+ INPUT: An list of unshared clause and an index.
+ EFFECT: The clauses are deleted from the index and deleted itself.
+ The list is deleted.
+***********************************************************/
+{
+ LIST Scan;
+
+ for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan))
+ clause_DeleteFlatFromIndex(list_Car(Scan), Index);
+
+ list_Delete(Clauses);
+}
+
+
+/******************************************************************/
+/* Some special functions used by hyper inference/reduction rules */
+/******************************************************************/
+
+static void clause_VarToSizeMap(SUBST Subst, NAT* Map, NAT MaxIndex)
+/**************************************************************
+ INPUT: A substitution, an array <Map> of size <MaxIndex>+1.
+ RETURNS: Nothing.
+ EFFECT: The index i within the array corresponds to the index
+ of a variable x_i. For each variable x_i, 0<=i<=MaxIndex
+ the size of its substitution term is calculated
+ and written to Map[i].
+***************************************************************/
+{
+ NAT *Scan;
+
+#ifdef CHECK
+ if (subst_Empty(Subst) || Map == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_VarToSizeMap: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /* Initialization */
+ for (Scan = Map + MaxIndex; Scan >= Map; Scan--)
+ *Scan = 1;
+ /* Compute the size of substitution terms */
+ for ( ; !subst_Empty(Subst); Subst = subst_Next(Subst))
+ Map[subst_Dom(Subst)] = term_ComputeSize(subst_Cod(Subst));
+}
+
+
+static NAT clause_ComputeTermSize(TERM Term, NAT* VarMap)
+/**************************************************************
+ INPUT: A term and a an array of NATs.
+ RETURNS: The number of symbols in the term.
+ EFFECT: This function calculates the number of symbols in <Term>
+ with respect to some substitution s.
+ A naive way to do this is to apply the substitution
+ to a copy of the term, and to count the number of symbols
+ in the copied term.
+ We use a more sophisticated algorithm, that first stores
+ the size of every variable's substitution term in <VarMap>.
+ We then 'scan' the term and for a variable occurrence x_i
+ we simply add the corresponding value VarMap[i] to the result.
+ This way we avoid copying the term and the substitution terms,
+ which is especially useful if we reuse the VarMap several times.
+***************************************************************/
+{
+ NAT Stack, Size;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_ComputeTermSize: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Size = 0;
+ Stack = stack_Bottom();
+ do {
+ if (VarMap!=NULL && symbol_IsVariable(term_TopSymbol(Term)))
+ Size += VarMap[symbol_VarIndex(term_TopSymbol(Term))];
+ else {
+ Size++;
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+ }
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+
+ if (!stack_Empty(Stack)) {
+ Term = list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return Size;
+}
+
+
+LIST clause_MoveBestLiteralToFront(LIST Literals, SUBST Subst, SYMBOL MaxVar,
+ BOOL (*Better)(LITERAL, NAT, LITERAL, NAT))
+/**************************************************************
+ INPUT: A list of literals, a substitution, the maximum variable
+ from the domain of the substitution, and a comparison
+ function. The function <Better> will be called with two
+ literals L1 and L2 and two number S1 and S2, where Si is
+ the size of the atom of Li with respect to variable bindings
+ in <Subst>.
+ RETURNS: The same list.
+ EFFECT: This function moves the first literal L to the front of the
+ list, so that no other literal L' is better than L with respect
+ to the function <Better>.
+ The function exchanges only the literals, the order of list
+ items within the list is not changed.
+***************************************************************/
+{
+ NAT *Map, MapSize, BestSize, Size;
+ LIST Best, Scan;
+
+#ifdef CHECK
+ if (!list_IsSetOfPointers(Literals)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_MoveBestLiteralToFront: List contains duplicates");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (list_Empty(Literals) || list_Empty(list_Cdr(Literals)))
+ /* < 2 list items, so nothing to do */
+ return Literals;
+
+ Map = NULL;
+ MapSize = 0;
+
+ if (!subst_Empty(Subst)) {
+ MapSize = symbol_VarIndex(MaxVar) + 1;
+ Map = memory_Malloc(sizeof(NAT)*MapSize);
+ clause_VarToSizeMap(Subst, Map, MapSize-1);
+ }
+ Best = Literals; /* Remember list item, not literal itself */
+ BestSize = clause_ComputeTermSize(clause_LiteralAtom(list_Car(Best)), Map);
+ for (Scan = list_Cdr(Literals); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Size = clause_ComputeTermSize(clause_LiteralAtom(list_Car(Scan)), Map);
+ if (Better(list_Car(Scan), Size, list_Car(Best), BestSize)) {
+ /* Actual literal is better than the best encountered so far */
+ BestSize = Size;
+ Best = Scan;
+ }
+ }
+ if (Best != Literals) {
+ /* Move best literal to the front. We just exchange the literals. */
+ LITERAL h = list_Car(Literals);
+ list_Rplaca(Literals, list_Car(Best));
+ list_Rplaca(Best, h);
+ }
+ /* cleanup */
+ if (Map != NULL)
+ memory_Free(Map, sizeof(NAT)*MapSize);
+
+ return Literals;
+}
+
+
+/**************************************************************/
+/* Literal Output Functions */
+/**************************************************************/
+
+void clause_LiteralPrint(LITERAL Literal)
+/**************************************************************
+ INPUT: A Literal.
+ RETURNS: Nothing.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Literal)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralPrint:");
+ misc_ErrorReport("\n Illegal input. Input not a literal.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_PrintPrefix(clause_LiteralSignedAtom(Literal));
+}
+
+
+void clause_LiteralListPrint(LIST LitList)
+/**************************************************************
+ INPUT: A list of literals.
+ RETURNS: Nothing.
+ SUMMARY: Prints the literals to stdout.
+***************************************************************/
+{
+ while (!(list_Empty(LitList))) {
+ clause_LiteralPrint(list_First(LitList));
+ LitList = list_Cdr(LitList);
+
+ if (!list_Empty(LitList))
+ putchar(' ');
+ }
+}
+
+
+void clause_LiteralPrintUnsigned(LITERAL Literal)
+/**************************************************************
+ INPUT: A Literal.
+ RETURNS: Nothing.
+ SUMMARY:
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Literal)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralPrintUnsigned:");
+ misc_ErrorReport("\n Illegal input. Input not a literal.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_PrintPrefix(clause_LiteralAtom(Literal));
+ fflush(stdout);
+}
+
+
+void clause_LiteralPrintSigned(LITERAL Literal)
+/**************************************************************
+ INPUT: A Literal.
+ RETURNS: Nothing.
+ SUMMARY:
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Literal)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralPrintSigned:");
+ misc_ErrorReport("\n Illegal input. Input not a literal.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_PrintPrefix(clause_LiteralSignedAtom(Literal));
+ fflush(stdout);
+}
+
+
+void clause_LiteralFPrint(FILE* File, LITERAL Lit)
+/**************************************************************
+ INPUT: A file and a literal.
+ RETURNS: Nothing.
+************************************************************/
+{
+ term_FPrintPrefix(File, clause_LiteralSignedAtom(Lit));
+}
+
+
+LIST clause_GetLiteralSubSetList(CLAUSE Clause, int StartIndex, int EndIndex,
+ FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a start literal index, an end index, a
+ flag store and a precedence.
+ RETURNS: The list of literals between the start and the end
+ index.
+ It is a list of pointers, not a list of indices.
+**************************************************************/
+{
+
+ LIST Result;
+ int i;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, FlagStore, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_ReplaceLiteralSubSet:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+ if ((StartIndex < clause_FirstLitIndex())
+ || (EndIndex > clause_LastLitIndex(Clause))) {
+ misc_ErrorReport("\n In clause_ReplaceLiteralSubSet:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_ErrorReport("\n Index out of range.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+
+ for (i=StartIndex;
+ i<=EndIndex;
+ i++) {
+ Result = list_Cons(clause_GetLiteral(Clause, i), Result);
+ }
+
+ return Result;
+}
+
+
+void clause_ReplaceLiteralSubSet(CLAUSE Clause, int StartIndex,
+ int EndIndex, LIST Replacement,
+ FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a start literal index, an end literal
+ index, a flag store and a precedence.
+ RETURNS: None.
+ EFFECT: Replaces the subset of literals in <Clause> with
+ indices between (and including) <StartIndex> and
+ <EndIndex> with literals from the <Replacement>
+ list.
+**************************************************************/
+{
+
+ int i;
+ LIST Scan;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, FlagStore, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_ReplaceLiteralSubSet:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+ if ((StartIndex < clause_FirstLitIndex())
+ || (EndIndex > clause_LastLitIndex(Clause))) {
+ misc_ErrorReport("\n In clause_ReplaceLiteralSubSet:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_ErrorReport("\n Index out of range.");
+ misc_FinishErrorReport();
+ }
+ if (list_Length(Replacement) != (EndIndex - StartIndex + 1)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_ReplaceLiteralSubSet:");
+ misc_ErrorReport("\n Illegal input. Replacement list size");
+ misc_ErrorReport("\n and set size don't match");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ for (i = StartIndex, Scan = Replacement;
+ i <= EndIndex;
+ i++, Scan = list_Cdr(Scan)) {
+ clause_SetLiteral(Clause, i, list_Car(Scan));
+ }
+}
+
+static __inline__ BOOL clause_LiteralsCompare(LITERAL Left, LITERAL Right)
+/**************************************************************
+ INPUT: Two literals.
+ RETURNS: TRUE if Left <= Right, FALSE otherwise.
+ EFFECT: Compares literals by comparing their terms' arities.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!(clause_LiteralIsLiteral(Left) && clause_LiteralIsLiteral(Right))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralsCompare:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return term_CompareAbstractLEQ(clause_LiteralSignedAtom(Left),
+ clause_LiteralSignedAtom(Right));
+}
+
+static __inline__ void clause_FixLiteralSubsetOrder(CLAUSE Clause,
+ int StartIndex,
+ int EndIndex,
+ FLAGSTORE FlagStore,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a start index, an end index a flag store
+ and a precedence.
+ RETURNS: None.
+ EFFECT: Sorts literals with indices between (and including)
+ <StartIndex> and <EndIndex> with respect to an abstract
+ list representation of terms that identifies function
+ symbols with their arity.
+***************************************************************/
+{
+
+ LIST literals;
+
+#ifdef CHECK
+ if ((StartIndex < clause_FirstLitIndex())
+ || (EndIndex > clause_LastLitIndex(Clause))) {
+ misc_ErrorReport("\n In clause_FixLiteralSubSetOrder:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_ErrorReport("\n Index out of range.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /* Get the literals */
+ literals = clause_GetLiteralSubSetList(Clause, StartIndex, EndIndex, FlagStore, Precedence);
+
+ /* Sort them */
+ literals = list_Sort(literals, (BOOL (*) (POINTER, POINTER)) clause_LiteralsCompare);
+
+ /* Replace clause literals in subset with sorted literals */
+ clause_ReplaceLiteralSubSet(Clause, StartIndex, EndIndex, literals, FlagStore, Precedence);
+
+ list_Delete(literals);
+}
+
+void clause_FixLiteralOrder(CLAUSE Clause, FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a flag store, and a precedence.
+ RETURNS: None.
+ EFFECT: Fixes literal order in a <Clause>. Different literal
+ types are ordered separately.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsClause(Clause, FlagStore, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_FixLiteralOrder:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /* Fix antecedent literal order */
+ clause_FixLiteralSubsetOrder(Clause,
+ clause_FirstAntecedentLitIndex(Clause),
+ clause_LastAntecedentLitIndex(Clause),
+ FlagStore, Precedence);
+
+ /* Fix succedent literal order */
+ clause_FixLiteralSubsetOrder(Clause,
+ clause_FirstSuccedentLitIndex(Clause),
+ clause_LastSuccedentLitIndex(Clause),
+ FlagStore, Precedence);
+
+ /* Fix constraint literal order */
+ clause_FixLiteralSubsetOrder(Clause,
+ clause_FirstConstraintLitIndex(Clause),
+ clause_LastConstraintLitIndex(Clause),
+ FlagStore, Precedence);
+
+ /* Normalize clause, to get variable names right. */
+ clause_Normalize(Clause);
+}
+
+static int clause_CompareByWeight(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by their weight.
+***************************************************************/
+{
+ NAT lweight, rweight;
+ int result;
+
+ lweight = clause_Weight(Left);
+ rweight = clause_Weight(Right);
+
+ if (lweight < rweight) {
+ result = -1;
+ }
+ else if (lweight > rweight) {
+ result = 1;
+ }
+ else {
+ result = 0;
+ }
+
+ return result;
+}
+
+static int clause_CompareByClausePartSize(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by the number of literals in
+ the antecedent, succedent and constraint.
+***************************************************************/
+{
+ int lsize, rsize;
+
+ lsize = clause_NumOfAnteLits(Left);
+ rsize = clause_NumOfAnteLits(Right);
+ if (lsize < rsize)
+ return -1;
+ else if (lsize > rsize)
+ return 1;
+
+ lsize = clause_NumOfSuccLits(Left);
+ rsize = clause_NumOfSuccLits(Right);
+
+ if (lsize < rsize)
+ return -1;
+ else if (lsize > rsize)
+ return 1;
+
+ lsize = clause_NumOfConsLits(Left);
+ rsize = clause_NumOfConsLits(Right);
+
+ if (lsize < rsize)
+ return -1;
+ else if (lsize > rsize)
+ return 1;
+
+ return 0;
+}
+
+void clause_CountSymbols(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: None.
+ EFFECT: Counts the non-variable symbols in the clause, and
+ increases their counts accordingly.
+***************************************************************/
+{
+ int i;
+
+ for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++) {
+ LITERAL l;
+ TERM t;
+
+ l = clause_GetLiteral(Clause, i);
+ if (clause_LiteralIsPredicate(l)) {
+ SYMBOL S;
+
+ S = clause_LiteralPredicate(l);
+ symbol_SetCount(S, symbol_GetCount(S) + 1);
+ }
+
+ t = clause_GetLiteralAtom(Clause, i);
+
+ term_CountSymbols(t);
+ }
+}
+
+
+LIST clause_ListOfPredicates(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: A list of symbols.
+ EFFECT: Creates a list of predicates occurring in the clause.
+ A predicate occurs several times in the list, if
+ it does so in the clause.
+***************************************************************/
+{
+ LIST preds;
+ int i;
+
+ preds = list_Nil();
+
+ for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++) {
+ LITERAL l;
+
+ l = clause_GetLiteral(Clause, i);
+ if (clause_LiteralIsPredicate(l)) {
+ preds = list_Cons((POINTER) clause_LiteralPredicate(l), preds);
+ }
+ }
+
+ return preds;
+}
+
+LIST clause_ListOfConstants(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: A list of symbols.
+ EFFECT: Creates a list of constants occurring in the clause.
+ A constant occurs several times in the list, if
+ it does so in the clause.
+***************************************************************/
+{
+ LIST consts;
+ int i;
+
+ consts = list_Nil();
+
+ for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++) {
+ TERM t;
+
+ t = clause_GetLiteralAtom(Clause, i);
+
+ consts = list_Nconc(term_ListOfConstants(t), consts);
+ }
+
+ return consts;
+}
+
+LIST clause_ListOfVariables(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: A list of variables.
+ EFFECT: Creates a list of variables occurring in the clause.
+ A variable occurs several times in the list, if
+ it does so in the clause.
+***************************************************************/
+{
+ LIST vars;
+ int i;
+
+ vars = list_Nil();
+
+ for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++) {
+ TERM t;
+
+ t = clause_GetLiteralAtom(Clause, i);
+
+ vars = list_Nconc(term_ListOfVariables(t), vars);
+ }
+
+ return vars;
+}
+
+LIST clause_ListOfFunctions(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: A list of symbols.
+ EFFECT: Creates a list of functions occurring in the clause.
+ A function occurs several times in the list, if
+ it does so in the clause.
+***************************************************************/
+{
+ LIST funs;
+ int i;
+
+ funs = list_Nil();
+
+ for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++) {
+ TERM t;
+
+ t = clause_GetLiteralAtom(Clause, i);
+
+ funs = list_Nconc(term_ListOfFunctions(t), funs);
+ }
+
+ return funs;
+}
+
+static int clause_CompareByPredicateDistribution(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by the frequency of predicates.
+***************************************************************/
+{
+ LIST lpreds, rpreds;
+ int result;
+
+ lpreds = clause_ListOfPredicates(Left);
+ rpreds = clause_ListOfPredicates(Right);
+
+ result = list_CompareMultisetsByElementDistribution(lpreds, rpreds);
+
+ list_Delete(lpreds);
+ list_Delete(rpreds);
+
+ return result;
+}
+
+static int clause_CompareByConstantDistribution(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by the frequency of constants.
+***************************************************************/
+{
+ LIST lconsts, rconsts;
+ int result;
+
+ lconsts = clause_ListOfConstants(Left);
+ rconsts = clause_ListOfConstants(Right);
+
+ result = list_CompareMultisetsByElementDistribution(lconsts, rconsts);
+
+ list_Delete(lconsts);
+ list_Delete(rconsts);
+
+ return result;
+}
+
+static int clause_CompareByVariableDistribution(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by the frequency of variables.
+***************************************************************/
+{
+ LIST lvars, rvars;
+ int result;
+
+ lvars = clause_ListOfVariables(Left);
+ rvars = clause_ListOfVariables(Right);
+
+ result = list_CompareMultisetsByElementDistribution(lvars, rvars);
+
+ list_Delete(lvars);
+ list_Delete(rvars);
+
+ return result;
+}
+
+static int clause_CompareByFunctionDistribution(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by the frequency of functions.
+***************************************************************/
+{
+ LIST lfuns, rfuns;
+ int result;
+
+ lfuns = clause_ListOfFunctions(Left);
+ rfuns = clause_ListOfFunctions(Right);
+
+ result = list_CompareMultisetsByElementDistribution(lfuns, rfuns);
+
+ list_Delete(lfuns);
+ list_Delete(rfuns);
+
+ return result;
+}
+
+static int clause_CompareByDepth(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by their depth.
+***************************************************************/
+{
+ if (clause_Depth(Left) < clause_Depth(Right))
+ return -1;
+ else if (clause_Depth(Left) > clause_Depth(Right))
+ return 1;
+
+ return 0;
+}
+
+static int clause_CompareByMaxVar(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by their maximal variable.
+***************************************************************/
+{
+ if (clause_MaxVar(Left) < clause_MaxVar(Right))
+ return -1;
+ else if (clause_MaxVar(Left) > clause_MaxVar(Right))
+ return 1;
+
+ return 0;
+}
+
+static int clause_CompareByLiterals(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by comparing their literals
+ from left to right.
+***************************************************************/
+{
+ int firstlitleft, lastlitleft;
+ int firstlitright, lastlitright;
+ int i, j;
+ int result;
+
+ result = 0;
+
+ /* Compare sorted literals from right to left */
+
+ firstlitleft = clause_FirstLitIndex();
+ lastlitleft = clause_LastLitIndex(Left);
+ firstlitright = clause_FirstLitIndex();
+ lastlitright = clause_LastLitIndex(Right);
+
+ for (i = lastlitleft, j = lastlitright;
+ i >= firstlitleft && j >= firstlitright;
+ --i, --j) {
+ TERM lterm, rterm;
+
+ lterm = clause_GetLiteralTerm(Left, i);
+ rterm = clause_GetLiteralTerm(Right, j);
+
+ result = term_CompareAbstract(lterm, rterm);
+
+ if (result != 0)
+ break;
+ }
+
+ if (result == 0) {
+ /* All literals compared equal, so check if someone has
+ uncompared literals left over.
+ */
+ if ( i > j) {
+ /* Left clause has uncompared literals left over. */
+ result = 1;
+ }
+ else if (i < j) {
+ /* Right clause has uncompared literals left over. */
+ result = -1;
+ }
+ }
+
+ return result;
+}
+
+static int clause_CompareBySymbolOccurences(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by comparing the occurrences of
+ symbols in their respective literals from left to
+ right. If a symbol occurs less frequently than
+ its positional equivalent in the other clause,
+ then the first clause is smaller.
+***************************************************************/
+{
+ int firstlitleft, lastlitleft;
+ int firstlitright, lastlitright;
+ int i, j;
+ int result;
+
+ result = 0;
+
+ /* Compare sorted literals from right to left */
+
+ firstlitleft = clause_FirstLitIndex();
+ lastlitleft = clause_LastLitIndex(Left);
+ firstlitright = clause_FirstLitIndex();
+ lastlitright = clause_LastLitIndex(Right);
+
+ for (i = lastlitleft, j = lastlitright;
+ i >= firstlitleft && j >= firstlitright;
+ --i, --j) {
+ TERM lterm, rterm;
+ LITERAL llit, rlit;
+
+ llit = clause_GetLiteral(Left, i);
+ rlit = clause_GetLiteral(Right, j);
+
+ if (clause_LiteralIsPredicate(llit)) {
+ if (clause_LiteralIsPredicate(rlit)) {
+ if (symbol_GetCount(clause_LiteralPredicate(llit))
+ < symbol_GetCount(clause_LiteralPredicate(rlit))) {
+ return -1;
+ }
+ else if (symbol_GetCount(clause_LiteralPredicate(llit))
+ > symbol_GetCount(clause_LiteralPredicate(rlit))) {
+ return 1;
+ }
+ }
+ }
+
+ lterm = clause_GetLiteralTerm(Left, i);
+ rterm = clause_GetLiteralTerm(Right, j);
+
+ result = term_CompareBySymbolOccurences(lterm, rterm);
+
+ if (result != 0)
+ break;
+ }
+
+ return result;
+}
+
+int clause_CompareAbstract(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two clauses by their weight. If the weight
+ is equal, it compares the clauses by the arity of
+ their literals from right to left.
+ CAUTION: Expects clause literal order to be fixed.
+***************************************************************/
+{
+
+ typedef int (*CLAUSE_COMPARE_FUNCTION) (CLAUSE, CLAUSE);
+
+ static const CLAUSE_COMPARE_FUNCTION clause_compare_functions [] = {
+ clause_CompareByWeight,
+ clause_CompareByDepth,
+ clause_CompareByMaxVar,
+ clause_CompareByClausePartSize,
+ clause_CompareByLiterals,
+ clause_CompareBySymbolOccurences,
+ clause_CompareByPredicateDistribution,
+ clause_CompareByConstantDistribution,
+ clause_CompareByFunctionDistribution,
+ clause_CompareByVariableDistribution,
+ };
+
+ int result;
+ int i;
+ int functions;
+
+ result = 0;
+ functions = sizeof(clause_compare_functions)/sizeof(CLAUSE_COMPARE_FUNCTION);
+
+ for (i = 0; i < functions; i++) {
+ result = clause_compare_functions[i](Left, Right);
+
+ if ( result != 0) {
+ return result;
+ }
+ }
+
+ return 0;
+}
+
+
+/**************************************************************/
+/* Clause functions */
+/**************************************************************/
+
+void clause_Init(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ SUMMARY: Initializes the clause counter and other variables
+ from this module.
+***************************************************************/
+{
+ int i;
+ clause_SetCounter(1);
+ clause_STAMPID = term_GetStampID();
+ for (i = 0; i <= clause_MAXWEIGHT; i++)
+ clause_SORT[i] = list_Nil();
+}
+
+
+CLAUSE clause_CreateBody(int ClauseLength)
+/**************************************************************
+ INPUT: The number of literals as integer.
+ RETURNS: A new generated clause node for 'ClauseLength'
+ MEMORY: Allocates a CLAUSE_NODE and the needed array for LITERALs.
+*************************************************************/
+{
+ CLAUSE Result;
+
+ Result = (CLAUSE)memory_Malloc(sizeof(CLAUSE_NODE));
+
+ Result->clausenumber = clause_IncreaseCounter();
+ Result->maxVar = symbol_GetInitialStandardVarCounter();
+ Result->flags = 0;
+ Result->depth = 0;
+ clause_InitSplitData(Result);
+ Result->weight = clause_WEIGHTUNDEFINED;
+ Result->parentCls = list_Nil();
+ Result->parentLits = list_Nil();
+
+ Result->c = 0;
+ Result->a = 0;
+ Result->s = 0;
+
+ if (ClauseLength != 0)
+ Result->literals =
+ (LITERAL *)memory_Malloc((ClauseLength) * sizeof(LITERAL));
+
+ clause_SetFromInput(Result);
+
+ return Result;
+}
+
+
+CLAUSE clause_Create(LIST Constraint, LIST Antecedent, LIST Succedent,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: Three lists of pointers to atoms, a flag store and
+ a precedence.
+ RETURNS: The new generated clause.
+ MEMORY: Allocates a CLAUSE_NODE and the needed LITERAL_NODEs,
+ uses the terms from the lists, additionally allocates
+ termnodes for the fol_Not() in Const. and Ante.
+*************************************************************/
+{
+ CLAUSE Result;
+ int i, c, a, s;
+
+ Result = (CLAUSE)memory_Malloc(sizeof(CLAUSE_NODE));
+
+ Result->clausenumber = clause_IncreaseCounter();
+ Result->flags = 0;
+ Result->depth = 0;
+ Result->weight = clause_WEIGHTUNDEFINED;
+ clause_InitSplitData(Result);
+ Result->parentCls = list_Nil();
+ Result->parentLits = list_Nil();
+
+ Result->c = (c = list_Length(Constraint));
+ Result->a = (a = list_Length(Antecedent));
+ Result->s = (s = list_Length(Succedent));
+
+ if (!clause_IsEmptyClause(Result))
+ Result->literals =
+ (LITERAL *) memory_Malloc((c+a+s) * sizeof(LITERAL));
+
+ for (i = 0; i < c; i++) {
+ Result->literals[i] =
+ clause_LiteralCreate(term_Create(fol_Not(),
+ list_List((TERM)list_Car(Constraint))),Result);
+ Constraint = list_Cdr(Constraint);
+ }
+
+ a += c;
+ for ( ; i < a; i++) {
+ Result->literals[i] =
+ clause_LiteralCreate(term_Create(fol_Not(),
+ list_List((TERM)list_Car(Antecedent))), Result);
+ Antecedent = list_Cdr(Antecedent);
+ }
+
+ s += a;
+ for ( ; i < s; i++) {
+ Result->literals[i] =
+ clause_LiteralCreate((TERM) list_Car(Succedent), Result);
+ Succedent = list_Cdr(Succedent);
+ }
+
+ clause_OrientAndReInit(Result, Flags, Precedence);
+ clause_SetFromInput(Result);
+
+ return Result;
+}
+
+
+CLAUSE clause_CreateCrude(LIST Constraint, LIST Antecedent, LIST Succedent,
+ BOOL Con)
+/**************************************************************
+ INPUT: Three lists of pointers to literals (!) and a Flag indicating
+ whether the clause comes from the conjecture part of of problem.
+ It is assumed that Constraint and Antecedent literals are negative,
+ whereas Succedent literals are positive.
+ RETURNS: The new generated clause, where a clause_OrientAndReInit has still
+ to be performed, i.e., variables are not normalized, maximal literal
+ flags not set, equations not oriented, the weight is not set.
+ MEMORY: Allocates a CLAUSE_NODE and the needed LITERAL_NODEs,
+ uses the terms from the lists, additionally allocates
+ termnodes for the fol_Not() in Const. and Ante.
+****************************************************************/
+{
+ CLAUSE Result;
+ int i,c,a,s;
+
+ Result = (CLAUSE)memory_Malloc(sizeof(CLAUSE_NODE));
+
+ Result->clausenumber = clause_IncreaseCounter();
+ Result->flags = 0;
+ if (Con)
+ clause_SetFlag(Result, CONCLAUSE);
+
+ Result->depth = 0;
+ Result->weight = clause_WEIGHTUNDEFINED;
+ clause_InitSplitData(Result);
+ Result->parentCls = list_Nil();
+ Result->parentLits = list_Nil();
+
+ Result->c = (c = list_Length(Constraint));
+ Result->a = (a = list_Length(Antecedent));
+ Result->s = (s = list_Length(Succedent));
+
+ if (!clause_IsEmptyClause(Result))
+ Result->literals = (LITERAL *)memory_Malloc((c+a+s) * sizeof(LITERAL));
+
+ for (i = 0; i < c; i++) {
+ Result->literals[i] =
+ clause_LiteralCreate(list_Car(Constraint),Result);
+ Constraint = list_Cdr(Constraint);
+ }
+
+ a += c;
+ for ( ; i < a; i++) {
+ Result->literals[i] =
+ clause_LiteralCreate(list_Car(Antecedent), Result);
+ Antecedent = list_Cdr(Antecedent);
+ }
+
+ s += a;
+ for ( ; i < s; i++) {
+ Result->literals[i] = clause_LiteralCreate(list_Car(Succedent), Result);
+ Succedent = list_Cdr(Succedent);
+ }
+
+ clause_SetFromInput(Result);
+
+ return Result;
+}
+
+
+CLAUSE clause_CreateUnnormalized(LIST Constraint, LIST Antecedent,
+ LIST Succedent)
+/**************************************************************
+ INPUT: Three lists of pointers to atoms.
+ RETURNS: The new generated clause.
+ MEMORY: Allocates a CLAUSE_NODE and the needed LITERAL_NODEs,
+ uses the terms from the lists, additionally allocates
+ termnodes for the fol_Not() in Const. and Ante.
+ CAUTION: The weight of the clause is not set correctly and
+ equations are not oriented!
+****************************************************************/
+{
+ CLAUSE Result;
+ int i,c,a,s;
+
+ Result = (CLAUSE)memory_Malloc(sizeof(CLAUSE_NODE));
+
+ Result->clausenumber = clause_IncreaseCounter();
+ Result->flags = 0;
+ Result->depth = 0;
+ Result->weight = clause_WEIGHTUNDEFINED;
+ clause_InitSplitData(Result);
+ Result->parentCls = list_Nil();
+ Result->parentLits = list_Nil();
+
+ Result->c = (c = list_Length(Constraint));
+ Result->a = (a = list_Length(Antecedent));
+ Result->s = (s = list_Length(Succedent));
+
+ if (!clause_IsEmptyClause(Result)) {
+ Result->literals = (LITERAL *)memory_Malloc((c+a+s) * sizeof(LITERAL));
+
+ for (i = 0; i < c; i++) {
+ Result->literals[i] =
+ clause_LiteralCreate(term_Create(fol_Not(),
+ list_List(list_Car(Constraint))),
+ Result);
+ Constraint = list_Cdr(Constraint);
+ }
+
+ a += c;
+ for ( ; i < a; i++) {
+ Result->literals[i] =
+ clause_LiteralCreate(term_Create(fol_Not(),
+ list_List(list_Car(Antecedent))),
+ Result);
+ Antecedent = list_Cdr(Antecedent);
+ }
+
+ s += a;
+ for ( ; i < s; i++) {
+ Result->literals[i] =
+ clause_LiteralCreate((TERM)list_Car(Succedent), Result);
+ Succedent = list_Cdr(Succedent);
+ }
+ clause_UpdateMaxVar(Result);
+ }
+
+ return Result;
+}
+
+
+CLAUSE clause_CreateFromLiterals(LIST LitList, BOOL Sorts, BOOL Conclause,
+ BOOL Ordering, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A list of literals, three boolean flags indicating whether
+ sort constraint literals should be generated, whether the
+ clause is a conjecture clause, whether the ordering information
+ should be established, a flag store and a precedence.
+ RETURNS: The new generated clause.
+ EFFECT: The result clause will be normalized and the maximal
+ variable will be set. If <Ordering> is FALSE no additional
+ initializations will be done. This mode is intended for
+ the parser for creating clauses at a time when the ordering
+ and weight flags aren't determined finally.
+ Only if <Ordering> is TRUE the equations will be oriented,
+ the maximal literals will be marked and the clause weight
+ will be set correctly.
+ MEMORY: Allocates a CLAUSE_NODE and the needed LITERAL_NODEs,
+ uses the terms from the lists.
+****************************************************************/
+{
+ CLAUSE Result;
+ LIST Antecedent,Succedent,Constraint;
+ TERM Atom;
+
+ Antecedent = list_Nil();
+ Succedent = list_Nil();
+ Constraint = list_Nil();
+
+ while (!list_Empty(LitList)) {
+ if (term_TopSymbol(list_Car(LitList)) == fol_Not()) {
+ Atom = term_FirstArgument(list_Car(LitList));
+ if (Sorts && symbol_IsBaseSort(term_TopSymbol(Atom)) && term_IsVariable(term_FirstArgument(Atom)))
+ Constraint = list_Cons(list_Car(LitList),Constraint);
+ else
+ Antecedent = list_Cons(list_Car(LitList),Antecedent);
+ }
+ else
+ Succedent = list_Cons(list_Car(LitList),Succedent);
+ LitList = list_Cdr(LitList);
+ }
+
+ Constraint = list_NReverse(Constraint);
+ Antecedent = list_NReverse(Antecedent);
+ Succedent = list_NReverse(Succedent);
+ Result = clause_CreateCrude(Constraint, Antecedent, Succedent, Conclause);
+
+ list_Delete(Constraint);
+ list_Delete(Antecedent);
+ list_Delete(Succedent);
+
+ if (Ordering)
+ clause_OrientAndReInit(Result, Flags, Precedence);
+ else {
+ clause_Normalize(Result);
+ clause_UpdateMaxVar(Result);
+ }
+
+ return Result;
+}
+
+void clause_SetSortConstraint(CLAUSE Clause, BOOL Strong, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a flag indicating whether also negative
+ monadic literals with a real term argument should be
+ put in the sort constraint, a flag store and a precedence.
+ RETURNS: Nothing.
+ EFFECT: Negative monadic literals are put in the sort constraint.
+****************************************************************/
+{
+ LITERAL ActLit,Help;
+ TERM ActAtom;
+ int i,k,NewConLits;
+
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_SetSortConstraint:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ i = clause_LastConstraintLitIndex(Clause);
+ NewConLits = 0;
+
+ for (k=clause_FirstAntecedentLitIndex(Clause);k<=clause_LastAntecedentLitIndex(Clause);k++) {
+ ActLit = clause_GetLiteral(Clause,k);
+ ActAtom = clause_LiteralAtom(ActLit);
+ if (symbol_IsBaseSort(term_TopSymbol(ActAtom)) &&
+ (Strong || term_IsVariable(term_FirstArgument(ActAtom)))) {
+ if (++i != k) {
+ Help = clause_GetLiteral(Clause,i);
+ clause_SetLiteral(Clause,i,ActLit);
+ clause_SetLiteral(Clause,k,Help);
+ }
+ NewConLits++;
+ }
+ }
+
+ clause_SetNumOfConsLits(Clause, clause_NumOfConsLits(Clause) + NewConLits);
+ clause_SetNumOfAnteLits(Clause, clause_NumOfAnteLits(Clause) - NewConLits);
+ clause_ReInit(Clause, Flags, Precedence);
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_SetSortConstraint:");
+ misc_ErrorReport("\n Illegal computations.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+}
+
+
+
+void clause_Delete(CLAUSE Clause)
+/**************************************************************
+ INPUT: A Clause.
+ RETURNS: Nothing.
+ MEMORY: Frees the memory of the clause.
+***************************************************************/
+{
+ int i, n;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) { /* Clause may be a byproduct of some hyper rule */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_Delete:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ n = clause_Length(Clause);
+
+ for (i = 0; i < n; i++)
+ clause_LiteralDelete(clause_GetLiteral(Clause,i));
+
+ clause_FreeLitArray(Clause);
+
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+#ifdef CHECK
+ if ((Clause->splitfield != NULL) && (Clause->splitfield_length == 0))
+ {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_Delete:");
+ misc_ErrorReport("\n Illegal splitfield_length.");
+ misc_FinishErrorReport();
+ }
+ if ((Clause->splitfield == NULL) && (Clause->splitfield_length != 0))
+ {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_Delete:");
+ misc_ErrorReport("\n Illegal splitfield.");
+ misc_FinishErrorReport();
+ }
+#endif
+ if (Clause->splitfield != NULL) {
+
+ memory_Free(Clause->splitfield,
+ sizeof(SPLITFIELDENTRY) * Clause->splitfield_length);
+ }
+ clause_Free(Clause);
+}
+
+
+/**************************************************************/
+/* Functions to use the sharing for clauses. */
+/**************************************************************/
+
+void clause_InsertIntoSharing(CLAUSE Clause, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, an index, a flag store and a precedence.
+ RETURNS: Nothing.
+ SUMMARY: Inserts the unsigned atoms of 'Clause' into the sharing index.
+***************************************************************/
+{
+ int i, litnum;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_Delete:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+ clause_Check(Clause, Flags, Precedence);
+#endif
+
+ litnum = clause_Length(Clause);
+
+ for (i = 0; i < litnum; i++) {
+ clause_LiteralInsertIntoSharing(clause_GetLiteral(Clause,i), ShIndex);
+ }
+}
+
+
+void clause_DeleteFromSharing(CLAUSE Clause, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, an Index, a flag store and a precedence.
+ RETURNS: Nothing.
+ SUMMARY: Deletes 'Clause' and all its literals from the sharing,
+ frees the memory of 'Clause'.
+***************************************************************/
+{
+ int i, length;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_DeleteFromSharing:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ length = clause_Length(Clause);
+
+ for (i = 0; i < length; i++)
+ clause_LiteralDeleteFromSharing(clause_GetLiteral(Clause,i),ShIndex);
+
+ clause_FreeLitArray(Clause);
+
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+#ifdef CHECK
+ if ((Clause->splitfield != NULL) && (Clause->splitfield_length == 0))
+ {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_DeleteFromSharing:");
+ misc_ErrorReport("\n Illegal splitfield_length.");
+ misc_FinishErrorReport();
+ }
+ if ((Clause->splitfield == NULL) && (Clause->splitfield_length != 0))
+ {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_DeleteFromSharing:");
+ misc_ErrorReport("\n Illegal splitfield.");
+ misc_FinishErrorReport();
+ }
+#endif
+ if (Clause->splitfield != NULL) {
+ memory_Free(Clause->splitfield,
+ sizeof(SPLITFIELDENTRY) * Clause->splitfield_length);
+ }
+ clause_Free(Clause);
+}
+
+
+void clause_MakeUnshared(CLAUSE Clause, SHARED_INDEX ShIndex)
+/**************************************************************
+ INPUT: A Clause and an Index.
+ RETURNS: Nothing.
+ SUMMARY: Deletes the clauses literals from the sharing and
+ replaces them by unshared copies.
+***************************************************************/
+{
+ LITERAL ActLit;
+ TERM SharedAtom, AtomCopy;
+ int i,LastAnte,length;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_MakeUnshared:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ LastAnte = clause_LastAntecedentLitIndex(Clause);
+ length = clause_Length(Clause);
+
+ for (i = clause_FirstLitIndex(); i <= LastAnte; i++) {
+ ActLit = clause_GetLiteral(Clause, i);
+ SharedAtom = clause_LiteralAtom(ActLit);
+ AtomCopy = term_Copy(SharedAtom);
+ sharing_Delete(ActLit, SharedAtom, ShIndex);
+ clause_LiteralSetNegAtom(ActLit, AtomCopy);
+ }
+
+ for ( ; i < length; i++) {
+ ActLit = clause_GetLiteral(Clause, i);
+ SharedAtom = clause_LiteralSignedAtom(ActLit);
+ AtomCopy = term_Copy(SharedAtom);
+ sharing_Delete(ActLit, SharedAtom, ShIndex);
+ clause_LiteralSetPosAtom(ActLit, AtomCopy);
+ }
+}
+
+void clause_MoveSharedClause(CLAUSE Clause, SHARED_INDEX Source,
+ SHARED_INDEX Destination, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, two indexes, a flag store, and a precedence.
+ RETURNS: Nothing.
+ EFFECT: Deletes <Clause> from <Source> and inserts it into
+ <Destination>.
+***************************************************************/
+{
+ LITERAL Lit;
+ TERM Atom,Copy;
+ int i,length;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_MoveSharedClause:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ length = clause_Length(Clause);
+
+ for (i = clause_FirstLitIndex(); i < length; i++) {
+ Lit = clause_GetLiteral(Clause, i);
+ Atom = clause_LiteralAtom(Lit);
+ Copy = term_Copy(Atom); /* sharing_Insert works destructively on <Copy>'s superterms */
+ clause_LiteralSetAtom(Lit, sharing_Insert(Lit, Copy, Destination));
+ sharing_Delete(Lit, Atom, Source);
+ term_Delete(Copy);
+ }
+}
+
+
+void clause_DeleteSharedLiteral(CLAUSE Clause, int Indice, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, a literals indice, an Index, a flag store
+ and a precedence.
+ RETURNS: Nothing.
+ SUMMARY: Deletes the shared literal from the clause.
+ MEMORY: Various.
+***************************************************************/
+{
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_DeleteSharedLiteral:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ clause_MakeUnshared(Clause, ShIndex);
+ clause_DeleteLiteral(Clause, Indice, Flags, Precedence);
+ clause_InsertIntoSharing(Clause, ShIndex, Flags, Precedence);
+}
+
+
+void clause_DeleteClauseList(LIST ClauseList)
+/**************************************************************
+ INPUT: A list of unshared clauses.
+ RETURNS: Nothing.
+ SUMMARY: Deletes all clauses in the list and the list.
+ MEMORY: Frees the lists and the clauses' memory.
+ ***************************************************************/
+{
+ LIST Scan;
+
+ for (Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (clause_Exists(list_Car(Scan)))
+ clause_Delete(list_Car(Scan));
+
+ list_Delete(ClauseList);
+}
+
+
+void clause_DeleteSharedClauseList(LIST ClauseList, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A list of clauses, an index, a flag store and
+ a precedence.
+ RETURNS: Nothing.
+ SUMMARY: Deletes all clauses in the list from the sharing.
+ MEMORY: Frees the lists and the clauses' memory.
+***************************************************************/
+{
+ LIST Scan;
+
+ for (Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ clause_DeleteFromSharing(list_Car(Scan), ShIndex, Flags, Precedence);
+
+ list_Delete(ClauseList);
+}
+
+
+void clause_DeleteAllIndexedClauses(SHARED_INDEX ShIndex, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: An Index, a flag store and a precedence.
+ RETURNS: Nothing.
+ SUMMARY: Deletes all clauses' terms from the sharing, frees their
+ memory.
+ MEMORY: Frees the memory of all clauses with terms in the index.
+***************************************************************/
+{
+ LIST TermList,DelList,Scan;
+ TERM NewVar;
+ SYMBOL NewVarSymbol;
+
+ NewVar = term_CreateStandardVariable();
+ NewVarSymbol = term_TopSymbol(NewVar);
+
+ TermList = st_GetInstance(cont_LeftContext(), sharing_Index(ShIndex), NewVar);
+ /* This should yield a list of all terms in the index
+ and thus the sharing. */
+
+ while (!list_Empty(TermList)) {
+
+ DelList = sharing_GetDataList(list_Car(TermList), ShIndex);
+
+ for (Scan = DelList;
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan))
+ list_Rplaca(Scan, clause_LiteralOwningClause(list_Car(Scan)));
+
+ DelList = list_PointerDeleteDuplicates(DelList);
+
+ for (Scan = DelList;
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan))
+ clause_DeleteFromSharing(list_Car(Scan), ShIndex, Flags, Precedence);
+
+ list_Delete(TermList);
+
+ TermList = st_GetInstance(cont_LeftContext(), sharing_Index(ShIndex), NewVar);
+
+ list_Delete(DelList);
+ }
+ term_Delete(NewVar);
+ symbol_Delete(NewVarSymbol);
+}
+
+
+void clause_PrintAllIndexedClauses(SHARED_INDEX ShIndex)
+/**************************************************************
+ INPUT: An Index.
+ RETURNS: Nothing.
+ SUMMARY: Prints all indexed clauses to stdout.
+***************************************************************/
+{
+ LIST TermList,ClList,PrintList,Scan;
+ TERM NewVar;
+ SYMBOL NewVarSymbol;
+
+ NewVar = term_CreateStandardVariable();
+ NewVarSymbol = term_TopSymbol(NewVar);
+
+ TermList = st_GetInstance(cont_LeftContext(), sharing_Index(ShIndex), NewVar);
+ /* This should yield a list of all terms in the index
+ and thus the sharing. */
+
+ PrintList = list_Nil();
+
+ while (!list_Empty(TermList)) {
+
+ ClList = sharing_GetDataList(list_Car(TermList), ShIndex);
+
+ for (Scan = ClList;
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan))
+ list_Rplaca(Scan, clause_LiteralOwningClause(list_Car(Scan)));
+
+ PrintList = list_NPointerUnion(ClList, PrintList);
+
+ Scan = TermList;
+ TermList = list_Cdr(TermList);
+ list_Free(Scan);
+ }
+ clause_ListPrint(PrintList);
+
+ list_Delete(PrintList);
+
+ term_Delete(NewVar);
+ symbol_Delete(NewVarSymbol);
+}
+
+
+LIST clause_AllIndexedClauses(SHARED_INDEX ShIndex)
+/**************************************************************
+ INPUT: An index
+ RETURNS: A list of all the clauses in the index
+ MEMORY: Memory is allocated for the list nodes
+***************************************************************/
+{
+ LIST clauselist, scan;
+ clauselist = sharing_GetAllSuperTerms(ShIndex);
+ for (scan = clauselist; scan != list_Nil(); scan = list_Cdr(scan))
+ list_Rplaca(scan, clause_LiteralOwningClause(list_Car(scan)));
+ clauselist = list_PointerDeleteDuplicates(clauselist);
+ return clauselist;
+}
+
+
+/**************************************************************/
+/* Clause Access Functions */
+/**************************************************************/
+
+void clause_DeleteLiteralNN(CLAUSE Clause, int Indice)
+/**************************************************************
+ INPUT: An unshared clause, and a literal index.
+ RETURNS: Nothing.
+ EFFECT: The literal is position <Indice> is deleted from <Clause>.
+ The clause isn't reinitialized afterwards.
+ MEMORY: The memory of the literal with the 'Indice' and
+ memory of its atom is freed.
+***************************************************************/
+{
+ int i, lc, la, length, shift;
+ LITERAL *Literals;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause) || (clause_Length(Clause) <= Indice) ||
+ Indice < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_DeleteLiteral:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ lc = clause_LastConstraintLitIndex(Clause);
+ la = clause_LastAntecedentLitIndex(Clause);
+ length = clause_Length(Clause);
+
+ /* Create a new literal array */
+ if (length > 1)
+ Literals = (LITERAL*) memory_Malloc(sizeof(LITERAL) * (length-1));
+ else
+ Literals = (LITERAL*) NULL;
+
+ /* Copy literals to the new array */
+ shift = 0;
+ length--; /* The loop iterates over the new array */
+ for (i = 0; i < length; i++) {
+ if (i == Indice)
+ shift = 1;
+ Literals[i] = Clause->literals[i+shift];
+ }
+
+ /* Free literal and old array and set new one */
+ clause_LiteralDelete(clause_GetLiteral(Clause, Indice));
+ clause_FreeLitArray(Clause);
+ Clause->literals = Literals;
+
+ /* Update clause */
+ if (Indice <= lc)
+ clause_SetNumOfConsLits(Clause, clause_NumOfConsLits(Clause) - 1);
+ else if (Indice <= la)
+ clause_SetNumOfAnteLits(Clause, clause_NumOfAnteLits(Clause) - 1);
+ else
+ clause_SetNumOfSuccLits(Clause, clause_NumOfSuccLits(Clause) - 1);
+ /* Mark the weight as undefined */
+ Clause->weight = clause_WEIGHTUNDEFINED;
+}
+
+
+void clause_DeleteLiteral(CLAUSE Clause, int Indice, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: An unshared clause, a literals index, a flag store,
+ and a precedence.
+ RETURNS: Nothing.
+ EFFECT: The literal at position <Indice> is deleted from <Clause>.
+ In contrast to the function clause_DeleteLiteralNN
+ the clause is reinitialized afterwards.
+ MEMORY: The memory of the literal with the 'Indice' and memory
+ of its atom is freed.
+***************************************************************/
+{
+ clause_DeleteLiteralNN(Clause, Indice);
+ clause_ReInit(Clause, Flags, Precedence);
+}
+
+
+void clause_DeleteLiterals(CLAUSE Clause, LIST Indices, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: An unshared clause, a list of literal indices a
+ flag store and a precedence.
+ RETURNS: Nothing.
+ EFFECT: The literals given by <Indices> are deleted.
+ The clause is reinitialized afterwards.
+ MEMORY: The memory of the literals with the 'Indice' and
+ memory of its atom is freed.
+***************************************************************/
+{
+ LITERAL *NewLits;
+ int i, j, nc, na, ns, lc, la, olength, nlength;
+
+#ifdef CHECK
+ LIST Scan;
+ if (!list_IsSetOfPointers(Indices)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_DeleteLiterals:");
+ misc_ErrorReport(" list contains duplicate indices.");
+ misc_FinishErrorReport();
+ }
+ /* check the literal indices */
+ for (Scan = Indices; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ i = (int) list_Car(Scan);
+ if (i < 0 || i > clause_LastLitIndex(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_DeleteLiterals:");
+ misc_ErrorReport(" literal index %d is out ", i);
+ misc_ErrorReport(" of bounds");
+ misc_FinishErrorReport();
+ }
+ }
+#endif
+
+ nc = 0;
+ na = 0;
+ ns = 0;
+ lc = clause_LastConstraintLitIndex(Clause);
+ la = clause_LastAntecedentLitIndex(Clause);
+
+ olength = clause_Length(Clause);
+ nlength = olength - list_Length(Indices);
+
+ if (nlength != 0)
+ NewLits = (LITERAL*) memory_Malloc(sizeof(LITERAL) * nlength);
+ else
+ NewLits = (LITERAL*) NULL;
+
+ for (i=clause_FirstLitIndex(), j=clause_FirstLitIndex(); i < olength; i++)
+
+ if (list_PointerMember(Indices, (POINTER) i))
+ clause_LiteralDelete(clause_GetLiteral(Clause,i));
+ else {
+
+ NewLits[j++] = clause_GetLiteral(Clause,i);
+
+ if (i <= lc)
+ nc++;
+ else if (i <= la)
+ na++;
+ else
+ ns++;
+ }
+ clause_FreeLitArray(Clause);
+ Clause->literals = NewLits;
+
+ clause_SetNumOfConsLits(Clause, nc);
+ clause_SetNumOfAnteLits(Clause, na);
+ clause_SetNumOfSuccLits(Clause, ns);
+
+ clause_ReInit(Clause, Flags, Precedence);
+}
+
+
+/**************************************************************/
+/* Clause Comparisons */
+/**************************************************************/
+
+BOOL clause_IsHornClause(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: The boolean value TRUE if 'Clause' is a hornclause
+ FALSE else.
+ ***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_IsHornClause:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+ return (clause_NumOfSuccLits(Clause) <= 1);
+}
+
+
+BOOL clause_HasTermSortConstraintLits(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause,
+ RETURNS: TRUE iff there is at least one sort constraint atom having
+ a term as its argument
+***************************************************************/
+{
+ int i,n;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_HasTermSortConstraintLits:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ n = clause_LastConstraintLitIndex(Clause);
+
+ for (i = clause_FirstConstraintLitIndex(Clause); i <= n; i++)
+ if (!term_AllArgsAreVar(clause_GetLiteralAtom(Clause,i)))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+BOOL clause_HasSolvedConstraint(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: The boolean value TRUE if 'Clause' has a solved
+ constraint, i.e. only variables as sort arguments,
+ FALSE else.
+***************************************************************/
+{
+ int i,c;
+ LIST CVars, LitVars;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_HasSolvedConstraint:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ CVars = list_Nil();
+ c = clause_NumOfConsLits(Clause);
+
+ if (c == 0)
+ return TRUE;
+
+ if (clause_HasTermSortConstraintLits(Clause))
+ return FALSE;
+
+ for (i = 0; i < c; i++)
+ CVars = list_NPointerUnion(term_VariableSymbols(clause_GetLiteralAtom(Clause, i)), CVars);
+
+ if (i == c) {
+ c = clause_Length(Clause);
+ LitVars = list_Nil();
+
+ for ( ; i < c; i++)
+ LitVars = list_NPointerUnion(LitVars, term_VariableSymbols(clause_GetLiteralAtom(Clause, i)));
+
+ if (list_Empty(CVars = list_NPointerDifference(CVars, LitVars))) {
+ list_Delete(LitVars);
+ return TRUE;
+ }
+ list_Delete(LitVars);
+ }
+
+ list_Delete(CVars);
+
+ return FALSE;
+}
+
+
+BOOL clause_HasSelectedLiteral(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, a flag store and a precedence.
+ RETURNS: The boolean value TRUE iff <Clause> has a selected literal
+***************************************************************/
+{
+ int i,negs;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_HasSelectedLiteral:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ negs = clause_LastAntecedentLitIndex(Clause);
+
+ for (i=clause_FirstAntecedentLitIndex(Clause); i <= negs; i++)
+ if (clause_LiteralGetFlag(clause_GetLiteral(Clause,i), LITSELECT))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+BOOL clause_IsDeclarationClause(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: The boolean value TRUE, if 'Clause' has only variables
+ as arguments in constraint literals.
+***************************************************************/
+{
+ int i,length;
+ LITERAL Lit;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_IsDeclarationClause:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!clause_HasSolvedConstraint(Clause))
+ return FALSE;
+
+ length = clause_Length(Clause);
+
+ for (i=clause_FirstSuccedentLitIndex(Clause);i<length;i++) {
+ Lit = clause_GetLiteral(Clause,i);
+ if (clause_LiteralIsMaximal(Lit) &&
+ symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(Lit))))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+BOOL clause_IsSortTheoryClause(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, a flag store and a precedence.
+ RETURNS: The boolean value TRUE, if 'Clause' has only variables
+ as arguments in constraint literals, no antecedent literals
+ and exactly one monadic succedent literal.
+***************************************************************/
+{
+ LITERAL Lit;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_IsSortTheoryClause:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (clause_NumOfAnteLits(Clause) > 0 ||
+ clause_NumOfSuccLits(Clause) > 1 ||
+ !clause_HasSolvedConstraint(Clause))
+ return FALSE;
+
+ Lit = clause_GetLiteral(Clause,clause_FirstSuccedentLitIndex(Clause));
+ if (symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(Lit))))
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL clause_IsPotentialSortTheoryClause(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, a flag store and a precedence.
+ RETURNS: The boolean value TRUE, if 'Clause' has monadic literals
+ only variables as arguments in antecedent/constraint literals,
+ no other antecedent literals and exactly one monadic succedent
+ literal.
+***************************************************************/
+{
+ LITERAL Lit;
+ int i;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_IsPotentialSortTheoryClause:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (clause_NumOfSuccLits(Clause) != 1)
+ return FALSE;
+
+ for (i=clause_FirstLitIndex();i<clause_FirstSuccedentLitIndex(Clause);i++) {
+ Lit = clause_GetLiteral(Clause,i);
+ if (!symbol_IsBaseSort(term_TopSymbol(clause_LiteralAtom(Lit))) ||
+ !term_IsVariable(term_FirstArgument(clause_LiteralAtom(Lit))))
+ return FALSE;
+ }
+
+ Lit = clause_GetLiteral(Clause,clause_FirstSuccedentLitIndex(Clause));
+ if (symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(Lit))))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+BOOL clause_HasOnlyVarsInConstraint(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, a flag store and a precedence.
+ RETURNS: The boolean value TRUE, if 'Clause' has only variables
+ as arguments in constraint literals.
+***************************************************************/
+{
+ int i,nc;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_HasOnlyVarsInConstraint:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ nc = clause_NumOfConsLits(Clause);
+
+ for (i = 0; i < nc && term_AllArgsAreVar(clause_GetLiteralAtom(Clause,i)); i++)
+ /* empty */;
+
+ return (i == nc);
+}
+
+
+BOOL clause_HasSortInSuccedent(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, a flag store and a precedence.
+ RETURNS: The boolean value TRUE, if 'Clause' has a maximal succedent
+ sort literal; FALSE, else.
+***************************************************************/
+{
+ LITERAL Lit;
+ int i,l;
+ BOOL result = FALSE;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_HasSortInSuccedent:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ l = clause_Length(Clause);
+
+ for (i = clause_FirstSuccedentLitIndex(Clause); i < l && !result ; i++) {
+ Lit = clause_GetLiteral(Clause, i);
+ result = (symbol_Arity(term_TopSymbol(clause_LiteralAtom(Lit))) == 1);
+ }
+ return result;
+}
+
+
+BOOL clause_LitsHaveCommonVar(LITERAL Lit1, LITERAL Lit2)
+/**************************************************************
+ INPUT: Two literals.
+ RETURNS: The boolean value TRUE, if 'Lit1' and 'Lit2' have
+ common variables, FALSE, else.
+***************************************************************/
+{
+ LIST Vars1, Vars2;
+ BOOL Result;
+
+ Vars1 = term_VariableSymbols(clause_LiteralAtom(Lit1));
+ Vars2 = term_VariableSymbols(clause_LiteralAtom(Lit2));
+ Result = list_HasIntersection(Vars1, Vars2);
+ list_Delete(Vars1);
+ list_Delete(Vars2);
+
+ return Result;
+}
+
+
+/**************************************************************/
+/* Clause Input and Output Functions */
+/**************************************************************/
+
+void clause_Print(CLAUSE Clause)
+/**************************************************************
+ INPUT: A Clause.
+ RETURNS: Nothing.
+ SUMMARY: The clause is printed to stdout.
+***************************************************************/
+{
+ RULE Origin;
+ LITERAL Lit;
+ int i,c,a,s;
+
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_Print:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!clause_Exists(Clause))
+ fputs("(CLAUSE)NULL", stdout);
+ else {
+ printf("%d",clause_Number(Clause));
+
+ Origin = clause_Origin(Clause);
+ printf("[%d:", clause_SplitLevel(Clause));
+
+#ifdef CHECK
+ if (Clause->splitfield_length <= 1)
+ fputs("0.", stdout);
+ else
+ for (i=Clause->splitfield_length-1; i > 0; i--)
+ printf("%lu.", Clause->splitfield[i]);
+ if (Clause->splitfield_length == 0)
+ putchar('1');
+ else
+ printf("%lu", (Clause->splitfield[0] | 1));
+ printf(":%c%c:%c:%d:%d:", clause_GetFlag(Clause, CONCLAUSE) ? 'C' : 'A',
+ clause_GetFlag(Clause, WORKEDOFF) ? 'W' : 'U',
+ clause_GetFlag(Clause, NOPARAINTO) ? 'N' : 'P',
+ clause_Weight(Clause), clause_Depth(Clause));
+#endif
+
+ clause_PrintOrigin(Clause);
+
+ if (Origin == INPUT) {
+ ;
+ } else {
+ putchar(':');
+ clause_PrintParentClauses(Clause);
+ }
+ putchar(']');
+
+ c = clause_NumOfConsLits(Clause);
+ a = clause_NumOfAnteLits(Clause);
+ s = clause_NumOfSuccLits(Clause);
+
+ for (i = 0; i < c; i++) {
+ putchar(' ');
+ Lit = clause_GetLiteral(Clause, i);
+ clause_LiteralPrintUnsigned(Lit);
+ }
+ fputs(" || ", stdout);
+
+ a += c;
+ for ( ; i < a; i++) {
+
+ Lit = clause_GetLiteral(Clause, i);
+ clause_LiteralPrintUnsigned(Lit);
+ if (clause_LiteralIsMaximal(Lit)) {
+ putchar('*');
+ if (clause_LiteralIsOrientedEquality(Lit))
+ putchar('*');
+ }
+ if (clause_LiteralGetFlag(Lit,LITSELECT))
+ putchar('+');
+ if (i+1 < a)
+ putchar(' ');
+ }
+ fputs(" -> ",stdout);
+
+ s += a;
+ for ( ; i < s; i++) {
+
+ Lit = clause_GetLiteral(Clause, i);
+ clause_LiteralPrintUnsigned(Lit);
+ if (clause_LiteralIsMaximal(Lit)) {
+ putchar('*');
+ if (clause_LiteralIsOrientedEquality(Lit))
+ putchar('*');
+ }
+#ifdef CHECK
+ if (clause_LiteralGetFlag(Lit,LITSELECT)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_Print: Clause has selected positive literal.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+ if (i+1 < s)
+ putchar(' ');
+ }
+ putchar('.');
+ }
+}
+
+
+void clause_PrintMaxLitsOnly(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, a flag store and a precedence.
+ RETURNS: Nothing.
+ SUMMARY:
+***************************************************************/
+{
+ int i,c,a,s;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_PrinMaxLitsOnly:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ c = clause_NumOfConsLits(Clause);
+ a = clause_NumOfAnteLits(Clause);
+ s = clause_NumOfSuccLits(Clause);
+
+ for (i = 0; i < c; i++) {
+ if (clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)))
+ clause_LiteralPrint(clause_GetLiteral(Clause, i));
+ if (clause_LiteralGetFlag(clause_GetLiteral(Clause, i),STRICTMAXIMAL)) {
+ clause_LiteralPrint(clause_GetLiteral(Clause, i));
+ fputs("(strictly)", stdout);
+ }
+ }
+ fputs(" || ", stdout);
+
+ a += c;
+ for ( ; i < a; i++) {
+ if (clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)))
+ clause_LiteralPrint(clause_GetLiteral(Clause, i));
+ if (clause_LiteralGetFlag(clause_GetLiteral(Clause, i),STRICTMAXIMAL)) {
+ clause_LiteralPrint(clause_GetLiteral(Clause, i));
+ fputs("(strictly)", stdout);
+ }
+ }
+ fputs(" -> ", stdout);
+
+ s += a;
+ for ( ; i < s; i++) {
+ if (clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)))
+ clause_LiteralPrint(clause_GetLiteral(Clause, i));
+ if (clause_LiteralGetFlag(clause_GetLiteral(Clause, i),STRICTMAXIMAL)) {
+ clause_LiteralPrint(clause_GetLiteral(Clause, i));
+ fputs("(strictly)", stdout);
+ }
+ }
+ puts("."); /* with newline */
+}
+
+
+void clause_FPrint(FILE* File, CLAUSE Clause)
+/**************************************************************
+ INPUT: A file and a clause.
+ RETURNS: Nothing.
+ SUMMARY: Prints any clause to the file 'File'.
+ CAUTION: Uses the term_Output functions.
+***************************************************************/
+{
+ int i, c, a, s;
+
+ c = clause_NumOfConsLits(Clause);
+ a = clause_NumOfAnteLits(Clause);
+ s = clause_NumOfSuccLits(Clause);
+
+ for (i = 0; i < c; i++)
+ term_FPrint(File, clause_GetLiteralAtom(Clause, i));
+
+ fputs(" || ", stdout);
+
+ a += c;
+ for ( ; i < a; i++)
+ term_FPrint(File, clause_GetLiteralAtom(Clause, i));
+
+ fputs(" -> ", stdout);
+
+ s += a;
+ for ( ; i < s; i++)
+ term_FPrint(File, clause_GetLiteralAtom(Clause, i));
+
+ putc('.', File);
+}
+
+
+void clause_ListPrint(LIST ClauseList)
+/**************************************************************
+ INPUT: A list of clauses.
+ RETURNS: Nothing.
+ SUMMARY: Prints the clauses to stdout.
+ CAUTION: Uses the clause_Print function.
+***************************************************************/
+{
+ while (!(list_Empty(ClauseList))) {
+ clause_Print(list_First(ClauseList));
+ ClauseList = list_Cdr(ClauseList);
+ if (!list_Empty(ClauseList))
+ putchar('\n');
+ }
+}
+
+
+void clause_PrintParentClauses(CLAUSE Clause)
+/**************************************************************
+ INPUT: A Clause.
+ RETURNS: Nothing.
+ SUMMARY: Prints the clauses parentclauses and -literals to stdout.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ if (!list_Empty(clause_ParentClauses(Clause))) {
+
+ Scan1 = clause_ParentClauses(Clause);
+ Scan2 = clause_ParentLiterals(Clause);
+ printf("%d.%d", (int)list_Car(Scan1), (int)list_Car(Scan2));
+
+ for (Scan1 = list_Cdr(Scan1), Scan2 = list_Cdr(Scan2);
+ !list_Empty(Scan1);
+ Scan1 = list_Cdr(Scan1), Scan2 = list_Cdr(Scan2))
+ printf(",%d.%d", (int)list_Car(Scan1), (int)list_Car(Scan2));
+ }
+}
+
+
+RULE clause_GetOriginFromString(const char* RuleName)
+/**************************************************************
+ INPUT: A string containing the abbreviated name of a rule.
+ RETURNS: The RULE corresponding to the <RuleName>.
+***************************************************************/
+{
+ if (string_Equal(RuleName, "App")) return CLAUSE_DELETION;
+ else if (string_Equal(RuleName, "EmS")) return EMPTY_SORT;
+ else if (string_Equal(RuleName, "SoR")) return SORT_RESOLUTION;
+ else if (string_Equal(RuleName, "EqR")) return EQUALITY_RESOLUTION;
+ else if (string_Equal(RuleName, "EqF")) return EQUALITY_FACTORING;
+ else if (string_Equal(RuleName, "MPm")) return MERGING_PARAMODULATION;
+ else if (string_Equal(RuleName, "SpR")) return SUPERPOSITION_RIGHT;
+ else if (string_Equal(RuleName, "SPm")) return PARAMODULATION;
+ else if (string_Equal(RuleName, "OPm")) return ORDERED_PARAMODULATION;
+ else if (string_Equal(RuleName, "SpL")) return SUPERPOSITION_LEFT;
+ else if (string_Equal(RuleName, "Res")) return GENERAL_RESOLUTION;
+ else if (string_Equal(RuleName, "SHy")) return SIMPLE_HYPER;
+ else if (string_Equal(RuleName, "OHy")) return ORDERED_HYPER;
+ else if (string_Equal(RuleName, "URR")) return UR_RESOLUTION;
+ else if (string_Equal(RuleName, "Fac")) return GENERAL_FACTORING;
+ else if (string_Equal(RuleName, "Spt")) return SPLITTING;
+ else if (string_Equal(RuleName, "Inp")) return INPUT;
+ else if (string_Equal(RuleName, "Rew")) return REWRITING;
+ else if (string_Equal(RuleName, "CRw")) return CONTEXTUAL_REWRITING;
+ else if (string_Equal(RuleName, "Con")) return CONDENSING;
+ else if (string_Equal(RuleName, "AED")) return ASSIGNMENT_EQUATION_DELETION;
+ else if (string_Equal(RuleName, "Obv")) return OBVIOUS_REDUCTIONS;
+ else if (string_Equal(RuleName, "SSi")) return SORT_SIMPLIFICATION;
+ else if (string_Equal(RuleName, "MRR")) return MATCHING_REPLACEMENT_RESOLUTION;
+ else if (string_Equal(RuleName, "UnC")) return UNIT_CONFLICT;
+ else if (string_Equal(RuleName, "Def")) return DEFAPPLICATION;
+ else if (string_Equal(RuleName, "Ter")) return TERMINATOR;
+ else {
+ misc_StartErrorReport();
+ misc_ErrorReport("\nIn clause_GetOriginFromString: Unknown clause origin.");
+ misc_FinishErrorReport();
+ return CLAUSE_DELETION; /* Just for the compiler, code is not reachable */
+ }
+}
+
+void clause_FPrintOrigin(FILE* File, CLAUSE Clause)
+/**************************************************************
+ INPUT: A Clause.
+ RETURNS: Nothing.
+ SUMMARY: Prints the clause's origin to the file.
+***************************************************************/
+{
+ RULE Result;
+
+ Result = clause_Origin(Clause);
+
+ switch(Result) {
+ case CLAUSE_DELETION: fputs("App", File); break;
+ case EMPTY_SORT: fputs("EmS", File); break;
+ case SORT_RESOLUTION: fputs("SoR", File); break;
+ case EQUALITY_RESOLUTION: fputs("EqR", File); break;
+ case EQUALITY_FACTORING: fputs("EqF", File); break;
+ case MERGING_PARAMODULATION: fputs("MPm", File); break;
+ case SUPERPOSITION_RIGHT: fputs("SpR", File); break;
+ case PARAMODULATION: fputs("SPm", File); break;
+ case ORDERED_PARAMODULATION: fputs("OPm", File); break;
+ case SUPERPOSITION_LEFT: fputs("SpL", File); break;
+ case GENERAL_RESOLUTION: fputs("Res", File); break;
+ case SIMPLE_HYPER: fputs("SHy", File); break;
+ case ORDERED_HYPER: fputs("OHy", File); break;
+ case UR_RESOLUTION: fputs("URR", File); break;
+ case GENERAL_FACTORING: fputs("Fac", File); break;
+ case SPLITTING: fputs("Spt", File); break;
+ case INPUT: fputs("Inp", File); break;
+ case REWRITING: fputs("Rew", File); break;
+ case CONTEXTUAL_REWRITING: fputs("CRw", File); break;
+ case CONDENSING: fputs("Con", File); break;
+ case ASSIGNMENT_EQUATION_DELETION: fputs("AED", File); break;
+ case OBVIOUS_REDUCTIONS: fputs("Obv", File); break;
+ case SORT_SIMPLIFICATION: fputs("SSi", File); break;
+ case MATCHING_REPLACEMENT_RESOLUTION: fputs("MRR", File); break;
+ case UNIT_CONFLICT: fputs("UnC", File); break;
+ case DEFAPPLICATION: fputs("Def", File); break;
+ case TERMINATOR: fputs("Ter", File); break;
+ case TEMPORARY: fputs("Temporary", File); break;
+ default:
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_FPrintOrigin: Clause has no origin.");
+ misc_FinishErrorReport();
+ }
+}
+
+
+void clause_PrintOrigin(CLAUSE Clause)
+/**************************************************************
+ INPUT: A Clause.
+ RETURNS: Nothing.
+ SUMMARY: Prints the clauses origin to stdout.
+***************************************************************/
+{
+ clause_FPrintOrigin(stdout, Clause);
+}
+
+
+void clause_PrintVerbose(CLAUSE Clause, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A Clause, a flag store and a precedence.
+ RETURNS: Nothing.
+ SUMMARY: Prints almost all the information kept in the
+ clause structure.
+***************************************************************/
+{
+ int c,a,s;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_PrintVerbose:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ c = clause_NumOfConsLits(Clause);
+ a = clause_NumOfAnteLits(Clause);
+ s = clause_NumOfSuccLits(Clause);
+
+ printf(" c = %d a = %d s = %d", c,a,s);
+ printf(" Weight : %d", clause_Weight(Clause));
+ printf(" Depth : %d", clause_Depth(Clause));
+ printf(" %s %s ",
+ (clause_GetFlag(Clause,WORKEDOFF) ? "WorkedOff" : "Usable"),
+ (clause_GetFlag(Clause,CLAUSESELECT) ? "Selected" : "NotSelected"));
+
+ clause_Print(Clause);
+}
+
+
+CLAUSE clause_GetNumberedCl(int number, LIST ClList)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ CAUTION:
+***************************************************************/
+{
+ while (!list_Empty(ClList) &&
+ clause_Number((CLAUSE)list_Car(ClList)) != number)
+ ClList = list_Cdr(ClList);
+
+ if (list_Empty(ClList))
+ return NULL;
+ else
+ return list_Car(ClList);
+}
+
+static __inline__ BOOL clause_NumberLower(CLAUSE A, CLAUSE B)
+{
+ return (BOOL) (clause_Number(A) < clause_Number(B));
+}
+
+LIST clause_NumberSort(LIST List)
+/**************************************************************
+ INPUT: A list of clauses.
+ RETURNS: The same list where the elements are sorted wrt their number.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ return list_Sort(List, (BOOL (*) (POINTER, POINTER)) clause_NumberLower);
+}
+
+
+LIST clause_NumberDelete(LIST List, int Number)
+/**************************************************************
+ INPUT: A list of clauses and an integer.
+ RETURNS: The same list where the clauses with <Number> are deleted.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ for (Scan1 = List; !list_Empty(Scan1); )
+ if (clause_Number(list_Car(Scan1))==Number) {
+
+ Scan2 = Scan1;
+ Scan1 = list_Cdr(Scan1);
+ List = list_PointerDeleteOneElement(List, list_Car(Scan2));
+ } else
+ Scan1 = list_Cdr(Scan1);
+
+ return List;
+}
+
+
+static NAT clause_NumberOfMaxLits(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: The number of maximal literals in a clause.
+***************************************************************/
+{
+ NAT Result,i,n;
+
+ Result = 0;
+ n = clause_Length(Clause);
+
+ for (i = clause_FirstAntecedentLitIndex(Clause); i < n; i++)
+ if (clause_LiteralIsMaximal(clause_GetLiteral(Clause,i)))
+ Result++;
+
+ return Result;
+}
+
+/* Unused ! */
+NAT clause_NumberOfMaxAntecedentLits(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: The number of maximal antecedent literals in a clause.
+***************************************************************/
+{
+ NAT Result,i,n;
+
+ Result = 0;
+ n = clause_LastAntecedentLitIndex(Clause);
+
+ for (i = clause_FirstAntecedentLitIndex(Clause); i <= n; i++)
+ if (clause_LiteralIsMaximal(clause_GetLiteral(Clause,i)))
+ Result++;
+
+ return Result;
+}
+
+
+void clause_SelectLiteral(CLAUSE Clause, FLAGSTORE Flags)
+/**************************************************************
+ INPUT: A clause and a flag store.
+ RETURNS: Nothing.
+ EFFECT: If the clause contains more than 2 maximal literals,
+ at least one antecedent literal, the literal with
+ the highest weight is selected.
+***************************************************************/
+{
+ if (clause_HasSolvedConstraint(Clause) &&
+ !clause_GetFlag(Clause,CLAUSESELECT) &&
+ clause_NumOfAnteLits(Clause) > 0 &&
+ (flag_GetFlagValue(Flags, flag_SELECT) == flag_SELECTALWAYS ||
+ (flag_GetFlagValue(Flags, flag_SELECT) == flag_SELECTIFSEVERALMAXIMAL &&
+ clause_NumberOfMaxLits(Clause) > 1))) {
+ NAT i,n;
+ LITERAL Lit;
+
+ n = clause_LastAntecedentLitIndex(Clause);
+ i = clause_FirstAntecedentLitIndex(Clause);
+ Lit = clause_GetLiteral(Clause,i);
+ i++;
+
+ for ( ; i <= n; i++)
+ if (clause_LiteralWeight(Lit)
+ < clause_LiteralWeight(clause_GetLiteral(Clause,i)))
+ Lit = clause_GetLiteral(Clause,i);
+
+ clause_LiteralSetFlag(Lit,LITSELECT);
+ clause_SetFlag(Clause,CLAUSESELECT);
+ }
+}
+
+
+void clause_SetSpecialFlags(CLAUSE Clause, BOOL SortDecreasing, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a flag indicating whether all equations are
+ sort decreasing, a flag store and a precedence.
+ RETURNS: void.
+ EFFECT: If the clause is a sort theory clause and its declaration
+ top symbol is a set declaration sort, i.e., it occurred in a
+ declaration right from the beginning, the paramodulation/superposition
+ steps into the clause are forbidden by setting the
+ NOPARAINTO clause flag
+***************************************************************/
+{
+ if (SortDecreasing &&
+ clause_IsSortTheoryClause(Clause, Flags, Precedence) &&
+ symbol_HasProperty(term_TopSymbol(clause_GetLiteralTerm(Clause,clause_FirstSuccedentLitIndex(Clause))),
+ DECLSORT))
+ clause_SetFlag(Clause,NOPARAINTO);
+}
+
+
+BOOL clause_ContainsPotPredDef(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence, NAT* Index, LIST* Pair)
+/**************************************************************
+ INPUT: A clause, a flag store, a precedence and a pointer to an index.
+ RETURNS: TRUE iff a succedent literal of the clause is a predicate
+ having only variables as arguments, the predicate occurs only
+ once in the clause and no other variables but the predicates'
+ occur.
+ In that case Index is set to the index of the predicate and
+ Pair contains two lists : the literals for which positive
+ occurrences must be found and a list of literals for which negative
+ occurrences must be found for a complete definition.
+***************************************************************/
+{
+ NAT i;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_ContainsPotPredDef:");
+ misc_ErrorReport("\n Illegal input. Input not a clause.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /* Iterate over all succedent literals */
+ for (i=clause_FirstSuccedentLitIndex(Clause); i < clause_Length(Clause); i++) {
+ LITERAL lit;
+ TERM atom;
+ LIST pair;
+
+ lit = clause_GetLiteral(Clause, i);
+ atom = clause_LiteralSignedAtom(lit);
+ if (symbol_IsPredicate(term_TopSymbol(atom))) {
+ LIST l;
+ BOOL ok;
+ ok = TRUE;
+ pair = list_PairCreate(list_Nil(), list_Nil());
+
+ /* Make sure all arguments of predicate are variables */
+ for (l=term_ArgumentList(atom); !list_Empty(l); l=list_Cdr(l)) {
+ if (!term_IsStandardVariable((TERM) list_Car(l))) {
+ ok = FALSE;
+ break;
+ }
+ }
+ if (ok) {
+ /* Make sure predicate occurs only once in clause */
+ NAT j, count;
+ count = 0;
+ for (j=0; (j < clause_Length(Clause)) && (count < 2); j++) {
+ TERM t;
+ t = clause_GetLiteralAtom(Clause, j);
+ if (symbol_Equal(term_TopSymbol(t), term_TopSymbol(atom)))
+ count++;
+ }
+ if (count > 1)
+ ok = FALSE;
+ }
+ if (ok) {
+ /* Build lists of positive and negative literals */
+ /* At the same time check if other variables than those among
+ the predicates arguments are found */
+ NAT j;
+ LIST predvars, vars;
+ predvars = fol_FreeVariables(atom);
+
+ /* Build list of literals for which positive occurrences are required */
+ for (j=0; (j < clause_FirstSuccedentLitIndex(Clause)) && ok; j++) {
+ list_Rplaca(pair, list_Cons(clause_GetLiteralAtom(Clause, j), list_PairFirst(pair)));
+ vars = fol_FreeVariables(clause_GetLiteralTerm(Clause, j));
+ for (l = vars; !list_Empty(l); l = list_Cdr(l)) {
+ if (!term_ListContainsTerm(predvars, list_Car(l))) {
+ ok = FALSE;
+ break;
+ }
+ }
+ list_Delete(vars);
+ }
+
+ /* Build list of literals for which negative occurrences are required */
+ for (j = clause_FirstSuccedentLitIndex(Clause);
+ (j < clause_Length(Clause)) && ok; j++) {
+ if (j != i) {
+ list_Rplacd(pair, list_Cons(clause_GetLiteralAtom(Clause, j), list_PairSecond(pair)));
+ vars = fol_FreeVariables(clause_GetLiteralAtom(Clause, j));
+ for (l=vars; !list_Empty(l); l=list_Cdr(l)) {
+ if (!term_ListContainsTerm(predvars, list_Car(l))) {
+ ok = FALSE;
+ break;
+ }
+ }
+ list_Delete(vars);
+ }
+ }
+ list_Delete(predvars);
+ }
+
+ if (ok) {
+ *Index = i;
+ *Pair = pair;
+ return TRUE;
+ }
+ else {
+ list_Delete(list_PairFirst(pair));
+ list_Delete(list_PairSecond(pair));
+ list_PairFree(pair);
+ }
+ }
+ }
+ return FALSE;
+}
+
+BOOL clause_IsPartOfDefinition(CLAUSE Clause, TERM Predicate, int *Index,
+ LIST Pair)
+/**************************************************************
+ INPUT: A clause, a term, a pointer to an int and a pair of term lists.
+ RETURNS: TRUE iff the predicate occurs among the negative literals of
+ the clause and the other negative and positive literals are found
+ in the pairs' lists.
+ In that case they are removed from the lists.
+ Index is set to the index of the defined predicate in Clause.
+***************************************************************/
+{
+ NAT predindex, i;
+ BOOL ok;
+
+ ok = TRUE;
+
+ /* Check whether Predicate is among antecedent or constraint literals */
+ for (predindex=clause_FirstLitIndex();
+ predindex < clause_FirstSuccedentLitIndex(Clause);
+ predindex++)
+ if (term_Equal(Predicate, clause_GetLiteralAtom(Clause, predindex)))
+ break;
+ if (predindex == clause_FirstSuccedentLitIndex(Clause))
+ return FALSE;
+ *Index = predindex;
+
+ /* Check if other negative literals are required for definition */
+ for (i=clause_FirstLitIndex();
+ (i < clause_FirstSuccedentLitIndex(Clause)) && ok; i++) {
+ if (i != predindex)
+ if (!term_ListContainsTerm((LIST) list_PairSecond(Pair),
+ clause_GetLiteralAtom(Clause, i)))
+ ok = FALSE;
+ }
+
+ /* Check if positive literals are required for definition */
+ for (i=clause_FirstSuccedentLitIndex(Clause);
+ (i < clause_Length(Clause)) && ok; i++)
+ if (!term_ListContainsTerm((LIST) list_PairFirst(Pair),
+ clause_GetLiteralAtom(Clause, i)))
+ ok = FALSE;
+
+ if (!ok)
+ return FALSE;
+ else {
+ /* Complement for definition found, remove literals from pair lists */
+ for (i=0; i < clause_FirstSuccedentLitIndex(Clause); i++)
+ if (i != predindex)
+ list_Rplacd(Pair,
+ list_DeleteElement((LIST) list_PairSecond(Pair),
+ clause_GetLiteralAtom(Clause, i),
+ (BOOL (*)(POINTER, POINTER)) term_Equal));
+ for (i=clause_FirstSuccedentLitIndex(Clause); i < clause_Length(Clause); i++)
+ list_Rplaca(Pair,
+ list_DeleteElement((LIST) list_PairFirst(Pair),
+ clause_GetLiteralAtom(Clause, i),
+ (BOOL (*)(POINTER, POINTER)) term_Equal));
+ return TRUE;
+ }
+}
+
+void clause_FPrintRule(FILE* File, CLAUSE Clause)
+/**************************************************************
+ INPUT: A file and a clause.
+ RETURNS: Nothing.
+ SUMMARY: Prints any term of the clause to file in rule format.
+ CAUTION: Uses the term_Output functions.
+***************************************************************/
+{
+ int i,n;
+ TERM Literal;
+ LIST scan,antecedent,succedent,constraints;
+
+ n = clause_Length(Clause);
+
+ constraints = list_Nil();
+ antecedent = list_Nil();
+ succedent = list_Nil();
+
+ for (i = 0; i < n; i++) {
+ Literal = clause_GetLiteralTerm(Clause,i);
+ if (symbol_Equal(term_TopSymbol(Literal),fol_Not())) {
+ if (symbol_Arity(term_TopSymbol(fol_Atom(Literal))) == 1 &&
+ symbol_IsVariable(term_TopSymbol(term_FirstArgument(fol_Atom(Literal)))))
+ constraints = list_Cons(Literal,constraints);
+ else
+ antecedent = list_Cons(Literal,antecedent);
+ }
+ else
+ succedent = list_Cons(Literal,succedent);
+ }
+
+ for (scan = constraints; !list_Empty(scan); scan = list_Cdr(scan)) {
+ term_FPrint(File, fol_Atom(list_Car(scan)));
+ putc(' ', File);
+ }
+ fputs("||", File);
+ for (scan = antecedent; !list_Empty(scan); scan = list_Cdr(scan)) {
+ putc(' ', File);
+ term_FPrint(File,fol_Atom(list_Car(scan)));
+ if (list_Empty(list_Cdr(scan)))
+ putc(' ', File);
+ }
+ fputs("->", File);
+ for (scan = succedent; !list_Empty(scan); scan = list_Cdr(scan)) {
+ putc(' ', File);
+ term_FPrint(File,list_Car(scan));
+ }
+ fputs(".\n", File);
+
+ list_Delete(antecedent);
+ list_Delete(succedent);
+ list_Delete(constraints);
+}
+
+
+void clause_FPrintOtter(FILE* File, CLAUSE clause)
+/**************************************************************
+ INPUT: A file and a clause.
+ RETURNS: Nothing.
+ SUMMARY: Prints any clause to File.
+ CAUTION: Uses the other clause_Output functions.
+***************************************************************/
+{
+ int n,j;
+ LITERAL Lit;
+ TERM Atom;
+
+ n = clause_Length(clause);
+
+ if (n == 0)
+ fputs(" $F ", File);
+ else {
+ for (j = 0; j < n; j++) {
+ Lit = clause_GetLiteral(clause,j);
+ Atom = clause_LiteralAtom(Lit);
+ if (clause_LiteralIsNegative(Lit))
+ putc('-', File);
+ if (fol_IsEquality(Atom)) {
+ if (clause_LiteralIsNegative(Lit))
+ putc('(', File);
+ term_FPrintOtterPrefix(File,term_FirstArgument(Atom));
+ fputs(" = ", File);
+ term_FPrintOtterPrefix(File,term_SecondArgument(Atom));
+ if (clause_LiteralIsNegative(Lit))
+ putc(')', File);
+ }
+ else
+ term_FPrintOtterPrefix(File,Atom);
+ if (j <= (n-2))
+ fputs(" | ", File);
+ }
+ }
+
+ fputs(".\n", File);
+}
+
+
+void clause_FPrintCnfDFG(FILE* File, BOOL OnlyProductive, LIST Axioms,
+ LIST Conjectures, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A file, a list of axiom clauses and a list of conjecture clauses.
+ A flag indicating whether only potentially productive clauses should
+ be printed.
+ A flag store.
+ A precedence.
+ RETURNS: Nothing.
+ SUMMARY: Prints a the respective clause lists to <File> dependent
+ on <OnlyProductive>.
+***************************************************************/
+{
+ LIST scan;
+ CLAUSE Clause;
+
+ if (Axioms) {
+ fputs("list_of_clauses(axioms, cnf).\n", File);
+ for (scan=Axioms;!list_Empty(scan);scan=list_Cdr(scan)) {
+ Clause = (CLAUSE)list_Car(scan);
+ if (!OnlyProductive ||
+ (clause_HasSolvedConstraint(Clause) &&
+ !clause_HasSelectedLiteral(Clause, Flags, Precedence)))
+ clause_FPrintDFG(File,Clause,FALSE);
+ }
+ fputs("end_of_list.\n\n", File);
+ }
+
+ if (Conjectures) {
+ fputs("list_of_clauses(conjectures, cnf).\n", File);
+ for (scan=Conjectures;!list_Empty(scan);scan=list_Cdr(scan)) {
+ Clause = (CLAUSE)list_Car(scan);
+ if (!OnlyProductive ||
+ (clause_HasSolvedConstraint(Clause) &&
+ !clause_HasSelectedLiteral(Clause, Flags, Precedence)))
+ clause_FPrintDFG(File,Clause,FALSE);
+ }
+ fputs("end_of_list.\n\n", File);
+ }
+}
+
+
+static void clause_FPrintDescription(FILE* File, const char* Name,
+ const char* Author, const char* Status,
+ const char* Description)
+{
+ fputs("list_of_descriptions.\n", File);
+ fprintf(File, "name(%s).\n", Name);
+ fprintf(File, "author(%s).\n", Author);
+ fprintf(File, "status(%s).\n", Status);
+ fprintf(File, "description(%s).\n", Description);
+ fputs("end_of_list.\n", File);
+}
+
+void clause_FPrintCnfDFGProblem(FILE* File, const char* Name,
+ const char* Author, const char* Status,
+ const char* Description, LIST Clauses)
+/**************************************************************
+ INPUT: A file, the problems name, author, status and description
+ to be included in the description block given as strings
+ and a list of clauses.
+ RETURNS: Nothing.
+ SUMMARY: Prints a complete DFG problem clause file to <File>.
+***************************************************************/
+{
+ LIST Scan;
+
+ fputs("begin_problem(Unknown).\n\n", File);
+ clause_FPrintDescription(File, Name, Author, Status, Description);
+ putc('\n', File);
+ fputs("list_of_symbols.\n", File);
+ fol_FPrintDFGSignature(File);
+ fputs("end_of_list.\n\n", File);
+ fputs("list_of_clauses(axioms, cnf).\n", File);
+
+ for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (!clause_GetFlag(list_Car(Scan),CONCLAUSE))
+ clause_FPrintDFG(File,list_Car(Scan),FALSE);
+
+ fputs("end_of_list.\n\n", File);
+ fputs("list_of_clauses(conjectures, cnf).\n", File);
+
+ for (Scan=Clauses; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (clause_GetFlag(list_Car(Scan),CONCLAUSE))
+ clause_FPrintDFG(File,list_Car(Scan),FALSE);
+
+ fputs("end_of_list.\n\n", File);
+ fputs("\nend_problem.\n\n", File);
+}
+
+
+void clause_FPrintCnfFormulasDFGProblem(FILE* File, BOOL OnlyProductive,
+ const char* Name, const char* Author,
+ const char* Status,
+ const char* Description, LIST Axioms,
+ LIST Conjectures, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A file, a list of axiom clauses and a list of conjecture clauses.
+ A flag indicating whether only potentially productive clauses should
+ be printed.
+ A bunch of strings that are printed to the description.
+ A flag store.
+ A precedence.
+ RETURNS: Nothing.
+ SUMMARY: Prints the respective clause lists as a complete DFG formulae output
+ to <File>.
+***************************************************************/
+{
+ LIST scan;
+ CLAUSE Clause;
+
+ fputs("begin_problem(Unknown).\n\n", File);
+ clause_FPrintDescription(File, Name, Author, Status, Description);
+ fputs("\nlist_of_symbols.\n", File);
+ fol_FPrintDFGSignature(File);
+ fputs("end_of_list.\n\n", File);
+
+ if (Axioms) {
+ fputs("list_of_formulae(axioms).\n", File);
+ for (scan=Axioms; !list_Empty(scan); scan=list_Cdr(scan)) {
+ Clause = (CLAUSE)list_Car(scan);
+ if (!OnlyProductive ||
+ (clause_HasSolvedConstraint(Clause) &&
+ !clause_HasSelectedLiteral(Clause, Flags, Precedence)))
+ clause_FPrintFormulaDFG(File,Clause,FALSE);
+ }
+ fputs("end_of_list.\n\n", File);
+ }
+
+ if (Conjectures) {
+ fputs("list_of_formulae(conjectures).\n", File);
+ for (scan=Conjectures; !list_Empty(scan); scan=list_Cdr(scan)) {
+ Clause = (CLAUSE)list_Car(scan);
+ if (!OnlyProductive ||
+ (clause_HasSolvedConstraint(Clause) &&
+ !clause_HasSelectedLiteral(Clause, Flags, Precedence)))
+ clause_FPrintFormulaDFG(File,Clause,FALSE);
+ }
+ fputs("end_of_list.\n\n", File);
+ }
+
+ fputs("list_of_settings(SPASS).\n{*\n", File);
+ fol_FPrintPrecedence(File, Precedence);
+ fputs("\n*}\nend_of_list.\n\nend_problem.\n\n", File);
+}
+
+void clause_FPrintCnfOtter(FILE* File, LIST Clauses, FLAGSTORE Flags)
+/**************************************************************
+ INPUT: A file, a list of clauses and a flag store.
+ RETURNS: Nothing.
+ SUMMARY: Prints the clauses to <File> in a format readable by Otter.
+***************************************************************/
+{
+ LIST scan;
+ int i;
+ BOOL Equality;
+ CLAUSE Clause;
+
+ Equality = FALSE;
+
+ for (scan=Clauses;!list_Empty(scan) && !Equality; scan=list_Cdr(scan)) {
+ Clause = (CLAUSE)list_Car(scan);
+ for (i=clause_FirstAntecedentLitIndex(Clause);i<clause_Length(Clause);i++)
+ if (fol_IsEquality(clause_GetLiteralAtom(Clause,i))) {
+ Equality = TRUE;
+ i = clause_Length(Clause);
+ }
+ }
+
+ fol_FPrintOtterOptions(File, Equality,
+ flag_GetFlagValue(Flags, flag_TDFG2OTTEROPTIONS));
+
+ if (Clauses) {
+ fputs("list(usable).\n", File);
+ if (Equality)
+ fputs("x=x.\n", File);
+ for (scan=Clauses;!list_Empty(scan);scan=list_Cdr(scan))
+ clause_FPrintOtter(File,list_Car(scan));
+ fputs("end_of_list.\n\n", File);
+ }
+}
+
+
+void clause_FPrintCnfDFGDerivables(FILE* File, LIST Clauses, BOOL Type)
+/**************************************************************
+ INPUT: A file, a list of clauses and a bool flag Type.
+ RETURNS: Nothing.
+ SUMMARY: If <Type> is true then all axiom clauses in <Clauses> are
+ written to <File>. Otherwise all conjecture clauses in
+ <Clauses> are written to <File>.
+***************************************************************/
+{
+ CLAUSE Clause;
+
+ while (Clauses) {
+ Clause = (CLAUSE)list_Car(Clauses);
+ if ((Type && !clause_GetFlag(Clause,CONCLAUSE)) ||
+ (!Type && clause_GetFlag(Clause,CONCLAUSE)))
+ clause_FPrintDFG(File,Clause,FALSE);
+ Clauses = list_Cdr(Clauses);
+ }
+}
+
+
+void clause_FPrintDFGStep(FILE* File, CLAUSE Clause, BOOL Justif)
+/**************************************************************
+ INPUT: A file, a clause and a boolean value.
+ RETURNS: Nothing.
+ SUMMARY: Prints any clause together with a label (the clause number)
+ to File. If <Justif> is TRUE also the labels of the parent
+ clauses are printed.
+ CAUTION: Uses the other clause_Output functions.
+***************************************************************/
+{
+ int n,j;
+ LITERAL Lit;
+ TERM Atom;
+ LIST Variables,Iter;
+
+ n = clause_Length(Clause);
+
+ fputs(" step(", File);
+ fprintf(File, "%d,", clause_Number(Clause));
+
+ Variables = list_Nil();
+
+ for (j = 0; j < n; j++)
+ Variables =
+ list_NPointerUnion(Variables,
+ term_VariableSymbols(clause_GetLiteralAtom(Clause,j)));
+
+ if (!list_Empty(Variables)) {
+ symbol_FPrint(File, fol_All());
+ fputs("([", File);
+ for (Iter = Variables; !list_Empty(Iter); Iter = list_Cdr(Iter)) {
+ symbol_FPrint(File, (SYMBOL) list_Car(Iter));
+ if (!list_Empty(list_Cdr(Iter)))
+ putc(',', File);
+ }
+ fputs("],", File);
+ }
+
+ symbol_FPrint(File, fol_Or());
+ putc('(', File);
+
+ for (j = 0; j < n; j++) {
+ Lit = clause_GetLiteral(Clause,j);
+ Atom = clause_LiteralSignedAtom(Lit);
+ term_FPrintPrefix(File,Atom);
+ if (j+1 < n)
+ putc(',', File);
+ }
+ if (n==0)
+ symbol_FPrint(File,fol_False());
+
+ if (!list_Empty(Variables)) {
+ list_Delete(Variables);
+ putc(')', File);
+ }
+ fputs("),", File);
+ clause_FPrintOrigin(File, Clause);
+
+ fputs(",[", File);
+ for (Iter = clause_ParentClauses(Clause);
+ !list_Empty(Iter);
+ Iter = list_Cdr(Iter)) {
+ fprintf(File, "%d", (int)list_Car(Iter));
+ if (!list_Empty(list_Cdr(Iter)))
+ putc(',', File);
+ }
+ putc(']', File);
+ fprintf(File, ",[splitlevel:%d]", clause_SplitLevel(Clause));
+
+ fputs(").\n", File);
+}
+
+void clause_FPrintDFG(FILE* File, CLAUSE Clause, BOOL Justif)
+/**************************************************************
+ INPUT: A file, a clause and a boolean value.
+ RETURNS: Nothing.
+ SUMMARY: Prints any clause together with a label (the clause number)
+ to File. If Justif is TRUE also the labels of the parent
+ clauses are printed.
+ CAUTION: Uses the other clause_Output functions.
+***************************************************************/
+{
+ int n,j;
+ LITERAL Lit;
+ TERM Atom;
+ LIST Variables,Iter;
+
+ n = clause_Length(Clause);
+
+ fputs(" clause(", File);
+ Variables = list_Nil();
+
+ for (j = 0; j < n; j++)
+ Variables =
+ list_NPointerUnion(Variables,
+ term_VariableSymbols(clause_GetLiteralAtom(Clause,j)));
+
+ if (!list_Empty(Variables)) {
+ symbol_FPrint(File, fol_All());
+ fputs("([", File);
+ for (Iter = Variables; !list_Empty(Iter); Iter = list_Cdr(Iter)) {
+ symbol_FPrint(File, (SYMBOL) list_Car(Iter));
+ if (!list_Empty(list_Cdr(Iter)))
+ putc(',', File);
+ }
+ fputs("],", File);
+ }
+
+ symbol_FPrint(File, fol_Or());
+ putc('(', File);
+
+ for (j = 0; j < n; j++) {
+ Lit = clause_GetLiteral(Clause,j);
+ Atom = clause_LiteralSignedAtom(Lit);
+ term_FPrintPrefix(File,Atom);
+ if (j+1 < n)
+ putc(',', File);
+ }
+ if (n==0)
+ symbol_FPrint(File,fol_False());
+
+ if (!list_Empty(Variables)) {
+ list_Delete(Variables);
+ putc(')', File);
+ }
+ fprintf(File, "),%d", clause_Number(Clause));
+
+ if (Justif) {
+ putc(',', File);
+ clause_FPrintOrigin(File, Clause);
+ fputs(",[", File);
+ for (Iter = clause_ParentClauses(Clause);
+ !list_Empty(Iter);
+ Iter = list_Cdr(Iter)) {
+ fprintf(File, "%d", (int)list_Car(Iter));
+ if (!list_Empty(list_Cdr(Iter)))
+ putc(',', File);
+ }
+ putc(']', File);
+ fprintf(File, ",%d", clause_SplitLevel(Clause));
+ }
+
+ fputs(").\n", File);
+}
+
+void clause_FPrintFormulaDFG(FILE* File, CLAUSE Clause, BOOL Justif)
+/**************************************************************
+ INPUT: A file, a clause and a boolean value.
+ RETURNS: Nothing.
+ SUMMARY: Prints any clause together with a label (the clause number)
+ as DFG Formula to File. If Justif is TRUE also the labels of the
+ parent clauses are printed.
+ CAUTION: Uses the other clause_Output functions.
+***************************************************************/
+{
+ int n,j;
+ LITERAL Lit;
+ TERM Atom;
+ LIST Variables,Iter;
+
+ n = clause_Length(Clause);
+
+ fputs(" formula(", File);
+ Variables = list_Nil();
+
+ for (j = 0; j < n; j++)
+ Variables =
+ list_NPointerUnion(Variables,
+ term_VariableSymbols(clause_GetLiteralAtom(Clause,j)));
+
+ if (!list_Empty(Variables)) {
+ symbol_FPrint(File, fol_All());
+ fputs("([", File);
+ for (Iter = Variables; !list_Empty(Iter); Iter = list_Cdr(Iter)) {
+ symbol_FPrint(File, (SYMBOL) list_Car(Iter));
+ if (!list_Empty(list_Cdr(Iter)))
+ putc(',', File);
+ }
+ fputs("],", File);
+ }
+
+ if (n>1) {
+ symbol_FPrint(File, fol_Or());
+ putc('(', File);
+ }
+
+ for (j = 0; j < n; j++) {
+ Lit = clause_GetLiteral(Clause,j);
+ Atom = clause_LiteralSignedAtom(Lit);
+ term_FPrintPrefix(File,Atom);
+ if (j+1 < n)
+ putc(',', File);
+ }
+ if (n==0)
+ symbol_FPrint(File,fol_False());
+
+ if (!list_Empty(Variables)) {
+ list_Delete(Variables);
+ putc(')', File);
+ }
+
+ if (n>1)
+ fprintf(File, "),%d", clause_Number(Clause));
+ else
+ fprintf(File, ",%d", clause_Number(Clause));
+
+ if (Justif) {
+ putc(',', File);
+ clause_FPrintOrigin(File, Clause);
+ fputs(",[", File);
+ for (Iter = clause_ParentClauses(Clause);
+ !list_Empty(Iter);
+ Iter = list_Cdr(Iter)) {
+ fprintf(File, "%d", (int)list_Car(Iter));
+ if (!list_Empty(list_Cdr(Iter)))
+ putc(',', File);
+ }
+ putc(']', File);
+ fprintf(File, ",%d", clause_SplitLevel(Clause));
+ }
+
+ fputs(").\n", File);
+}
+
+
+void clause_Check(CLAUSE Clause, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a flag store and a precedence.
+ RETURNS: Nothing.
+ EFFECT: Checks whether the clause is in a proper state. If
+ not, a core is dumped.
+***************************************************************/
+{
+ CLAUSE Copy;
+ if (!clause_Exists(Clause))
+ return;
+
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_Check: Clause not consistent !\n");
+ misc_FinishErrorReport();
+ }
+
+ Copy = clause_Copy(Clause);
+ clause_OrientAndReInit(Copy, Flags, Precedence);
+ if ((clause_Weight(Clause) != clause_Weight(Copy)) ||
+ (clause_MaxVar(Clause) != clause_MaxVar(Copy))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_Check: Weight or maximal variable not properly set.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Delete(Copy);
+}
+
+/* The following are output procedures for clauses with parent pointers */
+
+
+void clause_PParentsFPrintParentClauses(FILE* File, CLAUSE Clause, BOOL ParentPts)
+/**************************************************************
+ INPUT: A file, a clause and a boolean flag indicating whether
+ the clause's parents are given by numbers or pointers.
+ RETURNS: Nothing.
+ SUMMARY: Prints the clauses parent clauses and -literals to the file.
+ If <ParentPts> is TRUE the parent clauses are defined
+ by pointers, else by numbers.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+ int length;
+ int ParentNum;
+
+ if (!list_Empty(clause_ParentClauses(Clause))) {
+
+ Scan1 = clause_ParentClauses(Clause);
+ Scan2 = clause_ParentLiterals(Clause);
+
+ if (ParentPts)
+ ParentNum = clause_Number(list_Car(Scan1));
+ else
+ ParentNum = (int)list_Car(Scan1);
+
+ fprintf(File, "%d.%d", ParentNum, (int)list_Car(Scan2));
+
+ if (!list_Empty(list_Cdr(Scan1))) {
+
+ length = list_Length(Scan1) - 2;
+ putc(',', File);
+ Scan1 = list_Cdr(Scan1);
+ Scan2 = list_Cdr(Scan2);
+
+ if (ParentPts)
+ ParentNum = clause_Number(list_Car(Scan1));
+ else
+ ParentNum = (int)list_Car(Scan1);
+
+ fprintf(File, "%d.%d", ParentNum, (int)list_Car(Scan2));
+
+ for (Scan1 = list_Cdr(Scan1), Scan2 = list_Cdr(Scan2);
+ !list_Empty(Scan1);
+ Scan1 = list_Cdr(Scan1), Scan2 = list_Cdr(Scan2)) {
+
+ length -= 2;
+
+ if (ParentPts)
+ ParentNum = clause_Number(list_Car(Scan1));
+ else
+ ParentNum = (int)list_Car(Scan1);
+
+ fprintf(File, ",%d.%d", ParentNum, (int)list_Car(Scan2));
+ }
+ }
+ }
+}
+
+void clause_PParentsLiteralFPrintUnsigned(FILE* File, LITERAL Literal)
+/**************************************************************
+ INPUT: A Literal.
+ RETURNS: Nothing.
+ SUMMARY:
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Literal)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_PParentsLiteralFPrintUnsigned:");
+ misc_ErrorReport("\n Illegal input. Input not a literal.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_FPrintPrefix(File, clause_LiteralAtom(Literal));
+ fflush(stdout);
+}
+
+void clause_PParentsFPrintGen(FILE* File, CLAUSE Clause, BOOL ParentPts)
+/**************************************************************
+ INPUT: A file, a clause, a boolean flag.
+ RETURNS: Nothing.
+ EFFECTS: Prints the clause to file in SPASS format. If <ParentPts>
+ is TRUE, the parents of <Clause> are interpreted as pointers.
+***************************************************************/
+{
+ LITERAL Lit;
+ int i,c,a,s;
+
+ if (!clause_Exists(Clause))
+ fputs("(CLAUSE)NULL", File);
+ else {
+ fprintf(File, "%d",clause_Number(Clause));
+
+ fprintf(File, "[%d:", clause_SplitLevel(Clause));
+
+#ifdef CHECK
+ if (Clause->splitfield_length <= 1)
+ fputs("0.", File);
+ else
+ for (i=Clause->splitfield_length-1; i > 0; i--)
+ fprintf(File, "%lu.", Clause->splitfield[i]);
+ if (Clause->splitfield_length == 0)
+ putc('1', File);
+ else
+ fprintf(File, "%lu", (Clause->splitfield[0] | 1));
+ fprintf(File,":%c%c:%c:%d:%d:", clause_GetFlag(Clause, CONCLAUSE) ? 'C' : 'A',
+ clause_GetFlag(Clause, WORKEDOFF) ? 'W' : 'U',
+ clause_GetFlag(Clause, NOPARAINTO) ? 'N' : 'P',
+ clause_Weight(Clause), clause_Depth(Clause));
+#endif
+
+ clause_FPrintOrigin(File, Clause);
+
+ if (!list_Empty(clause_ParentClauses(Clause))) {
+ putc(':', File);
+ clause_PParentsFPrintParentClauses(File, Clause, ParentPts);
+ }
+ putc(']', File);
+
+ c = clause_NumOfConsLits(Clause);
+ a = clause_NumOfAnteLits(Clause);
+ s = clause_NumOfSuccLits(Clause);
+
+ for (i = 0; i < c; i++) {
+ Lit = clause_GetLiteral(Clause, i);
+ clause_PParentsLiteralFPrintUnsigned(File, Lit);
+ if (i+1 < c)
+ putc(' ', File);
+ }
+ fputs(" || ", File);
+
+ a += c;
+ for ( ; i < a; i++) {
+
+ Lit = clause_GetLiteral(Clause, i);
+ clause_PParentsLiteralFPrintUnsigned(File, Lit);
+ if (clause_LiteralIsMaximal(Lit)) {
+ putc('*', File);
+ if (clause_LiteralIsOrientedEquality(Lit))
+ putc('*', File);
+ }
+ if (clause_LiteralGetFlag(Lit,LITSELECT))
+ putc('+', File);
+ if (i+1 < a)
+ putc(' ', File);
+ }
+ fputs(" -> ",File);
+
+ s += a;
+ for ( ; i < s; i++) {
+
+ Lit = clause_GetLiteral(Clause, i);
+ clause_PParentsLiteralFPrintUnsigned(File, Lit);
+ if (clause_LiteralIsMaximal(Lit)) {
+ putc('*', File);
+ if (clause_LiteralIsOrientedEquality(Lit))
+ putc('*', File);
+ }
+#ifdef CHECK
+ if (clause_LiteralGetFlag(Lit, LITSELECT)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_PParentsFPrintGen: Clause has selected positive literal.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+ if (i+1 < s)
+ putc(' ', File);
+ }
+ putc('.', File);
+ }
+}
+
+void clause_PParentsFPrint(FILE* File, CLAUSE Clause)
+/**************************************************************
+ INPUT: A file handle and a clause.
+ RETURNS: Nothing.
+ EFFECTS: Prints out the clause to file in SPASS output format
+***************************************************************/
+{
+ clause_PParentsFPrintGen(File, Clause, TRUE);
+}
+
+void clause_PParentsListFPrint(FILE* File, LIST L)
+/**************************************************************
+ INPUT: A file handle, a list of clauses with parent pointers
+ RETURNS: Nothing.
+ EFFECTS: Print the list to <file>.
+***************************************************************/
+{
+ while (!list_Empty(L)) {
+ clause_PParentsFPrint(File, list_Car(L));
+ putc('\n', File);
+ L = list_Cdr(L);
+ }
+}
+
+
+void clause_PParentsPrint(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause with parent pointers
+ RETURNS: Nothing.
+ EFFECTS: The clause is printed to stdout.
+***************************************************************/
+{
+ clause_PParentsFPrint(stdout, Clause);
+}
+
+void clause_PParentsListPrint(LIST L)
+/**************************************************************
+ INPUT: A file handle, a list of clauses with parent pointers
+ RETURNS: Nothing.
+ EFFECTS: Print the clause list to stdout.
+***************************************************************/
+{
+ clause_PParentsListFPrint(stdout, L);
+}
diff --git a/test/spass/clause.h b/test/spass/clause.h
new file mode 100644
index 0000000..d163d35
--- /dev/null
+++ b/test/spass/clause.h
@@ -0,0 +1,1589 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CLAUSES * */
+/* * * */
+/* * $Module: CLAUSE * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _CLAUSE_
+#define _CLAUSE_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "sharing.h"
+#include "foldfg.h"
+#include "order.h"
+#include "subst.h"
+#include "flags.h"
+#include "symbol.h"
+
+/**************************************************************/
+/* Data Structures and Constants */
+/**************************************************************/
+
+/* Means weight of literal or clause is undefined */
+extern const NAT clause_WEIGHTUNDEFINED;
+
+extern int clause_CLAUSECOUNTER;
+
+typedef enum {MAXIMAL=1, STRICTMAXIMAL=2, LITSELECT=4} MAXFLAG;
+
+typedef enum {CLAUSE_DELETION, EMPTY_SORT, SORT_RESOLUTION,
+ EQUALITY_RESOLUTION, EQUALITY_FACTORING, MERGING_PARAMODULATION,
+ PARAMODULATION, ORDERED_PARAMODULATION,
+ SUPERPOSITION_RIGHT, SUPERPOSITION_LEFT,
+ SIMPLE_HYPER, ORDERED_HYPER, UR_RESOLUTION,
+ GENERAL_RESOLUTION, GENERAL_FACTORING, SPLITTING, INPUT,
+ CONDENSING, ASSIGNMENT_EQUATION_DELETION, OBVIOUS_REDUCTIONS,
+ SORT_SIMPLIFICATION, REWRITING, CONTEXTUAL_REWRITING,
+ MATCHING_REPLACEMENT_RESOLUTION, UNIT_CONFLICT, DEFAPPLICATION,
+ TERMINATOR, TEMPORARY
+} RULE;
+
+typedef unsigned long SPLITFIELDENTRY;
+typedef SPLITFIELDENTRY* SPLITFIELD;
+
+typedef enum {WORKEDOFF=1,CLAUSESELECT=2,DOCCLAUSE=4,CONCLAUSE=8,BLOCKED=16,
+ NOPARAINTO=32, MARKED=64, HIDDEN=128} CLAUSE_FLAGS;
+
+
+/* As there are a lot of implications a clauses properties may have */
+/* for the prover, this information should be kept with the clause. */
+/* That for a flagfield is foreseen, most likely an integer used */
+/* like the sort-Bitfield existing for term, now used for varoccs. */
+
+typedef struct CLAUSE_HELP{
+ int clausenumber;
+ NAT weight; /* The sum of the weight of all literals */
+ NAT depth; /* The depth of the clause in the derivation */
+ NAT validlevel; /* Level of splitting where clause is valid. */
+ SPLITFIELD splitfield;
+ unsigned splitfield_length;
+
+ LIST parentCls, parentLits; /* Parents clauses' clause and lit numbers.*/
+ NAT flags;
+ SYMBOL maxVar; /* The maximal variable symbol in the clause */
+ struct LITERAL_HELP{
+ NAT maxLit; /* for clause intern literal ordering */
+ NAT weight; /* weight of the <atomWithSign> below */
+ BOOL oriented; /* Flag, TRUE if clause is oriented, i.e. equalities
+ with bigger first arg and all other predicates */
+ struct CLAUSE_HELP *owningClause;
+ TERM atomWithSign; /* Pointer to the term, where an unshared
+ Term for the sign of negative literals
+ is supplied additionally. */
+ } **literals; /* An Array of (c+a+s) literalpointers in this order. */
+ int c; /* number of constraint literals */
+ int a; /* number of antecedent literals */
+ int s; /* number of succedent literals */
+ RULE origin;
+} *CLAUSE, CLAUSE_NODE;
+
+typedef struct LITERAL_HELP *LITERAL, LITERAL_NODE;
+
+
+/**************************************************************/
+/* Functions Prototypes */
+/**************************************************************/
+
+/**************************************************************/
+/* Functions on clauses and literals creation and deletion. */
+/**************************************************************/
+
+void clause_Init(void);
+
+CLAUSE clause_CreateBody(int);
+CLAUSE clause_Create(LIST, LIST, LIST, FLAGSTORE, PRECEDENCE);
+CLAUSE clause_CreateCrude(LIST, LIST, LIST, BOOL);
+CLAUSE clause_CreateUnnormalized(LIST, LIST, LIST);
+CLAUSE clause_CreateFromLiterals(LIST, BOOL, BOOL, BOOL, FLAGSTORE, PRECEDENCE);
+void clause_Delete(CLAUSE);
+
+LITERAL clause_LiteralCreate(TERM, CLAUSE);
+LITERAL clause_LiteralCreateNegative(TERM, CLAUSE); /* Unused */
+void clause_LiteralDelete(LITERAL);
+
+LIST clause_CopyConstraint(CLAUSE);
+LIST clause_CopyAntecedentExcept(CLAUSE, int);
+LIST clause_CopySuccedent(CLAUSE);
+LIST clause_CopySuccedentExcept(CLAUSE, int);
+
+
+/**************************************************************/
+/* Functions to use the sharing for clauses and literals. */
+/**************************************************************/
+
+void clause_InsertIntoSharing(CLAUSE, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+void clause_DeleteFromSharing(CLAUSE, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+
+void clause_MakeUnshared(CLAUSE, SHARED_INDEX);
+void clause_MoveSharedClause(CLAUSE, SHARED_INDEX, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+void clause_DeleteSharedLiteral(CLAUSE, int, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+
+void clause_LiteralInsertIntoSharing(LITERAL, SHARED_INDEX);
+void clause_LiteralDeleteFromSharing(LITERAL, SHARED_INDEX); /* Used only in clause.c */
+
+void clause_DeleteClauseList(LIST);
+void clause_DeleteSharedClauseList(LIST, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+void clause_DeleteAllIndexedClauses(SHARED_INDEX, FLAGSTORE, PRECEDENCE); /* Necessary? */
+void clause_PrintAllIndexedClauses(SHARED_INDEX); /* For Debugging */
+LIST clause_AllIndexedClauses(SHARED_INDEX);
+
+/**************************************************************/
+/* Clause Comparisons */
+/**************************************************************/
+
+BOOL clause_IsHornClause(CLAUSE);
+int clause_CompareAbstract(CLAUSE, CLAUSE);
+
+/**************************************************************/
+/* Clause and literal Input and Output Functions */
+/**************************************************************/
+
+void clause_Print(CLAUSE);
+void clause_PrintVerbose(CLAUSE, FLAGSTORE, PRECEDENCE);
+void clause_PrintMaxLitsOnly(CLAUSE, FLAGSTORE, PRECEDENCE); /* For Debugging */
+void clause_FPrint(FILE*, CLAUSE); /* For Debugging */
+void clause_FPrintRule(FILE*, CLAUSE);
+void clause_FPrintOtter(FILE*, CLAUSE); /* Unused */
+void clause_FPrintCnfDFG(FILE* , BOOL, LIST, LIST, FLAGSTORE, PRECEDENCE);
+void clause_FPrintCnfDFGProblem(FILE* , const char*, const char*, const char*, const char*, LIST);
+void clause_FPrintCnfFormulasDFGProblem(FILE* , BOOL, const char*, const char*, const char*, const char*, LIST, LIST, FLAGSTORE, PRECEDENCE);
+void clause_FPrintCnfDFGDerivables(FILE*, LIST, BOOL);
+void clause_FPrintDFG(FILE*, CLAUSE, BOOL);
+void clause_FPrintDFGStep(FILE*, CLAUSE, BOOL);
+void clause_FPrintFormulaDFG(FILE*, CLAUSE, BOOL);
+void clause_FPrintCnfOtter(FILE*, LIST, FLAGSTORE);
+
+void clause_LiteralPrint(LITERAL); /* For Debugging */
+void clause_LiteralListPrint(LIST); /* For Debugging */
+void clause_LiteralPrintUnsigned(LITERAL); /* For Debugging */
+void clause_LiteralPrintSigned(LITERAL); /* For Debugging */
+void clause_LiteralFPrint(FILE*, LITERAL); /* For Debugging */
+
+void clause_ListPrint(LIST);
+
+void clause_PrintParentClauses(CLAUSE); /* For Debugging */
+void clause_PrintOrigin(CLAUSE); /* For Debugging */
+void clause_FPrintOrigin(FILE*, CLAUSE);
+
+/**************************************************************/
+/* Specials */
+/**************************************************************/
+
+CLAUSE clause_Copy(CLAUSE);
+LITERAL clause_LiteralCopy(LITERAL);
+
+static __inline__ LIST clause_CopyClauseList(LIST List)
+{
+ return list_CopyWithElement(List, (POINTER (*)(POINTER)) clause_Copy);
+}
+
+void clause_DeleteLiteral(CLAUSE, int, FLAGSTORE, PRECEDENCE);
+void clause_DeleteLiteralNN(CLAUSE, int);
+void clause_DeleteLiterals(CLAUSE, LIST, FLAGSTORE, PRECEDENCE); /* Unused */
+LIST clause_GetLiteralSubSetList(CLAUSE, int, int, FLAGSTORE, PRECEDENCE);
+void clause_ReplaceLiteralSubSet(CLAUSE, int, int, LIST, FLAGSTORE, PRECEDENCE);
+void clause_FixLiteralOrder(CLAUSE, FLAGSTORE, PRECEDENCE);
+
+SYMBOL clause_AtomMaxVar(TERM);
+void clause_SetMaxLitFlags(CLAUSE, FLAGSTORE, PRECEDENCE);
+SYMBOL clause_LiteralMaxVar(LITERAL); /* Used only in clause.c */
+SYMBOL clause_SearchMaxVar(CLAUSE);
+void clause_UpdateMaxVar(CLAUSE);
+
+void clause_RenameVarsBiggerThan(CLAUSE, SYMBOL);
+void clause_Normalize(CLAUSE);
+void clause_SetSortConstraint(CLAUSE, BOOL, FLAGSTORE, PRECEDENCE);
+void clause_SubstApply(SUBST, CLAUSE);
+void clause_ReplaceVariable(CLAUSE, SYMBOL, TERM);
+void clause_OrientEqualities(CLAUSE, FLAGSTORE, PRECEDENCE);
+NAT clause_NumberOfVarOccs(CLAUSE);
+NAT clause_NumberOfSymbolOccurrences(CLAUSE, SYMBOL);
+NAT clause_ComputeWeight(CLAUSE, FLAGSTORE);
+NAT clause_LiteralComputeWeight(LITERAL, FLAGSTORE);
+NAT clause_ComputeTermDepth(CLAUSE);
+NAT clause_MaxTermDepthClauseList(LIST);
+NAT clause_ComputeSize(CLAUSE);
+BOOL clause_WeightCorrect(CLAUSE, FLAGSTORE, PRECEDENCE); /* Unused */
+
+LIST clause_MoveBestLiteralToFront(LIST, SUBST, SYMBOL,
+ BOOL (*)(LITERAL, NAT, LITERAL, NAT));
+
+
+LIST clause_InsertWeighed(CLAUSE, LIST, FLAGSTORE, PRECEDENCE);
+LIST clause_ListSortWeighed(LIST);
+
+BOOL clause_HasTermSortConstraintLits(CLAUSE);
+BOOL clause_HasSolvedConstraint(CLAUSE);
+BOOL clause_IsDeclarationClause(CLAUSE);
+BOOL clause_IsSortTheoryClause(CLAUSE, FLAGSTORE, PRECEDENCE);
+BOOL clause_IsPartOfDefinition(CLAUSE, TERM, int*, LIST);
+BOOL clause_IsPotentialSortTheoryClause(CLAUSE, FLAGSTORE, PRECEDENCE);
+BOOL clause_HasOnlyVarsInConstraint(CLAUSE, FLAGSTORE, PRECEDENCE);
+BOOL clause_HasSortInSuccedent(CLAUSE, FLAGSTORE, PRECEDENCE);
+BOOL clause_ContainsPotPredDef(CLAUSE, FLAGSTORE, PRECEDENCE, NAT*, LIST*);
+BOOL clause_LitsHaveCommonVar(LITERAL, LITERAL);
+
+void clause_SelectLiteral(CLAUSE, FLAGSTORE);
+void clause_SetSpecialFlags(CLAUSE,BOOL, FLAGSTORE, PRECEDENCE);
+
+BOOL clause_LiteralIsLiteral(LITERAL);
+BOOL clause_IsClause(CLAUSE, FLAGSTORE, PRECEDENCE);
+BOOL clause_IsUnorderedClause(CLAUSE);
+BOOL clause_ContainsPositiveEquations(CLAUSE);
+BOOL clause_ContainsNegativeEquations(CLAUSE);
+int clause_ContainsFolAtom(CLAUSE,BOOL*,BOOL*,BOOL*,BOOL*);
+BOOL clause_ContainsVariables(CLAUSE);
+BOOL clause_ContainsFunctions(CLAUSE);
+BOOL clause_ContainsSymbol(CLAUSE, SYMBOL);
+void clause_ContainsSortRestriction(CLAUSE,BOOL*,BOOL*);
+BOOL clause_ImpliesFiniteDomain(CLAUSE);
+BOOL clause_ImpliesNonTrivialDomain(CLAUSE);
+LIST clause_FiniteMonadicPredicates(LIST);
+
+CLAUSE clause_GetNumberedCl(int, LIST);
+LIST clause_NumberSort(LIST);
+LIST clause_NumberDelete(LIST,int);
+void clause_Check(CLAUSE, FLAGSTORE, PRECEDENCE);
+
+void clause_DeleteFlatFromIndex(CLAUSE, st_INDEX);
+void clause_InsertFlatIntoIndex(CLAUSE, st_INDEX);
+void clause_DeleteClauseListFlatFromIndex(LIST, st_INDEX);
+
+RULE clause_GetOriginFromString(const char*);
+
+void clause_CountSymbols(CLAUSE);
+
+LIST clause_ListOfPredicates(CLAUSE);
+LIST clause_ListOfConstants(CLAUSE);
+LIST clause_ListOfVariables(CLAUSE);
+LIST clause_ListOfFunctions(CLAUSE);
+
+/* special output functions for clauses with parent pointers */
+void clause_PParentsFPrint(FILE*, CLAUSE);
+void clause_PParentsListFPrint(FILE*, LIST L);
+void clause_PParentsPrint(CLAUSE);
+void clause_PParentsListPrint(LIST);
+void clause_PParentsFPrintGen(FILE*, CLAUSE, BOOL);
+
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+/**************************************************************/
+/* Accessing Literals 1 */
+/**************************************************************/
+
+static __inline__ TERM clause_LiteralSignedAtom(LITERAL L)
+{
+ return L->atomWithSign;
+}
+
+
+static __inline__ CLAUSE clause_LiteralOwningClause(LITERAL L)
+{
+ return L->owningClause;
+}
+
+static __inline__ void clause_LiteralSetOwningClause(LITERAL L, CLAUSE C)
+{
+ L->owningClause = C;
+}
+
+
+static __inline__ void clause_LiteralSetOrientedEquality(LITERAL L)
+{
+ L->oriented = TRUE;
+}
+
+static __inline__ void clause_LiteralSetNoOrientedEquality(LITERAL L)
+{
+ L->oriented = FALSE;
+}
+
+
+static __inline__ NAT clause_LiteralWeight(LITERAL L)
+{
+#ifdef CHECK
+ if (L->weight == clause_WEIGHTUNDEFINED) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_LiteralWeight:");
+ misc_ErrorReport(" Tried to access undefined weight.");
+ misc_FinishErrorReport();
+ }
+#endif
+ return L->weight;
+}
+
+
+static __inline__ void clause_UpdateLiteralWeight(LITERAL L, FLAGSTORE Flags)
+{
+ L->weight = clause_LiteralComputeWeight(L, Flags);
+}
+
+
+static __inline__ void clause_LiteralFlagReset(LITERAL L)
+{
+ L->maxLit = 0;
+}
+
+static __inline__ BOOL clause_LiteralGetFlag(LITERAL L, MAXFLAG Flag)
+{
+ return ((L->maxLit & Flag) != 0);
+}
+
+static __inline__ void clause_LiteralSetFlag(LITERAL L, MAXFLAG Flag)
+{
+ L->maxLit = (L->maxLit) | Flag;
+}
+
+static __inline__ BOOL clause_LiteralIsMaximal(LITERAL L)
+{
+ return clause_LiteralGetFlag(L, MAXIMAL);
+}
+
+
+
+static __inline__ BOOL clause_LiteralIsOrientedEquality(LITERAL L)
+{
+ return L->oriented;
+}
+
+
+static __inline__ BOOL clause_LiteralIsNotOrientedEquality(LITERAL L)
+{
+ return !(L->oriented);
+}
+
+
+/**************************************************************/
+/* Literal Comparison 1 */
+/**************************************************************/
+
+static __inline__ BOOL clause_LiteralIsNegative(LITERAL L)
+{
+ return (term_TopSymbol(clause_LiteralSignedAtom(L)) == fol_Not());
+}
+
+static __inline__ BOOL clause_LiteralIsPositive(LITERAL L)
+{
+ return !clause_LiteralIsNegative(L);
+}
+
+
+static __inline__ BOOL clause_LiteralsAreComplementary(LITERAL L1, LITERAL L2)
+{
+ return ((clause_LiteralIsNegative(L1) &&
+ clause_LiteralIsPositive(L2)) ||
+ (clause_LiteralIsNegative(L2) &&
+ clause_LiteralIsPositive(L1))); /* xor */
+}
+
+static __inline__ BOOL clause_HyperLiteralIsBetter(LITERAL Dummy1, NAT S1,
+ LITERAL Dummy2, NAT S2)
+/**************************************************************
+ INPUT: Two literals and its sizes wrt. some substitution.
+ RETURNS: TRUE, if the first literal is 'better' than the second literal,
+ FALSE otherwise.
+ EFFECT: A literal is 'better' than another, if S1 > Ss.
+ Since we have to find unifiable complementary literals
+ for every remaining antecedent literal, it seems to be
+ a good idea to try the most 'difficult' literal first,
+ in order to stop the search as early as possible..
+ Here we prefer the literal with the highest number
+ of symbols..
+ This function is used as parameter for the function
+ clause_MoveBestLiteralToFront.
+ CAUTION: The parameters <Dummy1> and <Dummy2> are unused, they're just
+ added to keep the compiler quiet.
+***************************************************************/
+{
+ return (S1 > S2);
+}
+
+
+/**************************************************************/
+/* Accessing Literals 2 */
+/**************************************************************/
+
+static __inline__ TERM clause_LiteralAtom(LITERAL L)
+{
+ if (clause_LiteralIsNegative(L))
+ return term_FirstArgument(clause_LiteralSignedAtom(L));
+ else
+ return clause_LiteralSignedAtom(L);
+}
+
+
+static __inline__ SYMBOL clause_LiteralPredicate(LITERAL L)
+{
+ return term_TopSymbol(clause_LiteralAtom(L));
+}
+
+static __inline__ BOOL clause_LiteralIsPredicate(LITERAL L)
+{
+ return !fol_IsEquality(clause_LiteralAtom(L));
+}
+
+static __inline__ BOOL clause_LiteralIsEquality(LITERAL L)
+{
+ return fol_IsEquality(clause_LiteralAtom(L));
+}
+
+static __inline__ BOOL clause_LiteralIsSort(LITERAL L)
+{
+ SYMBOL S;
+ S = clause_LiteralPredicate(L);
+ return (symbol_IsPredicate(S) &&
+ (symbol_Arity(S) == 1));
+}
+
+
+static __inline__ void clause_LiteralSetAtom(LITERAL L, TERM A)
+{
+ if (clause_LiteralIsNegative(L))
+ list_Rplaca(term_ArgumentList(clause_LiteralSignedAtom(L)),A);
+ else
+ L->atomWithSign = A;
+}
+
+static __inline__ void clause_LiteralSetNegAtom(LITERAL L, TERM A)
+{
+ list_Rplaca(term_ArgumentList(clause_LiteralSignedAtom(L)), A);
+}
+
+static __inline__ void clause_LiteralSetPosAtom(LITERAL L, TERM A)
+{
+ L->atomWithSign = A;
+}
+
+static __inline__ void clause_NLiteralSetLiteral(LITERAL L, TERM LIT)
+{
+ L->atomWithSign = LIT;
+}
+
+/**************************************************************/
+/* Memory management */
+/**************************************************************/
+
+static __inline__ void clause_LiteralFree(LITERAL L)
+{
+ memory_Free(L, sizeof(LITERAL_NODE));
+}
+
+
+/**************************************************************/
+/* Functions to access literals. */
+/**************************************************************/
+
+static __inline__ LITERAL clause_GetLiteral(CLAUSE C, int Index)
+{
+ return C->literals[Index];
+}
+
+static __inline__ void clause_SetLiteral(CLAUSE C, int Index, LITERAL L)
+{
+ C->literals[Index]= L;
+}
+
+static __inline__ TERM clause_GetLiteralTerm(CLAUSE C, int Index)
+{
+ return clause_LiteralSignedAtom(clause_GetLiteral(C, Index));
+}
+
+static __inline__ TERM clause_GetLiteralAtom(CLAUSE C, int Index)
+{
+ return clause_LiteralAtom(clause_GetLiteral(C, Index));
+}
+
+static __inline__ int clause_NumOfConsLits(CLAUSE Clause)
+{
+ return Clause->c;
+}
+
+static __inline__ int clause_NumOfAnteLits(CLAUSE Clause)
+{
+ return Clause->a;
+}
+
+static __inline__ int clause_NumOfSuccLits(CLAUSE Clause)
+{
+ return Clause->s;
+}
+
+static __inline__ void clause_SetNumOfConsLits(CLAUSE Clause, int Number)
+{
+ Clause->c = Number;
+}
+
+static __inline__ void clause_SetNumOfAnteLits(CLAUSE Clause, int Number)
+{
+ Clause->a = Number;
+}
+
+static __inline__ void clause_SetNumOfSuccLits(CLAUSE Clause, int Number)
+{
+ Clause->s = Number;
+}
+
+static __inline__ int clause_Length(CLAUSE Clause)
+{
+ return (clause_NumOfConsLits(Clause) +
+ clause_NumOfAnteLits(Clause) +
+ clause_NumOfSuccLits(Clause));
+}
+
+
+static __inline__ int clause_LastLitIndex(CLAUSE Clause)
+{
+ return clause_Length(Clause) - 1;
+}
+
+static __inline__ int clause_FirstLitIndex(void)
+{
+ return 0;
+}
+
+static __inline__ int clause_FirstConstraintLitIndex(CLAUSE Clause)
+{
+ return 0;
+}
+
+static __inline__ int clause_FirstAntecedentLitIndex(CLAUSE Clause)
+{
+ return clause_NumOfConsLits(Clause);
+}
+
+static __inline__ int clause_FirstSuccedentLitIndex(CLAUSE Clause)
+{
+ return (clause_NumOfAnteLits(Clause) + clause_NumOfConsLits(Clause));
+}
+
+
+static __inline__ int clause_LastConstraintLitIndex(CLAUSE Clause)
+{
+ return clause_NumOfConsLits(Clause) - 1;
+}
+
+static __inline__ int clause_LastAntecedentLitIndex(CLAUSE Clause)
+{
+ return clause_FirstSuccedentLitIndex(Clause) - 1;
+}
+
+static __inline__ int clause_LastSuccedentLitIndex(CLAUSE Clause)
+{
+ return clause_Length(Clause) - 1;
+}
+
+static __inline__ LIST clause_GetLiteralList(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: A new list is created containing all literals of the
+ clause. The list contains pointers, not literal indexes.
+***************************************************************/
+{
+ LIST Result;
+ int i;
+
+ Result = list_Nil();
+ for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++)
+ Result = list_Cons(clause_GetLiteral(Clause, i), Result);
+ return Result;
+}
+
+
+static __inline__ LIST clause_GetLiteralListExcept(CLAUSE Clause, int Index)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: A new list is created containing all literals of the
+ clause except the literal at <Index>. The list contains
+ pointers, not literal indexes.
+***************************************************************/
+{
+ LIST Result;
+ int i;
+
+ Result = list_Nil();
+ for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++)
+ if (i != Index)
+ Result = list_Cons(clause_GetLiteral(Clause, i), Result);
+ return Result;
+}
+
+
+/**************************************************************/
+/* Clause Access Macros */
+/**************************************************************/
+
+static __inline__ int clause_Counter(void)
+{
+ return clause_CLAUSECOUNTER;
+}
+
+static __inline__ void clause_SetCounter(int Value)
+{
+#ifdef CHECK
+ if (Value < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_SetCounter: new counter value is negative.");
+ misc_FinishErrorReport();
+ }
+#endif
+ clause_CLAUSECOUNTER = Value;
+}
+
+static __inline__ int clause_IncreaseCounter(void)
+{
+#ifdef CHECK
+ if (clause_CLAUSECOUNTER == INT_MAX) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_IncreaseCounter: counter overflow.");
+ misc_FinishErrorReport();
+ }
+#endif
+ return clause_CLAUSECOUNTER++;
+}
+
+static __inline__ void clause_DecreaseCounter(void)
+{
+#ifdef CHECK
+ if (clause_CLAUSECOUNTER == 0) {
+ misc_FinishErrorReport();
+ misc_ErrorReport("\n In clause_DecreaseCounter: counter underflow.");
+ misc_FinishErrorReport();
+ }
+#endif
+ clause_CLAUSECOUNTER--;
+}
+
+static __inline__ NAT clause_Depth(CLAUSE Clause)
+{
+ return Clause->depth;
+}
+
+static __inline__ void clause_SetDepth(CLAUSE Clause, NAT NewDepth)
+{
+ Clause->depth = NewDepth;
+}
+
+
+static __inline__ NAT clause_Weight(CLAUSE Clause)
+{
+#ifdef CHECK
+ if (Clause->weight == clause_WEIGHTUNDEFINED) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_Weight: Tried to access undefined weight.");
+ misc_FinishErrorReport();
+ }
+#endif
+ return Clause->weight;
+}
+
+static __inline__ void clause_UpdateWeight(CLAUSE Clause, FLAGSTORE Flags)
+{
+ Clause->weight = clause_ComputeWeight(Clause, Flags);
+}
+
+
+static __inline__ int clause_Number(const CLAUSE Clause)
+{
+ return Clause->clausenumber;
+}
+
+static __inline__ void clause_SetNumber(CLAUSE Clause, int Number)
+{
+ Clause->clausenumber = Number;
+}
+
+static __inline__ void clause_NewNumber(CLAUSE Clause)
+{
+ Clause->clausenumber = clause_IncreaseCounter();
+}
+
+
+static __inline__ NAT clause_SplitLevel(CLAUSE Clause)
+{
+ return Clause->validlevel;
+}
+
+static __inline__ BOOL clause_CheckSplitLevel(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: TRUE, if the splitlevel invariant for the clause is fulfilled.
+ EFFECT: Checks, if the validlevel of the clause is the order
+ of the highest set bit in the SPLITFIELD entry
+ of the clause.
+***************************************************************/
+{
+ if (Clause->validlevel == 0)
+ return (Clause->splitfield == NULL);
+ else {
+ int i, j;
+ for (i = Clause->splitfield_length-1; i >= 0; i--)
+ if (Clause->splitfield[i] != 0)
+ break;
+ for (j = sizeof(SPLITFIELDENTRY)*CHAR_BIT-1; j >= 0; j--)
+ if (Clause->splitfield[i] & ((SPLITFIELDENTRY)1 << j))
+ break;
+ return (Clause->validlevel == (i*sizeof(SPLITFIELDENTRY)*CHAR_BIT+j));
+ }
+}
+
+static __inline__ LIST clause_ParentClauses(CLAUSE Clause)
+{
+ return Clause->parentCls;
+}
+
+static __inline__ LIST clause_ParentLiterals(CLAUSE Clause)
+{
+ return Clause->parentLits;
+}
+
+
+static __inline__ SYMBOL clause_MaxVar(CLAUSE Clause)
+{
+ return Clause->maxVar;
+}
+
+static __inline__ void clause_SetMaxVar(CLAUSE Clause, SYMBOL Variable)
+{
+ Clause->maxVar = Variable;
+}
+
+
+static __inline__ RULE clause_Origin(CLAUSE Clause)
+{
+ return Clause->origin;
+}
+
+static __inline__ BOOL clause_Exists(CLAUSE Clause)
+{
+ return (Clause != (CLAUSE)NULL);
+}
+
+static __inline__ BOOL clause_LiteralExists(LITERAL L)
+{
+ return (L != (LITERAL)NULL);
+}
+
+static __inline__ CLAUSE clause_Null(void)
+{
+ return (CLAUSE) NULL;
+}
+
+static __inline__ void clause_SetSplitLevel(CLAUSE Clause, NAT Level)
+{
+ Clause->validlevel = Level;
+}
+
+static __inline__ void clause_InitSplitData(CLAUSE C)
+{
+ C->splitfield = NULL;
+ C->splitfield_length = 0;
+ clause_SetSplitLevel(C, 0);
+}
+
+static __inline__ void clause_SetSplitField(CLAUSE Clause, SPLITFIELD B,
+ unsigned Length)
+{
+ unsigned i;
+ if (Clause->splitfield_length != Length) {
+ if (Clause->splitfield != NULL) {
+ memory_Free(Clause->splitfield,
+ sizeof(SPLITFIELDENTRY) * Clause->splitfield_length);
+ }
+ if (Length != 0) {
+ Clause->splitfield = memory_Malloc(sizeof(SPLITFIELDENTRY) * Length);
+ }
+ else
+ Clause->splitfield = NULL;
+ Clause->splitfield_length = Length;
+ }
+ for (i=0; i < Length; i++)
+ Clause->splitfield[i] = B[i];
+}
+
+
+static __inline__ NAT clause_ComputeSplitFieldAddress(NAT n, NAT* field)
+{
+ *field = 0;
+ while (n >= (sizeof(SPLITFIELDENTRY) * CHAR_BIT)) {
+ (*field)++;
+ n -= sizeof(SPLITFIELDENTRY) * CHAR_BIT;
+ }
+ return n;
+}
+
+static __inline__ void clause_ExpandSplitField(CLAUSE C, NAT Length)
+{
+ SPLITFIELD NewField;
+ NAT i;
+ if (C->splitfield_length < Length) {
+ NewField = memory_Malloc(sizeof(SPLITFIELDENTRY) * Length);
+ for (i=0; i < C->splitfield_length; i++)
+ NewField[i] = C->splitfield[i];
+ for (i=C->splitfield_length; i < Length; i++)
+ NewField[i] = 0;
+ if (C->splitfield != NULL) {
+ memory_Free(C->splitfield,
+ sizeof(SPLITFIELDENTRY) * C->splitfield_length);
+ }
+ C->splitfield = NewField;
+ C->splitfield_length = Length;
+ }
+}
+
+static __inline__ void clause_UpdateSplitField(CLAUSE C1, CLAUSE C2)
+ /* Add the split data of <C2> to <C1> */
+{
+ unsigned i;
+ if (C1->splitfield_length < C2->splitfield_length)
+ clause_ExpandSplitField(C1, C2->splitfield_length);
+ for (i=0; i < C2->splitfield_length; i++)
+ C1->splitfield[i] = C1->splitfield[i] | C2->splitfield[i];
+}
+
+static __inline__ void clause_ClearSplitField(CLAUSE C)
+{
+ int i;
+
+ for (i=C->splitfield_length-1; i >=0; i--)
+ C->splitfield[i] = 0;
+}
+
+static __inline__ void clause_SetSplitFieldBit(CLAUSE Clause, NAT n)
+{
+ unsigned field;
+
+ n = clause_ComputeSplitFieldAddress(n, &field);
+ if (field >= Clause->splitfield_length)
+ clause_ExpandSplitField(Clause, field + 1);
+ Clause->splitfield[field] = (Clause->splitfield[field]) |
+ ((SPLITFIELDENTRY)1 << n);
+}
+
+static __inline__ BOOL clause_GetFlag(CLAUSE Clause, CLAUSE_FLAGS Flag)
+{
+ return (Clause->flags & Flag) != 0;
+}
+
+static __inline__ void clause_SetFlag(CLAUSE Clause, CLAUSE_FLAGS Flag)
+{
+ Clause->flags = Clause->flags | Flag;
+}
+
+static __inline__ void clause_RemoveFlag(CLAUSE Clause, CLAUSE_FLAGS Flag)
+{
+ if (Clause->flags & Flag)
+ Clause->flags = Clause->flags - Flag;
+}
+
+static __inline__ void clause_ClearFlags(CLAUSE Clause)
+{
+ Clause->flags = 0;
+}
+
+
+static __inline__ BOOL clause_DependsOnSplitLevel(CLAUSE C, NAT N)
+{
+ if (N==0)
+ return TRUE;
+ else {
+ unsigned field;
+ N = clause_ComputeSplitFieldAddress(N, &field);
+ if (field >= C->splitfield_length)
+ return FALSE;
+ else
+ return (C->splitfield[field] & ((SPLITFIELDENTRY)1 << N)) != 0;
+ }
+}
+
+static __inline__ void clause_SetSplitDataFromFather(CLAUSE Result,
+ CLAUSE Father)
+{
+ if (clause_GetFlag(Father, CONCLAUSE))
+ clause_SetFlag(Result, CONCLAUSE);
+ clause_SetSplitLevel(Result, clause_SplitLevel(Father));
+ clause_SetSplitField(Result, Father->splitfield, Father->splitfield_length);
+}
+
+static __inline__ void clause_UpdateSplitDataFromNewSplitting(CLAUSE Result,
+ CLAUSE Father,
+ NAT Level)
+{
+ unsigned field;
+ NAT i;
+
+ clause_SetSplitLevel(Result, Level);
+ Level = clause_ComputeSplitFieldAddress(Level, &field);
+
+ if (field >= Result->splitfield_length) {
+ if (Result->splitfield != NULL)
+ memory_Free(Result->splitfield,
+ sizeof(SPLITFIELDENTRY) * Result->splitfield_length);
+ Result->splitfield = memory_Malloc((field + 1) * sizeof(SPLITFIELDENTRY));
+ Result->splitfield_length = field + 1;
+ }
+ if (clause_GetFlag(Father, CONCLAUSE))
+ clause_SetFlag(Result, CONCLAUSE);
+ for (i=0; i < Father->splitfield_length; i++)
+ Result->splitfield[i] = Father->splitfield[i];
+ for (i=Father->splitfield_length; i < Result->splitfield_length; i++)
+ Result->splitfield[i] = 0;
+ Result->splitfield[field] = (Result->splitfield[field] | ((SPLITFIELDENTRY)1 << Level));
+}
+
+static __inline__ void clause_UpdateSplitDataFromPartner(CLAUSE Result,
+ CLAUSE Partner)
+{
+ if (clause_GetFlag(Partner, CONCLAUSE))
+ clause_SetFlag(Result, CONCLAUSE);
+ if (clause_SplitLevel(Partner) == 0)
+ return;
+ /* Set Split level to misc_Max(Partner, Result) */
+ clause_SetSplitLevel(Result, clause_SplitLevel(Partner) > clause_SplitLevel(Result)
+ ? clause_SplitLevel(Partner)
+ : clause_SplitLevel(Result));
+ clause_UpdateSplitField(Result, Partner);
+}
+
+static __inline__ void clause_SetSplitDataFromList(CLAUSE Result, LIST List)
+{
+ CLAUSE TempClause;
+ LIST Scan;
+ NAT l;
+ Scan = List;
+ l = Result->splitfield_length;
+ while (!list_Empty(Scan)) {
+ TempClause = (CLAUSE) list_Top(Scan);
+ if (clause_GetFlag(TempClause, CONCLAUSE))
+ clause_SetFlag(Result, CONCLAUSE);
+ clause_SetSplitLevel(Result,
+ clause_SplitLevel(TempClause) > clause_SplitLevel(Result)
+ ? clause_SplitLevel(TempClause)
+ : clause_SplitLevel(Result));
+ if (l < TempClause->splitfield_length)
+ l = TempClause->splitfield_length;
+ Scan = list_Cdr(Scan);
+ }
+ if (l > Result->splitfield_length) {
+ if (Result->splitfield != NULL)
+ memory_Free(Result->splitfield,
+ sizeof(SPLITFIELDENTRY) * Result->splitfield_length);
+ Result->splitfield = memory_Malloc(sizeof(SPLITFIELDENTRY) * l);
+ Result->splitfield_length = l;
+ }
+
+ for (l=0; l < Result->splitfield_length; l++)
+ Result->splitfield[l] = 0;
+
+ while (!list_Empty(List)) {
+ TempClause= (CLAUSE) list_Top(List);
+ List = list_Cdr(List);
+ for (l=0; l < TempClause->splitfield_length; l++)
+ Result->splitfield[l] = Result->splitfield[l] | TempClause->splitfield[l];
+ }
+}
+
+
+static __inline__ void clause_SetSplitDataFromParents(CLAUSE Result,
+ CLAUSE Mother,
+ CLAUSE Father)
+{
+ NAT i;
+ if (clause_GetFlag(Father, CONCLAUSE) || clause_GetFlag(Mother, CONCLAUSE))
+ clause_SetFlag(Result, CONCLAUSE);
+ if ((clause_SplitLevel(Father) == 0) && (clause_SplitLevel(Mother) == 0))
+ return;
+ clause_SetSplitLevel(Result, clause_SplitLevel(Mother) > clause_SplitLevel(Father)
+ ? clause_SplitLevel(Mother)
+ : clause_SplitLevel(Father));
+
+ if (Mother->splitfield_length > Father->splitfield_length) {
+ if (Result->splitfield != NULL)
+ memory_Free(Result->splitfield,
+ sizeof(SPLITFIELDENTRY) * Result->splitfield_length);
+ Result->splitfield = memory_Malloc(sizeof(SPLITFIELDENTRY) *
+ Mother->splitfield_length);
+ Result->splitfield_length = Mother->splitfield_length;
+ for (i=0; i < Father->splitfield_length; i++)
+ Result->splitfield[i] =
+ Mother->splitfield[i] | Father->splitfield[i];
+ for (i=Father->splitfield_length; i < Mother->splitfield_length; i++)
+ Result->splitfield[i] = Mother->splitfield[i];
+ }
+ else {
+ if (Result->splitfield != NULL)
+ memory_Free(Result->splitfield,
+ sizeof(SPLITFIELDENTRY) * Result->splitfield_length);
+ Result->splitfield = memory_Malloc(sizeof(SPLITFIELDENTRY) *
+ Father->splitfield_length);
+ Result->splitfield_length = Father->splitfield_length;
+ for (i=0; i < Mother->splitfield_length; i++)
+ Result->splitfield[i] =
+ Mother->splitfield[i] | Father->splitfield[i];
+ for (i=Mother->splitfield_length; i < Father->splitfield_length; i++)
+ Result->splitfield[i] = Father->splitfield[i];
+ }
+}
+
+static __inline__ void clause_SetParentClauses(CLAUSE Clause, LIST PClauses)
+{
+ Clause->parentCls = PClauses;
+}
+
+static __inline__ void clause_AddParentClause(CLAUSE Clause, int PClause)
+{
+ Clause->parentCls = list_Cons((POINTER) PClause, Clause->parentCls);
+}
+
+static __inline__ void clause_SetParentLiterals(CLAUSE Clause, LIST PLits)
+{
+ Clause->parentLits = PLits;
+}
+
+static __inline__ void clause_AddParentLiteral(CLAUSE Clause, int PLit)
+{
+ Clause->parentLits = list_Cons((POINTER) PLit, Clause->parentLits);
+}
+
+
+static __inline__ BOOL clause_ValidityIsNotSmaller(CLAUSE C1, CLAUSE C2)
+{
+ return (C1->validlevel <= C2->validlevel);
+}
+
+static __inline__ BOOL clause_IsMoreValid(CLAUSE C1, CLAUSE C2)
+{
+ return (C1->validlevel < C2->validlevel);
+}
+
+
+static __inline__ BOOL clause_CompareAbstractLEQ (CLAUSE Left, CLAUSE Right)
+/**************************************************************
+ INPUT: Two clauses.
+ RETURNS: TRUE if left <= right, FALSE otherwise.
+ EFFECTS: Internal function used to compare clauses for
+ sorting.
+ CAUTION: Expects clause literal order to be fixed.
+***************************************************************/
+{
+ return (BOOL) (clause_CompareAbstract(Left, Right) <= 0);
+}
+
+
+static __inline__ BOOL clause_IsFromRewriting(CLAUSE Clause)
+{
+ return Clause->origin == REWRITING;
+}
+
+static __inline__ BOOL clause_IsFromCondensing(CLAUSE Clause)
+{
+ return Clause->origin == CONDENSING;
+}
+
+static __inline__ BOOL clause_IsFromObviousReductions(CLAUSE Clause)
+{
+ return Clause->origin == OBVIOUS_REDUCTIONS;
+}
+
+static __inline__ BOOL clause_IsFromSortSimplification(CLAUSE Clause)
+{
+ return Clause->origin == SORT_SIMPLIFICATION;
+}
+
+static __inline__ BOOL clause_IsFromMatchingReplacementResolution(CLAUSE Clause)
+{
+ return Clause->origin == MATCHING_REPLACEMENT_RESOLUTION;
+}
+
+static __inline__ BOOL clause_IsFromClauseDeletion(CLAUSE Clause)
+{
+ return Clause->origin == CLAUSE_DELETION;
+}
+
+static __inline__ BOOL clause_IsFromEmptySort(CLAUSE Clause)
+{
+ return Clause->origin == EMPTY_SORT;
+}
+
+static __inline__ BOOL clause_IsFromSortResolution(CLAUSE Clause)
+{
+ return Clause->origin == SORT_RESOLUTION;
+}
+
+static __inline__ BOOL clause_IsFromUnitConflict(CLAUSE Clause)
+{
+ return Clause->origin == UNIT_CONFLICT;
+}
+
+static __inline__ BOOL clause_IsFromEqualityResolution(CLAUSE Clause)
+{
+ return Clause->origin == EQUALITY_RESOLUTION;
+}
+
+static __inline__ BOOL clause_IsFromEqualityFactoring(CLAUSE Clause)
+{
+ return Clause->origin == EQUALITY_FACTORING;
+}
+
+static __inline__ BOOL clause_IsFromMergingParamodulation(CLAUSE Clause)
+{
+ return Clause->origin == MERGING_PARAMODULATION;
+}
+
+static __inline__ BOOL clause_IsFromSuperpositionRight(CLAUSE Clause)
+{
+ return Clause->origin == SUPERPOSITION_RIGHT;
+}
+
+static __inline__ BOOL clause_IsFromSuperpositionLeft(CLAUSE Clause)
+{
+ return Clause->origin == SUPERPOSITION_LEFT;
+}
+
+static __inline__ BOOL clause_IsFromGeneralResolution(CLAUSE Clause)
+{
+ return Clause->origin == GENERAL_RESOLUTION;
+}
+
+static __inline__ BOOL clause_IsFromGeneralFactoring(CLAUSE Clause)
+{
+ return Clause->origin == GENERAL_FACTORING;
+}
+
+static __inline__ BOOL clause_IsFromSplitting(CLAUSE Clause)
+{
+ return Clause->origin == SPLITTING;
+}
+
+static __inline__ BOOL clause_IsFromDefApplication(CLAUSE Clause)
+{
+ return Clause->origin == DEFAPPLICATION;
+}
+
+static __inline__ BOOL clause_IsFromTerminator(CLAUSE Clause)
+{
+ return Clause->origin == TERMINATOR;
+}
+
+static __inline__ BOOL clause_IsTemporary(CLAUSE Clause)
+{
+ return Clause->origin == TEMPORARY;
+}
+
+static __inline__ BOOL clause_IsFromInput(CLAUSE Clause)
+{
+ return Clause->origin == INPUT;
+}
+
+
+static __inline__ BOOL clause_HasReducedPredecessor(CLAUSE Clause)
+{
+ RULE origin = clause_Origin(Clause);
+
+ return (origin == CONDENSING ||
+ origin == REWRITING ||
+ origin == SPLITTING ||
+ origin == ASSIGNMENT_EQUATION_DELETION ||
+ origin == SORT_SIMPLIFICATION ||
+ origin == OBVIOUS_REDUCTIONS);
+}
+
+static __inline__ BOOL clause_IsSplitFather(CLAUSE C1, CLAUSE C2)
+{
+ return (C1->clausenumber == (int)list_Car(C2->parentCls));
+}
+
+
+static __inline__ void clause_SetFromRewriting(CLAUSE Clause)
+{
+ Clause->origin = REWRITING;
+}
+
+static __inline__ void clause_SetFromContextualRewriting(CLAUSE Clause)
+{
+ Clause->origin = CONTEXTUAL_REWRITING;
+}
+
+static __inline__ void clause_SetFromUnitConflict(CLAUSE Clause)
+{
+ Clause->origin = UNIT_CONFLICT;
+}
+
+static __inline__ void clause_SetFromCondensing(CLAUSE Clause)
+{
+ Clause->origin = CONDENSING;
+}
+
+static __inline__ void clause_SetFromAssignmentEquationDeletion(CLAUSE Clause)
+{
+ Clause->origin = ASSIGNMENT_EQUATION_DELETION;
+}
+
+static __inline__ void clause_SetFromObviousReductions(CLAUSE Clause)
+{
+ Clause->origin = OBVIOUS_REDUCTIONS;
+}
+
+static __inline__ void clause_SetFromSortSimplification(CLAUSE Clause)
+{
+ Clause->origin = SORT_SIMPLIFICATION;
+}
+
+static __inline__ void clause_SetFromMatchingReplacementResolution(CLAUSE Clause)
+{
+ Clause->origin = MATCHING_REPLACEMENT_RESOLUTION;
+}
+
+static __inline__ void clause_SetFromClauseDeletion(CLAUSE Clause)
+{
+ Clause->origin = CLAUSE_DELETION;
+}
+
+static __inline__ void clause_SetFromEmptySort(CLAUSE Clause)
+{
+ Clause->origin = EMPTY_SORT;
+}
+
+static __inline__ void clause_SetFromSortResolution(CLAUSE Clause)
+{
+ Clause->origin = SORT_RESOLUTION;
+}
+
+static __inline__ void clause_SetFromEqualityResolution(CLAUSE Clause)
+{
+ Clause->origin = EQUALITY_RESOLUTION;
+}
+
+static __inline__ void clause_SetFromEqualityFactoring(CLAUSE Clause)
+{
+ Clause->origin = EQUALITY_FACTORING;
+}
+
+static __inline__ void clause_SetFromMergingParamodulation(CLAUSE Clause)
+{
+ Clause->origin = MERGING_PARAMODULATION;
+}
+
+static __inline__ void clause_SetFromParamodulation(CLAUSE Clause)
+{
+ Clause->origin = PARAMODULATION;
+}
+static __inline__ void clause_SetFromOrderedParamodulation(CLAUSE Clause)
+{
+ Clause->origin = ORDERED_PARAMODULATION;
+}
+static __inline__ void clause_SetFromSuperpositionRight(CLAUSE Clause)
+{
+ Clause->origin = SUPERPOSITION_RIGHT;
+}
+
+static __inline__ void clause_SetFromSuperpositionLeft(CLAUSE Clause)
+{
+ Clause->origin = SUPERPOSITION_LEFT;
+}
+
+static __inline__ void clause_SetFromGeneralResolution(CLAUSE Clause)
+{
+ Clause->origin = GENERAL_RESOLUTION;
+}
+
+static __inline__ void clause_SetFromOrderedHyperResolution(CLAUSE Clause)
+{
+ Clause->origin = ORDERED_HYPER;
+}
+
+static __inline__ void clause_SetFromSimpleHyperResolution(CLAUSE Clause)
+{
+ Clause->origin = SIMPLE_HYPER;
+}
+
+static __inline__ void clause_SetFromURResolution(CLAUSE Clause)
+{
+ Clause->origin = UR_RESOLUTION;
+}
+
+static __inline__ void clause_SetFromGeneralFactoring(CLAUSE Clause)
+{
+ Clause->origin = GENERAL_FACTORING;
+}
+
+static __inline__ void clause_SetFromSplitting(CLAUSE Clause)
+{
+ Clause->origin = SPLITTING;
+}
+
+static __inline__ void clause_SetFromDefApplication(CLAUSE Clause)
+{
+ Clause->origin = DEFAPPLICATION;
+}
+
+static __inline__ void clause_SetFromTerminator(CLAUSE Clause)
+{
+ Clause->origin = TERMINATOR;
+}
+
+static __inline__ void clause_SetTemporary(CLAUSE Clause)
+{
+ Clause->origin = TEMPORARY;
+}
+
+
+static __inline__ void clause_SetFromInput(CLAUSE Clause)
+{
+ Clause->origin = INPUT;
+}
+
+
+static __inline__ LITERAL clause_FirstConstraintLit(CLAUSE Clause)
+{
+ return Clause->literals[0];
+}
+
+static __inline__ LITERAL clause_FirstAntecedentLit(CLAUSE Clause)
+{
+ return Clause->literals[clause_FirstAntecedentLitIndex(Clause)];
+}
+
+static __inline__ LITERAL clause_FirstSuccedentLit(CLAUSE Clause)
+{
+ return Clause->literals[clause_FirstSuccedentLitIndex(Clause)];
+}
+
+static __inline__ LITERAL clause_LastConstraintLit(CLAUSE Clause)
+{
+ return Clause->literals[clause_LastConstraintLitIndex(Clause)];
+}
+
+static __inline__ LITERAL clause_LastAntecedentLit(CLAUSE Clause)
+{
+ return Clause->literals[clause_LastAntecedentLitIndex(Clause)];
+}
+
+static __inline__ LITERAL clause_LastSuccedentLit(CLAUSE Clause)
+{
+ return Clause->literals[clause_LastSuccedentLitIndex(Clause)];
+}
+
+
+static __inline__ BOOL clause_HasEmptyConstraint(CLAUSE Clause)
+{
+ return clause_NumOfConsLits(Clause) == 0;
+}
+
+static __inline__ BOOL clause_HasEmptyAntecedent(CLAUSE Clause)
+{
+ return clause_NumOfAnteLits(Clause) == 0;
+}
+
+static __inline__ BOOL clause_HasEmptySuccedent(CLAUSE Clause)
+{
+ return clause_NumOfSuccLits(Clause) == 0;
+}
+
+
+static __inline__ BOOL clause_IsGround(CLAUSE Clause)
+{
+#ifdef CHECK
+ if (!symbol_Equal(clause_MaxVar(Clause), clause_SearchMaxVar(Clause))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In clause_IsGround: Clause is corrupted.");
+ misc_FinishErrorReport();
+ }
+#endif
+ return (symbol_VarIndex(clause_MaxVar(Clause)) ==
+ symbol_GetInitialStandardVarCounter());
+}
+
+static __inline__ BOOL clause_IsEmptyClause(CLAUSE C)
+{
+ return (C != (CLAUSE)NULL &&
+ clause_HasEmptyAntecedent(C) &&
+ clause_HasEmptySuccedent(C) &&
+ clause_HasEmptyConstraint(C));
+}
+
+static __inline__ int clause_LiteralGetIndex(LITERAL L)
+{
+ int j = 0;
+
+ while (clause_GetLiteral(clause_LiteralOwningClause(L), j) != L)
+ j++;
+
+ return j;
+}
+
+static __inline__ BOOL clause_LiteralIsFromConstraint(LITERAL Literal)
+{
+ int index = clause_LiteralGetIndex(Literal);
+ CLAUSE clause = clause_LiteralOwningClause(Literal);
+
+ return (index <= clause_LastConstraintLitIndex(clause) &&
+ index >= clause_FirstConstraintLitIndex(clause));
+}
+
+static __inline__ BOOL clause_LiteralIsFromAntecedent(LITERAL Literal)
+{
+ int index = clause_LiteralGetIndex(Literal);
+ CLAUSE clause = clause_LiteralOwningClause(Literal);
+
+ return (index <= clause_LastAntecedentLitIndex(clause) &&
+ index >= clause_FirstAntecedentLitIndex(clause));
+}
+
+static __inline__ BOOL clause_LiteralIsFromSuccedent(LITERAL Literal)
+{
+ int index;
+ CLAUSE clause;
+ index = clause_LiteralGetIndex(Literal);
+ clause = clause_LiteralOwningClause(Literal);
+ return (index <= clause_LastSuccedentLitIndex(clause) &&
+ index >= clause_FirstSuccedentLitIndex(clause));
+}
+
+static __inline__ BOOL clause_IsSimpleSortClause(CLAUSE Clause)
+{
+ return (clause_HasEmptyAntecedent(Clause) &&
+ (clause_NumOfSuccLits(Clause) == 1) &&
+ clause_LiteralIsSort(clause_GetLiteral(Clause,
+ clause_NumOfConsLits(Clause))) &&
+ clause_HasSolvedConstraint(Clause));
+}
+
+static __inline__ BOOL clause_IsSubsortClause(CLAUSE Clause)
+{
+ return (clause_IsSimpleSortClause(Clause) &&
+ term_IsVariable(term_FirstArgument(
+ clause_LiteralSignedAtom(
+ clause_GetLiteral(Clause, clause_NumOfConsLits(Clause))))));
+}
+
+
+static __inline__ BOOL clause_HasSuccLits(CLAUSE Clause)
+{
+ return (clause_NumOfSuccLits(Clause) > 1);
+}
+
+static __inline__ BOOL clause_HasGroundSuccLit(CLAUSE Clause)
+{
+ int i, l;
+
+ l = clause_Length(Clause);
+ for (i = clause_FirstSuccedentLitIndex(Clause); i < l; i++)
+ if (term_IsGround(Clause->literals[i]->atomWithSign))
+ return TRUE;
+
+ return FALSE;
+}
+
+static __inline__ LITERAL clause_GetGroundSuccLit(CLAUSE Clause)
+{
+ int i, l;
+
+ l = clause_Length(Clause);
+ for (i = clause_FirstSuccedentLitIndex(Clause); i < l; i++)
+ if (term_IsGround(Clause->literals[i]->atomWithSign))
+ return Clause->literals[i];
+
+ return (LITERAL)NULL;
+}
+
+
+static __inline__ void clause_Free(CLAUSE Clause)
+{
+ memory_Free(Clause, sizeof(CLAUSE_NODE));
+}
+
+
+static __inline__ void clause_ReInit(CLAUSE Clause,
+ FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+{
+ clause_Normalize(Clause);
+ clause_SetMaxLitFlags(Clause, Flags, Precedence);
+ clause_UpdateWeight(Clause, Flags);
+ clause_UpdateMaxVar(Clause);
+}
+
+static __inline__ void clause_OrientAndReInit(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+{
+ clause_OrientEqualities(Clause, Flags, Precedence);
+ clause_ReInit(Clause, Flags, Precedence);
+}
+
+static __inline__ void clause_SetDataFromFather(CLAUSE Result, CLAUSE Father,
+ int i, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+{
+ clause_OrientAndReInit(Result, Flags, Precedence);
+ clause_SetSplitDataFromFather(Result, Father);
+ clause_SetDepth(Result, clause_Depth(Father) + 1);
+ clause_AddParentClause(Result, clause_Number(Father));
+ clause_AddParentLiteral(Result, i);
+}
+
+
+static __inline__ void clause_SetDataFromParents(CLAUSE Result, CLAUSE Father,
+ int i, CLAUSE Mother, int j,
+ FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+{
+ clause_OrientAndReInit(Result, Flags, Precedence);
+ clause_SetSplitDataFromParents(Result, Father, Mother);
+ clause_SetDepth(Result,
+ misc_Max(clause_Depth(Father), clause_Depth(Mother)) +1);
+ clause_AddParentClause(Result, clause_Number(Father));
+ clause_AddParentLiteral(Result, i);
+ clause_AddParentClause(Result, clause_Number(Mother));
+ clause_AddParentLiteral(Result, j);
+}
+
+
+#endif
+
diff --git a/test/spass/clock.c b/test/spass/clock.c
new file mode 100644
index 0000000..7106669
--- /dev/null
+++ b/test/spass/clock.c
@@ -0,0 +1,215 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CLOCK * */
+/* * * */
+/* * $Module: CLOCK * */
+/* * * */
+/* * Copyright (C) 1996, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "clock.h"
+
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+float clock_Akku[clock_TYPESIZE];
+CLOCK_TMS clock_Counters[clock_TYPESIZE];
+
+#ifdef WIN
+float clock_Ping;
+#endif
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void clock_Init(void)
+/*********************************************************
+ INPUT: None.
+ EFFECT: Initializes the clock Module.
+ RETURNS: None.
+ MEMORY: None.
+**********************************************************/
+{
+ int i;
+
+ for (i=0;i<clock_TYPESIZE;i++) {
+ clock_InitCounter(i);
+ }
+#ifdef WIN
+ clock_Ping = 0;
+#endif
+}
+
+
+
+void clock_InitCounter(CLOCK_CLOCKS ClockCounter)
+/*********************************************************
+ INPUT: A clock counter.
+ EFFECT: The clock counter <ClockCounter> is initialized.
+ RETURNS: None.
+ MEMORY: None.
+**********************************************************/
+{
+ clock_Akku[ClockCounter] = 0;
+}
+
+
+void clock_StartCounter(CLOCK_CLOCKS ClockCounter)
+/*********************************************************
+ INPUT: A clock counter.
+ EFFECT: The clock counter <ClockCounter> is started.
+ RETURNS: None.
+ MEMORY: None.
+**********************************************************/
+{
+#ifndef CLOCK_NO_TIMING
+ ftime(&(clock_Counters[ClockCounter]));
+#endif
+}
+
+
+void clock_StopPassedTime(CLOCK_CLOCKS ClockCounter)
+/*********************************************************
+ INPUT: A clock counter.
+ EFFECT: Stores the number of seconds passed since given
+ counter was started in the according
+ accumulator.
+ RETURNS: None.
+ MEMORY: None.
+**********************************************************/
+{
+#ifndef CLOCK_NO_TIMING
+ CLOCK_TMS newtime;
+ ftime(&newtime);
+ clock_Akku[ClockCounter] = clock_GetSeconds(ClockCounter);
+#endif
+}
+
+
+void clock_StopAddPassedTime(CLOCK_CLOCKS ClockCounter)
+/*********************************************************
+ INPUT: A clock counter.
+ EFFECT: Adds the number of seconds passed since given
+ counter was started to the according
+ accumulator.
+ RETURNS: None.
+ MEMORY: None.
+**********************************************************/
+{
+#ifndef CLOCK_NO_TIMING
+ CLOCK_TMS newtime;
+ ftime(&newtime);
+ clock_Akku[ClockCounter] += clock_GetSeconds(ClockCounter);
+#endif
+}
+
+
+float clock_GetSeconds(CLOCK_CLOCKS ClockCounter)
+/*********************************************************
+ INPUT: A clock counter.
+ EFFECT: Computes the number of seconds spent by the
+ counter.
+ RETURNS: The number of seconds spent by the counter as
+ a float.
+ MEMORY: None.
+**********************************************************/
+{
+#ifndef CLOCK_NO_TIMING
+ CLOCK_TMS newtime;
+ ftime(&newtime);
+ return ((float) (newtime.time - clock_Counters[ClockCounter].time)
+ + (((newtime.millitm - clock_Counters[ClockCounter].millitm))
+ /(float)1000));
+#else
+ return 0;
+#endif
+}
+
+#ifdef WIN
+void clock_PingOneSecond(void)
+/*********************************************************
+ INPUT: None but assumes the clock_OVERALL to be properly
+ initialized.
+ EFFECT: If between the previous call to this function or
+ to clock_Init more one second is passed, the
+ function prints a "PING" to stdout.
+ Needed only for the windows implementation.
+ CAUTION: Only needed to get around Windows95/98 scheduling
+ problems.
+**********************************************************/
+{
+ if (clock_GetSeconds(clock_OVERALL) > clock_Ping + 1) {
+ clock_Ping++;
+ puts("\n PING ");
+ }
+}
+#endif
+
+
+
+void clock_PrintTime(CLOCK_CLOCKS ClockCounter)
+/*********************************************************
+ INPUT: A clock counter.
+ EFFECT: The time is printed in format hh:mm:ss.dd to stdout
+ RETURNS: None.
+ MEMORY: None.
+**********************************************************/
+{
+#ifndef CLOCK_NO_TIMING
+ NAT hours, minutes;
+ float seconds;
+
+ seconds = clock_Akku[ClockCounter];
+ hours = (NAT)seconds/3600;
+ seconds -= hours*3600;
+ minutes = (NAT)seconds/60;
+ seconds -= (minutes*60);
+ if (seconds >= 10.0)
+ printf("%u:%02u:%2.2f",hours,minutes,seconds);
+ else
+ printf("%u:%02u:0%2.2f",hours,minutes,seconds);
+#else
+ fputs(" No Timing on this machine. ",stdout);
+#endif
+}
diff --git a/test/spass/clock.h b/test/spass/clock.h
new file mode 100644
index 0000000..6e67574
--- /dev/null
+++ b/test/spass/clock.h
@@ -0,0 +1,78 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CLOCK * */
+/* * * */
+/* * $Module: CLOCK * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1999, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+#ifndef _CLOCK_
+#define _CLOCK_
+
+#include "misc.h"
+#include <sys/types.h>
+#include <sys/timeb.h>
+
+typedef enum {
+ clock_BACKTRACK,
+ clock_OVERALL,
+ clock_INPUT,
+ clock_CNF,
+ clock_REDUCTION,
+ clock_INFERENCE,
+ clock_TYPESIZE
+} CLOCK_CLOCKS;
+
+typedef struct timeb CLOCK_TMS;
+
+void clock_Init(void);
+void clock_InitCounter(CLOCK_CLOCKS);
+void clock_StartCounter(CLOCK_CLOCKS);
+void clock_StopPassedTime(CLOCK_CLOCKS);
+void clock_StopAddPassedTime(CLOCK_CLOCKS);
+float clock_GetSeconds(CLOCK_CLOCKS);
+void clock_PrintTime(CLOCK_CLOCKS);
+
+#ifdef WIN
+void clock_PingOneSecond(void);
+#endif
+
+#endif
diff --git a/test/spass/closure.c b/test/spass/closure.c
new file mode 100644
index 0000000..cfebc7a
--- /dev/null
+++ b/test/spass/closure.c
@@ -0,0 +1,441 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CONGRUENCE CLOSURE ALGORITHM * */
+/* * * */
+/* * $Module: CLOSURE * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/**************************************************************/
+/* Include */
+/**************************************************************/
+
+#include "closure.h"
+
+
+/**************************************************************/
+/* Global constants and variable */
+/**************************************************************/
+
+/* standard initial size of a closure's stacks */
+static const int cc_RASSTDSIZE = 64;
+/* cc_RASSTDSIZE * ld(cc_RASSTDSIZE) */
+static const int cc_SIZELDSIZE = 384;
+/* the virtual term "true" has number 0 */
+static const ELEMENT cc_NOOFTRUE = 0;
+
+
+static struct {
+ PARTITION partition;
+ TABLE table;
+ RAS car, cdr, size, pending, combine;
+} cc_CLOSURE;
+
+/* the closure consists of a partition, a signature table, stacks for */
+/* (circularly linked) lists of predecessors of equivalence classes (i. e. */
+/* terms with direct subterms from this class), for the sizes of these lists, */
+/* for pending terms (the ones to be worked off) and for terms to be combined */
+/* in the same equivalence class */
+
+
+/**************************************************************/
+/* Inline functions */
+/**************************************************************/
+
+static __inline__ PARTITION cc_GetPartition(void)
+{
+ return cc_CLOSURE.partition;
+}
+
+
+static __inline__ void cc_SetPartition(PARTITION partition)
+{
+ cc_CLOSURE.partition = partition;
+}
+
+
+static __inline__ TABLE cc_GetTable(void)
+{
+ return cc_CLOSURE.table;
+}
+
+
+static __inline__ void cc_SetTable(TABLE table)
+{
+ cc_CLOSURE.table = table;
+}
+
+
+static __inline__ RAS cc_GetCars(void)
+{
+ return cc_CLOSURE.car;
+}
+
+
+static __inline__ TERM cc_GetCar(int index)
+{
+ return (TERM) ras_Get(cc_GetCars(), index);
+}
+
+
+static __inline__ void cc_SetCars(RAS car)
+{
+ cc_CLOSURE.car = car;
+}
+
+
+static __inline__ RAS cc_GetCdrs(void)
+{
+ return cc_CLOSURE.cdr;
+}
+
+
+static __inline__ int cc_GetCdr(int index)
+{
+ return (int) ras_Get(cc_GetCdrs(), index);
+}
+
+
+static __inline__ void cc_SetCdrs(RAS cdr)
+{
+ cc_CLOSURE.cdr = cdr;
+}
+
+
+static __inline__ void cc_SetCdr(int index, int cdr)
+{
+ ras_Set(cc_GetCdrs(), index, (POINTER) cdr);
+}
+
+
+static __inline__ RAS cc_GetSizes(void)
+{
+ return cc_CLOSURE.size;
+}
+
+
+static __inline__ int cc_GetSize(int index)
+{
+ return (int) ras_Get(cc_GetSizes(), index);
+}
+
+
+static __inline__ void cc_SetSizes(RAS size)
+{
+ cc_CLOSURE.size = size;
+}
+
+
+static __inline__ void cc_SetSize(int index, int size)
+{
+ ras_Set(cc_GetSizes(), index, (POINTER) size);
+}
+
+
+static __inline__ RAS cc_GetPending(void)
+{
+ return cc_CLOSURE.pending;
+}
+
+
+static __inline__ void cc_SetPending(RAS pending)
+{
+ cc_CLOSURE.pending = pending;
+}
+
+
+static __inline__ RAS cc_GetCombine(void)
+{
+ return cc_CLOSURE.combine;
+}
+
+
+static __inline__ void cc_SetCombine(RAS combine)
+{
+ cc_CLOSURE.combine = combine;
+}
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+static int cc_Number(int actno, TERM term, TERM pred)
+/***************************************************************
+ INPUT: the actual number of terms, the term to be numbered
+ and its predecessor (may be the empty term
+ term_Null())
+ RETURNS: the new number of terms after recursively numbering
+ the term and its subterms
+ EFFECT: stores a term's number as its size, partially
+ initializes its predecessor list and pushes all
+ subterms to the pending stack
+***************************************************************/
+{
+ LIST terms;
+
+#ifdef CHECK
+ if (actno < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cc_Number: negative actual number of terms.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_SetSize(term, actno++);
+ cc_SetCars(ras_Push(cc_GetCars(), pred));
+ cc_SetPending(ras_Push(cc_GetPending(), term));
+ for (terms = term_ArgumentList(term); !list_Empty(terms); terms =
+ list_Cdr(terms))
+ actno = cc_Number(actno, list_Car(terms), term);
+ return actno;
+}
+
+
+static void cc_Union(ECLASS c1, ECLASS c2)
+/***************************************************************
+ EFFECT: unions c1 and c2, therefore the signatures of the
+ predecessors of one class change, so these
+ predecessors have to be deleted from the signature
+ table and become pending again; sets new class's
+ predecessor list and its size to the concatenation of
+ the old lists resp. the sum of the old sizes
+***************************************************************/
+{
+ int aux, size;
+ TERM term;
+
+#ifdef CHECK
+ if (part_Find(cc_GetPartition(), c1) != c1) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cc_Union: first class corrupted, i. e. is not ");
+ misc_ErrorReport("the representative.");
+ misc_FinishErrorReport();
+ }
+ if (part_Find(cc_GetPartition(), c2) != c2) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cc_Union: second class corrupted, i. e. is not ");
+ misc_ErrorReport("the representative.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (c1 != c2) {
+
+ /* make c1 the class with the bigger (or at least not smaller) list: */
+ if (cc_GetSize(c1) < cc_GetSize(c2)) {
+ aux = c1;
+ c1 = c2;
+ c2 = aux;
+ }
+
+ /* delete c2's predecessors from signature table and add them to pending: */
+ for (size = cc_GetSize(c2), aux = c2; size > 0; size--) {
+ term = cc_GetCar(aux);
+ aux = cc_GetCdr(aux);
+ table_Delete(cc_GetTable(), term);
+ cc_SetPending(ras_Push(cc_GetPending(), term));
+ }
+
+ if (cc_GetSize(c2) > 0) { /* then GetSize(c1) ( >= GetSize(c2) ) > 0 too */
+
+ /* union circularly linked lists by exchanging cdrs: */
+ aux = cc_GetCdr(c1);
+ cc_SetCdr(c1, cc_GetCdr(c2));
+ cc_SetCdr(c2, aux);
+
+ cc_SetSize(c1, cc_GetSize(c1) + cc_GetSize(c2));
+ }
+ part_Union(cc_GetPartition(), c1, c2);
+ }
+}
+
+
+static void cc_InitData(CLAUSE clause)
+/***************************************************************
+ INPUT: the clause to investigate
+ EFFECT: pushes clause's atoms and their subterms on the
+ pending stack, initializes each predecessor list with
+ the list containing only a term's father, and unions
+ the equivalence classes of the terms of the same
+ antecedent equation
+***************************************************************/
+{
+ int last, actno, i, ld;
+ TERM atom;
+ RAS cdr, size;
+
+ cc_SetCars(ras_InitWithSize(cc_GetCars(), cc_RASSTDSIZE));
+ cc_SetPending(ras_InitWithSize(cc_GetPending(), cc_RASSTDSIZE));
+ ras_FastPush(cc_GetCars(), term_Null()); /* "true" has no predecessors */
+ actno = 1;
+ last = clause_LastLitIndex(clause);
+ for (i = clause_FirstLitIndex(); i <= last; i++) {
+ atom = clause_GetLiteralAtom(clause, i);
+ if (fol_IsEquality(atom)) {
+ actno = cc_Number(actno, term_FirstArgument(atom), term_Null());
+ actno = cc_Number(actno, term_SecondArgument(atom), term_Null());
+ }
+ else
+ actno = cc_Number(actno, atom, term_Null());
+ }
+ cc_SetPartition(part_Init(cc_GetPartition(), actno));
+ cc_SetTable(table_Init(cc_GetTable(), symbol_ActIndex() - 1,
+ clause_MaxVar(clause), actno - 1));
+ cdr = ras_InitWithSize(cc_GetCdrs(), actno);
+ size = ras_InitWithSize(cc_GetSizes(), actno);
+ for (i = 0; i < actno; i++) {
+ ras_FastPush(cdr, (POINTER) i); /* form a cycle */
+ ras_FastPush(size, (POINTER) (cc_GetCar(i) == term_Null()? 0 : 1));
+ }
+ cc_SetCdrs(cdr);
+ cc_SetSizes(size);
+
+ /* compute ceil(ld(actno)) avoiding mathbib-logarithm's rounding errors: */
+ for (ld = 0, i = actno - 1; i > 0; i >>= 1)
+ ld++;
+
+ cc_SetCombine(ras_InitWithSize(cc_GetCombine(), actno * ld + 1));
+
+ /* for every antecedent equation union equivalence classes of its terms */
+ /* (a non-equational atom is represented as the equation atom = "true"): */
+ last = clause_LastAntecedentLitIndex(clause);
+ for (i = clause_FirstLitIndex(); i <= last; i++) {
+ atom = clause_GetLiteralAtom(clause, i);
+ if (fol_IsEquality(atom))
+ cc_Union(term_Size(term_FirstArgument(atom)), /* clause not shared, therefore */
+ term_Size(term_SecondArgument(atom))); /* here no cc_Find needed */
+ else
+ cc_Union(term_Size(atom), part_Find(cc_GetPartition(), cc_NOOFTRUE));
+ }
+
+}
+
+
+static BOOL cc_Outit(CLAUSE clause)
+/***************************************************************
+ RETURNS: the decision, if the clause is a tautology
+***************************************************************/
+{
+ int last, i;
+ BOOL result;
+ TERM atom;
+
+#ifdef CHECK
+ if (!ras_Empty(cc_GetPending())) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cc_Outit: there are terms left to work off.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ last = clause_LastLitIndex(clause);
+ for (i = clause_FirstSuccedentLitIndex(clause), result = FALSE;
+ i <= last && !result; i++) {
+ atom = clause_GetLiteralAtom(clause, i);
+ if (fol_IsEquality(atom))
+ result = part_Equivalent(cc_GetPartition(),
+ term_Size(term_FirstArgument(atom)),
+ term_Size(term_SecondArgument(atom)));
+ else
+ result = part_Equivalent(cc_GetPartition(), term_Size(atom), cc_NOOFTRUE);
+ }
+ return result;
+}
+
+
+/**************************************************************/
+/* Main functions */
+/**************************************************************/
+
+void cc_Init(void)
+{
+ cc_SetPartition(part_Create(cc_RASSTDSIZE));
+ cc_SetTable(table_Create(cc_RASSTDSIZE, cc_RASSTDSIZE, cc_RASSTDSIZE));
+ cc_SetCars(ras_CreateWithSize(cc_RASSTDSIZE));
+ cc_SetCdrs(ras_CreateWithSize(cc_RASSTDSIZE));
+ cc_SetSizes(ras_CreateWithSize(cc_RASSTDSIZE));
+ cc_SetPending(ras_CreateWithSize(cc_RASSTDSIZE));
+ cc_SetCombine(ras_CreateWithSize(cc_SIZELDSIZE));
+}
+
+
+void cc_Free(void)
+{
+ part_Free(cc_GetPartition());
+ table_Free(cc_GetTable());
+ ras_Free(cc_GetCars());
+ ras_Free(cc_GetCdrs());
+ ras_Free(cc_GetSizes());
+ ras_Free(cc_GetPending());
+ ras_Free(cc_GetCombine());
+}
+
+
+BOOL cc_Tautology(CLAUSE clause)
+/***************************************************************
+ INPUT: the clause to test
+ RETURNS: the decision, if the clause - where all variables are
+ regarded as skolem constants - is a tautology, using
+ the congruence closure algorithm of Downey, Sethi and
+ Tarjan
+ CAUTION: overrides the sizes of the clause's terms
+***************************************************************/
+{
+ TERM term, query;
+
+ cc_InitData(clause);
+ while (!ras_Empty(cc_GetPending())) {
+
+ /* propagate the closure: */
+ while (!ras_Empty(cc_GetPending())) {
+ term = ras_Pop(cc_GetPending());
+ query = table_QueryAndEnter(cc_GetTable(), cc_GetPartition(), term);
+ if (query != term_Null()) {
+ ras_FastPush(cc_GetCombine(), term);
+ ras_FastPush(cc_GetCombine(), query);
+ }
+ }
+ while (!ras_Empty(cc_GetCombine()))
+ cc_Union(part_Find(cc_GetPartition(), term_Size(ras_Pop(cc_GetCombine()))),
+ part_Find(cc_GetPartition(), term_Size(ras_Pop(cc_GetCombine()))));
+ }
+ return cc_Outit(clause);
+}
+
diff --git a/test/spass/closure.h b/test/spass/closure.h
new file mode 100644
index 0000000..0a6d5c0
--- /dev/null
+++ b/test/spass/closure.h
@@ -0,0 +1,67 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CONGRUENCE CLOSURE ALGORITHM * */
+/* * * */
+/* * $Module: CLOSURE * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+#ifndef _CLOSURE_
+#define _CLOSURE_
+
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "clause.h"
+#include "table.h"
+#include "ras.h"
+
+
+/**************************************************************/
+/* Prototype */
+/**************************************************************/
+
+void cc_Init(void);
+void cc_Free(void);
+BOOL cc_Tautology(CLAUSE);
+
+
+#endif
+
diff --git a/test/spass/cnf.c b/test/spass/cnf.c
new file mode 100644
index 0000000..bf52a26
--- /dev/null
+++ b/test/spass/cnf.c
@@ -0,0 +1,4787 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CNF TRANSLATOR * */
+/* * * */
+/* * $Module: CNF * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "cnf.h"
+#include "rules-inf.h"
+#include "rules-red.h"
+
+
+static TERM cnf_AntiPrenexPath(TERM, TERM);
+static TERM cnf_ApplyDefinitionInternOnce(TERM, TERM, TERM, TERM, BOOL*);
+
+static SYMBOL cnf_GetDualSymbol(SYMBOL symbol);
+
+static TERM cnf_IsDefinition(TERM);
+
+static void cnf_OptimizedSkolemFormula(PROOFSEARCH, TERM, char*, BOOL, TERM,
+ LIST*, LIST*, BOOL, HASH, int);
+static int cnf_PredicateOccurrences(TERM, SYMBOL);
+
+static void cnf_RplacVar(TERM, LIST, LIST);
+
+static LIST cnf_SatUnit(PROOFSEARCH, LIST);
+static LIST cnf_SkolemFunctionFormula(TERM, LIST, LIST, PRECEDENCE);
+
+/* For every variable the depth in the current term, required for */
+/* strong skolemization */
+static int* cnf_VARIABLEDEPTHARRAY;
+/* Holds a copy of the ProofSearch--Object built by cnf_Flotter */
+/* during cnf_QueryFlotter */
+static PROOFSEARCH cnf_SEARCHCOPY;
+
+/* Proofsearch--Object for the function cnf_HaveProof. We need this */
+/* to reduce the number of term stamps required. */
+static PROOFSEARCH cnf_HAVEPROOFPS;
+
+
+void cnf_Init(FLAGSTORE Flags)
+/***************************************************************
+ INPUT: A flag store.
+ RETURNS: None.
+ SUMMARY: Initializes the CNF Module.
+ EFFECTS: Initializes global variables.
+ CAUTION: MUST BE CALLED BEFORE ANY OTHER CNF-FUNCTION.
+***************************************************************/
+{
+ /* If strong skolemization is performed, allocate array for variable depth */
+ if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM))
+ cnf_VARIABLEDEPTHARRAY = (int*) memory_Malloc(sizeof(int[symbol__MAXSTANDARDVAR + 1]));
+ else
+ cnf_VARIABLEDEPTHARRAY = NULL;
+ cnf_SEARCHCOPY = prfs_Create();
+ cnf_HAVEPROOFPS = prfs_Create();
+}
+
+
+void cnf_Free(FLAGSTORE Flags)
+/**************************************************************
+ INPUT: A flag store.
+ RETURNS: None.
+ SUMMARY: Frees the CNF Module.
+***************************************************************/
+{
+ /* If strong skolemization is performed, free array for variable depth */
+ if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM)) {
+ memory_Free(cnf_VARIABLEDEPTHARRAY, sizeof(int) * (symbol__NOOFSTANDARDVAR + 1));
+ cnf_VARIABLEDEPTHARRAY = NULL;
+ }
+ prfs_Delete(cnf_SEARCHCOPY);
+ cnf_SEARCHCOPY = NULL;
+ prfs_Delete(cnf_HAVEPROOFPS);
+ cnf_HAVEPROOFPS = NULL;
+}
+
+
+static int cnf_GetFormulaPolarity(TERM term, TERM subterm)
+/**********************************************************
+ INPUT: Two terms term and subterm where subterm is a
+ subterm of term.
+ RETURNS: The polarity of subterm in term.
+********************************************************/
+{
+ LIST scan;
+ TERM term1;
+ int polterm1,bottom;
+
+ bottom = vec_ActMax();
+ vec_Push((POINTER) 1);
+ vec_Push(term);
+
+ do {
+ term1 = (TERM)vec_PopResult();
+ polterm1 = (int)vec_PopResult();
+ if (term1 == subterm) {
+ vec_SetMax(bottom);
+ return polterm1;
+ }else
+ if (symbol_Equal(term_TopSymbol(term1),fol_Not())) {
+ vec_Push((POINTER) (- polterm1));
+ vec_Push(list_Car(term_ArgumentList(term1)));
+ }
+ if (symbol_Equal(term_TopSymbol(term1),fol_Exist()) ||
+ symbol_Equal(term_TopSymbol(term1),fol_All())) {
+ vec_Push((POINTER)polterm1);
+ vec_Push(list_Second(term_ArgumentList(term1)));
+ }
+ else
+ if (symbol_Equal(term_TopSymbol(term1),fol_Implies())) {
+ vec_Push((POINTER) (- polterm1));
+ vec_Push(list_Car(term_ArgumentList(term1)));
+ vec_Push((POINTER) polterm1);
+ vec_Push(list_Second(term_ArgumentList(term1)));
+ }
+ else
+ if (symbol_Equal(term_TopSymbol(term1),fol_Equiv())) {
+ vec_Push(0);
+ vec_Push(list_Car(term_ArgumentList(term1)));
+ vec_Push(0);
+ vec_Push(list_Second(term_ArgumentList(term1)));
+ }
+ else
+ if (symbol_Equal(term_TopSymbol(term1),fol_And()) ||
+ symbol_Equal(term_TopSymbol(term1),fol_Or())) {
+ for (scan = term_ArgumentList(term1);
+ !list_Empty(scan);
+ scan = list_Cdr(scan)) {
+ vec_Push((POINTER) polterm1);
+ vec_Push(list_Car(scan));
+ }
+ }
+ } while (bottom != vec_ActMax());
+ vec_SetMax(bottom);
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_GetFormulaPolarity: Wrong arguments !\n");
+ misc_FinishErrorReport();
+ return -2;
+}
+
+
+static BOOL cnf_ContainsDefinitionIntern(TERM TopDef, TERM Def, int Polarity,
+ TERM* FoundPred)
+/**********************************************************
+ INPUT: A term TopDef which is the top level term of the recursion.
+ A term Def which is searched for a definition.
+ A pointer to a term into which the predicate of the definition
+ is stored if it is found.
+ RETURNS: TRUE if Def contains a definition that can be converted
+ to standard form.
+********************************************************/
+{
+ /* AND / OR */
+ /* In these cases Def cannot be converted to standard form */
+
+ if ((symbol_Equal(term_TopSymbol(Def),fol_And()) && (Polarity == 1)) ||
+ (symbol_Equal(term_TopSymbol(Def),fol_Or()) && (Polarity == -1)))
+ return FALSE;
+
+ if (symbol_Equal(term_TopSymbol(Def), fol_And()) ||
+ symbol_Equal(term_TopSymbol(Def),fol_Or())) {
+ /* Polarity is ok */
+ LIST l;
+ for (l=term_ArgumentList(Def); !list_Empty(l); l=list_Cdr(l))
+ if (cnf_ContainsDefinitionIntern(TopDef, list_Car(l), Polarity, FoundPred))
+ return TRUE;
+ return FALSE;
+ }
+
+ /* Quantifiers */
+ if (fol_IsQuantifier(term_TopSymbol(Def)))
+ return cnf_ContainsDefinitionIntern(TopDef, term_SecondArgument(Def), Polarity, FoundPred);
+
+ /* Negation */
+ if (symbol_Equal(term_TopSymbol(Def),fol_Not()))
+ return cnf_ContainsDefinitionIntern(TopDef, term_FirstArgument(Def), -Polarity, FoundPred);
+
+ /* Implication */
+ if (symbol_Equal(term_TopSymbol(Def),fol_Implies())) {
+ if (Polarity==1) {
+ if (cnf_ContainsDefinitionIntern(TopDef, term_FirstArgument(Def), -Polarity, FoundPred))
+ return TRUE;
+ return cnf_ContainsDefinitionIntern(TopDef, term_SecondArgument(Def), Polarity, FoundPred);
+ }
+ return FALSE;
+ }
+
+ /* Equivalence */
+ if (symbol_Equal(term_TopSymbol(Def),fol_Equiv()) && (Polarity==1)) {
+ /* Check if equivalence itself is in correct form */
+ TERM defpredicate;
+
+ defpredicate = cnf_IsDefinition(Def);
+ if (defpredicate != (TERM) NULL) {
+ LIST predicate_vars, l, defpath;
+ BOOL allquantifierfound;
+ TERM super;
+ int pol;
+ /* Check if predicate occurs several times in TopDef */
+ /* if (cnf_PredicateOccurrences(TopDef, term_TopSymbol(defpredicate)) > 1) {}
+ puts("\n Predicate occurs more than once.");
+ return FALSE; */
+
+
+ /* Now make sure that the variables of the predicate are */
+ /* all--quantified and not in the scope of an exist quantifier */
+ /* predicate_vars = list_Copy(term_ArgumentList(defpredicate)); */
+ predicate_vars = term_ListOfVariables(defpredicate);
+ predicate_vars = term_DeleteDuplicatesFromList(predicate_vars);
+
+ /* So far (going bottom--up) no all-quantifier was found for */
+ /* a variable of the predicates' arguments */
+ allquantifierfound = FALSE;
+
+ /* Build defpath here by going bottom up */
+ /* At first, list of superterms on path is top down */
+ defpath = list_Nil();
+ super = Def;
+ while (super != (TERM) NULL) {
+ defpath = list_Cons(super, defpath);
+ super = term_Superterm(super);
+ }
+ /* No go top down and add polarities */
+ pol = 1;
+ for (l=defpath; !list_Empty(l); l=list_Cdr(l)) {
+ list_Rplaca(l, list_PairCreate((TERM) list_Car(l), (LIST) pol));
+ if (symbol_Equal(term_TopSymbol((TERM) list_Car(l)), fol_Not()))
+ pol = -pol;
+ else {
+ if (symbol_Equal(term_TopSymbol((TERM) list_Car(l)), fol_Implies()) &&
+ (term_FirstArgument((TERM) list_Car(l)) == (TERM) list_Car(list_Cdr(l))))
+ pol = -pol;
+ else
+ if (symbol_Equal(term_TopSymbol((TERM) list_Car(l)), fol_Equiv()))
+ pol = 0;
+ }
+ }
+ /* <defpath> is now a list of pairs (term, polarity) */
+ for (l=defpath; !list_Empty(l) && !list_Empty(predicate_vars); l=list_Cdr(l)) {
+ LIST pair;
+ TERM t;
+ int p;
+ /* Pair Term t / Polarity p */
+ pair = (LIST) list_Car(l);
+ t = (TERM) list_PairFirst(pair);
+ p = (int) list_PairSecond(pair);
+
+ if (fol_IsQuantifier(term_TopSymbol(t))) {
+
+ /* Variables of the predicate that are universally quantified are no problem */
+ if ((symbol_Equal(term_TopSymbol(t), fol_All()) && (p==1)) ||
+ (symbol_Equal(term_TopSymbol(t), fol_Exist()) && (p==-1))) {
+ LIST scan;
+ allquantifierfound = TRUE;
+ for (scan=fol_QuantifierVariables(t); !list_Empty(scan); scan=list_Cdr(scan))
+ predicate_vars = list_DeleteElement(predicate_vars,(TERM) list_Car(scan),
+ (BOOL (*)(POINTER,POINTER))term_Equal);
+ }
+ else {
+ /* Check if allquantified variables of the predicate are in scope of an exist--quantifier */
+ /* We already found an all quantified variable */
+ if (allquantifierfound) {
+ list_Delete(predicate_vars);
+ list_DeletePairList(defpath);
+ return FALSE;
+ }
+ else {
+ LIST scan;
+ /* Check if a variable of the predicate is exist--quantified */
+ for (scan=fol_QuantifierVariables(t); !list_Empty(scan); scan=list_Cdr(scan)) {
+ if (term_ListContainsTerm(predicate_vars, list_Car(scan))) {
+ list_Delete(predicate_vars);
+ list_DeletePairList(defpath);
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+ }
+
+#ifdef CHECK
+ if (!list_Empty(predicate_vars)) {
+ list_Delete(predicate_vars);
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_ContainsDefinitionIntern: Definition has free variables.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+ list_DeletePairList(defpath);
+ *FoundPred = defpredicate;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+BOOL cnf_ContainsDefinition(TERM Def, TERM* FoundPred)
+/**********************************************************
+ INPUT: A term Def which is searched for a definition of a predicate.
+ A pointer to a term into which the predicate of the definition
+ is stored if it is found.
+ RETURNS: TRUE if Def contains a definition that can be converted to
+ standard form.
+***********************************************************/
+{
+ BOOL result;
+#ifdef CHECK
+ fol_CheckFatherLinks(Def);
+#endif
+ result = cnf_ContainsDefinitionIntern(Def, Def, 1, FoundPred);
+#ifdef CHECK
+ fol_CheckFatherLinks(Def);
+#endif
+ return result;
+}
+
+
+static TERM cnf_IsDefinition(TERM Def)
+/**********************************************************
+ INPUT: A term Def.
+ RETURNS: The Def term where the arguments of the equivalence are exchanged
+ iff the first one is not a predicate.
+**********************************************************/
+{
+ LIST l,freevars, predicatevars;
+
+#ifdef CHECK
+ if (Def == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_IsDefinition: Empty formula.\n");
+ misc_FinishErrorReport();
+ }
+ if (!symbol_Equal(term_TopSymbol(Def),fol_Equiv())) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_IsDefinition: Formula is no equivalence.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /* If the predicate is the second argument of the equivalence, exchange them */
+ if (!symbol_IsPredicate(term_TopSymbol(term_FirstArgument(Def)))) {
+ TERM arg1;
+ arg1 = term_FirstArgument(Def);
+ term_RplacFirstArgument(Def, term_SecondArgument(Def));
+ term_RplacSecondArgument(Def, arg1);
+ }
+
+
+ /* Check if the first argument is a predicate */
+ if (!symbol_IsPredicate(term_TopSymbol(term_FirstArgument(Def))))
+ return NULL;
+
+ /* Check if first argument is a predicate and not fol_Equality */
+ /* if (!symbol_IsPredicate(term_TopSymbol(term_FirstArgument(Def)))
+ || symbol_Equal(term_TopSymbol(term_FirstArgument(Def)), fol_Equality()))) {
+ return NULL;
+ }*/
+
+
+ /* The free variables of the non-predicate term must occur in the predicate term */
+
+ freevars = fol_FreeVariables(term_SecondArgument(Def));
+ freevars = term_DeleteDuplicatesFromList(freevars);
+ predicatevars = term_ListOfVariables(term_FirstArgument(Def));
+ predicatevars = term_DeleteDuplicatesFromList(predicatevars);
+
+ for (l=predicatevars; !list_Empty(l); l=list_Cdr(l))
+ freevars = list_DeleteElement(freevars, list_Car(l),
+ (BOOL (*)(POINTER,POINTER))term_Equal);
+
+ if (!list_Empty(freevars)) {
+ list_Delete(freevars);
+ list_Delete(predicatevars);
+ return NULL;
+ }
+
+ list_Delete(predicatevars);
+ return term_FirstArgument(Def);
+}
+
+
+static BOOL cnf_ContainsPredicateIntern(TERM Target, SYMBOL Predicate,
+ int Polarity, TERM* TargetPredicate,
+ TERM* ToTopLevel, LIST* TargetVars,
+ LIST* VarsForTopLevel)
+/**********************************************************
+ INPUT: A term (sub--) Target
+ A symbol Predicate which is searched in the target term.
+ The polarity of the subterm.
+ A pointer to the term TargetPredicate into which the found
+ predicate term is stored.
+ A pointer to the list TargetVars into which the variables found
+ in the predicates' arguments are stored.
+ A pointer to a list VarsForTopLevel into which all variables are
+ stored that are all--quantified and can be moved to top level.
+
+ RETURNS: TRUE if Formula contains the predicate for which a definition
+ was found.
+********************************************************/
+{
+ /* AND / OR */
+ /* In these cases the predicate (if it exists) can not be moved to a higher level */
+
+ if ((symbol_Equal(term_TopSymbol(Target),fol_And()) && Polarity == 1) ||
+ (symbol_Equal(term_TopSymbol(Target),fol_Or()) && Polarity == -1) ||
+ (symbol_Equal(term_TopSymbol(Target),fol_Implies()) && Polarity != 1) ||
+ symbol_Equal(term_TopSymbol(Target), fol_Equiv())) {
+ TERM s;
+ LIST l;
+ /* Try to find Predicate in Target */
+ s = term_FindSubterm(Target, Predicate);
+ if (s == NULL)
+ return FALSE;
+
+ /* Store variables found in the predicates arguments */
+ for (l=term_ArgumentList(s); !list_Empty(l); l = list_Cdr(l))
+ *TargetVars = list_Nconc(fol_FreeVariables((TERM) list_Car(l)), *TargetVars);
+ *TargetVars = term_DeleteDuplicatesFromList(*TargetVars);
+ /* Keep found predicate */
+ *TargetPredicate = s;
+ *ToTopLevel = Target;
+ return TRUE;
+ }
+
+ /* AND / OR continued */
+ if (symbol_Equal(term_TopSymbol(Target),fol_And()) || symbol_Equal(term_TopSymbol(Target),fol_Or())) {
+ /* The polarity is ok here */
+ LIST l;
+ for (l=term_ArgumentList(Target); !list_Empty(l); l = list_Cdr(l))
+ if (cnf_ContainsPredicateIntern((TERM) list_Car(l), Predicate, Polarity,
+ TargetPredicate, ToTopLevel, TargetVars,
+ VarsForTopLevel))
+ return TRUE;
+ return FALSE;
+ }
+
+ /* Quantifiers */
+ if (fol_IsQuantifier(term_TopSymbol(Target))) {
+ if (cnf_ContainsPredicateIntern(term_SecondArgument(Target), Predicate,
+ Polarity, TargetPredicate, ToTopLevel,
+ TargetVars, VarsForTopLevel)) {
+ /* Quantifiers for free variables of the predicate should be moved
+ to top level to make the proof easier */
+ if ((symbol_Equal(term_TopSymbol(Target), fol_All()) && Polarity == 1) ||
+ (symbol_Equal(term_TopSymbol(Target), fol_Exist()) && Polarity == -1)) {
+ LIST l;
+ /* Check for all variables found in the predicates arguments */
+ for (l = *TargetVars; !list_Empty(l); l=list_Cdr(l)) {
+ if (term_ListContainsTerm(fol_QuantifierVariables(Target),list_Car(l)))
+ *VarsForTopLevel = list_Cons(list_Car(l), *VarsForTopLevel);
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /* Negation */
+ if (symbol_Equal(term_TopSymbol(Target),fol_Not()))
+ return cnf_ContainsPredicateIntern(term_FirstArgument(Target), Predicate,
+ -Polarity, TargetPredicate, ToTopLevel,
+ TargetVars, VarsForTopLevel);
+ /* Implication */
+ if (symbol_Equal(term_TopSymbol(Target),fol_Implies())) {
+ /* In this case the predicate (if it exists) can be moved to a higher level */
+ if (cnf_ContainsPredicateIntern(term_FirstArgument(Target), Predicate,
+ -Polarity, TargetPredicate, ToTopLevel,
+ TargetVars, VarsForTopLevel))
+ return TRUE;
+ return cnf_ContainsPredicateIntern(term_SecondArgument(Target), Predicate,
+ Polarity, TargetPredicate, ToTopLevel,
+ TargetVars, VarsForTopLevel);
+ }
+
+ /* Found the predicate */
+ if (symbol_Equal(term_TopSymbol(Target), Predicate)) {
+ LIST l;
+ for (l = term_ArgumentList(Target); !list_Empty(l); l = list_Cdr(l))
+ *TargetVars = list_Nconc(fol_FreeVariables((TERM) list_Car(l)), *TargetVars);
+ *TargetVars = term_DeleteDuplicatesFromList(*TargetVars);
+
+ *TargetPredicate = Target;
+ *ToTopLevel = Target;
+ return TRUE;
+ }
+
+ /* In all other cases the predicate was not found */
+ return FALSE;
+}
+
+
+BOOL cnf_ContainsPredicate(TERM Target, SYMBOL Predicate,
+ TERM* TargetPredicate, TERM* ToTopLevel,
+ LIST* TargetVars, LIST* VarsForTopLevel)
+/**********************************************************
+ INPUT: A term Target without implications.
+ A symbol Predicate which is searched in the target term.
+ A pointer to the predicate found in TargetTerm is recorded.
+ A pointer to the term TargetPredicate into which the found
+ predicate term is stored.
+ A pointer to the list TargetVars into which the variables
+ found in the predicates' arguments are stored.
+ A pointer to a list VarsForTopLevel into which all variables
+ are stored that are all--quantified and can be moved to top level.
+ RETURNS: TRUE if Formula contains the predicate for which a definition
+ was found.
+********************************************************/
+{
+ BOOL result;
+#ifdef CHECK
+ fol_CheckFatherLinks(Target);
+#endif
+ result = cnf_ContainsPredicateIntern(Target, Predicate, 1, TargetPredicate,
+ ToTopLevel, TargetVars, VarsForTopLevel);
+#ifdef CHECK
+ fol_CheckFatherLinks(Target);
+#endif
+ return result;
+}
+
+
+static int cnf_PredicateOccurrences(TERM Term, SYMBOL P)
+/****************************************************
+ INPUT: A term and a predicate symbol.
+ RETURNS: The number of occurrences of the predicate symbol in Term
+**************************************************/
+{
+ /* Quantifiers */
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return cnf_PredicateOccurrences(term_SecondArgument(Term), P);
+
+ /* Junctors and NOT */
+ if (fol_IsJunctor(term_TopSymbol(Term)) ||
+ symbol_Equal(term_TopSymbol(Term),fol_Not())) {
+ LIST scan;
+ int count;
+ count = 0;
+ for (scan=term_ArgumentList(Term); !list_Empty(scan); scan=list_Cdr(scan)) {
+ count += cnf_PredicateOccurrences(list_Car(scan), P);
+ /* Only the cases count==1 and count>1 are important */
+ if (count > 1)
+ return count;
+ }
+ return count;
+ }
+
+ if (symbol_Equal(term_TopSymbol(Term), P))
+ return 1;
+ return 0;
+}
+
+
+static TERM cnf_NegationNormalFormulaPath(TERM Term, TERM PredicateTerm)
+/**********************************************************
+ INPUT: A term and a predicate term which is a subterm of term
+ RETURNS: The negation normal form of the term along the path.
+ CAUTION: The term is destructively changed.
+ This works only if the superterm member of Term and its subterms
+ are set.
+********************************************************/
+{
+ TERM subterm, termL, term1;
+ LIST scan;
+ SYMBOL symbol;
+ BOOL set;
+
+ term1 = Term;
+ while (term1 != NULL) {
+ set = FALSE;
+ if (symbol_Equal(term_TopSymbol(term1),fol_Not())) {
+ subterm = term_FirstArgument(term1);
+ if (symbol_Equal(term_TopSymbol(subterm),fol_Not())) {
+ LIST l;
+ term_RplacTop(term1,term_TopSymbol(term_FirstArgument(subterm)));
+ list_Delete(term_ArgumentList(term1));
+ term_RplacArgumentList(term1,term_ArgumentList(term_FirstArgument(subterm)));
+ term_Free(term_FirstArgument(subterm));
+ list_Delete(term_ArgumentList(subterm));
+ term_Free(subterm);
+ /* Set superterm member to new superterm */
+ for (l=term_ArgumentList(term1); !list_Empty(l); l=list_Cdr(l))
+ term_RplacSuperterm(list_Car(l), term1);
+ /* term1 weiter betrachten */
+ set = TRUE;
+ }
+ else {
+ if (fol_IsQuantifier(term_TopSymbol(subterm))) {
+ LIST l;
+ symbol = (SYMBOL)cnf_GetDualSymbol(term_TopSymbol(subterm));
+ termL = term_CreateAddFather(fol_Not(),
+ list_List(term_SecondArgument(subterm)));
+ list_RplacSecond(term_ArgumentList(subterm), termL);
+ term_RplacSuperterm(termL, subterm);
+ term_RplacTop(term1,symbol);
+ list_Delete(term_ArgumentList(term1));
+ term_RplacArgumentList(term1, term_ArgumentList(subterm));
+ for (l=term_ArgumentList(term1); !list_Empty(l); l = list_Cdr(l))
+ term_RplacSuperterm(list_Car(l), term1);
+ term_RplacArgumentList(subterm, list_Nil());
+ term_Delete(subterm);
+ term1 = termL;
+ /* Next term to check is not(subterm) */
+ set = TRUE;
+ }
+ else {
+ if (symbol_Equal(term_TopSymbol(subterm),fol_Or()) ||
+ (symbol_Equal(term_TopSymbol(subterm),fol_And()))) {
+ LIST l;
+ symbol = (SYMBOL)cnf_GetDualSymbol(term_TopSymbol(subterm));
+ for (scan = term_ArgumentList(subterm); !list_Empty(scan);
+ scan = list_Cdr(scan)) {
+ TERM new;
+ termL = list_Car(scan);
+ new = term_CreateAddFather(fol_Not(),list_List(termL));
+ list_Rplaca(scan, new);
+ term_RplacSuperterm(new, subterm);
+ }
+ term_RplacTop(term1,symbol);
+ list_Delete(term_ArgumentList(term1));
+ term_RplacArgumentList(term1,term_ArgumentList(subterm));
+ for (l = term_ArgumentList(term1); !list_Empty(l); l=list_Cdr(l))
+ term_RplacSuperterm(list_Car(l), term1);
+ term_RplacArgumentList(subterm, list_Nil());
+ term_Delete(subterm);
+ }
+ }
+ }
+ }
+ if (!set) {
+ if (!list_Empty(term_ArgumentList(term1)))
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+ if (term_HasProperSuperterm(PredicateTerm, list_Car(scan))) {
+ term1 = list_Car(scan);
+ set = TRUE;
+ break;
+ }
+ if (!set)
+ term1 = NULL;
+ }
+ }
+ return Term;
+}
+
+
+TERM cnf_ApplyDefinitionOnce(TERM Predicate, TERM Formula, TERM TargetTerm,
+ TERM TargetPredicate, FLAGSTORE Flags)
+/*********************************************************
+ INPUT: A term Predicate which is a predicate found in a definition.
+ A term Formula which is a term equivalent to the predicate.
+ A term TargetTerm in which one occurrence of the predicate may be
+ replaced by the Formula.
+ A term TargetPredicate which is the subterm of the TargetTerm
+ to be replaced.
+ A flag store.
+ RETURNS: The changed TargetTerm.
+*************************************************************/
+{
+ SYMBOL maxvar, maxvar_temp;
+ LIST bound, scan;
+ BOOL success;
+
+ /* Init varcounter */
+ maxvar = term_MaxVar(TargetTerm);
+ maxvar_temp = term_MaxVar(Formula);
+ if (maxvar_temp > maxvar)
+ maxvar = maxvar_temp;
+ symbol_SetStandardVarCounter(maxvar);
+
+ /* Find bound variables in formula for renaming them */
+ bound = fol_BoundVariables(Formula);
+ for (scan=bound; !list_Empty(scan); scan=list_Cdr(scan)) {
+ /* Bound variable in definition is already used in term */
+ if (term_ContainsSymbol(TargetTerm, term_TopSymbol(list_Car(scan))))
+ term_ExchangeVariable(Formula, term_TopSymbol(list_Car(scan)),
+ symbol_CreateStandardVariable());
+ }
+ list_Delete(bound);
+ TargetTerm = cnf_ApplyDefinitionInternOnce(Predicate, Formula, TargetTerm,
+ TargetPredicate,&success);
+ if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+ if (success) {
+ fputs("\nTarget after applying def:\n", stdout);
+ fol_PrettyPrint(TargetTerm);
+ puts("\n");
+ }
+ }
+
+ return TargetTerm;
+}
+
+
+static TERM cnf_ApplyDefinitionInternOnce(TERM Predicate, TERM Formula,
+ TERM TargetTerm, TERM TargetPredicate,
+ BOOL* Success)
+/**********************************************************
+ INPUT: A term Predicate which is equivalence to
+ Formula and Term
+ RETURNS: The term in which all occurrences of P(..) are
+ replaced by Formula modulo the proper bindings
+ CAUTION: Term is destructively changed!
+***********************************************************/
+{
+ /* Quantifiers */
+ if (fol_IsQuantifier(term_TopSymbol(TargetTerm))) {
+ term_RplacSecondArgument(TargetTerm,
+ cnf_ApplyDefinitionInternOnce(Predicate, Formula,
+ term_SecondArgument(TargetTerm),
+ TargetPredicate, Success));
+ term_RplacSuperterm(term_SecondArgument(TargetTerm), TargetTerm);
+ return TargetTerm;
+ }
+
+ /* Junctors and NOT */
+ if (fol_IsJunctor(term_TopSymbol(TargetTerm)) ||
+ symbol_Equal(term_TopSymbol(TargetTerm),fol_Not())) {
+ LIST scan;
+ for (scan=term_ArgumentList(TargetTerm); !list_Empty(scan); scan=list_Cdr(scan)) {
+ list_Rplaca(scan, cnf_ApplyDefinitionInternOnce(Predicate, Formula,
+ list_Car(scan),
+ TargetPredicate, Success));
+ term_RplacSuperterm((TERM) list_Car(scan), TargetTerm);
+ }
+ return TargetTerm;
+ }
+
+ if (symbol_Equal(term_TopSymbol(TargetTerm), term_TopSymbol(Predicate))) {
+ if (TargetTerm == TargetPredicate) {
+ TERM result;
+ result = Formula;
+ cnf_RplacVar(result, term_ArgumentList(Predicate),
+ term_ArgumentList(TargetTerm));
+ term_AddFatherLinks(result);
+ term_Delete(TargetTerm);
+ *Success = TRUE;
+ return result;
+ }
+ }
+
+ return TargetTerm;
+}
+
+
+static TERM cnf_RemoveEquivImplFromFormula(TERM term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: The term with replaced implications and equivalences.
+ CAUTION: The term is destructively changed.
+********************************************************/
+{
+ TERM term1,termL,termR,termLneg,termRneg;
+ LIST scan;
+ int bottom,pol;
+
+ bottom = vec_ActMax();
+ vec_Push(term);
+
+ while (bottom != vec_ActMax()) {
+ term1 = (TERM)vec_PopResult();
+ if (symbol_Equal(term_TopSymbol(term1),fol_Implies())) {
+ term_RplacTop(term1, fol_Or());
+ list_Rplaca(term_ArgumentList(term1),
+ term_Create(fol_Not(), list_List(list_Car(term_ArgumentList(term1)))));
+ }else
+ if (symbol_Equal(term_TopSymbol(term1),fol_Equiv())) {
+ pol = cnf_GetFormulaPolarity(term,term1);
+ termL = (TERM)list_Car(term_ArgumentList(term1));
+ termR = (TERM)list_Second(term_ArgumentList(term1));
+ termLneg = term_Create(fol_Not(),list_List(term_Copy(termL)));
+ termRneg = term_Create(fol_Not(),list_List(term_Copy(termR)));
+ if (pol == 1 || pol == 0) {
+ term_RplacTop(term1, fol_And());
+ list_Rplaca(term_ArgumentList(term1), term_Create(fol_Or(),list_Cons(termLneg,list_List(termR))));
+ list_RplacSecond(term_ArgumentList(term1),term_Create(fol_Or(),list_Cons(termRneg,list_List(termL))));
+ }else
+ if (pol == -1) {
+ term_RplacTop(term1, fol_Or());
+ list_Rplaca(term_ArgumentList(term1), term_Create(fol_And(),list_Cons(termLneg,list_List(termRneg))));
+ list_RplacSecond(term_ArgumentList(term1), term_Create(fol_And(),list_Cons(termL,list_List(termR))));
+ }
+ }
+ if (!list_Empty(term_ArgumentList(term1)))
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+ vec_Push(list_Car(scan));
+ }
+ vec_SetMax(bottom);
+ return term;
+}
+
+
+static TERM cnf_MovePredicateVariablesUp(TERM Term, TERM TargetPredicateTerm,
+ LIST VarsForTopLevel)
+/**********************************************************
+ INPUT: A term and a predicate term which is a subterm of term
+ an equivalence.
+ RETURNS: The term where the free variables of the equivalence, which
+ must be allquantified and not in the scope of an
+ exist quantifier, are moved to toplevel.
+ CAUTION: The term is destructively changed.
+********************************************************/
+{
+ TERM term1;
+ LIST scan;
+ int bottom;
+
+ bottom = vec_ActMax();
+ vec_Push(Term);
+
+ while (bottom != vec_ActMax()) {
+ term1 = (TERM)vec_PopResult();
+ if (!list_Empty(term_ArgumentList(term1)))
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan)) {
+ TERM arg;
+ arg = (TERM) list_Car(scan);
+ if (term_HasProperSuperterm(TargetPredicateTerm, arg)) {
+ if (symbol_Equal(term_TopSymbol(arg), fol_All())) {
+ LIST predicatevarscan, quantifiervars;
+ quantifiervars = fol_QuantifierVariables(arg);
+ for (predicatevarscan=VarsForTopLevel; !list_Empty(predicatevarscan);
+ predicatevarscan = list_Cdr(predicatevarscan))
+ quantifiervars = list_DeleteElementFree(quantifiervars,
+ (TERM) list_Car(predicatevarscan),
+ (BOOL (*)(POINTER,POINTER))term_Equal,
+ (void (*)(POINTER))term_Delete);
+ if (!list_Empty(quantifiervars))
+ term_RplacArgumentList(term_FirstArgument(arg), quantifiervars);
+ else {
+ TERM subterm;
+ subterm = term_SecondArgument(arg);
+ term_Free(term_FirstArgument(arg));
+ list_Delete(term_ArgumentList(arg));
+ term_Free(arg);
+ list_Rplaca(scan, subterm);
+ term_RplacSuperterm(subterm, term1);
+ }
+ }
+ vec_Push((TERM) list_Car(scan));
+ }
+ }
+ }
+
+ for (scan=VarsForTopLevel; !list_Empty(scan); scan = list_Cdr(scan))
+ list_Rplaca(scan, term_Copy((TERM) list_Car(scan)));
+ if (symbol_Equal(term_TopSymbol(Term), fol_All())) {
+ LIST vars;
+ vars = fol_QuantifierVariables(Term);
+ vars = list_Nconc(vars, list_Copy(VarsForTopLevel));
+ vars = term_DestroyDuplicatesInList(vars);
+ term_RplacArgumentList(term_FirstArgument(Term), vars);
+ }
+ else {
+ TERM newtop;
+ newtop = fol_CreateQuantifier(fol_All(), list_Copy(VarsForTopLevel), list_List(Term));
+ term_RplacSuperterm(Term, newtop);
+ Term = newtop;
+ }
+ vec_SetMax(bottom);
+ return Term;
+}
+
+
+static TERM cnf_RemoveImplFromFormulaPath(TERM Term, TERM PredicateTerm)
+/**********************************************************
+ INPUT: A term and a predicate term which is a subterm of term
+ RETURNS: The term where implications along the path to PredicateTerm
+ are replaced.
+ CAUTION: The term is destructively changed.
+ This works only if the superterm member of Term and its
+ subterms are set.
+********************************************************/
+{
+ TERM term1;
+ LIST scan;
+ int bottom;
+
+ bottom = vec_ActMax();
+ vec_Push(Term);
+
+ while (bottom != vec_ActMax()) {
+ term1 = (TERM)vec_PopResult();
+ if (term_HasProperSuperterm(PredicateTerm, term1)) {
+ if (symbol_Equal(term_TopSymbol(term1),fol_Implies())) {
+ TERM newterm;
+ term_RplacTop(term1, fol_Or());
+ newterm = term_CreateAddFather(fol_Not(), list_List(list_Car(term_ArgumentList(term1))));
+ list_Rplaca(term_ArgumentList(term1), newterm);
+ term_RplacSuperterm(newterm, term1);
+ }
+
+ if (!list_Empty(term_ArgumentList(term1)))
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+ vec_Push(list_Car(scan));
+ }
+ }
+ vec_SetMax(bottom);
+ return Term;
+}
+
+
+static SYMBOL cnf_GetDualSymbol(SYMBOL symbol)
+/********************************************************
+ INPUT: A predefined symbol.
+ RETURNS: The dual symbol.
+********************************************************/
+{
+ SYMBOL dual;
+
+ dual = symbol;
+ if (symbol_Equal(symbol,fol_All()))
+ dual = fol_Exist();
+ else
+ if (symbol_Equal(symbol,fol_Exist()))
+ dual = fol_All();
+ else
+ if (symbol_Equal(symbol,fol_Or()))
+ dual = fol_And();
+ else
+ if (symbol_Equal(symbol,fol_And()))
+ dual = fol_Or();
+ return dual;
+}
+
+
+TERM cnf_NegationNormalFormula(TERM term)
+/********************************************************
+ INPUT: A term.
+ RETURNS: The negation normal form of the term.
+ CAUTION: The term is destructively changed.
+********************************************************/
+{
+ TERM term1,subterm,termL;
+ LIST scan;
+ SYMBOL symbol;
+ int bottom;
+
+ bottom = vec_ActMax();
+ vec_Push(term);
+
+ while (bottom != vec_ActMax()) {
+ term1 = (TERM)vec_PopResult();
+ if (symbol_Equal(term_TopSymbol(term1),fol_Not())) {
+ subterm = (TERM)list_Car(term_ArgumentList(term1));
+ if (symbol_Equal(term_TopSymbol(subterm),fol_Not())) {
+ term_RplacTop(term1,term_TopSymbol(term_FirstArgument(subterm)));
+ list_Delete(term_ArgumentList(term1));
+ term_RplacArgumentList(term1,term_ArgumentList(term_FirstArgument(subterm)));
+ term_Free(term_FirstArgument(subterm));
+ list_Delete(term_ArgumentList(subterm));
+ term_Free(subterm);
+ vec_Push(term1);
+ }else
+ if (fol_IsQuantifier(term_TopSymbol(subterm))) {
+ symbol = (SYMBOL)cnf_GetDualSymbol(term_TopSymbol(subterm));
+ termL = term_Create(fol_Not(),
+ list_List(term_SecondArgument(subterm)));
+ list_RplacSecond(term_ArgumentList(subterm), termL);
+ term_RplacTop(term1,symbol);
+ list_Delete(term_ArgumentList(term1));
+ term_RplacArgumentList(term1,term_CopyTermList(term_ArgumentList(subterm)));
+ term_Delete(subterm);
+ } else
+ if (symbol_Equal(term_TopSymbol(subterm),fol_Or()) ||
+ symbol_Equal(term_TopSymbol(subterm),fol_And())) {
+ symbol = (SYMBOL)cnf_GetDualSymbol(term_TopSymbol(subterm));
+ for (scan = term_ArgumentList(subterm);
+ !list_Empty(scan);
+ scan = list_Cdr(scan)) {
+ termL = (TERM)list_Car(scan);
+ list_Rplaca(scan, term_Create(fol_Not(),list_List(termL)));
+ }
+ term_RplacTop(term1,symbol);
+ list_Delete(term_ArgumentList(term1));
+ term_RplacArgumentList(term1,term_CopyTermList(term_ArgumentList(subterm)));
+ term_Delete(subterm);
+ }
+ }
+ if (!list_Empty(term_ArgumentList(term1)))
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+ vec_Push(list_Car(scan));
+ }
+ vec_SetMax(bottom);
+ return term;
+}
+
+
+static TERM cnf_QuantMakeOneVar(TERM term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: The term where all quantifiers quantify over only one variable.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ TERM term1,termL;
+ SYMBOL quantor;
+ LIST scan,varlist;
+ int bottom;
+
+ bottom = vec_ActMax();
+ vec_Push(term);
+
+ while (bottom != vec_ActMax()) {
+ term1 = (TERM)vec_PopResult();
+ if (fol_IsQuantifier(term_TopSymbol(term1))) {
+ quantor = term_TopSymbol(term1);
+ if (list_Length(term_ArgumentList(term_FirstArgument(term1))) > 1) {
+ varlist =
+ list_Copy(list_Cdr(term_ArgumentList(term_FirstArgument(term1))));
+ for (scan=varlist;!list_Empty(scan);scan=list_Cdr(scan)) {
+ termL = term_SecondArgument(term1);
+ term_RplacSecondArgument(term1, fol_CreateQuantifier(quantor,list_List(list_Car(scan)),list_List(termL)));
+ }
+ for (scan=varlist;!list_Empty(scan);scan=list_Cdr(scan)) {
+ term_RplacArgumentList(term_FirstArgument(term1),
+ list_PointerDeleteElement(term_ArgumentList(term_FirstArgument(term1)),list_Car(scan)));
+ }
+ list_Delete(varlist);
+ }
+ }
+ if (!list_Empty(term_ArgumentList(term1)))
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+ vec_Push(list_Car(scan));
+ }
+ vec_SetMax(bottom);
+ return term;
+}
+
+
+static LIST cnf_GetSymbolList(LIST varlist)
+/**************************************************************
+ INPUT: A list of variables
+ RETURNS: The list of the symbols of the variables.
+***************************************************************/
+{
+ LIST scan,result;
+
+ result = list_Nil();
+ for (scan=varlist;!list_Empty(scan);scan=list_Cdr(scan))
+ result = list_Cons((POINTER)term_TopSymbol((TERM)list_Car(scan)),result);
+
+ return result;
+}
+
+
+static BOOL cnf_TopIsAnd(LIST termlist)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: True if one term in termlist is a conjunction.
+***************************************************************/
+{
+ LIST scan;
+
+ for (scan=termlist;!list_Empty(scan);scan=list_Cdr(scan))
+ if (term_TopSymbol(list_Car(scan)) == fol_And())
+ return TRUE;
+ return FALSE;
+}
+
+
+static TERM cnf_MakeOneOr(TERM term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Takes all arguments of an or together.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+
+ LIST scan;
+
+ if (symbol_Equal(term_TopSymbol(term),fol_Or())) {
+ TERM argterm;
+ scan=term_ArgumentList(term);
+ while (!list_Empty(scan)) {
+ argterm = (TERM)list_Car(scan);
+ cnf_MakeOneOr(argterm);
+ if (symbol_Equal(term_TopSymbol(argterm),fol_Or())) {
+ scan = list_Cdr(scan);
+ term_RplacArgumentList(term,
+ list_Nconc(term_ArgumentList(argterm),list_PointerDeleteElement(term_ArgumentList(term),argterm)));
+ term_Free(argterm);
+ }
+ else
+ scan = list_Cdr(scan);
+ }
+ } else if (!symbol_IsPredicate(term_TopSymbol(term)))
+ for (scan=term_ArgumentList(term);!list_Empty(scan);scan=list_Cdr(scan))
+ cnf_MakeOneOr(list_Car(scan));
+
+ return term;
+}
+
+
+static TERM cnf_MakeOneOrPredicate(TERM term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Takes all predicates and negated predicates as arguments
+ of an or together.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+
+ LIST scan,scan1,predlist;
+
+ if (cnf_TopIsAnd(term_ArgumentList(term))) {
+
+ for (scan1=term_ArgumentList(term);
+ !(list_Empty(scan1) || symbol_Equal(term_TopSymbol(list_Car(scan1)),fol_And()));
+ scan1=list_Cdr(scan1));
+
+ if (!list_Empty(scan1)) {
+ predlist = list_Nil();
+ for (scan=scan1; !list_Empty(scan); scan=list_Cdr(scan)) {
+ if (symbol_IsPredicate(term_TopSymbol(list_Car(scan))) ||
+ fol_IsNegativeLiteral(list_Car(scan))) {
+ predlist = list_Cons(list_Car(scan),predlist);
+ }
+ }
+ for (scan=predlist;!list_Empty(scan);scan=list_Cdr(scan))
+ term_RplacArgumentList(term,
+ list_PointerDeleteElement(term_ArgumentList(term),list_Car(scan)));
+
+ if (!list_Empty(predlist))
+ term_RplacArgumentList(term, list_Nconc(predlist,term_ArgumentList(term)));
+ }
+ }
+ return term;
+}
+
+
+static TERM cnf_MakeOneOrTerm(TERM term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Takes all predicates as arguments of an or together.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ return cnf_MakeOneOrPredicate(cnf_MakeOneOr(term));
+}
+
+
+static TERM cnf_MakeOneAnd(TERM term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Takes all arguments of an and together.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ LIST scan;
+
+ if (symbol_Equal(term_TopSymbol(term),fol_And())) {
+ TERM argterm;
+ scan=term_ArgumentList(term);
+ while (!list_Empty(scan)) {
+ argterm = (TERM)list_Car(scan);
+ cnf_MakeOneAnd(argterm);
+ if (symbol_Equal(term_TopSymbol(argterm),fol_And())) {
+ scan = list_Cdr(scan);
+ term_RplacArgumentList(term,
+ list_Nconc(term_ArgumentList(argterm),list_PointerDeleteElement(term_ArgumentList(term),argterm)));
+ term_Free(argterm);
+ }
+ else
+ scan = list_Cdr(scan);
+ }
+ } else if (!symbol_IsPredicate(term_TopSymbol(term)))
+ for (scan=term_ArgumentList(term);!list_Empty(scan);scan=list_Cdr(scan))
+ cnf_MakeOneAnd(list_Car(scan));
+
+ return term;
+}
+
+
+static TERM cnf_MakeOneAndPredicate(TERM term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Takes all predicates as arguments of one or together.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ LIST scan,scan1,predlist;
+
+ for (scan1=term_ArgumentList(term);
+ !(list_Empty(scan1) || symbol_Equal(term_TopSymbol(list_Car(scan1)),fol_Or()));
+ scan1=list_Cdr(scan1));
+
+ if (!list_Empty(scan1)) {
+ /* The car of scan1 points to a term with topsymbol 'or' */
+ predlist = list_Nil();
+ for (scan=scan1; !list_Empty(scan); scan=list_Cdr(scan)) {
+ if (symbol_IsPredicate(term_TopSymbol(list_Car(scan))) &&
+ fol_IsNegativeLiteral(list_Car(scan))) {
+ predlist = list_Cons(list_Car(scan),predlist);
+ }
+ }
+ for (scan=predlist; !list_Empty(scan); scan=list_Cdr(scan))
+ term_RplacArgumentList(term, list_PointerDeleteElement(term_ArgumentList(term),list_Car(scan)));
+
+ if (!list_Empty(predlist))
+ term_RplacArgumentList(term, list_Nconc(predlist,term_ArgumentList(term)));
+ }
+ return term;
+}
+
+
+static TERM cnf_MakeOneAndTerm(TERM term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Takes all predicates as arguments of an or together.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ return cnf_MakeOneAndPredicate(cnf_MakeOneAnd(term));
+}
+
+
+LIST cnf_ComputeLiteralLists(TERM Term)
+/**********************************************************
+ INPUT: A term in negation normal form without quantifiers.
+ RETURNS: The list of all literal lists corresponding to the
+ CNF of Term.
+***********************************************************/
+{
+ LIST Scan, Scan1, Scan2, Help, Result, List1, List2, NewResult;
+ SYMBOL Symbol;
+
+ Symbol = term_TopSymbol(Term);
+ Result = list_Nil();
+
+ if (symbol_Equal(Symbol,fol_Or())) {
+ Result = cnf_ComputeLiteralLists(list_Car(term_ArgumentList(Term)));
+ for (Scan=list_Cdr(term_ArgumentList(Term));!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Help = cnf_ComputeLiteralLists(list_Car(Scan));
+ NewResult = list_Nil();
+ for (Scan1=Help;!list_Empty(Scan1);Scan1=list_Cdr(Scan1))
+ for (Scan2=Result;!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) {
+ List1 = list_Car(Scan1);
+ List2 = list_Car(Scan2);
+ if (!list_Empty(list_Cdr(Scan2)))
+ List1 = term_CopyTermList(List1);
+ if (!list_Empty(list_Cdr(Scan1)))
+ List2 = term_CopyTermList(List2);
+ NewResult = list_Cons(term_DestroyDuplicatesInList(list_Nconc(List1,List2)),
+ NewResult);
+ }
+ list_Delete(Help);
+ list_Delete(Result);
+ Result = NewResult;
+ }
+ return Result;
+ }
+
+ if (symbol_Equal(Symbol,fol_And())) {
+ Result = cnf_ComputeLiteralLists(list_Car(term_ArgumentList(Term)));
+ for (Scan=list_Cdr(term_ArgumentList(Term));!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Result = list_Nconc(cnf_ComputeLiteralLists(list_Car(Scan)), Result);
+ }
+ return Result;
+ }
+
+ if (symbol_Equal(Symbol,fol_Not()) || symbol_IsPredicate(Symbol))
+ return list_List(list_List(term_Copy(Term)));
+
+
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_ComputeLiteralLists: Unexpected junctor in input Formula!\n");
+ misc_FinishErrorReport();
+
+ return Result;
+}
+
+
+static TERM cnf_DistributiveFormula(TERM Formula)
+/**************************************************************
+ INPUT: A Formula in NNF which consists only of disjunctions and
+ conjunctions.
+ RETURNS: The Formula where the distributivity rule is exhaustively applied
+ and all disjunctions and the top level conjunction are grouped.
+ CAUTION: The Formula is destructively changed.
+***************************************************************/
+{
+ TERM Result;
+ LIST Scan, Lists;
+
+ Lists = cnf_ComputeLiteralLists(Formula);
+
+ for (Scan= Lists; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ list_Rplaca(Scan,term_Create(fol_Or(), list_Car(Scan)));
+
+ Result = term_Create(fol_And(), Lists);
+ term_Delete(Formula);
+
+ return Result;
+}
+
+
+
+void cnf_FPrintClause(TERM term, FILE* file)
+/**************************************************************
+ INPUT: A term and a file pointer.
+ RETURNS: Nothing.
+ EFFECT: Print the term which contains only disjunctions to file.
+ The disjunctions represent a clause.
+***************************************************************/
+{
+
+ TERM term1;
+ LIST scan;
+ int bottom;
+
+ bottom = vec_ActMax();
+ vec_Push(term);
+
+ while (bottom != vec_ActMax()) {
+ term1 = (TERM)vec_PopResult();
+ if (symbol_Equal(term_TopSymbol(term1),fol_Or())) {
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+ vec_Push(list_Car(scan));
+ }else
+ term_FPrint(file,term1);
+ }
+ fputs(".\n", file);
+ vec_SetMax(bottom);
+}
+
+
+void cnf_FPrint(TERM term, FILE* file)
+/**************************************************************
+ INPUT: A term and a file pointer.
+ RETURNS: Nothing.
+ EFFECT: Print the term (in negation normal form)
+ which contains only conjunctions of
+ disjunctions to file. The conjunctions are interpreted
+ to represent different clauses.
+***************************************************************/
+{
+ TERM term1;
+ LIST scan;
+ int bottom;
+
+ bottom = vec_ActMax();
+ vec_Push(term);
+
+ while (bottom != vec_ActMax()) {
+ term1 = (TERM)vec_PopResult();
+ if (symbol_Equal(term_TopSymbol(term1),fol_And())) {
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+ vec_Push(list_Car(scan));
+ }else
+ if (symbol_Equal(term_TopSymbol(term1),fol_Or()) ||
+ symbol_IsPredicate(term_TopSymbol(term1)) ||
+ symbol_Equal(term_TopSymbol(term1),fol_Not()))
+ cnf_FPrintClause(term1,file);
+ }
+ vec_SetMax(bottom);
+}
+
+
+void cnf_StdoutPrint(TERM term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Nothing.
+ EFFECT: Print the term (in negation normal form)
+ which contains only conjunctions of
+ disjunctions to standard out. The conjunctions are interpreted
+ to represent different clauses.
+***************************************************************/
+{
+ LIST termlist,scan,scan1;
+
+ for (scan=term_ArgumentList(term); !list_Empty(scan); scan=list_Cdr(scan)) {
+ termlist = list_Nil();
+ if (!(symbol_IsPredicate(term_TopSymbol(list_Car(scan))) ||
+ fol_IsNegativeLiteral(list_Car(scan))))
+ termlist = term_ArgumentList(list_Car(scan));
+
+ if (!list_Empty(termlist)) {
+ for (scan1=termlist;!list_Empty(scan1);scan1=list_Cdr(scan1))
+ term_Print(list_Car(scan1));
+ puts(".");
+ }else{
+ term_Print(list_Car(scan));
+ puts(".");
+ }
+ }
+}
+
+
+void cnf_FilePrint(TERM term, FILE* file)
+/**************************************************************
+ INPUT: A term and a file.
+ RETURNS: Nothing.
+ EFFECT: Print the term (in negation normal form)
+ which contains only conjunctions of
+ disjunctions to file. The conjunctions are interpreted
+ to represent different clauses.
+***************************************************************/
+{
+ LIST termlist,scan,scan1;
+
+ for (scan=term_ArgumentList(term); !list_Empty(scan); scan=list_Cdr(scan)) {
+ termlist = list_Nil();
+ if (!(symbol_IsPredicate(term_TopSymbol(list_Car(scan))) ||
+ fol_IsNegativeLiteral(list_Car(scan))))
+ termlist = term_ArgumentList(list_Car(scan));
+
+ if (!list_Empty(termlist)) {
+ for (scan1=termlist;!list_Empty(scan1);scan1=list_Cdr(scan1))
+ term_FPrint(file,list_Car(scan1));
+ fputs(".\n", file);
+ }else{
+ term_FPrint(file,list_Car(scan));
+ fputs(".\n", file);
+ }
+ }
+
+}
+
+
+void cnf_FilePrintPrefix(TERM term, FILE* file)
+/**************************************************************
+ INPUT: A term and a file pointer.
+ RETURNS: Nothing.
+ EFFECT: Prefix Print the term (in negation normal form)
+ which contains only conjunctions of
+ disjunctions to file. The conjunctions are interpreted
+ to represent different clauses.
+***************************************************************/
+{
+ LIST termlist,scan,scan1;
+
+ for (scan=term_ArgumentList(term);!list_Empty(scan);scan=list_Cdr(scan)) {
+ termlist = list_Nil();
+ if (!(symbol_IsPredicate(term_TopSymbol(list_Car(scan))) ||
+ fol_IsNegativeLiteral(list_Car(scan))))
+ termlist = term_ArgumentList(list_Car(scan));
+
+ if (!list_Empty(termlist)) {
+ for (scan1=termlist;!list_Empty(scan1);scan1=list_Cdr(scan1)) {
+ term_FPrintPrefix(file,list_Car(scan1));
+ if (!list_Empty(list_Cdr(scan1)))
+ fputs(" | ", file);
+ }
+ fputs(".\n", file);
+ } else {
+ term_FPrintPrefix(file,list_Car(scan));
+ fputs(".\n", file);
+ }
+ }
+}
+
+
+static LIST cnf_SubsumeClauseList(LIST clauselist)
+/**********************************************************
+ INPUT: A list of clauses.
+ RETURNS: The list of clauses without subsumed clauses.
+ CAUTION: The list is destructively changed.
+***********************************************************/
+{
+ LIST scan,result;
+ st_INDEX stindex;
+ CLAUSE actclause;
+
+ stindex = st_IndexCreate();
+ result = list_Nil();
+
+ for (scan = clauselist; !list_Empty(scan); scan=list_Cdr(scan))
+ res_InsertClauseIndex(list_Car(scan),stindex);
+
+ for (scan=clauselist; !list_Empty(scan); scan=list_Cdr(scan)) {
+ actclause = list_Car(scan);
+ res_DeleteClauseIndex(actclause,stindex);
+ if (!res_BackSubWithLength(actclause,stindex)) {
+ res_InsertClauseIndex(actclause,stindex);
+ result = list_Cons(actclause,result);
+ }
+ }
+ if (list_Length(result) != list_Length(clauselist)) {
+ for (scan = result; !list_Empty(scan); scan=list_Cdr(scan))
+ clauselist = list_PointerDeleteElement(clauselist,list_Car(scan));
+ if (!list_Empty(result))
+ clause_DeleteClauseList(clauselist);
+ }else
+ list_Delete(clauselist);
+ st_IndexDelete(stindex);
+ return result;
+}
+
+
+static LIST cnf_MakeClauseList(TERM term, BOOL Sorts, BOOL Conclause,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A term in cnf and two boolean values indicating
+ whether sorts should be generated and whether the
+ generated clauses are Conclauses, a flag store and
+ a precedence.
+ RETURNS: A list of clauses with respect to term. The terms
+ in the new clauses are the copied subterms from term.
+ EFFECT: The flag store and the precedence are not changed,
+ but they're needed for creating clauses.
+***************************************************************/
+{
+ LIST termlist,scan,clauselist,newclauselist,delclauselist,condlist;
+ CLAUSE clause;
+ int j;
+
+ termlist = list_Nil();
+ clauselist = list_Nil();
+
+ if (fol_IsTrue(term))
+ return clauselist;
+
+ if (fol_IsNegativeLiteral(term) || symbol_IsPredicate(term_TopSymbol(term))) {
+ termlist = list_List(term_Copy(term));
+ clause = clause_CreateFromLiterals(termlist, Sorts, Conclause,TRUE,
+ Flags, Precedence);
+ clauselist = list_Nconc(clauselist,list_List(clause));
+ term_StartMinRenaming();
+ term_Rename(clause_GetLiteralTerm(clause,0));
+ list_Delete(termlist);
+ return clauselist;
+ }
+
+ delclauselist = list_Nil();
+ term = cnf_MakeOneAndTerm(term);
+ if (symbol_Equal(term_TopSymbol(term), fol_And())) {
+ for (scan=term_ArgumentList(term); !list_Empty(scan); scan=list_Cdr(scan)) {
+ list_Rplaca(scan, cnf_MakeOneOrTerm(list_Car(scan)));
+ termlist = list_Nil();
+ if (!(symbol_IsPredicate(term_TopSymbol(list_Car(scan))) ||
+ fol_IsNegativeLiteral(list_Car(scan)))) {
+ termlist = term_CopyTermList(term_ArgumentList(list_Car(scan)));
+ termlist = term_DestroyDuplicatesInList(termlist);
+ } else
+ termlist = list_List(term_Copy(list_Car(scan)));
+
+ if (!list_Empty(termlist)) {
+ clause = clause_CreateFromLiterals(termlist, Sorts, Conclause, TRUE,
+ Flags, Precedence);
+ term_StartMinRenaming();
+ for (j = 0; j < clause_Length(clause); j++)
+ term_Rename(clause_GetLiteralTerm(clause,j));
+ clauselist = list_Cons(clause,clauselist);
+ list_Delete(termlist);
+ }
+ }
+ } else {
+ /* Here the term is a disjunction, i.e. there is only one clause */
+ term = cnf_MakeOneOrTerm(term);
+ if (!(symbol_IsPredicate(term_TopSymbol(term)) ||
+ fol_IsNegativeLiteral(term))) {
+ termlist = term_CopyTermList(term_ArgumentList(term));
+ termlist = term_DestroyDuplicatesInList(termlist);
+ } else
+ termlist = list_List(term_Copy(term));
+
+ if (!list_Empty(termlist)) {
+ clause = clause_CreateFromLiterals(termlist, Sorts, Conclause, TRUE,
+ Flags, Precedence);
+ term_StartMinRenaming();
+ for (j = 0; j < clause_Length(clause); j++)
+ term_Rename(clause_GetLiteralTerm(clause,j));
+ clauselist = list_Cons(clause,clauselist);
+ list_Delete(termlist);
+ }
+ }
+
+ for (scan=clauselist; !list_Empty(scan); scan=list_Cdr(scan)) {
+ condlist = cond_CondFast(list_Car(scan));
+ if (!list_Empty(condlist))
+ clause_DeleteLiterals(list_Car(scan), condlist, Flags, Precedence);
+ list_Delete(condlist);
+ }
+ clauselist = cnf_SubsumeClauseList(clauselist);
+ newclauselist = list_Nil();
+ while (!list_Empty(clauselist)) {
+ clause = res_SelectLightestClause(clauselist);
+ newclauselist = list_Nconc(newclauselist,list_List(clause));
+ clauselist = list_PointerDeleteElement(clauselist,clause);
+ }
+ list_Delete(clauselist);
+ for (scan=newclauselist; !list_Empty(scan); scan=list_Cdr(scan)) {
+ if (res_HasTautology(list_Car(scan)))
+ delclauselist = list_Cons(list_Car(scan),delclauselist);
+ }
+ for (scan=delclauselist; !list_Empty(scan); scan=list_Cdr(scan))
+ newclauselist = list_PointerDeleteElement(newclauselist,list_Car(scan));
+ clause_DeleteClauseList(delclauselist);
+
+ return newclauselist;
+}
+
+
+TERM cnf_Flatten(TERM Term, SYMBOL Symbol)
+/**************************************************************
+ INPUT: A <Term> and <Symbol> that is assumed to be associative.
+ RETURNS: If the top symbol of <Term> is <Symbol> the <Term> is flattened
+ as long as it contains further direct subterms starting with <Symbol>
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ if (symbol_Equal(term_TopSymbol(Term), Symbol)) {
+ TERM Argterm;
+ Scan1 =term_ArgumentList(Term);
+ while (!list_Empty(Scan1)) {
+ Argterm = (TERM)list_Car(Scan1);
+ Scan2 = list_Cdr(Scan1);
+ if (symbol_Equal(term_TopSymbol(Argterm),Symbol)) {
+ cnf_Flatten(Argterm,Symbol);
+ list_NInsert(Scan1,list_Cdr(term_ArgumentList(Argterm))); /* Be efficient ... */
+ list_Rplaca(Scan1,list_Car(term_ArgumentList(Argterm)));
+ list_Free(term_ArgumentList(Argterm));
+ term_Free(Argterm);
+ }
+ Scan1 = Scan2;
+ }
+ }
+ return Term;
+}
+
+
+static TERM cnf_FlattenPath(TERM Term, TERM PredicateTerm)
+/**************************************************************
+ INPUT: A <Term> and <Symbol> that is assumed to be associative,
+ and a predicate term which is a subterm of term
+ RETURNS: If the top symbol of <Term> is <Symbol> the <Term> is flattened
+ as long as it contains further direct subterms starting with <Symbol>
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ TERM subterm;
+
+ subterm = Term;
+ while (symbol_Equal(term_TopSymbol(subterm), fol_All()))
+ subterm = term_SecondArgument(subterm);
+
+ if (symbol_Equal(term_TopSymbol(subterm), fol_Or())) {
+ TERM Argterm;
+ LIST scan1;
+ scan1 = term_ArgumentList(subterm);
+ while (!list_Empty(scan1)) {
+ LIST scan2;
+ Argterm = (TERM)list_Car(scan1);
+ scan2 = list_Cdr(scan1);
+ if (term_HasProperSuperterm(PredicateTerm, Argterm)) {
+ if (symbol_Equal(term_TopSymbol(Argterm),fol_Or())) {
+ LIST l;
+ cnf_Flatten(Argterm,fol_Or());
+ for (l=term_ArgumentList(Argterm); !list_Empty(l); l=list_Cdr(l))
+ term_RplacSuperterm((TERM) list_Car(l), subterm);
+ list_NInsert(scan1,list_Cdr(term_ArgumentList(Argterm))); /* Be efficient ... */
+ list_Rplaca(scan1,list_Car(term_ArgumentList(Argterm)));
+ list_Free(term_ArgumentList(Argterm));
+ term_Free(Argterm);
+ }
+ }
+ scan1 = scan2;
+ }
+ }
+ return Term;
+}
+
+
+static void cnf_DistrQuantorNoVarSub(TERM Term)
+/**************************************************************
+ INPUT: A formula in negation normal form starting with a universal
+ (existential) quantifier and a disjunction (conjunction) as argument.
+ EFFECT: The Quantor is distributed if possible.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ LIST Variables,Subformulas,Scan1,Scan2,Rest;
+ TERM Subterm,Var,NewForm;
+ SYMBOL Subtop,Top;
+
+ Top = term_TopSymbol(Term);
+ Variables = list_Copy(fol_QuantifierVariables(Term));
+ Subterm = term_SecondArgument(Term);
+ Subtop = term_TopSymbol(Subterm);
+ Subterm = cnf_Flatten(Subterm,Subtop);
+
+ for (Scan1=Variables;!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+ Subformulas = list_Nil();
+ Var = (TERM)list_Car(Scan1);
+ for (Scan2=term_ArgumentList(Subterm);!list_Empty(Scan2);Scan2=list_Cdr(Scan2))
+ if (!fol_VarOccursFreely(Var,list_Car(Scan2)))
+ Subformulas = list_Cons(list_Car(Scan2),Subformulas);
+ if (!list_Empty(Subformulas)) {
+ Rest = list_NPointerDifference(term_ArgumentList(Subterm),Subformulas);
+ if (list_Empty(list_Cdr(Rest))) { /* One subformula */
+ if (symbol_Equal(Top,term_TopSymbol(list_Car(Rest)))) { /* Optimization: quantifier still exist */
+ NewForm = (TERM)list_Car(Rest);
+ term_RplacArgumentList(term_FirstArgument(NewForm),
+ list_Cons((POINTER)Var,fol_QuantifierVariables(NewForm)));
+ list_Delete(Rest);
+ }
+ else
+ NewForm = fol_CreateQuantifier(Top,list_List((POINTER)Var),Rest);
+ }
+ else
+ NewForm = fol_CreateQuantifier(Top,list_List((POINTER)Var),list_List(term_Create(Subtop,Rest)));
+ term_RplacArgumentList(Subterm,list_Cons(NewForm,Subformulas));
+ term_RplacArgumentList(term_FirstArgument(Term),
+ list_PointerDeleteElement(fol_QuantifierVariables(Term),(POINTER)Var));
+ }
+ }
+
+ if (list_Empty(fol_QuantifierVariables(Term))) { /* All variables moved inside */
+ term_Free(term_FirstArgument(Term));
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,Subtop);
+ term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+ term_Free(Subterm);
+ }
+ list_Delete(Variables);
+}
+
+
+static TERM cnf_AntiPrenex(TERM Term)
+/**************************************************************
+ INPUT: A formula in negation normal form.
+ RETURNS: The term after application of anti-prenexing. Quantifiers
+ are moved inside as long as possible.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ LIST Scan;
+ SYMBOL Top;
+
+ Top = term_TopSymbol(Term);
+
+ if (fol_IsQuantifier(Top)) {
+ TERM Subterm,Actterm;
+ SYMBOL DistrSymb,Subtop; /* The junctor the respective quantifier distributes over */
+
+ Subterm = term_SecondArgument(Term);
+ Subtop = term_TopSymbol(Subterm);
+
+ if (!symbol_IsPredicate(Subtop) &&
+ !symbol_Equal(Subtop,fol_Not())) { /* Formula in NNF: No Literals or Atoms */
+ if (symbol_Equal(Top,fol_All()))
+ DistrSymb = fol_And();
+ else
+ DistrSymb = fol_Or();
+ if (fol_IsQuantifier(Subtop)) {
+ cnf_AntiPrenex(Subterm);
+ Subtop = term_TopSymbol(Subterm);
+ }
+ if (symbol_Equal(Subtop,DistrSymb)) {
+ LIST Variables;
+ LIST NewVars;
+ Variables = fol_QuantifierVariables(Term);
+ Subterm = cnf_Flatten(Subterm,DistrSymb);
+ for (Scan=term_ArgumentList(Subterm);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Actterm = (TERM)list_Car(Scan);
+ NewVars = list_NIntersect(fol_FreeVariables(Actterm),Variables,
+ (BOOL (*)(POINTER,POINTER))term_Equal);
+ if (!list_Empty(NewVars)) {
+ if (symbol_Equal(Top,term_TopSymbol(Actterm))) { /* Quantor already there */
+ term_CopyTermsInList(NewVars);
+ term_RplacArgumentList(term_FirstArgument(Actterm),
+ list_Nconc(fol_QuantifierVariables(Actterm),
+ NewVars));
+ }
+ else {
+ term_CopyTermsInList(NewVars);
+ list_Rplaca(Scan,fol_CreateQuantifier(Top, NewVars, list_List(Actterm)));
+ }
+ }
+ }
+ term_Delete(term_FirstArgument(Term)); /* Delete old variable list */
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,DistrSymb);
+ term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+ term_Free(Subterm);
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ list_Rplaca(Scan,cnf_AntiPrenex(list_Car(Scan)));
+ }
+ else
+ if (!fol_IsQuantifier(Subtop)) {
+ cnf_DistrQuantorNoVarSub(Term);
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ cnf_AntiPrenex(list_Car(Scan));
+ }
+ }
+ }
+ else
+ if (!symbol_Equal(Top,fol_Not()) && !symbol_IsPredicate(Top))
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ cnf_AntiPrenex(list_Car(Scan));
+
+ return Term;
+}
+
+
+static void cnf_DistrQuantorNoVarSubPath(TERM Term, TERM PredicateTerm)
+/**************************************************************
+ INPUT: A formula in negation normal form starting with a universal
+ (existential) quantifier and a disjunction (conjunction) as argument
+ and a predicate term which is a subterm of term.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ LIST Variables,Subformulas,Scan1,Scan2,Rest;
+ TERM Subterm,Var,NewForm;
+ SYMBOL Subtop,Top;
+
+ /*fputs("\nAN0:\t",stdout);term_Print(Term);*/
+
+ Top = term_TopSymbol(Term);
+ Variables = list_Copy(fol_QuantifierVariables(Term));
+ Subterm = term_SecondArgument(Term);
+ Subtop = term_TopSymbol(Subterm);
+ Subterm = cnf_Flatten(Subterm,Subtop);
+
+ /*fputs("\nAN1:\t",stdout);term_Print(Subterm);*/
+
+ for (Scan1=Variables;!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+ Subformulas = list_Nil();
+ Var = (TERM)list_Car(Scan1);
+ /* Find subterms in which the variable does not occur freely */
+ for (Scan2=term_ArgumentList(Subterm);!list_Empty(Scan2);Scan2=list_Cdr(Scan2))
+ if (!fol_VarOccursFreely(Var,list_Car(Scan2)))
+ Subformulas = list_Cons(list_Car(Scan2),Subformulas);
+ if (!list_Empty(Subformulas)) {
+ /* Rest is the list of those subterms where the variable does occur freely */
+ Rest = list_NPointerDifference(term_ArgumentList(Subterm),Subformulas);
+ if (list_Empty(list_Cdr(Rest))) { /* One subformula */
+ if (symbol_Equal(Top,term_TopSymbol(list_Car(Rest)))) { /* Optimization: quantifier still exist */
+ NewForm = (TERM)list_Car(Rest);
+ /* Move one variable down */
+ term_RplacArgumentList(term_FirstArgument(NewForm),
+ list_Cons((POINTER)Var,fol_QuantifierVariables(NewForm)));
+ list_Delete(Rest);
+ }
+ else {
+ NewForm = fol_CreateQuantifierAddFather(Top,list_List((POINTER)Var),
+ Rest);
+ }
+ }
+ else {
+ TERM t;
+ t = term_CreateAddFather(Subtop,Rest);
+ NewForm = fol_CreateQuantifierAddFather(Top,list_List((POINTER)Var),list_List(t));
+ }
+ if (term_HasProperSuperterm(PredicateTerm, NewForm))
+ NewForm = cnf_AntiPrenexPath(NewForm, PredicateTerm);
+ term_RplacArgumentList(Subterm,list_Cons(NewForm,Subformulas));
+ term_RplacSuperterm(NewForm, Subterm);
+ term_RplacArgumentList(term_FirstArgument(Term),
+ list_PointerDeleteElement(fol_QuantifierVariables(Term),(POINTER)Var));
+ }
+ }
+
+ if (list_Empty(fol_QuantifierVariables(Term))) { /* All variables moved inside */
+ LIST l;
+ term_Free(term_FirstArgument(Term));
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,Subtop);
+ term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+ term_Free(Subterm);
+ for (l=term_ArgumentList(Term); !list_Empty(l); l=list_Cdr(l))
+ term_RplacSuperterm((TERM) list_Car(l), Term);
+ }
+ list_Delete(Variables);
+}
+
+
+static TERM cnf_AntiPrenexPath(TERM Term, TERM PredicateTerm)
+/**************************************************************
+ INPUT: A formula in negation normal form and a predicate term
+ which is a subterm of term.
+ RETURNS: The term after application of anti-prenexing. Quantifiers
+ are moved inside along the path as long as possible.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ LIST Scan;
+ SYMBOL Top;
+
+ Top = term_TopSymbol(Term);
+
+ if (fol_IsQuantifier(Top)) {
+ TERM Subterm,Actterm;
+ SYMBOL DistrSymb,Subtop; /* The junctor the respective quantifier distributes over */
+
+ Subterm = term_SecondArgument(Term);
+ Subtop = term_TopSymbol(Subterm);
+
+ if (!symbol_Equal(Subtop,fol_Not()) && !symbol_IsPredicate(Subtop)) { /* No Literals or Atoms */
+ if (symbol_Equal(Top,fol_All()))
+ DistrSymb = fol_And();
+ else
+ DistrSymb = fol_Or();
+ if (fol_IsQuantifier(Subtop)) {
+ cnf_AntiPrenexPath(Subterm, PredicateTerm);
+ Subtop = term_TopSymbol(Subterm);
+ }
+ if (symbol_Equal(Subtop,DistrSymb)) {
+ LIST Variables;
+ LIST NewVars;
+ Variables = fol_QuantifierVariables(Term);
+ Subterm = cnf_Flatten(Subterm,DistrSymb);
+ term_AddFatherLinks(Subterm);
+ /*
+ for (l=term_ArgumentList(Subterm); !list_Empty(l); l=list_Cdr(l))
+ term_RplacSuperterm((TERM) list_Car(l), Subterm);
+ */
+ for (Scan=term_ArgumentList(Subterm);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Actterm = (TERM)list_Car(Scan);
+ NewVars = list_NIntersect(fol_FreeVariables(Actterm),Variables,
+ (BOOL (*)(POINTER,POINTER))term_Equal);
+ if (!list_Empty(NewVars)) {
+ if (symbol_Equal(Top,term_TopSymbol(Actterm))) { /* Quantor already there */
+ term_CopyTermsInList(NewVars);
+ term_RplacArgumentList(term_FirstArgument(Actterm),
+ list_Nconc(fol_QuantifierVariables(Actterm), NewVars));
+ }
+ else {
+ term_CopyTermsInList(NewVars);
+ list_Rplaca(Scan,fol_CreateQuantifierAddFather(Top, NewVars, list_List(Actterm)));
+ }
+ }
+ }
+ term_Delete(term_FirstArgument(Term)); /* Delete old variable list */
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,DistrSymb);
+ term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+ term_Free(Subterm);
+ term_AddFatherLinks(Term);
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ term_RplacSuperterm((TERM) list_Car(Scan), Term);
+ if (term_HasPointerSubterm((TERM) list_Car(Scan), PredicateTerm)) {
+ puts("\ncheck1");
+ list_Rplaca(Scan,cnf_AntiPrenexPath(list_Car(Scan), PredicateTerm));
+ term_RplacSuperterm((TERM) list_Car(Scan), Term);
+ }
+ }
+ }
+ else
+ if (!fol_IsQuantifier(Subtop)) {
+ cnf_DistrQuantorNoVarSubPath(Term, PredicateTerm);
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (term_HasPointerSubterm(list_Car(Scan), PredicateTerm))
+ cnf_AntiPrenexPath(list_Car(Scan), PredicateTerm);
+ }
+ }
+ }
+ }
+ else
+ if (!symbol_Equal(Top,fol_Not()) && !symbol_IsPredicate(Top))
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (term_HasProperSuperterm(PredicateTerm, (TERM) list_Car(Scan)))
+ cnf_AntiPrenexPath(list_Car(Scan), PredicateTerm);
+
+ term_AddFatherLinks(Term);
+ return Term;
+}
+
+
+static TERM cnf_RemoveTrivialOperators(TERM Term)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: The formula after
+ removal of "or" and "and" with only one argument
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ SYMBOL Top;
+ LIST Scan;
+
+ Top = term_TopSymbol(Term);
+
+ if (symbol_IsPredicate(Top))
+ return Term;
+
+ if ((symbol_Equal(Top,fol_And()) || symbol_Equal(Top,fol_Or())) &&
+ list_Empty(list_Cdr(term_ArgumentList(Term)))) {
+ TERM Result;
+ Result = term_FirstArgument(Term);
+ term_RplacSuperterm(Result, term_Superterm(Term));
+ list_Delete(term_ArgumentList(Term));
+ term_Free(Term);
+ return cnf_RemoveTrivialOperators(Result);
+ }
+
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ list_Rplaca(Scan,cnf_RemoveTrivialOperators(list_Car(Scan)));
+ term_RplacSuperterm((TERM) list_Car(Scan), Term);
+ }
+
+ return Term;
+}
+
+
+static TERM cnf_SimplifyQuantors(TERM Term)
+ /**************************************************************
+ INPUT: A formula.
+ RETURNS: The formula after
+ removal of bindings of variables that don't occur in the
+ respective subformula and possible mergings of quantors
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ SYMBOL Top;
+ LIST Scan;
+
+ Top = term_TopSymbol(Term);
+
+ if (symbol_IsPredicate(Top) || symbol_Equal(Top,fol_Varlist()))
+ return Term;
+
+ if (fol_IsQuantifier(Top)) {
+ LIST Vars;
+ TERM Var,Subterm,Aux;
+ Vars = list_Nil();
+ Subterm = term_SecondArgument(Term);
+
+ while (symbol_Equal(term_TopSymbol(Subterm),Top)) {
+ term_RplacArgumentList(term_FirstArgument(Term),
+ list_Nconc(fol_QuantifierVariables(Term),fol_QuantifierVariables(Subterm)));
+ term_Free(term_FirstArgument(Subterm));
+ Aux = term_SecondArgument(Subterm);
+ list_Delete(term_ArgumentList(Subterm));
+ term_Free(Subterm);
+ list_Rplaca(list_Cdr(term_ArgumentList(Term)),Aux);
+ Subterm = Aux;
+ }
+
+ for (Scan=fol_QuantifierVariables(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Var = (TERM)list_Car(Scan);
+ if (!fol_VarOccursFreely(Var,Subterm))
+ Vars = list_Cons(Var,Vars);
+ }
+ if (!list_Empty(Vars)) {
+ Subterm = term_FirstArgument(Term);
+ term_RplacArgumentList(Subterm,list_NPointerDifference(term_ArgumentList(Subterm),Vars));
+ term_DeleteTermList(Vars);
+ if (list_Empty(term_ArgumentList(Subterm))) {
+ Subterm = term_SecondArgument(Term);
+ term_Delete(term_FirstArgument(Term));
+ list_Delete(term_ArgumentList(Term));
+ term_Free(Term);
+ return cnf_SimplifyQuantors(Subterm);
+ }
+ }
+ }
+
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ list_Rplaca(Scan,cnf_SimplifyQuantors(list_Car(Scan)));
+
+ return Term;
+}
+
+
+TERM cnf_RemoveTrivialAtoms(TERM Term)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: The formula where occurrences of the atoms "true"
+ and "false" are propagated and eventually removed.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ SYMBOL Top,Subtop;
+ LIST Scan;
+ TERM Result;
+ BOOL Update;
+
+
+ if (!term_IsComplex(Term))
+ return Term;
+
+ Top = term_TopSymbol(Term);
+ Update = FALSE;
+
+ if (symbol_Equal(Top,fol_And())) {
+ Scan = term_ArgumentList(Term);
+ while (!list_Empty(Scan)) {
+ Result = cnf_RemoveTrivialAtoms(list_Car(Scan));
+ Subtop = term_TopSymbol(Result);
+ if (symbol_Equal(Subtop,fol_True()))
+ Update = TRUE;
+ else
+ if (symbol_Equal(Subtop,fol_False())) {
+ term_RplacTop(Term,fol_False());
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term,list_Nil());
+ return Term;
+ }
+ Scan = list_Cdr(Scan);
+ }
+ if (Update) {
+ term_RplacArgumentList(Term,fol_DeleteTrueTermFromList(term_ArgumentList(Term)));
+ if (list_Empty(term_ArgumentList(Term))) {
+ term_RplacTop(Term,fol_True());
+ return Term;
+ }
+ }
+ }
+ else if (symbol_Equal(Top,fol_Or())) {
+ Scan = term_ArgumentList(Term);
+ while (!list_Empty(Scan)) {
+ Result = cnf_RemoveTrivialAtoms(list_Car(Scan));
+ Subtop = term_TopSymbol(Result);
+ if (symbol_Equal(Subtop,fol_False()))
+ Update = TRUE;
+ else
+ if (symbol_Equal(Subtop,fol_True())) {
+ term_RplacTop(Term,fol_True());
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term,list_Nil());
+ return Term;
+ }
+ Scan = list_Cdr(Scan);
+ }
+ if (Update) {
+ term_RplacArgumentList(Term,fol_DeleteFalseTermFromList(term_ArgumentList(Term)));
+ if (list_Empty(term_ArgumentList(Term))) {
+ term_RplacTop(Term,fol_False());
+ return Term;
+ }
+ }
+ }
+ else if (fol_IsQuantifier(Top) || symbol_Equal(Top,fol_Not())) {
+ if (fol_IsQuantifier(Top))
+ Result = cnf_RemoveTrivialAtoms(term_SecondArgument(Term));
+ else
+ Result = cnf_RemoveTrivialAtoms(term_FirstArgument(Term));
+ Subtop = term_TopSymbol(Result);
+ if ((symbol_Equal(Subtop,fol_False()) && symbol_Equal(Top,fol_Not())) ||
+ (symbol_Equal(Subtop,fol_True()) && fol_IsQuantifier(Top))) {
+ term_RplacTop(Term,fol_True());
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term,list_Nil());
+ return Term;
+ }
+ else
+ if ((symbol_Equal(Subtop,fol_True()) && symbol_Equal(Top,fol_Not())) ||
+ (symbol_Equal(Subtop,fol_False()) && fol_IsQuantifier(Top))) {
+ term_RplacTop(Term,fol_False());
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term,list_Nil());
+ return Term;
+ }
+ }
+ else if (symbol_Equal(Top,fol_Implies())) {
+ Result = cnf_RemoveTrivialAtoms(term_FirstArgument(Term));
+ Subtop = term_TopSymbol(Result);
+ if (symbol_Equal(Subtop,fol_False())) {
+ term_RplacTop(Term,fol_True());
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term,list_Nil());
+ return Term;
+ }
+ else if (symbol_Equal(Subtop,fol_True())) {
+ term_Delete(Result);
+ Result = term_SecondArgument(Term);
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,term_TopSymbol(Result));
+ term_RplacArgumentList(Term,term_ArgumentList(Result));
+ term_Free(Result);
+ return cnf_RemoveTrivialAtoms(Term);
+ }
+ Result = cnf_RemoveTrivialAtoms(term_SecondArgument(Term));
+ Subtop = term_TopSymbol(Result);
+ if (symbol_Equal(Subtop,fol_True())) {
+ term_RplacTop(Term,fol_True());
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term,list_Nil());
+ return Term;
+ }
+ else if (symbol_Equal(Subtop,fol_False())) {
+ term_RplacTop(Term,fol_Not());
+ term_RplacArgumentList(Term,fol_DeleteFalseTermFromList(term_ArgumentList(Term)));
+ }
+ }
+ else if (symbol_Equal(Top,fol_Equiv())) {
+ Result = cnf_RemoveTrivialAtoms(term_FirstArgument(Term));
+ Subtop = term_TopSymbol(Result);
+ if (symbol_Equal(Subtop,fol_False())) {
+ term_RplacTop(Term,fol_Not());
+ term_RplacArgumentList(Term,fol_DeleteFalseTermFromList(term_ArgumentList(Term)));
+ if (list_Empty(term_ArgumentList(Term))) {
+ term_RplacTop(Term, fol_True());
+ return Term;
+ }
+ return cnf_RemoveTrivialAtoms(Term);
+ }
+ else if (symbol_Equal(Subtop,fol_True())) {
+ term_Delete(Result);
+ Result = term_SecondArgument(Term);
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,term_TopSymbol(Result));
+ term_RplacArgumentList(Term,term_ArgumentList(Result));
+ term_Free(Result);
+ return cnf_RemoveTrivialAtoms(Term);
+ }
+ Result = cnf_RemoveTrivialAtoms(term_SecondArgument(Term));
+ Subtop = term_TopSymbol(Result);
+ if (symbol_Equal(Subtop,fol_False())) {
+ term_RplacTop(Term,fol_Not());
+ term_RplacArgumentList(Term,fol_DeleteFalseTermFromList(term_ArgumentList(Term)));
+ }
+ else if (symbol_Equal(Subtop,fol_True())) {
+ term_Delete(Result);
+ Result = term_FirstArgument(Term);
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,term_TopSymbol(Result));
+ term_RplacArgumentList(Term,term_ArgumentList(Result));
+ term_Free(Result);
+ }
+ }
+
+ return Term;
+}
+
+
+TERM cnf_ObviousSimplifications(TERM Term)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: The formula after performing the following simplifications:
+ - remove "or" and "and" with only one argument
+ - remove bindings of variables that don't occur in the
+ respective subformula
+ - merge quantors
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ Term = cnf_RemoveTrivialAtoms(Term);
+ Term = cnf_RemoveTrivialOperators(Term);
+ Term = cnf_SimplifyQuantors(Term);
+
+ return Term;
+}
+
+
+/* EK: warum wird Term zurueckgegeben, wenn er destruktiv geaendert wird??? */
+static TERM cnf_SkolemFormula(TERM Term, PRECEDENCE Precedence, LIST* Symblist)
+/**************************************************************
+ INPUT: A formula in negation normal form, a precedence and pointer
+ to a list used as return value.
+ RETURNS: The skolemized term and the list of introduced Skolem functions.
+ CAUTION: The term is destructively changed.
+ The precedence of the new Skolem functions is set in <Precedence>.
+***************************************************************/
+{
+ SYMBOL Top,SkolemSymbol;
+ TERM Subterm,SkolemTerm;
+ LIST Varlist,Scan;
+ NAT Arity;
+
+ Top = term_TopSymbol(Term);
+
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ if (symbol_Equal(Top,fol_All())) {
+ term_Delete(term_FirstArgument(Term));
+ Subterm = term_SecondArgument(Term);
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,term_TopSymbol(Subterm));
+ term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+ term_Free(Subterm);
+ return cnf_SkolemFormula(Term, Precedence, Symblist);
+ }
+ else { /* exist quantifier */
+ Varlist = fol_FreeVariables(Term);
+ Arity = list_Length(Varlist);
+ for (Scan=fol_QuantifierVariables(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ SkolemSymbol = symbol_CreateSkolemFunction(Arity, Precedence);
+ *Symblist = list_Cons((POINTER)SkolemSymbol, *Symblist);
+ SkolemTerm = term_Create(SkolemSymbol,Varlist); /* Caution: Sharing of Varlist ! */
+ fol_ReplaceVariable(term_SecondArgument(Term),term_TopSymbol(list_Car(Scan)),SkolemTerm);
+ term_Free(SkolemTerm);
+ }
+ list_Delete(Varlist);
+ term_Delete(term_FirstArgument(Term));
+ Subterm = term_SecondArgument(Term);
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,term_TopSymbol(Subterm));
+ term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+ term_Free(Subterm);
+ return cnf_SkolemFormula(Term, Precedence, Symblist);
+ }
+ }
+ else
+ if (symbol_Equal(Top,fol_And()) || symbol_Equal(Top,fol_Or()))
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ cnf_SkolemFormula(list_Car(Scan), Precedence, Symblist);
+ return Term;
+}
+
+
+static TERM cnf_Cnf(TERM Term, PRECEDENCE Precedence, LIST* Symblist)
+/**************************************************************
+ INPUT: A formula, a precedence and a pointer to a list of symbols
+ used as return value.
+ RETURNS: The term is transformed to conjunctive normal form.
+ EFFECT: The term is destructively changed and not normalized.
+ The precedence of new Skolem symbols is set in <Precedence>.
+***************************************************************/
+{
+ /* Necessary because ren_Rename crashes if a e.g. and() has only one argument */
+ Term = cnf_ObviousSimplifications(Term);
+ term_AddFatherLinks(Term);
+ Term = ren_Rename(Term, Precedence, Symblist, FALSE, FALSE);
+ Term = cnf_RemoveEquivImplFromFormula(Term);
+ Term = cnf_NegationNormalFormula(Term);
+ Term = cnf_SkolemFormula(cnf_AntiPrenex(Term), Precedence, Symblist);
+ Term = cnf_DistributiveFormula(Term);
+
+ return Term;
+}
+
+
+static LIST cnf_GetUsedTerms(CLAUSE C, PROOFSEARCH Search,
+ HASH InputClauseToTermLabellist)
+/**************************************************************
+ INPUT:
+ RETURNS:
+***************************************************************/
+{
+ LIST UsedTerms, Used2, Scan;
+ UsedTerms = list_Copy(hsh_Get(InputClauseToTermLabellist, C));
+ UsedTerms = cnf_DeleteDuplicateLabelsFromList(UsedTerms);
+ if (!list_Empty(UsedTerms))
+ return UsedTerms;
+
+ for (Scan = clause_ParentClauses(C); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ CLAUSE P;
+ int ClauseNumber;
+ ClauseNumber = (int) list_Car(Scan);
+ P = clause_GetNumberedCl(ClauseNumber, prfs_WorkedOffClauses(Search));
+ if (P == NULL) {
+ P = clause_GetNumberedCl(ClauseNumber, prfs_UsableClauses(Search));
+ if (P == NULL)
+ P = clause_GetNumberedCl(ClauseNumber, prfs_DocProofClauses(Search));
+ }
+ Used2 = cnf_GetUsedTerms(P, Search, InputClauseToTermLabellist);
+ UsedTerms = list_Nconc(UsedTerms, Used2);
+ }
+ return UsedTerms;
+}
+
+
+static BOOL cnf_HaveProofOptSkolem(PROOFSEARCH Search, TERM topterm,
+ char* toplabel, TERM term2,
+ LIST* UsedTerms, LIST* Symblist,
+ HASH InputClauseToTermLabellist)
+/**************************************************************
+ INPUT:
+ RETURNS: ??? EK
+***************************************************************/
+{
+ LIST ConClauses, EmptyClauses;
+ LIST scan;
+ BOOL found;
+ LIST Usables;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+ ConClauses = list_Nil();
+ found = FALSE;
+ /* List of clauses from term2 */
+ term_AddFatherLinks(term2);
+ term2 = cnf_Cnf(term2, Precedence, Symblist);
+ Usables = cnf_MakeClauseList(term2, FALSE, FALSE, Flags, Precedence);
+ term_Delete(term2);
+
+ for (scan=Usables; !list_Empty(scan); scan = list_Cdr(scan)) {
+ clause_SetFlag(list_Car(scan), CONCLAUSE);
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+#ifdef CHECK
+ hsh_Check(InputClauseToTermLabellist);
+#endif
+ hsh_Put(InputClauseToTermLabellist, list_Car(scan), toplabel);
+#ifdef CHECK_CNF
+ fputs("\nUsable : ", stdout);
+ clause_Print(list_Car(scan));
+ printf(" Label %s", toplabel);
+#endif
+ }
+ }
+ EmptyClauses = cnf_SatUnit(Search, Usables);
+ if (!list_Empty(EmptyClauses)) {
+ found = TRUE;
+#ifdef CHECK_CNF
+ fputs("\nHaveProof : Empty Clause : ", stdout);
+ clause_Print((CLAUSE) list_Car(EmptyClauses));
+ putchar('\n');
+#endif
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ *UsedTerms = list_Nconc(*UsedTerms, cnf_GetUsedTerms((CLAUSE) list_Car(EmptyClauses), Search, InputClauseToTermLabellist));
+ EmptyClauses = list_PointerDeleteDuplicates(EmptyClauses);
+ clause_DeleteClauseList(EmptyClauses);
+ }
+
+ /* Removing ConClauses from UsablesIndex */
+ ConClauses = list_Copy(prfs_UsableClauses(Search));
+ for (scan = ConClauses; !list_Empty(scan); scan = list_Cdr(scan))
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ prfs_MoveUsableDocProof(Search, (CLAUSE) list_Car(scan));
+ else
+ prfs_DeleteUsable(Search, (CLAUSE) list_Car(scan));
+ list_Delete(ConClauses);
+
+ return found;
+}
+
+
+BOOL cnf_HaveProof(LIST TermList, TERM ToProve, FLAGSTORE InputFlags,
+ PRECEDENCE InputPrecedence)
+/**************************************************************
+ INPUT: A list of terms, a term to prove, a flag store and a precedence.
+ The arguments are not changed.
+ RETURNS: True if the termlist implies ToProve
+ CAUTION: All terms are copied.
+***************************************************************/
+{
+ PROOFSEARCH search;
+ LIST scan, usables, symblist, emptyclauses;
+ BOOL found;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ /* Use global PROOFSEARCH object to avoid stamp overflow */
+ search = cnf_HAVEPROOFPS;
+ usables = symblist = list_Nil();
+
+ /* Initialize search object's flag store */
+ Flags = prfs_Store(search);
+ flag_CleanStore(Flags);
+ flag_InitFlotterSubproofFlags(InputFlags, Flags);
+ /* Initialize search object's precedence */
+ Precedence = prfs_Precedence(search);
+ symbol_TransferPrecedence(InputPrecedence, Precedence);
+
+ /* Build list of clauses from the termlist */
+ for (scan=TermList; !list_Empty(scan); scan=list_Cdr(scan)) {
+ TERM t;
+ t = term_Copy(list_Car(scan));
+ t = cnf_Cnf(t, Precedence, &symblist);
+
+ usables = list_Nconc(cnf_MakeClauseList(t,FALSE,FALSE,Flags,Precedence),
+ usables);
+ term_Delete(t);
+ }
+
+ /* Build clauses from negated term to prove */
+ ToProve = term_Create(fol_Not(), list_List(term_Copy(ToProve)));
+ term_AddFatherLinks(ToProve);
+ ToProve = cnf_Cnf(ToProve, Precedence, &symblist);
+ usables = list_Nconc(cnf_MakeClauseList(ToProve,FALSE,FALSE,Flags,Precedence),
+ usables);
+ term_Delete(ToProve);
+
+ /* SatUnit requires the CONCLAUSE flag */
+ for (scan=usables;!list_Empty(scan); scan = list_Cdr(scan))
+ clause_SetFlag(list_Car(scan), CONCLAUSE);
+
+ emptyclauses = cnf_SatUnit(search, usables);
+
+ if (!list_Empty(emptyclauses)) {
+ found = TRUE;
+ emptyclauses = list_PointerDeleteDuplicates(emptyclauses);
+ clause_DeleteClauseList(emptyclauses);
+ }
+ else
+ found = FALSE;
+ prfs_Clean(search);
+ symbol_DeleteSymbolList(symblist);
+
+ return found;
+}
+
+
+static void cnf_RplacVarsymbFunction(TERM term, SYMBOL varsymb, TERM function)
+/**********************************************************
+ INPUT: A term, a variable symbol and a function.
+ EFFECT: The variable with the symbol varsymb in the term
+ is replaced by the function function.
+ CAUTION: The term is destructively changed.
+***********************************************************/
+{
+ int bottom;
+ TERM term1;
+ LIST scan;
+
+ bottom = vec_ActMax();
+ vec_Push(term);
+
+ while (bottom != vec_ActMax()) {
+ term1 = (TERM)vec_PopResult();
+ if (symbol_Equal(term_TopSymbol(term1),varsymb)) {
+ term_RplacTop(term1,term_TopSymbol(function));
+ term_RplacArgumentList(term1,term_CopyTermList(term_ArgumentList(function)));
+ }else
+ if (!list_Empty(term_ArgumentList(term1)))
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+ vec_Push(list_Car(scan));
+ }
+ vec_SetMax(bottom);
+}
+
+
+static void cnf_RplacVar(TERM Term, LIST Varlist, LIST Termlist)
+/**********************************************************
+ INPUT: A term,a variable symbol and a function.
+ RETURNS: The variable with the symbol varsymb in the term
+ is replaced by the function function.
+ CAUTION: The term is destructively changed.
+***********************************************************/
+{
+ int bottom;
+ TERM term1;
+ LIST scan,scan2;
+
+ bottom = vec_ActMax();
+ vec_Push(Term);
+
+ while (bottom != vec_ActMax()) {
+ term1 = vec_PopResult();
+ if (symbol_IsVariable(term_TopSymbol(term1))) {
+ BOOL done;
+ done = FALSE;
+ for (scan=Varlist, scan2=Termlist; !list_Empty(scan) && !done;
+ scan = list_Cdr(scan), scan2 = list_Cdr(scan2)) {
+ if (symbol_Equal(term_TopSymbol(term1),term_TopSymbol(list_Car(scan)))) {
+ term_RplacTop(term1,term_TopSymbol((TERM) list_Car(scan2)));
+ term_RplacArgumentList(term1,
+ term_CopyTermList(term_ArgumentList(list_Car(scan2))));
+ done = TRUE;
+ }
+ }
+ }
+ else
+ if (!list_Empty(term_ArgumentList(term1)))
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+ vec_Push(list_Car(scan));
+ }
+ vec_SetMax(bottom);
+}
+
+
+static TERM cnf_MakeSkolemFunction(LIST varlist, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A list of variables and a precedence.
+ RETURNS: The new term oskf... (oskc...) which is a function
+ with varlist as arguments.
+ EFFECT: The precedence of the new Skolem function is set in <Precedence>.
+***************************************************************/
+{
+ TERM term;
+ SYMBOL skolem;
+
+ skolem = symbol_CreateSkolemFunction(list_Length(varlist), Precedence);
+ term = term_Create(skolem, term_CopyTermList(varlist));
+ return term;
+}
+
+
+static void cnf_PopAllQuantifier(TERM term)
+/********************************************************
+ INPUT: A term whose top symbol is fol_all.
+ RETURNS: Nothing.
+ EFFECT: Removes the quantifier
+********************************************************/
+{
+ TERM SubTerm;
+ LIST VarList;
+
+#ifdef CHECK
+ if (!symbol_Equal(term_TopSymbol(term), fol_All())) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_PopAllQuantifier: Top symbol is not fol_All !\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ VarList = term_ArgumentList(term_FirstArgument(term));
+ term_DeleteTermList(VarList);
+ term_Free(term_FirstArgument(term));
+ SubTerm = term_SecondArgument(term);
+ list_Delete(term_ArgumentList(term));
+ term_RplacTop(term,term_TopSymbol(SubTerm));
+ term_RplacArgumentList(term,term_ArgumentList(SubTerm));
+ term_Free(SubTerm);
+}
+
+
+static TERM cnf_QuantifyAndNegate(TERM term, LIST VarList, LIST FreeList)
+/****************************************************************
+ INPUT: A term, a list of variables to be exist-quantified,
+ a list of variables to be all-quantified
+ RETURNS: not(forall[FreeList](exists[VarList](term)))
+ MEMORY: The term, the lists and their arguments are copied.
+***************************************************************/
+{
+ TERM Result;
+ TERM TermCopy;
+ LIST VarListCopy;
+ LIST FreeListCopy;
+
+ TermCopy = term_Copy(term);
+ VarListCopy = term_CopyTermList(VarList);
+ Result = fol_CreateQuantifier(fol_Exist(),VarListCopy,list_List(TermCopy));
+ FreeListCopy = list_Nil();
+
+ FreeList = fol_FreeVariables(Result);
+ if (!list_Empty(FreeList)) {
+ FreeListCopy = term_CopyTermList(FreeList);
+ list_Delete(FreeList);
+ Result = fol_CreateQuantifier(fol_All(), FreeListCopy, list_List(Result));
+ }
+ Result = term_Create(fol_Not(), list_List(Result));
+ return Result;
+}
+
+
+static TERM cnf_MoveProvedTermToTopLevel(TERM Term, TERM Term1, TERM Proved,
+ LIST VarList, LIST FreeList,
+ PRECEDENCE Precedence)
+/********************************************************************
+ INPUT: A top-level term, which must be a conjunction,
+ a subterm <Term1> of <Term>, a subterm <Proved> of <Term1>,
+ a list of existence quantified variables <VarList>,
+ a list of free variables <FreeList> and a precedence.
+ <Term1> is of the form
+ exists[...](t1 and t2 and ... and Proved and ..)
+ RETURNS: A new term, where <Proved> is removed from the arguments
+ of <Term1>.
+ EFFECT: The precedence of new Skolem functions is set in <Precedence>
+*******************************************************************/
+{
+ TERM termR;
+ TERM skolemfunction;
+ SYMBOL varsymb;
+ LIST scan;
+
+ termR = term_SecondArgument(Term1); /* t1 and t2 and ... and Proved ... */
+ term_RplacArgumentList(termR,
+ list_PointerDeleteElement(term_ArgumentList(termR),
+ Proved));
+ if (list_Length(term_ArgumentList(termR)) < 2) {
+ TERM termRL = term_FirstArgument(termR); /* t1 */
+ list_Delete(term_ArgumentList(termR));
+ term_RplacTop(termR, term_TopSymbol(termRL));
+ term_RplacArgumentList(termR,term_ArgumentList(termRL));
+ term_Free(termRL);
+ }
+
+ for (scan = VarList; scan != list_Nil(); scan = list_Cdr(scan)) {
+ varsymb = term_TopSymbol(list_Car(scan));
+ skolemfunction = cnf_MakeSkolemFunction(FreeList, Precedence);
+ cnf_RplacVarsymbFunction(termR,varsymb,skolemfunction);
+ cnf_RplacVarsymbFunction(Proved,varsymb,skolemfunction);
+ term_Delete(skolemfunction);
+ }
+
+ if (!list_Empty(FreeList)) {
+ Proved =
+ fol_CreateQuantifier(fol_All(), term_CopyTermList(FreeList),
+ list_List(Proved));
+ if (list_Length(FreeList) > 1)
+ Proved = cnf_QuantMakeOneVar(Proved);
+ }
+
+ term_Delete(term_FirstArgument(Term1)); /* Variables of "exists" */
+ list_Delete(term_ArgumentList(Term1));
+ term_RplacTop(Term1,term_TopSymbol(termR));
+ term_RplacArgumentList(Term1,term_ArgumentList(termR));
+ term_Free(termR);
+
+ term_RplacArgumentList(Term, list_Cons(Proved, term_ArgumentList(Term)));
+ return Proved;
+}
+
+
+static void cnf_Skolemize(TERM Term, LIST FreeList, PRECEDENCE Precedence)
+/********************************************************
+ INPUT: A existence quantified term, the list of free variables
+ and a precedence.
+ RETURNS: Nothing.
+ EFFECT: The term is destructively changed, i.e. the
+ existence quantifier is removed by skolemization.
+ The precedence of new Skolem functions is set in <Precedence>.
+*********************************************************/
+{
+ LIST exlist;
+ TERM subterm;
+ LIST symblist;
+
+ symblist = list_Nil();
+ exlist = cnf_GetSymbolList(term_ArgumentList(term_FirstArgument(Term)));
+ term_Delete(term_FirstArgument(Term));
+ subterm = term_SecondArgument(Term);
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,term_TopSymbol(subterm));
+ term_RplacArgumentList(Term,term_ArgumentList(subterm));
+ term_Free(subterm);
+ symblist = cnf_SkolemFunctionFormula(Term, FreeList, exlist, Precedence);
+ list_Delete(exlist);
+ list_Delete(symblist);
+}
+
+
+static LIST cnf_FreeVariablesBut(TERM Term, LIST Symbols)
+/********************************************************
+ INPUT: A term and a list of symbols
+ RETURNS: A list of all free variable terms in Term whose symbols are
+ not in Symbols
+*********************************************************/
+{
+ LIST follist, Scan;
+ follist = fol_FreeVariables(Term);
+ for (Scan = follist; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (list_Member(Symbols, (POINTER)term_TopSymbol(list_Car(Scan)),
+ (BOOL (*)(POINTER,POINTER))symbol_Equal))
+ list_Rplaca(Scan,NULL);
+ follist = list_PointerDeleteElement(follist,NULL);
+
+ return follist;
+}
+
+
+static void cnf_SkolemFunctionFormulaMapped(TERM term, LIST allist, LIST map)
+/**************************************************************
+ INPUT: A term term and a list allist of variables and a list map
+ of pairs (variable symbols, function symbol)
+ RETURNS: None.
+ CAUTION: The term is destructively changed. All variable symbols
+ in map which appear in term are replaced by the skolem functions
+ with respect to allist which contains the universally quantified
+ variables.
+***************************************************************/
+{
+ TERM term1;
+ LIST scan,scan1;
+ SYMBOL skolem, symbol;
+ int bottom;
+
+ bottom = vec_ActMax();
+
+ for (scan1=map; !list_Empty(scan1); scan1=list_Cdr(scan1)) {
+ vec_Push(term);
+ symbol = (SYMBOL) list_PairFirst((LIST) list_Car(scan1));
+ skolem = (SYMBOL) list_PairSecond((LIST) list_Car(scan1));
+
+#ifdef CHECK_STRSKOLEM
+ if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+ fputs("\nVariable : ", stdout);
+ symbol_Print(symbol);
+ fputs("\nFunction : ", stdout);
+ symbol_Print(skolem);
+ }
+#endif
+ while (bottom != vec_ActMax()) {
+ term1 = (TERM)vec_PopResult();
+
+ if (symbol_Equal(term_TopSymbol(term1),symbol)) {
+ term_RplacTop(term1,skolem);
+ list_Delete(term_ArgumentList(term1));
+ term_RplacArgumentList(term1,term_CopyTermList(allist));
+ }
+ if (!list_Empty(term_ArgumentList(term1)))
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan)) {
+ vec_Push(list_Car(scan));
+ }
+ }
+ }
+ vec_SetMax(bottom);
+}
+
+
+static BOOL cnf_HasDeeperVariable(LIST List1, LIST List2)
+/******************************************************************
+ INPUT: Two lists of variable terms
+ RETURNS: TRUE if a variable in the first list is deeper than all variables
+ in the second list, FALSE otherwise.
+ NOTE: If cnf_VARIABLEDEPTHARRAY is not allocated this will crash
+ If new variables are introduced by strong skolemization, their
+ depth is -1.
+*******************************************************************/
+{
+ LIST scan;
+ int maxdepth1;
+
+ /* Determine maximum depth of variables in List1 */
+ maxdepth1 = 0;
+ for (scan=List1; !list_Empty(scan); scan=list_Cdr(scan)) {
+ int i;
+ i = cnf_VARIABLEDEPTHARRAY[term_TopSymbol((TERM) list_Car(scan))];
+#ifdef CHECK_STRSKOLEM
+ if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+ fputs("\nFor variable ", stdout);
+ symbol_Print(term_TopSymbol((TERM) list_Car(scan)));
+ printf(" depth is %d.", i);
+ }
+#endif
+ if (i > maxdepth1)
+ maxdepth1 = i;
+ }
+
+ /* Compare with depth of variables in List2 */
+ for (scan=List2; !list_Empty(scan); scan=list_Cdr(scan)) {
+ int i;
+ i = cnf_VARIABLEDEPTHARRAY[term_TopSymbol((TERM) list_Car(scan))];
+#ifdef CHECK_STRSKOLEM
+ if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+ fputs("\nFor variable ", stdout);
+ symbol_Print(term_TopSymbol((TERM) list_Car(scan)));
+ printf(" depth is %d.", i);
+ }
+#endif
+ if (i >= maxdepth1)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static void cnf_StrongSkolemization(PROOFSEARCH Search, TERM Topterm,
+ char* Toplabel, BOOL TopAnd, TERM Term,
+ LIST* UsedTerms, LIST* Symblist,
+ BOOL Result1,
+ HASH InputClauseToTermLabellist, int Depth)
+/******************************************************************
+ INPUT: An existence quantified formula. ??? EK
+ RETURNS: Nothing.
+ EFFECT: The existence quantifier is removed by strong skolemization.
+ The precedence of new Skolem symbols is set in the precedence
+ of the search object.
+*******************************************************************/
+{
+ LIST exlist; /* Variable symbols bound by exists[]() */
+ LIST pairlist; /* List of pairs (Subterm of AND, free variable symbols
+ not in exlist) */
+ LIST allfreevariables;
+ LIST newvariables; /* w2..wn*/
+ LIST mapping; /* List of pairs */
+ int numberofallfreevariables, acc_length, i;
+ LIST pair, pairscan, pairscan_pred, scan, accumulatedvariables;
+ TERM subterm, w;
+ BOOL strskolemsuccess; /* Indicates whether strong skolemization was
+ possible */
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ /* Necessary so that new variables really are new ! */
+ if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM))
+ symbol_SetStandardVarCounter(term_MaxVar(Topterm));
+
+ /* Get list of quantified variable symbols x_k */
+ exlist = cnf_GetSymbolList(term_ArgumentList(term_FirstArgument(Term)));
+ /* Pop quantifier */
+ term_Delete(term_FirstArgument(Term));
+ subterm = term_SecondArgument(Term);
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,term_TopSymbol(subterm));
+ term_RplacArgumentList(Term,term_ArgumentList(subterm));
+ term_Free(subterm);
+
+ /* Now for every argument get the list of free variables whose symbols
+ are not in exlist */
+ pairlist = list_Nil();
+ for (scan=term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan)) {
+ pair = list_PairCreate((TERM) list_Car(scan),
+ cnf_FreeVariablesBut((TERM) list_Car(scan), exlist));
+ if (list_Empty(pairlist))
+ pairlist = list_List(pair);
+ else {
+ /* First sort subterms by number of free variables */
+ int pairlength, currentlength;
+ pairlength = list_Length((LIST) list_PairSecond(pair));
+ pairscan = pairlist;
+ pairscan_pred = list_Nil();
+ currentlength = 0;
+ while (!list_Empty(pairscan)) {
+ currentlength = list_Length((LIST) list_PairSecond((LIST) list_Car(pairscan)));
+ if (currentlength < pairlength) {
+ pairscan_pred = pairscan;
+ pairscan = list_Cdr(pairscan);
+ }
+ else if (currentlength == pairlength) {
+ /* If both subterms have the same number of free variables compare depth of variables */
+ if (cnf_HasDeeperVariable((LIST) list_PairSecond((LIST) list_Car(pairscan)), /* in list */
+ (LIST) list_PairSecond(pair))) { /* new pair */
+#ifdef CHECK_STRSKOLEM
+ if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+ fputs("\nTerm ", stdout);
+ term_Print((TERM) list_PairFirst((LIST) list_Car(pairscan)));
+ fputs("\n has deeper variable than ", stdout);
+ term_Print((TERM) list_PairFirst(pair));
+ }
+#endif
+ pairscan_pred = pairscan;
+ pairscan = list_Cdr(pairscan);
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ /* New pair has more variables than all others in list */
+ if (list_Empty(pairscan))
+ list_Rplacd(pairscan_pred, list_List(pair));
+ /* New pair is inserted between pairscan_pred and pairscan */
+ else if (currentlength >= pairlength) {
+ /* Head of list */
+ if (list_Empty(pairscan_pred))
+ pairlist = list_Cons(pair, pairlist);
+ else
+ list_InsertNext(pairscan_pred, pair);
+ }
+ /* The case for the same number of variables is not yet implemented */
+ }
+ }
+
+#ifdef CHECK_STRSKOLEM
+ if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+ for (pairscan=pairlist; !list_Empty(pairscan); pairscan = list_Cdr(pairscan)) {
+ LIST l;
+ fputs("\nSubterm ", stdout);
+ term_Print((TERM) list_PairFirst((LIST) list_Car(pairscan)));
+ fputs("\n has free variables ", stdout);
+ for (l=(LIST) list_PairSecond((LIST) list_Car(pairscan)); !list_Empty(l); l = list_Cdr(l)) {
+ term_Print((TERM) list_Car(l));
+ fputs(" ", stdout);
+ }
+ }
+ }
+#endif
+
+ /* Determine number of all free variablein and()--term whose symbols are not in exlist */
+ /* Create map from ex_variables tp skolem symbols */
+ allfreevariables = cnf_FreeVariablesBut(Term, exlist);
+ numberofallfreevariables = list_Length(allfreevariables);
+
+ mapping = list_Nil();
+
+ for (scan = exlist; !list_Empty(scan); scan = list_Cdr(scan)) {
+ SYMBOL skolem;
+ skolem = symbol_CreateSkolemFunction(numberofallfreevariables, Precedence);
+ *Symblist = list_Cons((POINTER)skolem,*Symblist);
+ mapping = list_Cons(list_PairCreate(list_Car(scan), (POINTER)skolem),
+ mapping);
+ }
+ list_Delete(allfreevariables);
+
+ /* Create new variables */
+ newvariables = list_Nil();
+
+ for (i=0; i < numberofallfreevariables; i++) {
+ w = term_CreateStandardVariable();
+ newvariables = list_Cons(w, newvariables);
+ }
+
+#ifdef CHECK_STRSKOLEM
+ if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+ LIST l;
+ fputs("\nNew variables : ", stdout);
+ for (l=newvariables; !list_Empty(l); l = list_Cdr(l)) {
+ term_Print((TERM) list_Car(l));
+ fputs(" ", stdout);
+ }
+ }
+#endif
+
+ /* Now do the replacing */
+ accumulatedvariables = list_Nil();
+ acc_length = 0;
+ strskolemsuccess = FALSE;
+ for (pairscan=pairlist; !list_Empty(pairscan); pairscan=list_Cdr(pairscan)) {
+ LIST allist;
+
+ /* Add bound variables for this subterm */
+ accumulatedvariables = list_Nconc(accumulatedvariables,
+ (LIST) list_PairSecond((LIST) list_Car(pairscan)));
+ accumulatedvariables = term_DeleteDuplicatesFromList(accumulatedvariables);
+
+ /* Remove new variables not (no longer) needed */
+ for (i=0; i < list_Length(accumulatedvariables) - acc_length; i++) {
+ term_Delete((TERM) list_Top(newvariables));
+ newvariables = list_Pop(newvariables);
+ }
+ acc_length = list_Length(accumulatedvariables);
+
+#ifdef CHECK_STRSKOLEM
+ if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+ LIST l;
+ fputs("\n\nSubterm is ", stdout);
+ term_Print((TERM) list_PairFirst((LIST) list_Car(pairscan)));
+ fputs("\nFree variables : ", stdout);
+ for (l=accumulatedvariables; !list_Empty(l); l = list_Cdr(l)) {
+ term_Print((TERM) list_Car(l));
+ fputs(" ", stdout);
+ }
+ }
+#endif
+ if (!list_Empty(newvariables))
+ strskolemsuccess = TRUE;
+ allist = list_Nconc(list_Copy(accumulatedvariables), list_Copy(newvariables));
+
+ cnf_SkolemFunctionFormulaMapped((TERM) list_PairFirst((LIST) list_Car(pairscan)), allist,
+ mapping);
+#ifdef CHECK_STRSKOLEM
+ if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+ fputs("\nSubterm after skolemization : ", stdout);
+ term_Print(list_PairFirst((LIST) list_Car(pairscan)));
+ }
+#endif
+
+ list_Delete(allist);
+ cnf_OptimizedSkolemFormula(Search, Topterm, Toplabel, TopAnd,
+ (TERM) list_PairFirst((LIST) list_Car(pairscan)),
+ UsedTerms, Symblist, Result1,
+ InputClauseToTermLabellist, Depth);
+ }
+ while (!list_Empty(newvariables)) {
+ term_Delete((TERM) list_Top(newvariables));
+ newvariables = list_Pop(newvariables);
+ }
+ list_Delete(accumulatedvariables); /* Only pairs and pairlist left */
+ list_DeletePairList(pairlist);
+ list_Delete(exlist);
+ list_DeletePairList(mapping);
+ if (flag_GetFlagValue(Flags, flag_PSTRSKOLEM) && strskolemsuccess) {
+ fputs("\nStrong skolemization applied", stdout);
+ }
+}
+
+
+static void cnf_OptimizedSkolemFormula(PROOFSEARCH Search, TERM topterm,
+ char* toplabel, BOOL TopAnd, TERM term,
+ LIST* UsedTerms, LIST* Symblist,
+ BOOL Result1,
+ HASH InputClauseToTermLabellist,
+ int Depth)
+/**************************************************************
+ INPUT: Two terms in negation normal form. ??? EK
+ RETURNS: The skolemized term with the optimized skolemization
+ due to Ohlbach and Weidenbach of <term> and further improvements.
+ <rest> is used as additional, conjunctively added information.
+ EFFECT: The symbol precedence of the search object is changed
+ because new Skolem symbols are defined.
+ CAUTION: The term is destructively changed.
+***************************************************************/
+{
+ TERM termL2, provedterm;
+ LIST freevariables, scan, varlist;
+ SYMBOL top;
+ BOOL result2;
+ BOOL optimized;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ result2 = FALSE;
+ freevariables = list_Nil();
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ top = term_TopSymbol(term);
+ if (fol_IsQuantifier(top)) {
+ if (symbol_Equal(top,fol_All())) {
+ /* For quantified variables store depth if strong skolemization is performed */
+ if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM)) {
+ LIST variables;
+ variables = term_ArgumentList(term_FirstArgument(term));
+ for (scan=variables; !list_Empty(scan); scan=list_Cdr(scan)) {
+#ifdef CHECK_STRSKOLEM
+ if (flag_GetFlagValue(Flags, flag_PSTRSKOLEM)) {
+ if (cnf_VARIABLEDEPTHARRAY[term_TopSymbol(list_Car(scan))] != -1) {
+ fputs("\nFor variable ", stderr);
+ term_Print((TERM) list_Car(scan));
+ printf(" depth is already set to %d, now setting it to %d",
+ cnf_VARIABLEDEPTHARRAY[term_TopSymbol(list_Car(scan))],Depth);
+ }
+ }
+#endif
+#ifdef CHECK_STRSKOLEM
+ if (flag_GetFlagValue(Flags, flag_PSTRSKOLEM)) {
+ fputs("\nVariable ", stdout);
+ term_Print((TERM) list_Car(scan));
+ printf(" has depth %d in term\n ", Depth);
+ term_Print(term);
+ }
+#endif
+ cnf_VARIABLEDEPTHARRAY[term_TopSymbol(list_Car(scan))] = Depth;
+ }
+ Depth++;
+ }
+ cnf_PopAllQuantifier(term);
+ cnf_OptimizedSkolemFormula(Search,topterm, toplabel, TopAnd, term,
+ UsedTerms, Symblist, Result1,
+ InputClauseToTermLabellist, Depth);
+ return;
+ }
+ freevariables = fol_FreeVariables(term);
+ optimized = FALSE;
+ if (symbol_Equal(term_TopSymbol(term_SecondArgument(term)), fol_And())) {
+ if (flag_GetFlagValue(Flags, flag_CNFOPTSKOLEM)) {
+ scan = term_ArgumentList(term_SecondArgument(term));
+ varlist = term_ArgumentList(term_FirstArgument(term));
+ while (!list_Empty(scan) && !optimized) {
+ if (!Result1) {
+ if (TopAnd) {
+ if (flag_GetFlagValue(Flags, flag_POPTSKOLEM)) {
+ fputs("\nHaveProof not necessary", stdout);
+ }
+ result2 = TRUE;
+ }
+ else {
+ termL2 = cnf_QuantifyAndNegate((TERM) list_Car(scan),
+ varlist, freevariables);
+ result2 = cnf_HaveProofOptSkolem(Search, topterm, toplabel, termL2,
+ UsedTerms, Symblist,
+ InputClauseToTermLabellist);
+#ifdef CHECK_OPTSKOLEM
+ if (flag_GetFlagValue(Flags, flag_POPTSKOLEM)) {
+ fputs("\nHaveProof result : ", stdout);
+ if (result2)
+ fputs("TRUE", stdout);
+ else
+ fputs("FALSE", stdout);
+ }
+#endif
+ }
+ }
+
+ if (Result1 || result2) {
+ optimized = TRUE;
+ if (flag_GetFlagValue(Flags, flag_POPTSKOLEM)) {
+ fputs("\nIn term ", stdout);
+ term_Print(topterm);
+ fputs("\n subterm ", stdout);
+ term_Print((TERM) list_Car(scan));
+ puts(" is moved to toplevel.");
+ }
+ provedterm =
+ cnf_MoveProvedTermToTopLevel(topterm, term, list_Car(scan),
+ varlist, freevariables, Precedence);
+ if (flag_GetFlagValue(Flags, flag_POPTSKOLEM)) {
+ fputs("Result : ", stdout);
+ term_Print(topterm);
+ putchar('\n');
+ }
+ /* provedterm is argument of top AND term */
+ cnf_OptimizedSkolemFormula(Search, topterm, toplabel, TRUE,
+ provedterm,UsedTerms, Symblist, Result1,
+ InputClauseToTermLabellist, Depth);
+ }
+ else
+ scan = list_Cdr(scan);
+ }
+ }
+ if (!optimized) {
+ /* Optimized skolemization not enabled or not possible */
+ if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM)) {
+ optimized = TRUE; /* Strong Skolemization is always possible after exists[..](and(..)) */
+ cnf_StrongSkolemization(Search, topterm, toplabel, TopAnd, term,
+ UsedTerms, Symblist, Result1,
+ InputClauseToTermLabellist, Depth);
+ }
+ }
+ }
+ else
+ TopAnd = FALSE;
+ if (!optimized) {
+ /* Optimized skolemization not enabled or not possible */
+ /* Strong skolemization not enabled or not possible */
+ cnf_Skolemize(term, freevariables, Precedence);
+ }
+ list_Delete(freevariables);
+ cnf_OptimizedSkolemFormula(Search, topterm, toplabel, TopAnd, term,UsedTerms,
+ Symblist,Result1,InputClauseToTermLabellist,Depth);
+ return;
+ }
+ else {
+ if (symbol_Equal(top,fol_And()) || symbol_Equal(top,fol_Or())) {
+ if (symbol_Equal(top,fol_Or()))
+ TopAnd = FALSE;
+ for (scan=term_ArgumentList(term);!list_Empty(scan);
+ scan=list_Cdr(scan))
+ cnf_OptimizedSkolemFormula(Search, topterm, toplabel, TopAnd,
+ (TERM) list_Car(scan),
+ UsedTerms, Symblist,
+ Result1, InputClauseToTermLabellist, Depth);
+ }
+ }
+ return;
+}
+
+
+static LIST cnf_SkolemFunctionFormula(TERM term, LIST allist, LIST exlist,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A term <term>, a list <allist> of variables, a list <exlist>
+ of variable symbols and a precedence.
+ RETURNS: The list of new Skolem functions.
+ EFFECT: The term is destructively changed. All variable symbols
+ in <exlist> which appear in <term> are replaced by skolem functions
+ with respect to <allist> which contains the universally quantified
+ variables.
+ New Skolem functions are created and their precedence is set
+ in <Precedence>.
+***************************************************************/
+{
+ TERM term1;
+ LIST scan, scan1, Result;
+ SYMBOL skolem;
+ int bottom,n;
+
+ Result = list_Nil();
+ bottom = vec_ActMax();
+ n = list_Length(allist);
+
+ for (scan1=exlist; !list_Empty(scan1); scan1=list_Cdr(scan1)) {
+ vec_Push(term);
+ skolem = symbol_CreateSkolemFunction(n, Precedence);
+ Result = list_Cons((POINTER)skolem, Result);
+
+ while (bottom != vec_ActMax()) {
+ term1 = (TERM)vec_PopResult();
+ if (symbol_Equal(term_TopSymbol(term1),(SYMBOL)list_Car(scan1))) {
+ term_RplacTop(term1,skolem);
+ list_Delete(term_ArgumentList(term1));
+ term_RplacArgumentList(term1,term_CopyTermList(allist));
+ }
+ if (!list_Empty(term_ArgumentList(term1)))
+ for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+ vec_Push(list_Car(scan));
+ }
+ }
+ vec_SetMax(bottom);
+ return Result;
+}
+
+
+static LIST cnf_OptimizedSkolemization(PROOFSEARCH Search, TERM Term,
+ char* Label, LIST* UsedTerms,
+ LIST* Symblist, BOOL result,
+ BOOL Conjecture,
+ HASH InputClauseToTermLabellist)
+/**************************************************************
+ INPUT: A term, a shared index and a list of non-ConClauses. ??? EK
+ RETURNS: The list of clauses derived from Term.
+ EFFECT: The term is skolemized using optimized skolemization wrt ShIndex.
+**************************************************************/
+{
+ LIST Clauses;
+ TERM FirstArg;
+ int i;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+#ifdef CHECK
+ if (Term == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_OptimizedSkolemization: Input term is NULL.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+ FirstArg = Term;
+
+ if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM)) {
+ /* Initializing array */
+ for (i = 1; i <= symbol__MAXSTANDARDVAR; i++)
+ cnf_VARIABLEDEPTHARRAY[i] = -1;
+ }
+
+ if (flag_GetFlagValue(Flags, flag_POPTSKOLEM) ||
+ flag_GetFlagValue(Flags, flag_PSTRSKOLEM)) {
+ fputs("\nTerm before skolemization : \n ", stdout);
+ fol_PrettyPrintDFG(Term);
+ }
+
+ if (!fol_IsLiteral(Term)) {
+ if (flag_GetFlagValue(Flags, flag_CNFOPTSKOLEM) ||
+ flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM)) {
+ if (flag_GetFlagValue(Flags, flag_CNFOPTSKOLEM))
+ Term = term_Create(fol_And(), list_List(Term)); /* CW hack: definitions are added on top level*/
+ cnf_OptimizedSkolemFormula(Search, Term, Label, TRUE, FirstArg, UsedTerms,
+ Symblist, result, InputClauseToTermLabellist, 0);
+ }
+ else {
+ LIST Symbols;
+ Symbols = list_Nil();
+ Term = cnf_SkolemFormula(Term, Precedence, &Symbols);
+ list_Delete(Symbols);
+ }
+ }
+ if (flag_GetFlagValue(Flags, flag_POPTSKOLEM) ||
+ flag_GetFlagValue(Flags, flag_PSTRSKOLEM)) {
+ fputs("\nTerm after skolemization : ", stdout);
+ term_Print(Term);
+ }
+ Term = cnf_DistributiveFormula(Term);
+ Clauses = cnf_MakeClauseList(Term, FALSE, Conjecture, Flags, Precedence);
+ term_Delete(Term);
+
+ return Clauses;
+}
+
+
+LIST cnf_GetSkolemFunctions(TERM Term, LIST ArgList, LIST* SkolToExVar)
+/**************************************************************
+ INPUT: A term, the argumentlist of a skolem function, a mapping from
+ a skolem function to a variable
+ RETURNS: The longest argumentlist of all skolem functions found so far.
+ EFFECT: Computes information for renaming variables and replacing
+ skolem functions during de-skolemization.
+**************************************************************/
+{
+ LIST Scan;
+ SYMBOL Top;
+
+ Top = term_TopSymbol(Term);
+
+ if (fol_IsQuantifier(Top))
+ return cnf_GetSkolemFunctions(term_SecondArgument(Term), ArgList,
+ SkolToExVar);
+
+ if (symbol_IsFunction(Top) && symbol_HasProperty(Top, SKOLEM)) {
+ BOOL found;
+ SYMBOL Var = 0;
+ int Arity;
+ found = FALSE;
+
+ /* Keep longest argument list of all skolem functions in the clause for renaming */
+ /* Delete all other argument lists */
+ Arity = list_Length(term_ArgumentList(Term));
+ if (Arity > list_Length(ArgList)) {
+ term_DeleteTermList(ArgList);
+ ArgList = term_ArgumentList(Term);
+ }
+ else
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term, NULL);
+
+ /* Replace skolem function by variable */
+ if (list_Length(*SkolToExVar) > Arity) {
+ NAT i;
+ LIST SkolScan = *SkolToExVar;
+ for (i = 0; i < Arity; i++)
+ SkolScan = list_Cdr(SkolScan);
+ for (SkolScan = (LIST) list_Car(SkolScan);
+ (SkolScan != list_Nil()) && !found; SkolScan = list_Cdr(SkolScan)) {
+ SYMBOL Skol;
+ Skol = (SYMBOL) list_PairFirst((LIST) list_Car(SkolScan));
+ if (Skol == term_TopSymbol(Term)) {
+ Var = (SYMBOL) list_PairSecond((LIST) list_Car(SkolScan));
+ found = TRUE;
+ }
+ }
+ }
+ if (!found) {
+ LIST Pair;
+ NAT i;
+ LIST SkolScan;
+
+ SkolScan = *SkolToExVar;
+ for (i = 0; i < Arity; i++) {
+ if (list_Cdr(SkolScan) == list_Nil())
+ list_Rplacd(SkolScan, list_List(NULL));
+ SkolScan = list_Cdr(SkolScan);
+ }
+
+ Var = symbol_CreateStandardVariable();
+ Pair = list_PairCreate((POINTER) term_TopSymbol(Term),
+ (POINTER) Var);
+ if (list_Car(SkolScan) == list_Nil())
+ list_Rplaca(SkolScan, list_List(Pair));
+ else
+ list_Rplaca(SkolScan, list_Nconc((LIST) list_Car(SkolScan),
+ list_List(Pair)));
+ }
+ term_RplacTop(Term, Var);
+ }
+ else {
+ for (Scan = term_ArgumentList(Term); Scan != list_Nil();
+ Scan = list_Cdr(Scan))
+ ArgList = cnf_GetSkolemFunctions((TERM) list_Car(Scan), ArgList,
+ SkolToExVar);
+ }
+ return ArgList;
+}
+
+
+void cnf_ReplaceVariable(TERM Term, SYMBOL Old, SYMBOL New)
+/**************************************************************
+ INPUT: A term, two symbols that are variables
+ EFFECT: In term every occurrence of Old is replaced by New
+**************************************************************/
+{
+ LIST Scan;
+
+#ifdef CHECK
+ if (!symbol_IsVariable(Old)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_ReplaceVariable: Illegal input symbol.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (symbol_Equal(term_TopSymbol(Term), Old))
+ term_RplacTop(Term, New);
+ else
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan);
+ Scan = list_Cdr(Scan))
+ cnf_ReplaceVariable(list_Car(Scan), Old, New);
+}
+
+
+LIST cnf_RemoveSkolemFunctions(CLAUSE Clause, LIST* SkolToExVar, LIST Vars)
+/**************************************************************
+ INPUT: A clause, a list which is a mapping from skolem functions to
+ variables and a list of variables for forall-quantification.
+ RETURNS: A list of terms derived from the clause using deskolemization
+ EFFECT: Arguments of skolem functions are renamed consistently.
+ Skolemfunctions are replaced by variables.
+**************************************************************/
+{
+ LIST Scan;
+ LIST TermScan, TermList, ArgList;
+ TERM Term;
+ int i;
+
+ TermList = list_Nil();
+
+ ArgList = list_Nil();
+ for (i = 0; i < clause_Length(Clause); i++) {
+ Term = term_Copy(clause_GetLiteralTerm(Clause, i));
+ ArgList = cnf_GetSkolemFunctions(Term, ArgList, SkolToExVar);
+ TermList = list_Cons(Term, TermList);
+ }
+
+ if (list_Empty(ArgList))
+ return TermList;
+
+ /* Rename variables */
+ for (Scan = ArgList; Scan != list_Nil(); Scan = list_Cdr(Scan)) {
+ for (TermScan = TermList; TermScan != list_Nil();
+ TermScan = list_Cdr(TermScan)) {
+ Term = (TERM) list_Car(TermScan);
+ cnf_ReplaceVariable(Term,
+ term_TopSymbol((TERM) list_Car(Scan)),
+ (SYMBOL) list_Car(Vars));
+ }
+ if (list_Cdr(Vars) == list_Nil()) {
+ SYMBOL New = symbol_CreateStandardVariable();
+ Vars = list_Nconc(Vars, list_List((POINTER) New));
+ }
+ Vars = list_Cdr(Vars);
+ }
+ term_DeleteTermList(ArgList);
+ return TermList;
+}
+
+
+TERM cnf_DeSkolemFormula(LIST Clauses)
+/**************************************************************
+ INPUT: A list of clauses.
+ RETURNS: A formula built from the clauses.
+ EFFECT: All skolem functions are removed from the clauses.
+**************************************************************/
+{
+ LIST Scan, SkolToExVar, Vars, FreeVars, FreeVarsCopy, VarScan, TermList;
+ TERM VarListTerm, TopTerm, Term;
+ BOOL First;
+
+ SkolToExVar = list_List(NULL);
+ Vars = list_List((POINTER) symbol_CreateStandardVariable());
+
+ TopTerm = term_Create(fol_And(), NULL);
+
+ for (Scan = Clauses; Scan != list_Nil(); Scan = list_Cdr(Scan)) {
+ TermList = cnf_RemoveSkolemFunctions((CLAUSE) list_Car(Scan),
+ &SkolToExVar, Vars);
+ Term = term_Create(fol_Or(), TermList);
+ FreeVars = fol_FreeVariables(Term);
+ if (!list_Empty(FreeVars)) {
+ FreeVarsCopy = term_CopyTermList(FreeVars);
+ list_Delete(FreeVars);
+ Term = fol_CreateQuantifier(fol_All(), FreeVarsCopy, list_List(Term));
+ }
+ term_RplacArgumentList(TopTerm, list_Cons(Term, term_ArgumentList(TopTerm)));
+ }
+
+ VarScan = Vars;
+ First = TRUE;
+
+ for (Scan = SkolToExVar; Scan != list_Nil(); Scan = list_Cdr(Scan)) {
+ if (list_Empty(list_Car(Scan))) {
+ if (term_TopSymbol(TopTerm) == fol_All())
+ term_RplacArgumentList(TopTerm, list_Cons(term_Create((SYMBOL) list_Car(VarScan), NULL),
+ term_ArgumentList(TopTerm)));
+ if (!First)
+ TopTerm = fol_CreateQuantifier(fol_All(),
+ list_List(term_Create((SYMBOL) list_Car(VarScan), NULL)),
+ list_List(TopTerm));
+ }
+ else {
+ LIST ExVarScan;
+ LIST ExVars = list_Nil();
+ for (ExVarScan = list_Car(Scan); ExVarScan != list_Nil();
+ ExVarScan = list_Cdr(ExVarScan)) {
+ if (ExVars == list_Nil())
+ ExVars = list_List(term_Create((SYMBOL) list_PairSecond((LIST) list_Car(ExVarScan)), NULL));
+ else
+ ExVars = list_Cons(term_Create((SYMBOL) list_PairSecond((LIST) list_Car(ExVarScan)), NULL), ExVars);
+ list_PairFree((LIST) list_Car(ExVarScan));
+ }
+ list_Delete((LIST) list_Car(Scan));
+ list_Rplaca(Scan, NULL);
+
+ if (term_TopSymbol(TopTerm) == fol_Exist()) {
+ VarListTerm = (TERM) list_Car(term_ArgumentList(TopTerm));
+ term_RplacArgumentList(VarListTerm,
+ list_Nconc(term_ArgumentList(VarListTerm),
+ ExVars));
+ }
+ else
+ TopTerm = fol_CreateQuantifier(fol_Exist(), ExVars, list_List(TopTerm));
+ ExVars = list_Nil();
+
+ if (!First)
+ TopTerm = fol_CreateQuantifier(fol_All(),
+ list_List(term_Create((SYMBOL) list_Car(VarScan), NULL)),
+ list_List(TopTerm));
+ }
+ if (!First)
+ VarScan = list_Cdr(VarScan);
+ else
+ First = FALSE;
+
+ }
+ list_Delete(SkolToExVar);
+ list_Delete(Vars);
+
+ return TopTerm;
+}
+
+
+#ifdef OPTCHECK
+/* Currently unused */
+/*static */
+LIST cnf_CheckOptimizedSkolemization(LIST* AxClauses, LIST* ConClauses,
+ TERM AxTerm, TERM ConTerm,
+ LIST NonConClauses, LIST* SkolemPredicates,
+ SHARED_INDEX ShIndex, BOOL result)
+/**********************************************************
+ EFFECT: Used to check the correctness of optimized skolemization
+***********************************************************/
+{
+ TERM DeSkolemizedAxOpt, DeSkolemizedConOpt, DeSkolemizedAx, DeSkolemizedCon;
+ TERM TopOpt, Top, ToProve;
+ LIST SkolemFunctions2;
+
+ if (*AxClauses != list_Nil()) {
+ DeSkolemizedAxOpt = cnf_DeSkolemFormula(*AxClauses);
+ if (*ConClauses != list_Nil()) {
+ DeSkolemizedConOpt = cnf_DeSkolemFormula(*ConClauses);
+ TopOpt = term_Create(fol_And(),
+ list_Cons(DeSkolemizedAxOpt,
+ list_List(DeSkolemizedConOpt)));
+ }
+ else
+ TopOpt = DeSkolemizedAxOpt;
+ }
+ else {
+ DeSkolemizedConOpt = cnf_DeSkolemFormula(*ConClauses);
+ TopOpt = DeSkolemizedConOpt;
+ }
+
+ clause_DeleteClauseList(*AxClauses);
+ clause_DeleteClauseList(*ConClauses);
+ *AxClauses = list_Nil();
+ *ConClauses = list_Nil();
+
+ flag_SetFlagValue(flag_CNFOPTSKOLEM, flag_CNFOPTSKOLEMOFF);
+ if (AxTerm) {
+ *AxClauses = cnf_OptimizedSkolemization(term_Copy(AxTerm), ShIndex, NonConClauses, result,FALSE, ClauseToTermLabellist);
+ }
+ if (ConTerm) {
+ *ConClauses = cnf_OptimizedSkolemization(term_Copy(ConTerm), ShIndex, NonConClauses, result,TRUE, ClauseToTermLabellist);
+ }
+
+ if (*AxClauses != list_Nil()) {
+ DeSkolemizedAx = cnf_DeSkolemFormula(*AxClauses);
+ if (*ConClauses != list_Nil()) {
+ DeSkolemizedCon = cnf_DeSkolemFormula(*ConClauses);
+ Top = term_Create(fol_And(),
+ list_Cons(DeSkolemizedAx,
+ list_List(DeSkolemizedCon)));
+ }
+ else
+ Top = DeSkolemizedAx;
+ }
+ else {
+ DeSkolemizedCon = cnf_DeSkolemFormula(*ConClauses);
+ Top = DeSkolemizedCon;
+ }
+
+ clause_DeleteClauseList(*AxClauses);
+ clause_DeleteClausList(*ConClauses);
+ *AxClauses = list_Nil();
+ *ConClauses = list_Nil();
+
+ ToProve = term_Create(fol_Equiv(), list_Cons(TopOpt, list_List(Top)));
+ ToProve = term_Create(fol_Not(), list_List(ToProve));
+ fol_NormalizeVars(ToProve);
+ ToProve = cnf_ObviousSimplifications(ToProve);
+ term_AddFatherLinks(ToProve);
+ ToProve = ren_Rename(ToProve,SkolemPredicates,FALSE);
+ ToProve = cnf_RemoveEquivImplFromFormula(ToProve);
+ ToProve = cnf_NegationNormalFormula(ToProve);
+ ToProve = cnf_AntiPrenex(ToProve);
+
+ SkolemFunctions2 = list_Nil();
+ ToProve = cnf_SkolemFormula(ToProve, &SkolemFunctions2);
+ ToProve = cnf_DistributiveFormula(ToProve);
+ *ConClauses = cnf_MakeClauseList(ToProve);
+ if (ToProve)
+ term_Delete(ToProve);
+ *AxClauses = list_Nil();
+ return SkolemFunctions2;
+}
+#endif
+
+
+PROOFSEARCH cnf_Flotter(LIST AxiomList, LIST ConjectureList, LIST* AxClauses,
+ LIST* AllLabels, HASH TermLabelToClauselist,
+ HASH ClauseToTermLabellist, FLAGSTORE InputFlags,
+ PRECEDENCE InputPrecedence, LIST* Symblist)
+/**************************************************************
+ INPUT: A list of axiom formulae,
+ a list of conjecture formulae,
+ a pointer to a list in which clauses derived from axiom formulae
+ are stored,
+ a pointer to a list in which clauses derived from
+ conjecture formulae are stored, ???
+ a pointer to a list of all termlabels,
+ a hasharray in which for every term label the list of clauses
+ derived from the term is stored (if DocProof is set),
+ a hasharray in which for every clause the list of labels
+ of the terms used for deriving the clause is stored (if DocProof
+ is set),
+ a flag store,
+ a precedence
+ a pointer to a list of symbols which have to be deleted later if
+ the ProofSearch object is kept.
+ RETURNS: If KeepProofSearch ??? is TRUE, then the ProofSearch object is not
+ freed but returned.
+ Else, NULL is returned.
+ EFFECT: ??? EK
+ The precedence of new skolem symbols is set in <InputPrecedence>.
+***************************************************************/
+{
+ LIST Scan, Scan2, FormulaClauses,SkolemFunctions;
+ LIST SkolemPredicates, EmptyClauses, AllFormulae;
+ LIST UsedTerms;
+ TERM AxTerm,Formula;
+ BOOL Result;
+ PROOFSEARCH Search;
+ PRECEDENCE Precedence;
+ FLAGSTORE Flags;
+ NAT Count;
+ HASH InputClauseToTermLabellist;
+
+ Search = prfs_Create();
+
+ /* Initialize the flagstore for the CNF transformation */
+ Flags = prfs_Store(Search);
+ flag_CleanStore(Flags);
+ flag_InitFlotterFlags(InputFlags, Flags);
+ /* Initialize the precedence */
+ Precedence = prfs_Precedence(Search);
+ symbol_TransferPrecedence(InputPrecedence, Precedence);
+
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ prfs_AddDocProofSharingIndex(Search);
+
+ AxTerm = (TERM)NULL;
+ SkolemPredicates = list_Nil();
+ Result = FALSE;
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ InputClauseToTermLabellist = hsh_Create();
+ else
+ InputClauseToTermLabellist = NULL;
+
+ symbol_ReinitGenericNameCounters();
+
+ for (Scan = AxiomList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ LIST Pair;
+ Pair = list_Car(Scan);
+ AxTerm = (TERM) list_PairSecond(Pair);
+ fol_RemoveImplied(AxTerm);
+ term_AddFatherLinks(AxTerm);
+ fol_NormalizeVars(AxTerm);
+ if (flag_GetFlagValue(Flags, flag_CNFFEQREDUCTIONS))
+ cnf_PropagateSubstEquations(AxTerm);
+ AxTerm = cnf_ObviousSimplifications(AxTerm);
+ if (flag_GetFlagValue(Flags, flag_CNFRENAMING)) {
+ term_AddFatherLinks(AxTerm);
+ AxTerm = ren_Rename(AxTerm, Precedence, &SkolemPredicates,
+ flag_GetFlagValue(Flags, flag_CNFPRENAMING), TRUE);
+ }
+ AxTerm = cnf_RemoveEquivImplFromFormula(AxTerm);
+ AxTerm = cnf_NegationNormalFormula(AxTerm);
+ AxTerm = cnf_AntiPrenex(AxTerm);
+ list_Rplacd(Pair, (LIST) AxTerm);
+ }
+ AllFormulae = AxiomList;
+
+ /* At this point the list contains max. 1 element, which is a pair
+ of the label NULL and the negated
+ conjunction of all conjecture formulae. */
+
+ Count = 0;
+ for (Scan = ConjectureList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ TERM ConTerm;
+ char* Label;
+ char buf[100];
+ /* Add label */
+ if (list_PairFirst(list_Car(Scan)) == NULL) {
+ sprintf(buf, "conjecture%d", Count);
+ Label = string_StringCopy(buf);
+ list_Rplaca((LIST) list_Car(Scan), Label);
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF) &&
+ flag_GetFlagValue(Flags, flag_PLABELS)) {
+ printf("\nAdded label %s for conjecture", Label);
+ fol_PrettyPrintDFG((TERM) list_PairSecond(list_Car(Scan)));
+ }
+ }
+
+ ConTerm = (TERM) list_PairSecond((LIST) list_Car(Scan));
+ fol_RemoveImplied(ConTerm);
+ term_AddFatherLinks(ConTerm);
+ fol_NormalizeVars(ConTerm);
+ if (flag_GetFlagValue(Flags, flag_CNFFEQREDUCTIONS))
+ cnf_PropagateSubstEquations(ConTerm);
+ ConTerm = cnf_ObviousSimplifications(ConTerm);
+
+ if (flag_GetFlagValue(Flags, flag_CNFRENAMING)) {
+ term_AddFatherLinks(ConTerm);
+ ConTerm = ren_Rename(ConTerm, Precedence, &SkolemPredicates,
+ flag_GetFlagValue(Flags, flag_CNFPRENAMING),TRUE);
+ }
+ /* fputs("\nRen:\t",stdout);term_Print(ConTerm);putchar('\n'); */
+ ConTerm = cnf_RemoveEquivImplFromFormula(ConTerm);
+ ConTerm = cnf_NegationNormalFormula(ConTerm);
+ /* fputs("\nAn:\t",stdout);term_Print(ConTerm);putchar('\n'); */
+ ConTerm = cnf_AntiPrenex(ConTerm);
+ /* fputs("\nPr:\t",stdout);term_Print(ConTerm);putchar('\n'); */
+ /* Insert changed term into pair */
+ list_Rplacd((LIST) list_Car(Scan), (LIST) ConTerm);
+
+ Count++;
+ }
+
+ AllFormulae = list_Append(ConjectureList, AllFormulae);
+ for (Scan = ConjectureList;!list_Empty(Scan); Scan = list_Cdr(Scan))
+ list_Rplaca(Scan,list_PairSecond(list_Car(Scan)));
+
+ FormulaClauses = list_Nil();
+ SkolemFunctions = list_Nil();
+ Count = 0;
+ for (Scan = AllFormulae; !list_Empty(Scan); Scan = list_Cdr(Scan), Count++) {
+ LIST FormulaClausesTemp;
+ Formula = term_Copy((TERM) list_PairSecond(list_Car(Scan)));
+#ifdef CHECK_CNF
+ fputs("\nInputFormula : ",stdout); term_Print(Formula);
+ printf("\nLabel : %s", (char*) list_PairFirst(list_Car(Scan)));
+#endif
+ Formula = cnf_SkolemFormula(Formula,Precedence,&SkolemFunctions);
+ Formula = cnf_DistributiveFormula(Formula);
+ FormulaClausesTemp = cnf_MakeClauseList(Formula,FALSE,FALSE,Flags,Precedence);
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+ for (Scan2 = FormulaClausesTemp; !list_Empty(Scan2); Scan2 = list_Cdr(Scan2)) {
+ hsh_Put(InputClauseToTermLabellist, list_Car(Scan2), list_PairFirst(list_Car(Scan)));
+ }
+ }
+ FormulaClauses = list_Nconc(FormulaClauses, FormulaClausesTemp);
+ term_Delete(Formula);
+ }
+
+ /* Trage nun Formula Clauses modulo Reduktion in einen Index ein */
+
+ /* red_SatUnit works only on conclauses */
+ for (Scan = FormulaClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ clause_SetFlag((CLAUSE) list_Car(Scan), CONCLAUSE);
+ /* For FormulaClauses a full saturation */
+ /* List is deleted in red_SatUnit ! */
+ EmptyClauses = red_SatUnit(Search, FormulaClauses);
+ if (!list_Empty(EmptyClauses)) {
+ Result = TRUE;
+ /*puts("\nPROOF in FormulaClauses");*/
+ clause_DeleteClauseList(EmptyClauses);
+ }
+
+ /* Move all usables to workedoff */
+ FormulaClauses = list_Copy(prfs_UsableClauses(Search));
+ for (Scan = FormulaClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ prfs_MoveUsableWorkedOff(Search, (CLAUSE) list_Car(Scan));
+ list_Delete(FormulaClauses);
+ FormulaClauses = list_Nil();
+
+#ifdef CHECK
+ /*cnf_CheckClauseListsConsistency(ShIndex); */
+#endif
+
+
+ *Symblist = list_Nil();
+ for (Scan = AllFormulae; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ LIST Ax, Pair;
+ UsedTerms = list_Nil();
+ Pair = list_Car(Scan);
+#ifdef CHECK_CNF
+ fputs("\nFormula : ", stdout);
+ term_Print((TERM) list_PairSecond(Pair));
+ printf("\nLabel : %s", (char*) list_PairFirst(Pair));
+#endif
+ Ax = cnf_OptimizedSkolemization(Search, term_Copy((TERM)list_PairSecond(Pair)),
+ (char*) list_PairFirst(Pair), &UsedTerms,
+ Symblist,Result,FALSE,InputClauseToTermLabellist);
+ /* Set CONCLAUSE flag for clauses derived from conjectures */
+ if (list_PointerMember(ConjectureList,list_PairSecond(Pair))) {
+ LIST l;
+ for (l = Ax; !list_Empty(l); l = list_Cdr(l))
+ clause_SetFlag((CLAUSE) list_Car(l), CONCLAUSE);
+ }
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+ hsh_PutListWithCompareFunc(TermLabelToClauselist, list_PairFirst(Pair),
+ list_Copy(Ax),
+ (BOOL (*)(POINTER,POINTER))cnf_LabelEqual,
+ (unsigned long (*)(POINTER))hsh_StringHashKey);
+ UsedTerms = list_Cons(list_PairFirst(Pair), UsedTerms);
+ UsedTerms = cnf_DeleteDuplicateLabelsFromList(UsedTerms);
+ for (Scan2 = Ax; !list_Empty(Scan2); Scan2 = list_Cdr(Scan2)) {
+ hsh_PutList(ClauseToTermLabellist, list_Car(Scan2), list_Copy(UsedTerms));
+ hsh_PutList(InputClauseToTermLabellist, list_Car(Scan2), list_Copy(UsedTerms));
+ }
+ }
+ *AxClauses = list_Nconc(*AxClauses, Ax);
+ list_Delete(UsedTerms);
+ }
+
+ /* Transfer precedence of new skolem symbols into <InputPrecedence> */
+ symbol_TransferPrecedence(Precedence, InputPrecedence);
+
+ list_Delete(ConjectureList);
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ hsh_Delete(InputClauseToTermLabellist);
+ if (!flag_GetFlagValue(Flags, flag_INTERACTIVE)) {
+ list_Delete(*Symblist);
+ }
+
+ *AllLabels = list_Nil();
+ for (Scan = AllFormulae; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ LIST Pair;
+ Pair = list_Car(Scan);
+ term_Delete((TERM) list_PairSecond(Pair));
+ *AllLabels = list_Cons(list_PairFirst(Pair), *AllLabels);
+ list_PairFree(Pair);
+ }
+
+ list_Delete(AllFormulae);
+ list_Delete(SkolemFunctions);
+ list_Delete(SkolemPredicates);
+
+ if (!flag_GetFlagValue(Flags, flag_INTERACTIVE)) {
+ symbol_ResetSkolemIndex();
+ prfs_Delete(Search);
+ return NULL;
+ }
+ else {
+ /* Delete DocProof clauses */
+ prfs_DeleteDocProof(Search);
+ return Search;
+ }
+}
+
+LIST cnf_QueryFlotter(PROOFSEARCH Search, TERM Term, LIST* Symblist)
+/**************************************************************
+ INPUT: A term to derive clauses from, using optimized skolemization,
+ and a ProofSearch object.
+ RETURNS: A list of derived clauses.
+ EFFECT: ??? EK
+ The precedence of new skolem symbols is set in <Search>.
+***************************************************************/
+{
+ LIST SkolemPredicates, SkolemFunctions, IndexedClauses, Scan;
+ LIST ResultClauses, Dummy, EmptyClauses;
+ TERM TermCopy;
+ int Formulae2Clause;
+ BOOL Result;
+ FLAGSTORE Flags, SubProofFlags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ /* Initialize the flagstore of the cnf_SEARCHCOPY object with default values */
+ /* and copy the value of flag_DOCPROOF from the global Proofserach object. */
+ SubProofFlags = prfs_Store(cnf_SEARCHCOPY);
+ flag_InitStoreByDefaults(SubProofFlags);
+ flag_TransferFlag(Flags, SubProofFlags, flag_DOCPROOF);
+ /* Transfer the precedence into the local search object */
+ symbol_TransferPrecedence(Precedence, prfs_Precedence(cnf_SEARCHCOPY));
+
+ SkolemPredicates = SkolemFunctions = list_Nil();
+ Result = FALSE;
+
+ prfs_CopyIndices(Search, cnf_SEARCHCOPY);
+
+ Term = term_Create(fol_Not(), list_List(Term));
+ fol_NormalizeVars(Term);
+ Term = cnf_ObviousSimplifications(Term);
+ if (flag_GetFlagValue(Flags, flag_CNFRENAMING)) {
+ term_AddFatherLinks(Term);
+ Term = ren_Rename(Term, Precedence, &SkolemPredicates,
+ flag_GetFlagValue(Flags,flag_CNFPRENAMING), TRUE);
+ }
+ Term = cnf_RemoveEquivImplFromFormula(Term);
+ Term = cnf_NegationNormalFormula(Term);
+ Term = cnf_AntiPrenex(Term);
+
+ TermCopy = term_Copy(Term);
+ TermCopy = cnf_SkolemFormula(TermCopy, Precedence, &SkolemFunctions);
+ TermCopy = cnf_DistributiveFormula(TermCopy);
+
+ IndexedClauses = cnf_MakeClauseList(TermCopy,FALSE,FALSE,Flags,Precedence);
+ term_Delete(TermCopy);
+
+ /* red_SatUnit works only on conclauses */
+ for (Scan = IndexedClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ clause_SetFlag((CLAUSE) list_Car(Scan), CONCLAUSE);
+
+ EmptyClauses = red_SatUnit(cnf_SEARCHCOPY, IndexedClauses);
+
+ if (!list_Empty(EmptyClauses)) {
+ Result = TRUE;
+ clause_DeleteClauseList(EmptyClauses);
+ }
+
+ while (!list_Empty(prfs_UsableClauses(cnf_SEARCHCOPY))) {
+ prfs_MoveUsableWorkedOff(cnf_SEARCHCOPY, (CLAUSE) list_Car(prfs_UsableClauses(cnf_SEARCHCOPY)));
+ }
+ /* Works only if DOCPROOF is false. Otherwise we need labels */
+ Dummy = list_Nil();
+ if (flag_GetFlagValue(SubProofFlags, flag_DOCPROOF))
+ Formulae2Clause = TRUE;
+ else
+ Formulae2Clause = FALSE;
+ flag_SetFlagValue(SubProofFlags, flag_DOCPROOF, flag_DOCPROOFOFF);
+ ResultClauses = cnf_OptimizedSkolemization(cnf_SEARCHCOPY, term_Copy(Term),
+ NULL, &Dummy, Symblist, Result,
+ FALSE, NULL);
+
+ if (Formulae2Clause)
+ flag_SetFlagValue(SubProofFlags, flag_DOCPROOF, flag_DOCPROOFON);
+
+ term_Delete(Term);
+ list_Delete(SkolemPredicates);
+ list_Delete(SkolemFunctions);
+ prfs_Clean(cnf_SEARCHCOPY);
+
+ /* All result clauses of queries are conjecture clauses */
+ for (Scan=ResultClauses; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ clause_SetFlag((CLAUSE) list_Car(Scan), CONCLAUSE);
+
+ return ResultClauses;
+}
+
+
+#ifdef CHECK
+/* Currently unused */
+/*static*/ void cnf_CheckClauseListsConsistency(SHARED_INDEX ShIndex)
+/**************************************************************
+ INPUT: A shared index and a list of non-ConClauses.
+ EFFECT: When this function is called all clauses in the index must be
+ non-ConClauses, which must also be members of the list.
+**************************************************************/
+{
+ LIST AllClauses, scan;
+
+ AllClauses = clause_AllIndexedClauses(ShIndex);
+ for (scan = AllClauses; scan != list_Nil(); scan = list_Cdr(scan)) {
+ if (clause_GetFlag((CLAUSE) list_Car(scan), CONCLAUSE)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_CheckClauseListsConsistency: Clause is a CONCLAUSE.\n");
+ misc_FinishErrorReport();
+ }
+ if (clause_GetFlag((CLAUSE) list_Car(scan), BLOCKED)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_CheckClauseListsConsistency: Clause is BLOCKED.\n");
+ misc_FinishErrorReport();
+ }
+ }
+ list_Delete(AllClauses);
+}
+#endif
+
+
+static LIST cnf_SatUnit(PROOFSEARCH Search, LIST ClauseList)
+/*********************************************************
+ INPUT: A list of unshared clauses, proof search object
+ RETURNS: A possibly empty list of empty clauses.
+**********************************************************/
+{
+ CLAUSE Given;
+ LIST Scan, Derivables, EmptyClauses, BackReduced;
+ NAT n, Derived;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+ Derived = flag_GetFlagValue(Flags, flag_CNFPROOFSTEPS);
+ EmptyClauses = list_Nil();
+ ClauseList = clause_ListSortWeighed(ClauseList);
+
+ while (!list_Empty(ClauseList) && list_Empty(EmptyClauses)) {
+ Given = (CLAUSE)list_NCar(&ClauseList);
+ Given = red_CompleteReductionOnDerivedClause(Search, Given, red_ALL);
+ if (Given) {
+ if (clause_IsEmptyClause(Given))
+ EmptyClauses = list_List(Given);
+ else {
+ /*fputs("\n\nGiven: ",stdout);clause_Print(Given);*/
+ BackReduced = red_BackReduction(Search, Given, red_USABLE);
+
+ if (Derived != 0) {
+ Derivables =
+ inf_BoundedDepthUnitResolution(Given, prfs_UsableSharingIndex(Search),
+ FALSE, Flags, Precedence);
+ Derivables =
+ list_Nconc(Derivables,
+ inf_BoundedDepthUnitResolution(Given,prfs_WorkedOffSharingIndex(Search),
+ FALSE, Flags, Precedence));
+ n = list_Length(Derivables);
+ if (n > Derived)
+ Derived = 0;
+ else
+ Derived -= n;
+ }
+ else
+ Derivables = list_Nil();
+
+ Derivables = list_Nconc(BackReduced,Derivables);
+ Derivables = split_ExtractEmptyClauses(Derivables, &EmptyClauses);
+
+ prfs_InsertUsableClause(Search, Given);
+
+ for (Scan = Derivables; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ ClauseList = clause_InsertWeighed(list_Car(Scan), ClauseList, Flags,
+ Precedence);
+ list_Delete(Derivables);
+ }
+ }
+ }
+ clause_DeleteClauseList(ClauseList);
+ return EmptyClauses;
+}
+
+
+TERM cnf_DefTargetConvert(TERM Target, TERM ToTopLevel, TERM ToProveDef,
+ LIST DefPredArgs, LIST TargetPredArgs,
+ LIST TargetPredVars, LIST VarsForTopLevel,
+ FLAGSTORE Flags, PRECEDENCE Precedence,
+ BOOL* LocallyTrue)
+/**********************************************************
+ INPUT: A term Target which contains a predicate that might be replaced
+ by its definition.
+ A term ToTopLevel which is the highest level subterm in Target
+ that contains the predicate and can be moved to top level or().
+ A term ToProveDef which must hold if the definition is to be applied.
+ (IS DESTROYED AND FREED)
+ A list DefPredArgs of the arguments of the predicate in the
+ Definition.
+ A list TargetPredArgs of the arguments of the predicate in Target.
+ A list TargetPredVars of the variables occurring in the arguments
+ of the predicate in Target.
+ A list VarsForTopLevel containing the variables that should be
+ all-quantified at top level to make the proof easier.
+ A flag store.
+ A pointer to a boolean LocallyTrue which is set to TRUE iff
+ the definition can be applied.
+ RETURNS: The Target term which is brought into standard form.
+**********************************************************/
+
+{
+ TERM orterm, targettoprove;
+ SYMBOL maxvar; /* For normalizing terms */
+ LIST l1, l2;
+ LIST freevars, vars; /* Free variables in targettoprove */
+
+ if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+ puts("\nTarget :");
+ fol_PrettyPrint(Target);
+ }
+#ifdef CHECK
+ fol_CheckFatherLinks(Target);
+#endif
+ /* No proof found yet */
+ *LocallyTrue = FALSE;
+
+ /* Remove implications from path */
+ Target = cnf_RemoveImplFromFormulaPath(Target, ToTopLevel);
+
+ /* Move negations as far down as possible */
+ Target = cnf_NegationNormalFormulaPath(Target, ToTopLevel);
+
+ /* Move quantifiers as far down as possible */
+ Target = cnf_AntiPrenexPath(Target, ToTopLevel);
+
+ /* Move all-quantified variables from the predicates' arguments to top level */
+ Target = cnf_MovePredicateVariablesUp(Target, ToTopLevel, VarsForTopLevel);
+
+ /* Flatten top or() */
+ Target = cnf_FlattenPath(Target, ToTopLevel);
+
+ /* Now make sure that all variables in the top forall quantifier are in TargetPredVars */
+ /* Not necessary, according to CW */
+ if (symbol_Equal(term_TopSymbol(Target), fol_All())) {
+ targettoprove = term_Copy(term_SecondArgument(Target));
+ orterm = term_SecondArgument(Target);
+ }
+ else {
+ targettoprove = term_Copy(Target);
+ orterm = Target;
+ }
+
+ /* Find argument of targettoprove that contains the predicate and remove it */
+ if (symbol_Equal(term_TopSymbol(targettoprove), fol_Or())) {
+ /* Find subterm that contains the predicate */
+ LIST arglist;
+ arglist = term_ArgumentList(targettoprove);
+ for (l1=arglist, l2=term_ArgumentList(orterm); !list_Empty(l1);
+ l1 = list_Cdr(l1), l2 = list_Cdr(l2)) {
+ if (term_HasProperSuperterm(ToTopLevel, (TERM) list_Car(l2)) ||
+ (ToTopLevel == (TERM) list_Car(l2))) {
+ arglist = list_PointerDeleteElementFree(arglist, list_Car(l1),
+ (void (*)(POINTER))term_Delete);
+ break;
+ }
+ }
+ term_RplacArgumentList(targettoprove, arglist);
+ /* Nothing left for the proof ? */
+ if (list_Empty(term_ArgumentList(targettoprove))) {
+ term_Delete(targettoprove);
+ term_Delete(ToProveDef);
+#ifdef CHECK
+ fol_CheckFatherLinks(Target);
+#endif
+ return Target;
+ }
+ }
+ else {
+ /* Nothing left for the proof */
+ term_Delete(targettoprove);
+ term_Delete(ToProveDef);
+#ifdef CHECK
+ fol_CheckFatherLinks(Target);
+#endif
+ return Target;
+ }
+
+ /* Normalize variables in ToProveDef with respect to targettoprove */
+ maxvar = term_MaxVar(targettoprove);
+ symbol_SetStandardVarCounter(maxvar);
+ vars = fol_BoundVariables(ToProveDef);
+ vars = term_DeleteDuplicatesFromList(vars);
+ for (l1=vars; !list_Empty(l1); l1=list_Cdr(l1))
+ term_ExchangeVariable(ToProveDef, term_TopSymbol(list_Car(l1)), symbol_CreateStandardVariable());
+ list_Delete(vars);
+
+ /* Replace arguments of predicate in condition of definition by matching arguments
+ of predicate in target term */
+ for (l1=DefPredArgs, l2=TargetPredArgs; !list_Empty(l1); l1=list_Cdr(l1), l2=list_Cdr(l2))
+ term_ReplaceVariable(ToProveDef, term_TopSymbol((TERM) list_Car(l1)), (TERM) list_Car(l2));
+
+ targettoprove = term_Create(fol_Not(), list_List(targettoprove));
+ targettoprove = cnf_NegationNormalFormula(targettoprove);
+ targettoprove = term_Create(fol_Implies(),
+ list_Cons(targettoprove, list_List(ToProveDef)));
+
+ /* At this point ToProveDef must not be accessed again ! */
+
+ /* Add all--quantifier to targettoprove */
+ freevars = fol_FreeVariables(targettoprove);
+ term_CopyTermsInList(freevars);
+ targettoprove = fol_CreateQuantifier(fol_All(), freevars, list_List(targettoprove));
+
+ if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+ puts("\nConverted to :");
+ fol_PrettyPrint(Target);
+ }
+
+ targettoprove = cnf_NegationNormalFormula(targettoprove);
+
+ if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+ puts("\nToProve for this target :");
+ fol_PrettyPrint(targettoprove);
+ }
+
+ *LocallyTrue = cnf_HaveProof(list_Nil(), targettoprove, Flags, Precedence);
+
+ term_Delete(targettoprove);
+
+#ifdef CHECK
+ fol_CheckFatherLinks(Target);
+#endif
+
+ return Target;
+}
+
+
+static TERM cnf_RemoveQuantFromPathAndFlatten(TERM TopTerm, TERM SubTerm)
+/**********************************************************
+ INPUT: Two terms, <SubTerm> must be a subterm of <TopTerm>.
+ Superterm of <SubTerm> must be an equivalence.
+ Along the path to SubTerm there are only quantifiers or disjunctions.
+ All free variables in the equivalence are free variables
+ in <SubTerm>.
+ All free variables in <SubTerm> are bound by a universal quantifier
+ (with polarity 1).
+ RETURN: The destructively changed <TopTerm>.
+ EFFECT: Removes all quantifiers not binding a variable in <SubTerm>
+ from <subTerm>'s path.
+ Moves all universal quantifiers binding free variable
+ in <SubTerm> up.
+ <TopTerm> is transformed into the form
+ forall([X1,...,Xn],or (equiv(<SubTerm>,psi),phi)).
+**********************************************************/
+{
+ TERM Term1, Term2, Flat, Variable;
+ LIST Scan1, Scan2, FreeVars;
+
+
+#ifdef CHECK
+ if (!fol_CheckFormula(TopTerm) || !term_HasPointerSubterm(TopTerm, SubTerm)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\nIn cnf_RemoveQuantFromPathAndFlatten: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ TopTerm = cnf_SimplifyQuantors(TopTerm);
+ term_AddFatherLinks(TopTerm);
+ Term1 = term_Superterm(SubTerm);
+
+ while (Term1 != TopTerm) {
+
+ while (symbol_Equal(fol_Or(), term_TopSymbol(Term1)) && (TopTerm != Term1)) {
+ Term1 = term_Superterm(Term1);
+ }
+ if (fol_IsQuantifier(term_TopSymbol(Term1))) {
+ Flat = term_SecondArgument(Term1);
+ Flat = cnf_Flatten(Flat, fol_Or());
+ Scan1 = fol_QuantifierVariables(Term1);
+ while (!list_Empty(Scan1)) {
+ Variable = (TERM)list_Car(Scan1);
+ if (fol_VarOccursFreely(Variable, SubTerm)) {
+ Scan2 = list_Cdr(Scan1);
+ fol_DeleteQuantifierVariable(Term1, term_TopSymbol(list_Car(Scan1)));
+ Scan1 = Scan2;
+ }
+ else {
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ if (fol_IsQuantifier(term_TopSymbol(Term1))) {
+ /* still variables, but not binding a variable in the equivalence term */
+ LIST ArgList;
+
+ term_RplacArgumentList(Flat, list_PointerDeleteOneElement(term_ArgumentList(Flat), SubTerm));
+ ArgList = term_ArgumentList(Term1);
+ term_RplacArgumentList(Term1, list_Nil());
+ Term2 = term_Create(term_TopSymbol(Term1), ArgList);
+ term_RplacArgumentList(Term1, list_Cons(SubTerm, list_List(Term2)));
+ term_RplacTop(Term1, fol_Or());
+ Scan1 = term_ArgumentList(Term1);
+ while (!list_Empty(Scan1)) {
+ term_RplacSuperterm((TERM)list_Car(Scan1), Term1);
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ }
+ else {
+
+#ifdef CHECK
+ if (!symbol_Equal(term_TopSymbol(Term1), fol_Or())) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\nIn cnf_RemoveQuantFromPathAndFlatten: Illegal term Term1");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Term1 = cnf_Flatten(Term1, fol_Or());
+ }
+ }
+ FreeVars = fol_FreeVariables(Term1);
+ if (!list_Empty(FreeVars)) {
+ term_CopyTermsInList(FreeVars);
+ TopTerm = fol_CreateQuantifier(fol_All(), FreeVars, list_List(Term1));
+ }
+ return TopTerm;
+}
+
+
+TERM cnf_DefConvert(TERM Def, TERM FoundPredicate, TERM* ToProve)
+/*********************************************************
+ INPUT: A term Def which is an equivalence (P(x1,..,xn) <=> Formula)
+ that can be converted to standard form.
+ The subterm that holds the defined predicate.
+ A pointer to a term ToProve into which a term is stored
+ that has to be proved before applying the definition.
+ RETURNS: The converted definition : forall([..], or(equiv(..,..), ..))
+************************************************************/
+{
+ TERM orterm;
+
+#ifdef CHECK
+ fol_CheckFatherLinks(Def);
+#endif
+
+ Def = cnf_RemoveImplFromFormulaPath(Def, FoundPredicate); /* Remove implications along the path */
+ Def = cnf_NegationNormalFormulaPath(Def, FoundPredicate); /* Move not's as far down as possible */
+
+#ifdef CHECK
+ if (!fol_CheckFormula(Def)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\nIn cnf_DefConvert: Illegal input Formula.\n");
+ misc_FinishErrorReport();
+ }
+ if (!term_HasPointerSubterm(Def, FoundPredicate)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\nIn cnf_DefConvert: Illegal input SubTerm.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Def = cnf_RemoveQuantFromPathAndFlatten(Def, term_Superterm(FoundPredicate));
+ term_AddFatherLinks(Def);
+
+#ifdef CHECK
+ if (!fol_CheckFormula(Def)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\nIn cnf_DefConvert: Illegal term Def.");
+ misc_FinishErrorReport();
+ }
+ if (!term_HasPointerSubterm(Def, FoundPredicate)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\nIn cnf_DefConvert: Illegal term FoundPredicate.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /* Find top level or() */
+ if (symbol_Equal(term_TopSymbol(Def), fol_All())) {
+ /* Make sure there are several arguments */
+ if (symbol_Equal(term_TopSymbol(term_SecondArgument(Def)), fol_Or()) &&
+ (list_Length(term_ArgumentList(term_SecondArgument(Def))) == 1)) {
+ TERM t;
+ t = term_SecondArgument(Def);
+ term_RplacSecondArgument(Def, term_FirstArgument(term_SecondArgument(Def)));
+ term_Free(t);
+ orterm = NULL;
+ term_RplacSuperterm(term_SecondArgument(Def), Def);
+ }
+ else
+ orterm = term_SecondArgument(Def);
+ }
+ else {
+ /* Make sure there are several arguments */
+ if (symbol_Equal(term_TopSymbol(Def), fol_Or()) &&
+ (list_Length(term_ArgumentList(Def)) == 1)) {
+ TERM t;
+ t = Def;
+ Def = term_FirstArgument(Def);
+ term_Free(t);
+ orterm = NULL;
+ term_RplacSuperterm(term_SecondArgument(Def), Def);
+ }
+ else
+ orterm = Def;
+ }
+
+ /* If there is something to prove */
+ if (orterm != (TERM) NULL) {
+ TERM equiv;
+ LIST args;
+
+ equiv = (TERM) NULL;
+
+ /* In pell 10 there are no conditions for the equivalence */
+ if (symbol_Equal(term_TopSymbol(orterm), fol_Equiv())) {
+ equiv = orterm;
+ *ToProve = NULL;
+ }
+ else {
+ TERM t;
+ /* First find equivalence term among arguments */
+ args = term_ArgumentList(orterm);
+ equiv = term_Superterm(FoundPredicate);
+
+ /* Delete equivalence from list */
+ args = list_PointerDeleteElement(args, equiv);
+ term_RplacArgumentList(orterm, args);
+
+ /* ToProve consists of all the definitions arguments except the equivalence */
+ *ToProve = term_Copy(orterm);
+
+ /* Now not(*ToProve) implies the equivalence */
+ /* Negate *ToProve */
+ *ToProve = term_Create(fol_Not(), list_List(*ToProve));
+ *ToProve = cnf_NegationNormalFormula(*ToProve);
+ term_AddFatherLinks(*ToProve);
+
+ /* Now convert definition to implication form */
+ term_RplacTop(orterm, fol_Implies());
+ t = term_Create(fol_Not(),
+ list_List(term_Create(fol_Or(),
+ term_ArgumentList(orterm))));
+ term_RplacArgumentList(orterm, list_Cons(t, list_List(equiv)));
+
+ Def = cnf_NegationNormalFormula(Def);
+ term_AddFatherLinks(Def);
+ }
+ }
+
+#ifdef CHECK
+ fol_CheckFatherLinks(Def);
+#endif
+ return Def;
+}
+
+
+LIST cnf_HandleDefinition(PROOFSEARCH Search, LIST Pair, LIST Axioms,
+ LIST Sorts, LIST Conjectures)
+/*******************************************************************
+ INPUT: A PROOFSEARCH object, a pair (label, term) and 3 lists of pairs.
+ If the term in pair is a definition, the defined predicate
+ is expanded in all the lists
+ and added to the proofsearch object.
+ RETURNS: The pair with the converted definition:
+ forall([..], or(equiv(..,..), .......))
+********************************************************************/
+{
+ TERM definition, defpredicate, equivterm;
+
+ BOOL alwaysapplicable; /* Is set to TRUE iff the definition can always be applied */
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ /* The axiomlist consists of (label, formula) pairs */
+ definition = list_PairSecond(Pair);
+
+ /* Test if Definition contains a definition */
+ defpredicate = (TERM) NULL;
+ if (cnf_ContainsDefinition(definition, &defpredicate)) {
+ TERM toprove;
+ LIST allformulae, scan;
+
+ /* Create list of all formula pairs */
+ /* Check if definition may be applied to each formula */
+ allformulae = list_Copy(Axioms);
+ allformulae = list_Nconc(allformulae, list_Copy(Sorts));
+ allformulae = list_Nconc(allformulae, list_Copy(Conjectures));
+#ifdef CHECK
+ for (scan=allformulae; !list_Empty(scan); scan=list_Cdr(scan)) {
+ if (!list_Empty((LIST) list_Car(scan))) {
+ if (!term_IsTerm((TERM) list_PairSecond((LIST) list_Car(scan))))
+ fol_CheckFatherLinks((TERM) list_PairSecond((LIST) list_Car(scan)));
+ }
+ }
+#endif
+
+ /* Convert definition to standard form */
+ if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+ fputs("\nPredicate : ", stdout);
+ symbol_Print(term_TopSymbol(defpredicate));
+ }
+
+ definition = cnf_DefConvert(definition, defpredicate, &toprove);
+ if (toprove == NULL)
+ alwaysapplicable = TRUE;
+ else
+ alwaysapplicable = FALSE;
+
+ prfs_SetDefinitions(Search, list_Cons(term_Copy(definition),
+ prfs_Definitions(Search)));
+
+ if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+ if (alwaysapplicable) {
+ fputs("\nAlways Applicable : ", stdout);
+ fol_PrettyPrint(definition);
+ }
+ }
+
+ /* Definition is converted to a form where the equivalence is
+ the first argument of the disjunction */
+ equivterm = term_SecondArgument(term_Superterm(defpredicate));
+
+
+ scan = allformulae;
+ while (!list_Empty(scan)) {
+ BOOL localfound;
+ LIST pair, targettermvars;
+
+ /* Pair label / term */
+ pair = list_Car(scan);
+
+ /* Pair may be NULL if it is a definition that could be deleted */
+ if ((pair != NULL) && (definition != (TERM) list_PairSecond(pair))) {
+ TERM target, targetpredicate, totoplevel;
+ LIST varsfortoplevel;
+ target = (TERM) list_PairSecond(pair);
+ targettermvars = varsfortoplevel = list_Nil();
+
+ /* If definition is not always applicable, check if it is applicable
+ for this formula */
+ localfound = FALSE;
+ if (!alwaysapplicable) {
+ if (cnf_ContainsPredicate(target, term_TopSymbol(defpredicate),
+ &targetpredicate, &totoplevel,
+ &targettermvars, &varsfortoplevel)) {
+ TERM toprovecopy;
+ toprovecopy = term_Copy(toprove);
+ target = cnf_DefTargetConvert(target, totoplevel, toprovecopy,
+ term_ArgumentList(defpredicate),
+ term_ArgumentList(targetpredicate),
+ targettermvars, varsfortoplevel,
+ Flags, Precedence, &localfound);
+ list_Delete(targettermvars);
+ list_Delete(varsfortoplevel);
+ targettermvars = varsfortoplevel = list_Nil();
+
+ list_Rplacd(pair, (LIST) target);
+ if (localfound)
+ list_Rplacd(pair,
+ (LIST) cnf_ApplyDefinitionOnce(defpredicate,
+ equivterm,
+ list_PairSecond(pair),
+ targetpredicate,
+ Flags));
+ }
+ }
+ else {
+ if (cnf_ContainsPredicate(target, term_TopSymbol(defpredicate),
+ &targetpredicate, &totoplevel,
+ &targettermvars, &varsfortoplevel))
+ list_Rplacd(pair, (LIST) cnf_ApplyDefinitionOnce(defpredicate,
+ equivterm,
+ list_PairSecond(pair),
+ targetpredicate,
+ Flags));
+ else
+ scan = list_Cdr(scan);
+ list_Delete(targettermvars);
+ list_Delete(varsfortoplevel);
+ targettermvars = varsfortoplevel = list_Nil();
+ }
+ }
+ else
+ scan = list_Cdr(scan);
+ }
+ list_Delete(allformulae);
+ /* toprove can be NULL if the definition can always be applied */
+ if (toprove != (TERM) NULL)
+ term_Delete(toprove);
+ list_Rplacd(Pair, (LIST) definition);
+ }
+
+ return Pair;
+}
+
+
+LIST cnf_ApplyDefinitionToClause(CLAUSE Clause, TERM Predicate, TERM Expansion,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, two terms and a flag store and a precedence.
+ RETURNS: The list of clauses where each occurrence of Predicate is
+ replaced by Expansion.
+***************************************************************/
+{
+ NAT i;
+ BOOL changed;
+ LIST args, scan, symblist;
+ TERM clauseterm, argument;
+
+ changed = FALSE;
+
+ /* Build term from clause */
+ args = list_Nil();
+ for (i = 0; i < clause_Length(Clause); i++) {
+ argument = clause_GetLiteralTerm(Clause, i); /* with sign */
+ args = list_Cons(term_Copy(argument), args);
+ }
+ clauseterm = term_Create(fol_Or(), args);
+
+ for (scan=term_ArgumentList(clauseterm); !list_Empty(scan); scan=list_Cdr(scan)) {
+ BOOL isneg;
+
+ argument = (TERM) list_Car(scan);
+ if (symbol_Equal(term_TopSymbol(argument), fol_Not())) {
+ argument = term_FirstArgument(argument);
+ isneg = TRUE;
+ }
+ else
+ isneg = FALSE;
+
+ /* Try to match with predicate */
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(), Predicate, argument)) {
+ SUBST subst;
+ TERM newargument;
+ subst = subst_ExtractMatcher();
+ newargument = subst_Apply(subst, term_Copy(Expansion));
+ subst_Free(subst);
+ if (isneg)
+ newargument = term_Create(fol_Not(), list_List(newargument));
+ term_Delete((TERM) list_Car(scan));
+ list_Rplaca(scan, newargument);
+ changed = TRUE;
+ }
+ cont_BackTrack();
+ }
+
+ if (changed) {
+ /* Build term and derive list of clauses */
+ LIST result;
+ if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+ puts("\nClause before applying def :");
+ clause_Print(Clause);
+ puts("\nPredicate :");
+ fol_PrettyPrint(Predicate);
+ puts("\nExpansion :");
+ fol_PrettyPrint(Expansion);
+ }
+ symblist = list_Nil();
+ clauseterm = cnf_Cnf(clauseterm, Precedence, &symblist);
+ result = cnf_MakeClauseList(clauseterm,FALSE,FALSE,Flags,Precedence);
+ list_Delete(symblist);
+ term_Delete(clauseterm);
+ if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+ LIST l;
+ puts("\nClauses derived by expanding definition :");
+ for (l = result; !list_Empty(l); l=list_Cdr(l)) {
+ clause_Print((CLAUSE) list_Car(l));
+ fputs("\n", stdout);
+ }
+ }
+ return result;
+ }
+ else {
+ term_Delete(clauseterm);
+ return list_Nil();
+ }
+}
+
+
+BOOL cnf_PropagateSubstEquations(TERM StartTerm)
+/*************************************************************
+ INPUT: A term where we assume that father links are established and
+ that no variable is bound by more than one quantifier.
+ RETURNS: TRUE, if any substitutions were made, FALSE otherwise.
+ EFFECT: Function looks for equations of the form x=t where x does not
+ occur in t. If x=t occurs negatively and disjunctively below
+ a universal quantifier binding x or if x=t occurs positively and
+ conjunctively below an existential quantifier binding x,
+ all occurrences of x are replaced by t in <StartTerm>.
+**************************************************************/
+{
+ LIST Subequ;
+ TERM QuantorTerm, Equation, EquationTerm;
+ SYMBOL Variable;
+ BOOL Hit, Substituted;
+
+#ifdef CHECK
+ if (fol_VarBoundTwice(StartTerm)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cnf_PropagateSubstEquations: Variables of");
+ misc_ErrorReport("\n input term are not normalized.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Substituted = FALSE;
+
+ Subequ = fol_GetSubstEquations(StartTerm);
+ for ( ; !list_Empty(Subequ); Subequ = list_Pop(Subequ)) {
+ Hit = FALSE;
+ Equation = list_Car(Subequ);
+ Variable = symbol_Null();
+ QuantorTerm = term_Null();
+ EquationTerm = term_Null();
+
+ if (term_IsVariable(term_FirstArgument(Equation)) &&
+ !term_ContainsVariable(term_SecondArgument(Equation),
+ term_TopSymbol(term_FirstArgument(Equation)))) {
+
+ Variable = term_TopSymbol(term_FirstArgument(Equation));
+ QuantorTerm = fol_GetBindingQuantifier(Equation, Variable);
+ EquationTerm = term_SecondArgument(Equation);
+ Hit = fol_PolarCheck(Equation, QuantorTerm);
+ }
+ if (!Hit && term_IsVariable(term_SecondArgument(Equation)) &&
+ !term_ContainsVariable(term_FirstArgument(Equation),
+ term_TopSymbol(term_SecondArgument(Equation)))) {
+
+ Variable = term_TopSymbol(term_SecondArgument(Equation));
+ QuantorTerm = fol_GetBindingQuantifier(Equation, Variable);
+ EquationTerm = term_FirstArgument(Equation);
+ Hit = fol_PolarCheck(Equation, QuantorTerm);
+ }
+ if (Hit) {
+ fol_DeleteQuantifierVariable(QuantorTerm,Variable);
+ term_ReplaceVariable(StartTerm, Variable, EquationTerm); /* We replace everythere ! */
+ term_AddFatherLinks(StartTerm);
+ if (symbol_Equal(term_TopSymbol(QuantorTerm),fol_Equality())) /* Trivial Formula */
+ fol_SetTrue(QuantorTerm);
+ else
+ fol_SetTrue(Equation);
+ Substituted = TRUE;
+ }
+ }
+
+ /* <Subequ> was freed in the loop. */
+
+ return Substituted;
+}
diff --git a/test/spass/cnf.h b/test/spass/cnf.h
new file mode 100644
index 0000000..be04c5f
--- /dev/null
+++ b/test/spass/cnf.h
@@ -0,0 +1,120 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * NAIVE CNF TRANSLATOR * */
+/* * * */
+/* * $Module: CNF * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#ifndef _CNF_
+#define _CNF_
+
+#include "hasharray.h"
+#include "renaming.h"
+#include "resolution.h"
+#include "search.h"
+#include "flags.h"
+
+#include <string.h>
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+static __inline__ BOOL cnf_LabelEqual(const char* l1, const char* l2)
+/********************************************************
+ INPUT: Two labels.
+ RETURNS: TRUE, if the labels are equal, FALSE otherwise.
+*********************************************************/
+{
+ return string_Equal(l1, l2);
+}
+
+
+static __inline__ LIST cnf_DeleteDuplicateLabelsFromList(LIST Labels)
+/********************************************************
+ INPUT: A list of labels.
+ RETURNS: The list where duplicate labels are removed.
+ EFFECTS: The duplicate labels are not freed.
+*********************************************************/
+{
+ return list_DeleteDuplicates(Labels, (BOOL (*)(POINTER,POINTER))cnf_LabelEqual);
+}
+
+
+TERM cnf_ApplyDefinitionOnce(TERM, TERM, TERM, TERM, FLAGSTORE);
+LIST cnf_ApplyDefinitionToClause(CLAUSE, TERM, TERM,FLAGSTORE,PRECEDENCE);
+
+BOOL cnf_ContainsDefinition(TERM, TERM*);
+BOOL cnf_ContainsPredicate(TERM, SYMBOL, TERM*, TERM*, LIST*, LIST*);
+
+TERM cnf_DeSkolemFormula(LIST);
+TERM cnf_DefConvert(TERM, TERM, TERM*);
+void cnf_FilePrint(TERM, FILE*);
+TERM cnf_DefTargetConvert(TERM, TERM, TERM, LIST, LIST, LIST, LIST,
+ FLAGSTORE, PRECEDENCE, BOOL*);
+
+void cnf_FilePrintPrefix(TERM, FILE*);
+void cnf_FPrint(TERM, FILE*);
+TERM cnf_Flatten(TERM, SYMBOL);
+PROOFSEARCH cnf_Flotter(LIST, LIST, LIST*, LIST*, HASH, HASH, FLAGSTORE,
+ PRECEDENCE, LIST*);
+void cnf_Free(FLAGSTORE);
+
+LIST cnf_HandleDefinition(PROOFSEARCH, LIST, LIST, LIST, LIST);
+void cnf_Init(FLAGSTORE);
+TERM cnf_NegationNormalFormula(TERM);
+TERM cnf_ObviousSimplifications(TERM);
+
+LIST cnf_QueryFlotter(PROOFSEARCH, TERM, LIST*);
+void cnf_StdoutPrint(TERM);
+
+BOOL cnf_PropagateSubstEquations(TERM);
+
+BOOL cnf_HaveProof(LIST, TERM, FLAGSTORE, PRECEDENCE);
+
+
+#endif
diff --git a/test/spass/component.c b/test/spass/component.c
new file mode 100644
index 0000000..def8e30
--- /dev/null
+++ b/test/spass/component.c
@@ -0,0 +1,266 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * COMPONENTS OF CLAUSES * */
+/* * * */
+/* * $Module: COMPONENT * */
+/* * * */
+/* * Copyright (C) 1996, 1998, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "term.h"
+#include "component.h"
+
+
+CLITERAL literal_Create(BOOL used, int index, LIST varlist)
+/**********************************************************
+ INPUT: A boolean used, an integer index and a list varlist.
+ RETURNS: A LITERAL is created.
+ MEMORY: The boolean, integer and varlist are no copies.
+*** ********************************************************/
+{
+ CLITERAL literal;
+
+ literal = (CLITERAL)memory_Malloc(sizeof(CLITERAL_NODE));
+ literal_PutUsed(literal,used);
+ literal_PutLitIndex(literal,index);
+ literal_PutLitVarList(literal,varlist);
+
+ return literal;
+}
+
+
+void literal_Delete(CLITERAL literal)
+/**********************************************************
+ INPUT: A literal.
+ RETURNS: None.
+ MEMORY: Deletes the LITERAL and frees the storage.
+***********************************************************/
+{
+ list_Delete(literal_GetLitVarList(literal));
+ literal_Free(literal);
+}
+
+
+LITPTR litptr_Create(LIST Indexlist, LIST Termsymblist)
+/**********************************************************
+ INPUT: A list indexes and a list of terms, i.e. a list of integers.
+ RETURNS: A LITPTR structure is created.
+ MEMORY: The integers in the created structure are the integers
+ in indexList, no copies.
+***********************************************************/
+{
+ LITPTR lit_ptr;
+ LIST Scan,varlist;
+ CLITERAL literal;
+ int index,n,k;
+
+ n = list_Length(Indexlist);
+
+ lit_ptr = (LITPTR)memory_Malloc(sizeof(LITPTR_NODE));
+ litptr_SetLength(lit_ptr, n);
+
+ if (n > 0) {
+ lit_ptr->litptr = (CLITERAL *)memory_Malloc(n * sizeof(CLITERAL));
+
+ k = 0;
+ for (Scan = Indexlist; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ index = (int)list_Car(Scan);
+ varlist = (LIST)list_Car(Termsymblist);
+ Termsymblist = list_Cdr(Termsymblist);
+ literal = literal_Create(FALSE,index,varlist);
+
+ litptr_SetLiteral(lit_ptr, k, literal);
+
+ k++;
+ }
+ } else
+ lit_ptr->litptr = NULL;
+
+ return lit_ptr;
+}
+
+
+void litptr_Delete(LITPTR lit_ptr)
+/**********************************************************
+ INPUT: A pointer to LITPTR.
+ MEMORY: Deletes the LITPTR and frees the storage.
+***********************************************************/
+{
+ int n,i;
+
+ n = litptr_Length(lit_ptr);
+
+ if (n > 0) {
+ for (i = 0; i < n; i++)
+ literal_Delete(litptr_Literal(lit_ptr,i));
+
+ memory_Free(lit_ptr->litptr, sizeof(CLITERAL) * n);
+ memory_Free(lit_ptr, sizeof(LITPTR_NODE));
+ } else
+ memory_Free(lit_ptr, sizeof(LITPTR_NODE));
+}
+
+
+void litptr_Print(LITPTR lit_ptr)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: void.
+ SUMMARY: Prints any term to stdout.
+ CAUTION: Uses the other term_Output functions.
+***************************************************************/
+{
+ int i,n;
+
+ n = litptr_Length(lit_ptr);
+ /*n = lit_ptr->length;*/
+
+ if (n > 0) {
+ printf("\nlength of LITPTR: %d\n",n);
+ for (i = 0; i < n; i++) {
+ printf("Entries of literal %d : \n",i);
+ puts("----------------------");
+ fputs("used:\t\t", stdout);
+
+ if (literal_GetUsed(litptr_Literal(lit_ptr,i)))
+ /*if (lit_ptr->litptr[i]->used)*/
+ puts("TRUE");
+ else
+ puts("FALSE");
+ printf("litindex:\t%d\n",
+ literal_GetLitIndex(litptr_Literal(lit_ptr,i)));
+ fputs("litvarlist:\t", stdout);
+ list_Apply((void (*)(POINTER)) symbol_Print,
+ literal_GetLitVarList(litptr_Literal(lit_ptr,i)));
+ puts("\n");
+ }
+ }else
+ puts("No entries in litptr structure");
+}
+
+
+BOOL litptr_AllUsed(LITPTR lit_ptr)
+/**************************************************************
+ INPUT: A LITPTR.
+ RETURNS: TRUE if every literal in the LITPTR is used and
+ FALSE otherwise.
+***************************************************************/
+{
+ int n,i;
+
+ n = litptr_Length(lit_ptr);
+
+ for (i = 0; i < n; i++)
+ if (!(literal_GetUsed(litptr_Literal(lit_ptr,i))))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+LIST subs_CompList(LITPTR litptr)
+/**********************************************************
+ INPUT: A pointer litptr.
+ RETURNS: A list with indexes which represents the first component of
+ with respect to the actual bindings and to litptr.
+ CAUTION: The structure to which litptr points to
+ is changed destructively in the used slot.
+***********************************************************/
+{
+ BOOL found,hasinter;
+ LIST scan,complist,compindexlist;
+ int n,i,j,lit;
+
+ compindexlist = list_Nil(); /* the result will be placed into this list */
+ complist = list_Nil(); /* added afterwards */
+ n = litptr_Length(litptr);
+
+ if (n > 0) {
+ for (j = 0; j < n; j++) {
+ printf("\nj = %d\n",j);
+ if (!literal_GetUsed(litptr_Literal(litptr,j))){
+ complist = list_Nil();
+ complist = list_Cons((POINTER)j,complist);
+ compindexlist = list_Cons((POINTER)(litptr->litptr[j]->litindex),
+ compindexlist);
+ literal_PutUsed(litptr_Literal(litptr,j), TRUE);
+ j = n+1;
+ printf("\nj == %d\n",j);
+ }
+ }
+
+ if (j == n){
+ list_Delete(complist); /* There is no more component */
+ return compindexlist; /* should be empty here */
+ }
+
+ found = TRUE;
+ while (found) {
+ found = FALSE;
+ for (scan = complist; !list_Empty(scan); scan = list_Cdr(scan)) {
+ lit = (int)list_Car(scan);
+ for (i = 0; i < n; i++) {
+ if (!literal_GetUsed(litptr_Literal(litptr,i))) {
+ printf("lit = %d\n",lit);
+ printf("i = %d\n",i);
+
+ hasinter = list_HasIntersection(litptr->litptr[lit]->litvarlist,
+ litptr->litptr[i]->litvarlist);
+
+ if (hasinter) {
+ puts("hasinter = TRUE");
+ complist = list_Cons((POINTER)i,complist);
+ compindexlist = list_Cons((POINTER)(litptr->litptr[i]->litindex),compindexlist);
+ literal_PutUsed(litptr_Literal(litptr,i), TRUE);
+ found = TRUE;
+ }
+ }
+ }
+ }
+
+ if (!found) { /* one component is finished */
+ list_Delete(complist);
+ found = FALSE;
+ }
+ }
+ }
+
+ return compindexlist;
+}
diff --git a/test/spass/component.h b/test/spass/component.h
new file mode 100644
index 0000000..14cb096
--- /dev/null
+++ b/test/spass/component.h
@@ -0,0 +1,151 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * COMPONENTS OF CLAUSES * */
+/* * * */
+/* * $Module: COMPONENT * */
+/* * * */
+/* * Copyright (C) 1996, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _COMPONENT_
+#define _COMPONENT_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "list.h"
+
+/**************************************************************/
+/* Structures */
+/**************************************************************/
+
+typedef struct cliteral {
+ BOOL used; /* Flag if the index is already used */
+ int litindex; /* Index of the literal in the original clause */
+ LIST litvarlist; /* List of variables of the literal */
+} *CLITERAL, CLITERAL_NODE;
+
+
+typedef struct litptr {
+ CLITERAL *litptr; /* Array of Pointer to literals */
+ int length; /* Number of literal in the array *litptr */
+} *LITPTR, LITPTR_NODE;
+
+/**************************************************************/
+/* Macros */
+/**************************************************************/
+
+static __inline__ BOOL literal_GetUsed(CLITERAL C)
+{
+ return C->used;
+}
+
+static __inline__ int literal_GetLitIndex(CLITERAL C)
+{
+ return C->litindex;
+}
+
+static __inline__ LIST literal_GetLitVarList(CLITERAL C)
+{
+ return C->litvarlist;
+}
+
+static __inline__ void literal_PutUsed(CLITERAL C,BOOL Bool)
+{
+ C->used = Bool;
+}
+
+static __inline__ void literal_PutLitIndex(CLITERAL C, int I)
+{
+ C->litindex = I;
+}
+
+static __inline__ void literal_PutLitVarList(CLITERAL C, LIST L)
+{
+ C->litvarlist = L;
+}
+
+static __inline__ CLITERAL litptr_Literal(LITPTR C, int I)
+{
+ return C->litptr[I];
+}
+
+static __inline__ void litptr_SetLiteral(LITPTR LP, int I, CLITERAL CL)
+{
+ LP->litptr[I] = CL;
+}
+
+
+static __inline__ int litptr_Length(LITPTR C)
+{
+ return C->length;
+}
+
+static __inline__ void litptr_SetLength(LITPTR C, int n)
+{
+ C->length = n;
+}
+
+static __inline__ void litptr_IncLength(LITPTR C)
+{
+ (C->length)++;
+}
+
+static __inline__ void literal_Free(CLITERAL Lit)
+{
+ memory_Free(Lit, sizeof(CLITERAL_NODE));
+}
+
+
+/**************************************************************/
+/* Functions on a Component and on a Literal */
+/**************************************************************/
+
+CLITERAL literal_Create(BOOL, int, LIST);
+void literal_Delete(CLITERAL);
+
+LITPTR litptr_Create(LIST, LIST);
+void litptr_Delete(LITPTR);
+void litptr_Print(LITPTR);
+BOOL litptr_AllUsed(LITPTR);
+
+
+#endif
diff --git a/test/spass/condensing.c b/test/spass/condensing.c
new file mode 100644
index 0000000..fca04bf
--- /dev/null
+++ b/test/spass/condensing.c
@@ -0,0 +1,100 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CONDENSATION OF CLAUSES * */
+/* * * */
+/* * $Module: CONDENSING * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "subsumption.h"
+#include "misc.h"
+#include "condensing.h"
+
+
+LIST cond_CondFast(CLAUSE c)
+/**********************************************************
+ INPUT: A clause c.
+ RETURNS: A list with indexes with respect to c that can
+ be deleted due to condensing.
+ CAUTION: None.
+***********************************************************/
+{
+ int vec, i, j, k;
+ LIST indexlist;
+
+ indexlist = list_Nil();
+ vec = vec_ActMax();
+
+ for (i = 0; i < clause_Length(c); i++) {
+ vec_Push((POINTER) i);
+ }
+
+ for (k = clause_Length(c) - 1; k >= 0; k--) {
+ for (i = vec; i < vec_ActMax(); i++) {
+ if ((int)vec_GetNth(i) != k) {
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),
+ clause_GetLiteralTerm(c,k),
+ clause_GetLiteralTerm(c,(int)vec_GetNth(i)))) {
+ cont_BackTrack();
+ for (j = vec; j < vec_ActMax(); j++) {
+ if (k == (int)vec_GetNth(j)) {
+ vec_Swap((vec_ActMax() -1) ,j);
+ j = vec_ActMax();
+ }
+ }
+
+ if (subs_IdcRes(c,vec,(vec_ActMax() -1))) {
+ indexlist = list_Cons((POINTER)k,indexlist);
+ vec_Pop();
+ }
+
+ i = vec_ActMax()+1;
+ }
+ else
+ cont_BackTrack();
+ }
+ }
+ }
+
+ vec_SetMax(vec);
+ return indexlist;
+}
diff --git a/test/spass/condensing.h b/test/spass/condensing.h
new file mode 100644
index 0000000..7da40a5
--- /dev/null
+++ b/test/spass/condensing.h
@@ -0,0 +1,64 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CONDENSATION OF CLAUSES * */
+/* * * */
+/* * $Module: CONDENSING * */
+/* * * */
+/* * Copyright (C) 1996, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _CONDENSING_
+#define _CONDENSING_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "unify.h"
+
+
+/**************************************************************/
+/* Function Prototypes */
+/**************************************************************/
+
+LIST cond_CondFast(CLAUSE);
+
+
+#endif
diff --git a/test/spass/context.c b/test/spass/context.c
new file mode 100644
index 0000000..7d3aacb
--- /dev/null
+++ b/test/spass/context.c
@@ -0,0 +1,636 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CONTEXTS FOR VARIABLES * */
+/* * * */
+/* * $Module: CONTEXT * */
+/* * * */
+/* * Copyright (C) 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "context.h"
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+int cont_NOOFCONTEXTS;
+LIST cont_LISTOFCONTEXTS;
+int cont_BINDINGS;
+
+SYMBOL cont_INDEXVARSCANNER;
+
+CONTEXT cont_LASTBINDING; /* The last binding made. */
+CONTEXT cont_CURRENTBINDING; /* Help variable. */
+
+CONTEXT cont_LEFTCONTEXT;
+CONTEXT cont_RIGHTCONTEXT;
+CONTEXT cont_INSTANCECONTEXT;
+
+cont_STACK_TYPE cont_STACK;
+int cont_STACKPOINTER;
+
+cont_CHECKSTACK_TYPE cont_CHECKSTACK;
+int cont_CHECKSTACKPOINTER;
+
+CONTEXT cont_STATELASTBINDING; /* Storage to save state of trails. */
+int cont_STATEBINDINGS; /* Storage to save number of current bindings. */
+int cont_STATESTACK; /* Storage to save state of stack. */
+int cont_STATETOPSTACK; /* Storage to save state of the top element of the stack. */
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INITIALIZATION * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void cont_Init(void)
+/**********************************************************
+ INPUT: None.
+ RETURNS: None.
+ EFFECT: Initializes the unify module.
+********************************************************/
+{
+ cont_LASTBINDING = (CONTEXT)NULL;
+
+ cont_ResetIndexVarScanner();
+
+ cont_NOOFCONTEXTS = 0;
+ cont_LISTOFCONTEXTS = list_Nil();
+ cont_BINDINGS = 0;
+
+ cont_INSTANCECONTEXT = (CONTEXT)memory_Malloc(sizeof(CONTEXT_NODE));
+
+ cont_LEFTCONTEXT = cont_Create();
+ cont_RIGHTCONTEXT = cont_Create();
+
+ cont_StackInit();
+ cont_StackPush(0);
+ cont_StackPop();
+}
+
+
+void cont_Check(void)
+/**********************************************************
+ INPUT: None.
+ RETURNS: None.
+ EFFECT: Frees internal structures of the unify module.
+********************************************************/
+{
+#ifdef CHECK
+ if (cont_LASTBINDING || (cont_BINDINGS != 0) ||
+ !symbol_Equal(cont_INDEXVARSCANNER,
+ symbol_GetInitialIndexVarCounter())) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_Check: There are variable bindings not reset.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+}
+
+
+void cont_Free(void)
+/**********************************************************
+ INPUT: None.
+ RETURNS: None.
+ EFFECT: Frees internal structures of the unify module.
+********************************************************/
+{
+ cont_Check();
+
+ while (cont_NOOFCONTEXTS > 0)
+ cont_Delete(list_Car(cont_LISTOFCONTEXTS)); /* Decreases NOOFCONTEXTS */
+
+ cont_BINDINGS = 0;
+
+ memory_Free(cont_INSTANCECONTEXT, sizeof(CONTEXT_NODE));
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * TERM EQUALITY WITH RESPECT TO BOUND VARIABLES * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL cont_TermEqual(CONTEXT Context1, TERM Term1, CONTEXT Context2, TERM Term2)
+/*********************************************************
+ INPUT: Two terms and two contexts.
+ RETURNS: TRUE iff the two terms are equal, where
+ variables are interpreted with respect to
+ the bindings in the contexts.
+********************************************************/
+{
+#ifdef CHECK
+ if (!(term_IsTerm(Term1) && term_IsTerm(Term2))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_TermEqual: Input terms are corrupted.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Term1 = cont_Deref(&Context1,Term1);
+ Term2 = cont_Deref(&Context2,Term2);
+
+ if (!term_EqualTopSymbols(Term1, Term2))
+ return FALSE;
+ else if (term_ArgumentList(Term1)) {
+ LIST Scan1, Scan2;
+ for (Scan1=term_ArgumentList(Term1), Scan2=term_ArgumentList(Term2);
+ list_Exist(Scan1) && list_Exist(Scan2);
+ Scan1=list_Cdr(Scan1), Scan2=list_Cdr(Scan2))
+ if (!cont_TermEqual(Context1,list_Car(Scan1), Context2,list_Car(Scan2)))
+ return FALSE;
+ return (list_Empty(Scan1) ? list_Empty(Scan2) : FALSE);
+ } else
+ return TRUE;
+}
+
+
+BOOL cont_TermEqualModuloBindings(CONTEXT IndexContext, CONTEXT CtL, TERM TermL,
+ CONTEXT CtR, TERM TermR)
+/*********************************************************
+ INPUT: Two contexts, two terms.
+ RETURNS: The boolean value TRUE if the terms are equal.
+ CAUTION: EQUAL FUNCTION- OR PREDICATE SYMBOLS SHARE THE
+ SAME ARITY. THIS IS NOT VALID FOR JUNCTORS!
+*******************************************************/
+{
+#ifdef CHECK
+ if (!(term_IsTerm(TermL) && term_IsTerm(TermR))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_TermEqualModuloBindings: Input terms are corrupted.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ while (term_IsVariable(TermL)) {
+ SYMBOL TermTop;
+
+ TermTop = term_TopSymbol(TermL);
+
+ if (symbol_IsIndexVariable(TermTop))
+ CtL = IndexContext;
+ else if (CtL == cont_InstanceContext())
+ break;
+
+ if (cont_VarIsBound(CtL, TermTop)) {
+ CONTEXT CHelp;
+
+ CHelp = cont_ContextBindingContext(CtL, TermTop);
+ TermL = cont_ContextBindingTerm(CtL, TermTop);
+ CtL = CHelp;
+ } else
+ break;
+ }
+
+ while (term_IsVariable(TermR)) {
+ SYMBOL TermTop;
+
+ TermTop = term_TopSymbol(TermR);
+
+ if (symbol_IsIndexVariable(TermTop))
+ CtR = IndexContext;
+ else if (CtR == cont_InstanceContext())
+ break;
+
+ if (cont_VarIsBound(CtR, TermTop)) {
+ CONTEXT CHelp;
+
+ CHelp = cont_ContextBindingContext(CtR, TermTop);
+ TermR = cont_ContextBindingTerm(CtR, TermTop);
+ CtR = CHelp;
+ } else
+ break;
+ }
+
+ if (!term_EqualTopSymbols(TermL, TermR))
+ return FALSE;
+ else
+ if (term_IsVariable(TermL)) {
+ if (CtL == CtR)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ else
+ if (term_IsComplex(TermL)) {
+ LIST ScanL, ScanR;
+
+ for (ScanL=term_ArgumentList(TermL), ScanR=term_ArgumentList(TermR);
+ list_Exist(ScanL) && list_Exist(ScanR);
+ ScanL=list_Cdr(ScanL), ScanR=list_Cdr(ScanR))
+ if (!cont_TermEqualModuloBindings(IndexContext, CtL, list_Car(ScanL),
+ CtR, list_Car(ScanR)))
+ return FALSE;
+
+ return (list_Empty(ScanL) ? list_Empty(ScanR) : FALSE);
+
+ }
+ else
+ return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * APPLY BINDINGS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+TERM cont_CopyAndApplyBindings(CONTEXT TermContext, TERM Term)
+{
+ while (term_IsVariable(Term)) {
+ SYMBOL TermTop;
+
+ TermTop = term_TopSymbol(Term);
+
+ if (cont_VarIsBound(TermContext, TermTop)) {
+ CONTEXT HelpContext;
+
+ HelpContext = cont_ContextBindingContext(TermContext, TermTop);
+ Term = cont_ContextBindingTerm(TermContext, TermTop);
+ TermContext = HelpContext;
+ } else
+ break;
+ }
+
+ if (term_IsComplex(Term)) {
+ LIST Scan, ArgumentList;
+ for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term));
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan))
+ list_Rplaca(Scan, cont_CopyAndApplyBindings(TermContext, list_Car(Scan)));
+ return term_Create(term_TopSymbol(Term), ArgumentList);
+ } else
+ return term_Create(term_TopSymbol(Term), list_Nil());
+}
+
+
+TERM cont_CopyAndApplyBindingsCom(const CONTEXT Context, TERM Term)
+{
+ while (term_IsVariable(Term) && cont_VarIsBound(Context, term_TopSymbol(Term)))
+ Term = cont_ContextBindingTerm(Context, term_TopSymbol(Term));
+
+ if (term_IsComplex(Term)) {
+ LIST Scan, ArgumentList;
+ for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term));
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan))
+ list_Rplaca(Scan, cont_CopyAndApplyBindingsCom(Context, list_Car(Scan)));
+ return term_Create(term_TopSymbol(Term), ArgumentList);
+ } else
+ return term_Create(term_TopSymbol(Term), list_Nil());
+}
+
+
+TERM cont_ApplyBindingsModuloMatching(const CONTEXT Context, TERM Term,
+ BOOL VarCheck)
+/**********************************************************
+ INPUT: A context, a term, and a boolean flag.
+ RETURNS: <Term> is destructively changed with respect to
+ established bindings in the context.
+ If <VarCheck> is true, all variables in <Term>
+ must be bound in the context. When compiled with
+ "CHECK" on, this condition is in fact checked.
+ This function only makes sense after a matching operation.
+***********************************************************/
+{
+ TERM RplacTerm;
+ LIST Arglist;
+ SYMBOL Top;
+
+#ifdef CHECK
+ if (VarCheck && symbol_IsVariable(term_TopSymbol(Term)) &&
+ !cont_VarIsBound(Context, term_TopSymbol(Term))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_ApplyBindingsModuloMatching:");
+ misc_ErrorReport(" Used in forbidden context.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Top = term_TopSymbol(Term);
+
+ if (symbol_IsVariable(Top)) {
+
+ if (cont_VarIsBound(Context, Top)) {
+ RplacTerm = cont_ContextBindingTerm(Context, Top);
+ Arglist = term_CopyTermList(term_ArgumentList(RplacTerm));
+ term_RplacTop(Term, term_TopSymbol(RplacTerm));
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term, Arglist);
+ }
+ }
+ else {
+
+ for (Arglist = term_ArgumentList(Term);
+ !list_Empty(Arglist);
+ Arglist = list_Cdr(Arglist))
+ cont_ApplyBindingsModuloMatching(Context, list_Car(Arglist), VarCheck);
+ }
+
+ return Term;
+}
+
+
+static TERM cont_CopyAndApplyIndexVariableBindings(const CONTEXT Context, TERM Term)
+{
+ SYMBOL TermTop;
+
+#ifdef CHECK
+ if (symbol_IsIndexVariable(term_TopSymbol(Term)) &&
+ !cont_VarIsBound(Context, term_TopSymbol(Term))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_CopyAndApplyIndexVariableBindings:");
+ misc_ErrorReport(" Expected bound index variable.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ TermTop = term_TopSymbol(Term);
+
+ while (symbol_IsIndexVariable(TermTop)) {
+ if (cont_VarIsBound(Context, TermTop)) {
+ Term = cont_ContextBindingTerm(Context, TermTop);
+ TermTop = term_TopSymbol(Term);
+ }
+ }
+
+ if (term_IsComplex(Term)) {
+ LIST Scan, ArgumentList;
+ for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term));
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan))
+ list_Rplaca(Scan, cont_CopyAndApplyIndexVariableBindings(Context, list_Car(Scan)));
+ return term_Create(TermTop, ArgumentList);
+ } else
+ return term_Create(TermTop, list_Nil());
+}
+
+
+TERM cont_ApplyBindingsModuloMatchingReverse(const CONTEXT Context, TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: <Term> is destructively changed with respect to
+ established bindings in the leftmost context. This
+ function only make sense after a matching operation (reverse).
+***********************************************************/
+{
+ TERM RplacTerm;
+ LIST Arglist;
+ SYMBOL Top;
+
+#ifdef CHECK
+ if (symbol_IsVariable(term_TopSymbol(Term)) &&
+ !cont_VarIsBound(Context, term_TopSymbol(Term))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_ApplyBindingsModuloMatchingReverse:");
+ misc_ErrorReport(" Used in forbidden context.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Top = term_TopSymbol(Term);
+
+ if (symbol_IsVariable(Top)) {
+
+ if (cont_VarIsBound(Context, Top)) {
+ RplacTerm =
+ cont_CopyAndApplyIndexVariableBindings(Context,
+ cont_ContextBindingTerm(Context, Top));
+ term_RplacTop(Term, term_TopSymbol(RplacTerm));
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term, term_ArgumentList(RplacTerm));
+ term_Free(RplacTerm);
+ }
+ }
+ else {
+
+ for (Arglist = term_ArgumentList(Term); !list_Empty(Arglist);
+ Arglist = list_Cdr(Arglist))
+ cont_ApplyBindingsModuloMatchingReverse(Context, list_Car(Arglist));
+ }
+
+ return Term;
+}
+
+
+BOOL cont_BindingsAreRenamingModuloMatching(const CONTEXT RenamingContext)
+{
+ CONTEXT Context;
+
+#ifdef CHECK
+ if (!cont_IsContextEmpty(RenamingContext)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_BindingsAreRenamingModuloMatching:");
+ misc_ErrorReport(" Renaming context contains bindings.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ cont_StartBinding();
+
+ Context = cont_LastBinding();
+
+ while (Context) {
+
+ if (!symbol_IsIndexVariable(cont_BindingSymbol(Context))) {
+ SYMBOL CodomainSymbol;
+
+ CodomainSymbol = term_TopSymbol(cont_BindingTerm(Context));
+
+ if (symbol_IsVariable(CodomainSymbol)) {
+ if (cont_VarIsRenamed(RenamingContext, CodomainSymbol)) {
+ cont_BackTrack();
+ return FALSE;
+ } else {
+ cont_CreateBinding(RenamingContext, CodomainSymbol, NULL, NULL);
+ cont_SetContextBindingRenaming(RenamingContext, CodomainSymbol, CodomainSymbol);
+ }
+ } else {
+ cont_BackTrack();
+ return FALSE;
+ }
+ }
+
+ Context = cont_BindingLink(Context);
+ }
+
+ cont_BackTrack();
+ return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * MISC FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+SYMBOL cont_TermMaxVar(CONTEXT Context, TERM Term)
+/*********************************************************
+ INPUT: A context and a term.
+ RETURNS: The maximal variable in <Term> with respect to
+ the bindings in <Context>
+********************************************************/
+{
+ LIST scan;
+ SYMBOL result;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_TermMaxVar: Input term is corrupted.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Term = cont_Deref(&Context,Term);
+ result = symbol_Null();
+
+ if (term_IsStandardVariable(Term)) {
+ if (term_TopSymbol(Term) > result)
+ result = term_TopSymbol(Term);
+ } else {
+ for (scan = term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan)) {
+ SYMBOL max = cont_TermMaxVar(Context, list_Car(scan));
+
+ if (max > result)
+ result = max;
+ }
+ }
+
+ return result;
+}
+
+
+NAT cont_TermSize(CONTEXT Context, TERM Term)
+/*********************************************************
+ INPUT: A context and a term.
+ RETURNS: The number of symbols in <Term> with respect to
+ the bindings in <Context>
+********************************************************/
+{
+ NAT result;
+ LIST scan;
+
+ Term = cont_Deref(&Context, Term);
+ result = 1;
+ for (scan = term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan))
+ result += cont_TermSize(Context, list_Car(scan));
+
+ return result;
+}
+
+
+BOOL cont_TermContainsSymbol(CONTEXT Context, TERM Term, SYMBOL Symbol)
+/*********************************************************
+ INPUT: A context, a term and a symbol.
+ RETURNS: TRUE, if <Symbol> occurs in <Term> with respect to
+ the bindings in <Context>, FALSE otherwise.
+********************************************************/
+{
+ LIST scan;
+
+ Term = cont_Deref(&Context, Term);
+
+ if (symbol_Equal(term_TopSymbol(Term), Symbol))
+ return TRUE;
+ else
+ for (scan = term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan)) {
+ if (cont_TermContainsSymbol(Context, list_Car(scan), Symbol))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * OUTPUT * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void cont_TermPrintPrefix(CONTEXT Context, TERM Term)
+/**************************************************************
+ INPUT: A context and a term.
+ RETURNS: none.
+ SUMMARY: Prints the term modulo the context to stdout.
+ CAUTION: none.
+***************************************************************/
+{
+ Term = cont_Deref(&Context, Term);
+
+ symbol_Print(term_TopSymbol(Term));
+
+ if (term_IsComplex(Term)) {
+ LIST List;
+
+ putchar('(');
+
+ for (List = term_ArgumentList(Term); !list_Empty(List);
+ List = list_Cdr(List)) {
+ cont_TermPrintPrefix(Context, list_Car(List));
+
+ if (!list_Empty(list_Cdr(List)))
+ putchar(',');
+ }
+
+ putchar(')');
+ }
+}
diff --git a/test/spass/context.h b/test/spass/context.h
new file mode 100644
index 0000000..a3239ac
--- /dev/null
+++ b/test/spass/context.h
@@ -0,0 +1,1049 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CONTEXTS FOR VARIABLES * */
+/* * * */
+/* * $Module: CONTEXT * */
+/* * * */
+/* * Copyright (C) 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#define SHOWBINDINGS 0
+
+#ifndef _CONTEXT_
+#define _CONTEXT_
+
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "term.h"
+#include "symbol.h"
+#include "list.h"
+
+/**************************************************************/
+/* Structures */
+/**************************************************************/
+
+/* Set 'SHOWBINDINGS' to non-zero value to enable debug output. */
+/* #define SHOWBINDINGS 1 */
+
+#define cont__SIZE symbol__MAXVARIABLES
+
+extern int cont_NOOFCONTEXTS;
+extern LIST cont_LISTOFCONTEXTS;
+extern int cont_BINDINGS;
+
+/* An array to remember bindings for the variables. The array */
+/* is indexed by the variable index and holds the binding term. */
+
+typedef struct binding {
+ SYMBOL symbol;
+ SYMBOL renaming;
+ TERM term;
+ struct binding *context;
+ struct binding *link;
+} *CONTEXT, CONTEXT_NODE;
+
+extern CONTEXT cont_LASTBINDING; /* The last binding made. */
+extern CONTEXT cont_CURRENTBINDING; /* Help variable. */
+
+extern SYMBOL cont_INDEXVARSCANNER;
+
+/* Two contexts are allocated by default */
+
+extern CONTEXT cont_LEFTCONTEXT;
+extern CONTEXT cont_RIGHTCONTEXT;
+extern CONTEXT cont_INSTANCECONTEXT; /* This context is used as a label only (dummy context) */
+
+
+static __inline__ CONTEXT cont_LeftContext(void)
+{
+ return cont_LEFTCONTEXT;
+}
+
+static __inline__ CONTEXT cont_RightContext(void)
+{
+ return cont_RIGHTCONTEXT;
+}
+
+static __inline__ CONTEXT cont_InstanceContext(void)
+{
+ return cont_INSTANCECONTEXT;
+}
+
+/**************************************************************/
+/* A stack for the number of established bindings */
+/**************************************************************/
+
+#define cont__STACKSIZE 1000
+
+typedef int cont_STACK_TYPE[cont__STACKSIZE];
+
+extern cont_STACK_TYPE cont_STACK;
+extern int cont_STACKPOINTER;
+
+/* Stack operations */
+
+static __inline__ void cont_StackInit(void)
+{
+ cont_STACKPOINTER = 1;
+}
+
+static __inline__ void cont_StackPush(int Entry)
+{
+#ifdef CHECK
+ if (cont_STACKPOINTER >= cont__STACKSIZE) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_StackPush: Context stack overflow!\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ cont_STACK[cont_STACKPOINTER++] = Entry;
+}
+
+static __inline__ void cont_StackPop(void)
+{
+ --cont_STACKPOINTER;
+}
+
+static __inline__ int cont_StackPopResult(void)
+{
+ return cont_STACK[--cont_STACKPOINTER];
+}
+
+static __inline__ void cont_StackNPop(int N)
+{
+ cont_STACKPOINTER -= N;
+}
+
+static __inline__ int cont_StackTop(void)
+{
+ return cont_STACK[cont_STACKPOINTER - 1];
+}
+
+static __inline__ int cont_StackNthTop(int N)
+{
+ return cont_STACK[cont_STACKPOINTER - (1 + N)];
+}
+
+static __inline__ void cont_StackRplacTop(int Entry)
+{
+ cont_STACK[cont_STACKPOINTER - 1] = Entry;
+}
+
+static __inline__ void cont_StackRplacNthTop(int N, int Entry)
+{
+ cont_STACK[cont_STACKPOINTER - (1 + N)] = Entry;
+}
+
+static __inline__ void cont_StackRplacNth(int N, int Entry)
+{
+ cont_STACK[N] = Entry;
+}
+
+static __inline__ int cont_StackBottom(void)
+{
+ return cont_STACKPOINTER;
+}
+
+static __inline__ void cont_StackSetBottom(int Pointer)
+{
+ cont_STACKPOINTER = Pointer;
+}
+
+static __inline__ BOOL cont_StackEmpty(int Pointer)
+{
+ return cont_STACKPOINTER == Pointer;
+}
+
+
+static __inline__ void cont_StartBinding(void)
+{
+ cont_StackPush(cont_BINDINGS);
+
+ cont_BINDINGS = 0;
+}
+
+static __inline__ int cont_BindingsSinceLastStart(void)
+{
+ return cont_BINDINGS;
+}
+
+static __inline__ void cont_StopAndStartBinding(void)
+{
+ cont_StackRplacTop(cont_StackTop() + cont_BINDINGS);
+
+ cont_BINDINGS = 0;
+}
+
+/**************************************************************/
+/* Access */
+/**************************************************************/
+
+static __inline__ CONTEXT cont_Binding(CONTEXT C, SYMBOL Var)
+{
+ return &(C)[Var];
+}
+
+static __inline__ CONTEXT cont_BindingLink(CONTEXT B)
+{
+ return B->link;
+}
+
+static __inline__ void cont_SetBindingLink(CONTEXT B, CONTEXT L)
+{
+ B->link = L;
+}
+
+static __inline__ TERM cont_BindingTerm(CONTEXT B)
+{
+ return B->term;
+}
+
+static __inline__ void cont_SetBindingTerm(CONTEXT B, TERM T)
+{
+ B->term = T;
+}
+
+static __inline__ SYMBOL cont_BindingSymbol(CONTEXT B)
+{
+ return B->symbol;
+}
+
+static __inline__ void cont_SetBindingSymbol(CONTEXT B, SYMBOL S)
+{
+ B->symbol = S;
+}
+
+static __inline__ SYMBOL cont_BindingRenaming(CONTEXT B)
+{
+ return B->renaming;
+}
+
+static __inline__ void cont_SetBindingRenaming(CONTEXT B, SYMBOL S)
+{
+ B->renaming = S;
+}
+
+static __inline__ CONTEXT cont_BindingContext(CONTEXT B)
+{
+ return B->context;
+}
+
+static __inline__ void cont_SetBindingContext(CONTEXT B, CONTEXT C)
+{
+ B->context = C;
+}
+
+static __inline__ CONTEXT cont_ContextBindingLink(CONTEXT C,SYMBOL Var)
+{
+ return C[Var].link;
+}
+
+static __inline__ TERM cont_ContextBindingTerm(CONTEXT C,SYMBOL Var)
+{
+ return C[Var].term;
+}
+
+static __inline__ void cont_SetContextBindingTerm(CONTEXT C, SYMBOL Var, TERM t)
+{
+ C[Var].term = t;
+}
+
+static __inline__ SYMBOL cont_ContextBindingSymbol(CONTEXT C,SYMBOL Var)
+{
+ return C[Var].symbol;
+}
+
+static __inline__ SYMBOL cont_ContextBindingRenaming(CONTEXT C,SYMBOL Var)
+{
+ return C[Var].renaming;
+}
+
+static __inline__ void cont_SetContextBindingRenaming(CONTEXT C, SYMBOL Var,
+ SYMBOL R)
+{
+ C[Var].renaming = R;
+}
+
+static __inline__ CONTEXT cont_ContextBindingContext(CONTEXT C,SYMBOL Var)
+{
+ return C[Var].context;
+}
+
+/**************************************************************/
+/* Predicates */
+/**************************************************************/
+
+static __inline__ BOOL cont_VarIsBound(CONTEXT C, SYMBOL Var)
+{
+ return cont_ContextBindingTerm(C,Var) != (TERM) NULL;
+}
+
+static __inline__ BOOL cont_VarIsUsed(CONTEXT C, SYMBOL Var)
+{
+ return cont_ContextBindingContext(C,Var) != (CONTEXT) NULL;
+}
+
+static __inline__ BOOL cont_VarIsLinked(CONTEXT C, SYMBOL Var)
+{
+ return cont_ContextBindingLink(C,Var) != (CONTEXT) NULL;
+}
+
+static __inline__ BOOL cont_VarIsRenamed(CONTEXT C, SYMBOL Var)
+{
+ return cont_ContextBindingRenaming(C, Var) != symbol_Null();
+}
+
+static __inline__ BOOL cont_VarIsClosed(CONTEXT C,SYMBOL Var)
+{
+ return !cont_VarIsBound(C,Var) && cont_VarIsUsed(C,Var);
+}
+
+static __inline__ BOOL cont_BindingIsBound(CONTEXT B)
+{
+ return cont_BindingTerm(B) != (TERM) NULL;
+}
+
+static __inline__ BOOL cont_BindingIsUsed(CONTEXT B)
+{
+ return cont_BindingContext(B) != (CONTEXT) NULL;
+}
+
+/**************************************************************/
+/* Aux functions for backtracking */
+/**************************************************************/
+
+static __inline__ CONTEXT cont_LastBinding(void)
+{
+ return cont_LASTBINDING;
+}
+
+static __inline__ void cont_SetLastBinding(CONTEXT B)
+{
+ cont_LASTBINDING = B;
+}
+
+static __inline__ TERM cont_LastBindingTerm(void)
+{
+ return cont_BindingTerm(cont_LastBinding());
+}
+
+static __inline__ SYMBOL cont_LastBindingSymbol(void)
+{
+ return cont_BindingSymbol(cont_LastBinding());
+}
+
+static __inline__ CONTEXT cont_LastBindingContext(void)
+{
+ return cont_BindingContext(cont_LastBinding());
+}
+
+static __inline__ BOOL cont_LastIsBound(void)
+{
+ return cont_BindingIsBound(cont_LastBinding());
+}
+
+static __inline__ BOOL cont_LastIsUsed(void)
+{
+ return cont_LastBindingContext() != (CONTEXT) NULL;
+}
+
+static __inline__ BOOL cont_LastIsClosed(void)
+{
+ return !cont_LastIsBound() && cont_LastIsUsed();
+}
+
+static __inline__ BOOL cont_IsInContext(CONTEXT C, SYMBOL Var, CONTEXT B)
+{
+ return cont_Binding(C, Var) == B;
+}
+
+static __inline__ CONTEXT cont_ContextOfBinding(CONTEXT B)
+{
+ CONTEXT Result;
+ LIST Scan;
+
+ for (Result = NULL, Scan = cont_LISTOFCONTEXTS;
+ list_Exist(Scan);
+ Scan = list_Cdr(Scan)) {
+ if (cont_IsInContext(list_Car(Scan), cont_BindingSymbol(B), B)) {
+ Result = list_Car(Scan);
+ break;
+ }
+ }
+
+#ifdef CHECK
+ if (Result == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_ContextOfBinding: Unknown context.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return Result;
+}
+
+/**************************************************************/
+/* Initialization */
+/**************************************************************/
+
+static __inline__ void cont_InitBinding(CONTEXT C, SYMBOL Var)
+{
+ cont_CURRENTBINDING = cont_Binding(C, Var);
+ cont_SetBindingLink(cont_CURRENTBINDING, (CONTEXT)NULL);
+ cont_SetBindingTerm(cont_CURRENTBINDING, (TERM)NULL);
+ cont_SetBindingSymbol(cont_CURRENTBINDING, Var);
+ cont_SetBindingRenaming(cont_CURRENTBINDING, symbol_Null());
+ cont_SetBindingContext(cont_CURRENTBINDING, (CONTEXT)NULL);
+}
+
+static __inline__ void cont_InitContext(CONTEXT C)
+{
+ int i;
+
+ for (i = 0; i < cont__SIZE; i++)
+ cont_InitBinding(C, i);
+}
+
+/**************************************************************/
+/* Creation and deletion of contexts */
+/**************************************************************/
+
+static __inline__ CONTEXT cont_Create(void)
+{
+ CONTEXT Result;
+
+ Result = (CONTEXT)memory_Malloc(cont__SIZE*sizeof(CONTEXT_NODE));
+
+ cont_InitContext(Result);
+
+ cont_LISTOFCONTEXTS = list_Cons(Result, cont_LISTOFCONTEXTS);
+ cont_NOOFCONTEXTS++;
+
+ return Result;
+}
+
+static __inline__ void cont_Delete(CONTEXT C)
+{
+#ifdef CHECK
+ if ((cont_NOOFCONTEXTS == 0) ||
+ !list_PointerMember(cont_LISTOFCONTEXTS, C)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_Delete: Context %ld not registered.\n",
+ (unsigned long)C);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ cont_LISTOFCONTEXTS = list_PointerDeleteOneElement(cont_LISTOFCONTEXTS, C);
+
+ cont_NOOFCONTEXTS--;
+
+ memory_Free(C, cont__SIZE*sizeof(CONTEXT_NODE));
+}
+
+static __inline__ void cont_ResetIndexVarScanner(void)
+{
+ cont_INDEXVARSCANNER = symbol_GetInitialIndexVarCounter();
+}
+
+/**************************************************************/
+/* Output bindings */
+/**************************************************************/
+
+static __inline__ void cont_BindingOutput(CONTEXT C, SYMBOL Var)
+{
+ symbol_Print(cont_ContextBindingSymbol(C, Var));
+ putchar(':');
+ symbol_Print(Var);
+
+ fputs(" -> ", stdout);
+
+ if (cont_VarIsBound(C, Var)) {
+ term_PrintPrefix(cont_ContextBindingTerm(C, Var));
+ } else
+ fputs("unbound", stdout);
+
+ fputs(" in ", stdout);
+
+ if (cont_VarIsUsed(C, Var)) {
+ printf("%ld", (unsigned long)cont_ContextBindingContext(C, Var));
+ } else
+ fputs("NULL (unused)", stdout);
+
+ fputs(". ", stdout);
+
+ if (cont_VarIsClosed(C, Var)) {
+ fputs("(closed)", stdout);
+ }
+
+ if (!cont_VarIsBound(C, Var) &&
+ !cont_VarIsUsed(C, Var)) {
+ fputs(",(free)", stdout);
+ }
+
+ if (cont_VarIsRenamed(C, Var)) {
+ fputs(",(renamed): ", stdout);
+ symbol_Print(Var);
+ fputs(" -> ", stdout);
+ symbol_Print(cont_ContextBindingRenaming(C, Var));
+ }
+
+ fflush(stdout);
+}
+
+static __inline__ void cont_PrintCurrentTrail(void)
+{
+ fputs("\nPrint bindings:", stdout);
+ cont_CURRENTBINDING = cont_LastBinding();
+ while (cont_CURRENTBINDING) {
+ cont_BindingOutput(cont_ContextOfBinding(cont_CURRENTBINDING),
+ cont_BindingSymbol(cont_CURRENTBINDING));
+ cont_CURRENTBINDING = cont_BindingLink(cont_CURRENTBINDING);
+ if (cont_CURRENTBINDING)
+ putchar('\n');
+ }
+ fflush(stdout);
+}
+
+/**************************************************************/
+/* Close bindings */
+/**************************************************************/
+
+static __inline__ void cont_CloseBindingHelp(CONTEXT C, SYMBOL Var)
+{
+ cont_SetContextBindingTerm(C, Var, NULL);
+}
+
+static __inline__ void cont_CloseBindingBindingHelp(CONTEXT B)
+{
+ cont_SetBindingTerm(B, NULL);
+}
+
+#if SHOWBINDINGS
+static __inline__ void cont_CloseBinding(CONTEXT C, SYMBOL Var)
+{
+ fputs("\nClose binding from ", stdout);
+ cont_BindingOutput(C, Var);
+ cont_CloseBindingHelp(C, Var);
+}
+#else
+static __inline__ void cont_CloseBinding(CONTEXT C, SYMBOL Var)
+{
+ cont_CloseBindingHelp(C, Var);
+}
+#endif
+
+static __inline__ void cont_CloseBindingBinding(CONTEXT B) {
+ cont_CloseBindingBindingHelp(B);
+}
+
+/**************************************************************/
+/* Establish bindings */
+/**************************************************************/
+
+static __inline__ void cont_CreateBindingHelp(CONTEXT C, SYMBOL Var,
+ CONTEXT CTerm, TERM Term)
+{
+#ifdef CHECK
+ if (cont_VarIsBound(C, Var)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_CreateBindingHelp: Variable already bound.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ cont_CURRENTBINDING = cont_Binding(C,Var);
+ cont_SetBindingTerm(cont_CURRENTBINDING, Term);
+ cont_SetBindingContext(cont_CURRENTBINDING, CTerm);
+ cont_SetBindingLink(cont_CURRENTBINDING, cont_LastBinding());
+ cont_SetLastBinding(cont_CURRENTBINDING);
+}
+
+#if SHOWBINDINGS
+
+static __inline__ int cont_CreateBinding(CONTEXT C, SYMBOL Var, CONTEXT CTerm, TERM Term)
+{
+ cont_CreateBindingHelp(C,Var,CTerm,Term);
+ fputs("\nEstablish binding from ", stdout);
+ cont_BindingOutput(C, Var);
+ return ++cont_BINDINGS;
+}
+
+static __inline__ int cont_CreateClosedBinding(CONTEXT C, SYMBOL Var)
+{
+ cont_CreateBindingHelp(C, Var, C, NULL);
+ fputs("\nEstablish closed binding from ", stdout);
+ cont_BindingOutput(C,Var);
+ return ++cont_BINDINGS;
+}
+
+#else
+
+static __inline__ int cont_CreateBinding(CONTEXT C, SYMBOL Var, CONTEXT CTerm, TERM Term)
+{
+ cont_CreateBindingHelp(C,Var,CTerm,Term);
+ return ++cont_BINDINGS;
+}
+
+static __inline__ int cont_CreateClosedBinding(CONTEXT C, SYMBOL Var)
+{
+ cont_CreateBindingHelp(C, Var, C, NULL);
+ return ++cont_BINDINGS;
+}
+
+#endif
+
+/**************************************************************/
+/* Backtracking */
+/**************************************************************/
+
+static __inline__ void cont_BackTrackLastBindingHelp(void)
+{
+ cont_CURRENTBINDING = cont_LastBinding();
+ cont_SetLastBinding(cont_BindingLink(cont_CURRENTBINDING));
+ cont_SetBindingTerm(cont_CURRENTBINDING, NULL);
+ cont_SetBindingContext(cont_CURRENTBINDING, NULL);
+ cont_SetBindingRenaming(cont_CURRENTBINDING, symbol_Null());
+ cont_SetBindingLink(cont_CURRENTBINDING, NULL);
+
+ cont_BINDINGS--;
+}
+
+#if SHOWBINDINGS
+
+static __inline__ void cont_BackTrackLastBinding(void)
+{
+ CONTEXT LastContext;
+ SYMBOL LastSymbol;
+
+ LastContext = cont_ContextOfBinding(cont_LastBinding());
+ LastSymbol = cont_LastBindingSymbol();
+ fputs("\nBacktrack binding from ", stdout);
+ cont_BindingOutput(LastContext, LastSymbol);
+ cont_BackTrackLastBindingHelp();
+}
+
+static __inline__ int cont_BackTrack(void)
+{
+ printf("\nBacktrack %d bindings:", cont_BINDINGS);
+
+ while (cont_BINDINGS > 0)
+ cont_BackTrackLastBinding();
+
+ if (!cont_StackEmpty(0))
+ cont_BINDINGS = cont_StackPopResult();
+
+ fflush(stdout);
+ return 0;
+}
+
+static __inline__ int cont_StopAndBackTrack(void)
+{
+#ifdef CHECK
+ if (cont_BINDINGS > 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_StopAndBackTrack: Bindings not reset!\n");
+ misc_FinishErrorReport();
+ } else if (cont_StackEmpty(0)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_StopAndBackTrack: No bindings on stack!\n");
+ misc_FinishErrorReport();
+ }
+#endif
+ cont_BINDINGS = cont_StackPopResult();
+
+ printf("\nStop and Backtrack %d bindings:", cont_BINDINGS);
+
+ while (cont_BINDINGS > 0)
+ cont_BackTrackLastBinding();
+
+ fflush(stdout);
+ return 0;
+}
+
+static __inline__ int cont_BackTrackAndStart(void)
+{
+ printf("\nBacktrack %d bindings:", cont_BINDINGS);
+
+ while (cont_BINDINGS > 0)
+ cont_BackTrackLastBinding();
+
+ fflush(stdout);
+ return 0;
+}
+
+static __inline__ void cont_Reset(void)
+{
+ fputs("\nReset bindings:", stdout);
+ while (cont_LastBinding())
+ cont_BackTrackLastBinding();
+
+ cont_BINDINGS = 0;
+ cont_StackInit();
+ cont_ResetIndexVarScanner();
+ fflush(stdout);
+}
+
+#else
+
+static __inline__ void cont_BackTrackLastBinding(void)
+{
+ cont_BackTrackLastBindingHelp();
+}
+
+static __inline__ int cont_BackTrack(void)
+{
+ while (cont_BINDINGS > 0)
+ cont_BackTrackLastBinding();
+
+ if (!cont_StackEmpty(0))
+ cont_BINDINGS = cont_StackPopResult();
+
+ return 0;
+}
+
+static __inline__ int cont_StopAndBackTrack(void)
+{
+#ifdef CHECK
+ if (cont_BINDINGS > 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_StopAndBackTrack: Bindings not reset!\n");
+ misc_FinishErrorReport();
+ } else if (cont_StackEmpty(0)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_StopAndBackTrack: No bindings on stack!\n");
+ misc_FinishErrorReport();
+ }
+#endif
+ cont_BINDINGS = cont_StackPopResult();
+
+ while (cont_BINDINGS > 0)
+ cont_BackTrackLastBinding();
+
+ return 0;
+}
+
+static __inline__ int cont_BackTrackAndStart(void)
+{
+ while (cont_BINDINGS > 0)
+ cont_BackTrackLastBinding();
+
+ return 0;
+}
+
+static __inline__ void cont_Reset(void)
+{
+ while (cont_LastBinding())
+ cont_BackTrackLastBinding();
+
+ cont_BINDINGS = 0;
+ cont_StackInit();
+ cont_ResetIndexVarScanner();
+}
+
+#endif
+
+/**************************************************************/
+/* Check state of bindings */
+/**************************************************************/
+
+#define cont__CHECKSTACKSIZE 1000
+#define cont__CHECKSTACKEMPTY 0
+
+typedef POINTER cont_CHECKSTACK_TYPE[cont__CHECKSTACKSIZE];
+
+extern cont_CHECKSTACK_TYPE cont_CHECKSTACK;
+extern int cont_CHECKSTACKPOINTER;
+
+/* Stack operations */
+
+static __inline__ void cont_CheckStackInit(void)
+{
+ cont_CHECKSTACKPOINTER = cont__CHECKSTACKEMPTY;
+}
+
+static __inline__ void cont_CheckStackPush(POINTER Entry)
+{
+#ifdef CHECK
+ if (cont_CHECKSTACKPOINTER >= cont__STACKSIZE) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_CheckStackPush: Context check stack overflow!\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ cont_CHECKSTACK[cont_CHECKSTACKPOINTER++] = Entry;
+}
+
+static __inline__ void cont_CheckStackPop(void)
+{
+ --cont_CHECKSTACKPOINTER;
+}
+
+static __inline__ POINTER cont_CheckStackPopResult(void)
+{
+ return cont_CHECKSTACK[--cont_CHECKSTACKPOINTER];
+}
+
+static __inline__ void cont_CheckStackNPop(int N)
+{
+ cont_CHECKSTACKPOINTER -= N;
+}
+
+static __inline__ POINTER cont_CheckStackTop(void)
+{
+ return cont_CHECKSTACK[cont_CHECKSTACKPOINTER - 1];
+}
+
+static __inline__ POINTER cont_CheckStackNthTop(int N)
+{
+ return cont_CHECKSTACK[cont_CHECKSTACKPOINTER - (1 + N)];
+}
+
+static __inline__ void cont_CheckStackRplacTop(POINTER Entry)
+{
+ cont_CHECKSTACK[cont_CHECKSTACKPOINTER - 1] = Entry;
+}
+
+static __inline__ void cont_CheckStackRplacNthTop(int N, POINTER Entry)
+{
+ cont_CHECKSTACK[cont_CHECKSTACKPOINTER - (1 + N)] = Entry;
+}
+
+static __inline__ void cont_CheckStackRplacNth(int N, POINTER Entry)
+{
+ cont_CHECKSTACK[N] = Entry;
+}
+
+static __inline__ int cont_CheckStackBottom(void)
+{
+ return cont_CHECKSTACKPOINTER;
+}
+
+static __inline__ void cont_CheckStackSetBottom(int Pointer)
+{
+ cont_CHECKSTACKPOINTER = Pointer;
+}
+
+static __inline__ BOOL cont_CheckStackEmpty(int Pointer)
+{
+ return cont_CHECKSTACKPOINTER == Pointer;
+}
+
+extern CONTEXT cont_STATELASTBINDING; /* Storage to save state of trails. */
+extern int cont_STATEBINDINGS; /* Storage to save number of current bindings. */
+extern int cont_STATESTACK; /* Storage to save state of stack. */
+extern int cont_STATETOPSTACK; /* Storage to save state of the top element of the stack. */
+
+static __inline__ BOOL cont_CheckLastBinding(CONTEXT Check, int Bindings)
+{
+ CONTEXT Scan;
+ BOOL Result;
+
+ Scan = cont_LastBinding();
+
+ while (Bindings > 0) {
+ Scan = cont_BindingLink(Scan);
+ Bindings--;
+ }
+ if (Check == Scan)
+ Result = TRUE;
+ else
+ Result = FALSE;
+
+ return Result;
+}
+
+static __inline__ void cont_CheckState(void)
+{
+ if (cont_CheckStackEmpty(cont__CHECKSTACKEMPTY)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_CheckState: No states saved.\n");
+ misc_FinishErrorReport();
+ }
+
+ cont_STATETOPSTACK = (int)cont_CheckStackPopResult();
+ cont_STATESTACK = (int)cont_CheckStackPopResult();
+ cont_STATEBINDINGS = (int)cont_CheckStackPopResult();
+ cont_STATELASTBINDING = (CONTEXT)cont_CheckStackPopResult();
+
+ if ((cont_STATELASTBINDING != cont_LastBinding()) ||
+ (cont_STATEBINDINGS != cont_BINDINGS) ||
+ (!cont_StackEmpty(cont_STATESTACK)) ||
+ (cont_STATETOPSTACK != cont_StackTop())) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In cont_CheckState: State of contexts does not match saved state.");
+ misc_ErrorReport("\nTrail: Saved state: %ld; current state: %ld.",
+ (long)cont_STATELASTBINDING, (long)cont_LastBinding());
+ misc_ErrorReport("\nNumber of bindings: Saved state: %d; current state: %d.",
+ cont_STATEBINDINGS, cont_BINDINGS);
+ misc_ErrorReport("\nBinding stack pointer: Saved state: %d; current state: %d.",
+ cont_STATESTACK, cont_StackBottom());
+ misc_ErrorReport("\nNumber of bindings on top of stack: Saved state: %d; current state: %d.\n\n",
+ cont_STATETOPSTACK, cont_StackTop());
+ misc_FinishErrorReport();
+ }
+}
+
+static __inline__ void cont_SaveState(void)
+{
+ cont_CheckStackPush((POINTER)cont_LastBinding());
+ cont_CheckStackPush((POINTER)cont_BINDINGS);
+ cont_CheckStackPush((POINTER)cont_StackBottom());
+ cont_CheckStackPush((POINTER)cont_StackTop());
+}
+
+static __inline__ BOOL cont_IsContextEmpty(const CONTEXT Check)
+{
+ int i;
+
+ for (i = 0; i < cont__SIZE; i++)
+ if (cont_VarIsBound(Check, i) ||
+ cont_VarIsUsed(Check, i) ||
+ cont_VarIsLinked(Check, i) ||
+ cont_VarIsRenamed(Check, i))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**************************************************************/
+/* Generation of index variables */
+/**************************************************************/
+
+static __inline__ SYMBOL cont_NextIndexVariable(const CONTEXT IndexContext)
+{
+ if (symbol_Equal(cont_INDEXVARSCANNER, symbol_LastIndexVariable()))
+ cont_INDEXVARSCANNER = symbol_CreateIndexVariable();
+ else
+ for (;;) {
+ cont_INDEXVARSCANNER = symbol_NextIndexVariable(cont_INDEXVARSCANNER);
+ if (!cont_VarIsUsed(IndexContext, cont_INDEXVARSCANNER))
+ break;
+ else
+ if (symbol_Equal(cont_INDEXVARSCANNER, symbol_LastIndexVariable())) {
+ cont_INDEXVARSCANNER = symbol_CreateIndexVariable();
+ break;
+ }
+ }
+ return cont_INDEXVARSCANNER;
+}
+
+/**************************************************************/
+/* Dereferencing of terms wrt. contexts */
+/**************************************************************/
+
+static __inline__ TERM cont_Deref(CONTEXT* Context, TERM Term)
+/**************************************************************
+ INPUT: A call-by-ref context and a term.
+ RETURNS: The dereferenced term and the corresponding context.
+ SUMMARY: Dereferences bindings of variables.
+ CAUTION: In general, the context of the returned term
+ is different to the input context.
+***************************************************************/
+{
+
+ while (term_IsVariable(Term) && *Context != cont_InstanceContext()) {
+ SYMBOL TermTop;
+
+ TermTop = term_TopSymbol(Term);
+
+ if (cont_VarIsBound(*Context, TermTop)) {
+ CONTEXT HelpContext;
+
+ HelpContext = cont_ContextBindingContext(*Context, TermTop);
+ Term = cont_ContextBindingTerm(*Context, TermTop);
+ *Context = HelpContext;
+ }
+ else
+ return Term;
+ }
+
+ return Term;
+}
+
+/**************************************************************/
+/* Functions for Initialization and Controlling */
+/**************************************************************/
+
+void cont_Init(void);
+void cont_Check(void);
+void cont_Free(void);
+
+/**************************************************************/
+/* Functions for Term Equality Test with respect to Bindings */
+/**************************************************************/
+
+BOOL cont_TermEqual(CONTEXT, TERM, CONTEXT, TERM);
+BOOL cont_TermEqualModuloBindings(CONTEXT, CONTEXT, TERM, CONTEXT, TERM);
+
+/**************************************************************/
+/* Functions for Applying Bindings */
+/**************************************************************/
+
+TERM cont_CopyAndApplyBindings(CONTEXT, TERM);
+TERM cont_CopyAndApplyBindingsCom(const CONTEXT, TERM);
+
+TERM cont_ApplyBindingsModuloMatching(const CONTEXT, TERM, BOOL);
+TERM cont_ApplyBindingsModuloMatchingReverse(const CONTEXT, TERM);
+
+BOOL cont_BindingsAreRenamingModuloMatching(const CONTEXT);
+
+/**************************************************************/
+/* Misc Functions */
+/**************************************************************/
+
+SYMBOL cont_TermMaxVar(CONTEXT, TERM);
+NAT cont_TermSize(CONTEXT, TERM);
+BOOL cont_TermContainsSymbol(CONTEXT, TERM, SYMBOL);
+
+/**************************************************************/
+/* Functions for Output */
+/**************************************************************/
+
+void cont_TermPrintPrefix(CONTEXT, TERM);
+
+#endif
diff --git a/test/spass/defs.c b/test/spass/defs.c
new file mode 100644
index 0000000..0b6268b
--- /dev/null
+++ b/test/spass/defs.c
@@ -0,0 +1,1359 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * DEFINITIONS * */
+/* * * */
+/* * $Module: DEFS * */
+/* * * */
+/* * Copyright (C) 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "cnf.h"
+#include "defs.h"
+#include "foldfg.h"
+
+static void def_DeleteFromClauses(DEF);
+static void def_DeleteFromTerm(DEF);
+
+DEF def_CreateFromClauses(TERM ExpTerm, TERM PredTerm, LIST Clauses, LIST Lits,
+ BOOL Con)
+/**********************************************************
+ INPUT: Two terms, a list of clausenumbers, a list of literal indices and
+ a boolean saying whether all clauses derived by expanding the
+ predicate should be conclauses.
+ RETURNS: A definition consisting of the 2 terms as expansion term and
+ predicate term and the list of parent clause numbers and a list
+ of the indices of the defined predicate in the parent clauses.
+ ToProve and label are set to NULL.
+********************************************************/
+{
+ DEF result;
+
+#ifdef CHECK
+ if (!term_IsTerm(ExpTerm) || !term_IsTerm(PredTerm)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_CreateFromClause: Illegal input.");
+ misc_FinishErrorReport();
+ }
+ if (list_Empty(Clauses)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_CreateFromClause: No parent clause given.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = (DEF) memory_Malloc(sizeof(DEF_NODE));
+ result->expansion = ExpTerm;
+ result->predicate = PredTerm;
+ result->toprove = (TERM) NULL;
+ result->parentclauses = list_PairCreate(Clauses, Lits);
+ result->label = (const char*) NULL;
+ result->conjecture = Con;
+
+ return result;
+}
+
+DEF def_CreateFromTerm(TERM ExpTerm, TERM PredTerm, TERM ToProve, const char* Label)
+/**********************************************************
+ INPUT: 3 terms and a term label.
+ RETURNS: A definition consisting of the 3 terms as expansion term,
+ predicate term and term to prove before applying the
+ definition and the label of the parent term.
+ The list of clausenumbers is set to NULL.
+********************************************************/
+{
+ DEF result;
+
+#ifdef CHECK
+ if (!term_IsTerm(ExpTerm) || !term_IsTerm(PredTerm)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_CreateFromTerm: Illegal input.");
+ misc_FinishErrorReport();
+ }
+ if (Label == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_CreateFromTerm: No parent clause given.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = (DEF) memory_Malloc(sizeof(DEF_NODE));
+ result->expansion = ExpTerm;
+ result->predicate = PredTerm;
+ result->toprove = ToProve;
+ result->parentclauses = list_PairCreate(list_Nil(), list_Nil());
+ result->label = Label;
+ result->conjecture = FALSE;
+
+ return result;
+}
+
+static void def_DeleteFromClauses(DEF D)
+/**********************************************************
+ INPUT: A definition derived from clauses.
+ EFFECT: The definition is deleted, INCLUDING THE TERMS AND
+ THE LIST OF CLAUSE NUMBERS.
+********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(def_Expansion(D)) || !term_IsTerm(def_Predicate(D))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_DeleteFormClauses: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /* ToProve and Label are NULL */
+ term_Delete(def_Expansion(D));
+ term_Delete(def_Predicate(D));
+ list_Delete(def_ClauseNumberList(D));
+ list_Delete(def_ClauseLitsList(D));
+ list_PairFree(D->parentclauses);
+
+ memory_Free(D, sizeof(DEF_NODE));
+}
+
+static void def_DeleteFromTerm(DEF D)
+/**********************************************************
+ INPUT: A definition derived from a term.
+ EFFECT: The definition is deleted, INCLUDING THE TERMS.
+ THE LABEL IS NOT FREED.
+********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(def_Expansion(D)) || !term_IsTerm(def_Predicate(D))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_DeleteFromTerm: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /* List of clausenumbers is NULL */
+ term_Delete(def_Expansion(D));
+ term_Delete(def_Predicate(D));
+ if (def_ToProve(D) != (TERM) NULL)
+ term_Delete(def_ToProve(D));
+ list_PairFree(D->parentclauses);
+ memory_Free(D, sizeof(DEF_NODE));
+}
+
+void def_Delete(DEF D)
+/**********************************************************
+ INPUT: A definition derived from a term.
+ EFFECT: The definition is deleted.
+ CAUTION: All elements of the definition except of the label are freed.
+********************************************************/
+{
+ if (!list_Empty(def_ClauseNumberList(D)))
+ def_DeleteFromClauses(D);
+ else
+ def_DeleteFromTerm(D);
+}
+
+int def_PredicateOccurrences(TERM Term, SYMBOL P)
+/****************************************************
+ INPUT: A term and a predicate symbol.
+ RETURNS: The number of occurrences of the predicate symbol in Term
+**************************************************/
+{
+ /* Quantifiers */
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return def_PredicateOccurrences(term_SecondArgument(Term), P);
+
+ /* Junctors and NOT */
+ if (fol_IsJunctor(term_TopSymbol(Term)) ||
+ symbol_Equal(term_TopSymbol(Term),fol_Not())){
+ LIST scan;
+ int count;
+ count = 0;
+ for (scan=term_ArgumentList(Term); !list_Empty(scan); scan=list_Cdr(scan)) {
+ count += def_PredicateOccurrences((TERM) list_Car(scan), P);
+ /* Only the cases count==1 and count>1 are important */
+ if (count > 1)
+ return count;
+ }
+ return count;
+ }
+
+ if (symbol_Equal(term_TopSymbol(Term), P))
+ return 1;
+ return 0;
+}
+
+LIST def_ExtractDefsFromTerm(TERM Term, const char* Label)
+/**************************************************************
+ INPUT: A term and its label.
+ RETURNS: A list of definitions found in the term.
+ NOTE: The Term is not changed, the definitions contain copies.
+***************************************************************/
+{
+ TERM andterm;
+ BOOL found;
+ int pol;
+ LIST univars, termlist, defslist, scan;
+
+ /* First check if there is a top level and() so that the Term may
+ contain several definitions */
+
+ andterm = Term;
+ found = FALSE;
+ pol = 1;
+ univars = list_Nil();
+
+ /* Traverse top down universal quantifiers */
+ while (!found) {
+ if ((symbol_Equal(term_TopSymbol(andterm), fol_All()) && (pol == 1))
+ || (symbol_Equal(term_TopSymbol(andterm), fol_Exist()) && (pol == -1))) {
+ univars = list_Nconc(univars, list_Copy(fol_QuantifierVariables(andterm)));
+ andterm = term_SecondArgument(andterm);
+ }
+ else {
+ if (symbol_Equal(term_TopSymbol(andterm), fol_Not())) {
+ pol = -pol;
+ andterm = term_FirstArgument(andterm);
+ }
+ else
+ found = TRUE;
+ }
+ }
+
+ termlist = list_Nil();
+ /* Check if conjunction was found */
+ if ((symbol_Equal(term_TopSymbol(andterm), fol_And()) && (pol == 1))
+ || (symbol_Equal(term_TopSymbol(andterm), fol_Or()) && (pol == -1))) {
+ LIST l;
+ /* Flatten nested and/or */
+ /* Make copy of relevant subterm */
+ andterm = cnf_Flatten(term_Copy(andterm), term_TopSymbol(andterm));
+ for (l=term_ArgumentList(andterm); !list_Empty(l); l=list_Cdr(l)) {
+ TERM newterm;
+ newterm = fol_CreateQuantifierAddFather(fol_All(), term_CopyTermList(univars),
+ list_List(list_Car(l)));
+ termlist = list_Cons(newterm, termlist);
+ }
+ /* Arguments are used in new terms */
+ list_Delete(term_ArgumentList(andterm));
+ term_Free(andterm);
+ }
+ else
+ termlist = list_List(term_Copy(Term));
+
+ list_Delete(univars);
+
+ /* Now we have a list of terms that may contain definitions */
+ defslist = list_Nil();
+ for (scan=termlist; !list_Empty(scan); scan=list_Cdr(scan)) {
+ TERM cand;
+ TERM foundpred, toprove;
+
+ /* Candidate from list */
+ cand = (TERM) list_Car(scan);
+ term_AddFatherLinks(cand);
+
+ if (cnf_ContainsDefinition(cand, &foundpred)) {
+ DEF def;
+#ifdef CHECK
+ if (!fol_CheckFormula(cand)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_ExtractDefsFromTerm: Illegal term cand");
+ misc_FinishErrorReport();
+ }
+#endif
+ cand = cnf_DefConvert(cand, foundpred, &toprove);
+#ifdef CHECK
+ if (!fol_CheckFormula(cand)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_ExtractDefsFromTerm: Illegal term cand");
+ misc_FinishErrorReport();
+ }
+#endif
+ def = def_CreateFromTerm(term_Copy(term_SecondArgument(term_Superterm(foundpred))),
+ term_Copy(foundpred), toprove, Label);
+
+ if (def_PredicateOccurrences(cand, term_TopSymbol(foundpred)) > 1)
+ def_RemoveAttribute(def, PREDOCCURONCE);
+ else
+ def_AddAttribute(def, PREDOCCURONCE);
+ if (symbol_Equal(term_TopSymbol(foundpred), fol_Equality()))
+ def_AddAttribute(def, ISEQUALITY);
+ else
+ def_RemoveAttribute(def, ISEQUALITY);
+
+ defslist = list_Cons(def, defslist);
+ }
+ term_Delete(cand);
+ }
+
+ list_Delete(termlist);
+ return defslist;
+}
+
+void def_ExtractDefsFromClauselist(PROOFSEARCH Search, LIST Clauselist)
+/**************************************************************
+ INPUT: A proofsearch object and a list of clauses
+ RETURNS: Nothing.
+ EFFECT: The definitions found in the clauselist object are stored in
+ the proofsearch object.
+ NOTE: The clause list is not changed.
+ The old list of definitions in the proofsearch object is
+ overwritten.
+***************************************************************/
+{
+ LIST scan, defslist;
+ FLAGSTORE FlagStore;
+ PRECEDENCE Precedence;
+
+ defslist = list_Nil();
+ FlagStore = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ for (scan=Clauselist; !list_Empty(scan); scan=list_Cdr(scan)) {
+ CLAUSE Clause;
+ NAT index;
+ LIST pair;
+
+ Clause = (CLAUSE) list_Car(scan);
+ /* Check if clause contains a predicate that may be part of a definition */
+ if (clause_ContainsPotPredDef(Clause, FlagStore, Precedence, &index, &pair)) {
+ LIST l, compl, compllits;
+ BOOL done;
+
+ compl = compllits = list_Nil();
+ done = FALSE;
+
+ /* Search for complement clauses */
+ for (l=Clauselist; !list_Empty(l) && !done; l=list_Cdr(l)) {
+ int predindex;
+ if (clause_IsPartOfDefinition((CLAUSE) list_Car(l),
+ clause_GetLiteralTerm(Clause, index),
+ &predindex, pair)) {
+ compl = list_Cons(list_Car(l), compl);
+ compllits = list_Cons((POINTER) predindex, compllits);
+
+ if (list_Empty(list_PairFirst(pair)) &&
+ list_Empty(list_PairSecond(pair)))
+ done = TRUE;
+ }
+ }
+
+ /* All complements found ? */
+ if (done) {
+ LIST l2, clausenumbers, args;
+ DEF def;
+ NAT i;
+ TERM defterm, predterm;
+ BOOL con;
+
+ clausenumbers = list_Nil();
+ con = clause_GetFlag(Clause, CONCLAUSE);
+
+ for (l2=compl; !list_Empty(l2); l2=list_Cdr(l2)) {
+ clausenumbers = list_Cons((POINTER) clause_Number((CLAUSE) list_Car(l2)),
+ clausenumbers);
+ if (clause_GetFlag((CLAUSE) list_Car(l2), CONCLAUSE))
+ con = TRUE;
+ }
+ clausenumbers = list_Cons((POINTER) clause_Number(Clause),
+ clausenumbers);
+ compllits = list_Cons((POINTER) index, compllits);
+
+ /* Build definition term */
+ predterm = term_Copy(clause_GetLiteralTerm(Clause, index));
+ args = list_Nil();
+ for (i = 0; i < clause_Length(Clause); i++)
+ if (i != index)
+ args = list_Cons(term_Copy(clause_GetLiteralTerm(Clause, i)), args);
+ defterm = term_CreateAddFather(fol_Or(), args);
+ /* The expansion is negative here, so it must be inverted */
+ defterm = term_Create(fol_Not(), list_List(defterm));
+ defterm = cnf_NegationNormalFormula(defterm);
+ def = def_CreateFromClauses(defterm, predterm, clausenumbers, compllits, con);
+ defslist = list_Cons(def, defslist);
+ if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) {
+ fputs("\nNew definition found :", stdout);
+ def_Print(def);
+ }
+ }
+ else {
+ list_Delete(compllits);
+ list_Delete(list_PairSecond(pair));
+ list_Delete(list_PairFirst(pair));
+ }
+ list_Delete(compl);
+ list_PairFree(pair);
+ }
+ }
+
+ if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) {
+ if (!list_Empty(defslist)) {
+ fputs("\nFound definitions :\n", stdout);
+ for (scan = defslist; !list_Empty(scan); scan = list_Cdr(scan)) {
+ def_Print((DEF) list_Car(scan));
+ fputs("\n---\n", stdout);
+ }
+ }
+ }
+
+ for (scan=defslist; !list_Empty(scan); scan=list_Cdr(scan))
+ symbol_AddProperty(term_TopSymbol(def_Predicate((DEF) list_Car(scan))), ISDEF);
+
+ prfs_SetDefinitions(Search, list_Nconc(prfs_Definitions(Search), defslist));
+}
+
+TERM def_ApplyDefToTermOnce(DEF Def, TERM Term, FLAGSTORE FlagStore,
+ PRECEDENCE Precedence, BOOL* Complete)
+/**************************************************************
+ INPUT: A DEF structure, a term and a boolean that is set
+ to TRUE if no occurrences of the defined predicate
+ remain in the term. A flag store and a precedence.
+ RETURNS: A term where all occurrences of the definitions
+ predicate are expanded if possible.
+ NOTE: The Term is not changed.
+***************************************************************/
+{
+ TERM newtarget, oldtarget, targetpredicate, totoplevel, toprove;
+ LIST targettermvars, varsfortoplevel;
+ BOOL applicable;
+
+ oldtarget = Term;
+ *Complete = TRUE;
+
+ while (TRUE) {
+ newtarget = term_Copy(oldtarget);
+ term_AddFatherLinks(newtarget);
+ targettermvars = varsfortoplevel = list_Nil();
+
+ if (cnf_ContainsPredicate(newtarget, term_TopSymbol(def_Predicate(Def)),
+ &targetpredicate, &totoplevel, &targettermvars,
+ &varsfortoplevel)) {
+ *Complete = FALSE;
+ applicable = FALSE;
+ /* Check if definition is not always applicable */
+ if (term_Equal(def_ToProve(Def), term_Null())) {
+ applicable = TRUE;
+ newtarget = cnf_ApplyDefinitionOnce(def_Predicate(Def), term_Copy(def_Expansion(Def)),
+ newtarget, targetpredicate, FlagStore);
+ if (oldtarget != Term)
+ term_Delete(oldtarget);
+ oldtarget = newtarget;
+ list_Delete(targettermvars);
+ list_Delete(varsfortoplevel);
+ }
+ else {
+ toprove = term_Copy(def_ToProve(Def));
+ newtarget = cnf_DefTargetConvert(newtarget, totoplevel, toprove,
+ term_ArgumentList(def_Predicate(Def)),
+ term_ArgumentList(targetpredicate),
+ targettermvars, varsfortoplevel,
+ FlagStore, Precedence,
+ &applicable);
+ list_Delete(targettermvars);
+ list_Delete(varsfortoplevel);
+ if (applicable) {
+ newtarget = cnf_ApplyDefinitionOnce(def_Predicate(Def), term_Copy(def_Expansion(Def)),
+ newtarget, targetpredicate, FlagStore);
+ if (oldtarget != Term)
+ term_Delete(oldtarget);
+ oldtarget = newtarget;
+ }
+ else {
+ /* Predicate still exists but cannot be expanded */
+ term_Delete(newtarget);
+ if (oldtarget == Term)
+ return NULL;
+ else {
+ oldtarget = cnf_ObviousSimplifications(oldtarget);
+ return oldtarget;
+ }
+ }
+ }
+ }
+ else {
+ *Complete = TRUE;
+ /* Predicate does no longer exist */
+ term_Delete(newtarget);
+ /* No expansion possible */
+ if (oldtarget == Term)
+ return NULL;
+ else {
+ oldtarget = cnf_ObviousSimplifications(oldtarget);
+ return oldtarget;
+ }
+ }
+ }
+ return NULL; /* Unreachable */
+}
+
+TERM def_ApplyDefToTermExhaustive(PROOFSEARCH Search, TERM Term)
+/**************************************************************
+ INPUT: A proofsearch object and a term.
+ RETURNS: An expanded term.
+ NOTE: All occurences of defined predicates are expanded in the term,
+ until no further changes are possible.
+ CAUTION: If cyclic definitions exist, this will crash.
+***************************************************************/
+{
+ TERM oldterm, newterm;
+ BOOL done, complete;
+ FLAGSTORE FlagStore;
+ PRECEDENCE Precedence;
+
+ done = FALSE;
+ oldterm = Term;
+ FlagStore = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ while (!done) {
+ LIST l;
+ done = TRUE;
+ /* Apply all definitions to term until no more changes occur */
+ for (l=prfs_Definitions(Search); !list_Empty(l); l=list_Cdr(l)) {
+ newterm = def_ApplyDefToTermOnce((DEF) list_Car(l), oldterm,
+ FlagStore, Precedence, &complete);
+ if (newterm != NULL) {
+ if (oldterm != Term)
+ term_Delete(oldterm);
+ oldterm = newterm;
+ done = FALSE;
+ }
+ }
+ }
+ if (oldterm == Term)
+ return NULL;
+ else
+ return oldterm;
+}
+
+LIST def_ApplyDefToClauseOnce(DEF Def, CLAUSE Clause,
+ FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A DEF structure, a clause, a flag store and a
+ precedence.
+ RETURNS: A list of new clauses.
+ NOTE: The clause is not changed.
+ All occurences of the defined predicate are expanded
+ in the clause and in the derived clauses.
+***************************************************************/
+{
+ LIST result, l;
+
+ result = list_List(Clause);
+
+ for (l = result; !list_Empty(l); l = list_Cdr(l)) {
+ if (clause_ContainsSymbol((CLAUSE) list_Car(l),
+ term_TopSymbol(def_Predicate(Def)))) {
+ result = list_Nconc(result,
+ cnf_ApplyDefinitionToClause((CLAUSE) list_Car(l),
+ def_Predicate(Def),
+ def_Expansion(Def),
+ FlagStore, Precedence));
+ /* Remove temporary clause */
+ if ((CLAUSE) list_Car(l) != Clause)
+ clause_Delete((CLAUSE) list_Car(l));
+ list_Rplaca(l, NULL);
+ }
+ }
+ result = list_PointerDeleteElement(result, NULL);
+
+ /* Make sure the original clause is no longer in the list */
+ if (!list_Empty(result))
+ if (list_First(result) == Clause)
+ result = list_Pop(result);
+
+ for (l = result; !list_Empty(l); l=list_Cdr(l)) {
+ CLAUSE c;
+ c = (CLAUSE) list_Car(l);
+ if (def_Conjecture(Def))
+ clause_SetFlag((CLAUSE) list_Car(l), CONCLAUSE);
+ clause_SetFromDefApplication(c);
+ clause_SetParentClauses(c, list_Cons((POINTER) clause_Number(Clause),
+ list_Copy(def_ClauseNumberList(Def))));
+ /* Parent literal is not available, as the predicate may occur several
+ times in the target clause */
+ clause_SetParentLiterals(c, list_Cons((POINTER) 0,
+ list_Copy(def_ClauseLitsList(Def))));
+ }
+ return result;
+}
+
+LIST def_ApplyDefToClauseExhaustive(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proofsearch object and a clause.
+ RETURNS: A list of derived clauses.
+ NOTE: All occurences of defined predicates are expanded in the clause.
+ until no further changes are possible.
+ CAUTION: If cyclic definitions exist, this will crash.
+***************************************************************/
+{
+ LIST newclauses, scan, result;
+ CLAUSE orig;
+ FLAGSTORE FlagStore;
+ PRECEDENCE Precedence;
+
+ orig = clause_Copy(Clause);
+ newclauses = list_List(orig);
+ result = list_Nil();
+ FlagStore = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ while (!list_Empty(newclauses)) {
+ /* Check all clauses */
+ LIST l, nextlist;
+
+ /* List of clauses derived from newclauses by expanding predicates */
+ nextlist = list_Nil();
+
+ for (l=newclauses; !list_Empty(l); l=list_Cdr(l)) {
+ LIST clauses;
+ CLAUSE c;
+
+ c = (CLAUSE) list_Car(l);
+
+ /* Apply all definitions to the clause */
+
+ /* List of clauses derived from one clause in newclauses by */
+ /* expanding all possible predicates */
+ clauses = list_Nil();
+
+ for (scan=prfs_Definitions(Search); !list_Empty(scan); scan=list_Cdr(scan))
+ clauses = list_Nconc(clauses, def_ApplyDefToClauseOnce((DEF) list_Car(scan), c, FlagStore, Precedence));
+
+ /* If expansions were made delete old clause */
+ if (!list_Empty(clauses)) {
+ /* DOCPROOF ? */
+ if (c != Clause) {
+ if (flag_GetFlagValue(FlagStore, flag_DOCPROOF)) {
+ prfs_InsertDocProofClause(Search, c);
+ }
+ else
+ clause_Delete(c);
+ }
+ nextlist = list_Nconc(nextlist, clauses);
+ }
+ else {
+ /* No more expansions possible for this clause */
+ /* If it is not the original clause, add it to the result list */
+ if (c != Clause)
+ result = list_Cons(c, result);
+ }
+ }
+ list_Delete(newclauses);
+ newclauses = nextlist;
+ }
+
+ return result;
+}
+
+
+void def_Print(DEF D)
+/**************************************************************
+ INPUT: A DEF structure.
+ RETURNS: None.
+ EFFECT: Prints the definition to stdout.
+***************************************************************/
+{
+ LIST scan, scan2;
+ fputs("\n\nAtom: ", stdout);
+ fol_PrettyPrint(def_Predicate(D));
+ fputs("\nExpansion: \n", stdout);
+ fol_PrettyPrint(def_Expansion(D));
+ if (!list_Empty(def_ClauseNumberList(D))) {
+ fputs("\nParent clauses: ", stdout);
+ for (scan = def_ClauseNumberList(D), scan2 = def_ClauseLitsList(D);
+ !list_Empty(scan); scan = list_Cdr(scan), scan2 = list_Cdr(scan2))
+ printf("%d.%d ", (NAT) list_Car(scan), (NAT) list_Car(scan2));
+ if (D->conjecture)
+ fputs("\nDerived from conjecture clauses.", stdout);
+ else
+ fputs("\nNot derived from conjecture clauses.", stdout);
+ }
+ else {
+ fputs("\nLabel: ", stdout);
+ fputs(def_Label(D), stdout);
+ puts("\nGuard:");
+ if (def_ToProve(D) != NULL)
+ fol_PrettyPrint(def_ToProve(D));
+ else
+ fputs("Nothing.", stdout);
+ }
+
+ fputs("\nAttributes: ", stdout);
+ if (def_HasAttribute(D, ISEQUALITY) || def_HasAttribute(D, PREDOCCURONCE)) {
+ if (def_HasAttribute(D, ISEQUALITY))
+ fputs(" Equality ", stdout);
+ if (def_HasAttribute(D, PREDOCCURONCE))
+ fputs(" No Multiple Occurrences ", stdout);
+ }
+ else {
+ fputs(" None ", stdout);
+ }
+}
+
+LIST def_ApplyDefToClauselist(PROOFSEARCH Search, DEF Def,
+ LIST Clauselist, BOOL Destructive)
+/**************************************************************
+ INPUT: A proofsearch object, a DEF structure, a list of unshared clauses
+ and a boolean saying whether the parent clause of an expansion
+ should be deleted.
+ RETURNS: None.
+ EFFECT: For each occurrence of the defined predicate in a clause in the list,
+ a new clause with expanded predicate is added to the list.
+***************************************************************/
+{
+ LIST l, newclauses, allnew;
+ FLAGSTORE FlagStore;
+ PRECEDENCE Precedence;
+
+ allnew = list_Nil();
+ FlagStore = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ for (l = Clauselist; !list_Empty(l); l = list_Cdr(l)) {
+ newclauses = def_ApplyDefToClauseOnce(Def, (CLAUSE) list_Car(l),
+ FlagStore, Precedence);
+ /* Expansions were possible, delete the original clause */
+ if (Destructive && !list_Empty(newclauses)) {
+ if (flag_GetFlagValue(FlagStore, flag_DOCPROOF))
+ prfs_InsertDocProofClause(Search, (CLAUSE) list_Car(l));
+ else
+ clause_Delete((CLAUSE) list_Car(l));
+ list_Rplaca(l, NULL);
+ }
+ allnew = list_Nconc(allnew, newclauses);
+ }
+ if (Destructive)
+ Clauselist = list_PointerDeleteElement(Clauselist, NULL);
+
+
+ if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) {
+ if (!list_Empty(allnew)) {
+ fputs("\nNew clauses after applying definitions : \n", stdout);
+ clause_ListPrint(allnew);
+ }
+ }
+
+ Clauselist = list_Nconc(Clauselist, allnew);
+ return Clauselist;
+}
+
+LIST def_ApplyDefToTermlist(DEF Def, LIST Termlist,
+ FLAGSTORE FlagStore, PRECEDENCE Precedence,
+ BOOL* Complete, BOOL Destructive)
+/**************************************************************
+ INPUT: A DEF structure and a list of pairs (label, term),
+ a flag store, a precedence and a pointer to a
+ boolean.
+ If Destructive is TRUE the father of an expanded
+ term is deleted.
+ RETURNS: The changed list of terms.
+ EFFECT: For each occurrence of the defined predicate in a
+ term in the list, a new term with expanded predicate
+ is added to the list.
+ If every occurrence of the predicate could be
+ expanded, Complete is set to TRUE.
+***************************************************************/
+{
+ LIST l, newterms;
+
+ newterms = list_Nil();
+
+ *Complete = TRUE;
+ for (l=Termlist; !list_Empty(l); l=list_Cdr(l)) {
+ TERM newterm;
+ TERM oldterm;
+ BOOL complete;
+ oldterm = list_PairSecond(list_Car(l));
+ newterm = def_ApplyDefToTermOnce(Def, oldterm, FlagStore,
+ Precedence, &complete);
+ if (!complete)
+ *Complete = FALSE;
+ /* destructive part of function */
+ if (newterm != NULL) {
+ newterms = list_Cons(list_PairCreate(NULL, newterm),newterms);
+ if (Destructive) {
+ /* Delete oldterm from Termlist */
+ term_Delete(list_PairSecond(list_Car(l)));
+ if (list_PairFirst(list_Car(l)) != NULL)
+ string_StringFree(list_PairFirst(list_Car(l)));
+
+ list_PairFree(list_Car(l));
+ list_Rplaca(l, NULL);
+ }
+ }
+ }
+ Termlist = list_PointerDeleteElement(Termlist, NULL);
+
+ if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) {
+ if (!list_Empty(newterms)) {
+ fputs("\n\nNew terms after applying definitions : \n", stdout);
+ for (l=newterms; !list_Empty(l); l=list_Cdr(l)) {
+ fputs("\n", stdout);
+ fol_PrettyPrint(list_PairSecond(list_Car(l)));
+ }
+ }
+ }
+
+ Termlist = list_Nconc(Termlist, newterms);
+ return Termlist;
+}
+
+void def_ExtractDefsFromTermlist(PROOFSEARCH Search, LIST Axioms, LIST Conj)
+/**************************************************************
+ INPUT: A proofsearch object and 2 lists of pairs label/term.
+ RETURNS: None.
+ EFFECT: Add all found definitions to the proofsearch object.
+ The old list of definitions in the proofsearch object is
+ overwritten.
+***************************************************************/
+{
+ LIST l, deflist;
+ FLAGSTORE FlagStore;
+
+ deflist = list_Nil();
+ FlagStore = prfs_Store(Search);
+
+ for (l=Axioms; !list_Empty(l); l=list_Cdr(l)) {
+ fol_NormalizeVars(list_PairSecond(list_Car(l))); /* Is needed for proper variable match ! */
+ deflist = list_Nconc(deflist,
+ def_ExtractDefsFromTerm(list_PairSecond(list_Car(l)),
+ list_PairFirst(list_Car(l))));
+ }
+ for (l=Conj; !list_Empty(l); l=list_Cdr(l)) {
+ fol_NormalizeVars(list_PairSecond(list_Car(l))); /* Is needed for proper variable match ! */
+ deflist = list_Nconc(deflist,
+ def_ExtractDefsFromTerm(list_PairSecond(list_Car(l)),
+ list_PairFirst(list_Car(l))));
+ }
+ for (l=deflist; !list_Empty(l); l=list_Cdr(l))
+ symbol_AddProperty(term_TopSymbol(def_Predicate(list_Car(l))), ISDEF);
+
+ prfs_SetDefinitions(Search, list_Nconc(prfs_Definitions(Search), deflist));
+
+ if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) {
+ if (!list_Empty(deflist)) {
+ fputs("\nFound definitions :\n", stdout);
+ for (l = prfs_Definitions(Search); !list_Empty(l); l = list_Cdr(l)) {
+ def_Print(list_Car(l));
+ fputs("\n---\n", stdout);
+ }
+ }
+ }
+}
+
+LIST def_FlattenWithOneDefinition(PROOFSEARCH Search, DEF Def)
+/**************************************************************
+ INPUT: A proofsearch object and one definition.
+ RETURNS: The list of new definitions.
+ EFFECT: For every occurrence of the defined predicate among the other
+ definitions an expansion is attempted.
+ A new definition is only created if the result of the expansion is
+ again a definition.
+ The proofsearch object is not changed.
+***************************************************************/
+{
+ LIST newdefinitions;
+ FLAGSTORE FlagStore;
+ PRECEDENCE Precedence;
+
+ newdefinitions = list_Nil();
+ FlagStore = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ if (def_ToProve(Def) == NULL) {
+ LIST definitions, l;
+
+ definitions = prfs_Definitions(Search);
+
+ for (l = definitions; !list_Empty(l); l=list_Cdr(l)) {
+ DEF d;
+
+ d = (DEF) list_Car(l);
+ if (d != Def) {
+ /* Expansion possible */
+ if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) {
+ /* Resulting term is still a definition */
+ if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) {
+ TERM newexpansion;
+ BOOL complete;
+ DEF newdef;
+ newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d),
+ FlagStore, Precedence,
+ &complete);
+
+ newdef = def_CreateFromTerm(newexpansion,
+ term_Copy(def_Predicate(d)),
+ term_Copy(def_ToProve(d)), def_Label(d));
+ newdefinitions = list_Cons(newdef, newdefinitions);
+ }
+ }
+ }
+
+ }
+ }
+ return newdefinitions;
+}
+
+
+void def_FlattenWithOneDefinitionDestructive(PROOFSEARCH Search, DEF Def)
+/**************************************************************
+ INPUT: A proofsearch object and one definition.
+ RETURNS: None.
+ EFFECT: If the definition is always applicable, every occurrence of the
+ defined predicate among the other definitions is expanded in place.
+ If the resulting term is no longer a definition, it is deleted from
+ the proofsearch object.
+ Def is deleted.
+ CAUTION: This function changes the list entries in the list of definitions
+ in the proofsearch object, so do not call it from a loop over
+ all definitions.
+***************************************************************/
+{
+ FLAGSTORE FlagStore;
+ PRECEDENCE Precedence;
+
+ FlagStore = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ if (def_ToProve(Def) == NULL) {
+ LIST definitions, l;
+
+ definitions = prfs_Definitions(Search);
+ for (l = definitions; !list_Empty(l); l = list_Cdr(l)) {
+ DEF d;
+
+ d = (DEF) list_Car(l);
+ if (d != Def) {
+ /* Expansion possible */
+ if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) {
+ /* Resulting term is still a definition */
+ if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) {
+ TERM newexpansion;
+ BOOL complete;
+
+ newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d), FlagStore, Precedence, &complete);
+ term_Delete(def_Expansion(d));
+ def_RplacExp(d, newexpansion);
+ }
+ else {
+ symbol_RemoveProperty(term_TopSymbol(def_Predicate(d)), ISDEF);
+ def_Delete(d);
+ list_Rplaca(l, NULL);
+ }
+ }
+ }
+ else {
+ /* Remove given definition */
+ list_Rplaca(l, NULL);
+ }
+ }
+ symbol_RemoveProperty(term_TopSymbol(def_Predicate(Def)), ISDEF);
+ def_Delete(Def);
+ definitions = list_PointerDeleteElement(definitions, NULL);
+ prfs_SetDefinitions(Search, definitions);
+ }
+}
+
+void def_FlattenWithOneDefinitionSemiDestructive(PROOFSEARCH Search, DEF Def)
+/**************************************************************
+ INPUT: A proofsearch object and one definition.
+ RETURNS: Nothing.
+ EFFECT: If the definition can be applied to another definition
+ in the search object, that definition is destructively changed.
+ If the resulting term is no longer a definition, it is deleted to
+ prevent cycles.
+ The applied definition Def is NOT deleted.
+ CAUTION: After calling this function some entries of the definitions list
+ in the proofsearch object may be NULL.
+***************************************************************/
+{
+ FLAGSTORE FlagStore;
+ PRECEDENCE Precedence;
+
+ FlagStore = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ if (def_ToProve(Def) == NULL) {
+ LIST definitions, l;
+
+ definitions = prfs_Definitions(Search);
+ for (l = definitions; !list_Empty(l); l=list_Cdr(l)) {
+ DEF d;
+
+ d = (DEF) list_Car(l);
+ if (d != Def) {
+ /* Expansion possible */
+ if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) {
+ /* Resulting term is still a definition */
+ if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) {
+ TERM newexpansion;
+ BOOL complete;
+
+ newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d),
+ FlagStore, Precedence,
+ &complete);
+ term_Delete(def_Expansion(d));
+ def_RplacExp(d, newexpansion);
+ }
+ else {
+ symbol_RemoveProperty(term_TopSymbol(def_Predicate(d)), ISDEF);
+ def_Delete(d);
+ list_Rplaca(l, NULL);
+ }
+ }
+ }
+ }
+ }
+}
+
+void def_FlattenDefinitionsDestructive(PROOFSEARCH Search)
+/**************************************************************
+ INPUT: A proofsearch object.
+ RETURNS: None.
+ EFFECT: For every definition that is always applicable try to
+ expand the predicate in other
+ definitions if possible.
+***************************************************************/
+{
+ LIST l;
+
+ for (l = prfs_Definitions(Search); !list_Empty(l); l=list_Cdr(l)) {
+ DEF d;
+
+ d = (DEF) list_Car(l);
+ fol_PrettyPrintDFG(def_Predicate(d));
+ if (d != NULL)
+ def_FlattenWithOneDefinitionSemiDestructive(Search, d);
+ }
+ prfs_SetDefinitions(Search, list_PointerDeleteElement(prfs_Definitions(Search), NULL));
+}
+
+LIST def_GetTermsForProof(TERM Term, TERM SubTerm, int Polarity)
+/**************************************************************
+ INPUT: Two formulas, <Term> and <SubTerm> which must be subformula
+ of <Term>,an int which is the polarity of <SubTerm> in its
+ superterm and a list of variables <Variables>.
+ RETURN: A list of formulas that are used to prove the guard of Atom.
+ COMMENT: Helpfunction of def_FindProofFor Guard.
+ CAUTION: Father links must be set. Free variables may exist in terms of
+ return list.
+ Terms are copied.
+***************************************************************/
+{
+ TERM SuperTerm, AddToList;
+ SYMBOL Top;
+ LIST Scan1, NewList;
+
+ term_AddFatherLinks(Term);
+
+#ifdef CHECK
+ if (!fol_CheckFormula(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_GetTermsForProof: Illegal input Term.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (Term == SubTerm)
+ return list_Nil();
+
+ SuperTerm = term_Superterm(SubTerm);
+ Top = term_TopSymbol(SuperTerm);
+ NewList = list_Nil();
+ AddToList = term_Null();
+
+ if (symbol_Equal(Top, fol_Not()))
+ return def_GetTermsForProof(Term, SuperTerm, -1*Polarity);
+
+ if (symbol_Equal(Top, fol_Or()) && Polarity == 1) {
+ /* Get and store AddToList */
+ for (Scan1 = term_ArgumentList(SuperTerm); !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) {
+ if (!term_HasPointerSubterm(list_Car(Scan1), SubTerm))
+ NewList = list_Cons(term_Create(fol_Not(),list_List(term_Copy(list_Car(Scan1)))), NewList);
+ /* NewList's elements have the form not(term) */
+ }
+ if (list_Length(NewList) == 1) {
+ AddToList = list_Car(NewList);
+ list_Delete(NewList);
+ }
+ else {
+ AddToList = term_Create(fol_And(), NewList);
+ }
+ return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
+ }
+ if (symbol_Equal(Top, fol_And()) && Polarity == -1) {
+ /* Get and store AddToList */
+ if (list_Length(term_ArgumentList(SuperTerm)) == 2) {
+ if (!term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm)) {
+ AddToList = term_Copy(term_FirstArgument(SuperTerm));
+ }
+ else {
+ AddToList = term_Copy(term_SecondArgument(SuperTerm));
+ }
+ }
+ else if (list_Length(term_ArgumentList(SuperTerm)) > 2) {
+ for (Scan1 = term_ArgumentList(SuperTerm); !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) {
+ if (!term_HasPointerSubterm(list_Car(Scan1), SubTerm))
+ NewList = list_Cons(term_Copy(list_Car(Scan1)), NewList);
+ }
+ AddToList = term_Create(fol_And(), NewList);
+ }
+ else { /* Only one argument */
+ AddToList = term_Copy(term_FirstArgument(SuperTerm));
+ }
+ return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
+ }
+ if (symbol_Equal(Top, fol_Implies())) {
+ if (term_HasPointerSubterm(term_SecondArgument(SuperTerm), SubTerm) && Polarity == 1) {
+ AddToList = term_Copy(term_FirstArgument(SuperTerm));
+ return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
+ }
+ if (term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm) && Polarity == -1) {
+ AddToList = term_Copy(term_SecondArgument(SuperTerm));
+ AddToList = term_Create(fol_Not(), list_List(AddToList));
+ return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, -1*Polarity));
+ }
+ }
+ if (symbol_Equal(Top, fol_Implied())) { /* symmetric to fol_Implies */
+ if (term_HasPointerSubterm(term_SecondArgument(SuperTerm), SubTerm) && Polarity == -1) {
+ AddToList = term_Copy(term_FirstArgument(SuperTerm));
+ AddToList = term_Create(fol_Not(), list_List(AddToList));
+ return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, -1*Polarity));
+ }
+ if (term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm) && Polarity == 1) {
+ AddToList = term_Copy(term_SecondArgument(SuperTerm));
+ return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
+ }
+ }
+ if (fol_IsQuantifier(Top))
+ return def_GetTermsForProof(Term, SuperTerm, Polarity);
+
+ /* In all other cases, SubTerm is the top level term in which Atom occurs disjunctively */
+
+ return list_Nil();
+}
+
+BOOL def_FindProofForGuard(TERM Term, TERM Atom, TERM Guard, FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/**************************************************************************
+ INPUT: A formula Term, an atom Atom, a term Guard a flag store and a
+ precedence.
+ RETURNS: True iff a proof can be found for Guard in Term.
+***************************************************************************/
+{
+ BOOL LocallyTrue;
+ TERM ToProve, Conjecture;
+ LIST ArgList, FreeVars;
+
+ ArgList = list_Nil();
+ FreeVars = list_Nil();
+ ToProve = term_Null();
+ Conjecture = term_Copy(Term);
+
+#ifdef CHECK
+ if (!fol_CheckFormula(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_FindProofForGuard: No correct formula term.");
+ misc_FinishErrorReport();
+ }
+ if (!term_HasPointerSubterm(Term, Atom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_FindProofForGuard: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ ArgList = def_GetTermsForProof(Term, Atom, 1);
+
+ if (!list_Empty(ArgList)) {
+ ToProve = term_Create(fol_And(), ArgList);
+ FreeVars = list_Nconc(fol_FreeVariables(ToProve), fol_FreeVariables(Guard));
+ FreeVars = term_DeleteDuplicatesFromList(FreeVars);
+ term_CopyTermsInList(FreeVars);
+
+ ArgList = list_List(term_Copy(Guard));
+ ArgList = list_Cons(ToProve, ArgList);
+ ToProve = term_Create(fol_Implies(), ArgList);
+ ToProve = fol_CreateQuantifier(fol_All(), FreeVars, list_List(ToProve));
+
+ /* Now ToProve has the form <forall[]: A implies Guard> */
+ /* puts("\n*ToProve: "); fol_PrettyPrintDFG(ToProve); */
+
+#ifdef CHECK
+ if (!fol_CheckFormula(ToProve)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_FindProofForGuard: No correct formula ToProve.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ LocallyTrue = cnf_HaveProof(list_Nil(), ToProve, FlagStore, Precedence);
+ term_Delete(ToProve);
+ term_Delete(Conjecture);
+ if (LocallyTrue)
+ return TRUE;
+ }
+ else { /* empty list */
+ term_DeleteTermList(ArgList);
+ term_Delete(Conjecture);
+ }
+
+ return FALSE;
+}
+
+LIST def_ApplyDefinitionToTermList(LIST Defs, LIST Terms,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************************
+ INPUT: A list of definitions <Defs> and a list of pairs (Label.Formula),
+ the maximal number <Applics> of expansions, a flag store and a
+ precedence.
+ RETURNS: The possibly destructively changed list <Terms>.
+ EFFECT: In all formulas of Terms any definition of Defs is applied exactly
+ once if possible.
+ The terms are changed destructively if the expanded def_predicate
+ is not an equality.
+**************************************************************************/
+{
+ TERM ActTerm; /* Actual term in Terms */
+ TERM DefPredicate; /* Actual definition predicate out of Defs */
+ TERM Expansion; /* Expansion term of the definition */
+ TERM Target; /* Target predicate to be replaced */
+ LIST TargetList, Scan1, Scan2, Scan3;
+ BOOL Apply;
+ int Applics;
+
+ Apply = TRUE;
+ TargetList = list_Nil();
+ Applics = flag_GetFlagValue(Flags, flag_APPLYDEFS);
+
+ while (Apply && Applics != 0) {
+ Apply = FALSE;
+
+ for (Scan1=Defs; !list_Empty(Scan1) && Applics != 0; Scan1=list_Cdr(Scan1)) {
+ DefPredicate = term_Copy(def_Predicate(list_Car(Scan1)));
+
+ /* puts("\n----\nDefPred:"); fol_PrettyPrintDFG(DefPredicate);*/
+
+ for (Scan2=Terms; !list_Empty(Scan2) && Applics != 0; Scan2=list_Cdr(Scan2)) {
+ ActTerm = list_PairSecond(list_Car(Scan2));
+ TargetList = term_FindAllAtoms(ActTerm, term_TopSymbol(DefPredicate));
+ term_AddFatherLinks(ActTerm);
+
+ /* puts("\nActTerm:"); fol_PrettyPrintDFG(ActTerm);*/
+
+ for (Scan3=TargetList; !list_Empty(Scan3) && Applics != 0; Scan3=list_Cdr(Scan3)) {
+ Target = list_Car(Scan3);
+ cont_StartBinding();
+
+ /* puts("\nTarget:"); fol_PrettyPrintDFG(Target);*/
+
+ if (unify_Match(cont_LeftContext(), DefPredicate, Target)) {
+ cont_BackTrack();
+ Expansion = term_Copy(def_Expansion(list_Car(Scan1)));
+ fol_NormalizeVarsStartingAt(ActTerm, term_MaxVar(Expansion));
+ unify_Match(cont_LeftContext(), DefPredicate, Target);
+
+ if (fol_ApplyContextToTerm(cont_LeftContext(), Expansion)) { /* Matcher applied on Expansion */
+ if (!def_HasGuard(list_Car(Scan1))) {
+ Applics--;
+ Apply = TRUE;
+ /* puts("\n*no Guard!");*/
+ term_RplacTop(Target, term_TopSymbol(Expansion));
+ term_DeleteTermList(term_ArgumentList(Target));
+ term_RplacArgumentList(Target, term_ArgumentList(Expansion));
+ term_RplacArgumentList(Expansion, list_Nil());
+ term_AddFatherLinks(ActTerm);
+#ifdef CHECK
+ if (!fol_CheckFormula(ActTerm)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_ApplyDefinitionToTermList:");
+ misc_ErrorReport(" No correct formula ActTerm.");
+ misc_FinishErrorReport();
+ }
+#endif
+ if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+ puts("\nApplied definition for");
+ fol_PrettyPrintDFG(def_Predicate(list_Car(Scan1)));
+ puts("\nNew formula:");
+ fol_PrettyPrintDFG(ActTerm);
+ }
+ }
+ else { /* check guard */
+ TERM Guard;
+ Guard = term_Copy(def_ToProve(list_Car(Scan1)));
+ if (fol_ApplyContextToTerm(cont_LeftContext(), Guard)) {
+ cont_BackTrack();
+ if (def_FindProofForGuard(ActTerm, Target,Guard,
+ Flags, Precedence)) {
+ Applics--;
+ Apply = TRUE;
+ term_RplacTop(Target, term_TopSymbol(Expansion));
+ term_DeleteTermList(term_ArgumentList(Target));
+ term_RplacArgumentList(Target, term_ArgumentList(Expansion));
+ term_RplacArgumentList(Expansion, list_Nil());
+ term_AddFatherLinks(ActTerm);
+#ifdef CHECK
+ if (!fol_CheckFormula(ActTerm)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In def_ApplyDefinitionToTermList:");
+ misc_ErrorReport(" No correct formula ActTerm");
+ misc_FinishErrorReport();
+ }
+#endif
+ if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+ puts("\nApplied definition for");
+ fol_PrettyPrintDFG(def_Predicate(list_Car(Scan1)));
+ puts("\nNew formula:");
+ fol_PrettyPrintDFG(ActTerm);
+ }
+ }
+ }
+ term_Delete(Guard);
+ }
+ }
+ term_Delete(Expansion);
+ }
+ cont_BackTrack();
+ }
+ list_Delete(TargetList);
+ }
+ term_Delete(DefPredicate);
+ }
+ }
+ return Terms;
+}
diff --git a/test/spass/defs.h b/test/spass/defs.h
new file mode 100644
index 0000000..e3cdd2d
--- /dev/null
+++ b/test/spass/defs.h
@@ -0,0 +1,205 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * Definitions * */
+/* * * */
+/* * $Module: DEFS * */
+/* * * */
+/* * Copyright (C) 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _DEFS_
+#define _DEFS_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+
+#include "clause.h"
+#include "term.h"
+#include "list.h"
+#include "search.h"
+
+/**************************************************************/
+/* Structures */
+/**************************************************************/
+typedef enum { PREDOCCURONCE = 1, /* whether predicate occurs only once */
+ ISEQUALITY = 2 /* whether predicate is equality */
+} DEF_ATTRIBUTES;
+
+typedef struct DEF_HELP {
+ TERM expansion; /* The definition of the predicate term*/
+ TERM predicate; /* The predicate which is defined*/
+ TERM toprove;
+ LIST parentclauses; /* List of clause numbers plus list of literal indices */
+ const char *label; /* The label of the predicate term*/
+ BOOL conjecture;
+ NAT attributes; /* The attributes of the predicate*/
+} *DEF, DEF_NODE;
+
+/**************************************************************/
+/* Inline functions */
+/**************************************************************/
+static __inline__ TERM def_Expansion(DEF D)
+{
+ return D->expansion;
+}
+
+static __inline__ void def_RplacExp(DEF D, TERM E)
+{
+ D->expansion = E;
+}
+
+static __inline__ TERM def_Predicate(DEF D)
+{
+ return D->predicate;
+}
+
+static __inline__ void def_RplacPred(DEF D, TERM Pred)
+{
+ D->predicate = Pred;
+}
+
+static __inline__ TERM def_ToProve(DEF D)
+{
+ return D->toprove;
+}
+
+static __inline__ void def_RplacToProve(DEF D, TERM ToProve)
+{
+ D->toprove = ToProve;
+}
+
+static __inline__ LIST def_ClauseNumberList(DEF D)
+{
+ return list_PairFirst(D->parentclauses);
+}
+
+static __inline__ void def_RplacClauseNumberList(DEF D, LIST L)
+{
+ list_Rplaca(D->parentclauses, L);
+}
+
+static __inline__ LIST def_ClauseLitsList(DEF D)
+{
+ return list_PairSecond(D->parentclauses);
+}
+
+static __inline__ void def_RplacClauseLitsList(DEF D, LIST L)
+{
+ list_Rplacd(D->parentclauses, L);
+}
+
+static __inline__ const char* def_Label(DEF D)
+{
+ return D->label;
+}
+
+static __inline__ void def_RplacLabel(DEF D, const char* L)
+{
+ D->label = L;
+}
+
+static __inline__ BOOL def_Conjecture(DEF D)
+{
+ return D->conjecture;
+}
+
+static __inline__ void def_SetConjecture(DEF D)
+{
+ D->conjecture = TRUE;
+}
+
+static __inline__ void def_AddAttribute(DEF D, DEF_ATTRIBUTES Attribute)
+{
+ D->attributes = D->attributes | Attribute;
+}
+
+static __inline__ NAT def_HasAttribute(DEF D, DEF_ATTRIBUTES Attribute)
+{
+ return (D->attributes & Attribute);
+}
+
+static __inline__ void def_RemoveAttribute(DEF D, DEF_ATTRIBUTES Attribute)
+{
+ if (D->attributes & Attribute)
+ D->attributes = D->attributes - Attribute;
+}
+
+static __inline__ BOOL def_HasGuard(DEF D)
+{
+ return (def_ToProve(D)!=term_Null());
+}
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+DEF def_CreateFromClauses(TERM, TERM, LIST, LIST, BOOL);
+DEF def_CreateFromTerm(TERM, TERM, TERM, const char*);
+
+LIST def_ExtractDefsFromTerm(TERM, const char*);
+void def_ExtractDefsFromTermlist(PROOFSEARCH, LIST, LIST);
+void def_ExtractDefsFromClauselist(PROOFSEARCH, LIST);
+
+TERM def_ApplyDefToTermOnce(DEF, TERM, FLAGSTORE, PRECEDENCE, BOOL*);
+TERM def_ApplyDefToTermExhaustive(PROOFSEARCH, TERM);
+LIST def_ApplyDefToTermlist(DEF, LIST, FLAGSTORE, PRECEDENCE, BOOL*, BOOL);
+LIST def_ApplyDefinitionToTermList(LIST, LIST, FLAGSTORE, PRECEDENCE);
+/*
+LIST def_GetTermsForProof(TERM, TERM, int);
+BOOL def_FindProofForGuard(TERM, TERM, TERM, FLAGSTORE);
+*/
+
+LIST def_ApplyDefToClauseOnce(DEF, CLAUSE, FLAGSTORE, PRECEDENCE);
+LIST def_ApplyDefToClauseExhaustive(PROOFSEARCH, CLAUSE);
+LIST def_ApplyDefToClauselist(PROOFSEARCH, DEF, LIST, BOOL);
+
+LIST def_FlattenWithOneDefinition(PROOFSEARCH, DEF);
+void def_FlattenWithOneDefinitionSemiDestructive(PROOFSEARCH, DEF);
+void def_FlattenWithOneDefinitionDestructive(PROOFSEARCH, DEF);
+void def_FlattenDefinitionsDestructive(PROOFSEARCH);
+
+void def_Delete(DEF);
+void def_Print(DEF);
+
+int def_PredicateOccurrences(TERM, SYMBOL);
+#endif
diff --git a/test/spass/dfg.h b/test/spass/dfg.h
new file mode 100644
index 0000000..83d38ae
--- /dev/null
+++ b/test/spass/dfg.h
@@ -0,0 +1,86 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INTERFACE FOR THE DFG PARSER * */
+/* * * */
+/* * $Module: DFG * */
+/* * * */
+/* * Copyright (C) 1997, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _DFG_
+#define _DFG_
+
+#include <stdio.h>
+#include "list.h"
+#include "flags.h"
+#include "clause.h"
+
+typedef enum { DFG_SATISFIABLE, DFG_UNSATISFIABLE, DFG_UNKNOWNSTATE } DFG_STATE;
+
+/* Parser functions */
+LIST dfg_DFGParser(FILE*, FLAGSTORE, PRECEDENCE, LIST*, LIST*, LIST*, LIST*);
+LIST dfg_ProofParser(FILE*, FLAGSTORE, PRECEDENCE);
+LIST dfg_TermParser(FILE*, FLAGSTORE, PRECEDENCE);
+
+
+/* Functions for accessing description information */
+const char* dfg_ProblemName(void);
+const char* dfg_ProblemAuthor(void);
+const char* dfg_ProblemVersion(void);
+const char* dfg_ProblemLogic(void);
+DFG_STATE dfg_ProblemStatus(void);
+const char* dfg_ProblemStatusString(void);
+const char* dfg_ProblemDescription(void);
+const char* dfg_ProblemDate(void);
+NAT dfg_DescriptionLength(void);
+
+/* Misc functions */
+void dfg_Free(void); /* Must be called after each parser call */
+void dfg_DeleteFormulaPairList(LIST);
+void dfg_StripLabelsFromList(LIST);
+void dfg_FPrintDescription(FILE*);
+
+void dfg_DeleteProofList(LIST);
+
+CLAUSE dfg_CreateClauseFromTerm(TERM, BOOL, FLAGSTORE, PRECEDENCE);
+TERM dfg_CreateQuantifier(SYMBOL, LIST, TERM);
+
+#endif
diff --git a/test/spass/dfgparser.c b/test/spass/dfgparser.c
new file mode 100644
index 0000000..3691271
--- /dev/null
+++ b/test/spass/dfgparser.c
@@ -0,0 +1,3728 @@
+/* A Bison parser, made from dfgparser.y, by GNU bison 1.75. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ 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, 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. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+ names. */
+#define yyparse dfg_parse
+#define yylex dfg_lex
+#define yyerror dfg_error
+#define yylval dfg_lval
+#define yychar dfg_char
+#define yydebug dfg_debug
+#define yynerrs dfg_nerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ DFG_AND = 258,
+ DFG_AUTHOR = 259,
+ DFG_AXIOMS = 260,
+ DFG_BEGPROB = 261,
+ DFG_BY = 262,
+ DFG_CLAUSE = 263,
+ DFG_CLOSEBRACE = 264,
+ DFG_CLSLIST = 265,
+ DFG_CNF = 266,
+ DFG_CONJECS = 267,
+ DFG_DATE = 268,
+ DFG_DECLLIST = 269,
+ DFG_DESC = 270,
+ DFG_DESCLIST = 271,
+ DFG_DNF = 272,
+ DFG_DOMPRED = 273,
+ DFG_ENDLIST = 274,
+ DFG_ENDPROB = 275,
+ DFG_EQUAL = 276,
+ DFG_EQUIV = 277,
+ DFG_EXISTS = 278,
+ DFG_FALSE = 279,
+ DFG_FORMLIST = 280,
+ DFG_FORMULA = 281,
+ DFG_FORALL = 282,
+ DFG_FREELY = 283,
+ DFG_FUNC = 284,
+ DFG_GENERATED = 285,
+ DFG_GENSET = 286,
+ DFG_HYPOTH = 287,
+ DFG_IMPLIED = 288,
+ DFG_IMPLIES = 289,
+ DFG_LOGIC = 290,
+ DFG_NAME = 291,
+ DFG_NOT = 292,
+ DFG_OPENBRACE = 293,
+ DFG_OPERAT = 294,
+ DFG_OR = 295,
+ DFG_PREC = 296,
+ DFG_PRED = 297,
+ DFG_PRDICAT = 298,
+ DFG_PRFLIST = 299,
+ DFG_QUANTIF = 300,
+ DFG_SATIS = 301,
+ DFG_SETFLAG = 302,
+ DFG_SETTINGS = 303,
+ DFG_SYMLIST = 304,
+ DFG_SORT = 305,
+ DFG_SORTS = 306,
+ DFG_STATUS = 307,
+ DFG_STEP = 308,
+ DFG_SUBSORT = 309,
+ DFG_TERMLIST = 310,
+ DFG_TRUE = 311,
+ DFG_UNKNOWN = 312,
+ DFG_UNSATIS = 313,
+ DFG_VERSION = 314,
+ DFG_NUM = 315,
+ DFG_MINUS1 = 316,
+ DFG_ID = 317,
+ DFG_TEXT = 318
+ };
+#endif
+#define DFG_AND 258
+#define DFG_AUTHOR 259
+#define DFG_AXIOMS 260
+#define DFG_BEGPROB 261
+#define DFG_BY 262
+#define DFG_CLAUSE 263
+#define DFG_CLOSEBRACE 264
+#define DFG_CLSLIST 265
+#define DFG_CNF 266
+#define DFG_CONJECS 267
+#define DFG_DATE 268
+#define DFG_DECLLIST 269
+#define DFG_DESC 270
+#define DFG_DESCLIST 271
+#define DFG_DNF 272
+#define DFG_DOMPRED 273
+#define DFG_ENDLIST 274
+#define DFG_ENDPROB 275
+#define DFG_EQUAL 276
+#define DFG_EQUIV 277
+#define DFG_EXISTS 278
+#define DFG_FALSE 279
+#define DFG_FORMLIST 280
+#define DFG_FORMULA 281
+#define DFG_FORALL 282
+#define DFG_FREELY 283
+#define DFG_FUNC 284
+#define DFG_GENERATED 285
+#define DFG_GENSET 286
+#define DFG_HYPOTH 287
+#define DFG_IMPLIED 288
+#define DFG_IMPLIES 289
+#define DFG_LOGIC 290
+#define DFG_NAME 291
+#define DFG_NOT 292
+#define DFG_OPENBRACE 293
+#define DFG_OPERAT 294
+#define DFG_OR 295
+#define DFG_PREC 296
+#define DFG_PRED 297
+#define DFG_PRDICAT 298
+#define DFG_PRFLIST 299
+#define DFG_QUANTIF 300
+#define DFG_SATIS 301
+#define DFG_SETFLAG 302
+#define DFG_SETTINGS 303
+#define DFG_SYMLIST 304
+#define DFG_SORT 305
+#define DFG_SORTS 306
+#define DFG_STATUS 307
+#define DFG_STEP 308
+#define DFG_SUBSORT 309
+#define DFG_TERMLIST 310
+#define DFG_TRUE 311
+#define DFG_UNKNOWN 312
+#define DFG_UNSATIS 313
+#define DFG_VERSION 314
+#define DFG_NUM 315
+#define DFG_MINUS1 316
+#define DFG_ID 317
+#define DFG_TEXT 318
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 48 "dfgparser.y"
+
+
+#include <ctype.h>
+#include "dfg.h"
+#include "symbol.h"
+#include "term.h"
+#include "foldfg.h"
+#include "stringsx.h"
+
+/* Used for the texts from description section. */
+typedef struct {
+ char* name;
+ char* author;
+ char* version;
+ char* logic;
+ DFG_STATE status;
+ char* description;
+ char* date;
+} DFG_DESCRIPTIONTYPE;
+
+static DFG_DESCRIPTIONTYPE dfg_DESC;
+static LIST dfg_AXIOMLIST;
+static LIST dfg_CONJECLIST;
+static LIST dfg_SORTDECLLIST;
+/* symbol precedence explicitly defined by user */
+static LIST dfg_USERPRECEDENCE;
+static LIST dfg_AXCLAUSES;
+static LIST dfg_CONCLAUSES;
+static LIST dfg_PROOFLIST; /* list_of_proofs */
+static LIST dfg_TERMLIST; /* list_of_terms */
+static BOOL dfg_IGNORE; /* tokens are ignored while TRUE */
+static FLAGSTORE dfg_FLAGS;
+static PRECEDENCE dfg_PRECEDENCE;
+
+/* used also in the scanner */
+NAT dfg_LINENUMBER;
+BOOL dfg_IGNORETEXT;
+
+void yyerror(const char*);
+int yylex(void); /* Defined in dfgscanner.l */
+
+static void dfg_SymbolDecl(int, char*, int);
+static SYMBOL dfg_Symbol(char*, NAT);
+static void dfg_SubSort(char*, char*);
+static void dfg_SymbolGenerated(SYMBOL, BOOL, LIST);
+
+static __inline__ TERM dfg_TermCreate(char* Name, LIST Arguments)
+/* Look up the symbol, check its arity and create the term */
+{
+ SYMBOL s;
+ NAT arity;
+ arity = list_Length(Arguments);
+ s = dfg_Symbol(Name, arity); /* Frees the string */
+ if (!symbol_IsVariable(s) && !symbol_IsFunction(s)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: is not a function.\n", dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ return term_Create(s, Arguments);
+}
+
+static __inline__ TERM dfg_AtomCreate(char* Name, LIST Arguments)
+/* Look up the symbol, check its arity and create the atom term */
+{
+ SYMBOL s;
+ s = dfg_Symbol(Name, list_Length(Arguments)); /* Frees the string */
+ if (symbol_IsVariable(s) || !symbol_IsPredicate(s)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: Symbol is not a predicate.\n", dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ return term_Create(s, Arguments);
+}
+
+static __inline__ void dfg_DeleteStringList(LIST List)
+{
+ list_DeleteWithElement(List, (void (*)(POINTER)) string_StringFree);
+}
+
+/**************************************************************/
+/* Functions that handle symbols with unspecified arity */
+/**************************************************************/
+
+/* The symbol list holds all symbols whose arity wasn't */
+/* specified in the symbol declaration section. */
+/* If the arity of a symbol was not specified in this section */
+/* it is first set to 0. If the symbol occurs with always the */
+/* same arity 'A' the arity of this symbol is set to 'A'. */
+static LIST dfg_SYMBOLLIST;
+
+static void dfg_SymAdd(SYMBOL);
+static void dfg_SymCheck(SYMBOL, NAT);
+static void dfg_SymCleanUp(void);
+
+/**************************************************************/
+/* Functions that handle variable names */
+/**************************************************************/
+
+/* List of quantified variables in the current input formula. */
+/* This list is used to find symbols that by mistake weren't */
+/* declared in the symbol declaration section */
+/* --> free variables */
+/* This is a list of lists, since each time a quantifier is */
+/* reached, a new list is added to the global list. */
+static LIST dfg_VARLIST;
+static BOOL dfg_VARDECL;
+
+static void dfg_VarStart(void);
+static void dfg_VarStop(void);
+static void dfg_VarBacktrack(void);
+static void dfg_VarCheck(void);
+static SYMBOL dfg_VarLookup(char*);
+
+#define YYERROR_VERBOSE
+
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#ifndef YYSTYPE
+#line 165 "dfgparser.y"
+typedef union {
+ int number;
+ char* string;
+ SYMBOL symbol;
+ SPROPERTY property;
+ TERM term;
+ LIST list;
+ DFG_STATE state;
+ BOOL bool;
+} yystype;
+/* Line 193 of /opt/gnu//share/bison/yacc.c. */
+#line 336 "dfgparser.c"
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#ifndef YYLTYPE
+typedef struct yyltype
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} yyltype;
+# define YYLTYPE yyltype
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 213 of /opt/gnu//share/bison/yacc.c. */
+#line 357 "dfgparser.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# else
+# ifndef YYSTACK_USE_ALLOCA
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC malloc
+# define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAX)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 4
+#define YYLAST 506
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 71
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 100
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 196
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 477
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 318
+
+#define YYTRANSLATE(X) \
+ ((unsigned)(X) <= YYMAXUTOK ? yytranslate[X] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 64, 65, 2, 2, 69, 2, 66, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 70, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 67, 2, 68, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned short yyprhs[] =
+{
+ 0, 0, 3, 14, 26, 32, 38, 44, 50, 51,
+ 57, 58, 64, 65, 71, 73, 75, 77, 84, 85,
+ 95, 96, 102, 104, 108, 110, 116, 117, 123, 125,
+ 129, 131, 137, 138, 144, 146, 150, 151, 157, 159,
+ 163, 165, 171, 172, 178, 180, 184, 186, 192, 194,
+ 196, 197, 203, 204, 207, 209, 217, 220, 228, 229,
+ 230, 242, 252, 253, 255, 257, 261, 263, 267, 276,
+ 278, 280, 281, 284, 285, 293, 294, 297, 299, 304,
+ 311, 316, 317, 318, 329, 330, 332, 334, 338, 340,
+ 342, 344, 346, 348, 350, 352, 354, 356, 358, 360,
+ 362, 364, 368, 370, 375, 376, 379, 390, 391, 403,
+ 404, 412, 413, 415, 417, 418, 419, 430, 435, 437,
+ 441, 443, 448, 450, 454, 456, 458, 460, 467, 472,
+ 473, 481, 482, 484, 486, 495, 500, 502, 507, 509,
+ 513, 514, 517, 518, 528, 529, 545, 547, 551, 552,
+ 557, 561, 567, 568, 572, 574, 576, 578, 580, 582,
+ 584, 586, 588, 590, 591, 595, 603, 605, 607, 608,
+ 611, 612, 619, 620, 624, 625, 628, 634, 635, 645,
+ 647, 651, 652, 656, 661, 666, 673, 675, 679, 681,
+ 688, 689, 692, 694, 697, 703, 705
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const short yyrhs[] =
+{
+ 72, 0, -1, 6, 64, 121, 65, 66, 73, 82,
+ 159, 20, 66, -1, 16, 66, 74, 75, 78, 79,
+ 76, 77, 80, 19, 66, -1, 36, 64, 63, 65,
+ 66, -1, 4, 64, 63, 65, 66, -1, 52, 64,
+ 81, 65, 66, -1, 15, 64, 63, 65, 66, -1,
+ -1, 59, 64, 63, 65, 66, -1, -1, 35, 64,
+ 63, 65, 66, -1, -1, 13, 64, 63, 65, 66,
+ -1, 46, -1, 58, -1, 57, -1, 83, 99, 110,
+ 124, 143, 155, -1, -1, 49, 66, 84, 87, 90,
+ 92, 95, 19, 66, -1, -1, 29, 67, 85, 68,
+ 66, -1, 86, -1, 85, 69, 86, -1, 121, -1,
+ 64, 121, 69, 98, 65, -1, -1, 43, 67, 88,
+ 68, 66, -1, 89, -1, 88, 69, 89, -1, 121,
+ -1, 64, 121, 69, 98, 65, -1, -1, 51, 67,
+ 91, 68, 66, -1, 121, -1, 91, 69, 121, -1,
+ -1, 39, 67, 93, 68, 66, -1, 94, -1, 93,
+ 69, 94, -1, 121, -1, 64, 121, 69, 98, 65,
+ -1, -1, 45, 67, 96, 68, 66, -1, 97, -1,
+ 96, 69, 97, -1, 121, -1, 64, 121, 69, 98,
+ 65, -1, 61, -1, 60, -1, -1, 14, 66, 100,
+ 19, 66, -1, -1, 100, 101, -1, 104, -1, 54,
+ 64, 121, 69, 121, 65, 66, -1, 136, 66, -1,
+ 42, 64, 121, 69, 107, 65, 66, -1, -1, -1,
+ 27, 64, 67, 102, 122, 103, 68, 69, 136, 65,
+ 66, -1, 50, 121, 105, 30, 7, 67, 106, 68,
+ 66, -1, -1, 28, -1, 121, -1, 106, 69, 121,
+ -1, 121, -1, 107, 69, 121, -1, 25, 64, 109,
+ 65, 66, 111, 19, 66, -1, 5, -1, 12, -1,
+ -1, 110, 108, -1, -1, 111, 26, 64, 116, 112,
+ 65, 66, -1, -1, 69, 121, -1, 136, -1, 37,
+ 64, 113, 65, -1, 118, 64, 113, 69, 113, 65,
+ -1, 119, 64, 117, 65, -1, -1, -1, 120, 64,
+ 67, 114, 122, 115, 68, 69, 113, 65, -1, -1,
+ 113, -1, 113, -1, 117, 69, 113, -1, 22, -1,
+ 33, -1, 34, -1, 3, -1, 40, -1, 23, -1,
+ 27, -1, 62, -1, 60, -1, 47, -1, 18, -1,
+ 41, -1, 123, -1, 122, 69, 123, -1, 121, -1,
+ 121, 64, 121, 65, -1, -1, 124, 125, -1, 10,
+ 64, 109, 69, 11, 65, 66, 127, 19, 66, -1,
+ -1, 10, 64, 109, 69, 17, 65, 66, 126, 137,
+ 19, 66, -1, -1, 127, 8, 64, 128, 112, 65,
+ 66, -1, -1, 129, -1, 132, -1, -1, -1, 27,
+ 64, 67, 130, 122, 131, 68, 69, 132, 65, -1,
+ 40, 64, 133, 65, -1, 134, -1, 133, 69, 134,
+ -1, 136, -1, 37, 64, 136, 65, -1, 136, -1,
+ 135, 69, 136, -1, 121, -1, 56, -1, 24, -1,
+ 21, 64, 141, 69, 141, 65, -1, 121, 64, 142,
+ 65, -1, -1, 137, 8, 64, 138, 112, 65, 66,
+ -1, -1, 139, -1, 140, -1, 23, 64, 67, 135,
+ 68, 69, 140, 65, -1, 3, 64, 133, 65, -1,
+ 121, -1, 121, 64, 142, 65, -1, 141, -1, 142,
+ 69, 141, -1, -1, 143, 144, -1, -1, 44, 64,
+ 121, 65, 66, 145, 146, 19, 66, -1, -1, 146,
+ 53, 64, 150, 69, 154, 69, 121, 69, 67, 147,
+ 68, 148, 65, 66, -1, 150, -1, 147, 69, 150,
+ -1, -1, 69, 67, 149, 68, -1, 150, 70, 150,
+ -1, 149, 69, 150, 70, 150, -1, -1, 152, 151,
+ 153, -1, 121, -1, 37, -1, 22, -1, 33, -1,
+ 34, -1, 3, -1, 40, -1, 27, -1, 23, -1,
+ -1, 64, 117, 65, -1, 64, 67, 122, 68, 69,
+ 113, 65, -1, 129, -1, 139, -1, -1, 155, 156,
+ -1, -1, 55, 66, 157, 158, 19, 66, -1, -1,
+ 158, 141, 66, -1, -1, 159, 160, -1, 31, 66,
+ 168, 19, 66, -1, -1, 48, 64, 121, 161, 65,
+ 66, 162, 19, 66, -1, 63, -1, 38, 163, 9,
+ -1, -1, 163, 164, 66, -1, 41, 64, 165, 65,
+ -1, 18, 64, 170, 65, -1, 47, 64, 62, 69,
+ 98, 65, -1, 166, -1, 165, 69, 166, -1, 121,
+ -1, 64, 121, 69, 60, 167, 65, -1, -1, 69,
+ 62, -1, 169, -1, 168, 169, -1, 32, 67, 170,
+ 68, 66, -1, 121, -1, 170, 69, 121, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short yyrline[] =
+{
+ 0, 206, 206, 218, 229, 233, 237, 241, 245, 246,
+ 250, 251, 255, 256, 260, 261, 262, 269, 281, 282,
+ 291, 292, 295, 296, 299, 300, 304, 305, 308, 309,
+ 312, 313, 316, 317, 320, 321, 324, 325, 328, 329,
+ 332, 333, 336, 337, 340, 341, 344, 345, 348, 349,
+ 356, 357, 362, 363, 366, 367, 369, 370, 372, 373,
+ 372, 382, 386, 387, 390, 391, 394, 395, 402, 412,
+ 413, 416, 417, 420, 421, 435, 436, 439, 440, 442,
+ 444, 446, 447, 446, 454, 455, 458, 460, 464, 465,
+ 466, 469, 470, 473, 474, 477, 483, 485, 487, 489,
+ 493, 495, 499, 510, 534, 535, 538, 548, 547, 554,
+ 555, 569, 570, 573, 574, 575, 574, 582, 586, 588,
+ 592, 593, 597, 598, 601, 603, 605, 607, 609, 616,
+ 617, 620, 621, 624, 625, 628, 635, 637, 641, 643,
+ 651, 652, 656, 655, 669, 670, 691, 693, 698, 699,
+ 702, 710, 721, 720, 732, 733, 734, 735, 736, 737,
+ 738, 739, 740, 743, 744, 745, 748, 749, 757, 758,
+ 761, 761, 768, 769, 776, 777, 780, 781, 781, 789,
+ 792, 795, 796, 799, 800, 820, 832, 833, 836, 848,
+ 865, 866, 883, 884, 887, 891, 892
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "DFG_AND", "DFG_AUTHOR", "DFG_AXIOMS",
+ "DFG_BEGPROB", "DFG_BY", "DFG_CLAUSE", "DFG_CLOSEBRACE", "DFG_CLSLIST",
+ "DFG_CNF", "DFG_CONJECS", "DFG_DATE", "DFG_DECLLIST", "DFG_DESC",
+ "DFG_DESCLIST", "DFG_DNF", "DFG_DOMPRED", "DFG_ENDLIST", "DFG_ENDPROB",
+ "DFG_EQUAL", "DFG_EQUIV", "DFG_EXISTS", "DFG_FALSE", "DFG_FORMLIST",
+ "DFG_FORMULA", "DFG_FORALL", "DFG_FREELY", "DFG_FUNC", "DFG_GENERATED",
+ "DFG_GENSET", "DFG_HYPOTH", "DFG_IMPLIED", "DFG_IMPLIES", "DFG_LOGIC",
+ "DFG_NAME", "DFG_NOT", "DFG_OPENBRACE", "DFG_OPERAT", "DFG_OR",
+ "DFG_PREC", "DFG_PRED", "DFG_PRDICAT", "DFG_PRFLIST", "DFG_QUANTIF",
+ "DFG_SATIS", "DFG_SETFLAG", "DFG_SETTINGS", "DFG_SYMLIST", "DFG_SORT",
+ "DFG_SORTS", "DFG_STATUS", "DFG_STEP", "DFG_SUBSORT", "DFG_TERMLIST",
+ "DFG_TRUE", "DFG_UNKNOWN", "DFG_UNSATIS", "DFG_VERSION", "DFG_NUM",
+ "DFG_MINUS1", "DFG_ID", "DFG_TEXT", "'('", "')'", "'.'", "'['", "']'",
+ "','", "':'", "$accept", "problem", "description", "name", "author",
+ "status", "desctext", "versionopt", "logicopt", "dateopt", "log_state",
+ "logicalpart", "symbollistopt", "functionsopt", "functionlist", "func",
+ "predicatesopt", "predicatelist", "pred", "sortsopt", "sortlist",
+ "operatorsopt", "operatorlist", "op", "quantifiersopt",
+ "quantifierlist", "quant", "number", "declarationlistopt",
+ "decllistopt", "decl", "@1", "@2", "gendecl", "freelyopt", "funclist",
+ "sortdecl", "formulalist", "origin", "formulalistsopt",
+ "formulalistopt", "labelopt", "formula", "@3", "@4", "formulaopt",
+ "arglist", "binsymbol", "nsymbol", "quantsymbol", "id", "qtermlist",
+ "qterm", "clauselistsopt", "clauselist", "@5", "cnfclausesopt",
+ "cnfclauseopt", "cnfclause", "@6", "@7", "cnfclausebody", "litlist",
+ "lit", "atomlist", "atom", "dnfclausesopt", "dnfclauseopt", "dnfclause",
+ "dnfclausebody", "term", "termlist", "prooflistsopt", "prooflist", "@8",
+ "prooflistopt", "parentlist", "assoclistopt", "assoclist",
+ "id_or_formula", "@9", "anysymbol", "optargs", "clause",
+ "listOfTermsopt", "listOfTerms", "@10", "terms", "settinglistsopt",
+ "settinglist", "@11", "flags", "spassflags", "spassflag", "preclist",
+ "precitem", "statopt", "gsettings", "gsetting", "labellist", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 40, 41, 46, 91, 93, 44,
+ 58
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 71, 72, 73, 74, 75, 76, 77, 78, 78,
+ 79, 79, 80, 80, 81, 81, 81, 82, 83, 83,
+ 84, 84, 85, 85, 86, 86, 87, 87, 88, 88,
+ 89, 89, 90, 90, 91, 91, 92, 92, 93, 93,
+ 94, 94, 95, 95, 96, 96, 97, 97, 98, 98,
+ 99, 99, 100, 100, 101, 101, 101, 101, 102, 103,
+ 101, 104, 105, 105, 106, 106, 107, 107, 108, 109,
+ 109, 110, 110, 111, 111, 112, 112, 113, 113, 113,
+ 113, 114, 115, 113, 116, 116, 117, 117, 118, 118,
+ 118, 119, 119, 120, 120, 121, 121, 121, 121, 121,
+ 122, 122, 123, 123, 124, 124, 125, 126, 125, 127,
+ 127, 128, 128, 129, 130, 131, 129, 132, 133, 133,
+ 134, 134, 135, 135, 136, 136, 136, 136, 136, 137,
+ 137, 138, 138, 139, 139, 140, 141, 141, 142, 142,
+ 143, 143, 145, 144, 146, 146, 147, 147, 148, 148,
+ 149, 149, 151, 150, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 153, 153, 153, 154, 154, 155, 155,
+ 157, 156, 158, 158, 159, 159, 160, 161, 160, 162,
+ 162, 163, 163, 164, 164, 164, 165, 165, 166, 166,
+ 167, 167, 168, 168, 169, 170, 170
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 10, 11, 5, 5, 5, 5, 0, 5,
+ 0, 5, 0, 5, 1, 1, 1, 6, 0, 9,
+ 0, 5, 1, 3, 1, 5, 0, 5, 1, 3,
+ 1, 5, 0, 5, 1, 3, 0, 5, 1, 3,
+ 1, 5, 0, 5, 1, 3, 1, 5, 1, 1,
+ 0, 5, 0, 2, 1, 7, 2, 7, 0, 0,
+ 11, 9, 0, 1, 1, 3, 1, 3, 8, 1,
+ 1, 0, 2, 0, 7, 0, 2, 1, 4, 6,
+ 4, 0, 0, 10, 0, 1, 1, 3, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 1, 4, 0, 2, 10, 0, 11, 0,
+ 7, 0, 1, 1, 0, 0, 10, 4, 1, 3,
+ 1, 4, 1, 3, 1, 1, 1, 6, 4, 0,
+ 7, 0, 1, 1, 8, 4, 1, 4, 1, 3,
+ 0, 2, 0, 9, 0, 15, 1, 3, 0, 4,
+ 3, 5, 0, 3, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 3, 7, 1, 1, 0, 2,
+ 0, 6, 0, 3, 0, 2, 5, 0, 9, 1,
+ 3, 0, 3, 4, 4, 6, 1, 3, 1, 6,
+ 0, 2, 1, 2, 5, 1, 3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 0, 0, 0, 0, 1, 98, 99, 97, 96, 95,
+ 0, 0, 0, 0, 18, 0, 0, 174, 50, 0,
+ 0, 20, 0, 0, 71, 0, 0, 8, 0, 26,
+ 0, 0, 0, 175, 52, 104, 0, 0, 0, 10,
+ 0, 0, 32, 2, 0, 0, 0, 0, 72, 140,
+ 0, 0, 0, 0, 0, 0, 0, 22, 24, 0,
+ 0, 36, 0, 0, 192, 177, 0, 0, 126, 0,
+ 0, 0, 0, 125, 53, 54, 124, 0, 0, 0,
+ 105, 168, 4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 28, 30, 0, 0, 42, 0, 0,
+ 193, 0, 51, 0, 0, 0, 62, 0, 0, 56,
+ 69, 70, 0, 0, 0, 141, 17, 5, 0, 0,
+ 0, 0, 12, 0, 21, 23, 0, 0, 0, 0,
+ 34, 0, 0, 0, 195, 0, 176, 0, 136, 0,
+ 58, 0, 63, 0, 0, 138, 0, 0, 0, 0,
+ 0, 169, 9, 0, 14, 16, 15, 0, 0, 0,
+ 0, 49, 48, 0, 0, 27, 29, 0, 0, 0,
+ 0, 38, 40, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 128, 0, 73, 0, 0, 170,
+ 11, 0, 0, 0, 0, 25, 0, 33, 35, 0,
+ 0, 0, 0, 0, 44, 46, 19, 194, 196, 181,
+ 179, 0, 0, 0, 102, 59, 100, 0, 66, 0,
+ 0, 139, 0, 0, 0, 0, 172, 6, 0, 0,
+ 3, 31, 0, 37, 39, 0, 0, 0, 0, 0,
+ 137, 127, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 142, 0, 7, 0, 0, 0, 43,
+ 45, 180, 0, 0, 0, 0, 178, 0, 101, 0,
+ 57, 67, 0, 64, 55, 68, 84, 109, 107, 144,
+ 0, 0, 13, 41, 0, 0, 0, 0, 182, 103,
+ 0, 0, 0, 91, 88, 93, 94, 89, 90, 0,
+ 92, 85, 75, 0, 0, 0, 77, 0, 129, 0,
+ 171, 173, 47, 0, 0, 188, 0, 186, 0, 0,
+ 61, 65, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 184, 0, 183, 0, 0, 0, 0,
+ 76, 0, 0, 86, 0, 81, 111, 106, 0, 0,
+ 143, 0, 0, 187, 0, 60, 78, 74, 0, 80,
+ 0, 0, 0, 0, 75, 112, 113, 131, 108, 159,
+ 156, 162, 161, 157, 158, 155, 160, 154, 0, 152,
+ 190, 185, 0, 87, 82, 0, 0, 0, 0, 0,
+ 75, 132, 133, 0, 163, 0, 0, 79, 0, 114,
+ 0, 0, 118, 120, 0, 0, 0, 0, 166, 167,
+ 0, 0, 153, 191, 189, 0, 0, 0, 117, 0,
+ 110, 0, 0, 0, 0, 0, 0, 0, 115, 0,
+ 119, 135, 0, 122, 130, 0, 0, 164, 0, 0,
+ 121, 0, 0, 0, 0, 83, 0, 0, 123, 0,
+ 0, 0, 0, 0, 146, 0, 0, 134, 148, 0,
+ 165, 116, 0, 0, 147, 0, 0, 0, 0, 145,
+ 149, 0, 0, 0, 150, 0, 151
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short yydefgoto[] =
+{
+ -1, 2, 14, 20, 27, 87, 122, 39, 54, 160,
+ 157, 17, 18, 29, 56, 57, 42, 92, 93, 61,
+ 129, 97, 170, 171, 133, 203, 204, 163, 24, 46,
+ 74, 180, 244, 75, 143, 272, 217, 48, 112, 35,
+ 222, 324, 343, 361, 398, 302, 344, 303, 304, 305,
+ 76, 215, 216, 49, 80, 308, 307, 364, 365, 416,
+ 439, 366, 401, 402, 432, 306, 330, 390, 391, 392,
+ 145, 146, 81, 115, 279, 309, 453, 463, 467, 378,
+ 394, 379, 412, 410, 116, 151, 226, 254, 22, 33,
+ 101, 211, 238, 265, 316, 317, 396, 63, 64, 135
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -356
+static const short yypact[] =
+{
+ 9, -32, 35, 232, -356, -356, -356, -356, -356, -356,
+ -6, 13, 67, 20, 45, 53, 30, -356, 110, 46,
+ 118, 121, -12, 73, -356, 91, 84, 113, 112, 141,
+ 123, 128, 132, -356, -356, 175, 152, 161, 155, 191,
+ 2, 162, 180, -356, 204, 232, 214, 173, -356, 252,
+ 176, 206, 209, 213, 226, 232, 47, -356, -356, 80,
+ 218, 254, 224, -14, -356, -356, 230, 233, -356, 234,
+ 241, 232, 242, -356, -356, -356, 243, 237, 21, 244,
+ -356, 260, -356, 246, 245, 250, 251, 294, 247, 248,
+ 2, 232, 93, -356, -356, 232, 255, 272, 232, 253,
+ -356, 256, -356, 232, 257, 232, 290, 232, 232, -356,
+ -356, -356, 258, 21, 261, -356, 271, -356, 262, 264,
+ 14, 263, 317, 108, -356, -356, 265, 266, 80, 119,
+ -356, 85, 268, 312, -356, 124, -356, 270, 273, 269,
+ -356, 274, -356, 309, 275, -356, -52, 276, 277, 232,
+ 279, -356, -356, 281, -356, -356, -356, 284, 287, 288,
+ 321, -356, -356, 286, 108, -356, -356, 289, 232, 232,
+ 138, -356, -356, 156, 291, 293, 232, -17, 232, 232,
+ 232, 232, 346, 232, -356, 232, -356, 40, 296, -356,
+ -356, 297, 299, 302, 300, -356, 303, -356, -356, 285,
+ 301, 85, 232, 143, -356, -356, -356, -356, -356, -356,
+ -356, 337, 16, 304, 298, 306, -356, 32, -356, 311,
+ 305, -356, 56, 308, 314, 310, -356, -356, 315, 318,
+ -356, -356, 108, -356, -356, 313, 319, 156, -2, 320,
+ -356, -356, 232, 232, 316, 322, 232, 232, 323, 324,
+ 307, 325, 326, -356, 240, -356, 327, 329, 108, -356,
+ -356, -356, 331, 332, 334, 333, -356, 335, -356, 336,
+ -356, -356, 145, -356, -356, -356, 96, -356, -356, -356,
+ 338, 340, -356, -356, 342, 232, 163, 339, -356, -356,
+ 239, 343, 232, -356, -356, -356, -356, -356, -356, 344,
+ -356, -356, 341, 347, 348, 350, -356, 3, -356, -15,
+ -356, -356, -356, 42, 232, -356, 43, -356, 349, 351,
+ -356, -356, 96, 232, 352, 96, 96, 353, 355, 357,
+ 57, 358, 361, -356, 359, -356, 163, 108, 360, 362,
+ -356, 363, 364, -356, 44, -356, -13, -356, 366, 365,
+ -356, 168, 372, -356, 369, -356, -356, -356, 96, -356,
+ 96, 232, 371, 373, 341, -356, -356, 0, -356, -356,
+ -356, -356, -356, -356, -356, -356, -356, -356, 367, -356,
+ 370, -356, 375, -356, 306, 374, 228, 377, 379, 380,
+ 341, -356, -356, 50, 381, 376, 382, -356, 383, -356,
+ 384, 66, -356, -356, 386, 228, 387, 385, -356, -356,
+ 388, 7, -356, -356, -356, 389, 232, 239, -356, 228,
+ -356, 69, 239, 393, 232, 232, 90, 96, 306, 390,
+ -356, -356, 153, -356, -356, 391, 179, -356, 396, 395,
+ -356, 397, 239, 398, 401, -356, 402, 399, -356, 168,
+ 96, 409, 408, 185, -356, 410, 411, -356, 405, 168,
+ -356, -356, 400, 412, -356, 168, 413, 198, 345, -356,
+ -356, 168, 168, 394, -356, 168, -356
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const short yypgoto[] =
+{
+ -356, -356, -356, -356, -356, -356, -356, -356, -356, -356,
+ -356, -356, -356, -356, -356, 392, -356, -356, 259, -356,
+ -356, -356, -356, 202, -356, -356, 216, -152, -356, -356,
+ -356, -356, -356, -356, -356, -356, -356, -356, 267, -356,
+ -356, -340, -267, -356, -356, -356, 70, -356, -356, -356,
+ -3, -355, 235, -356, -356, -356, -356, -356, 87, -356,
+ -356, 33, 78, 68, -356, -45, -356, -356, 92, 39,
+ -101, 328, -356, -356, -356, -356, -356, -356, -356, -308,
+ -356, -356, -356, -356, -356, -356, -356, -356, -356, -356,
+ -356, -356, -356, -356, -356, 154, -356, -356, 425, 207
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, parse error. */
+#define YYTABLE_NINF -1
+static const unsigned short yytable[] =
+{
+ 10, 77, 139, 388, 331, 99, 384, 261, 30, 301,
+ 293, 328, 196, 184, 362, 1, 262, 185, 62, 31,
+ 5, 209, 329, 389, 387, 5, 110, 363, 67, 294,
+ 295, 68, 3, 111, 296, 4, 32, 58, 332, 263,
+ 297, 298, 65, 6, 299, 264, 210, 300, 6, 7,
+ 407, 223, 88, 388, 7, 339, 94, 224, 342, 11,
+ 154, 428, 8, 73, 9, 348, 55, 8, 106, 9,
+ 436, 155, 156, 389, 425, 249, 349, 362, 213, 12,
+ 257, 240, 250, 13, 221, 185, 15, 58, 126, 19,
+ 363, 382, 130, 383, 16, 134, 21, 245, 5, 293,
+ 138, 246, 141, 5, 144, 138, 284, 333, 335, 359,
+ 25, 176, 336, 360, 5, 89, 90, 67, 294, 295,
+ 68, 6, 26, 296, 23, 94, 6, 7, 172, 297,
+ 298, 418, 7, 299, 431, 419, 300, 6, 419, 34,
+ 8, 454, 9, 7, 91, 8, 188, 9, 37, 169,
+ 28, 464, 73, 281, 36, 437, 8, 468, 9, 360,
+ 438, 127, 128, 473, 474, 198, 199, 476, 161, 162,
+ 205, 369, 38, 208, 5, 138, 138, 214, 218, 40,
+ 220, 5, 138, 455, 41, 354, 5, 167, 168, 43,
+ 370, 371, 175, 176, 44, 372, 45, 6, 172, 235,
+ 47, 373, 374, 7, 6, 375, 200, 201, 376, 6,
+ 7, 236, 237, 291, 292, 7, 8, 50, 9, 52,
+ 202, 441, 442, 8, 51, 9, 53, 314, 8, 59,
+ 9, 60, 5, 66, 205, 67, 62, 78, 68, 267,
+ 214, 69, 82, 271, 273, 319, 5, 444, 243, 67,
+ 5, 138, 68, 458, 459, 6, 70, 5, 5, 280,
+ 67, 7, 79, 68, 71, 400, 470, 471, 72, 6,
+ 73, 83, 84, 6, 8, 7, 9, 85, 86, 7,
+ 6, 6, 134, 315, 73, 95, 7, 7, 8, 321,
+ 9, 98, 8, 96, 9, 73, 102, 103, 104, 8,
+ 8, 9, 9, 109, 114, 105, 107, 108, 113, 121,
+ 118, 334, 117, 119, 124, 120, 123, 132, 142, 136,
+ 340, 137, 131, 147, 140, 149, 150, 158, 152, 153,
+ 159, 174, 165, 315, 164, 173, 177, 178, 179, 182,
+ 194, 403, 186, 181, 183, 189, 187, 190, 377, 191,
+ 192, 195, 193, 219, 232, 197, 239, 206, 214, 207,
+ 403, 225, 242, 227, 228, 229, 230, 233, 231, 241,
+ 248, 276, 429, 251, 403, 243, 253, 433, 247, 252,
+ 148, 255, 258, 256, 269, 259, 266, 166, 270, 274,
+ 275, 277, 278, 282, 283, 285, 286, 448, 287, 288,
+ 289, 318, 388, 234, 310, 290, 311, 312, 322, 320,
+ 323, 325, 326, 214, 327, 472, 338, 341, 337, 346,
+ 345, 435, 214, 347, 350, 351, 355, 356, 352, 357,
+ 367, 368, 380, 358, 381, 385, 393, 386, 413, 395,
+ 397, 399, 404, 405, 406, 411, 377, 414, 417, 363,
+ 423, 415, 420, 260, 422, 440, 377, 424, 427, 434,
+ 443, 445, 377, 446, 475, 449, 447, 465, 377, 377,
+ 450, 451, 377, 457, 462, 460, 461, 466, 268, 469,
+ 408, 426, 125, 421, 456, 409, 452, 430, 100, 0,
+ 353, 0, 313, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 212
+};
+
+static const short yycheck[] =
+{
+ 3, 46, 103, 3, 19, 19, 361, 9, 20, 276,
+ 3, 8, 164, 65, 27, 6, 18, 69, 32, 31,
+ 18, 38, 19, 23, 364, 18, 5, 40, 21, 22,
+ 23, 24, 64, 12, 27, 0, 48, 40, 53, 41,
+ 33, 34, 45, 41, 37, 47, 63, 40, 41, 47,
+ 390, 11, 55, 3, 47, 322, 59, 17, 325, 65,
+ 46, 416, 60, 56, 62, 8, 64, 60, 71, 62,
+ 425, 57, 58, 23, 67, 19, 19, 27, 179, 66,
+ 232, 65, 26, 16, 185, 69, 66, 90, 91, 36,
+ 40, 358, 95, 360, 49, 98, 66, 65, 18, 3,
+ 103, 69, 105, 18, 107, 108, 258, 65, 65, 65,
+ 64, 69, 69, 69, 18, 68, 69, 21, 22, 23,
+ 24, 41, 4, 27, 14, 128, 41, 47, 131, 33,
+ 34, 65, 47, 37, 65, 69, 40, 41, 69, 66,
+ 60, 449, 62, 47, 64, 60, 149, 62, 64, 64,
+ 29, 459, 56, 254, 63, 65, 60, 465, 62, 69,
+ 427, 68, 69, 471, 472, 168, 169, 475, 60, 61,
+ 173, 3, 59, 176, 18, 178, 179, 180, 181, 67,
+ 183, 18, 185, 450, 43, 337, 18, 68, 69, 66,
+ 22, 23, 68, 69, 66, 27, 64, 41, 201, 202,
+ 25, 33, 34, 47, 41, 37, 68, 69, 40, 41,
+ 47, 68, 69, 68, 69, 47, 60, 65, 62, 64,
+ 64, 68, 69, 60, 63, 62, 35, 64, 60, 67,
+ 62, 51, 18, 19, 237, 21, 32, 64, 24, 242,
+ 243, 27, 66, 246, 247, 290, 18, 68, 69, 21,
+ 18, 254, 24, 68, 69, 41, 42, 18, 18, 19,
+ 21, 47, 10, 24, 50, 37, 68, 69, 54, 41,
+ 56, 65, 63, 41, 60, 47, 62, 64, 52, 47,
+ 41, 41, 285, 286, 56, 67, 47, 47, 60, 292,
+ 62, 67, 60, 39, 62, 56, 66, 64, 64, 60,
+ 60, 62, 62, 66, 44, 64, 64, 64, 64, 15,
+ 65, 314, 66, 63, 66, 64, 69, 45, 28, 66,
+ 323, 65, 67, 65, 67, 64, 55, 64, 66, 65,
+ 13, 19, 66, 336, 69, 67, 66, 64, 69, 30,
+ 19, 386, 66, 69, 69, 66, 69, 66, 351, 65,
+ 63, 65, 64, 7, 69, 66, 19, 66, 361, 66,
+ 405, 65, 64, 66, 65, 63, 66, 66, 65, 65,
+ 65, 64, 417, 65, 419, 69, 66, 422, 67, 65,
+ 113, 66, 69, 65, 68, 66, 66, 128, 66, 66,
+ 66, 66, 66, 66, 65, 64, 64, 442, 64, 66,
+ 65, 62, 3, 201, 66, 69, 66, 65, 64, 66,
+ 69, 64, 64, 416, 64, 70, 65, 65, 69, 64,
+ 67, 424, 425, 66, 66, 64, 66, 65, 69, 66,
+ 64, 66, 60, 69, 65, 64, 69, 64, 62, 69,
+ 65, 67, 65, 64, 64, 64, 449, 65, 64, 40,
+ 65, 68, 66, 237, 67, 65, 459, 69, 69, 66,
+ 69, 65, 465, 68, 70, 67, 69, 67, 471, 472,
+ 69, 69, 475, 65, 69, 65, 65, 65, 243, 66,
+ 393, 411, 90, 405, 451, 393, 447, 419, 63, -1,
+ 336, -1, 285, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 178
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 6, 72, 64, 0, 18, 41, 47, 60, 62,
+ 121, 65, 66, 16, 73, 66, 49, 82, 83, 36,
+ 74, 66, 159, 14, 99, 64, 4, 75, 29, 84,
+ 20, 31, 48, 160, 66, 110, 63, 64, 59, 78,
+ 67, 43, 87, 66, 66, 64, 100, 25, 108, 124,
+ 65, 63, 64, 35, 79, 64, 85, 86, 121, 67,
+ 51, 90, 32, 168, 169, 121, 19, 21, 24, 27,
+ 42, 50, 54, 56, 101, 104, 121, 136, 64, 10,
+ 125, 143, 66, 65, 63, 64, 52, 76, 121, 68,
+ 69, 64, 88, 89, 121, 67, 39, 92, 67, 19,
+ 169, 161, 66, 64, 64, 64, 121, 64, 64, 66,
+ 5, 12, 109, 64, 44, 144, 155, 66, 65, 63,
+ 64, 15, 77, 69, 66, 86, 121, 68, 69, 91,
+ 121, 67, 45, 95, 121, 170, 66, 65, 121, 141,
+ 67, 121, 28, 105, 121, 141, 142, 65, 109, 64,
+ 55, 156, 66, 65, 46, 57, 58, 81, 64, 13,
+ 80, 60, 61, 98, 69, 66, 89, 68, 69, 64,
+ 93, 94, 121, 67, 19, 68, 69, 66, 64, 69,
+ 102, 69, 30, 69, 65, 69, 66, 69, 121, 66,
+ 66, 65, 63, 64, 19, 65, 98, 66, 121, 121,
+ 68, 69, 64, 96, 97, 121, 66, 66, 121, 38,
+ 63, 162, 142, 141, 121, 122, 123, 107, 121, 7,
+ 121, 141, 111, 11, 17, 65, 157, 66, 65, 63,
+ 66, 65, 69, 66, 94, 121, 68, 69, 163, 19,
+ 65, 65, 64, 69, 103, 65, 69, 67, 65, 19,
+ 26, 65, 65, 66, 158, 66, 65, 98, 69, 66,
+ 97, 9, 18, 41, 47, 164, 66, 121, 123, 68,
+ 66, 121, 106, 121, 66, 66, 64, 66, 66, 145,
+ 19, 141, 66, 65, 98, 64, 64, 64, 66, 65,
+ 69, 68, 69, 3, 22, 23, 27, 33, 34, 37,
+ 40, 113, 116, 118, 119, 120, 136, 127, 126, 146,
+ 66, 66, 65, 170, 64, 121, 165, 166, 62, 136,
+ 66, 121, 64, 69, 112, 64, 64, 64, 8, 19,
+ 137, 19, 53, 65, 121, 65, 69, 69, 65, 113,
+ 121, 65, 113, 113, 117, 67, 64, 66, 8, 19,
+ 66, 64, 69, 166, 98, 66, 65, 66, 69, 65,
+ 69, 114, 27, 40, 128, 129, 132, 64, 66, 3,
+ 22, 23, 27, 33, 34, 37, 40, 121, 150, 152,
+ 60, 65, 113, 113, 122, 64, 64, 112, 3, 23,
+ 138, 139, 140, 69, 151, 69, 167, 65, 115, 67,
+ 37, 133, 134, 136, 65, 64, 64, 112, 129, 139,
+ 154, 64, 153, 62, 65, 68, 130, 64, 65, 69,
+ 66, 133, 67, 65, 69, 67, 117, 69, 122, 136,
+ 134, 65, 135, 136, 66, 121, 122, 65, 113, 131,
+ 65, 68, 69, 69, 68, 65, 68, 69, 136, 67,
+ 69, 69, 140, 147, 150, 113, 132, 65, 68, 69,
+ 65, 65, 69, 148, 150, 67, 65, 149, 150, 66,
+ 68, 69, 70, 150, 150, 70, 150
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up"); \
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current.first_line = Rhs[1].first_line; \
+ Current.first_column = Rhs[1].first_column; \
+ Current.last_line = Rhs[N].last_line; \
+ Current.last_column = Rhs[N].last_column;
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#define YYLEX yylex ()
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*-----------------------------.
+| Print this symbol on YYOUT. |
+`-----------------------------*/
+
+static void
+#if defined (__STDC__) || defined (__cplusplus)
+yysymprint (FILE* yyout, int yytype, YYSTYPE yyvalue)
+#else
+yysymprint (yyout, yytype, yyvalue)
+ FILE* yyout;
+ int yytype;
+ YYSTYPE yyvalue;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvalue;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyout, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyout, yytoknum[yytype], yyvalue);
+# endif
+ }
+ else
+ YYFPRINTF (yyout, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyout, ")");
+}
+#endif /* YYDEBUG. */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+#if defined (__STDC__) || defined (__cplusplus)
+yydestruct (int yytype, YYSTYPE yyvalue)
+#else
+yydestruct (yytype, yyvalue)
+ int yytype;
+ YYSTYPE yyvalue;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvalue;
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL
+# else
+# define YYPARSE_PARAM_ARG YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of parse errors so far. */
+int yynerrs;
+
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yychar1 = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with. */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more. */
+
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE (yychar);
+
+ /* We have to keep this `#if YYDEBUG', since we use variables
+ which are defined only if `YYDEBUG' is set. */
+ YYDPRINTF ((stderr, "Next token is "));
+ YYDSYMPRINT ((stderr, yychar1, yylval));
+ YYDPRINTF ((stderr, "\n"));
+ }
+
+ /* If the proper action on seeing token YYCHAR1 is to reduce or to
+ detect an error, take that action. */
+ yyn += yychar1;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yychar1)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %d (%s), ",
+ yychar, yytname[yychar1]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+
+#if YYDEBUG
+ /* We have to keep this `#if YYDEBUG', since we use variables which
+ are defined only if `YYDEBUG' is set. */
+ if (yydebug)
+ {
+ int yyi;
+
+ YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
+ yyn - 1, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyn]; yyrhs[yyi] >= 0; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+ YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+ switch (yyn)
+ {
+ case 2:
+#line 210 "dfgparser.y"
+ { string_StringFree(yyvsp[-7].string);
+ YYACCEPT; /* Stop immediately */ }
+ break;
+
+ case 4:
+#line 230 "dfgparser.y"
+ { dfg_DESC.name = yyvsp[-2].string; }
+ break;
+
+ case 5:
+#line 234 "dfgparser.y"
+ { dfg_DESC.author = yyvsp[-2].string; }
+ break;
+
+ case 6:
+#line 238 "dfgparser.y"
+ { dfg_DESC.status = yyvsp[-2].state; }
+ break;
+
+ case 7:
+#line 242 "dfgparser.y"
+ { dfg_DESC.description = yyvsp[-2].string; }
+ break;
+
+ case 9:
+#line 247 "dfgparser.y"
+ { dfg_DESC.version = yyvsp[-2].string; }
+ break;
+
+ case 11:
+#line 252 "dfgparser.y"
+ { dfg_DESC.logic = yyvsp[-2].string; }
+ break;
+
+ case 13:
+#line 257 "dfgparser.y"
+ { dfg_DESC.date = yyvsp[-2].string; }
+ break;
+
+ case 14:
+#line 260 "dfgparser.y"
+ { yyval.state = DFG_SATISFIABLE; }
+ break;
+
+ case 15:
+#line 261 "dfgparser.y"
+ { yyval.state = DFG_UNSATISFIABLE; }
+ break;
+
+ case 16:
+#line 262 "dfgparser.y"
+ { yyval.state = DFG_UNKNOWNSTATE; }
+ break;
+
+ case 24:
+#line 299 "dfgparser.y"
+ { dfg_SymbolDecl(DFG_FUNC, yyvsp[0].string, -2); }
+ break;
+
+ case 25:
+#line 301 "dfgparser.y"
+ { dfg_SymbolDecl(DFG_FUNC, yyvsp[-3].string, yyvsp[-1].number); }
+ break;
+
+ case 30:
+#line 312 "dfgparser.y"
+ { dfg_SymbolDecl(DFG_PRDICAT, yyvsp[0].string, -2); }
+ break;
+
+ case 31:
+#line 313 "dfgparser.y"
+ { dfg_SymbolDecl(DFG_PRDICAT, yyvsp[-3].string, yyvsp[-1].number); }
+ break;
+
+ case 34:
+#line 320 "dfgparser.y"
+ { dfg_SymbolDecl(DFG_PRDICAT, yyvsp[0].string, 1); }
+ break;
+
+ case 35:
+#line 321 "dfgparser.y"
+ { dfg_SymbolDecl(DFG_PRDICAT, yyvsp[0].string, 1); }
+ break;
+
+ case 40:
+#line 332 "dfgparser.y"
+ { dfg_SymbolDecl(DFG_OPERAT, yyvsp[0].string, -2); }
+ break;
+
+ case 41:
+#line 333 "dfgparser.y"
+ { dfg_SymbolDecl(DFG_OPERAT, yyvsp[-3].string, yyvsp[-1].number); }
+ break;
+
+ case 46:
+#line 344 "dfgparser.y"
+ { dfg_SymbolDecl(DFG_QUANTIF, yyvsp[0].string, -2); }
+ break;
+
+ case 47:
+#line 345 "dfgparser.y"
+ { dfg_SymbolDecl(DFG_QUANTIF, yyvsp[-3].string, yyvsp[-1].number); }
+ break;
+
+ case 48:
+#line 348 "dfgparser.y"
+ { yyval.number = -1; }
+ break;
+
+ case 49:
+#line 349 "dfgparser.y"
+ { yyval.number = yyvsp[0].number; }
+ break;
+
+ case 55:
+#line 368 "dfgparser.y"
+ { dfg_SubSort(yyvsp[-4].string,yyvsp[-2].string); }
+ break;
+
+ case 56:
+#line 369 "dfgparser.y"
+ { dfg_SORTDECLLIST = list_Nconc(dfg_SORTDECLLIST,list_List(list_PairCreate(NULL,yyvsp[-1].term))); }
+ break;
+
+ case 57:
+#line 371 "dfgparser.y"
+ { string_StringFree(yyvsp[-4].string); }
+ break;
+
+ case 58:
+#line 372 "dfgparser.y"
+ { dfg_VarStart(); }
+ break;
+
+ case 59:
+#line 373 "dfgparser.y"
+ { dfg_VarStop(); }
+ break;
+
+ case 60:
+#line 374 "dfgparser.y"
+ { TERM term;
+ dfg_VarBacktrack();
+ dfg_VarCheck();
+ term = dfg_CreateQuantifier(fol_All(),yyvsp[-6].list,yyvsp[-2].term);
+ dfg_SORTDECLLIST = list_Nconc(dfg_SORTDECLLIST,list_List(list_PairCreate(NULL,term)));
+ }
+ break;
+
+ case 61:
+#line 383 "dfgparser.y"
+ { dfg_SymbolGenerated(dfg_Symbol(yyvsp[-7].string,1), yyvsp[-6].bool, yyvsp[-2].list); }
+ break;
+
+ case 62:
+#line 386 "dfgparser.y"
+ { yyval.bool = FALSE; }
+ break;
+
+ case 63:
+#line 387 "dfgparser.y"
+ { yyval.bool = TRUE; }
+ break;
+
+ case 64:
+#line 390 "dfgparser.y"
+ { yyval.list = list_List(yyvsp[0].string); }
+ break;
+
+ case 65:
+#line 391 "dfgparser.y"
+ { yyval.list = list_Cons(yyvsp[0].string, yyvsp[-2].list); }
+ break;
+
+ case 66:
+#line 394 "dfgparser.y"
+ { string_StringFree(yyvsp[0].string); }
+ break;
+
+ case 67:
+#line 395 "dfgparser.y"
+ { string_StringFree(yyvsp[0].string); }
+ break;
+
+ case 68:
+#line 404 "dfgparser.y"
+ { list_NReverse(yyvsp[-2].list);
+ if (yyvsp[-5].bool) /* Axioms */
+ dfg_AXIOMLIST = list_Nconc(dfg_AXIOMLIST, yyvsp[-2].list);
+ else
+ dfg_CONJECLIST = list_Nconc(dfg_CONJECLIST, yyvsp[-2].list);
+ }
+ break;
+
+ case 69:
+#line 412 "dfgparser.y"
+ { yyval.bool = TRUE; }
+ break;
+
+ case 70:
+#line 413 "dfgparser.y"
+ { yyval.bool = FALSE; }
+ break;
+
+ case 73:
+#line 420 "dfgparser.y"
+ { yyval.list = list_Nil(); }
+ break;
+
+ case 74:
+#line 422 "dfgparser.y"
+ { LIST pair;
+ if (yyvsp[-3].term == NULL) { /* No term */
+ if (yyvsp[-2].string != NULL)
+ string_StringFree(yyvsp[-2].string);
+ yyval.list = yyvsp[-6].list;
+ } else {
+ pair = list_PairCreate(yyvsp[-2].string, yyvsp[-3].term);
+ yyval.list = list_Cons(pair, yyvsp[-6].list);
+ }
+ dfg_VarCheck();
+ }
+ break;
+
+ case 75:
+#line 435 "dfgparser.y"
+ { yyval.string = NULL; }
+ break;
+
+ case 76:
+#line 436 "dfgparser.y"
+ { yyval.string = yyvsp[0].string; }
+ break;
+
+ case 77:
+#line 439 "dfgparser.y"
+ { yyval.term = yyvsp[0].term; }
+ break;
+
+ case 78:
+#line 441 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : term_Create(fol_Not(),list_List(yyvsp[-1].term)); }
+ break;
+
+ case 79:
+#line 443 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : term_Create(yyvsp[-5].symbol, list_Cons(yyvsp[-3].term, list_List(yyvsp[-1].term))); }
+ break;
+
+ case 80:
+#line 445 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : term_Create(yyvsp[-3].symbol, yyvsp[-1].list); }
+ break;
+
+ case 81:
+#line 446 "dfgparser.y"
+ { dfg_VarStart(); }
+ break;
+
+ case 82:
+#line 447 "dfgparser.y"
+ { dfg_VarStop(); }
+ break;
+
+ case 83:
+#line 449 "dfgparser.y"
+ { dfg_VarBacktrack();
+ yyval.term = dfg_IGNORE ? NULL : dfg_CreateQuantifier(yyvsp[-9].symbol,yyvsp[-5].list,yyvsp[-1].term);
+ }
+ break;
+
+ case 84:
+#line 454 "dfgparser.y"
+ { yyval.term = NULL; }
+ break;
+
+ case 85:
+#line 455 "dfgparser.y"
+ { yyval.term = yyvsp[0].term; }
+ break;
+
+ case 86:
+#line 459 "dfgparser.y"
+ { yyval.list = dfg_IGNORE ? list_Nil() : list_List(yyvsp[0].term); }
+ break;
+
+ case 87:
+#line 461 "dfgparser.y"
+ { yyval.list = dfg_IGNORE ? yyvsp[-2].list : list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+ break;
+
+ case 88:
+#line 464 "dfgparser.y"
+ { yyval.symbol = fol_Equiv(); }
+ break;
+
+ case 89:
+#line 465 "dfgparser.y"
+ { yyval.symbol = fol_Implied(); }
+ break;
+
+ case 90:
+#line 466 "dfgparser.y"
+ { yyval.symbol = fol_Implies(); }
+ break;
+
+ case 91:
+#line 469 "dfgparser.y"
+ { yyval.symbol = fol_And(); }
+ break;
+
+ case 92:
+#line 470 "dfgparser.y"
+ { yyval.symbol = fol_Or(); }
+ break;
+
+ case 93:
+#line 473 "dfgparser.y"
+ { yyval.symbol = fol_Exist(); }
+ break;
+
+ case 94:
+#line 474 "dfgparser.y"
+ { yyval.symbol = fol_All(); }
+ break;
+
+ case 95:
+#line 477 "dfgparser.y"
+ { if (dfg_IGNORE) {
+ string_StringFree(yyvsp[0].string);
+ yyval.string = NULL;
+ } else
+ yyval.string = yyvsp[0].string;
+ }
+ break;
+
+ case 96:
+#line 484 "dfgparser.y"
+ { yyval.string = dfg_IGNORE ? NULL : string_IntToString(yyvsp[0].number); }
+ break;
+
+ case 97:
+#line 486 "dfgparser.y"
+ { yyval.string = dfg_IGNORE ? NULL : string_StringCopy("set_flag"); }
+ break;
+
+ case 98:
+#line 488 "dfgparser.y"
+ { yyval.string = dfg_IGNORE ? NULL : string_StringCopy("set_DomPred"); }
+ break;
+
+ case 99:
+#line 490 "dfgparser.y"
+ { yyval.string = dfg_IGNORE ? NULL : string_StringCopy("set_precedence"); }
+ break;
+
+ case 100:
+#line 494 "dfgparser.y"
+ { yyval.list = dfg_IGNORE ? list_Nil() : list_List(yyvsp[0].term); }
+ break;
+
+ case 101:
+#line 496 "dfgparser.y"
+ { yyval.list = dfg_IGNORE ? yyvsp[-2].list : list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+ break;
+
+ case 102:
+#line 500 "dfgparser.y"
+ { if (!dfg_IGNORE) {
+ SYMBOL s = dfg_Symbol(yyvsp[0].string,0);
+ if (!symbol_IsVariable(s)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: Symbol is not a variable.\n",dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ yyval.term = term_Create(s, list_Nil());
+ }
+ }
+ break;
+
+ case 103:
+#line 511 "dfgparser.y"
+ { if (!dfg_IGNORE) {
+ SYMBOL p, v;
+ p = dfg_Symbol(yyvsp[-3].string, 1);
+ if (!symbol_IsPredicate(p)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: Symbol is not a predicate.\n",dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ v = dfg_Symbol(yyvsp[-1].string, 0);
+ if (!symbol_IsVariable(v)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: Symbol is not a variable.\n",dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ yyval.term = term_Create(p, list_List(term_Create(v,list_Nil())));
+ }
+ }
+ break;
+
+ case 106:
+#line 541 "dfgparser.y"
+ { list_NReverse(yyvsp[-2].list);
+ if (yyvsp[-7].bool) /* Axioms */
+ dfg_AXCLAUSES = list_Nconc(dfg_AXCLAUSES, yyvsp[-2].list);
+ else
+ dfg_CONCLAUSES = list_Nconc(dfg_CONCLAUSES, yyvsp[-2].list);
+ }
+ break;
+
+ case 107:
+#line 548 "dfgparser.y"
+ { stack_Push((POINTER)dfg_IGNORE); dfg_IGNORE = TRUE; }
+ break;
+
+ case 108:
+#line 551 "dfgparser.y"
+ { dfg_IGNORE = (BOOL)stack_PopResult(); }
+ break;
+
+ case 109:
+#line 554 "dfgparser.y"
+ { yyval.list = list_Nil(); }
+ break;
+
+ case 110:
+#line 556 "dfgparser.y"
+ { LIST pair;
+ if (yyvsp[-3].term == NULL) { /* No clause */
+ if (yyvsp[-2].string != NULL)
+ string_StringFree(yyvsp[-2].string);
+ yyval.list = yyvsp[-6].list;
+ } else {
+ pair = list_PairCreate(yyvsp[-2].string, yyvsp[-3].term);
+ yyval.list = list_Cons(pair, yyvsp[-6].list);
+ }
+ dfg_VarCheck();
+ }
+ break;
+
+ case 111:
+#line 569 "dfgparser.y"
+ { yyval.term = NULL; }
+ break;
+
+ case 112:
+#line 570 "dfgparser.y"
+ { yyval.term = yyvsp[0].term; }
+ break;
+
+ case 113:
+#line 573 "dfgparser.y"
+ { yyval.term = yyvsp[0].term; }
+ break;
+
+ case 114:
+#line 574 "dfgparser.y"
+ { dfg_VarStart(); }
+ break;
+
+ case 115:
+#line 575 "dfgparser.y"
+ { dfg_VarStop(); }
+ break;
+
+ case 116:
+#line 577 "dfgparser.y"
+ { dfg_VarBacktrack();
+ yyval.term = dfg_IGNORE ? NULL : dfg_CreateQuantifier(fol_All(),yyvsp[-5].list,yyvsp[-1].term);
+ }
+ break;
+
+ case 117:
+#line 583 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : term_Create(fol_Or(), yyvsp[-1].list); }
+ break;
+
+ case 118:
+#line 587 "dfgparser.y"
+ { yyval.list = dfg_IGNORE ? list_Nil() : list_List(yyvsp[0].term); }
+ break;
+
+ case 119:
+#line 589 "dfgparser.y"
+ { yyval.list = dfg_IGNORE ? yyvsp[-2].list : list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+ break;
+
+ case 120:
+#line 592 "dfgparser.y"
+ { yyval.term = yyvsp[0].term; }
+ break;
+
+ case 121:
+#line 594 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? yyvsp[-1].term : term_Create(fol_Not(),list_List(yyvsp[-1].term)); }
+ break;
+
+ case 122:
+#line 597 "dfgparser.y"
+ { yyval.list = list_List(yyvsp[0].term); }
+ break;
+
+ case 123:
+#line 598 "dfgparser.y"
+ { yyval.list = list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+ break;
+
+ case 124:
+#line 602 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : dfg_AtomCreate(yyvsp[0].string,list_Nil()); }
+ break;
+
+ case 125:
+#line 604 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : term_Create(fol_True(),list_Nil()); }
+ break;
+
+ case 126:
+#line 606 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : term_Create(fol_False(),list_Nil()); }
+ break;
+
+ case 127:
+#line 608 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : term_Create(fol_Equality(),list_Cons(yyvsp[-3].term,list_List(yyvsp[-1].term))); }
+ break;
+
+ case 128:
+#line 610 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : dfg_AtomCreate(yyvsp[-3].string, yyvsp[-1].list); }
+ break;
+
+ case 136:
+#line 636 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : dfg_TermCreate(yyvsp[0].string,list_Nil()); }
+ break;
+
+ case 137:
+#line 638 "dfgparser.y"
+ { yyval.term = dfg_IGNORE ? NULL : dfg_TermCreate(yyvsp[-3].string, yyvsp[-1].list); }
+ break;
+
+ case 138:
+#line 642 "dfgparser.y"
+ { yyval.list = dfg_IGNORE ? list_Nil() : list_List(yyvsp[0].term); }
+ break;
+
+ case 139:
+#line 644 "dfgparser.y"
+ { yyval.list = dfg_IGNORE ? yyvsp[-2].list : list_Nconc(yyvsp[-2].list,list_List(yyvsp[0].term)); }
+ break;
+
+ case 142:
+#line 656 "dfgparser.y"
+ { if (!string_Equal(yyvsp[-2].string,"SPASS")) {
+ stack_Push((POINTER)dfg_IGNORE);
+ dfg_IGNORE = TRUE;
+ }
+ }
+ break;
+
+ case 143:
+#line 663 "dfgparser.y"
+ { if (!string_Equal(yyvsp[-6].string,"SPASS"))
+ dfg_IGNORE = (BOOL)stack_PopResult();
+ string_StringFree(yyvsp[-6].string);
+ }
+ break;
+
+ case 145:
+#line 672 "dfgparser.y"
+ { if (!dfg_IGNORE && yyvsp[-11].string!=NULL && yyvsp[-9].term!=NULL && !list_Empty(yyvsp[-4].list)) {
+ LIST tupel;
+ RULE Rule = clause_GetOriginFromString(yyvsp[-7].string);
+ string_StringFree(yyvsp[-7].string);
+ /* Build a tuple (label,clause,parentlist,split level,origin) */
+ tupel = list_Cons((POINTER)yyvsp[-2].number,list_List((POINTER)Rule));
+ tupel = list_Cons(yyvsp[-11].string,list_Cons(yyvsp[-9].term,list_Cons(yyvsp[-4].list,tupel)));
+ dfg_PROOFLIST = list_Cons(tupel, dfg_PROOFLIST);
+ } else {
+ /* ignore DNF clauses and clauses with incomplete data */
+ if (yyvsp[-11].string != NULL) string_StringFree(yyvsp[-11].string);
+ if (yyvsp[-9].term != NULL) term_Delete(yyvsp[-9].term);
+ if (yyvsp[-7].string != NULL) string_StringFree(yyvsp[-7].string);
+ dfg_DeleteStringList(yyvsp[-4].list);
+ }
+ dfg_VarCheck();
+ }
+ break;
+
+ case 146:
+#line 692 "dfgparser.y"
+ { yyval.list = (dfg_IGNORE||yyvsp[0].string==NULL) ? list_Nil() : list_List(yyvsp[0].string); }
+ break;
+
+ case 147:
+#line 694 "dfgparser.y"
+ { yyval.list = (dfg_IGNORE||yyvsp[0].string==NULL) ? yyvsp[-2].list : list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].string)); }
+ break;
+
+ case 148:
+#line 698 "dfgparser.y"
+ { yyval.number = 0; }
+ break;
+
+ case 149:
+#line 699 "dfgparser.y"
+ { yyval.number = yyvsp[-1].number; }
+ break;
+
+ case 150:
+#line 703 "dfgparser.y"
+ { if (!dfg_IGNORE && yyvsp[-2].string!=NULL && yyvsp[0].string!=NULL && string_Equal(yyvsp[-2].string,"splitlevel"))
+ string_StringToInt(yyvsp[0].string, TRUE, &yyval.number);
+ else
+ yyval.number = 0;
+ if (yyvsp[-2].string != NULL) string_StringFree(yyvsp[-2].string);
+ if (yyvsp[0].string != NULL) string_StringFree(yyvsp[0].string);
+ }
+ break;
+
+ case 151:
+#line 711 "dfgparser.y"
+ { if (!dfg_IGNORE && yyvsp[-2].string!=NULL && yyvsp[0].string!=NULL && string_Equal(yyvsp[-2].string,"splitlevel"))
+ string_StringToInt(yyvsp[0].string, TRUE, &yyval.number);
+ else
+ yyval.number = yyvsp[-4].number;
+ if (yyvsp[-2].string != NULL) string_StringFree(yyvsp[-2].string);
+ if (yyvsp[0].string != NULL) string_StringFree(yyvsp[0].string);
+ }
+ break;
+
+ case 152:
+#line 721 "dfgparser.y"
+ { stack_Push((POINTER) dfg_IGNORE); dfg_IGNORE = TRUE; }
+ break;
+
+ case 153:
+#line 723 "dfgparser.y"
+ { dfg_IGNORE = (BOOL) stack_PopResult();
+ if (yyvsp[0].bool) {
+ if (yyvsp[-2].string != NULL) string_StringFree(yyvsp[-2].string);
+ yyval.string = NULL;
+ } else
+ yyval.string = yyvsp[-2].string;
+ }
+ break;
+
+ case 154:
+#line 732 "dfgparser.y"
+ { yyval.string = yyvsp[0].string; }
+ break;
+
+ case 155:
+#line 733 "dfgparser.y"
+ { yyval.string = NULL; }
+ break;
+
+ case 156:
+#line 734 "dfgparser.y"
+ { yyval.string = NULL; }
+ break;
+
+ case 157:
+#line 735 "dfgparser.y"
+ { yyval.string = NULL; }
+ break;
+
+ case 158:
+#line 736 "dfgparser.y"
+ { yyval.string = NULL; }
+ break;
+
+ case 159:
+#line 737 "dfgparser.y"
+ { yyval.string = NULL; }
+ break;
+
+ case 160:
+#line 738 "dfgparser.y"
+ { yyval.string = NULL; }
+ break;
+
+ case 161:
+#line 739 "dfgparser.y"
+ { yyval.string = NULL; }
+ break;
+
+ case 162:
+#line 740 "dfgparser.y"
+ { yyval.string = NULL; }
+ break;
+
+ case 163:
+#line 743 "dfgparser.y"
+ { yyval.bool = FALSE; }
+ break;
+
+ case 164:
+#line 744 "dfgparser.y"
+ { yyval.bool = TRUE; }
+ break;
+
+ case 165:
+#line 745 "dfgparser.y"
+ { yyval.bool = TRUE; }
+ break;
+
+ case 166:
+#line 748 "dfgparser.y"
+ { yyval.term = yyvsp[0].term; }
+ break;
+
+ case 167:
+#line 749 "dfgparser.y"
+ { yyval.term = NULL; }
+ break;
+
+ case 170:
+#line 761 "dfgparser.y"
+ { dfg_VarStart(); }
+ break;
+
+ case 171:
+#line 762 "dfgparser.y"
+ {
+ dfg_VarStop();
+ dfg_VarBacktrack();
+ dfg_VarCheck(); }
+ break;
+
+ case 173:
+#line 769 "dfgparser.y"
+ { dfg_TERMLIST = list_Nconc(dfg_TERMLIST, list_List(yyvsp[-1].term)); }
+ break;
+
+ case 177:
+#line 781 "dfgparser.y"
+ { if (string_Equal(yyvsp[0].string,"SPASS"))
+ dfg_IGNORETEXT = FALSE;
+ string_StringFree(yyvsp[0].string);
+ }
+ break;
+
+ case 178:
+#line 786 "dfgparser.y"
+ { dfg_IGNORETEXT = TRUE; }
+ break;
+
+ case 179:
+#line 789 "dfgparser.y"
+ { /* no SPASS flags */
+ string_StringFree(yyvsp[0].string);
+ }
+ break;
+
+ case 184:
+#line 801 "dfgparser.y"
+ { SYMBOL s;
+ for ( ; !list_Empty(yyvsp[-1].list); yyvsp[-1].list = list_Pop(yyvsp[-1].list)) {
+ s = symbol_Lookup(list_Car(yyvsp[-1].list));
+ if (s == 0) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Undefined symbol %s", list_Car(yyvsp[-1].list));
+ misc_UserErrorReport(" in DomPred list.\n");
+ misc_FinishUserErrorReport();
+ }
+ if (!symbol_IsPredicate(s)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Symbol %s isn't a predicate", list_Car(yyvsp[-1].list));
+ misc_UserErrorReport(" in DomPred list.\n");
+ misc_FinishUserErrorReport();
+ }
+ string_StringFree(list_Car(yyvsp[-1].list));
+ symbol_AddProperty(s, DOMPRED);
+ }
+ }
+ break;
+
+ case 185:
+#line 821 "dfgparser.y"
+ { int flag = flag_Id(yyvsp[-3].string);
+ if (flag == -1) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Found unknown flag %s", yyvsp[-3].string);
+ misc_FinishUserErrorReport();
+ }
+ string_StringFree(yyvsp[-3].string);
+ flag_SetFlagValue(dfg_FLAGS, flag, yyvsp[-1].number);
+ }
+ break;
+
+ case 188:
+#line 837 "dfgparser.y"
+ { SYMBOL s = symbol_Lookup(yyvsp[0].string);
+ if (s == 0) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Undefined symbol %s ", yyvsp[0].string);
+ misc_UserErrorReport(" in precedence list.\n");
+ misc_FinishUserErrorReport();
+ }
+ string_StringFree(yyvsp[0].string);
+ symbol_SetIncreasedOrdering(dfg_PRECEDENCE, s);
+ dfg_USERPRECEDENCE = list_Cons((POINTER)s, dfg_USERPRECEDENCE);
+ }
+ break;
+
+ case 189:
+#line 849 "dfgparser.y"
+ { SYMBOL s = symbol_Lookup(yyvsp[-4].string);
+ if (s == 0) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Undefined symbol %s", yyvsp[-4].string);
+ misc_UserErrorReport("in precedence list.\n");
+ misc_FinishUserErrorReport();
+ }
+ string_StringFree(yyvsp[-4].string);
+ symbol_SetIncreasedOrdering(dfg_PRECEDENCE, s);
+ dfg_USERPRECEDENCE = list_Cons((POINTER)s, dfg_USERPRECEDENCE);
+ symbol_SetWeight(s, yyvsp[-2].number);
+ if (yyvsp[-1].property != 0)
+ symbol_AddProperty(s, yyvsp[-1].property);
+ }
+ break;
+
+ case 190:
+#line 865 "dfgparser.y"
+ { yyval.property = 0; /* left */ }
+ break;
+
+ case 191:
+#line 867 "dfgparser.y"
+ { if (yyvsp[0].string[1] != '\0' ||
+ (yyvsp[0].string[0]!='l' && yyvsp[0].string[0]!='m' && yyvsp[0].string[0]!='r')) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Invalid symbol status %s", yyvsp[0].string);
+ misc_UserErrorReport(" in precedence list.");
+ misc_FinishUserErrorReport();
+ }
+ switch (yyvsp[0].string[0]) {
+ case 'm': yyval.property = ORDMUL; break;
+ case 'r': yyval.property = ORDRIGHT; break;
+ default: yyval.property = 0;
+ }
+ string_StringFree(yyvsp[0].string);
+ }
+ break;
+
+ case 194:
+#line 888 "dfgparser.y"
+ { dfg_DeleteStringList(yyvsp[-2].list); }
+ break;
+
+ case 195:
+#line 891 "dfgparser.y"
+ { yyval.list = list_List(yyvsp[0].string); }
+ break;
+
+ case 196:
+#line 892 "dfgparser.y"
+ { yyval.list = list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].string)); }
+ break;
+
+
+ }
+
+/* Line 1016 of /opt/gnu//share/bison/yacc.c. */
+#line 2471 "dfgparser.c"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+#if YYDEBUG
+ if (yydebug)
+ {
+ short *yyssp1 = yyss - 1;
+ YYFPRINTF (stderr, "state stack now");
+ while (yyssp1 != yyssp)
+ YYFPRINTF (stderr, " %d", *++yyssp1);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ char *yymsg;
+ int yyx, yycount;
+
+ yycount = 0;
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+ yysize += yystrlen ("parse error, unexpected ") + 1;
+ yysize += yystrlen (yytname[yytype]);
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yycount = 0;
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *));
+ yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ const char *yyq = ! yycount ? ", expecting " : " or ";
+ yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yycount++;
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("parse error");
+ }
+ goto yyerrlab1;
+
+
+/*----------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action. |
+`----------------------------------------------------*/
+yyerrlab1:
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ {
+ /* Pop the error token. */
+ YYPOPSTACK;
+ /* Pop the rest of the stack. */
+ while (yyssp > yyss)
+ {
+ YYDPRINTF ((stderr, "Error: popping "));
+ YYDSYMPRINT ((stderr,
+ yystos[*yyssp],
+ *yyvsp));
+ YYDPRINTF ((stderr, "\n"));
+ yydestruct (yystos[*yyssp], *yyvsp);
+ YYPOPSTACK;
+ }
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
+ yychar, yytname[yychar1]));
+ yydestruct (yychar1, yylval);
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ YYDPRINTF ((stderr, "Error: popping "));
+ YYDSYMPRINT ((stderr,
+ yystos[*yyssp], *yyvsp));
+ YYDPRINTF ((stderr, "\n"));
+
+ yydestruct (yystos[yystate], *yyvsp);
+ yyvsp--;
+ yystate = *--yyssp;
+
+
+#if YYDEBUG
+ if (yydebug)
+ {
+ short *yyssp1 = yyss - 1;
+ YYFPRINTF (stderr, "Error: state stack now");
+ while (yyssp1 != yyssp)
+ YYFPRINTF (stderr, " %d", *++yyssp1);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+#line 895 "dfgparser.y"
+
+
+void yyerror(const char *s)
+{
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %i: %s\n", dfg_LINENUMBER, s);
+ misc_FinishUserErrorReport();
+}
+
+static void dfg_Init(FILE* Input, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: The input file stream for the parser, a flag store and
+ a precedence.
+ RETURNS: Nothing.
+ EFFECT: The parser and scanner are initialized.
+ The parser will use the flag store and the precedence
+ to memorize the settings from the input file.
+***************************************************************/
+{
+ extern FILE* dfg_in; /* declared in dfgscanner */
+
+ dfg_in = Input;
+ dfg_LINENUMBER = 1;
+ dfg_IGNORETEXT = TRUE;
+ dfg_AXIOMLIST = list_Nil();
+ dfg_CONJECLIST = list_Nil();
+ dfg_SORTDECLLIST = list_Nil();
+ dfg_USERPRECEDENCE = list_Nil();
+ dfg_AXCLAUSES = list_Nil();
+ dfg_CONCLAUSES = list_Nil();
+ dfg_PROOFLIST = list_Nil();
+ dfg_TERMLIST = list_Nil();
+ dfg_SYMBOLLIST = list_Nil();
+ dfg_VARLIST = list_Nil();
+ dfg_VARDECL = FALSE;
+ dfg_IGNORE = FALSE;
+ dfg_FLAGS = Flags;
+ dfg_PRECEDENCE = Precedence;
+ dfg_DESC.name = (char*) NULL;
+ dfg_DESC.author = (char*) NULL;
+ dfg_DESC.version = (char*) NULL;
+ dfg_DESC.logic = (char*) NULL;
+ dfg_DESC.status = DFG_UNKNOWNSTATE;
+ dfg_DESC.description = (char*) NULL;
+ dfg_DESC.date = (char*) NULL;
+}
+
+
+void dfg_Free(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECT: Frees memory used by the problem description.
+***************************************************************/
+{
+ if (dfg_DESC.name != NULL)
+ string_StringFree(dfg_DESC.name);
+ if (dfg_DESC.author != NULL)
+ string_StringFree(dfg_DESC.author);
+ if (dfg_DESC.version != NULL)
+ string_StringFree(dfg_DESC.version);
+ if (dfg_DESC.logic != NULL)
+ string_StringFree(dfg_DESC.logic);
+ if (dfg_DESC.description != NULL)
+ string_StringFree(dfg_DESC.description);
+ if(dfg_DESC.date != NULL)
+ string_StringFree(dfg_DESC.date);
+}
+
+const char* dfg_ProblemName(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The problem's name from the description section.
+***************************************************************/
+{
+ return dfg_DESC.name;
+}
+
+const char* dfg_ProblemAuthor(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The problem's author from the description section.
+***************************************************************/
+{
+ return dfg_DESC.author;
+}
+
+const char* dfg_ProblemVersion(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The problem's version from the description section.
+***************************************************************/
+{
+ return dfg_DESC.version;
+}
+
+const char* dfg_ProblemLogic(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The problem's logic from the description section.
+***************************************************************/
+{
+ return dfg_DESC.logic;
+}
+
+DFG_STATE dfg_ProblemStatus(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The problem's status from the description section.
+***************************************************************/
+{
+ return dfg_DESC.status;
+}
+
+const char* dfg_ProblemStatusString(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The string representation of the problem's status.
+***************************************************************/
+{
+ const char* result = "";
+
+ switch (dfg_DESC.status) {
+ case DFG_SATISFIABLE:
+ result = "satisfiable"; break;
+ case DFG_UNSATISFIABLE:
+ result = "unsatisfiable"; break;
+ case DFG_UNKNOWNSTATE:
+ result = "unknown"; break;
+ default:
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In dfg_ProblemStatusString: Invalid status.\n");
+ misc_FinishErrorReport();
+ }
+ return result;
+}
+
+const char* dfg_ProblemDescription(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The problem's description from the description section.
+***************************************************************/
+{
+ return dfg_DESC.description;
+}
+
+const char* dfg_ProblemDate(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The problem's date from the description section.
+***************************************************************/
+{
+ return dfg_DESC.date;
+}
+
+void dfg_FPrintDescription(FILE* File)
+/**************************************************************
+ INPUT: A file stream.
+ RETURNS: Nothing.
+ EFFECT: The description section from the input file
+ is printed to 'File'. You must call the parser first
+ before calling this function.
+***************************************************************/
+{
+ fputs("list_of_descriptions.\n name(", File);
+ if (dfg_DESC.name != NULL)
+ fputs(dfg_DESC.name, File);
+ else
+ fputs("{* *}", File);
+ fputs(").\n author(", File);
+ if (dfg_DESC.author != NULL)
+ fputs(dfg_DESC.author, File);
+ else
+ fputs("{* *}", File);
+ fputs(").\n", File);
+ if (dfg_DESC.version != NULL) {
+ fputs(" version(", File);
+ fputs(dfg_DESC.version, File);
+ fputs(").\n", File);
+ }
+ if (dfg_DESC.logic != NULL) {
+ fputs(" logic(", File);
+ fputs(dfg_DESC.logic, File);
+ fputs(").\n", File);
+ }
+ fputs(" status(", File);
+ fputs(dfg_ProblemStatusString(), File);
+ fputs(").\n description(", File);
+ if (dfg_DESC.description != NULL)
+ fputs(dfg_DESC.description, File);
+ else
+ fputs("{* *}", File);
+ fputs(").\n", File);
+ if (dfg_DESC.date != NULL) {
+ fputs(" date(", File);
+ fputs(dfg_DESC.date, File);
+ fputs(").\n", File);
+ }
+ fputs("end_of_list.", File);
+}
+
+
+LIST dfg_DFGParser(FILE* File, FLAGSTORE Flags, PRECEDENCE Precedence,
+ LIST* Axioms, LIST* Conjectures, LIST* SortDecl,
+ LIST* UserDefinedPrecedence)
+/**************************************************************
+ INPUT: The input file containing clauses or formulae in DFG syntax,
+ a flag store and a precedence used to memorize settings
+ from the file.
+ Axioms, Conjectures, SortDecl and UserDefinedPrecedence are
+ pointers to lists used as return values.
+ RETURNS: The list of clauses from File.
+ EFFECT: Reads formulae and clauses from the input file.
+ The axioms, conjectures, sort declarations and user-defined
+ precedences are appended to the respective lists, the lists
+ are not deleted!
+ All lists except the clause list contain pairs
+ (label, term), where <label> may be NULL, if no
+ label was specified for that term.
+ <UserDefinedPrecedence> contains symbols sorted by decreasing
+ precedence. This list will only be changed, if the precedence
+ is explicitly defined in the input file. This can be done
+ by the 'set_precedence' flag in the SPASS settings list in
+ the DFG input file.
+ CAUTION: The weight of the clauses is not correct and the literals
+ are not oriented!
+***************************************************************/
+{
+ LIST scan, tupel;
+ TERM clauseTerm;
+ NAT bottom;
+
+ dfg_Init(File, Flags, Precedence); /* Initialize the parser and scanner */
+ bottom = stack_Bottom();
+ dfg_parse(); /* Invoke the parser */
+#ifdef CHECK
+ if (!stack_Empty(bottom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In dfg_DFGParser: Stack not empty!\n");
+ misc_FinishErrorReport();
+ }
+#endif
+ dfg_SymCleanUp();
+
+ /* Remove clause labels and create clauses from the terms */
+ for (scan = dfg_AXCLAUSES; !list_Empty(scan); scan = list_Cdr(scan)) {
+ tupel = list_Car(scan);
+ clauseTerm = list_PairSecond(tupel);
+ list_Rplaca(scan, dfg_CreateClauseFromTerm(clauseTerm,TRUE, Flags, Precedence));
+ if (list_PairFirst(tupel) != NULL) /* Label is defined */
+ string_StringFree(list_PairFirst(tupel)); /* Delete the label */
+ list_PairFree(tupel);
+ }
+ /* Since dfg_CreateClauseFromTerm() returns NULL for trivial tautologies */
+ /* we now delete those NULL pointers from the clause list. */
+ dfg_AXCLAUSES = list_PointerDeleteElement(dfg_AXCLAUSES, NULL);
+ for (scan = dfg_CONCLAUSES; !list_Empty(scan); scan = list_Cdr(scan)) {
+ tupel = list_Car(scan);
+ clauseTerm = list_PairSecond(tupel);
+ list_Rplaca(scan, dfg_CreateClauseFromTerm(clauseTerm,FALSE, Flags, Precedence));
+ if (list_PairFirst(tupel) != NULL) /* Label is defined */
+ string_StringFree(list_PairFirst(tupel)); /* Delete the label */
+ list_PairFree(tupel);
+ }
+ /* Since dfg_CreateClauseFromTerm() returns NULL for trivial tautologies */
+ /* we now delete those NULL pointers from the clause list. */
+ dfg_CONCLAUSES = list_PointerDeleteElement(dfg_CONCLAUSES, NULL);
+
+ /* Delete the proof list */
+ dfg_DeleteProofList(dfg_PROOFLIST);
+
+ /* Delete the list_of_terms, since it'll be ignored */
+ term_DeleteTermList(dfg_TERMLIST);
+
+ scan = list_Nconc(dfg_AXCLAUSES, dfg_CONCLAUSES);
+
+ *Axioms = list_Nconc(*Axioms, dfg_AXIOMLIST);
+ *Conjectures = list_Nconc(*Conjectures, dfg_CONJECLIST);
+ *SortDecl = list_Nconc(*SortDecl, dfg_SORTDECLLIST);
+ list_NReverse(dfg_USERPRECEDENCE);
+ *UserDefinedPrecedence = list_Nconc(*UserDefinedPrecedence, dfg_USERPRECEDENCE);
+
+ return scan;
+}
+
+
+LIST dfg_ProofParser(FILE* File, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: The input file containing clauses in DFG syntax,
+ a flag store and a precedence used to memorize settings
+ from the file.
+ RETURNS: A list of tuples (label,clause,justificationlist,splitlevel,origin)
+ representing a proof.
+ EFFECT: Reads inputs clauses with labels and the proof lists
+ from the input file.
+ The elements of the list are lists with five items.
+ 1. the label (a string) of a clause,
+ 2. the clause in TERM format,
+ 3. the list of justification labels (strings, too),
+ 4. the split level of the clause,
+ 5. the origin of the clause (RULE struct from clause.h).
+ Note that the justification list is empty for input
+ clauses.
+***************************************************************/
+{
+ LIST scan, tupel;
+ TERM term;
+ NAT bottom;
+
+ dfg_Init(File, Flags, Precedence); /* Initialize the parser and scanner */
+ bottom = stack_Bottom();
+ dfg_parse(); /* Invoke the parser */
+#ifdef CHECK
+ if (!stack_Empty(bottom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In dfg_ProofParser: Stack not empty!\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ dfg_SymCleanUp();
+
+ /* Build the union of axiom and conjecture clauses */
+ dfg_AXCLAUSES = list_Nconc(dfg_AXCLAUSES, dfg_CONCLAUSES);
+ dfg_CONCLAUSES = list_Nil();
+ for (scan = dfg_AXCLAUSES; !list_Empty(scan); scan = list_Cdr(scan)) {
+ tupel = list_Car(scan);
+ term = list_PairSecond(tupel);
+ if (list_PairFirst(tupel) == NULL) {
+ /* Ignore input clauses without label */
+ term_Delete(term);
+ list_PairFree(tupel);
+ list_Rplaca(scan, NULL);
+ } else
+ /* Expand the pair to a tuple */
+ /* (label,clause,justificationlist, split level, origin) */
+ /* For input clauses the justificationlist is empty. */
+ /* Input clauses have split level 0. */
+ list_Rplacd(tupel, list_Cons(term,list_Cons(list_Nil(),list_Cons(0, list_List((POINTER)INPUT)))));
+ }
+ /* Now delete the list items without labels */
+ dfg_AXCLAUSES = list_PointerDeleteElement(dfg_AXCLAUSES, NULL);
+
+ /* Delete the formula lists */
+ dfg_DeleteFormulaPairList(dfg_AXIOMLIST);
+ dfg_DeleteFormulaPairList(dfg_CONJECLIST);
+ /* Delete the list of sort declarations */
+ dfg_DeleteFormulaPairList(dfg_SORTDECLLIST);
+ /* Delete the list_of_terms, since it'll be ignored */
+ term_DeleteTermList(dfg_TERMLIST);
+
+ /* Finally append the proof list to the list of input clauses with labels */
+ dfg_PROOFLIST = list_NReverse(dfg_PROOFLIST);
+ dfg_AXCLAUSES = list_Nconc(dfg_AXCLAUSES, dfg_PROOFLIST);
+
+ return dfg_AXCLAUSES;
+}
+
+
+LIST dfg_TermParser(FILE* File, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: The input file containing a list of terms in DFG syntax,
+ a flag store and a precedence used to memorize settings
+ from the file.
+ RETURNS: The list of terms from <File>.
+ EFFECT: Reads terms from the list_of_terms from the input file.
+***************************************************************/
+{
+ NAT bottom;
+
+ dfg_Init(File, Flags, Precedence); /* Initialize the parser and scanner */
+ bottom = stack_Bottom();
+ dfg_parse(); /* Invoke the parser */
+#ifdef CHECK
+ if (!stack_Empty(bottom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In dfg_TermParser: Stack not empty!\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ dfg_SymCleanUp();
+
+ /* Delete the clause lists */
+ dfg_DeleteFormulaPairList(dfg_AXCLAUSES);
+ dfg_DeleteFormulaPairList(dfg_CONCLAUSES);
+ /* Delete the formula lists */
+ dfg_DeleteFormulaPairList(dfg_AXIOMLIST);
+ dfg_DeleteFormulaPairList(dfg_CONJECLIST);
+ /* Delete the proof list */
+ dfg_DeleteProofList(dfg_PROOFLIST);
+ /* Delete the list of sort declarations */
+ dfg_DeleteFormulaPairList(dfg_SORTDECLLIST);
+
+ return dfg_TERMLIST;
+}
+
+
+void dfg_DeleteFormulaPairList(LIST FormulaPairs)
+/**************************************************************
+ INPUT: A list of pairs (label, formula).
+ RETURNS: Nothing.
+ EFFECT: The list and the pairs with their strings and terms
+ are completely deleted.
+***************************************************************/
+{
+ LIST pair;
+
+ for ( ; !list_Empty(FormulaPairs); FormulaPairs = list_Pop(FormulaPairs)) {
+ pair = list_Car(FormulaPairs); /* (label, term) */
+ term_Delete(list_PairSecond(pair));
+ if (list_PairFirst(pair) != NULL)
+ string_StringFree(list_PairFirst(pair)); /* Free the label */
+ list_PairFree(pair);
+ }
+}
+
+void dfg_StripLabelsFromList(LIST FormulaPairs)
+/**************************************************************
+ INPUT: A list of pairs (label, formula).
+ RETURNS: Nothing.
+ EFFECT: The pairs are replaced by the respective formula
+ and the pairs with their label strings are deleted.
+***************************************************************/
+{
+ LIST pair, scan;
+
+ for (scan = FormulaPairs; !list_Empty(scan); scan = list_Cdr(scan)) {
+ pair = list_Car(scan); /* (label, term) */
+ list_Rplaca(scan, list_PairSecond(pair));
+ if (list_PairFirst(pair) != NULL)
+ string_StringFree(list_PairFirst(pair)); /* Free the label */
+ list_PairFree(pair);
+ }
+}
+
+void dfg_DeleteProofList(LIST Proof)
+/**************************************************************
+ INPUT: A list of tuples (label, term, justificationlist, split level).
+ RETURNS: Nothing.
+ EFFECT: All memory used by the proof list is freed.
+ The labels must NOT be NULL entries!
+***************************************************************/
+{
+ /* Delete the proof list */
+ for ( ; !list_Empty(Proof); Proof = list_Pop(Proof)) {
+ LIST tupel = list_Car(Proof);
+ string_StringFree(list_First(tupel));
+ term_Delete(list_Second(tupel));
+ dfg_DeleteStringList(list_Third(tupel));
+ list_Delete(tupel);
+ }
+}
+
+/**************************************************************/
+/* Static Functions */
+/**************************************************************/
+
+static void dfg_SymbolDecl(int SymbolType, char* Name, int Arity)
+/**************************************************************
+ INPUT: The type of a symbol, the name, and the arity.
+ RETURNS: Nothing.
+ EFFECT: This function handles the declaration of symbols.
+ If <Arity> is -2, it means that the arity of the symbol
+ was not specified, if it is -1 the symbol is declared
+ with arbitrary arity. User defined symbols with arbitrary
+ arity are not allowed.
+ The <Name> is deleted.
+***************************************************************/
+{
+ NAT arity, length;
+ SYMBOL symbol;
+
+ switch (Arity) {
+ case -2: /* not specified */
+ arity = 0;
+ break;
+ case -1:
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %u: symbols with arbitrary arity are not allowed.\n",
+ dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ default:
+ arity = Arity;
+}
+
+ /* Pay attention to the maximum symbol name length */
+ length = strlen(Name);
+ if (length >= symbol__SYMBOLMAXLEN)
+ Name[symbol__SYMBOLMAXLEN-1] = '\0';
+
+ /* Check if this symbol was declared earlier */
+ symbol = symbol_Lookup(Name);
+ if (symbol != 0) {
+ /* Symbol was declared before */
+ /* Check if the old and new symbol type are equal */
+ if ((SymbolType == DFG_FUNC && !symbol_IsFunction(symbol)) ||
+ (SymbolType == DFG_PRDICAT && !symbol_IsPredicate(symbol)) ||
+ ((SymbolType == DFG_OPERAT || SymbolType == DFG_QUANTIF) &&
+ !symbol_IsJunctor(symbol))) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %u: symbol %s was already declared as ",
+ dfg_LINENUMBER, Name);
+ switch (symbol_Type(symbol)) {
+ case symbol_CONSTANT:
+ case symbol_FUNCTION:
+ misc_UserErrorReport("function.\n"); break;
+ case symbol_PREDICATE:
+ misc_UserErrorReport("predicate.\n"); break;
+ case symbol_JUNCTOR:
+ misc_UserErrorReport("junctor.\n"); break;
+ default:
+ misc_UserErrorReport("unknown type.\n");
+ }
+ misc_FinishUserErrorReport();
+ }
+ /* Now check the old and new arity if specified */
+ if (Arity != -2 && Arity != symbol_Arity(symbol)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %u: symbol %s was already declared with arity %d\n",
+ dfg_LINENUMBER, Name, symbol_Arity(symbol));
+ misc_FinishUserErrorReport();
+ }
+ } else {
+ /* Symbol was not declared before */
+ switch (SymbolType) {
+ case DFG_FUNC:
+ symbol = symbol_CreateFunction(Name, arity, symbol_STATLEX,dfg_PRECEDENCE);
+ break;
+ case DFG_PRDICAT:
+ symbol = symbol_CreatePredicate(Name, arity,symbol_STATLEX,dfg_PRECEDENCE);
+ break;
+ default:
+ symbol = symbol_CreateJunctor(Name, arity, symbol_STATLEX, dfg_PRECEDENCE);
+ }
+ if (Arity == -2)
+ /* Arity wasn't specified so check the arity for each occurrence */
+ dfg_SymAdd(symbol);
+ }
+
+ if (length >= symbol__SYMBOLMAXLEN) {
+ /* To avoid a memory error restore the old string length */
+ Name[symbol__SYMBOLMAXLEN-1] = ' '; /* Something != '\0' */
+ }
+ string_StringFree(Name); /* Name was copied */
+}
+
+
+static SYMBOL dfg_Symbol(char* Name, NAT Arity)
+/**************************************************************
+ INPUT: The name of a symbol and the actual arity of the symbol.
+ RETURNS: The corresponding SYMBOL.
+ EFFECT: This function checks if the <Name> was declared as
+ symbol or variable. If not, an error message is printed
+ to stderr.
+ The <Name> is deleted.
+***************************************************************/
+{
+ SYMBOL symbol;
+ char old;
+ NAT length;
+
+ old = ' '; /* Just to avoid a compiler warning */
+ /* Pay attention to the maximum symbol name length */
+ length = strlen(Name);
+ if (length >= symbol__SYMBOLMAXLEN) {
+ old = Name[symbol__SYMBOLMAXLEN-1];
+ Name[symbol__SYMBOLMAXLEN-1] = '\0';
+ }
+
+ symbol = symbol_Lookup(Name);
+ if (length >= symbol__SYMBOLMAXLEN) {
+ /* To avoid a memory error restore the old string */
+ Name[symbol__SYMBOLMAXLEN-1] = old;
+ }
+ if (symbol != 0) {
+ string_StringFree(Name);
+ dfg_SymCheck(symbol, Arity); /* Check the arity */
+ } else {
+ /* Variable */
+ if (Arity > 0) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: Undefined symbol %s.\n",dfg_LINENUMBER,Name);
+ misc_FinishUserErrorReport();
+ }
+ symbol = dfg_VarLookup(Name);
+ }
+ return symbol;
+}
+
+
+TERM dfg_CreateQuantifier(SYMBOL Symbol, LIST VarTermList, TERM Term)
+/**************************************************************
+ INPUT: A quantifier symbol, a list possibly containing sorts,
+ and a term.
+ RETURNS: The created quantifier term..
+***************************************************************/
+{
+ LIST varlist, sortlist, scan;
+ TERM helpterm;
+
+ /* First collect the variable symbols in varlist and the sorts in sortlist */
+ varlist = sortlist = list_Nil();
+ for ( ; !list_Empty(VarTermList); VarTermList = list_Pop(VarTermList)) {
+ helpterm = list_Car(VarTermList);
+ if (term_IsVariable(helpterm)) {
+ varlist = list_Nconc(varlist, list_List((POINTER)term_TopSymbol(helpterm)));
+ term_Delete(helpterm);
+ } else {
+ SYMBOL var = term_TopSymbol(term_FirstArgument(helpterm));
+ varlist = list_Nconc(varlist, list_List((POINTER)var));
+ sortlist = list_Nconc(sortlist, list_List(helpterm));
+ }
+ }
+
+ varlist = list_PointerDeleteDuplicates(varlist);
+ /* Now create terms from the variables */
+ for (scan = varlist; !list_Empty(scan); scan = list_Cdr(scan))
+ list_Rplaca(scan, term_Create((SYMBOL)list_Car(scan), list_Nil()));
+
+ if (!list_Empty(sortlist)) {
+ if (symbol_Equal(fol_All(), Symbol)) {
+ /* The conjunction of all sortterms implies the Term */
+ if (symbol_Equal(fol_Or(), term_TopSymbol(Term))) {
+ /* Special treatment if <Term> is a term with "or" like */
+ /* in clauses: add all sort terms negated to the args */
+ /* of the "or" */
+ for (scan = sortlist; !list_Empty(scan); scan = list_Cdr(scan))
+ /* Negate the sort terms */
+ list_Rplaca(scan, term_Create(fol_Not(), list_List(list_Car(scan))));
+ sortlist = list_Nconc(sortlist, term_ArgumentList(Term));
+ term_RplacArgumentList(Term, sortlist);
+ } else {
+ /* No "or" term, so build the implication term */
+ if (list_Empty(list_Cdr(sortlist))) {
+ /* Only one sort term */
+ list_Rplacd(sortlist, list_List(Term));
+ Term = term_Create(fol_Implies(), sortlist);
+ } else {
+ /* More than one sort term */
+ helpterm = term_Create(fol_And(), sortlist);
+ Term = term_Create(fol_Implies(), list_Cons(helpterm, list_List(Term)));
+ }
+ }
+ } else if (symbol_Equal(fol_Exist(), Symbol)) {
+ /* Quantify the conjunction of all sort terms and <Term> */
+ if (symbol_Equal(fol_And(), term_TopSymbol(Term))) {
+ /* Special treatment if <Term> has an "and" as top symbol: */
+ /* just add the sort terms to the args of the "and". */
+ sortlist = list_Nconc(sortlist, term_ArgumentList(Term));
+ term_RplacArgumentList(Term, sortlist);
+ } else {
+ sortlist = list_Nconc(sortlist, list_List(Term));
+ Term = term_Create(fol_And(), sortlist);
+ }
+ }
+ }
+ helpterm = fol_CreateQuantifier(Symbol, varlist, list_List(Term));
+ return helpterm;
+}
+
+
+CLAUSE dfg_CreateClauseFromTerm(TERM Clause, BOOL IsAxiom, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause term, a boolean value, a flag store and a precedence.
+ RETURNS: The clause term converted to a CLAUSE or NULL if the
+ clause is a trivial tautology (the clause contains
+ the literal "true" or "not(false)" ).
+ EFFECT: This function converts a clause stored as term into an
+ EARL clause structure.
+ If 'IsAxiom' is TRUE the clause is treated as axiom
+ clause else as conjecture clause.
+ The function deletes the literals "false" and "not(true)"
+ if they occur in <Clause>.
+ The contents of the flag store and the precedence are changed
+ because the parser read flag and precedence settings from
+
+ MEMORY: The clause term is deleted.
+***************************************************************/
+{
+ LIST literals, scan;
+ TERM literal;
+ CLAUSE result;
+
+ if (term_TopSymbol(Clause) == fol_All()) {
+ /* Remove and free the quantifier and the OR term */
+ literals = term_ArgumentList(term_SecondArgument(Clause));
+ term_RplacArgumentList(term_SecondArgument(Clause), list_Nil());
+ } else {
+ /* Remove and free the OR term */
+ literals = term_ArgumentList(Clause);
+ term_RplacArgumentList(Clause, list_Nil());
+ }
+ term_Delete(Clause);
+
+ for (scan = literals; !list_Empty(scan); scan = list_Cdr(scan)) {
+ literal = (TERM) list_Car(scan);
+ if (symbol_IsPredicate(term_TopSymbol(literal))) { /* Positive literal */
+ if (fol_IsTrue(literal)) {
+ /* Clause is a tautology */
+ list_PointerDeleteElement(literals, NULL);
+ /* Remove possible NULL elements to avoid a crash in term_Delete */
+ term_DeleteTermList(literals);
+ return (CLAUSE) NULL;
+ } else if (fol_IsFalse(literal)) {
+ /* Ignore this literal */
+ term_Delete(literal);
+ list_Rplaca(scan, NULL); /* Mark the actual list element */
+ }
+ } else {
+ /* Found a negative literal */
+ TERM atom = term_FirstArgument(literal);
+ if (fol_IsFalse(atom)) {
+ /* Clause is a tautology */
+ list_PointerDeleteElement(literals, NULL);
+ /* Remove possible NULL elements to avoid a crash in term_Delete */
+ term_DeleteTermList(literals);
+ return (CLAUSE) NULL;
+ } else if (fol_IsTrue(atom)) {
+ /* Ignore this literal */
+ term_Delete(literal);
+ list_Rplaca(literals, NULL); /* Mark the actual list element */
+ }
+ }
+ }
+
+ literals = list_PointerDeleteElement(literals, NULL);
+ /* Remove the special literals treated above from the list */
+ result = clause_CreateFromLiterals(literals, FALSE, !IsAxiom, FALSE, Flags, Precedence);
+ /* Don't create sorts! */
+ list_Delete(literals);
+
+ return result;
+}
+
+
+static void dfg_SubSort(char* Name1, char* Name2)
+/**************************************************************
+ INPUT: Two sort symbol names.
+ RETURNS: Nothing.
+ EFFECT: This functions adds the formula
+ forall([U], implies(Name1(U), Name2(U)))
+ to the list of axiom formulas. Both <Name1> and <Name2>
+ are deleted.
+***************************************************************/
+{
+ SYMBOL s1, s2;
+ TERM varterm, t1, t2, term;
+
+ s1 = dfg_Symbol(Name1, 1); /* Should be unary predicates */
+ s2 = dfg_Symbol(Name2, 1);
+ if (!symbol_IsPredicate(s1)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: Symbol is not a sort predicate.\n", dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ if (!symbol_IsPredicate(s2)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: Symbol is not a sort predicate.\n", dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+
+ varterm = term_Create(symbol_CreateStandardVariable(), list_Nil());
+ symbol_ResetStandardVarCounter();
+
+ t1 = term_Create(s1, list_List(varterm));
+ t2 = term_Create(s2, list_List(term_Copy(varterm)));
+ term = term_Create(fol_Implies(), list_Cons(t1, list_List(t2)));
+ term = fol_CreateQuantifier(fol_All(), list_List(term_Copy(varterm)),
+ list_List(term));
+ dfg_SORTDECLLIST = list_Nconc(dfg_SORTDECLLIST, list_List(list_PairCreate(NULL,term)));
+}
+
+
+static void dfg_SymbolGenerated(SYMBOL SortPredicate, BOOL FreelyGenerated,
+ LIST GeneratedBy)
+/**************************************************************
+ INPUT: A sort predicate, a boolean flag, and a list of function
+ symbol names.
+ RETURNS: Nothing.
+ EFFECT: This function stores the information that the <SortPredicate>
+ is generated by the function symbols from the <GeneratedBy>
+ list. The list contains only symbol names!
+ The <SortPredicate> AND the symbols from the list get
+ the property GENERATED. Additionally the symbols get
+ the property FREELY, if the flag <FreelyGenerated> is TRUE.
+***************************************************************/
+{
+ SYMBOL symbol;
+ LIST scan;
+
+ if (!symbol_IsPredicate(SortPredicate)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: Symbol is not a sort predicate.\n", dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ /* First reset the old information */
+ symbol_RemoveProperty(SortPredicate, GENERATED);
+ symbol_RemoveProperty(SortPredicate, FREELY);
+ list_Delete(symbol_GeneratedBy(SortPredicate));
+ /* Now set the new information */
+ symbol_AddProperty(SortPredicate, GENERATED);
+ if (FreelyGenerated)
+ symbol_AddProperty(SortPredicate, FREELY);
+ for (scan = GeneratedBy; !list_Empty(scan); scan = list_Cdr(scan)) {
+ symbol = symbol_Lookup(list_Car(scan));
+ if (symbol == 0) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: undefined symbol %s.\n", dfg_LINENUMBER,
+ (char*)list_Car(scan));
+ misc_FinishUserErrorReport();
+ } else if (!symbol_IsFunction(symbol)) { /* must be function or constant */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: Symbol is not a function.\n", dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ string_StringFree(list_Car(scan));
+ list_Rplaca(scan, (POINTER)symbol); /* change the name list to a symbol list */
+ /* Set GENERATED properties for generating symbols */
+ symbol_AddProperty(symbol, GENERATED);
+ if (FreelyGenerated)
+ symbol_AddProperty(symbol, FREELY);
+ }
+ symbol_SetGeneratedBy(SortPredicate, GeneratedBy);
+}
+
+
+/**************************************************************/
+/* Functions for the Symbol Table */
+/**************************************************************/
+
+typedef struct {
+ SYMBOL symbol;
+ BOOL valid;
+ int arity;
+} DFG_SYMENTRY, *DFG_SYM;
+
+static __inline__ DFG_SYM dfg_SymCreate(void)
+{
+ return (DFG_SYM) memory_Malloc(sizeof(DFG_SYMENTRY));
+}
+
+static __inline__ void dfg_SymFree(DFG_SYM Entry)
+{
+ memory_Free(Entry, sizeof(DFG_SYMENTRY));
+}
+
+
+static void dfg_SymAdd(SYMBOL Symbol)
+/**************************************************************
+ INPUT: A symbol.
+ RETURNS: Nothing.
+ EFFECT: This function adds 'Symbol' to the symbol list.
+ The arity of these symbols will be checked every time
+ the symbol occurs.
+***************************************************************/
+{
+ DFG_SYM newEntry = dfg_SymCreate();
+ newEntry->symbol = Symbol;
+ newEntry->valid = FALSE;
+ newEntry->arity = 0;
+ dfg_SYMBOLLIST = list_Cons(newEntry, dfg_SYMBOLLIST);
+}
+
+
+static void dfg_SymCheck(SYMBOL Symbol, NAT Arity)
+/**************************************************************
+ INPUT: A symbol and the current arity of this symbol.
+ RETURNS: Nothing.
+ EFFECT: This function compares the previous arity of 'Symbol'
+ with the actual 'Arity'. If these values differ
+ the symbol's arity is set to arbitrary.
+ The arity of symbols whose arity was specified in
+ the symbol declaration section is checked and a warning
+ is printed to stderr in case of differences.
+***************************************************************/
+{
+ LIST scan = dfg_SYMBOLLIST;
+ while (!list_Empty(scan)) {
+ DFG_SYM actEntry = (DFG_SYM) list_Car(scan);
+ if (actEntry->symbol == Symbol) {
+ if (actEntry->valid) {
+ if (actEntry->arity != Arity) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %u:", dfg_LINENUMBER);
+ misc_UserErrorReport(" The actual arity %u", Arity);
+ misc_UserErrorReport(" of symbol %s differs", symbol_Name(Symbol));
+ misc_UserErrorReport(" from the previous arity %u.\n", actEntry->arity);
+ misc_FinishUserErrorReport();
+ }
+ } else {
+ /* Not valid => first time */
+ actEntry->arity = Arity;
+ actEntry->valid = TRUE;
+ }
+ return;
+ }
+ scan = list_Cdr(scan);
+ }
+
+ /* Symbol isn't in SymbolList, so its arity was specified. */
+ /* Check if the specified arity corresponds with the actual arity */
+ if (symbol_Arity(Symbol) != Arity) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %u: Symbol %s was declared with arity %u.\n",
+ dfg_LINENUMBER, symbol_Name(Symbol), symbol_Arity(Symbol));
+ misc_FinishUserErrorReport();
+ }
+}
+
+
+static void dfg_SymCleanUp(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECT: This function corrects all symbols whose arity wasn't
+ specified in the symbol declaration section but seem
+ to occur with always the same arity.
+ The memory for the symbol list is freed.
+***************************************************************/
+{
+ while (!list_Empty(dfg_SYMBOLLIST)) {
+ DFG_SYM actEntry = (DFG_SYM) list_Car(dfg_SYMBOLLIST);
+ SYMBOL actSymbol = actEntry->symbol;
+
+ if (actEntry->arity != symbol_Arity(actSymbol))
+ symbol_SetArity(actSymbol, actEntry->arity);
+
+ dfg_SymFree(actEntry);
+ dfg_SYMBOLLIST = list_Pop(dfg_SYMBOLLIST);
+ }
+}
+
+
+/**************************************************************/
+/* Functions for the Variable Table */
+/**************************************************************/
+
+typedef struct {
+ char* name;
+ SYMBOL symbol;
+} DFG_VARENTRY, *DFG_VAR;
+
+static __inline__ char* dfg_VarName(DFG_VAR Entry)
+{
+ return Entry->name;
+}
+
+static __inline__ SYMBOL dfg_VarSymbol(DFG_VAR Entry)
+{
+ return Entry->symbol;
+}
+
+static __inline__ DFG_VAR dfg_VarCreate(void)
+{
+ return (DFG_VAR) memory_Malloc(sizeof(DFG_VARENTRY));
+}
+
+static void dfg_VarFree(DFG_VAR Entry)
+{
+ string_StringFree(Entry->name);
+ memory_Free(Entry, sizeof(DFG_VARENTRY));
+}
+
+static void dfg_VarStart(void)
+{
+ dfg_VARLIST = list_Push(list_Nil(), dfg_VARLIST);
+ dfg_VARDECL = TRUE;
+}
+
+static void dfg_VarStop(void)
+{
+ dfg_VARDECL = FALSE;
+}
+
+static void dfg_VarBacktrack(void)
+{
+ list_DeleteWithElement(list_Top(dfg_VARLIST), (void (*)(POINTER)) dfg_VarFree);
+ dfg_VARLIST = list_Pop(dfg_VARLIST);
+}
+
+static void dfg_VarCheck(void)
+/* Should be called after a complete clause or formula was parsed */
+{
+ if (!list_Empty(dfg_VARLIST)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In dfg_VarCheck: List of variables should be empty!\n");
+ misc_FinishErrorReport();
+ }
+ symbol_ResetStandardVarCounter();
+}
+
+static SYMBOL dfg_VarLookup(char* Name)
+/**************************************************************
+ INPUT: A variable name.
+ RETURNS: The corresponding variable symbol.
+ EFFECT: If the variable name was quantified before, the
+ corresponding symbol is returned and the <Name> is freed.
+ If the variable name was not quantified, and <dfg_VARDECL>
+ is TRUE, a new variable is created, else an error
+ message is printed and the program exits.
+***************************************************************/
+{
+ LIST scan, scan2;
+ SYMBOL symbol = symbol_Null();
+
+ scan = dfg_VARLIST;
+ scan2 = list_Nil();
+ while (!list_Empty(scan) && list_Empty(scan2)) {
+ scan2 = list_Car(scan);
+ while (!list_Empty(scan2) &&
+ (!string_Equal(dfg_VarName(list_Car(scan2)), Name)))
+ scan2 = list_Cdr(scan2);
+ scan = list_Cdr(scan);
+ }
+
+ if (!list_Empty(scan2)) {
+ /* Found variable */
+ string_StringFree(Name);
+ symbol = dfg_VarSymbol(list_Car(scan2));
+ } else {
+ /* Variable not found */
+ if (dfg_VARDECL) {
+ DFG_VAR newEntry = dfg_VarCreate();
+ newEntry->name = Name;
+ newEntry->symbol = symbol_CreateStandardVariable();
+ /* Add <newentry> to the first list in dfg_VARLIST */
+ list_Rplaca(dfg_VARLIST, list_Cons(newEntry,list_Car(dfg_VARLIST)));
+ symbol = dfg_VarSymbol(newEntry);
+ } else {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %u: Free Variable %s.\n", dfg_LINENUMBER, Name);
+ misc_FinishUserErrorReport();
+ }
+ }
+ return symbol;
+}
+
diff --git a/test/spass/dfgparser.h b/test/spass/dfgparser.h
new file mode 100644
index 0000000..252f140
--- /dev/null
+++ b/test/spass/dfgparser.h
@@ -0,0 +1,184 @@
+/* A Bison parser, made from dfgparser.y, by GNU bison 1.75. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ 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, 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. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+#ifndef BISON_DFGPARSER_H
+# define BISON_DFGPARSER_H
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ DFG_AND = 258,
+ DFG_AUTHOR = 259,
+ DFG_AXIOMS = 260,
+ DFG_BEGPROB = 261,
+ DFG_BY = 262,
+ DFG_CLAUSE = 263,
+ DFG_CLOSEBRACE = 264,
+ DFG_CLSLIST = 265,
+ DFG_CNF = 266,
+ DFG_CONJECS = 267,
+ DFG_DATE = 268,
+ DFG_DECLLIST = 269,
+ DFG_DESC = 270,
+ DFG_DESCLIST = 271,
+ DFG_DNF = 272,
+ DFG_DOMPRED = 273,
+ DFG_ENDLIST = 274,
+ DFG_ENDPROB = 275,
+ DFG_EQUAL = 276,
+ DFG_EQUIV = 277,
+ DFG_EXISTS = 278,
+ DFG_FALSE = 279,
+ DFG_FORMLIST = 280,
+ DFG_FORMULA = 281,
+ DFG_FORALL = 282,
+ DFG_FREELY = 283,
+ DFG_FUNC = 284,
+ DFG_GENERATED = 285,
+ DFG_GENSET = 286,
+ DFG_HYPOTH = 287,
+ DFG_IMPLIED = 288,
+ DFG_IMPLIES = 289,
+ DFG_LOGIC = 290,
+ DFG_NAME = 291,
+ DFG_NOT = 292,
+ DFG_OPENBRACE = 293,
+ DFG_OPERAT = 294,
+ DFG_OR = 295,
+ DFG_PREC = 296,
+ DFG_PRED = 297,
+ DFG_PRDICAT = 298,
+ DFG_PRFLIST = 299,
+ DFG_QUANTIF = 300,
+ DFG_SATIS = 301,
+ DFG_SETFLAG = 302,
+ DFG_SETTINGS = 303,
+ DFG_SYMLIST = 304,
+ DFG_SORT = 305,
+ DFG_SORTS = 306,
+ DFG_STATUS = 307,
+ DFG_STEP = 308,
+ DFG_SUBSORT = 309,
+ DFG_TERMLIST = 310,
+ DFG_TRUE = 311,
+ DFG_UNKNOWN = 312,
+ DFG_UNSATIS = 313,
+ DFG_VERSION = 314,
+ DFG_NUM = 315,
+ DFG_MINUS1 = 316,
+ DFG_ID = 317,
+ DFG_TEXT = 318
+ };
+#endif
+#define DFG_AND 258
+#define DFG_AUTHOR 259
+#define DFG_AXIOMS 260
+#define DFG_BEGPROB 261
+#define DFG_BY 262
+#define DFG_CLAUSE 263
+#define DFG_CLOSEBRACE 264
+#define DFG_CLSLIST 265
+#define DFG_CNF 266
+#define DFG_CONJECS 267
+#define DFG_DATE 268
+#define DFG_DECLLIST 269
+#define DFG_DESC 270
+#define DFG_DESCLIST 271
+#define DFG_DNF 272
+#define DFG_DOMPRED 273
+#define DFG_ENDLIST 274
+#define DFG_ENDPROB 275
+#define DFG_EQUAL 276
+#define DFG_EQUIV 277
+#define DFG_EXISTS 278
+#define DFG_FALSE 279
+#define DFG_FORMLIST 280
+#define DFG_FORMULA 281
+#define DFG_FORALL 282
+#define DFG_FREELY 283
+#define DFG_FUNC 284
+#define DFG_GENERATED 285
+#define DFG_GENSET 286
+#define DFG_HYPOTH 287
+#define DFG_IMPLIED 288
+#define DFG_IMPLIES 289
+#define DFG_LOGIC 290
+#define DFG_NAME 291
+#define DFG_NOT 292
+#define DFG_OPENBRACE 293
+#define DFG_OPERAT 294
+#define DFG_OR 295
+#define DFG_PREC 296
+#define DFG_PRED 297
+#define DFG_PRDICAT 298
+#define DFG_PRFLIST 299
+#define DFG_QUANTIF 300
+#define DFG_SATIS 301
+#define DFG_SETFLAG 302
+#define DFG_SETTINGS 303
+#define DFG_SYMLIST 304
+#define DFG_SORT 305
+#define DFG_SORTS 306
+#define DFG_STATUS 307
+#define DFG_STEP 308
+#define DFG_SUBSORT 309
+#define DFG_TERMLIST 310
+#define DFG_TRUE 311
+#define DFG_UNKNOWN 312
+#define DFG_UNSATIS 313
+#define DFG_VERSION 314
+#define DFG_NUM 315
+#define DFG_MINUS1 316
+#define DFG_ID 317
+#define DFG_TEXT 318
+
+
+
+
+#ifndef YYSTYPE
+#line 165 "dfgparser.y"
+typedef union {
+ int number;
+ char* string;
+ SYMBOL symbol;
+ SPROPERTY property;
+ TERM term;
+ LIST list;
+ DFG_STATE state;
+ BOOL bool;
+} yystype;
+/* Line 1281 of /opt/gnu//share/bison/yacc.c. */
+#line 177 "dfgparser.h"
+# define YYSTYPE yystype
+#endif
+
+extern YYSTYPE dfg_lval;
+
+
+#endif /* not BISON_DFGPARSER_H */
+
diff --git a/test/spass/dfgscanner.c b/test/spass/dfgscanner.c
new file mode 100644
index 0000000..a6eefa4
--- /dev/null
+++ b/test/spass/dfgscanner.c
@@ -0,0 +1,5174 @@
+#define yy_create_buffer dfg__create_buffer
+#define yy_delete_buffer dfg__delete_buffer
+#define yy_scan_buffer dfg__scan_buffer
+#define yy_scan_string dfg__scan_string
+#define yy_scan_bytes dfg__scan_bytes
+#define yy_flex_debug dfg__flex_debug
+#define yy_init_buffer dfg__init_buffer
+#define yy_flush_buffer dfg__flush_buffer
+#define yy_load_buffer_state dfg__load_buffer_state
+#define yy_switch_to_buffer dfg__switch_to_buffer
+#define yyin dfg_in
+#define yyleng dfg_leng
+#define yylex dfg_lex
+#define yyout dfg_out
+#define yyrestart dfg_restart
+#define yytext dfg_text
+
+#line 19 "dfgscanner.c"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header$
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+static yyconst short yy_nxt[][41] =
+ {
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0
+ },
+
+ {
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 13,
+ 14, 14, 14, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 14, 14, 24, 14, 25, 26, 27,
+ 28, 14, 29, 30, 31, 32, 14, 14, 14, 33,
+ 6
+
+ },
+
+ {
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 13,
+ 14, 14, 14, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 14, 14, 24, 14, 25, 26, 27,
+ 28, 14, 29, 30, 31, 32, 14, 14, 14, 33,
+ 6
+ },
+
+ {
+ 5, 34, 34, 34, 34, 34, 35, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34
+
+ },
+
+ {
+ 5, 34, 34, 34, 34, 34, 35, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34
+ },
+
+ {
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5
+
+ },
+
+ {
+ 5, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6
+ },
+
+ {
+ 5, -7, 36, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7
+
+ },
+
+ {
+ 5, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8
+ },
+
+ {
+ 5, 37, 37, -9, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37
+
+ },
+
+ {
+ 5, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10
+ },
+
+ {
+ 5, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ 38
+
+ },
+
+ {
+ 5, -12, -12, -12, -12, -12, -12, -12, -12, 39,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12
+ },
+
+ {
+ 5, -13, -13, -13, -13, -13, -13, -13, 40, 40,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -13,
+ -13
+
+ },
+
+ {
+ 5, -14, -14, -14, -14, -14, -14, -14, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -14,
+ -14
+ },
+
+ {
+ 5, -15, -15, -15, -15, -15, -15, -15, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 42, 41, 41,
+ 41, 41, 41, 41, 43, 41, 41, 44, 41, -15,
+ -15
+
+ },
+
+ {
+ 5, -16, -16, -16, -16, -16, -16, -16, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 45, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 46, -16,
+ -16
+ },
+
+ {
+ 5, -17, -17, -17, -17, -17, -17, -17, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 47, 41, 48, 49, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -17,
+ -17
+
+ },
+
+ {
+ 5, -18, -18, -18, -18, -18, -18, -18, 41, 41,
+ 41, 41, 41, 41, 50, 41, 41, 41, 51, 41,
+ 41, 41, 41, 41, 41, 41, 41, 52, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -18,
+ -18
+ },
+
+ {
+ 5, -19, -19, -19, -19, -19, -19, -19, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 53, 41, 41,
+ 54, 41, 41, 41, 41, 41, 41, 55, 41, -19,
+ -19
+
+ },
+
+ {
+ 5, -20, -20, -20, -20, -20, -20, -20, 41, 41,
+ 41, 41, 41, 41, 56, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 57, 41,
+ 41, 58, 41, 41, 59, 41, 41, 41, 41, -20,
+ -20
+ },
+
+ {
+ 5, -21, -21, -21, -21, -21, -21, -21, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 60, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -21,
+ -21
+
+ },
+
+ {
+ 5, -22, -22, -22, -22, -22, -22, -22, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 61, -22,
+ -22
+ },
+
+ {
+ 5, -23, -23, -23, -23, -23, -23, -23, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 62, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -23,
+ -23
+
+ },
+
+ {
+ 5, -24, -24, -24, -24, -24, -24, -24, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 63, 41, 41, 41, 41, 41, 64, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -24,
+ -24
+ },
+
+ {
+ 5, -25, -25, -25, -25, -25, -25, -25, 41, 41,
+ 41, 41, 41, 41, 65, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 66, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -25,
+ -25
+
+ },
+
+ {
+ 5, -26, -26, -26, -26, -26, -26, -26, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 67,
+ 41, 68, 41, 41, 41, 41, 41, 41, 41, -26,
+ -26
+ },
+
+ {
+ 5, -27, -27, -27, -27, -27, -27, -27, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 69, 41, 41, 41, 41, 41, 41, 41, -27,
+ -27
+
+ },
+
+ {
+ 5, -28, -28, -28, -28, -28, -28, -28, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 70, 41, 41, 41, 41, -28,
+ -28
+ },
+
+ {
+ 5, -29, -29, -29, -29, -29, -29, -29, 41, 41,
+ 41, 41, 41, 41, 71, 41, 41, 41, 72, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 73, 41,
+ 41, 41, 41, 74, 75, 41, 41, 41, 41, -29,
+ -29
+
+ },
+
+ {
+ 5, -30, -30, -30, -30, -30, -30, -30, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 76, 41, 41, 41, 41, 41, 41, 41, -30,
+ -30
+ },
+
+ {
+ 5, -31, -31, -31, -31, -31, -31, -31, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 77, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -31,
+ -31
+
+ },
+
+ {
+ 5, -32, -32, -32, -32, -32, -32, -32, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 78, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -32,
+ -32
+ },
+
+ {
+ 5, -33, -33, -33, -33, -33, 79, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33
+
+ },
+
+ {
+ 5, 80, 80, 80, 80, 80, -34, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80
+ },
+
+ {
+ 5, 81, 81, 81, 81, 81, 82, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 83
+
+ },
+
+ {
+ 5, -36, 36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36
+ },
+
+ {
+ 5, 37, 37, -37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37
+
+ },
+
+ {
+ 5, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38
+ },
+
+ {
+ 5, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39
+
+ },
+
+ {
+ 5, -40, -40, -40, -40, -40, -40, -40, 40, 40,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -40,
+ -40
+ },
+
+ {
+ 5, -41, -41, -41, -41, -41, -41, -41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -41,
+ -41
+
+ },
+
+ {
+ 5, -42, -42, -42, -42, -42, -42, -42, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 84, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -42,
+ -42
+ },
+
+ {
+ 5, -43, -43, -43, -43, -43, -43, -43, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 85, 41, 41, 41, 41, 41, -43,
+ -43
+
+ },
+
+ {
+ 5, -44, -44, -44, -44, -44, -44, -44, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 86, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -44,
+ -44
+ },
+
+ {
+ 5, -45, -45, -45, -45, -45, -45, -45, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 87, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -45,
+ -45
+
+ },
+
+ {
+ 5, -46, -46, -46, -46, -46, -46, -46, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -46,
+ -46
+ },
+
+ {
+ 5, -47, -47, -47, -47, -47, -47, -47, 41, 41,
+ 41, 41, 41, 41, 88, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -47,
+ -47
+
+ },
+
+ {
+ 5, -48, -48, -48, -48, -48, -48, -48, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 89,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -48,
+ -48
+ },
+
+ {
+ 5, -49, -49, -49, -49, -49, -49, -49, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 90, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -49,
+ -49
+
+ },
+
+ {
+ 5, -50, -50, -50, -50, -50, -50, -50, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 91, 41, 41, 41, 41, 41, -50,
+ -50
+ },
+
+ {
+ 5, -51, -51, -51, -51, -51, -51, -51, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 92, 41, 41, 41, 41, 41, 41, -51,
+ -51
+
+ },
+
+ {
+ 5, -52, -52, -52, -52, -52, -52, -52, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 93,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -52,
+ -52
+ },
+
+ {
+ 5, -53, -53, -53, -53, -53, -53, -53, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 94, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -53,
+ -53
+
+ },
+
+ {
+ 5, -54, -54, -54, -54, -54, -54, -54, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 95, 41, 41, 41, 41, -54,
+ -54
+ },
+
+ {
+ 5, -55, -55, -55, -55, -55, -55, -55, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 96, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -55,
+ -55
+
+ },
+
+ {
+ 5, -56, -56, -56, -56, -56, -56, -56, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 97, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -56,
+ -56
+ },
+
+ {
+ 5, -57, -57, -57, -57, -57, -57, -57, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 98, 41, 41, 41, 41, 41, 41, 41, -57,
+ -57
+
+ },
+
+ {
+ 5, -58, -58, -58, -58, -58, -58, -58, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 99, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -58,
+ -58
+ },
+
+ {
+ 5, -59, -59, -59, -59, -59, -59, -59, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 100, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -59,
+ -59
+
+ },
+
+ {
+ 5, -60, -60, -60, -60, -60, -60, -60, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 101, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -60,
+ -60
+ },
+
+ {
+ 5, -61, -61, -61, -61, -61, -61, -61, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 102,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -61,
+ -61
+
+ },
+
+ {
+ 5, -62, -62, -62, -62, -62, -62, -62, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 103,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -62,
+ -62
+ },
+
+ {
+ 5, -63, -63, -63, -63, -63, -63, -63, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 104, 41, 41, 41, 41, 41, 41, -63,
+ -63
+
+ },
+
+ {
+ 5, -64, -64, -64, -64, -64, -64, -64, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 105, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -64,
+ -64
+ },
+
+ {
+ 5, -65, -65, -65, -65, -65, -65, -65, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 106, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -65,
+ -65
+
+ },
+
+ {
+ 5, -66, -66, -66, -66, -66, -66, -66, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 107, 41, 41, 41, 41, 41, -66,
+ -66
+ },
+
+ {
+ 5, -67, -67, -67, -67, -67, -67, -67, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 108, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -67,
+ -67
+
+ },
+
+ {
+ 5, -68, -68, -68, -68, -68, -68, -68, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -68,
+ -68
+ },
+
+ {
+ 5, -69, -69, -69, -69, -69, -69, -69, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 109, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -69,
+ -69
+
+ },
+
+ {
+ 5, -70, -70, -70, -70, -70, -70, -70, 41, 41,
+ 41, 41, 41, 41, 110, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -70,
+ -70
+ },
+
+ {
+ 5, -71, -71, -71, -71, -71, -71, -71, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 111, 41, 41, 41, 41, 41, -71,
+ -71
+
+ },
+
+ {
+ 5, -72, -72, -72, -72, -72, -72, -72, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 112, 41, 41, 41, 41, 41, -72,
+ -72
+ },
+
+ {
+ 5, -73, -73, -73, -73, -73, -73, -73, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 113, 41, 41, 41, 41, 41, 41, 41, -73,
+ -73
+
+ },
+
+ {
+ 5, -74, -74, -74, -74, -74, -74, -74, 41, 41,
+ 41, 41, 41, 41, 114, 41, 41, 41, 115, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -74,
+ -74
+ },
+
+ {
+ 5, -75, -75, -75, -75, -75, -75, -75, 41, 41,
+ 41, 41, 41, 41, 41, 116, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -75,
+ -75
+
+ },
+
+ {
+ 5, -76, -76, -76, -76, -76, -76, -76, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 117, 41, 41, 41, 41, -76,
+ -76
+ },
+
+ {
+ 5, -77, -77, -77, -77, -77, -77, -77, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 118, 41, 41, 41, 41, 41,
+ 41, 41, 119, 41, 41, 41, 41, 41, 41, -77,
+ -77
+
+ },
+
+ {
+ 5, -78, -78, -78, -78, -78, -78, -78, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 120, 41, 41, 41, 41, 41, 41, 41, -78,
+ -78
+ },
+
+ {
+ 5, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79
+
+ },
+
+ {
+ 5, 80, 80, 80, 80, 80, -80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80
+ },
+
+ {
+ 5, 81, 81, 81, 81, 81, -81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ -81
+
+ },
+
+ {
+ 5, 81, 81, 81, 81, 81, 82, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 83
+ },
+
+ {
+ 5, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83
+
+ },
+
+ {
+ 5, -84, -84, -84, -84, -84, -84, -84, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -84,
+ -84
+ },
+
+ {
+ 5, -85, -85, -85, -85, -85, -85, -85, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 121, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -85,
+ -85
+
+ },
+
+ {
+ 5, -86, -86, -86, -86, -86, -86, -86, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 122, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -86,
+ -86
+ },
+
+ {
+ 5, -87, -87, -87, -87, -87, -87, -87, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 123, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -87,
+ -87
+
+ },
+
+ {
+ 5, -88, -88, -88, -88, -88, -88, -88, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 124, 41, 41, 41, 41, -88,
+ -88
+ },
+
+ {
+ 5, -89, -89, -89, -89, -89, -89, -89, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -89,
+ -89
+
+ },
+
+ {
+ 5, -90, -90, -90, -90, -90, -90, -90, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 125, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -90,
+ -90
+ },
+
+ {
+ 5, -91, -91, -91, -91, -91, -91, -91, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 126, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -91,
+ -91
+
+ },
+
+ {
+ 5, -92, -92, -92, -92, -92, -92, -92, 41, 41,
+ 41, 41, 41, 41, 41, 41, 127, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -92,
+ -92
+ },
+
+ {
+ 5, -93, -93, -93, -93, -93, -93, -93, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -93,
+ -93
+
+ },
+
+ {
+ 5, -94, -94, -94, -94, -94, -94, -94, 41, 41,
+ 41, 41, 41, 128, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -94,
+ -94
+ },
+
+ {
+ 5, -95, -95, -95, -95, -95, -95, -95, 41, 41,
+ 41, 41, 41, 41, 129, 41, 41, 41, 41, 41,
+ 41, 41, 130, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -95,
+ -95
+
+ },
+
+ {
+ 5, -96, -96, -96, -96, -96, -96, -96, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 131, 41, 41, 41, 41, 41, 41, -96,
+ -96
+ },
+
+ {
+ 5, -97, -97, -97, -97, -97, -97, -97, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 132, 41, 41, 41, 41, 41, 41, -97,
+ -97
+
+ },
+
+ {
+ 5, -98, -98, -98, -98, -98, -98, -98, 41, 41,
+ 41, 41, 41, 41, 133, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 134, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -98,
+ -98
+ },
+
+ {
+ 5, -99, -99, -99, -99, -99, -99, -99, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 135, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -99,
+ -99
+
+ },
+
+ {
+ 5, -100, -100, -100, -100, -100, -100, -100, 41, 41,
+ 41, 41, 41, 41, 41, 41, 136, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -100,
+ -100
+ },
+
+ {
+ 5, -101, -101, -101, -101, -101, -101, -101, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 137, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -101,
+ -101
+
+ },
+
+ {
+ 5, -102, -102, -102, -102, -102, -102, -102, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 138, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -102,
+ -102
+ },
+
+ {
+ 5, -103, -103, -103, -103, -103, -103, -103, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 139, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -103,
+ -103
+
+ },
+
+ {
+ 5, -104, -104, -104, -104, -104, -104, -104, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 140, 41, 41, 41, 41, 41, -104,
+ -104
+ },
+
+ {
+ 5, -105, -105, -105, -105, -105, -105, -105, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 141, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -105,
+ -105
+
+ },
+
+ {
+ 5, -106, -106, -106, -106, -106, -106, -106, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 142, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -106,
+ -106
+ },
+
+ {
+ 5, -107, -107, -107, -107, -107, -107, -107, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -107,
+ -107
+
+ },
+
+ {
+ 5, -108, -108, -108, -108, -108, -108, -108, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 143, 41, 41, 41, 41, 41, 41, 41, -108,
+ -108
+ },
+
+ {
+ 5, -109, -109, -109, -109, -109, -109, -109, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 144, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -109,
+ -109
+
+ },
+
+ {
+ 5, -110, -110, -110, -110, -110, -110, -110, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 145, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -110,
+ -110
+ },
+
+ {
+ 5, -111, -111, -111, -111, -111, -111, -111, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 146, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -111,
+ -111
+
+ },
+
+ {
+ 5, -112, -112, -112, -112, -112, -112, -112, 41, 41,
+ 41, 41, 41, 147, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -112,
+ -112
+ },
+
+ {
+ 5, -113, -113, -113, -113, -113, -113, -113, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 148, 41, 41, 41, 41, 41, -113,
+ -113
+
+ },
+
+ {
+ 5, -114, -114, -114, -114, -114, -114, -114, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 149, 41, 41, 41, 41, 41, -114,
+ -114
+ },
+
+ {
+ 5, -115, -115, -115, -115, -115, -115, -115, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 150,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -115,
+ -115
+
+ },
+
+ {
+ 5, -116, -116, -116, -116, -116, -116, -116, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 151, 41, 41, 41, 41, 41, 41, -116,
+ -116
+ },
+
+ {
+ 5, -117, -117, -117, -117, -117, -117, -117, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 152, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -117,
+ -117
+
+ },
+
+ {
+ 5, -118, -118, -118, -118, -118, -118, -118, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 153, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -118,
+ -118
+ },
+
+ {
+ 5, -119, -119, -119, -119, -119, -119, -119, 41, 41,
+ 41, 41, 41, 41, 154, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -119,
+ -119
+
+ },
+
+ {
+ 5, -120, -120, -120, -120, -120, -120, -120, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 155, 41, 41, 41, 41, 41, 41, -120,
+ -120
+ },
+
+ {
+ 5, -121, -121, -121, -121, -121, -121, -121, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 156, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -121,
+ -121
+
+ },
+
+ {
+ 5, -122, -122, -122, -122, -122, -122, -122, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 157, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -122,
+ -122
+ },
+
+ {
+ 5, -123, -123, -123, -123, -123, -123, -123, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 158, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -123,
+ -123
+
+ },
+
+ {
+ 5, -124, -124, -124, -124, -124, -124, -124, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 159, 41, 41, 41, 41, 41, 41, -124,
+ -124
+ },
+
+ {
+ 5, -125, -125, -125, -125, -125, -125, -125, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 160, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -125,
+ -125
+
+ },
+
+ {
+ 5, -126, -126, -126, -126, -126, -126, -126, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -126,
+ -126
+ },
+
+ {
+ 5, -127, -127, -127, -127, -127, -127, -127, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 161, 41, 41, 41, 41, 41, 41, 41, -127,
+ -127
+
+ },
+
+ {
+ 5, -128, -128, -128, -128, -128, -128, -128, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 162, 163,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -128,
+ -128
+ },
+
+ {
+ 5, -129, -129, -129, -129, -129, -129, -129, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 164, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -129,
+ -129
+
+ },
+
+ {
+ 5, -130, -130, -130, -130, -130, -130, -130, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 165, 41, 41, 41, -130,
+ -130
+ },
+
+ {
+ 5, -131, -131, -131, -131, -131, -131, -131, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 166, 41, 41, 41, 41, 41, -131,
+ -131
+
+ },
+
+ {
+ 5, -132, -132, -132, -132, -132, -132, -132, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 167, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -132,
+ -132
+ },
+
+ {
+ 5, -133, -133, -133, -133, -133, -133, -133, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 168, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -133,
+ -133
+
+ },
+
+ {
+ 5, -134, -134, -134, -134, -134, -134, -134, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 169, 41, 41, 41, 41, -134,
+ -134
+ },
+
+ {
+ 5, -135, -135, -135, -135, -135, -135, -135, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 170, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -135,
+ -135
+
+ },
+
+ {
+ 5, -136, -136, -136, -136, -136, -136, -136, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 171, 41, 41, 41, 41, 41, -136,
+ -136
+ },
+
+ {
+ 5, -137, -137, -137, -137, -137, -137, -137, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 172, 41, 41, 41, 41, 41, 41, 41, -137,
+ -137
+
+ },
+
+ {
+ 5, -138, -138, -138, -138, -138, -138, -138, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 173, 41, 41, 41, 41, 41, -138,
+ -138
+ },
+
+ {
+ 5, -139, -139, -139, -139, -139, -139, -139, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 174, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -139,
+ -139
+
+ },
+
+ {
+ 5, -140, -140, -140, -140, -140, -140, -140, 41, 41,
+ 41, 41, 41, 175, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -140,
+ -140
+ },
+
+ {
+ 5, -141, -141, -141, -141, -141, -141, -141, 41, 41,
+ 41, 41, 41, 41, 41, 41, 176, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -141,
+ -141
+
+ },
+
+ {
+ 5, -142, -142, -142, -142, -142, -142, -142, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -142,
+ -142
+ },
+
+ {
+ 5, -143, -143, -143, -143, -143, -143, -143, 41, 41,
+ 41, 41, 41, 41, 177, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -143,
+ -143
+
+ },
+
+ {
+ 5, -144, -144, -144, -144, -144, -144, -144, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 178, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -144,
+ -144
+ },
+
+ {
+ 5, -145, -145, -145, -145, -145, -145, -145, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 179, 41, 41, 41, 41, 41, -145,
+ -145
+
+ },
+
+ {
+ 5, -146, -146, -146, -146, -146, -146, -146, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 180, 41, 41, 41, 41, 41, 41, -146,
+ -146
+ },
+
+ {
+ 5, -147, -147, -147, -147, -147, -147, -147, 41, 41,
+ 41, 181, 41, 41, 41, 41, 41, 41, 41, 182,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 183,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -147,
+ -147
+
+ },
+
+ {
+ 5, -148, -148, -148, -148, -148, -148, -148, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 184, 41, 41, 41, 41, 41, 41, -148,
+ -148
+ },
+
+ {
+ 5, -149, -149, -149, -149, -149, -149, -149, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 185, 41, 41, 41, 41, -149,
+ -149
+
+ },
+
+ {
+ 5, -150, -150, -150, -150, -150, -150, -150, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -150,
+ -150
+ },
+
+ {
+ 5, -151, -151, -151, -151, -151, -151, -151, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 186, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -151,
+ -151
+
+ },
+
+ {
+ 5, -152, -152, -152, -152, -152, -152, -152, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -152,
+ -152
+ },
+
+ {
+ 5, -153, -153, -153, -153, -153, -153, -153, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 187, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -153,
+ -153
+
+ },
+
+ {
+ 5, -154, -154, -154, -154, -154, -154, -154, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 188, 41, 41, 41, 41, 41, -154,
+ -154
+ },
+
+ {
+ 5, -155, -155, -155, -155, -155, -155, -155, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 189, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -155,
+ -155
+
+ },
+
+ {
+ 5, -156, -156, -156, -156, -156, -156, -156, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 190, 41, 41, 41, 41, 41, 41, 41, -156,
+ -156
+ },
+
+ {
+ 5, -157, -157, -157, -157, -157, -157, -157, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 191, 41, 41, 41, 41, 41, 41, -157,
+ -157
+
+ },
+
+ {
+ 5, -158, -158, -158, -158, -158, -158, -158, 41, 41,
+ 41, 41, 41, 192, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -158,
+ -158
+ },
+
+ {
+ 5, -159, -159, -159, -159, -159, -159, -159, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 193, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -159,
+ -159
+
+ },
+
+ {
+ 5, -160, -160, -160, -160, -160, -160, -160, 41, 41,
+ 41, 41, 41, 41, 41, 41, 194, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -160,
+ -160
+ },
+
+ {
+ 5, -161, -161, -161, -161, -161, -161, -161, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 195, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -161,
+ -161
+
+ },
+
+ {
+ 5, -162, -162, -162, -162, -162, -162, -162, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 196,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -162,
+ -162
+ },
+
+ {
+ 5, -163, -163, -163, -163, -163, -163, -163, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 197, 41, 41, 41, 41, 41, 41, 41, -163,
+ -163
+
+ },
+
+ {
+ 5, -164, -164, -164, -164, -164, -164, -164, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -164,
+ -164
+ },
+
+ {
+ 5, -165, -165, -165, -165, -165, -165, -165, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -165,
+ -165
+
+ },
+
+ {
+ 5, -166, -166, -166, -166, -166, -166, -166, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 198, 41, 41, 41, 41, 41, 41, -166,
+ -166
+ },
+
+ {
+ 5, -167, -167, -167, -167, -167, -167, -167, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -167,
+ -167
+
+ },
+
+ {
+ 5, -168, -168, -168, -168, -168, -168, -168, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 199, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -168,
+ -168
+ },
+
+ {
+ 5, -169, -169, -169, -169, -169, -169, -169, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 200, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -169,
+ -169
+
+ },
+
+ {
+ 5, -170, -170, -170, -170, -170, -170, -170, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 201, -170,
+ -170
+ },
+
+ {
+ 5, -171, -171, -171, -171, -171, -171, -171, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 202, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -171,
+ -171
+
+ },
+
+ {
+ 5, -172, -172, -172, -172, -172, -172, -172, 41, 41,
+ 41, 41, 41, 41, 203, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -172,
+ -172
+ },
+
+ {
+ 5, -173, -173, -173, -173, -173, -173, -173, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 204, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -173,
+ -173
+
+ },
+
+ {
+ 5, -174, -174, -174, -174, -174, -174, -174, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 205, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -174,
+ -174
+ },
+
+ {
+ 5, -175, -175, -175, -175, -175, -175, -175, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 206, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -175,
+ -175
+
+ },
+
+ {
+ 5, -176, -176, -176, -176, -176, -176, -176, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -176,
+ -176
+ },
+
+ {
+ 5, -177, -177, -177, -177, -177, -177, -177, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 207, 41, 41, 41, 41, 41, -177,
+ -177
+
+ },
+
+ {
+ 5, -178, -178, -178, -178, -178, -178, -178, 41, 41,
+ 41, 41, 41, 41, 41, 41, 208, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -178,
+ -178
+ },
+
+ {
+ 5, -179, -179, -179, -179, -179, -179, -179, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 209, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -179,
+ -179
+
+ },
+
+ {
+ 5, -180, -180, -180, -180, -180, -180, -180, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 210,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -180,
+ -180
+ },
+
+ {
+ 5, -181, -181, -181, -181, -181, -181, -181, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 211, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -181,
+ -181
+
+ },
+
+ {
+ 5, -182, -182, -182, -182, -182, -182, -182, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 212, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -182,
+ -182
+ },
+
+ {
+ 5, -183, -183, -183, -183, -183, -183, -183, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 213, 41, 41, 41, 41, 41, 41, 41, -183,
+ -183
+
+ },
+
+ {
+ 5, -184, -184, -184, -184, -184, -184, -184, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -184,
+ -184
+ },
+
+ {
+ 5, -185, -185, -185, -185, -185, -185, -185, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 214, 41, 41, 41, 41, 41, 41, -185,
+ -185
+
+ },
+
+ {
+ 5, -186, -186, -186, -186, -186, -186, -186, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 215, 41, 41, 41, 41, 41, 41, 41, -186,
+ -186
+ },
+
+ {
+ 5, -187, -187, -187, -187, -187, -187, -187, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 216, 41, 41, -187,
+ -187
+
+ },
+
+ {
+ 5, -188, -188, -188, -188, -188, -188, -188, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 217, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -188,
+ -188
+ },
+
+ {
+ 5, -189, -189, -189, -189, -189, -189, -189, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 218, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -189,
+ -189
+
+ },
+
+ {
+ 5, -190, -190, -190, -190, -190, -190, -190, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -190,
+ -190
+ },
+
+ {
+ 5, -191, -191, -191, -191, -191, -191, -191, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -191,
+ -191
+
+ },
+
+ {
+ 5, -192, -192, -192, -192, -192, -192, -192, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 219,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -192,
+ -192
+ },
+
+ {
+ 5, -193, -193, -193, -193, -193, -193, -193, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -193,
+ -193
+
+ },
+
+ {
+ 5, -194, -194, -194, -194, -194, -194, -194, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 220, 41, 41, 41, 41, 41, -194,
+ -194
+ },
+
+ {
+ 5, -195, -195, -195, -195, -195, -195, -195, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 221,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -195,
+ -195
+
+ },
+
+ {
+ 5, -196, -196, -196, -196, -196, -196, -196, 41, 41,
+ 41, 41, 41, 222, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -196,
+ -196
+ },
+
+ {
+ 5, -197, -197, -197, -197, -197, -197, -197, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 223, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -197,
+ -197
+
+ },
+
+ {
+ 5, -198, -198, -198, -198, -198, -198, -198, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -198,
+ -198
+ },
+
+ {
+ 5, -199, -199, -199, -199, -199, -199, -199, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -199,
+ -199
+
+ },
+
+ {
+ 5, -200, -200, -200, -200, -200, -200, -200, 41, 41,
+ 41, 41, 41, 41, 224, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -200,
+ -200
+ },
+
+ {
+ 5, -201, -201, -201, -201, -201, -201, -201, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -201,
+ -201
+
+ },
+
+ {
+ 5, -202, -202, -202, -202, -202, -202, -202, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 225, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -202,
+ -202
+ },
+
+ {
+ 5, -203, -203, -203, -203, -203, -203, -203, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 226, 41, 41, 41, 41, 41, -203,
+ -203
+
+ },
+
+ {
+ 5, -204, -204, -204, -204, -204, -204, -204, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 227, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -204,
+ -204
+ },
+
+ {
+ 5, -205, -205, -205, -205, -205, -205, -205, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 228, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 229, 41, 41, 41, 41, 41, 41, -205,
+ -205
+
+ },
+
+ {
+ 5, -206, -206, -206, -206, -206, -206, -206, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 230,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -206,
+ -206
+ },
+
+ {
+ 5, -207, -207, -207, -207, -207, -207, -207, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 231, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -207,
+ -207
+
+ },
+
+ {
+ 5, -208, -208, -208, -208, -208, -208, -208, 41, 41,
+ 41, 41, 41, 41, 232, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -208,
+ -208
+ },
+
+ {
+ 5, -209, -209, -209, -209, -209, -209, -209, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 233,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -209,
+ -209
+
+ },
+
+ {
+ 5, -210, -210, -210, -210, -210, -210, -210, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 234, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -210,
+ -210
+ },
+
+ {
+ 5, -211, -211, -211, -211, -211, -211, -211, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 235, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -211,
+ -211
+
+ },
+
+ {
+ 5, -212, -212, -212, -212, -212, -212, -212, 41, 41,
+ 41, 41, 41, 41, 236, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -212,
+ -212
+ },
+
+ {
+ 5, -213, -213, -213, -213, -213, -213, -213, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 237, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -213,
+ -213
+
+ },
+
+ {
+ 5, -214, -214, -214, -214, -214, -214, -214, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -214,
+ -214
+ },
+
+ {
+ 5, -215, -215, -215, -215, -215, -215, -215, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 238, 41, 41, 41, 41, 41, -215,
+ -215
+
+ },
+
+ {
+ 5, -216, -216, -216, -216, -216, -216, -216, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 239, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -216,
+ -216
+ },
+
+ {
+ 5, -217, -217, -217, -217, -217, -217, -217, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 240, 41, 41, 41, 41, 41, 41, -217,
+ -217
+
+ },
+
+ {
+ 5, -218, -218, -218, -218, -218, -218, -218, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 241, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -218,
+ -218
+ },
+
+ {
+ 5, -219, -219, -219, -219, -219, -219, -219, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 242, 41, 41, 41, 41, 41, 41, 41, -219,
+ -219
+
+ },
+
+ {
+ 5, -220, -220, -220, -220, -220, -220, -220, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 243, 41, 41, 41, 41, -220,
+ -220
+ },
+
+ {
+ 5, -221, -221, -221, -221, -221, -221, -221, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 244, 41, 41, 41, 41, 41, -221,
+ -221
+
+ },
+
+ {
+ 5, -222, -222, -222, -222, -222, -222, -222, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 245, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -222,
+ -222
+ },
+
+ {
+ 5, -223, -223, -223, -223, -223, -223, -223, 41, 41,
+ 41, 41, 41, 41, 41, 246, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -223,
+ -223
+
+ },
+
+ {
+ 5, -224, -224, -224, -224, -224, -224, -224, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -224,
+ -224
+ },
+
+ {
+ 5, -225, -225, -225, -225, -225, -225, -225, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 247, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -225,
+ -225
+
+ },
+
+ {
+ 5, -226, -226, -226, -226, -226, -226, -226, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 248, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -226,
+ -226
+ },
+
+ {
+ 5, -227, -227, -227, -227, -227, -227, -227, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 249, 41, 41, 41, 41, 41, 41, -227,
+ -227
+
+ },
+
+ {
+ 5, -228, -228, -228, -228, -228, -228, -228, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -228,
+ -228
+ },
+
+ {
+ 5, -229, -229, -229, -229, -229, -229, -229, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -229,
+ -229
+
+ },
+
+ {
+ 5, -230, -230, -230, -230, -230, -230, -230, 41, 41,
+ 41, 41, 41, 250, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -230,
+ -230
+ },
+
+ {
+ 5, -231, -231, -231, -231, -231, -231, -231, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 251, 41, 41, 41, 41, 41, 41, 41, -231,
+ -231
+
+ },
+
+ {
+ 5, -232, -232, -232, -232, -232, -232, -232, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 252, 41, 41, 41, 41, 41, -232,
+ -232
+ },
+
+ {
+ 5, -233, -233, -233, -233, -233, -233, -233, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 253, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -233,
+ -233
+
+ },
+
+ {
+ 5, -234, -234, -234, -234, -234, -234, -234, 41, 41,
+ 41, 41, 41, 41, 254, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -234,
+ -234
+ },
+
+ {
+ 5, -235, -235, -235, -235, -235, -235, -235, 41, 41,
+ 41, 41, 255, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -235,
+ -235
+
+ },
+
+ {
+ 5, -236, -236, -236, -236, -236, -236, -236, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 256, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -236,
+ -236
+ },
+
+ {
+ 5, -237, -237, -237, -237, -237, -237, -237, 41, 41,
+ 41, 41, 41, 41, 41, 41, 257, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -237,
+ -237
+
+ },
+
+ {
+ 5, -238, -238, -238, -238, -238, -238, -238, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -238,
+ -238
+ },
+
+ {
+ 5, -239, -239, -239, -239, -239, -239, -239, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -239,
+ -239
+
+ },
+
+ {
+ 5, -240, -240, -240, -240, -240, -240, -240, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 258,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -240,
+ -240
+ },
+
+ {
+ 5, -241, -241, -241, -241, -241, -241, -241, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -241,
+ -241
+
+ },
+
+ {
+ 5, -242, -242, -242, -242, -242, -242, -242, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 259, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -242,
+ -242
+ },
+
+ {
+ 5, -243, -243, -243, -243, -243, -243, -243, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 260, 41, 41, 41, 41, 41, 41, 41, -243,
+ -243
+
+ },
+
+ {
+ 5, -244, -244, -244, -244, -244, -244, -244, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 261, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -244,
+ -244
+ },
+
+ {
+ 5, -245, -245, -245, -245, -245, -245, -245, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 262, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -245,
+ -245
+
+ },
+
+ {
+ 5, -246, -246, -246, -246, -246, -246, -246, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 263, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -246,
+ -246
+ },
+
+ {
+ 5, -247, -247, -247, -247, -247, -247, -247, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 264, 41, 41, 41, 41, 41, 41, -247,
+ -247
+
+ },
+
+ {
+ 5, -248, -248, -248, -248, -248, -248, -248, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 265, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -248,
+ -248
+ },
+
+ {
+ 5, -249, -249, -249, -249, -249, -249, -249, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 266, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -249,
+ -249
+
+ },
+
+ {
+ 5, -250, -250, -250, -250, -250, -250, -250, 41, 41,
+ 41, 41, 41, 41, 41, 41, 267, 268, 41, 269,
+ 270, 41, 41, 41, 41, 41, 41, 41, 41, 271,
+ 41, 41, 272, 273, 41, 41, 41, 41, 41, -250,
+ -250
+ },
+
+ {
+ 5, -251, -251, -251, -251, -251, -251, -251, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 274, 41, 41, 41, 41, 41, 41, -251,
+ -251
+
+ },
+
+ {
+ 5, -252, -252, -252, -252, -252, -252, -252, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 275, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -252,
+ -252
+ },
+
+ {
+ 5, -253, -253, -253, -253, -253, -253, -253, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 276, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -253,
+ -253
+
+ },
+
+ {
+ 5, -254, -254, -254, -254, -254, -254, -254, 41, 41,
+ 41, 41, 41, 41, 41, 277, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -254,
+ -254
+ },
+
+ {
+ 5, -255, -255, -255, -255, -255, -255, -255, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 278, 41, 41, 41, 41, 41, 41, 41, -255,
+ -255
+
+ },
+
+ {
+ 5, -256, -256, -256, -256, -256, -256, -256, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -256,
+ -256
+ },
+
+ {
+ 5, -257, -257, -257, -257, -257, -257, -257, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 279, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -257,
+ -257
+
+ },
+
+ {
+ 5, -258, -258, -258, -258, -258, -258, -258, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 280, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -258,
+ -258
+ },
+
+ {
+ 5, -259, -259, -259, -259, -259, -259, -259, 41, 41,
+ 41, 41, 41, 41, 41, 281, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -259,
+ -259
+
+ },
+
+ {
+ 5, -260, -260, -260, -260, -260, -260, -260, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 282, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -260,
+ -260
+ },
+
+ {
+ 5, -261, -261, -261, -261, -261, -261, -261, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 283, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -261,
+ -261
+
+ },
+
+ {
+ 5, -262, -262, -262, -262, -262, -262, -262, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 284, 41, 41, 41, 41, 41, 41, -262,
+ -262
+ },
+
+ {
+ 5, -263, -263, -263, -263, -263, -263, -263, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 285, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -263,
+ -263
+
+ },
+
+ {
+ 5, -264, -264, -264, -264, -264, -264, -264, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -264,
+ -264
+ },
+
+ {
+ 5, -265, -265, -265, -265, -265, -265, -265, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -265,
+ -265
+
+ },
+
+ {
+ 5, -266, -266, -266, -266, -266, -266, -266, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 286, 41, 41, 41, 41, 41, 41, -266,
+ -266
+ },
+
+ {
+ 5, -267, -267, -267, -267, -267, -267, -267, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 287, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -267,
+ -267
+
+ },
+
+ {
+ 5, -268, -268, -268, -268, -268, -268, -268, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 288, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -268,
+ -268
+ },
+
+ {
+ 5, -269, -269, -269, -269, -269, -269, -269, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 289, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -269,
+ -269
+
+ },
+
+ {
+ 5, -270, -270, -270, -270, -270, -270, -270, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 290, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -270,
+ -270
+ },
+
+ {
+ 5, -271, -271, -271, -271, -271, -271, -271, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 291, 41, 41, 41, 41, 41, 41, 41, -271,
+ -271
+
+ },
+
+ {
+ 5, -272, -272, -272, -272, -272, -272, -272, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 292, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 293, -272,
+ -272
+ },
+
+ {
+ 5, -273, -273, -273, -273, -273, -273, -273, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 294, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -273,
+ -273
+
+ },
+
+ {
+ 5, -274, -274, -274, -274, -274, -274, -274, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -274,
+ -274
+ },
+
+ {
+ 5, -275, -275, -275, -275, -275, -275, -275, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 295, 41, 41, 41, 41, 41, 41, -275,
+ -275
+
+ },
+
+ {
+ 5, -276, -276, -276, -276, -276, -276, -276, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 296, 41, 41, 41, 41, 41, 41, 41, -276,
+ -276
+ },
+
+ {
+ 5, -277, -277, -277, -277, -277, -277, -277, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 297, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -277,
+ -277
+
+ },
+
+ {
+ 5, -278, -278, -278, -278, -278, -278, -278, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 298, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -278,
+ -278
+ },
+
+ {
+ 5, -279, -279, -279, -279, -279, -279, -279, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 299, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -279,
+ -279
+
+ },
+
+ {
+ 5, -280, -280, -280, -280, -280, -280, -280, 41, 41,
+ 41, 41, 41, 41, 300, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -280,
+ -280
+ },
+
+ {
+ 5, -281, -281, -281, -281, -281, -281, -281, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 301, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -281,
+ -281
+
+ },
+
+ {
+ 5, -282, -282, -282, -282, -282, -282, -282, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 302, 41, 41, 41, 41, 41, 41, -282,
+ -282
+ },
+
+ {
+ 5, -283, -283, -283, -283, -283, -283, -283, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 303, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -283,
+ -283
+
+ },
+
+ {
+ 5, -284, -284, -284, -284, -284, -284, -284, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 304, 41, 41, 41, 41, 41, -284,
+ -284
+ },
+
+ {
+ 5, -285, -285, -285, -285, -285, -285, -285, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 305, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -285,
+ -285
+
+ },
+
+ {
+ 5, -286, -286, -286, -286, -286, -286, -286, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -286,
+ -286
+ },
+
+ {
+ 5, -287, -287, -287, -287, -287, -287, -287, 41, 41,
+ 41, 41, 41, 41, 306, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -287,
+ -287
+
+ },
+
+ {
+ 5, -288, -288, -288, -288, -288, -288, -288, 41, 41,
+ 41, 41, 41, 41, 41, 41, 307, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 308, 41, 41, 41, 41, 41, 41, -288,
+ -288
+ },
+
+ {
+ 5, -289, -289, -289, -289, -289, -289, -289, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 309, 41, 41, 41, 41, 41, 41, 41, -289,
+ -289
+
+ },
+
+ {
+ 5, -290, -290, -290, -290, -290, -290, -290, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 310, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -290,
+ -290
+ },
+
+ {
+ 5, -291, -291, -291, -291, -291, -291, -291, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 311, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -291,
+ -291
+
+ },
+
+ {
+ 5, -292, -292, -292, -292, -292, -292, -292, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 312, 41, 41, 41, 41, 41, -292,
+ -292
+ },
+
+ {
+ 5, -293, -293, -293, -293, -293, -293, -293, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 313, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -293,
+ -293
+
+ },
+
+ {
+ 5, -294, -294, -294, -294, -294, -294, -294, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 314, 41, 41, 41, 41, 41, 41, 41, -294,
+ -294
+ },
+
+ {
+ 5, -295, -295, -295, -295, -295, -295, -295, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -295,
+ -295
+
+ },
+
+ {
+ 5, -296, -296, -296, -296, -296, -296, -296, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 315, 41, 41, 41, 41, 41, 41, -296,
+ -296
+ },
+
+ {
+ 5, -297, -297, -297, -297, -297, -297, -297, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 316, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -297,
+ -297
+
+ },
+
+ {
+ 5, -298, -298, -298, -298, -298, -298, -298, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 317, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -298,
+ -298
+ },
+
+ {
+ 5, -299, -299, -299, -299, -299, -299, -299, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 318, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -299,
+ -299
+
+ },
+
+ {
+ 5, -300, -300, -300, -300, -300, -300, -300, 41, 41,
+ 41, 41, 41, 41, 41, 319, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -300,
+ -300
+ },
+
+ {
+ 5, -301, -301, -301, -301, -301, -301, -301, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 320, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -301,
+ -301
+
+ },
+
+ {
+ 5, -302, -302, -302, -302, -302, -302, -302, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -302,
+ -302
+ },
+
+ {
+ 5, -303, -303, -303, -303, -303, -303, -303, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -303,
+ -303
+
+ },
+
+ {
+ 5, -304, -304, -304, -304, -304, -304, -304, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -304,
+ -304
+ },
+
+ {
+ 5, -305, -305, -305, -305, -305, -305, -305, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -305,
+ -305
+
+ },
+
+ {
+ 5, -306, -306, -306, -306, -306, -306, -306, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 321, 41, 41, 41, 41, -306,
+ -306
+ },
+
+ {
+ 5, -307, -307, -307, -307, -307, -307, -307, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 322, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -307,
+ -307
+
+ },
+
+ {
+ 5, -308, -308, -308, -308, -308, -308, -308, 41, 41,
+ 41, 41, 41, 41, 41, 41, 323, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -308,
+ -308
+ },
+
+ {
+ 5, -309, -309, -309, -309, -309, -309, -309, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 324, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -309,
+ -309
+
+ },
+
+ {
+ 5, -310, -310, -310, -310, -310, -310, -310, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 325, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -310,
+ -310
+ },
+
+ {
+ 5, -311, -311, -311, -311, -311, -311, -311, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 326, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -311,
+ -311
+
+ },
+
+ {
+ 5, -312, -312, -312, -312, -312, -312, -312, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 327, 41, 41, 41, 41, 41, -312,
+ -312
+ },
+
+ {
+ 5, -313, -313, -313, -313, -313, -313, -313, 41, 41,
+ 41, 41, 41, 41, 41, 328, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -313,
+ -313
+
+ },
+
+ {
+ 5, -314, -314, -314, -314, -314, -314, -314, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 329, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -314,
+ -314
+ },
+
+ {
+ 5, -315, -315, -315, -315, -315, -315, -315, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -315,
+ -315
+
+ },
+
+ {
+ 5, -316, -316, -316, -316, -316, -316, -316, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -316,
+ -316
+ },
+
+ {
+ 5, -317, -317, -317, -317, -317, -317, -317, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -317,
+ -317
+
+ },
+
+ {
+ 5, -318, -318, -318, -318, -318, -318, -318, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 330, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -318,
+ -318
+ },
+
+ {
+ 5, -319, -319, -319, -319, -319, -319, -319, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 331, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -319,
+ -319
+
+ },
+
+ {
+ 5, -320, -320, -320, -320, -320, -320, -320, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 332, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -320,
+ -320
+ },
+
+ {
+ 5, -321, -321, -321, -321, -321, -321, -321, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 333, 41, 41, 41, 41, 41, 41, -321,
+ -321
+
+ },
+
+ {
+ 5, -322, -322, -322, -322, -322, -322, -322, 41, 41,
+ 41, 41, 41, 41, 334, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -322,
+ -322
+ },
+
+ {
+ 5, -323, -323, -323, -323, -323, -323, -323, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 335, 41, 41, 41, 41, 41, 41, 41, -323,
+ -323
+
+ },
+
+ {
+ 5, -324, -324, -324, -324, -324, -324, -324, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 336, 41, 41, 41, 41, -324,
+ -324
+ },
+
+ {
+ 5, -325, -325, -325, -325, -325, -325, -325, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 337, 41, 41, 41, 41, 41, 41, 41, -325,
+ -325
+
+ },
+
+ {
+ 5, -326, -326, -326, -326, -326, -326, -326, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 338,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -326,
+ -326
+ },
+
+ {
+ 5, -327, -327, -327, -327, -327, -327, -327, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 339, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -327,
+ -327
+
+ },
+
+ {
+ 5, -328, -328, -328, -328, -328, -328, -328, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 340, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -328,
+ -328
+ },
+
+ {
+ 5, -329, -329, -329, -329, -329, -329, -329, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 341, 41, 41, 41, 41, 41, 41, -329,
+ -329
+
+ },
+
+ {
+ 5, -330, -330, -330, -330, -330, -330, -330, 41, 41,
+ 41, 41, 41, 41, 41, 41, 342, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -330,
+ -330
+ },
+
+ {
+ 5, -331, -331, -331, -331, -331, -331, -331, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 343, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -331,
+ -331
+
+ },
+
+ {
+ 5, -332, -332, -332, -332, -332, -332, -332, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -332,
+ -332
+ },
+
+ {
+ 5, -333, -333, -333, -333, -333, -333, -333, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 344, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -333,
+ -333
+
+ },
+
+ {
+ 5, -334, -334, -334, -334, -334, -334, -334, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 345, 41, 41, 41, 41, 41, 41, 41, -334,
+ -334
+ },
+
+ {
+ 5, -335, -335, -335, -335, -335, -335, -335, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 346, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -335,
+ -335
+
+ },
+
+ {
+ 5, -336, -336, -336, -336, -336, -336, -336, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 347, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -336,
+ -336
+ },
+
+ {
+ 5, -337, -337, -337, -337, -337, -337, -337, 41, 41,
+ 41, 41, 41, 41, 348, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -337,
+ -337
+
+ },
+
+ {
+ 5, -338, -338, -338, -338, -338, -338, -338, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -338,
+ -338
+ },
+
+ {
+ 5, -339, -339, -339, -339, -339, -339, -339, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 349, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -339,
+ -339
+
+ },
+
+ {
+ 5, -340, -340, -340, -340, -340, -340, -340, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 350, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -340,
+ -340
+ },
+
+ {
+ 5, -341, -341, -341, -341, -341, -341, -341, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -341,
+ -341
+
+ },
+
+ {
+ 5, -342, -342, -342, -342, -342, -342, -342, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 351, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -342,
+ -342
+ },
+
+ {
+ 5, -343, -343, -343, -343, -343, -343, -343, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -343,
+ -343
+
+ },
+
+ {
+ 5, -344, -344, -344, -344, -344, -344, -344, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 352, 41, 41, 41, 41, 41, 41, -344,
+ -344
+ },
+
+ {
+ 5, -345, -345, -345, -345, -345, -345, -345, 41, 41,
+ 41, 41, 41, 41, 353, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -345,
+ -345
+
+ },
+
+ {
+ 5, -346, -346, -346, -346, -346, -346, -346, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 354,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -346,
+ -346
+ },
+
+ {
+ 5, -347, -347, -347, -347, -347, -347, -347, 41, 41,
+ 41, 41, 41, 41, 355, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -347,
+ -347
+
+ },
+
+ {
+ 5, -348, -348, -348, -348, -348, -348, -348, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 356, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -348,
+ -348
+ },
+
+ {
+ 5, -349, -349, -349, -349, -349, -349, -349, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 357, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -349,
+ -349
+
+ },
+
+ {
+ 5, -350, -350, -350, -350, -350, -350, -350, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 358, 41, 41, 41, 41, 41, 41, -350,
+ -350
+ },
+
+ {
+ 5, -351, -351, -351, -351, -351, -351, -351, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -351,
+ -351
+
+ },
+
+ {
+ 5, -352, -352, -352, -352, -352, -352, -352, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -352,
+ -352
+ },
+
+ {
+ 5, -353, -353, -353, -353, -353, -353, -353, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 359, 41, 41, 41, 41, 41, -353,
+ -353
+
+ },
+
+ {
+ 5, -354, -354, -354, -354, -354, -354, -354, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 360, 41, 41, 41, 41, 41, -354,
+ -354
+ },
+
+ {
+ 5, -355, -355, -355, -355, -355, -355, -355, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 361, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -355,
+ -355
+
+ },
+
+ {
+ 5, -356, -356, -356, -356, -356, -356, -356, 41, 41,
+ 41, 41, 41, 362, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -356,
+ -356
+ },
+
+ {
+ 5, -357, -357, -357, -357, -357, -357, -357, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 363, 41, 41, 41, 41, 41, 41, -357,
+ -357
+
+ },
+
+ {
+ 5, -358, -358, -358, -358, -358, -358, -358, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -358,
+ -358
+ },
+
+ {
+ 5, -359, -359, -359, -359, -359, -359, -359, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 364, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -359,
+ -359
+
+ },
+
+ {
+ 5, -360, -360, -360, -360, -360, -360, -360, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 365, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -360,
+ -360
+ },
+
+ {
+ 5, -361, -361, -361, -361, -361, -361, -361, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -361,
+ -361
+
+ },
+
+ {
+ 5, -362, -362, -362, -362, -362, -362, -362, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 366, 41, 41, 41, 41, 41, 41, -362,
+ -362
+ },
+
+ {
+ 5, -363, -363, -363, -363, -363, -363, -363, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -363,
+ -363
+
+ },
+
+ {
+ 5, -364, -364, -364, -364, -364, -364, -364, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 367, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -364,
+ -364
+ },
+
+ {
+ 5, -365, -365, -365, -365, -365, -365, -365, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 368, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -365,
+ -365
+
+ },
+
+ {
+ 5, -366, -366, -366, -366, -366, -366, -366, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 369, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -366,
+ -366
+ },
+
+ {
+ 5, -367, -367, -367, -367, -367, -367, -367, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 370, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -367,
+ -367
+
+ },
+
+ {
+ 5, -368, -368, -368, -368, -368, -368, -368, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 371, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -368,
+ -368
+ },
+
+ {
+ 5, -369, -369, -369, -369, -369, -369, -369, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 372, 41, 41, 41, 41, 41, -369,
+ -369
+
+ },
+
+ {
+ 5, -370, -370, -370, -370, -370, -370, -370, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 373, 41, 41, 41, 41, 41, 41, -370,
+ -370
+ },
+
+ {
+ 5, -371, -371, -371, -371, -371, -371, -371, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 374, 41, 41, 41, 41, 41, 41, -371,
+ -371
+
+ },
+
+ {
+ 5, -372, -372, -372, -372, -372, -372, -372, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 375, 41, 41, 41, 41, 41, -372,
+ -372
+ },
+
+ {
+ 5, -373, -373, -373, -373, -373, -373, -373, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -373,
+ -373
+
+ },
+
+ {
+ 5, -374, -374, -374, -374, -374, -374, -374, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -374,
+ -374
+ },
+
+ {
+ 5, -375, -375, -375, -375, -375, -375, -375, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 376, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -375,
+ -375
+
+ },
+
+ {
+ 5, -376, -376, -376, -376, -376, -376, -376, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 377, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -376,
+ -376
+ },
+
+ {
+ 5, -377, -377, -377, -377, -377, -377, -377, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 378, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -377,
+ -377
+
+ },
+
+ {
+ 5, -378, -378, -378, -378, -378, -378, -378, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 379, 41, 41, 41, 41, 41, 41, -378,
+ -378
+ },
+
+ {
+ 5, -379, -379, -379, -379, -379, -379, -379, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, -379,
+ -379
+
+ },
+
+ } ;
+
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yytext_ptr -= yy_more_len; \
+ yyleng = (int) (yy_cp - yytext_ptr); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 69
+#define YY_END_OF_BUFFER 70
+static yyconst short int yy_accept[380] =
+ { 0,
+ 0, 0, 0, 0, 70, 68, 65, 66, 57, 67,
+ 68, 67, 63, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 68, 60, 61, 65, 57, 59, 56, 63,
+ 64, 64, 64, 64, 64, 5, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 39, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 58, 60,
+ 61, 61, 62, 1, 64, 64, 64, 64, 7, 64,
+ 64, 64, 11, 64, 64, 64, 64, 64, 64, 64,
+
+ 64, 64, 64, 64, 64, 64, 37, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 9, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 36, 64, 64, 64, 64, 64, 47, 64, 50,
+ 64, 52, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 14, 15, 64, 17, 64, 64, 64,
+ 64, 64, 64, 64, 64, 35, 64, 64, 64, 64,
+ 64, 64, 64, 48, 64, 64, 64, 64, 64, 2,
+ 3, 64, 6, 64, 64, 64, 64, 16, 18, 64,
+
+ 20, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 49, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 19, 64, 64, 64, 24, 25, 64,
+ 64, 64, 64, 64, 64, 64, 64, 51, 53, 64,
+ 55, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 45, 64, 64, 64, 64,
+ 64, 64, 64, 21, 22, 64, 64, 64, 64, 64,
+ 64, 64, 64, 38, 40, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 23, 64, 64, 64, 64,
+ 64, 64, 64, 64, 41, 64, 64, 64, 64, 64,
+
+ 64, 8, 10, 12, 13, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 42, 43, 44, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 4, 64, 64, 64, 64, 64, 31, 64, 64,
+ 34, 64, 54, 64, 64, 64, 64, 64, 64, 64,
+ 46, 26, 64, 64, 64, 64, 64, 33, 64, 64,
+ 29, 64, 32, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 27, 28, 64, 64, 64, 64, 30
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 1, 1, 1, 4, 1, 1, 5,
+ 5, 6, 1, 5, 7, 5, 1, 8, 9, 8,
+ 8, 8, 8, 8, 8, 8, 8, 5, 1, 1,
+ 1, 1, 1, 1, 10, 10, 10, 11, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 12,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 5, 1, 5, 1, 13, 1, 14, 15, 16, 17,
+
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 10, 39, 1, 40, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+static int yy_more_flag = 0;
+static int yy_more_len = 0;
+#define yymore() (yy_more_flag = 1)
+#define YY_MORE_ADJ yy_more_len
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "dfgscanner.l"
+#define INITIAL 0
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SCANNER FOR DFG SYNTAX * */
+/* * * */
+/* * $Module: DFG * */
+/* * * */
+/* * Copyright (C) 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+/* $RCSfile$ */
+#line 49 "dfgscanner.l"
+
+#include <ctype.h> /* for isprint */
+#include <errno.h>
+#include "misc.h"
+#include "memory.h"
+#include "symbol.h"
+#include "term.h"
+#include "dfg.h"
+#include "dfgparser.h"
+
+/* defined in dfgparser.y */
+extern NAT dfg_LINENUMBER;
+extern BOOL dfg_IGNORETEXT;
+
+static NAT dfg_CountNewlines(char*);
+
+static __inline__ char* dfg_StringCopy(void)
+{
+ char *copy;
+ copy = (char*) memory_Malloc(yyleng+1);
+ strcpy(copy, yytext);
+ return copy;
+}
+
+/* Force the scanner to read the input character by character */
+#define YY_ALWAYS_INTERACTIVE 1
+/* Omit unused function yyunput */
+#define YY_NO_UNPUT 1
+/* Start conditions */
+#define TXT 1
+
+#line 3709 "dfgscanner.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 84 "dfgscanner.l"
+
+
+#line 3863 "dfgscanner.c"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_more_len = 0;
+ if ( yy_more_flag )
+ {
+ yy_more_len = yy_c_buf_p - yytext_ptr;
+ yy_more_flag = 0;
+ }
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ while ( (yy_current_state = yy_nxt[yy_current_state][yy_ec[YY_SC_TO_UI(*yy_cp)]]) > 0 )
+ ++yy_cp;
+
+ yy_current_state = -yy_current_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+case 1:
+YY_RULE_SETUP
+#line 86 "dfgscanner.l"
+return DFG_AND;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 87 "dfgscanner.l"
+return DFG_AUTHOR;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 88 "dfgscanner.l"
+return DFG_AXIOMS;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 89 "dfgscanner.l"
+return DFG_BEGPROB;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 90 "dfgscanner.l"
+return DFG_BY;
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 91 "dfgscanner.l"
+return DFG_CLAUSE;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 92 "dfgscanner.l"
+return DFG_CNF;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 93 "dfgscanner.l"
+return DFG_CONJECS;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 94 "dfgscanner.l"
+return DFG_DATE;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 95 "dfgscanner.l"
+return DFG_DESC;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 96 "dfgscanner.l"
+return DFG_DNF;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 97 "dfgscanner.l"
+return DFG_ENDLIST;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 98 "dfgscanner.l"
+return DFG_ENDPROB;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 99 "dfgscanner.l"
+return DFG_EQUAL;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 100 "dfgscanner.l"
+return DFG_EQUIV;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 101 "dfgscanner.l"
+return DFG_EXISTS;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 102 "dfgscanner.l"
+return DFG_FALSE;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 103 "dfgscanner.l"
+return DFG_FORALL;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 104 "dfgscanner.l"
+return DFG_FORMULA;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 105 "dfgscanner.l"
+return DFG_FREELY;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 106 "dfgscanner.l"
+return DFG_FUNC;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 107 "dfgscanner.l"
+return DFG_GENERATED;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 108 "dfgscanner.l"
+return DFG_HYPOTH;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 109 "dfgscanner.l"
+return DFG_IMPLIED;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 110 "dfgscanner.l"
+return DFG_IMPLIES;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 111 "dfgscanner.l"
+return DFG_CLSLIST;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 112 "dfgscanner.l"
+return DFG_DECLLIST;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 113 "dfgscanner.l"
+return DFG_DESCLIST;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 114 "dfgscanner.l"
+return DFG_FORMLIST;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 115 "dfgscanner.l"
+return DFG_GENSET;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 116 "dfgscanner.l"
+return DFG_PRFLIST;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 117 "dfgscanner.l"
+return DFG_SETTINGS;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 118 "dfgscanner.l"
+return DFG_SYMLIST;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 119 "dfgscanner.l"
+return DFG_TERMLIST;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 120 "dfgscanner.l"
+return DFG_LOGIC;
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 121 "dfgscanner.l"
+return DFG_NAME;
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 122 "dfgscanner.l"
+return DFG_NOT;
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 123 "dfgscanner.l"
+return DFG_OPERAT;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 124 "dfgscanner.l"
+return DFG_OR;
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 125 "dfgscanner.l"
+return DFG_PRED;
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 126 "dfgscanner.l"
+return DFG_PRDICAT;
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 127 "dfgscanner.l"
+return DFG_QUANTIF;
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 128 "dfgscanner.l"
+return DFG_SATIS;
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 129 "dfgscanner.l"
+return DFG_DOMPRED;
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 130 "dfgscanner.l"
+return DFG_SETFLAG;
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 131 "dfgscanner.l"
+return DFG_PREC;
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 132 "dfgscanner.l"
+return DFG_SORT;
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 133 "dfgscanner.l"
+return DFG_SORTS;
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 134 "dfgscanner.l"
+return DFG_STATUS;
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 135 "dfgscanner.l"
+return DFG_STEP;
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 136 "dfgscanner.l"
+return DFG_SUBSORT;
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 137 "dfgscanner.l"
+return DFG_TRUE;
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 138 "dfgscanner.l"
+return DFG_UNKNOWN;
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 139 "dfgscanner.l"
+return DFG_UNSATIS;
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 140 "dfgscanner.l"
+return DFG_VERSION;
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 141 "dfgscanner.l"
+return DFG_MINUS1;
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 143 "dfgscanner.l"
+/* one-line comment */
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 144 "dfgscanner.l"
+{ /* Start of multiline comment */
+ if (dfg_IGNORETEXT) {
+ BEGIN(TXT);
+ yymore();
+ } else
+ return DFG_OPENBRACE;
+ }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 151 "dfgscanner.l"
+return DFG_CLOSEBRACE;
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 152 "dfgscanner.l"
+yymore();
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 153 "dfgscanner.l"
+yymore();
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 154 "dfgscanner.l"
+{ BEGIN(INITIAL);
+ dfg_lval.string = dfg_StringCopy();
+ dfg_LINENUMBER += dfg_CountNewlines(yytext);
+ return DFG_TEXT;
+ }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 159 "dfgscanner.l"
+{ unsigned long n;
+ errno = 0;
+ n = strtoul(yytext, NULL, 10);
+ if (errno != 0 || n > INT_MAX) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Number too big in line %d.\n",
+ dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ dfg_lval.number = (int) n;
+ return DFG_NUM;
+ }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 171 "dfgscanner.l"
+{ dfg_lval.string = dfg_StringCopy();
+ return DFG_ID;
+ }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 174 "dfgscanner.l"
+/* ignore */
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 175 "dfgscanner.l"
+dfg_LINENUMBER++;
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 176 "dfgscanner.l"
+return yytext[0];
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 177 "dfgscanner.l"
+{ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Illegal character '");
+ if (isprint((int)yytext[0]))
+ misc_UserErrorReport("%c",yytext[0]);
+ else
+ misc_UserErrorReport("\\x%x", (unsigned int) yytext[0]);
+ misc_UserErrorReport("' in line %d.\n", dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 187 "dfgscanner.l"
+ECHO;
+ YY_BREAK
+#line 4301 "dfgscanner.c"
+ case YY_STATE_EOF(INITIAL):
+ case YY_STATE_EOF(TXT):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+
+ yy_current_state = yy_nxt[yy_current_state][1];
+ yy_is_jam = (yy_current_state <= 0);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 187 "dfgscanner.l"
+
+
+static NAT dfg_CountNewlines(char* Text)
+{
+ NAT result = 0;
+
+ while (*Text != 0) {
+ if (*Text++ == '\n')
+ result++;
+ }
+ return result;
+}
diff --git a/test/spass/doc-proof.c b/test/spass/doc-proof.c
new file mode 100644
index 0000000..dadd698
--- /dev/null
+++ b/test/spass/doc-proof.c
@@ -0,0 +1,247 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * PROOF DOCUMENTATION * */
+/* * * */
+/* * $Module: DOCPROOF * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "doc-proof.h"
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+int dp_DEPTH;
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void dp_Init(void)
+{
+ dp_DEPTH = 0;
+}
+
+
+static void dp_FPrintDFGProof(LIST Clauses, const char *FilePrefix,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/*********************************************************
+ INPUT: A list of clauses representing a proof, a
+ string indicating a file name prefix, a flag
+ store and a precedence.
+ RETURNS: void.
+ EFFECT: Outputs the proof in DFG proof format to
+ <FilePrefix>.prf
+**********************************************************/
+{
+ FILE *Output;
+ CLAUSE Clause;
+ LIST AxClauses,ConClauses,ProofClauses,Scan;
+ char *name;
+
+ AxClauses = ConClauses = ProofClauses = list_Nil();
+
+ name = memory_Malloc(sizeof(char)*(strlen(FilePrefix)+5));
+ sprintf(name,"%s.prf", FilePrefix);
+
+ Output = misc_OpenFile(name,"w");
+
+ fputs("begin_problem(Unknown).\n\n", Output);
+
+ fputs("list_of_descriptions.\n", Output);
+ fputs("name({*", Output);
+ fputs(FilePrefix, Output);
+ fputs("*}).\n", Output);
+ fputs("author({*SPASS ", Output);
+ fputs(misc_VERSION, Output);
+ fputs("*}).\n", Output);
+ fputs("status(unsatisfiable).\n", Output);
+ fputs("description({*File generated by SPASS containing a proof.*}).\n", Output);
+ fputs("end_of_list.\n\n", Output);
+
+ fputs("list_of_symbols.\n", Output);
+ fol_FPrintDFGSignature(Output);
+ fputs("end_of_list.\n\n", Output);
+
+ for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ if (clause_IsFromInput(Clause)) {
+ if (clause_GetFlag(Clause, CONCLAUSE))
+ ConClauses = list_Cons(Clause, ConClauses);
+ else
+ AxClauses = list_Cons(Clause, AxClauses);
+ }
+ else
+ ProofClauses = list_Cons(Clause, ProofClauses);
+ }
+
+ ConClauses = list_NReverse(ConClauses);
+ AxClauses = list_NReverse(AxClauses);
+ ProofClauses = list_NReverse(ProofClauses);
+
+ clause_FPrintCnfDFG(Output, FALSE, AxClauses, ConClauses, Flags, Precedence);
+ fputs("\nlist_of_proof(SPASS).\n", Output);
+ for (Scan=ProofClauses; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ clause_FPrintDFGStep(Output,list_Car(Scan),TRUE);
+ }
+ fputs("end_of_list.\n\n", Output);
+
+ fputs("end_problem.\n\n", Output);
+
+ misc_CloseFile(Output, name);
+ fputs("\nDFG Proof printed to: ", stdout);
+ puts(name);
+
+ list_Delete(ConClauses);
+ list_Delete(AxClauses);
+ list_Delete(ProofClauses);
+ memory_Free(name, sizeof(char)*(strlen(FilePrefix)+5));
+}
+
+LIST dp_PrintProof(PROOFSEARCH Search, LIST Clauses, const char *FilePrefix)
+/*********************************************************
+ INPUT: A proofsearch object, a list of empty clauses and
+ the prefix of the output file name.
+ RETURNS: The list of clauses required for the proof.
+ MEMORY: The returned list must be freed.
+ EFFECT: The proof is printed both to standard output and
+ to the file <FilePrefix>.prf.
+**********************************************************/
+{
+ LIST ProofClauses,Scan,EmptyClauses,AllClauses, ReducedProof;
+ LIST Missing, Incomplete, SplitClauses;
+
+ FLAGSTORE Flags;
+
+ Flags = prfs_Store(Search);
+
+ Missing = pcheck_ConvertParentsInSPASSProof(Search, Clauses);
+
+ if (!list_Empty(Missing)) {
+ puts("\nNOTE: clauses with following numbers have not been found:");
+ for (; !list_Empty(Missing); Missing = list_Pop(Missing))
+ printf("%d ", (int)list_Car(Missing));
+ putchar('\n');
+ }
+
+ EmptyClauses = list_Copy(Clauses);
+ ProofClauses = list_Nil();
+ AllClauses = list_Nconc(list_Copy(prfs_DocProofClauses(Search)),
+ list_Nconc(list_Copy(prfs_UsableClauses(Search)),
+ list_Copy(prfs_WorkedOffClauses(Search))));
+
+ /*
+ * collect proof clauses by noodling upward in the
+ * proof tree, starting from <EmptyClauses>.
+ * Before, add all splitting clauses to avoid gaps in split tree
+ */
+
+ SplitClauses = list_Nil();
+ for (Scan = AllClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (clause_IsFromSplitting(list_Car(Scan)))
+ SplitClauses = list_Cons(list_Car(Scan), SplitClauses);
+
+ /* mark all needed clauses */
+ pcheck_ClauseListRemoveFlag(EmptyClauses, MARKED);
+ pcheck_ClauseListRemoveFlag(AllClauses, MARKED);
+ pcheck_MarkRecursive(EmptyClauses);
+ pcheck_MarkRecursive(SplitClauses);
+
+ /* collect all marked clauses */
+ ProofClauses = list_Nil();
+ for (Scan = AllClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (clause_GetFlag(list_Car(Scan), MARKED))
+ ProofClauses = list_Cons(list_Car(Scan), ProofClauses);
+ }
+
+ /* build reduced proof */
+ ProofClauses = list_Nconc(ProofClauses, list_Copy(EmptyClauses));
+ ProofClauses = pcheck_ClauseNumberMergeSort(ProofClauses);
+ ReducedProof = pcheck_ReduceSPASSProof(ProofClauses);
+
+ dp_SetProofDepth(pcheck_SeqProofDepth(ReducedProof));
+
+ pcheck_ParentPointersToParentNumbers(AllClauses);
+ pcheck_ParentPointersToParentNumbers(Clauses);
+
+ /* check reduced proof for clauses whose parents have been marked as
+ incomplete (HIDDEN flag) by ConvertParentsInSPASSProof */
+
+ Incomplete = list_Nil();
+ for (Scan = ReducedProof; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (clause_GetFlag(list_Car(Scan), HIDDEN))
+ Incomplete = list_Cons(list_Car(Scan), Incomplete);
+ }
+ if (!list_Empty(Incomplete)) {
+ puts("NOTE: Following clauses in reduced proof have incomplete parent sets:");
+ for (Scan = Incomplete; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ printf("%d ", clause_Number(list_Car(Scan)));
+ putchar('\n');
+ }
+
+ printf("\n\nHere is a proof with depth %d, length %d :\n",
+ dp_ProofDepth(), list_Length(ReducedProof));
+ clause_ListPrint(ReducedProof);
+
+ if (flag_GetFlagValue(Flags, flag_FPDFGPROOF))
+ dp_FPrintDFGProof(ReducedProof, FilePrefix, Flags, prfs_Precedence(Search));
+
+ fflush(stdout);
+
+ list_Delete(EmptyClauses);
+ list_Delete(AllClauses);
+ list_Delete(ProofClauses);
+ list_Delete(SplitClauses);
+ list_Delete(Incomplete);
+
+ return ReducedProof;
+}
+
+
+
+
diff --git a/test/spass/doc-proof.h b/test/spass/doc-proof.h
new file mode 100644
index 0000000..327cb4e
--- /dev/null
+++ b/test/spass/doc-proof.h
@@ -0,0 +1,91 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * PROOF DOCUMENTATION * */
+/* * * */
+/* * $Module: DOCPROOF * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _DOC_PROOF_
+#define _DOC_PROOF_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "clause.h"
+#include "st.h"
+#include "sharing.h"
+#include "search.h"
+#include "doc-proof.h"
+#include "proofcheck.h"
+
+/**************************************************************/
+/* Data Structures and Constants */
+/**************************************************************/
+
+extern int dp_DEPTH;
+
+
+/**************************************************************/
+/* Macros */
+/**************************************************************/
+
+static __inline__ int dp_ProofDepth(void)
+{
+ return dp_DEPTH;
+}
+
+static __inline__ void dp_SetProofDepth(int Depth)
+{
+ dp_DEPTH = Depth;
+}
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void dp_Init(void);
+LIST dp_PrintProof(PROOFSEARCH, LIST, const char*);
+
+#endif
diff --git a/test/spass/flags.c b/test/spass/flags.c
new file mode 100644
index 0000000..5cebfc6
--- /dev/null
+++ b/test/spass/flags.c
@@ -0,0 +1,810 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * FLAGS OF SPASS * */
+/* * * */
+/* * $Module: FLAGS * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 35442 $ * */
+/* $State$ * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $ * */
+/* $Author: jeffc $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "flags.h"
+#include "misc.h"
+#include "stringsx.h"
+
+/**************************************************************/
+/* Global Declarations */
+/**************************************************************/
+
+const int flag_CLEAN = -5;
+
+
+/**************************************************************/
+/* File Local Declarations */
+/**************************************************************/
+
+/* Define flag properties */
+typedef struct {
+ int minimum;
+ int maximum;
+ FLAG_TYPE type;
+ const char *name;
+} FLAG_PROPERTY;
+
+
+static FLAGARRAY flag_DEFAULTSTORE;
+static FLAG_PROPERTY flag_PROPERTIES[flag_MAXFLAG];
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+static __inline__ void flag_InitIntern (FLAG_ID Flag, FLAG_TYPE Type,
+ const char *Name, int Value,
+ int Minimum, int Maximum)
+{
+ FLAG_PROPERTY *property;
+
+ flag_CheckFlagIdInRange(Flag);
+
+ property = &(flag_PROPERTIES[Flag]);
+
+ /* Set the flag type */
+ flag_CheckFlagTypeInRange(Type);
+ property->type = Type;
+
+ /* Set flag name */
+ property->name = Name;
+
+ /* Set flag minimum and maximum */
+ property->minimum = Minimum;
+ property->maximum = Maximum;
+
+ /* Set flag value */
+#ifdef CHECK
+ if (Value > Minimum && Value < Maximum) {
+#endif
+
+ flag_DEFAULTSTORE[Flag] = Value;
+
+#ifdef CHECK
+ }
+ else {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In flag_InitIntern: Default value out of range.");
+ misc_ErrorReport("\n Flag: %s. Value: %d.", Name, Value);
+ misc_FinishErrorReport();
+ }
+#endif
+}
+
+void flag_Init(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECT: Sets all default values for known flags.
+ MEMORY: Allocates memory for the default store.
+***************************************************************/
+{
+ /* Autonomous mode */
+ flag_InitIntern(flag_AUTO, flag_UNIQUE, "Auto", flag_AUTOON,
+ flag_AUTOMIN, flag_AUTOMAX);
+
+ /* Set of Support Mode */
+ flag_InitIntern(flag_SOS, flag_UNIQUE, "SOS", flag_SOSOFF,
+ flag_SOSMIN, flag_SOSMAX);
+
+ /* If set input is considered from stdin and printed to stdout */
+ flag_InitIntern(flag_STDIN, flag_UNIQUE, "Stdin", flag_STDINOFF,
+ flag_STDINMIN, flag_STDINMAX);
+
+ /* If set interactive queries are possible */
+ flag_InitIntern(flag_INTERACTIVE, flag_UNIQUE, "Interactive", flag_INTERACTIVEOFF,
+ flag_INTERACTIVEMIN, flag_INTERACTIVEMAX);
+
+ /* If set only Flotter CNF-translation is performed */
+ flag_InitIntern(flag_FLOTTER, flag_UNIQUE, "Flotter", flag_FLOTTEROFF,
+ flag_FLOTTERMIN, flag_FLOTTERMAX);
+
+ /* Allowed number of loops, -1 means no restriction */
+ flag_InitIntern(flag_LOOPS, flag_UNIQUE, "Loops", flag_LOOPSUNLIMITED,
+ flag_LOOPSMIN, flag_LOOPSMAX);
+
+ /* Allowed number of splits, -1 means no restriction */
+ flag_InitIntern(flag_SPLITS, flag_UNIQUE, "Splits", flag_SPLITSOFF,
+ flag_SPLITSMIN, flag_SPLITSMAX);
+
+ /* Decides the level of sort usage: if 0 then no sort information is processed,
+ if 1 all negative monadic literals with a variable as its argument are processed,
+ if 2 all negative monadic literals are processed */
+ flag_InitIntern(flag_SORTS, flag_UNIQUE, "Sorts", flag_SORTSOFF,
+ flag_SORTSMIN, flag_SORTSMAX);
+
+ /* ForwardSubsumption output not activated */
+ flag_InitIntern(flag_PSUB, flag_PRINTING, "PSub", flag_PSUBOFF,
+ flag_PSUBMIN, flag_PSUBMAX);
+
+ /* Maximal memory allocation */
+ flag_InitIntern(flag_MEMORY, flag_UNIQUE, "Memory", flag_MEMORYUNLIMITED,
+ flag_MEMORYMIN, flag_MEMORYMAX);
+
+ /* Document static soft typing */
+ flag_InitIntern(flag_DOCSST, flag_PRINTING, "DocSST", flag_DOCSSTOFF,
+ flag_DOCSSTMIN, flag_DOCSSTMAX);
+
+ /* Rewriting output not activated */
+ flag_InitIntern(flag_PREW, flag_PRINTING, "PRew", flag_PREWOFF,
+ flag_PREWMIN, flag_PREWMAX);
+
+ /* Contextual rewriting output not activated */
+ flag_InitIntern(flag_PCRW, flag_PRINTING, "PCRw", flag_PCRWOFF,
+ flag_PCRWMIN, flag_PCRWMAX);
+
+ /* Condensing output not activated */
+ flag_InitIntern(flag_PCON, flag_PRINTING, "PCon", flag_PCONOFF,
+ flag_PCONMIN, flag_PCONMAX);
+
+ /* Assignment Equation Deletion output not activated */
+ flag_InitIntern(flag_PAED, flag_PRINTING, "PAED", flag_PAEDOFF,
+ flag_PAEDMIN, flag_PAEDMAX);
+
+ /* Tautology output not activated */
+ flag_InitIntern(flag_PTAUT, flag_PRINTING, "PTaut", flag_PTAUTOFF,
+ flag_PTAUTMIN, flag_PTAUTMAX);
+
+ /* Output of obvious red. not activated */
+ flag_InitIntern(flag_POBV, flag_PRINTING, "PObv", flag_POBVOFF,
+ flag_POBVMIN, flag_POBVMAX);
+
+ /* SortSimplification output not activated */
+ flag_InitIntern(flag_PSSI, flag_PRINTING, "PSSi", flag_PSSIOFF,
+ flag_PSSIMIN, flag_PSSIMAX);
+
+ /* Static soft typing output not activated */
+ flag_InitIntern(flag_PSST, flag_PRINTING, "PSST", flag_PSSTOFF,
+ flag_PSSTMIN, flag_PSSTMAX);
+
+ /* Proof output not activated */
+ flag_InitIntern(flag_DOCPROOF, flag_UNIQUE, "DocProof", flag_DOCPROOFOFF,
+ flag_DOCPROOFMIN, flag_DOCPROOFMAX);
+
+ /* Matching Replacement Resolution output not activated */
+ flag_InitIntern(flag_PMRR, flag_PRINTING, "PMRR", flag_PMRROFF,
+ flag_PMRRMIN, flag_PMRRMAX);
+
+ /* Unit conflict output not activated */
+ flag_InitIntern(flag_PUNC, flag_PRINTING, "PUnC", flag_PUNCOFF,
+ flag_PUNCMIN, flag_PUNCMAX);
+
+ /* Derived clauses output not activated */
+ flag_InitIntern(flag_PDER, flag_PRINTING, "PDer", flag_PDEROFF,
+ flag_PDERMIN, flag_PDERMAX);
+
+ /* Given clause output activated */
+ flag_InitIntern(flag_PGIVEN, flag_PRINTING, "PGiven", flag_PGIVENON,
+ flag_PGIVENMIN, flag_PGIVENMAX);
+
+ /* If labels are created they are not printed */
+ flag_InitIntern(flag_PLABELS, flag_PRINTING, "PLabels", flag_PLABELSOFF,
+ flag_PLABELSMIN, flag_PLABELSMAX);
+
+ /* Kept clauses output not activated */
+ flag_InitIntern(flag_PKEPT, flag_PRINTING, "PKept", flag_PKEPTOFF,
+ flag_PKEPTMIN, flag_PKEPTMAX);
+
+ /* Split backtrack emphasizing not activated */
+ flag_InitIntern(flag_DOCSPLIT, flag_PRINTING, "DocSplit", flag_DOCSPLITOFF,
+ flag_DOCSPLITMIN, flag_DOCSPLITMAX);
+
+ /* Print information about input clauses */
+ flag_InitIntern(flag_PPROBLEM, flag_PRINTING, "PProblem", flag_PPROBLEMON,
+ flag_PPROBLEMMIN, flag_PPROBLEMMAX);
+
+ /* Print all derived empty clauses */
+ flag_InitIntern(flag_PEMPTYCLAUSE, flag_PRINTING, "PEmptyClause", flag_PEMPTYCLAUSEOFF,
+ flag_PEMPTYCLAUSEMIN, flag_PEMPTYCLAUSEMAX);
+
+ /* Print statistic about memory, clauses */
+ flag_InitIntern(flag_PSTATISTIC, flag_PRINTING, "PStatistic", flag_PSTATISTICON,
+ flag_PSTATISTICMIN, flag_PSTATISTICMAX);
+
+ /* Output saturated set of clauses to file, default no */
+ flag_InitIntern(flag_FPMODEL, flag_PRINTING, "FPModel", flag_FPMODELOFF,
+ flag_FPMODELMIN, flag_FPMODELMAX);
+
+ /* Output proof in DFG format to file, default no */
+ flag_InitIntern(flag_FPDFGPROOF, flag_PRINTING, "FPDFGProof", flag_FPDFGPROOFOFF,
+ flag_FPDFGPROOFMIN, flag_FPDFGPROOFMAX);
+
+ /* Output the actual values of all SPASS flags */
+ flag_InitIntern(flag_PFLAGS, flag_PRINTING, "PFlags", flag_PFLAGSOFF,
+ flag_PFLAGSMIN, flag_PFLAGSMAX);
+
+ /* Optimized skolemization output not activated */
+ flag_InitIntern(flag_POPTSKOLEM, flag_PRINTING, "POptSkolem", flag_POPTSKOLEMOFF,
+ flag_POPTSKOLEMMIN, flag_POPTSKOLEMMAX);
+
+ /* Strong skolemization output not activated */
+ flag_InitIntern(flag_PSTRSKOLEM, flag_PRINTING, "PStrSkolem", flag_PSTRSKOLEMOFF,
+ flag_PSTRSKOLEMMIN, flag_PSTRSKOLEMMAX);
+
+ /* Printing of clauses deleted by bound restriction not activated */
+ flag_InitIntern(flag_PBDC, flag_PRINTING, "PBDC", flag_PBDCOFF,
+ flag_PBDCMIN, flag_PBDCMAX);
+
+ /* Printing of bound increase actions */
+ flag_InitIntern(flag_PBINC, flag_PRINTING, "PBInc", flag_PBINCOFF,
+ flag_PBINCMIN, flag_PBINCMAX);
+
+ /* Application of definitions output activated */
+ flag_InitIntern(flag_PAPPLYDEFS, flag_PRINTING, "PApplyDefs", flag_PAPPLYDEFSOFF,
+ flag_PAPPLYDEFSMIN, flag_PAPPLYDEFSMAX);
+
+ /* Amount of time (seconds) available to SPASS, -1 means arbitrary */
+ flag_InitIntern(flag_TIMELIMIT, flag_UNIQUE, "TimeLimit", flag_TIMELIMITUNLIMITED,
+ flag_TIMELIMITMIN, flag_TIMELIMITMAX);
+
+ /* Select: 0 -> no selection, 1 -> select if multiple maximal literals, 2 -> always select */
+ flag_InitIntern(flag_SELECT, flag_UNIQUE, "Select", flag_SELECTIFSEVERALMAXIMAL,
+ flag_SELECTMIN, flag_SELECTMAX);
+
+ /* Activates the inference rule Empty Sort */
+ flag_InitIntern(flag_IEMS, flag_INFERENCE, "IEmS", flag_EMPTYSORTOFF,
+ flag_EMPTYSORTMIN, flag_EMPTYSORTMAX);
+
+ /* Activates the inference rule Sort Resolution */
+ flag_InitIntern(flag_ISOR, flag_INFERENCE, "ISoR", flag_SORTRESOLUTIONOFF,
+ flag_SORTRESOLUTIONMIN, flag_SORTRESOLUTIONMAX);
+
+ /* Activates the inference rule Equality Resolution */
+ flag_InitIntern(flag_IEQR, flag_INFERENCE, "IEqR", flag_EQUALITYRESOLUTIONOFF,
+ flag_EQUALITYRESOLUTIONMIN, flag_EQUALITYRESOLUTIONMAX);
+
+ /* Activates the inference rule Reflexivity Resolution */
+ flag_InitIntern(flag_IERR, flag_INFERENCE, "IERR", flag_REFLEXIVITYRESOLUTIONOFF,
+ flag_REFLEXIVITYRESOLUTIONMIN, flag_REFLEXIVITYRESOLUTIONMAX);
+
+ /* Activates the inference rule Equality Factoring */
+ flag_InitIntern(flag_IEQF, flag_INFERENCE, "IEqF", flag_EQUALITYFACTORINGOFF,
+ flag_EQUALITYFACTORINGMIN, flag_EQUALITYFACTORINGMAX);
+
+ /* Activates the inference rule Merging Paramodulation */
+ flag_InitIntern(flag_IMPM, flag_INFERENCE, "IMPm", flag_MERGINGPARAMODULATIONOFF,
+ flag_MERGINGPARAMODULATIONMIN, flag_MERGINGPARAMODULATIONMAX);
+
+ /* Activates the inference rule Superposition Right */
+ flag_InitIntern(flag_ISPR, flag_INFERENCE, "ISpR", flag_SUPERPOSITIONRIGHTOFF,
+ flag_SUPERPOSITIONRIGHTMIN, flag_SUPERPOSITIONRIGHTMAX);
+
+ /* Inference rule Ordered Paramodulation not active */
+ flag_InitIntern(flag_IOPM, flag_INFERENCE, "IOPm", flag_ORDEREDPARAMODULATIONOFF,
+ flag_ORDEREDPARAMODULATIONMIN, flag_ORDEREDPARAMODULATIONMAX);
+
+ /* Inference rule Paramodulation not active */
+ flag_InitIntern(flag_ISPM, flag_INFERENCE, "ISPm", flag_STANDARDPARAMODULATIONOFF,
+ flag_STANDARDPARAMODULATIONMIN, flag_STANDARDPARAMODULATIONMAX);
+
+ /* Activates the inference rule Superposition Left */
+ flag_InitIntern(flag_ISPL, flag_INFERENCE, "ISpL", flag_SUPERPOSITIONLEFTOFF,
+ flag_SUPERPOSITIONLEFTMIN, flag_SUPERPOSITIONLEFTMAX);
+
+ /* Activates the inference rule Ordered Resolution */
+ flag_InitIntern(flag_IORE, flag_INFERENCE, "IORe", flag_ORDEREDRESOLUTIONOFF,
+ flag_ORDEREDRESOLUTIONMIN, flag_ORDEREDRESOLUTIONMAX);
+
+ /* Activates the inference rule Standard Resolution */
+ flag_InitIntern(flag_ISRE, flag_INFERENCE, "ISRe", flag_STANDARDRESOLUTIONOFF,
+ flag_STANDARDRESOLUTIONMIN, flag_STANDARDRESOLUTIONMAX);
+
+ /* Activates the inference rule Standard Hyperresolution */
+ flag_InitIntern(flag_ISHY, flag_INFERENCE, "ISHy", flag_STANDARDHYPERRESOLUTIONOFF,
+ flag_STANDARDHYPERRESOLUTIONMIN, flag_STANDARDHYPERRESOLUTIONMAX);
+
+ /* Activates the inference rule Ordered Hyperresolution */
+ flag_InitIntern(flag_IOHY, flag_INFERENCE, "IOHy", flag_ORDEREDHYPERRESOLUTIONOFF,
+ flag_ORDEREDHYPERRESOLUTIONMIN, flag_ORDEREDHYPERRESOLUTIONMAX);
+
+ /* Activates the inference rule UR Resolution */
+ flag_InitIntern(flag_IURR, flag_INFERENCE, "IURR", flag_UNITRESULTINGRESOLUTIONOFF,
+ flag_UNITRESULTINGRESOLUTIONMIN, flag_UNITRESULTINGRESOLUTIONMAX);
+
+ /* Activates the inference rule Ordered Factoring */
+ flag_InitIntern(flag_IOFC, flag_INFERENCE, "IOFc", flag_FACTORINGOFF,
+ flag_FACTORINGMIN, flag_FACTORINGMAX);
+
+ /* Activates the inference rule Standard Factoring */
+ flag_InitIntern(flag_ISFC, flag_INFERENCE, "ISFc", flag_STANDARDFACTORINGOFF,
+ flag_STANDARDFACTORINGMIN, flag_STANDARDFACTORINGMAX);
+
+ /* Activates the inference rule Bounded Unit Resolution */
+ flag_InitIntern(flag_IBUR, flag_INFERENCE, "IBUR", flag_BOUNDEDDEPTHUNITRESOLUTIONOFF,
+ flag_BOUNDEDDEPTHUNITRESOLUTIONMIN, flag_BOUNDEDDEPTHUNITRESOLUTIONMAX);
+
+ /* Activates the inference rule Definition Application */
+ flag_InitIntern(flag_IDEF, flag_INFERENCE, "IDEF", flag_DEFINITIONAPPLICATIONOFF,
+ flag_DEFINITIONAPPLICATIONMIN, flag_DEFINITIONAPPLICATIONMAX);
+
+ /* Activates the inference rule Unit Resolution */
+ flag_InitIntern(flag_IUNR, flag_INFERENCE, "IUnR", flag_UNITRESOLUTIONOFF,
+ flag_UNITRESOLUTIONMIN, flag_UNITRESOLUTIONMAX);
+
+ /* Activates Forward Rewriting */
+ flag_InitIntern(flag_RFREW, flag_REDUCTION, "RFRew", flag_RFREWOFF,
+ flag_RFREWMIN, flag_RFREWMAX);
+
+ /* Activates Backward Rewriting */
+ flag_InitIntern(flag_RBREW, flag_REDUCTION, "RBRew", flag_RBREWOFF,
+ flag_RBREWMIN, flag_RBREWMAX);
+
+ /* Activates Forward Contextual Rewriting */
+ flag_InitIntern(flag_RFCRW, flag_REDUCTION, "RFCRw", flag_RFCRWOFF,
+ flag_RFCRWMIN, flag_RFCRWMAX);
+
+ /* Activates Backward Contextual Rewriting */
+ flag_InitIntern(flag_RBCRW, flag_REDUCTION, "RBCRw", flag_RBCRWOFF,
+ flag_RBCRWMIN, flag_RBCRWMAX);
+
+ /* Activates Unit Conflict */
+ flag_InitIntern(flag_RUNC, flag_REDUCTION, "RUnC", flag_RUNCOFF,
+ flag_RUNCMIN, flag_RUNCMAX);
+
+ /* Activates Terminator */
+ flag_InitIntern(flag_RTER, flag_REDUCTION, "RTer", flag_RTEROFF,
+ flag_RTERMIN, flag_RTERMAX);
+
+ /* Activates Forward Subsumption */
+ flag_InitIntern(flag_RFSUB, flag_REDUCTION, "RFSub", flag_RFSUBOFF,
+ flag_RFSUBMIN, flag_RFSUBMAX);
+
+ /* Activates Backward Subsumption */
+ flag_InitIntern(flag_RBSUB, flag_REDUCTION, "RBSub", flag_RBSUBOFF,
+ flag_RBSUBMIN, flag_RBSUBMAX);
+
+ /* Activates Forward Matching Replacement Resolution */
+ flag_InitIntern(flag_RFMRR, flag_REDUCTION, "RFMRR", flag_RFMRROFF,
+ flag_RFMRRMIN, flag_RFMRRMAX);
+
+ /* Activates Backward Matching Replacement Resolution */
+ flag_InitIntern(flag_RBMRR, flag_REDUCTION, "RBMRR", flag_RBMRROFF,
+ flag_RBMRRMIN, flag_RBMRRMAX);
+
+ /* Activates the reduction rule Obvious Reduction */
+ flag_InitIntern(flag_ROBV, flag_REDUCTION, "RObv", flag_ROBVOFF,
+ flag_ROBVMIN, flag_ROBVMAX);
+
+ /* Activates the reduction rule Tautology */
+ flag_InitIntern(flag_RTAUT, flag_REDUCTION, "RTaut", flag_RTAUTOFF,
+ flag_RTAUTMIN, flag_RTAUTMAX);
+
+ /* Activates the reduction rule Sort Simplification */
+ flag_InitIntern(flag_RSSI, flag_REDUCTION, "RSSi", flag_RSSIOFF,
+ flag_RSSIMIN, flag_RSSIMAX);
+
+ /* Activates static soft typing */
+ flag_InitIntern(flag_RSST, flag_REDUCTION, "RSST", flag_RSSTOFF,
+ flag_RSSTMIN, flag_RSSTMAX);
+
+ /* Activates Assignment Equation Deletion */
+ /* If set to 2 it also eliminates equations */
+ /* that are redundant only in non-trivial domains */
+ flag_InitIntern(flag_RAED, flag_REDUCTION, "RAED", flag_RAEDOFF,
+ flag_RAEDMIN, flag_RAEDMAX);
+
+ /* Activates Condensing */
+ flag_InitIntern(flag_RCON, flag_REDUCTION, "RCon", flag_RCONOFF,
+ flag_RCONMIN, flag_RCONMAX);
+
+ /* Activates reduction of input clauses */
+ flag_InitIntern(flag_RINPUT, flag_UNIQUE, "RInput", flag_RINPUTON,
+ flag_RINPUTMIN, flag_RINPUTMAX);
+
+ /* Activates application of definitions */
+ flag_InitIntern(flag_APPLYDEFS, flag_UNIQUE, "ApplyDefs", flag_APPLYDEFSOFF,
+ flag_APPLYDEFSMIN, flag_APPLYDEFSMAX);
+
+ /* If true usable and worked off are completely interreduced; otherwise only worked off */
+ flag_InitIntern(flag_FULLRED, flag_UNIQUE, "FullRed", flag_FULLREDON,
+ flag_FULLREDMIN, flag_FULLREDMAX);
+
+ /* Activates unit saturation of input clauses */
+ flag_InitIntern(flag_SATINPUT, flag_UNIQUE, "SatInput", flag_SATINPUTOFF,
+ flag_SATINPUTMIN, flag_SATINPUTMAX);
+
+ /* Ratio between weight and depth selection of clauses from usable */
+ flag_InitIntern(flag_WDRATIO, flag_UNIQUE, "WDRatio", 5,
+ flag_WDRATIOMIN, flag_WDRATIOMAX);
+
+ /* Factor to divide the weight of conjecture clauses to prefer them for selection */
+ flag_InitIntern(flag_PREFCON, flag_UNIQUE, "PrefCon", flag_PREFCONUNCHANGED,
+ flag_PREFCONMIN, flag_PREFCONMAX);
+
+ /* Weight of a function symbol; weight of clause is used to select given */
+ flag_InitIntern(flag_FUNCWEIGHT, flag_UNIQUE, "FuncWeight", 1,
+ flag_FUNCWEIGHTMIN, flag_FUNCWEIGHTMAX);
+
+ /* Weight of a variable symbol; weight of clause is used to select given */
+ flag_InitIntern(flag_VARWEIGHT, flag_UNIQUE, "VarWeight", 1,
+ flag_VARWEIGHTMIN, flag_VARWEIGHTMAX);
+
+ /* Prefer the selection of clauses with many variable occurrences */
+ flag_InitIntern(flag_PREFVAR, flag_UNIQUE, "PrefVar", flag_PREFVAROFF,
+ flag_PREFVARMIN, flag_PREFVARMAX);
+
+ /* The type of bound: 0 (no bound) 1 (by clause weight) 2 (by clause term depth) */
+ flag_InitIntern(flag_BOUNDMODE, flag_UNIQUE, "BoundMode", flag_BOUNDMODEUNLIMITED,
+ flag_BOUNDMODEMIN, flag_BOUNDMODEMAX);
+
+ /* The initial bound value, where -1 means no restriction */
+ flag_InitIntern(flag_BOUNDSTART, flag_UNIQUE, "BoundStart", flag_BOUNDSTARTUNLIMITED,
+ flag_BOUNDSTARTMIN, flag_BOUNDSTARTMAX);
+
+ /* The number of bound saturation loops */
+ flag_InitIntern(flag_BOUNDLOOPS, flag_UNIQUE, "BoundLoops", 1,
+ flag_BOUNDLOOPSMIN, flag_BOUNDLOOPSMAX);
+
+ /* Flags for selecting the ordering to use */
+ flag_InitIntern(flag_ORD, flag_UNIQUE, "Ordering", flag_ORDKBO,
+ flag_ORDMIN, flag_ORDMAX);
+
+ /* CNF flag, if set optimized skolemization is performed */
+ flag_InitIntern(flag_CNFOPTSKOLEM, flag_UNIQUE, "CNFOptSkolem", flag_CNFOPTSKOLEMON,
+ flag_CNFOPTSKOLEMMIN, flag_CNFOPTSKOLEMMAX);
+
+ /* CNF flag, restricts the number of optimized skolemization proof steps */
+ flag_InitIntern(flag_CNFPROOFSTEPS, flag_UNIQUE, "CNFProofSteps", 100,
+ flag_CNFPROOFSTEPSMIN, flag_CNFPROOFSTEPSMAX);
+
+ /* CNF flag, if set renaming is performed */
+ flag_InitIntern(flag_CNFRENAMING, flag_UNIQUE, "CNFRenaming", flag_CNFRENAMINGON,
+ flag_CNFRENAMINGMIN, flag_CNFRENAMINGMAX);
+
+ /* CNF flag, if set renaming is printed */
+ flag_InitIntern(flag_CNFPRENAMING, flag_UNIQUE, "CNFPRenaming", flag_CNFPRENAMINGOFF,
+ flag_CNFPRENAMINGMIN, flag_CNFPRENAMINGMAX);
+
+ /* CNF flag, if set strong skolemization is performed */
+ flag_InitIntern(flag_CNFSTRSKOLEM, flag_UNIQUE, "CNFStrSkolem", flag_CNFSTRSKOLEMON,
+ flag_CNFSTRSKOLEMMIN, flag_CNFSTRSKOLEMMAX);
+
+ /* CNF flag, if set reductions on equality literals are performed */
+ flag_InitIntern(flag_CNFFEQREDUCTIONS, flag_UNIQUE, "CNFFEqR", flag_CNFFEQREDUCTIONSON,
+ flag_CNFFEQREDUCTIONSMIN, flag_CNFFEQREDUCTIONSMAX);
+
+ /* dfg2otter flag, if set input options for otter are generated */
+ flag_InitIntern(flag_TDFG2OTTEROPTIONS, flag_UNIQUE, "TDfg2OtterOptions", flag_TDFG2OTTEROPTIONSOFF,
+ flag_TDFG2OTTEROPTIONSMIN, flag_TDFG2OTTEROPTIONSMAX);
+}
+
+
+FLAGSTORE flag_DefaultStore(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Default flag store.
+***************************************************************/
+{
+ return flag_DEFAULTSTORE;
+}
+
+
+void flag_Print(FLAGSTORE Store)
+/**************************************************************
+ INPUT: A FlagStore.
+ RETURNS: Nothing.
+ EFFECT: Prints the values of all flags to stdout.
+***************************************************************/
+{
+ flag_FPrint(stdout, Store);
+}
+
+
+void flag_FPrint(FILE* File, FLAGSTORE Store)
+/**************************************************************
+ INPUT: A File to print to, and a FlagStore.
+ RETURNS: Nothing.
+ EFFECT: Prints the values of all flags to File.
+***************************************************************/
+{
+ FLAG_ID i;
+ char name[30];
+
+ fputs("list_of_settings(SPASS).{*", File);
+
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i+= (FLAG_ID) 3) {
+ sprintf(name,"set_flag(%s,%d).", flag_Name(i), flag_GetFlagValue(Store, i));
+ fprintf(File,"\n %-30s",name);
+ if (i+1 < flag_MAXFLAG) {
+ sprintf(name,"set_flag(%s,%d).", flag_Name(i+ (FLAG_ID) 1), flag_GetFlagValue(Store, i+ (FLAG_ID) 1));
+ fprintf(File," %-30s",name);
+ if (i+2 < flag_MAXFLAG) {
+ sprintf(name," set_flag(%s,%d).", flag_Name(i+ (FLAG_ID) 2), flag_GetFlagValue(Store, i+ (FLAG_ID) 2));
+ fprintf(File," %-30s",name);
+ }
+ }
+ }
+ fputs("*}\nend_of_list.\n", File);
+}
+
+
+BOOL flag_Lookup(const char* String)
+/**************************************************************
+ INPUT: A string <String>.
+ RETURNS: TRUE iff <String> is the string of a known flag.
+***************************************************************/
+{
+ return (flag_Id(String) != -1);
+}
+
+
+FLAG_ID flag_Id(const char* String)
+/**************************************************************
+ INPUT: A string <String>.
+ RETURNS: The identification of the flag <String> if it exists
+ -1 otherwise.
+***************************************************************/
+{
+ FLAG_ID i;
+
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++)
+ if (string_Equal(flag_Name(i), String))
+ return i;
+
+ return (FLAG_ID) -1;
+}
+
+
+const char* flag_Name(FLAG_ID Flag)
+/**************************************************************
+ INPUT: A FlagId.
+ RETURNS: The name of the flag <Flag>.
+ EFFECT: Looks up the name of the flag <Flag> and returns it,
+ if it exists.
+***************************************************************/
+{
+ flag_CheckFlagIdInRange(Flag);
+
+ return(flag_PROPERTIES[Flag].name);
+}
+
+
+int flag_Minimum(FLAG_ID Flag)
+/**************************************************************
+ INPUT: A FlagId.
+ RETURNS: The first integer below the minimal legal value
+ of the flag.
+***************************************************************/
+{
+ flag_CheckFlagIdInRange(Flag);
+
+ return flag_PROPERTIES[Flag].minimum;
+}
+
+
+int flag_Maximum(FLAG_ID Flag)
+/**************************************************************
+ INPUT: A FlagId.
+ RETURNS: The first integer above the maximal legal value
+ of the flag.
+***************************************************************/
+{
+ flag_CheckFlagIdInRange(Flag);
+
+ return flag_PROPERTIES[Flag].maximum;
+}
+
+
+FLAG_TYPE flag_Type(FLAG_ID Flag)
+/**************************************************************
+ INPUT: A FlagId.
+ RETURNS: The flag type.
+***************************************************************/
+{
+ flag_CheckFlagIdInRange(Flag);
+
+ return flag_PROPERTIES[Flag].type;
+}
+
+
+void flag_ClearInferenceRules(FLAGSTORE Store)
+/**************************************************************
+ INPUT: A FlagStore.
+ RETURNS: Nothing.
+ EFFECT: Turns all inference rules off.
+***************************************************************/
+{
+ FLAG_ID i;
+
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+ if (flag_IsInference(i))
+ flag_SetFlagValue(Store, i, flag_OFF);
+ }
+}
+
+
+void flag_ClearReductionRules(FLAGSTORE Store)
+/**************************************************************
+ INPUT: A FlagStore.
+ RETURNS: Nothing.
+ EFFECT: Turns all reduction rules off.
+***************************************************************/
+{
+ FLAG_ID i;
+
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+ if (flag_IsReduction(i)) {
+ flag_SetFlagValue(Store, i, flag_OFF);
+ }
+ }
+}
+
+
+void flag_ClearPrinting(FLAGSTORE Store)
+/**************************************************************
+ INPUT: A FlagStore.
+ RETURNS: Nothing.
+ EFFECT: Turns all printing off.
+***************************************************************/
+{
+
+ FLAG_ID i;
+
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+ if (flag_IsPrinting(i))
+ flag_SetFlagValue(Store, i, flag_OFF);
+ }
+}
+
+
+void flag_SetReductionsToDefaults(FLAGSTORE Store)
+/**************************************************************
+ INPUT: A FlagStore.
+ RETURNS: Nothing.
+ EFFECT: Sets all reduction rules to defaults.
+***************************************************************/
+{
+
+ FLAG_ID i;
+
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+ if (flag_IsReduction(i))
+ flag_SetFlagToDefault(Store, i);
+ }
+}
+
+
+void flag_InitFlotterSubproofFlags(FLAGSTORE Source, FLAGSTORE Target)
+/**************************************************************
+ INPUT: Two flag stores.
+ RETURNS: Nothing.
+ EFFECT: Initializes the flag store <Target> to the values required by a
+ Flotter subproof. The other flag store is needed to take over
+ some flags, e.g. DOCPROOF.
+***************************************************************/
+{
+ /* Deactivate printing */
+ flag_ClearPrinting(Target);
+
+ /* Deactivate inference rules */
+ flag_ClearInferenceRules(Target);
+
+ /* Set reductions to default values */
+ flag_SetReductionsToDefaults(Target);
+
+ flag_SetFlagToDefault(Target, flag_CNFFEQREDUCTIONS);
+ flag_SetFlagToDefault(Target, flag_RINPUT);
+
+ /* Copy flag_DOCPROOF and flag_CNFPROOFSTEPS */
+ flag_TransferFlag(Source, Target, flag_DOCPROOF);
+ flag_TransferFlag(Source, Target, flag_CNFPROOFSTEPS);
+
+ /* Activate BoundedDepthUnitResolution */
+ flag_SetFlagValue(Target, flag_IBUR, flag_BOUNDEDDEPTHUNITRESOLUTIONON);
+
+ /* Activate KBO */
+ flag_SetFlagValue(Target, flag_ORD, flag_ORDKBO);
+
+ /* Transfer Weights for Terms */
+ flag_TransferFlag(Source, Target, flag_FUNCWEIGHT);
+ flag_TransferFlag(Source, Target, flag_VARWEIGHT);
+
+ /* Transfer Selection Strategy, not needed for depth bounded */
+ /* unit resolution (see above) but for other potentially useful inference rules */
+ flag_TransferFlag(Source, Target, flag_SELECT);
+}
+
+
+void flag_InitFlotterFlags(FLAGSTORE Source, FLAGSTORE Target)
+/**************************************************************
+ INPUT: Two flag stores.
+ RETURNS: Nothing.
+ EFFECT: Initalizes the flag store <Target> to the values required by
+ Flotter. The other flag store is needed to set
+ some flags, e.g. DOCPROOF.
+***************************************************************/
+{
+ flag_InitFlotterSubproofFlags(Source, Target);
+
+ /* Set ordering to default value */
+ flag_SetFlagToDefault(Target, flag_ORD);
+
+ /* Set weighting flags to default values */
+ flag_SetFlagToDefault(Target, flag_FUNCWEIGHT);
+ flag_SetFlagToDefault(Target, flag_VARWEIGHT);
+
+ /* Copy given values to diverse flags */
+ flag_TransferFlag(Source, Target, flag_CNFRENAMING);
+ flag_TransferFlag(Source, Target, flag_CNFOPTSKOLEM);
+ flag_TransferFlag(Source, Target, flag_CNFSTRSKOLEM);
+ flag_TransferFlag(Source, Target, flag_PAPPLYDEFS);
+ flag_TransferFlag(Source, Target, flag_PBDC);
+ flag_TransferFlag(Source, Target, flag_PBINC);
+ flag_TransferFlag(Source, Target, flag_CNFPRENAMING);
+ flag_TransferFlag(Source, Target, flag_POPTSKOLEM);
+ flag_TransferFlag(Source, Target, flag_PSTRSKOLEM);
+ flag_TransferFlag(Source, Target, flag_INTERACTIVE);
+}
+
+
+void flag_CheckStore(FLAGSTORE Store)
+/**************************************************************
+ INPUT: A flag store.
+ RETURNS: TRUE is the flag store is in a valid state,
+ FALSE otherwise.
+***************************************************************/
+{
+ FLAG_ID i;
+ FLAG value;
+
+ /* check all flags */
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i ++) {
+ /* Get flag value first. We can't use flag_GetFlagValue() since it
+ prints an error message and exits, if a flag is clean. A flag can
+ be clean, only reading it is an error (for most functions).
+ */
+
+ value = Store[i];
+ if (value != flag_CLEAN) {
+ flag_CheckFlagValueInRange(i,value);
+ }
+ }
+}
diff --git a/test/spass/flags.h b/test/spass/flags.h
new file mode 100644
index 0000000..2a9e1a5
--- /dev/null
+++ b/test/spass/flags.h
@@ -0,0 +1,1117 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * FLAGS OF SPASS * */
+/* * * */
+/* * $Module: FLAGS * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _FLAGS_
+#define _FLAGS_
+
+#include <limits.h>
+#include <stdio.h>
+
+#include "memory.h"
+#include "misc.h"
+
+/**************************************************************/
+/* Data Structures and Constants */
+/**************************************************************/
+
+extern const int flag_CLEAN;
+
+/* Define the legal values for all flags as data types.
+
+ All flags have a minimum and a maximum. Legal values are
+ within that range, *excluding* the minimum, maximum value. By using
+ flag_XXXMIN and flag_XXXMAX we have a simple test for a
+ flag's correctness:
+
+ if
+ flag value <= flag minimum
+ or flag value >= flag maximum
+ then
+ the flag has an illegal state.
+
+ Boolean flags have two legal values:
+ * flag_XXXOFF ( = 0)
+ * flag_XXXON ( = 1)
+*/
+
+/* State definitions for boolean flags */
+typedef enum { flag_OFF = 0,
+ flag_ON = 1
+} FLAG_BOOLEAN;
+
+/* State definitions for flag_APPLYDEFS */
+typedef enum { flag_APPLYDEFSMIN = -1,
+ flag_APPLYDEFSOFF = flag_OFF,
+ flag_APPLYDEFSMAX = INT_MAX
+} FLAG_APPLYDEFSTYPE;
+
+/* State definitions for flag_AUTO */
+typedef enum { flag_AUTOMIN = -1,
+ flag_AUTOOFF = flag_OFF,
+ flag_AUTOON = flag_ON,
+ flag_AUTOMAX
+} FLAG_AUTOTYPE;
+
+/* State definitions for flag_BOUNDLOOPS */
+typedef enum { flag_BOUNDLOOPSMIN = 0,
+ flag_BOUNDLOOPSMAX = INT_MAX
+} FLAG_BOUNDLOOPSTYPE;
+
+/* State definitions for flag_BOUNDMODE */
+typedef enum { flag_BOUNDMODEMIN = -1,
+ flag_BOUNDMODEUNLIMITED,
+ flag_BOUNDMODERESTRICTEDBYWEIGHT,
+ flag_BOUNDMODERESTRICTEDBYDEPTH,
+ flag_BOUNDMODEMAX
+} FLAG_BOUNDMODETYPE;
+
+/* State definitions for flag_BOUNDSTART */
+typedef enum { flag_BOUNDSTARTMIN = -2,
+ flag_BOUNDSTARTUNLIMITED,
+ flag_BOUNDSTARTMAX = INT_MAX
+} FLAG_BOUNDSTARTTYPE;
+
+/* State definitions for flag_CNFFEQREDUCTIONS */
+typedef enum { flag_CNFFEQREDUCTIONSMIN = -1,
+ flag_CNFFEQREDUCTIONSOFF = flag_OFF,
+ flag_CNFFEQREDUCTIONSON = flag_ON,
+ flag_CNFFEQREDUCTIONSMAX
+} FLAG_CNFFEQREDUCTIONSTYPE;
+
+/* State definitions for flag_CNFOPTSKOLEM */
+typedef enum { flag_CNFOPTSKOLEMMIN = -1,
+ flag_CNFOPTSKOLEMOFF = flag_OFF,
+ flag_CNFOPTSKOLEMON = flag_ON,
+ flag_CNFOPTSKOLEMMAX
+} flag_CNFOPTSKOLEMTYPE;
+
+/* State definitions for flag_CNFPRENAMING */
+typedef enum { flag_CNFPRENAMINGMIN = -1,
+ flag_CNFPRENAMINGOFF = flag_OFF,
+ flag_CNFPRENAMINGON = flag_ON,
+ flag_CNFPRENAMINGMAX
+} FLAG_CNFPRENAMINGTYPE;
+
+/* State definitions for flag_CNFPROOFSTEPS */
+typedef enum { flag_CNFPROOFSTEPSMIN = 0,
+ flag_CNFPROOFSTEPSMAX = INT_MAX
+} FLAG_CNFPROOFSTEPSTYPE;
+
+/* State definitions for flag_CNFRENAMING */
+typedef enum { flag_CNFRENAMINGMIN = -1,
+ flag_CNFRENAMINGOFF = flag_OFF,
+ flag_CNFRENAMINGON = flag_ON,
+ flag_CNFRENAMINGMAX
+} FLAG_CNFRENAMINGTYPE;
+
+/* State definitions for flag_CNFSTRSKOLEM */
+typedef enum { flag_CNFSTRSKOLEMMIN = -1,
+ flag_CNFSTRSKOLEMOFF = flag_OFF,
+ flag_CNFSTRSKOLEMON = flag_ON,
+ flag_CNFSTRSKOLEMMAX
+} FLAG_CNFSTRSKOLEMTYPE;
+
+/* State definitions for flag_DOCPROOF */
+typedef enum { flag_DOCPROOFMIN = -1,
+ flag_DOCPROOFOFF = flag_OFF,
+ flag_DOCPROOFON = flag_ON,
+ flag_DOCPROOFMAX
+} FLAG_DOCPROOFTYPE;
+
+/* State definitions for flag_DOCSPLIT */
+typedef enum { flag_DOCSPLITMIN = -1,
+ flag_DOCSPLITOFF = flag_OFF,
+ flag_DOCSPLITON = flag_ON,
+ flag_DOCSPLITMAX
+} FLAG_DOCSPLITTYPE;
+
+/* State definitions for flag_DOCSST */
+typedef enum { flag_DOCSSTMIN = -1,
+ flag_DOCSSTOFF = flag_OFF,
+ flag_DOCSSTON = flag_ON,
+ flag_DOCSSTMAX
+} FLAG_DOCSSTTYPE;
+
+/* State definitions for flag_FLOTTER */
+typedef enum { flag_FLOTTERMIN = -1,
+ flag_FLOTTEROFF = flag_OFF,
+ flag_FLOTTERON = flag_ON,
+ flag_FLOTTERMAX
+} FLAG_FLOTTERTYPE;
+
+/* State definitions for flag_FPDFGPROOF */
+typedef enum { flag_FPDFGPROOFMIN = -1,
+ flag_FPDFGPROOFOFF = flag_OFF,
+ flag_FPDFGPROOFON = flag_ON,
+ flag_FPDFGPROOFMAX
+} FLAG_FPDFGPROOFTYPE;
+
+/* State definitions for flag_FPMODEL */
+typedef enum { flag_FPMODELMIN = -1,
+ flag_FPMODELOFF = flag_OFF,
+ flag_FPMODELALLCLAUSES,
+ flag_FPMODELPOTENTIALLYPRODUCTIVECLAUSES,
+ flag_FPMODELMAX
+} FLAG_FPMODELTYPE;
+
+/* State definitions for flag_FULLRED */
+typedef enum { flag_FULLREDMIN = -1,
+ flag_FULLREDOFF = flag_OFF,
+ flag_FULLREDON = flag_ON,
+ flag_FULLREDMAX
+} FLAG_FULLREDTYPE;
+
+/* State definitions for flag_FUNCWEIGHT */
+typedef enum { flag_FUNCWEIGHTMIN = 0,
+ flag_FUNCWEIGHTMAX = INT_MAX
+} FLAG_FUNCWEIGHTTYPE;
+
+/* State definitions for flag_IBUR */
+typedef enum { flag_BOUNDEDDEPTHUNITRESOLUTIONMIN = -1,
+ flag_BOUNDEDDEPTHUNITRESOLUTIONOFF = flag_OFF,
+ flag_BOUNDEDDEPTHUNITRESOLUTIONON = flag_ON,
+ flag_BOUNDEDDEPTHUNITRESOLUTIONMAX
+} FLAG_IBURTYPE;
+
+/* State definitions for flag_IDEF */
+typedef enum { flag_DEFINITIONAPPLICATIONMIN = -1,
+ flag_DEFINITIONAPPLICATIONOFF = flag_OFF,
+ flag_DEFINITIONAPPLICATIONON = flag_ON,
+ flag_DEFINITIONAPPLICATIONMAX
+} FLAG_IDEFTYPE;
+
+/* State definitions for flag_IEMS */
+typedef enum { flag_EMPTYSORTMIN = -1,
+ flag_EMPTYSORTOFF = flag_OFF,
+ flag_EMPTYSORTON = flag_ON,
+ flag_EMPTYSORTMAX
+} FLAG_IEMSTYPE;
+
+/* State definitions for flag_IEQF */
+typedef enum { flag_EQUALITYFACTORINGMIN = -1,
+ flag_EQUALITYFACTORINGOFF = flag_OFF,
+ flag_EQUALITYFACTORINGON = flag_ON,
+ flag_EQUALITYFACTORINGMAX
+} FLAG_IEQFTYPE;
+
+/* State definitions for flag_IEQR */
+typedef enum { flag_EQUALITYRESOLUTIONMIN = -1,
+ flag_EQUALITYRESOLUTIONOFF = flag_OFF,
+ flag_EQUALITYRESOLUTIONON = flag_ON,
+ flag_EQUALITYRESOLUTIONMAX
+} FLAG_IEQRTYPE;
+
+/* State definitions for flag_IERR */
+typedef enum { flag_REFLEXIVITYRESOLUTIONMIN = -1,
+ flag_REFLEXIVITYRESOLUTIONOFF = flag_OFF,
+ flag_REFLEXIVITYRESOLUTIONON = flag_ON,
+ flag_REFLEXIVITYRESOLUTIONMAX
+} FLAG_IERRTYPE;
+
+/* State definitions for flag_IMPM */
+typedef enum { flag_MERGINGPARAMODULATIONMIN = -1,
+ flag_MERGINGPARAMODULATIONOFF = flag_OFF,
+ flag_MERGINGPARAMODULATIONON = flag_ON,
+ flag_MERGINGPARAMODULATIONMAX
+} FLAG_IMPMTYPE;
+
+/* State definitions for flag_INTERACTIVE */
+typedef enum { flag_INTERACTIVEMIN = -1,
+ flag_INTERACTIVEOFF = flag_OFF,
+ flag_INTERACTIVEON = flag_ON,
+ flag_INTERACTIVEMAX
+} FLAG_INTERACTIVETYPE;
+
+/* State definitions for flag_IOFC */
+typedef enum { flag_FACTORINGMIN = -1,
+ flag_FACTORINGOFF = flag_OFF,
+ flag_FACTORINGONLYRIGHT,
+ flag_FACTORINGRIGHTANDLEFT,
+ flag_FACTORINGMAX
+} FLAG_IOFCTYPE;
+
+/* State definitions for flag_IOHY */
+typedef enum { flag_ORDEREDHYPERRESOLUTIONMIN = -1,
+ flag_ORDEREDHYPERRESOLUTIONOFF = flag_OFF,
+ flag_ORDEREDHYPERRESOLUTIONON = flag_ON,
+ flag_ORDEREDHYPERRESOLUTIONMAX
+} FLAG_IOHYTYPE;
+
+/* State definitions for flag_IOPM */
+typedef enum { flag_ORDEREDPARAMODULATIONMIN = -1,
+ flag_ORDEREDPARAMODULATIONOFF = flag_OFF,
+ flag_ORDEREDPARAMODULATIONON = flag_ON,
+ flag_ORDEREDPARAMODULATIONMAX
+} FLAG_IOPMTYPE;
+
+/* State definitions for flag_IORE */
+typedef enum { flag_ORDEREDRESOLUTIONMIN = -1,
+ flag_ORDEREDRESOLUTIONOFF = flag_OFF,
+ flag_ORDEREDRESOLUTIONNOEQUATIONS,
+ flag_ORDEREDRESOLUTIONWITHEQUATIONS,
+ flag_ORDEREDRESOLUTIONMAX
+} FLAG_IORETYPE;
+
+/* State definitions for flag_ISFC */
+typedef enum { flag_STANDARDFACTORINGMIN = -1,
+ flag_STANDARDFACTORINGOFF = flag_OFF,
+ flag_STANDARDFACTORINGON = flag_ON,
+ flag_STANDARDFACTORINGMAX
+} FLAG_ISFCTYPE;
+
+/* State definitions for flag_ISHY */
+typedef enum { flag_STANDARDHYPERRESOLUTIONMIN = -1,
+ flag_STANDARDHYPERRESOLUTIONOFF = flag_OFF,
+ flag_STANDARDHYPERRESOLUTIONON = flag_ON,
+ flag_STANDARDHYPERRESOLUTIONMAX
+} FLAG_ISHYTYPE;
+
+/* State definitions for flag_ISOR */
+typedef enum { flag_SORTRESOLUTIONMIN = -1,
+ flag_SORTRESOLUTIONOFF = flag_OFF,
+ flag_SORTRESOLUTIONON = flag_ON,
+ flag_SORTRESOLUTIONMAX
+} FLAG_ISORTYPE;
+
+/* State definitions for flag_ISPL */
+typedef enum { flag_SUPERPOSITIONLEFTMIN = -1,
+ flag_SUPERPOSITIONLEFTOFF = flag_OFF,
+ flag_SUPERPOSITIONLEFTON = flag_ON,
+ flag_SUPERPOSITIONLEFTMAX
+} FLAG_ISPLTYPE;
+
+/* State definitions for flag_ISPM */
+typedef enum { flag_STANDARDPARAMODULATIONMIN = -1,
+ flag_STANDARDPARAMODULATIONOFF = flag_OFF,
+ flag_STANDARDPARAMODULATIONON = flag_ON,
+ flag_STANDARDPARAMODULATIONMAX
+} FLAG_ISPMTYPE;
+
+/* State definitions for flag_ISPR */
+typedef enum { flag_SUPERPOSITIONRIGHTMIN = -1,
+ flag_SUPERPOSITIONRIGHTOFF = flag_OFF,
+ flag_SUPERPOSITIONRIGHTON = flag_ON,
+ flag_SUPERPOSITIONRIGHTMAX
+} FLAG_ISPRTYPE;
+
+/* State definitions for flag_ISRE */
+typedef enum { flag_STANDARDRESOLUTIONMIN = -1,
+ flag_STANDARDRESOLUTIONOFF = flag_OFF,
+ flag_STANDARDRESOLUTIONNOEQUATIONS,
+ flag_STANDARDRESOLUTIONWITHEQUATIONS,
+ flag_STANDARDRESOLUTIONMAX
+} FLAG_ISRETYPE;
+
+/* State definitions for flag_IUNR */
+typedef enum { flag_UNITRESOLUTIONMIN = -1,
+ flag_UNITRESOLUTIONOFF = flag_OFF,
+ flag_UNITRESOLUTIONON = flag_ON,
+ flag_UNITRESOLUTIONMAX
+} FLAG_IUNRTYPE;
+
+/* State definitions for flag_IURR */
+typedef enum { flag_UNITRESULTINGRESOLUTIONMIN = -1,
+ flag_UNITRESULTINGRESOLUTIONOFF = flag_OFF,
+ flag_UNITRESULTINGRESOLUTIONON = flag_ON,
+ flag_UNITRESULTINGRESOLUTIONMAX
+} FLAG_IURRTYPE;
+
+/* State definitions for flag_LOOPS */
+typedef enum { flag_LOOPSMIN = -2,
+ flag_LOOPSUNLIMITED,
+ flag_LOOPSMAX = INT_MAX
+} FLAG_LOOPSTYPE;
+
+/* State definitions for flag_MEMORY */
+typedef enum { flag_MEMORYMIN = -2,
+ flag_MEMORYUNLIMITED,
+ flag_MEMORYMAX = INT_MAX
+} FLAG_MEMORYTYPE;
+
+/* State definitions for flag_ORD */
+typedef enum { flag_ORDMIN = -1,
+ flag_ORDKBO,
+ flag_ORDRPOS,
+ flag_ORDMAX
+} FLAG_ORDTYPE;
+
+/* State definitions for flag_PAPPLYDEFS */
+typedef enum { flag_PAPPLYDEFSMIN = -1,
+ flag_PAPPLYDEFSOFF = flag_OFF,
+ flag_PAPPLYDEFSON = flag_ON,
+ flag_PAPPLYDEFSMAX
+} FLAG_PAPPLYDEFSTYPE;
+
+/* State definitions for flag_PBDC */
+typedef enum { flag_PBDCMIN = -1,
+ flag_PBDCOFF = flag_OFF,
+ flag_PBDCON = flag_ON,
+ flag_PBDCMAX
+} FLAG_PBDCTYPE;
+
+/* State definitions for flag_PBINC */
+typedef enum { flag_PBINCMIN = -1,
+ flag_PBINCOFF = flag_OFF,
+ flag_PBINCON = flag_ON,
+ flag_PBINCMAX
+} FLAG_PBINCTYPE;
+
+/* State definitions for flag_PMRR */
+typedef enum { flag_PMRRMIN = -1,
+ flag_PMRROFF = flag_OFF,
+ flag_PMRRON = flag_ON,
+ flag_PMRRMAX
+} FLAG_PMRRTYPE;
+
+/* State definitions for flag_PCON */
+typedef enum { flag_PCONMIN = -1,
+ flag_PCONOFF = flag_OFF,
+ flag_PCONON = flag_ON,
+ flag_PCONMAX
+} FLAG_PCONTYPE;
+
+/* State definitions for flag_PDER */
+typedef enum { flag_PDERMIN = -1,
+ flag_PDEROFF = flag_OFF,
+ flag_PDERON = flag_ON,
+ flag_PDERMAX
+} FLAG_PDERTYPE;
+
+/* State definitions for flag_PEMPTYCLAUSE */
+typedef enum { flag_PEMPTYCLAUSEMIN = -1,
+ flag_PEMPTYCLAUSEOFF = flag_OFF,
+ flag_PEMPTYCLAUSEON = flag_ON,
+ flag_PEMPTYCLAUSEMAX
+} FLAG_PEMPTYCLAUSETYPE;
+
+/* State definitions for flag_PFLAGS */
+typedef enum { flag_PFLAGSMIN = -1,
+ flag_PFLAGSOFF = flag_OFF,
+ flag_PFLAGSON = flag_ON,
+ flag_PFLAGSMAX
+} FLAG_PFLAGSTYPE;
+
+/* State definitions for flag_PGIVEN */
+typedef enum { flag_PGIVENMIN = -1,
+ flag_PGIVENOFF = flag_OFF,
+ flag_PGIVENON = flag_ON,
+ flag_PGIVENMAX
+} FLAG_PGIVENTYPE;
+
+/* State definitions for flag_PKEPT */
+typedef enum { flag_PKEPTMIN = -1,
+ flag_PKEPTOFF = flag_OFF,
+ flag_PKEPTON = flag_ON,
+ flag_PKEPTMAX
+} FLAG_PKEPTTYPE;
+
+/* State definitions for flag_PLABELS */
+typedef enum { flag_PLABELSMIN = -1,
+ flag_PLABELSOFF = flag_OFF,
+ flag_PLABELSON = flag_ON,
+ flag_PLABELSMAX
+} FLAG_PLABELSTYPE;
+
+/* State definitions for flag_POBV */
+typedef enum { flag_POBVMIN = -1,
+ flag_POBVOFF = flag_OFF,
+ flag_POBVON = flag_ON,
+ flag_POBVMAX
+} FLAG_POBVTYPE;
+
+/* State definitions for flag_POPTSKOLEM */
+typedef enum { flag_POPTSKOLEMMIN = -1,
+ flag_POPTSKOLEMOFF = flag_OFF,
+ flag_POPTSKOLEMON = flag_ON,
+ flag_POPTSKOLEMMAX
+} FLAG_POPTSKOLEMTYPE;
+
+/* State definitions for flag_PPROBLEM */
+typedef enum { flag_PPROBLEMMIN = -1,
+ flag_PPROBLEMOFF = flag_OFF,
+ flag_PPROBLEMON = flag_ON,
+ flag_PPROBLEMMAX
+} FLAG_PPROBLEMTYPE;
+
+/* State definitions for flag_PREFCON */
+typedef enum { flag_PREFCONMIN = 0,
+ flag_PREFCONUNCHANGED,
+ flag_PREFCONMAX = INT_MAX
+} FLAG_PREFCONTYPE;
+
+/* State definitions for flag_PREFVAR */
+typedef enum { flag_PREFVARMIN = -1,
+ flag_PREFVAROFF = flag_OFF,
+ flag_PREFVARON = flag_ON,
+ flag_PREFVARMAX
+} FLAG_PREFVARTYPE;
+
+/* State definitions for flag_PREW */
+typedef enum { flag_PREWMIN = -1,
+ flag_PREWOFF = flag_OFF,
+ flag_PREWON = flag_ON,
+ flag_PREWMAX
+} FLAG_PREWTYPE;
+
+/* State definitions for flag_PCRW */
+typedef enum { flag_PCRWMIN = -1,
+ flag_PCRWOFF = flag_OFF,
+ flag_PCRWON = flag_ON,
+ flag_PCRWMAX
+} FLAG_PCRWTYPE;
+
+/* State definitions for flag_PAED */
+typedef enum { flag_PAEDMIN = -1,
+ flag_PAEDOFF = flag_OFF,
+ flag_PAEDON = flag_ON,
+ flag_PAEDMAX
+} FLAG_PAEDTYPE;
+
+/* State definitions for flag_PSSI */
+typedef enum { flag_PSSIMIN = -1,
+ flag_PSSIOFF = flag_OFF,
+ flag_PSSION = flag_ON,
+ flag_PSSIMAX
+} FLAG_PSSITYPE;
+
+/* State definitions for flag_PSST */
+typedef enum { flag_PSSTMIN = -1,
+ flag_PSSTOFF = flag_OFF,
+ flag_PSSTON = flag_ON,
+ flag_PSSTMAX
+} FLAG_PSSTTYPE;
+
+/* State definitions for flag_PSTATISTIC */
+typedef enum { flag_PSTATISTICMIN = -1,
+ flag_PSTATISTICOFF = flag_OFF,
+ flag_PSTATISTICON = flag_ON,
+ flag_PSTATISTICMAX
+} FLAG_PSTATISTICTYPE;
+
+/* State definitions for flag_PSTRSKOLEM */
+typedef enum { flag_PSTRSKOLEMMIN = -1,
+ flag_PSTRSKOLEMOFF = flag_OFF,
+ flag_PSTRSKOLEMON = flag_ON,
+ flag_PSTRSKOLEMMAX
+} FLAG_PSTRSKOLEMTYPE;
+
+/* State definitions for flag_PSUB */
+typedef enum { flag_PSUBMIN = -1,
+ flag_PSUBOFF = flag_OFF,
+ flag_PSUBON = flag_ON,
+ flag_PSUBMAX
+} FLAG_PSUBTYPE;
+
+/* State definitions for flag_PTAUT */
+typedef enum { flag_PTAUTMIN = -1,
+ flag_PTAUTOFF = flag_OFF,
+ flag_PTAUTON = flag_ON,
+ flag_PTAUTMAX
+} FLAG_PTAUTTYPE;
+
+/* State definitions for flag_PUNC */
+typedef enum { flag_PUNCMIN = -1,
+ flag_PUNCOFF = flag_OFF,
+ flag_PUNCON = flag_ON,
+ flag_PUNCMAX
+} FLAG_PUNCTYPE;
+
+/* State definitions for flag_RBMRR */
+typedef enum { flag_RBMRRMIN = -1,
+ flag_RBMRROFF = flag_OFF,
+ flag_RBMRRON = flag_ON,
+ flag_RBMRRMAX
+} FLAG_RBMRRTYPE;
+
+/* State definitions for flag_RBREW */
+typedef enum { flag_RBREWMIN = -1,
+ flag_RBREWOFF = flag_OFF,
+ flag_RBREWON = flag_ON,
+ flag_RBREWMAX
+} FLAG_RBREWTYPE;
+
+/* State definitions for flag_RBCRW */
+typedef enum { flag_RBCRWMIN = -1,
+ flag_RBCRWOFF = flag_OFF,
+ flag_RBCRWON = flag_ON,
+ flag_RBCRWMAX
+} FLAG_RBCRWTYPE;
+
+/* State definitions for flag_RBSUB */
+typedef enum { flag_RBSUBMIN = -1,
+ flag_RBSUBOFF = flag_OFF,
+ flag_RBSUBON = flag_ON,
+ flag_RBSUBMAX
+} FLAG_RBSUBTYPE;
+
+/* State definitions for flag_RCON */
+typedef enum { flag_RCONMIN = -1,
+ flag_RCONOFF = flag_OFF,
+ flag_RCONON = flag_ON,
+ flag_RCONMAX
+} FLAG_RCONTYPE;
+
+/* State definitions for flag_RFMRR */
+typedef enum { flag_RFMRRMIN = -1,
+ flag_RFMRROFF = flag_OFF,
+ flag_RFMRRON = flag_ON,
+ flag_RFMRRMAX
+} FLAG_RFMRRTYPE;
+
+/* State definitions for flag_RFREW */
+typedef enum { flag_RFREWMIN = -1,
+ flag_RFREWOFF = flag_OFF,
+ flag_RFREWON = flag_ON,
+ flag_RFREWMAX
+} FLAG_RFREWTYPE;
+
+/* State definitions for flag_RFCRW */
+typedef enum { flag_RFCRWMIN = -1,
+ flag_RFCRWOFF = flag_OFF,
+ flag_RFCRWON = flag_ON,
+ flag_RFCRWMAX
+} FLAG_RFCRWTYPE;
+
+/* State definitions for flag_RFSUB */
+typedef enum { flag_RFSUBMIN = -1,
+ flag_RFSUBOFF = flag_OFF,
+ flag_RFSUBON = flag_ON,
+ flag_RFSUBMAX
+} FLAG_RFSUBTYPE;
+
+/* State definitions for flag_RINPUT */
+typedef enum { flag_RINPUTMIN = -1,
+ flag_RINPUTOFF = flag_OFF,
+ flag_RINPUTON = flag_ON,
+ flag_RINPUTMAX
+} FLAG_RINPUTTYPE;
+
+/* State definitions for flag_ROBV */
+typedef enum { flag_ROBVMIN = -1,
+ flag_ROBVOFF = flag_OFF,
+ flag_ROBVON = flag_ON,
+ flag_ROBVMAX
+} FLAG_ROBVTYPE;
+
+/* State definitions for flag_RAED */
+typedef enum { flag_RAEDMIN = -1,
+ flag_RAEDOFF = flag_OFF,
+ flag_RAEDSOUND,
+ flag_RAEDPOTUNSOUND,
+ flag_RAEDMAX
+} FLAG_RAEDTYPE;
+
+/* State definitions for flag_RSSI */
+typedef enum { flag_RSSIMIN = -1,
+ flag_RSSIOFF = flag_OFF,
+ flag_RSSION = flag_ON,
+ flag_RSSIMAX
+} FLAG_RSSITYPE;
+
+/* State definitions for flag_RSST */
+typedef enum { flag_RSSTMIN = -1,
+ flag_RSSTOFF = flag_OFF,
+ flag_RSSTON = flag_ON,
+ flag_RSSTMAX
+} FLAG_RSSTTYPE;
+
+/* State definitions for flag_RTAUT */
+typedef enum { flag_RTAUTMIN = -1,
+ flag_RTAUTOFF = flag_OFF,
+ flag_RTAUTSYNTACTIC,
+ flag_RTAUTSEMANTIC,
+ flag_RTAUTMAX
+} FLAG_RTAUTTYPE;
+
+/* State definitions for flag_RTER */
+typedef enum { flag_RTERMIN = -1,
+ flag_RTEROFF = flag_OFF,
+ flag_RTERMAX = INT_MAX
+} FLAG_RTERTYPE;
+
+/* State definitions for flag_RUNC */
+typedef enum { flag_RUNCMIN = -1,
+ flag_RUNCOFF = flag_OFF,
+ flag_RUNCON = flag_ON,
+ flag_RUNCMAX
+} FLAG_RUNCTYPE;
+
+/* State definitions for flag_SATINPUT */
+typedef enum { flag_SATINPUTMIN = -1,
+ flag_SATINPUTOFF = flag_OFF,
+ flag_SATINPUTON = flag_ON,
+ flag_SATINPUTMAX
+} FLAG_SATINPUTTYPE;
+
+/* State definitions for flag_SELECT */
+typedef enum { flag_SELECTMIN = -1,
+ flag_SELECTOFF = flag_OFF,
+ flag_SELECTIFSEVERALMAXIMAL,
+ flag_SELECTALWAYS,
+ flag_SELECTMAX
+} FLAG_SELECTTYPE;
+
+/* State definitions for flag_SORTS */
+typedef enum { flag_SORTSMIN = -1,
+ flag_SORTSOFF = flag_OFF,
+ flag_SORTSMONADICWITHVARIABLE,
+ flag_SORTSMONADICALL,
+ flag_SORTSMAX
+} FLAG_SORTSTYPE;
+
+/* State definitions for flag_SOS */
+typedef enum { flag_SOSMIN = -1,
+ flag_SOSOFF = flag_OFF,
+ flag_SOSON = flag_ON,
+ flag_SOSMAX
+} FLAG_SOSTYPE;
+
+/* State definitions for flag_SPLITS */
+typedef enum { flag_SPLITSMIN = -2,
+ flag_SPLITSUNLIMITED,
+ flag_SPLITSOFF = flag_OFF,
+ flag_SPLITSMAX = INT_MAX
+} FLAG_SPLITSTYPE;
+
+/* State definitions for flag_STDIN */
+typedef enum { flag_STDINMIN = -1,
+ flag_STDINOFF = flag_OFF,
+ flag_STDINON = flag_ON,
+ flag_STDINMAX
+} FLAG_STDINTYPE;
+
+/* State definitions for flag_TDFG2OTTEROPTIONS */
+typedef enum { flag_TDFG2OTTEROPTIONSMIN = -1,
+ flag_TDFG2OTTEROPTIONSOFF = flag_OFF,
+ flag_TDFG2OTTEROPTIONSPROOFCHECK,
+ flag_TDFG2OTTEROPTIONSAUTO,
+ flag_TDFG2OTTEROPTIONSAUTO2,
+ flag_TDFG2OTTEROPTIONSMAX
+} FLAG_TDFG2OTTEROPTIONSTYPE;
+
+/* State definitions for flag_TIMELIMIT */
+typedef enum { flag_TIMELIMITMIN = -2,
+ flag_TIMELIMITUNLIMITED,
+ flag_TIMELIMITMAX = INT_MAX
+} FLAG_TIMELIMITTYPE;
+
+/* State definitions for flag_VARWEIGHT */
+typedef enum { flag_VARWEIGHTMIN = 0,
+ flag_VARWEIGHTMAX = INT_MAX
+} FLAG_VARWEIGHTTYPE;
+
+/* State definitions for flag_WDRATIO */
+typedef enum { flag_WDRATIOMIN = 0,
+ flag_WDRATIOMAX = INT_MAX
+} FLAG_WDRATIOTYPE;
+
+
+/* Define all flags */
+
+typedef enum { flag_AUTO, flag_STDIN, flag_INTERACTIVE, flag_FLOTTER,
+ flag_SOS,
+
+ flag_SPLITS, flag_MEMORY, flag_TIMELIMIT,
+ flag_DOCSST, flag_DOCPROOF,
+ flag_DOCSPLIT, flag_LOOPS, flag_PSUB,
+ flag_PREW, flag_PCRW, flag_PCON,
+ flag_PTAUT, flag_POBV, flag_PSSI,
+ flag_PSST, flag_PMRR, flag_PUNC,
+ flag_PAED,
+
+ flag_PDER, flag_PGIVEN, flag_PLABELS,
+ flag_PKEPT, flag_PPROBLEM, flag_PEMPTYCLAUSE,
+ flag_PSTATISTIC, flag_FPMODEL, flag_FPDFGPROOF,
+ flag_PFLAGS, flag_POPTSKOLEM, flag_PSTRSKOLEM,
+ flag_PBDC, flag_PBINC,
+ flag_PAPPLYDEFS,
+
+ flag_SELECT, flag_RINPUT, flag_SORTS,
+ flag_SATINPUT, flag_WDRATIO, flag_PREFCON,
+ flag_FULLRED,
+ flag_FUNCWEIGHT, flag_VARWEIGHT, flag_PREFVAR,
+ flag_BOUNDMODE, flag_BOUNDSTART,
+ flag_BOUNDLOOPS, flag_APPLYDEFS,
+
+ flag_ORD,
+
+ flag_CNFOPTSKOLEM, flag_CNFSTRSKOLEM, flag_CNFPROOFSTEPS,
+ flag_CNFRENAMING, flag_CNFPRENAMING, flag_CNFFEQREDUCTIONS,
+
+ flag_IEMS, flag_ISOR,
+ flag_IEQR, flag_IERR,
+ flag_IEQF, flag_IMPM, flag_ISPR,
+ flag_IOPM, flag_ISPM,
+ flag_ISPL, flag_IORE, flag_ISRE,
+ flag_ISHY, flag_IOHY, flag_IURR,
+ flag_IOFC, flag_ISFC,
+ flag_IUNR, flag_IBUR, flag_IDEF,
+
+ flag_RFREW, flag_RBREW,
+ flag_RFCRW, flag_RBCRW,
+ flag_RFMRR, flag_RBMRR,
+ flag_ROBV, flag_RUNC, flag_RTER,
+ flag_RTAUT, flag_RSST, flag_RSSI,
+ flag_RFSUB, flag_RBSUB, flag_RAED,
+ flag_RCON,
+
+ flag_TDFG2OTTEROPTIONS,
+
+ flag_MAXFLAG } FLAG_ID; /* flag_MAXFLAG is a final Dummy */
+
+
+/* Define different flag types */
+typedef enum { flag_INFERENCE,
+ flag_PRINTING,
+ flag_REDUCTION,
+ flag_UNIQUE, /* miscellaneous flags */
+ flag_MAXTYPE
+} FLAG_TYPE;
+
+
+/* Define the flag data type */
+typedef int FLAG;
+
+/* Define the internal representation of a flag store */
+typedef FLAG FLAGARRAY[flag_MAXFLAG];
+
+/* Define the flag store */
+typedef FLAG *FLAGSTORE;
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void flag_Init(void);
+void flag_InitFlotterFlags(FLAGSTORE, FLAGSTORE);
+void flag_InitFlotterSubproofFlags(FLAGSTORE, FLAGSTORE);
+FLAGSTORE flag_DefaultStore(void);
+void flag_Print(FLAGSTORE);
+void flag_FPrint(FILE*, FLAGSTORE);
+BOOL flag_Lookup(const char*);
+FLAG_ID flag_Id(const char*);
+const char* flag_Name(FLAG_ID);
+int flag_Minimum(FLAG_ID);
+int flag_Maximum(FLAG_ID);
+FLAG_TYPE flag_Type(FLAG_ID Flag);
+void flag_ClearInferenceRules(FLAGSTORE Store);
+void flag_ClearReductionRules(FLAGSTORE Store);
+void flag_ClearPrinting(FLAGSTORE Store);
+void flag_SetReductionsToDefaults(FLAGSTORE Store);
+void flag_CheckStore(FLAGSTORE Store);
+
+/**************************************************************/
+/* Macros */
+/**************************************************************/
+
+static __inline__ void flag_CheckFlagIdInRange(FLAG_ID FlagId)
+ /* prints an error report if a FLAG_ID is not valid */
+{
+#ifdef CHECK
+ if (FlagId >= flag_MAXFLAG) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In flag_CheckFlagIdInRange: Range of flags exceeded.");
+ misc_FinishErrorReport();
+ }
+#endif
+}
+
+static __inline__ void flag_CheckFlagValueInRange(FLAG_ID FlagId, int Value)
+ /* prints an error report if a flag's value is out of range */
+{
+ flag_CheckFlagIdInRange(FlagId);
+
+ if (Value <= flag_Minimum(FlagId)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Flag value %d is too small for flag %s.\n", Value, flag_Name(FlagId));
+ misc_FinishUserErrorReport();
+ }
+ else
+ if (Value >= flag_Maximum(FlagId)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Flag value %d is too large for flag %s.\n", Value, flag_Name(FlagId));
+ misc_FinishUserErrorReport();
+ }
+}
+
+static __inline__ void flag_CheckFlagTypeInRange(FLAG_TYPE Type)
+ /* prints an error report if a flag's type is out of range */
+{
+#ifdef CHECK
+ if (Type >= flag_MAXTYPE) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In flag_CheckFlagTypeInRange: Range of types exceeded.");
+ misc_FinishErrorReport();
+ }
+#endif
+}
+
+static __inline__ BOOL flag_StoreIsDefaultStore(FLAGSTORE Store)
+ /* returns TRUE if a flag store is the default store, FALSE otherwise */
+{
+ return (BOOL) (Store == flag_DefaultStore());
+}
+
+static __inline__ int flag_GetFlagValue(FLAGSTORE Store, FLAG_ID FlagId)
+{
+ int Value;
+
+ flag_CheckFlagIdInRange(FlagId);
+
+ Value = Store[FlagId];
+#ifdef CHECK
+ if (Value == flag_CLEAN) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In flag_GetFlagValue:");
+ misc_ErrorReport(" Attempt to read undefined flag value.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return Value;
+}
+
+static __inline__ void flag_SetFlagValue(FLAGSTORE Store, FLAG_ID FlagId, int Value)
+{
+#ifdef CHECK
+ if (flag_StoreIsDefaultStore(Store)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In flag_SetFlagValue:");
+ misc_ErrorReport(" Attempt to modify default flag value.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ flag_CheckFlagIdInRange(FlagId);
+
+ flag_CheckFlagValueInRange (FlagId, Value);
+
+ Store[FlagId] = Value;
+}
+
+static __inline__ BOOL flag_ValueIsClean(FLAGSTORE Store, FLAG_ID FlagId)
+{
+#ifdef CHECK
+ flag_CheckFlagIdInRange(FlagId);
+ return (BOOL) (Store[FlagId] == flag_CLEAN);
+#else
+ return (BOOL) (flag_GetFlagValue(Store, FlagId) == flag_CLEAN);
+#endif
+}
+
+static __inline__ void flag_CleanStore(FLAGSTORE Store)
+{
+ int i;
+ for (i = 0; i < flag_MAXFLAG; i++)
+ Store[i] = flag_CLEAN;
+}
+
+
+static __inline__ FLAGSTORE flag_CreateStore(void)
+ /* creates a fresh, clean FLAGSTORE */
+{
+ FLAGSTORE store;
+
+ store = (FLAGSTORE) memory_Malloc(sizeof(FLAGARRAY));
+ flag_CleanStore(store);
+ return store;
+}
+
+
+static __inline__ void flag_DeleteStore(FLAGSTORE Store)
+{
+#ifdef CHECK
+ /* Check if the flag store is a valid state */
+ flag_CheckStore(Store);
+#endif
+
+ memory_Free(Store,sizeof(FLAGARRAY));
+}
+
+
+static __inline__ void flag_InitStoreByDefaults(FLAGSTORE Store)
+{
+ FLAG_ID i;
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++)
+ flag_SetFlagValue(Store, i, flag_GetFlagValue(flag_DefaultStore(),i));
+}
+
+
+static __inline__ void flag_SetFlagToDefault(FLAGSTORE Store, FLAG_ID Flag)
+{
+ flag_SetFlagValue(Store, Flag, flag_GetFlagValue(flag_DefaultStore(), Flag));
+}
+
+
+static __inline__ void flag_TransferFlag(FLAGSTORE Source, FLAGSTORE Destination, FLAG_ID FlagId)
+{
+ flag_SetFlagValue(Destination, FlagId, flag_GetFlagValue(Source, FlagId));
+}
+
+
+static __inline__ void flag_TransferAllFlags(FLAGSTORE Source, FLAGSTORE Destination)
+{
+ FLAG_ID i;
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++)
+ Destination[i] = Source[i];
+}
+
+
+static __inline__ void flag_TransferSetFlags(FLAGSTORE Source, FLAGSTORE Destination)
+{
+ FLAG_ID i;
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++)
+ if (!flag_ValueIsClean(Source,i))
+ flag_TransferFlag(Source, Destination, i);
+}
+
+
+static __inline__ BOOL flag_IsOfType(FLAG_ID Flag, FLAG_TYPE Type)
+/**************************************************************
+ INPUT: A FlagId and a flag type.
+ RETURNS: TRUE is the flag is of given type,
+ FALSE otherwise.
+***************************************************************/
+{
+ flag_CheckFlagIdInRange(Flag);
+ flag_CheckFlagTypeInRange(Type);
+
+ return (BOOL) (flag_Type(Flag) == Type);
+}
+
+
+static __inline__ BOOL flag_IsInference(FLAG_ID Flag)
+/**************************************************************
+ INPUT: A FlagId.
+ RETURNS: TRUE is the flag is an inference flag,
+ FALSE otherwise.
+***************************************************************/
+{
+ flag_CheckFlagIdInRange(Flag);
+
+ return flag_IsOfType(Flag, flag_INFERENCE);
+}
+
+
+static __inline__ BOOL flag_IsReduction(FLAG_ID Flag)
+/**************************************************************
+ INPUT: A FlagId.
+ RETURNS: TRUE is the flag is a reduction flag,
+ FALSE otherwise.
+***************************************************************/
+{
+ flag_CheckFlagIdInRange(Flag);
+
+ return flag_IsOfType(Flag, flag_REDUCTION);
+}
+
+
+static __inline__ BOOL flag_IsPrinting(FLAG_ID Flag)
+/**************************************************************
+ INPUT: A FlagId.
+ RETURNS: TRUE is the flag is a printing flag,
+ FALSE otherwise.
+***************************************************************/
+{
+ flag_CheckFlagIdInRange(Flag);
+
+ return flag_IsOfType(Flag, flag_PRINTING);
+}
+
+
+static __inline__ BOOL flag_IsUnique(FLAG_ID Flag)
+/**************************************************************
+ INPUT: A FlagId.
+ RETURNS: TRUE is the flag is an unique flag,
+ FALSE otherwise.
+***************************************************************/
+{
+ flag_CheckFlagIdInRange(Flag);
+
+ return flag_IsOfType(Flag, flag_UNIQUE);
+}
+
+
+static __inline__ void flag_PrintReductionRules(FLAGSTORE Store)
+/**************************************************************
+ INPUT: A FlagStore.
+ RETURNS: Nothing.
+ EFFECT: Prints the values of all reduction flags to stdout.
+***************************************************************/
+{
+ FLAG_ID i;
+ fputs("\n Reductions: ", stdout);
+
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+ if (flag_IsReduction(i) && flag_GetFlagValue(Store, i))
+ printf("%s=%d ",flag_Name(i), flag_GetFlagValue(Store, i));
+ }
+}
+
+static __inline__ void flag_PrintInferenceRules(FLAGSTORE Store)
+/**************************************************************
+ INPUT: A FlagStore.
+ RETURNS: Nothing.
+ EFFECT: Prints the values of all inference flags to stdout.
+***************************************************************/
+{
+ FLAG_ID i;
+ fputs("\n Inferences: ", stdout);
+
+ for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+ if (flag_IsInference(i) && flag_GetFlagValue(Store, i))
+ printf("%s=%d ",flag_Name(i), flag_GetFlagValue(Store,i));
+ }
+}
+
+#endif
+
+
+
+
+
+
diff --git a/test/spass/foldfg.c b/test/spass/foldfg.c
new file mode 100644
index 0000000..549b92e
--- /dev/null
+++ b/test/spass/foldfg.c
@@ -0,0 +1,2444 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * FIRST ORDER LOGIC SYMBOLS * */
+/* * * */
+/* * $Module: FOL DFG * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#include "foldfg.h"
+#include "flags.h"
+
+
+SYMBOL fol_ALL;
+SYMBOL fol_EXIST;
+SYMBOL fol_AND;
+SYMBOL fol_OR;
+SYMBOL fol_NOT;
+SYMBOL fol_IMPLIES;
+SYMBOL fol_IMPLIED;
+SYMBOL fol_EQUIV;
+SYMBOL fol_VARLIST;
+SYMBOL fol_EQUALITY;
+SYMBOL fol_TRUE;
+SYMBOL fol_FALSE;
+
+LIST fol_SYMBOLS;
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+void fol_Init(BOOL All, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A boolean value determining whether only 'equality' or
+ all fol symbols are created, and a precedence.
+ RETURNS: Nothing.
+ SUMMARY: Initializes the Fol Module.
+ EFFECTS: If <All> then all fol-symbols are created,
+ only 'equality' otherwise.
+ The precedence of the first order logic symbols is set
+ in <Precedence>.
+ CAUTION: MUST BE CALLED BEFORE ANY OTHER fol-FUNCTION.
+***************************************************************/
+{
+ if (All) {
+
+ fol_ALL = symbol_CreateJunctor("forall", 2, symbol_STATLEX, Precedence);
+ fol_EXIST = symbol_CreateJunctor("exists", 2, symbol_STATLEX, Precedence);
+ fol_AND = symbol_CreateJunctor("and", symbol_ArbitraryArity(),
+ symbol_STATLEX, Precedence);
+ fol_OR = symbol_CreateJunctor("or", symbol_ArbitraryArity(),
+ symbol_STATLEX, Precedence);
+ fol_NOT = symbol_CreateJunctor("not", 1, symbol_STATLEX, Precedence);
+ fol_IMPLIES = symbol_CreateJunctor("implies", 2, symbol_STATLEX, Precedence);
+ fol_IMPLIED = symbol_CreateJunctor("implied", 2, symbol_STATLEX, Precedence);
+ fol_EQUIV = symbol_CreateJunctor("equiv", 2, symbol_STATLEX, Precedence);
+ fol_VARLIST = symbol_CreateJunctor("", symbol_ArbitraryArity(),
+ symbol_STATLEX, Precedence);
+ fol_EQUALITY = symbol_CreatePredicate("equal", 2, symbol_STATLEX, Precedence);
+ fol_TRUE = symbol_CreatePredicate("true", 0, symbol_STATLEX, Precedence);
+ fol_FALSE = symbol_CreatePredicate("false", 0, symbol_STATLEX, Precedence);
+
+ fol_SYMBOLS =
+ list_Cons((POINTER)fol_ALL, list_Cons((POINTER)fol_EXIST,
+ list_Cons((POINTER)fol_AND, list_Cons((POINTER)fol_OR,
+ list_Cons((POINTER)fol_NOT,
+ list_Cons((POINTER)fol_IMPLIES, list_Cons((POINTER)fol_IMPLIED,
+ list_Cons((POINTER)fol_EQUIV, list_Cons((POINTER)fol_VARLIST,
+ list_Cons((POINTER)fol_EQUALITY, list_Cons((POINTER)fol_TRUE,
+ list_List((POINTER)fol_FALSE))))))))))));
+ }
+ else {
+ fol_EQUALITY = symbol_CreatePredicate("equal", 2, symbol_STATLEX, Precedence);
+ fol_NOT = symbol_CreateJunctor("not", 1, symbol_STATLEX, Precedence);
+ fol_SYMBOLS = list_Cons((POINTER)fol_NOT, list_List((POINTER)fol_EQUALITY));
+ }
+}
+
+
+SYMBOL fol_IsStringPredefined(const char* String)
+/**************************************************************
+ INPUT: A string.
+ RETURNS: The symbol iff String is a predefined fol string,
+ symbol NULL otherwise
+***************************************************************/
+{
+ LIST Scan;
+ for (Scan=fol_SYMBOLS; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (string_Equal(String, symbol_Name((SYMBOL)list_Car(Scan))))
+ return (SYMBOL)list_Car(Scan);
+ return symbol_Null();
+}
+
+
+TERM fol_CreateQuantifier(SYMBOL Quantifier, LIST VarList, LIST Arguments)
+/**************************************************************
+ INPUT: A symbol (which MUST be a fol quantifier),
+ a list of variables that will be bound, and
+ a list of arguments.
+ RETURNS: A quantified term.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!fol_IsQuantifier(Quantifier)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_CreateQuantifier: Symbol isn't FOL quantifier.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return term_Create(Quantifier, list_Cons(term_Create(fol_Varlist(), VarList),
+ Arguments));
+}
+
+
+TERM fol_CreateQuantifierAddFather(SYMBOL Quantifier, LIST VarList, LIST Arguments)
+/**************************************************************
+ INPUT: A symbol (which MUST be a fol quantifier),
+ a list of variables that will be bound, and
+ a list of arguments.
+ In contrast to fol_CreateQuantifier the superterm members
+ are set for the arguments.
+ RETURNS: A quantified term.
+***************************************************************/
+{
+ return term_CreateAddFather(Quantifier,
+ list_Cons(term_CreateAddFather(fol_Varlist(),
+ VarList),
+ Arguments));
+}
+
+
+TERM fol_ComplementaryTerm(TERM Term)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: The (copied) complementary (in sign) formula of <Term>
+***************************************************************/
+{
+ if (symbol_Equal(term_TopSymbol(Term), fol_Not()))
+ return term_Copy((TERM)list_First(term_ArgumentList(Term)));
+ else
+ return term_Create(fol_Not(), list_List(term_Copy(Term)));
+}
+
+
+LIST fol_GetNonFOLPredicates(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The list of all predicate symbols except the predefined
+ FOL symbols.
+***************************************************************/
+{
+ LIST Result;
+
+ Result = symbol_GetAllPredicates();
+ Result = list_DeleteElementIf(Result, (BOOL (*)(POINTER))fol_IsPredefinedPred);
+ return Result;
+}
+
+
+LIST fol_GetAssignments(TERM Term)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: All assignemnts that occur inside the formula, i.e.,
+ equations of the form "x=t" where "x" does not
+ occur in "t".
+***************************************************************/
+{
+ if (term_IsAtom(Term)) {
+ if (fol_IsAssignment(Term))
+ return list_List(Term);
+ }
+ else
+ if (term_IsComplex(Term)) {
+ LIST Scan,Result;
+ Result = list_Nil();
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ Result = list_Nconc(fol_GetAssignments(list_Car(Scan)),Result);
+ return Result;
+ }
+
+ return list_Nil();
+
+}
+
+static void fol_NormalizeVarsIntern(TERM Formula)
+/**************************************************************
+ INPUT: A sentence.
+ RETURNS: void.
+ EFFECT: The quantifier variables of the formula are
+ normalized, i.e., no two different quantifiers
+ bind the same variable.
+ CAUTION: Desctructive.
+***************************************************************/
+{
+ SYMBOL Top;
+ LIST Scan1;
+
+#ifdef CHECK
+ if (!term_IsTerm(Formula)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_NormalizeVarsIntern: Formula is corrupted.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Top = term_TopSymbol(Formula);
+
+ if (term_IsComplex(Formula)) {
+ if (fol_IsQuantifier(Top)) {
+ SYMBOL Var;
+ LIST OldVars,Scan2;
+ OldVars = list_Nil();
+ for (Scan1=fol_QuantifierVariables(Formula);!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+ Var = term_TopSymbol(list_Car(Scan1));
+ OldVars = list_Nconc(OldVars,list_List((POINTER)term_BindingValue(Var)));
+ term_CreateValueBinding(Var, term_OldMark(), (POINTER)symbol_CreateStandardVariable());
+ }
+ fol_NormalizeVarsIntern(term_SecondArgument(Formula));
+ for (Scan1=fol_QuantifierVariables(Formula),Scan2=OldVars;
+ !list_Empty(Scan1);
+ Scan1=list_Cdr(Scan1),Scan2=list_Cdr(Scan2)) {
+ Var = term_TopSymbol(list_Car(Scan1));
+ term_RplacTop(list_Car(Scan1),(SYMBOL)term_BindingValue(Var));
+ term_CreateValueBinding(Var, term_OldMark(), list_Car(Scan2));
+ }
+ list_Delete(OldVars);
+ }
+ else
+ for (Scan1=term_ArgumentList(Formula);!list_Empty(Scan1);Scan1=list_Cdr(Scan1))
+ fol_NormalizeVarsIntern(list_Car(Scan1));
+ }
+ else
+ if (symbol_IsVariable(Top))
+ term_RplacTop(Formula,(SYMBOL)term_BindingValue(Top));
+
+ return;
+}
+
+
+void fol_NormalizeVars(TERM Formula)
+/**************************************************************
+ INPUT: A sentence.
+ RETURNS: void.
+ EFFECT: The quantifier variables of the formula are
+ normalized, i.e., no two different quantifiers
+ bind the same variable.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ symbol_ResetStandardVarCounter();
+ term_NewMark();
+ fol_NormalizeVarsIntern(Formula);
+}
+
+
+void fol_NormalizeVarsStartingAt(TERM Formula, SYMBOL S)
+/**************************************************************
+ INPUT: A sentence.
+ RETURNS: void.
+ EFFECT: The quantifier variables of the formula are
+ normalized, i.e., no two different quantifiers
+ bind the same variable.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ SYMBOL old = symbol_STANDARDVARCOUNTER;
+ symbol_SetStandardVarCounter(S);
+ term_NewMark();
+ fol_NormalizeVarsIntern(Formula);
+ symbol_SetStandardVarCounter(old);
+}
+
+
+void fol_RemoveImplied(TERM Formula)
+/*********************************************************
+ INPUT: A formula.
+ RETURNS: void.
+ EFFECT: All occurrences of "implied" are replaced by "implies"
+ CAUTION: Destructive.
+*******************************************************/
+{
+ if (!fol_IsLiteral(Formula)) {
+ if (fol_IsQuantifier(term_TopSymbol(Formula)))
+ fol_RemoveImplied(term_SecondArgument(Formula));
+ else {
+ LIST Scan;
+ if (symbol_Equal(term_TopSymbol(Formula),fol_Implied())) {
+ term_RplacTop(Formula,fol_Implies());
+ term_RplacArgumentList(Formula,list_NReverse(term_ArgumentList(Formula)));
+ }
+ for (Scan=term_ArgumentList(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ fol_RemoveImplied(list_Car(Scan));
+ }
+ }
+}
+
+
+BOOL fol_VarOccursFreely(TERM Var,TERM Term)
+/**************************************************************
+ INPUT: A variable and a term.
+ RETURNS: TRUE iff <Var> occurs freely in <Term>
+***************************************************************/
+{
+ LIST Scan;
+ int Stack;
+ SYMBOL Top;
+ BOOL Hit;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !term_IsVariable(Var)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_VarOccursFreely: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Stack = stack_Bottom();
+
+ do {
+ Top = term_TopSymbol(Term);
+ if (term_IsComplex(Term)) {
+ if (fol_IsQuantifier(Top)) {
+ Hit = TRUE;
+ for (Scan=fol_QuantifierVariables(Term);!list_Empty(Scan)&&Hit;Scan=list_Cdr(Scan))
+ if (symbol_Equal(term_TopSymbol(list_Car(Scan)),term_TopSymbol(Var)))
+ Hit = FALSE;
+ if (Hit)
+ stack_Push(list_Cdr(term_ArgumentList(Term)));
+ }
+ else
+ stack_Push(term_ArgumentList(Term));
+ }
+ else {
+ if (symbol_IsVariable(Top) && symbol_Equal(Top,term_TopSymbol(Var))) {
+ stack_SetBottom(Stack);
+ return TRUE;
+ }
+ }
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Term = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return FALSE;
+}
+
+
+LIST fol_FreeVariables(TERM Term)
+/**************************************************************
+ INPUT: A term where we assume that no variable is bound by more than
+ one quantifier in <Term> !!!!!
+ RETURNS: The list of variables occurring in the term. Variables are
+ not (!) copied.
+ Note that there may be many terms with same variable symbol.
+ All Variable terms are newly created.
+***************************************************************/
+{
+ LIST Variables,Scan;
+ int Stack;
+ SYMBOL Top;
+ NAT BoundMark,FreeMark;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || term_InBindingPhase()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_FreeVariables: Illegal input or context.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+
+ Variables = list_Nil();
+ Stack = stack_Bottom();
+ BoundMark = term_ActMark();
+ FreeMark = term_ActMark();
+
+ do {
+ Top = term_TopSymbol(Term);
+ if (term_IsComplex(Term)) {
+ if (fol_IsQuantifier(Top)) {
+ for (Scan=fol_QuantifierVariables(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (!term_VarIsMarked(term_TopSymbol(list_Car(Scan)), FreeMark))
+ term_CreateBinding(term_TopSymbol(list_Car(Scan)), BoundMark);
+ stack_Push(term_ArgumentList(Term)); /* Mark has to be removed ! */
+ stack_Push(list_Cdr(term_ArgumentList(Term)));
+ }
+ else
+ if (symbol_Equal(Top,fol_Varlist())) {
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (!term_VarIsMarked(term_TopSymbol(list_Car(Scan)), FreeMark))
+ term_CreateBinding(term_TopSymbol(list_Car(Scan)), 0); /* Mark has to be removed ! */
+ stack_RplacTop(list_Cdr(stack_Top())); /* Second Argument is Quantifier Arg */
+ }
+ else
+ stack_Push(term_ArgumentList(Term));
+ }
+ else {
+ if (symbol_IsVariable(Top) && !term_VarIsMarked(Top, FreeMark)
+ && !term_VarIsMarked(Top, BoundMark)) {
+ Variables = list_Cons(Term, Variables);
+ term_CreateBinding(Top, FreeMark);
+ }
+ }
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Term = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ term_StopBinding();
+
+ return Variables;
+}
+
+LIST fol_BoundVariables(TERM Term)
+/**************************************************************
+ INPUT: A term
+ RETURNS: The list of bound variables occurring in the term.
+***************************************************************/
+{
+ int stack;
+ LIST result;
+
+ stack = stack_Bottom();
+ result = list_Nil();
+
+ do {
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ result = list_Nconc(result, list_Copy(fol_QuantifierVariables(Term)));
+ stack_Push(list_Cdr(term_ArgumentList(Term)));
+ }
+ else
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+
+ while (!stack_Empty(stack) && list_Empty(stack_Top()))
+ stack_Pop();
+
+ if (!stack_Empty(stack)) {
+ Term = list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(stack));
+ result = term_DeleteDuplicatesFromList(result);
+ return result;
+}
+
+
+void fol_Free(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: void.
+ EFFECT: The memory used by the fol modul is freed.
+***************************************************************/
+{
+ list_Delete(fol_SYMBOLS);
+}
+
+
+BOOL fol_FormulaIsClause(TERM Formula)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: TRUE, if <Formula> is a clause, FALSE otherwise.
+***************************************************************/
+{
+ LIST LitList;
+
+ if (term_TopSymbol(Formula) == fol_ALL)
+ Formula = term_SecondArgument(Formula);
+
+ if (term_TopSymbol(Formula) != fol_OR)
+ return FALSE;
+
+ LitList = term_ArgumentList(Formula);
+
+ while (!list_Empty(LitList)) {
+ if (!fol_IsLiteral(list_Car(LitList)))
+ return FALSE;
+ LitList = list_Cdr(LitList);
+ }
+
+ return TRUE;
+}
+
+
+void fol_FPrintOtterOptions(FILE* File, BOOL Equality,
+ FLAG_TDFG2OTTEROPTIONSTYPE Options)
+/**************************************************************
+ INPUT: A file, a boolean flag and an Flag determining printed options.
+ RETURNS: Nothing.
+ SUMMARY: Prints Otter Options to <File>.
+ If <Equality> then appropriate paramodulation options
+ are possibly added.
+***************************************************************/
+{
+ switch (Options) {
+ case flag_TDFG2OTTEROPTIONSPROOFCHECK:
+ fputs("\nset(process_input).", File);
+ fputs("\nset(binary_res).", File);
+ fputs("\nset(factor).", File);
+ /*fputs("\nassign(pick_given_ratio, 4).", File);*/
+ fputs("\nclear(print_kept).", File);
+ fputs("\nassign(max_seconds, 20).", File);
+ if (Equality) {
+ fputs("\nclear(print_new_demod).", File);
+ fputs("\nclear(print_back_demod).", File);
+ fputs("\nclear(print_back_sub).", File);
+ /*fputs("\nset(knuth_bendix).", File);*/
+ fputs("\nset(para_from).", File);
+ fputs("\nset(para_into).", File);
+ fputs("\nset(para_from_vars).", File);
+ fputs("\nset(back_demod).", File);
+ } /* No break: add auto */
+ case flag_TDFG2OTTEROPTIONSAUTO:
+ fputs("\nset(auto).", File);
+ break;
+ case flag_TDFG2OTTEROPTIONSAUTO2:
+ fputs("\nset(auto2).", File);
+ break;
+ case flag_TDFG2OTTEROPTIONSOFF:
+ /* print nothing */
+ break;
+ default:
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_FPrintOtterOptions: Illegal parameter value %d.",
+ Options);
+ misc_FinishErrorReport();
+ }
+
+ fputs("\n\n",File);
+}
+
+static void fol_FPrintOtterFormula(FILE* File, TERM Formula)
+/**************************************************************
+ INPUT: A file and a formula.
+ RETURNS: Nothing.
+ SUMMARY: Prints the formula in Otter format to <File>.
+***************************************************************/
+{
+ SYMBOL Top;
+
+ Top = term_TopSymbol(Formula);
+
+ if (symbol_IsPredicate(Top)) {
+ if (symbol_Equal(Top, fol_Equality())) {
+ term_FPrintOtterPrefix(File,term_FirstArgument(Formula));
+ fputs(" = ", File);
+ term_FPrintOtterPrefix(File,term_SecondArgument(Formula));
+ }
+ else
+ term_FPrintOtterPrefix(File,Formula);
+ }
+ else {
+ if (fol_IsQuantifier(Top)) {
+ LIST Scan;
+ for (Scan=fol_QuantifierVariables(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ if (symbol_Equal(Top,fol_All()))
+ fputs("all ", File);
+ else
+ fputs("exists ", File);
+ term_FPrintOtterPrefix(File, list_Car(Scan));
+ fputs(" (", File);
+ }
+ fol_FPrintOtterFormula(File, term_SecondArgument(Formula));
+ for (Scan=fol_QuantifierVariables(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ fputs(")", File);
+ }
+ else
+ if (symbol_Equal(Top,fol_Not())) {
+ fputs("- (", File);
+ fol_FPrintOtterFormula(File, term_FirstArgument(Formula));
+ fputs(")", File);
+ }
+ else
+ if (symbol_Equal(Top, fol_And()) || symbol_Equal(Top, fol_Or()) ||
+ symbol_Equal(Top, fol_Equiv()) || symbol_Equal(Top, fol_Implies()) ) {
+ LIST Scan;
+ fputs("(", File);
+ for (Scan=term_ArgumentList(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ if (fol_IsLiteral(list_Car(Scan)))
+ fol_FPrintOtterFormula(File, list_Car(Scan));
+ else {
+ fputs("(", File);
+ fol_FPrintOtterFormula(File, list_Car(Scan));
+ fputs(")", File);
+ }
+ if (!list_Empty(list_Cdr(Scan))) {
+ if (symbol_Equal(Top, fol_And()))
+ fputs(" & ", File);
+ if (symbol_Equal(Top, fol_Or()))
+ fputs(" | ", File);
+ if (symbol_Equal(Top, fol_Equiv()))
+ fputs(" <-> ", File);
+ if (symbol_Equal(Top, fol_Implies()))
+ fputs(" -> ", File);
+ }
+ }
+ fputs(")", File);
+ }
+ }
+}
+
+void fol_FPrintOtter(FILE* File, LIST Formulae, FLAG_TDFG2OTTEROPTIONSTYPE Option)
+/**************************************************************
+ INPUT: A file, a list of pairs (label.formula) and an option flag.
+ RETURNS: Nothing.
+ SUMMARY: Prints a the respective formulae in Otter format to <File>.
+***************************************************************/
+{
+ LIST Scan;
+ BOOL Equality;
+ TERM Formula;
+
+ Equality = FALSE;
+
+ for (Scan=Formulae;!list_Empty(Scan) && !Equality; Scan=list_Cdr(Scan)) {
+ Formula = (TERM)list_PairSecond(list_Car(Scan));
+ Equality = term_ContainsSymbol(Formula, fol_Equality());
+ }
+
+ fol_FPrintOtterOptions(File, Equality, Option);
+
+ if (!list_Empty(Formulae)) {
+ fputs("formula_list(usable).\n", File);
+ if (Equality)
+ fputs("all x (x=x).\n", File);
+ for (Scan=Formulae;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ if (list_PairFirst(list_Car(Scan)) != NULL)
+ fprintf(File,"\n%% %s \n",(char *)list_PairFirst(list_Car(Scan)));
+ fol_FPrintOtterFormula(File,list_PairSecond(list_Car(Scan)));
+ fputs(".\n\n", File);
+ }
+ fputs("end_of_list.\n\n", File);
+ }
+}
+
+
+void fol_FPrintDFGSignature(FILE* File)
+/**************************************************************
+ INPUT: A file stream.
+ RETURNS: Nothing.
+ SUMMARY: Prints all signature symbols in DFG format to the
+ file stream.
+***************************************************************/
+
+{
+ NAT i;
+ SYMBOL symbol;
+ LIST functions, predicates;
+
+ functions = symbol_GetAllFunctions();
+ predicates = fol_GetNonFOLPredicates();
+
+ /* First print the function symbols */
+ if (!list_Empty(functions)) {
+ fputs(" functions[", File);
+ i = 0;
+ do {
+ symbol = (SYMBOL) list_Top(functions);
+ fprintf(File, "(%s, %d)", symbol_Name(symbol), symbol_Arity(symbol));
+ functions = list_Pop(functions);
+ if (!list_Empty(functions))
+ fputs(", ", File);
+ if (i < 15)
+ i++;
+ else {
+ i = 0;
+ fputs("\n\t", File);
+ }
+
+ } while (!list_Empty(functions));
+ fputs("].\n", File);
+ }
+
+ /* Now print the predicate symbols */
+ if (!list_Empty(predicates)) {
+ i = 0;
+ fputs(" predicates[", File);
+ do {
+ symbol = (SYMBOL) list_Top(predicates);
+ fprintf(File, "(%s, %d)", symbol_Name(symbol), symbol_Arity(symbol));
+ predicates = list_Pop(predicates);
+ if (!list_Empty(predicates))
+ fputs(", ", File);
+ if (i < 15)
+ i++;
+ else {
+ i = 0;
+ fputs("\n\t", File);
+ }
+ } while (!list_Empty(predicates));
+ fputs("].\n", File);
+ }
+ list_Delete(predicates);
+ list_Delete(functions);
+}
+
+
+static void fol_TermListFPrintDFG(FILE* File, LIST List)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: Nothing.
+***************************************************************/
+{
+ for (; !list_Empty(List); List=list_Cdr(List)) {
+ fol_FPrintDFG(File,list_Car(List));
+ if (!list_Empty(list_Cdr(List)))
+ putc(',', File);
+ }
+}
+
+
+void fol_FPrintDFG(FILE* File, TERM Term)
+/**************************************************************
+ INPUT: A file and a term.
+ RETURNS: none.
+ SUMMARY: Prints the term in prefix notation to the file.
+ CAUTION: Uses the other fol_Output functions.
+***************************************************************/
+{
+ if (term_IsComplex(Term)) {
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ symbol_FPrint(File,term_TopSymbol(Term));
+ fputs("([", File);
+ fol_TermListFPrintDFG(File,fol_QuantifierVariables(Term));
+ fputs("],", File);
+ fol_FPrintDFG(File, term_SecondArgument(Term));
+ putc(')', File);
+ }
+ else {
+ symbol_FPrint(File,term_TopSymbol(Term));
+ putc('(', File);
+ fol_TermListFPrintDFG(File,term_ArgumentList(Term));
+ putc(')', File);
+ }
+ }
+ else
+ symbol_FPrint(File,term_TopSymbol(Term));
+}
+
+void fol_PrintDFG(TERM Term)
+{
+ fol_FPrintDFG(stdout,Term);
+}
+
+
+void fol_PrintPrecedence(PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A precedence.
+ RETURNS: void
+ EFFECT: Prints the current precedence to stdout,
+ fol symbols are excluded.
+***************************************************************/
+{
+ if (symbol_SignatureExists()) {
+ LIST Symbols, Scan;
+ SYMBOL Symbol;
+ int Index;
+ SIGNATURE S;
+
+ Symbols = list_Nil();
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL) {
+ Symbol = S->info;
+ if ((symbol_IsPredicate(Symbol) || symbol_IsFunction(Symbol)) &&
+ !fol_IsPredefinedPred(Symbol))
+ Symbols = list_Cons((POINTER)Symbol, Symbols);
+ }
+ }
+ Symbols = symbol_SortByPrecedence(Symbols, Precedence);
+ for (Scan = Symbols; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ S = symbol_Signature(symbol_Index((SYMBOL)list_Car(Scan)));
+ fputs(S->name, stdout);
+ if (!list_Empty(list_Cdr(Scan)))
+ fputs(" > ", stdout);
+ }
+ list_Delete(Symbols);
+ }
+}
+
+void fol_FPrintPrecedence(FILE *File, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A file to print to, and a precedence.
+ RETURNS: Nothing.
+ EFFECT: Prints the current precedence as a setting
+ command in DFG syntax to <File>.
+ fol symbols are excluded.
+***************************************************************/
+{
+ if (symbol_SignatureExists()) {
+ LIST Symbols, Scan;
+ SYMBOL Symbol;
+ int Index;
+ SIGNATURE S;
+
+ Symbols = list_Nil();
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL) {
+ Symbol = S->info;
+ if ((symbol_IsPredicate(Symbol) || symbol_IsFunction(Symbol)) &&
+ !fol_IsPredefinedPred(Symbol))
+ Symbols = list_Cons((POINTER)Symbol, Symbols);
+ }
+ }
+ Symbols = symbol_SortByPrecedence(Symbols, Precedence);
+ Index = 0;
+ fputs("set_precedence(", File);
+ for (Scan = Symbols; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ S = symbol_Signature(symbol_Index((SYMBOL)list_Car(Scan)));
+ putc('(', File);
+ fputs(S->name, File);
+ putc(',', File);
+ fprintf(File, "%d", S->weight);
+ putc(',', File);
+ putc((symbol_HasProperty((SYMBOL)list_Car(Scan),ORDRIGHT) ? 'r' :
+ (symbol_HasProperty((SYMBOL)list_Car(Scan),ORDMUL) ? 'm' : 'l')),
+ File);
+ putc(')', File);
+ if (!list_Empty(list_Cdr(Scan)))
+ putc(',', File);
+
+ if (Index > 15) {
+ Index = 0;
+ fputs("\n\t", File);
+ }
+ else
+ Index++;
+ }
+ fputs(").", File);
+ list_Delete(Symbols);
+ }
+}
+
+
+static void fol_FPrintFormulaList(FILE* File, LIST Formulas, const char* Name)
+/**************************************************************
+ INPUT: A file, a list of formulas, a name.
+ EFFECTS: Print a list formulas in DFG format, with given list name.
+ **************************************************************/
+{
+ LIST scan;
+
+ fputs("list_of_formulae(", File);
+ fputs(Name, File);
+ fputs(").\n", File);
+ for (scan = Formulas; !list_Empty(scan); scan= list_Cdr(scan)) {
+ fputs("\tformula(", File);
+ fol_FPrintDFG(File, list_Car(scan));
+ fputs(").\n", File);
+ }
+ fputs("end_of_list.\n\n", File);
+}
+
+
+void fol_FPrintDFGProblem(FILE* File, const char* Name, const char* Author,
+ const char* Status, const char* Description,
+ LIST Axioms, LIST Conjectures)
+/**************************************************************
+ INPUT: A file, two lists of formulas, ??? EK
+ EFFECTS: Prints a complete DFG file containing these lists.
+**************************************************************/
+{
+ fputs("begin_problem(Unknown).\n\n", File);
+
+ fputs("list_of_descriptions.\n", File);
+ fprintf(File,"name(%s).\n",Name);
+ fprintf(File,"author(%s).\n",Author);
+ fprintf(File,"status(%s).\n",Status);
+ fprintf(File,"description(%s).\n",Description);
+ fputs("end_of_list.\n\n", File);
+
+ fputs("list_of_symbols.\n", File);
+ fol_FPrintDFGSignature(File);
+ fputs("end_of_list.\n\n", File);
+
+ fol_FPrintFormulaList(File, Axioms, "axioms");
+ fol_FPrintFormulaList(File, Conjectures, "conjectures");
+
+ fputs("end_problem.\n", File);
+}
+
+
+BOOL fol_AssocEquation(TERM Term, SYMBOL *Result)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: TRUE if the term is an equation defining associativity
+ for some function symbol.
+ EFFECT: If the <Term> is an assoc equation, then <*Result> is
+ assigned the assoc symbol.
+***************************************************************/
+{
+
+ if (fol_IsEquality(Term)) {
+ SYMBOL Top;
+ TERM Left,Right;
+ Left = term_FirstArgument(Term);
+ Right= term_SecondArgument(Term);
+ Top = term_TopSymbol(Left);
+ if (symbol_IsFunction(Top) && symbol_Arity(Top) == 2 &&
+ symbol_Equal(Top,term_TopSymbol(Right))) {
+ SYMBOL v1,v2,v3;
+ if (term_IsVariable(term_FirstArgument(Left)))
+ v1 = term_TopSymbol(term_FirstArgument(Left));
+ else
+ if (term_IsVariable(term_FirstArgument(Right))) {
+ Term = Right;
+ Right = Left;
+ Left = Term;
+ v1 = term_TopSymbol(term_FirstArgument(Left));
+ }
+ else
+ return FALSE;
+ if (symbol_Equal(term_TopSymbol(term_SecondArgument(Left)),Top) &&
+ symbol_IsVariable((v2=term_TopSymbol(term_FirstArgument(term_SecondArgument(Left)))))&&
+ symbol_IsVariable((v3=term_TopSymbol(term_SecondArgument(term_SecondArgument(Left)))))&&
+ symbol_Equal(term_TopSymbol(term_FirstArgument(Right)),Top) &&
+ symbol_Equal(v1,term_TopSymbol(term_FirstArgument(term_FirstArgument(Right)))) &&
+ symbol_Equal(v2,term_TopSymbol(term_SecondArgument(term_FirstArgument(Right)))) &&
+ symbol_Equal(v3,term_TopSymbol(term_SecondArgument(Right)))) {
+ *Result = Top;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+BOOL fol_DistributiveEquation(TERM Term, SYMBOL* Addition,
+ SYMBOL* Multiplication)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: TRUE if the term is an equation defining distributivity
+ for two function symbols, FALSE otherwise.
+ EFFECT: If the function returns TRUE, < Addition> and
+ <Multiplication> return the respective symbols.
+***************************************************************/
+{
+ TERM left, right, help, v1, v2, v3;
+
+ if (!fol_IsEquality(Term))
+ return FALSE;
+
+ left = term_FirstArgument(Term);
+ right = term_SecondArgument(Term);
+
+ if (term_EqualTopSymbols(left, right) ||
+ !symbol_IsFunction(term_TopSymbol(left)) ||
+ !symbol_IsFunction(term_TopSymbol(right)) ||
+ symbol_Arity(term_TopSymbol(left)) != 2 ||
+ symbol_Arity(term_TopSymbol(right)) != 2)
+ return FALSE;
+
+ if (term_IsVariable(term_FirstArgument(left)))
+ v1 = term_FirstArgument(left);
+ else if (term_IsVariable(term_FirstArgument(right))) {
+ help = right; /* Exchange left and right terms */
+ right = left;
+ left = help;
+ v1 = term_FirstArgument(left);
+ } else
+ return FALSE;
+
+ if (!term_EqualTopSymbols(left, term_FirstArgument(right)) ||
+ !term_EqualTopSymbols(left, term_SecondArgument(right)) ||
+ !term_EqualTopSymbols(term_SecondArgument(left), right))
+ return FALSE;
+
+ v2 = term_FirstArgument(term_SecondArgument(left));
+ v3 = term_SecondArgument(term_SecondArgument(left));
+
+ if (term_IsVariable(v2) && term_IsVariable(v3) &&
+ term_EqualTopSymbols(term_FirstArgument(term_FirstArgument(right)), v1) &&
+ term_EqualTopSymbols(term_SecondArgument(term_FirstArgument(right)), v2) &&
+ term_EqualTopSymbols(term_FirstArgument(term_SecondArgument(right)), v1) &&
+ term_EqualTopSymbols(term_SecondArgument(term_SecondArgument(right)), v3)) {
+ *Addition = term_TopSymbol(right);
+ *Multiplication = term_TopSymbol(left);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static LIST fol_InstancesIntern(TERM Formula, TERM ToMatch, NAT Symbols)
+/**************************************************************
+ INPUT: A formula in which all instances of <ToMatch> are searched.
+ The number of symbols of <ToMatch>.
+ RETURNS: The list of found instances.
+ CAUTION: Bound variables must be different, for otherwise the
+ used matching produces wrong results!!
+***************************************************************/
+{
+ NAT HitSymbols;
+ LIST Result;
+ int Stack;
+
+ Stack = stack_Bottom();
+ Result = list_Nil();
+
+ do {
+ HitSymbols = term_Size(Formula); /* First check number of symbols of current formula */
+
+ if (HitSymbols >= Symbols && (Formula != ToMatch)) {
+ cont_StartBinding();
+ if (unify_MatchFlexible(cont_LeftContext(), ToMatch, Formula))
+ Result = list_Cons(Formula, Result);
+ else
+ if (!symbol_IsPredicate(term_TopSymbol(Formula))) {
+ if (fol_IsQuantifier(term_TopSymbol(Formula)))
+ stack_Push(list_Cdr(term_ArgumentList(Formula)));
+ else
+ stack_Push(term_ArgumentList(Formula));
+ }
+ cont_BackTrack();
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Formula = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return Result;
+}
+
+
+LIST fol_Instances(TERM Formula, TERM ToMatch)
+/**************************************************************
+ INPUT: A formula in which all instances of <ToMatch> are searched.
+ RETURNS: The list of found occurrences matched by <ToMatch>.
+ The formula <ToMatch> is not included!
+***************************************************************/
+{
+ NAT Symbols;
+
+ Symbols = term_ComputeSize(ToMatch); /* We use the number of symbols as a filter */
+ term_InstallSize(Formula);
+
+ return fol_InstancesIntern(Formula, ToMatch, Symbols);
+}
+
+
+static LIST fol_GeneralizationsIntern(TERM Formula, TERM MatchedBy, NAT Symbols)
+/**************************************************************
+ INPUT: A formula in which all instances of <ToMatch> are searched.
+ The number of symbols of <ToMatch>.
+ RETURNS: The list of found instances.
+ CAUTION: Bound variables must be different, for otherwise the
+ used matching produces wrong results!!
+***************************************************************/
+{
+ NAT HitSymbols;
+ LIST Result;
+ int Stack;
+
+ Stack = stack_Bottom();
+ Result = list_Nil();
+
+ do {
+ if (Formula != MatchedBy) {
+ HitSymbols = term_Size(Formula); /* First check number of symbols of current formula */
+ if (HitSymbols <= Symbols) {
+ cont_StartBinding();
+ if (unify_MatchFlexible(cont_LeftContext(), Formula, MatchedBy))
+ Result = list_Cons(Formula, Result);
+ else
+ if (!symbol_IsPredicate(term_TopSymbol(Formula))) {
+ if (fol_IsQuantifier(term_TopSymbol(Formula)))
+ stack_Push(list_Cdr(term_ArgumentList(Formula)));
+ else
+ stack_Push(term_ArgumentList(Formula));
+ }
+ cont_BackTrack();
+ }
+ else
+ if (!symbol_IsPredicate(term_TopSymbol(Formula))) {
+ if (fol_IsQuantifier(term_TopSymbol(Formula)))
+ stack_Push(list_Cdr(term_ArgumentList(Formula)));
+ else
+ stack_Push(term_ArgumentList(Formula));
+ }
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Formula = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return Result;
+}
+
+
+LIST fol_Generalizations(TERM Formula, TERM MatchedBy)
+/**************************************************************
+ INPUT: A formula in which all first-order generalizations of <MatchedBy> are searched.
+ RETURNS: The list of found occurrences that are more general than <MatchedBy>.
+ The formula <MatchedBy> is not included!
+***************************************************************/
+{
+ NAT Symbols;
+
+ Symbols = term_ComputeSize(MatchedBy); /* We use the number of symbols as a filter */
+ term_InstallSize(Formula);
+
+ return fol_GeneralizationsIntern(Formula, MatchedBy, Symbols);
+}
+
+
+TERM fol_MostGeneralFormula(LIST Formulas)
+/**************************************************************
+ INPUT: A list of formulas.
+ RETURNS: A most general formula out of the list, i.e., if
+ some formula is returned, there is no formula in the
+ list that is more general than that formula.
+***************************************************************/
+{
+ TERM Result, Candidate;
+ LIST Scan;
+
+#ifdef CHECK
+ if (list_Empty(Formulas)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_MostGeneralFormula: Called with empty list.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Car(Formulas);
+
+ for (Scan=list_Cdr(Formulas);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Candidate = (TERM)list_Car(Scan);
+ cont_StartBinding();
+ if (unify_MatchFlexible(cont_LeftContext(), Candidate, Result))
+ Result = Candidate;
+ cont_BackTrack();
+ }
+
+ return Result;
+}
+
+
+void fol_ReplaceVariable(TERM Term, SYMBOL Symbol, TERM Repl)
+/**************************************************************
+ INPUT: A term, a variable symbol and a replacement term.
+ RETURNS: void
+ EFFECT: All free variables with <Symbol> in <Term> are replaced with copies of <Repl>
+ CAUTION: Destructive
+***************************************************************/
+{
+ LIST Scan;
+
+#ifdef CHECK
+ if (!(term_IsTerm(Term) && term_IsTerm(Repl) && symbol_IsVariable(Symbol))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_ReplaceVariable: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ for (Scan=term_ArgumentList(term_FirstArgument(Term)); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (symbol_Equal(term_TopSymbol(list_Car(Scan)), Symbol)) /* var is bound */
+ return;
+ fol_ReplaceVariable(term_SecondArgument(Term), Symbol, Repl);
+ }
+
+ if (symbol_Equal(term_TopSymbol(Term), Symbol)) {
+ term_RplacTop(Term,term_TopSymbol(Repl));
+ term_RplacArgumentList(Term,term_CopyTermList(term_ArgumentList(Repl)));
+ }
+ else
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ fol_ReplaceVariable(list_Car(Scan),Symbol,Repl);
+}
+
+
+static void fol_PrettyPrintInternDFG(TERM Term, int Depth)
+/**************************************************************
+ INPUT: A term and a depth parameter for indentation.
+ RETURNS: none.
+ SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+ int i;
+ LIST scan;
+ SYMBOL Top;
+
+ Top = term_TopSymbol(Term);
+ if (!symbol_Equal(Top,fol_Varlist())) {
+ for (i = 0; i < Depth; i++)
+ fputs(" ", stdout);
+ if (fol_IsLiteral(Term))
+ term_PrintPrefix(Term);
+ else {
+ if (symbol_IsJunctor(Top)) {
+ if (term_IsComplex(Term)) {
+ symbol_Print(Top);
+ putchar('(');
+ if (!fol_IsQuantifier(Top))
+ putchar('\n');
+ for (scan=term_ArgumentList(Term); !list_Empty(scan); scan= list_Cdr(scan)) {
+ fol_PrettyPrintInternDFG((TERM) list_Car(scan), Depth+1);
+ if (!list_Empty(list_Cdr(scan)))
+ fputs(",\n", stdout);
+ }
+ putchar(')');
+ }
+ else {
+ if (term_IsVariable(Term)) {
+ symbol_Print(Top);
+ }
+ else {
+ putchar('(');
+ symbol_Print(Top);
+ putchar(')');
+ }
+ }
+ }
+ else {
+ term_PrintPrefix(Term);
+ }
+ }
+ }
+ else {
+ putchar('[');
+ term_TermListPrintPrefix(term_ArgumentList(Term));
+ putchar(']');
+ }
+}
+
+
+void fol_PrettyPrintDFG(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: none.
+ SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+ fol_PrettyPrintInternDFG(Term, 0);
+}
+
+
+TERM fol_CheckFatherLinksIntern(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: A subterm whose superterm pointer is not set correctly,
+ else NULL.
+ SUMMARY: Checks if all superterm links except of those from quantifier
+ variables are set correctly.
+***************************************************************/
+{
+ LIST l;
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return fol_CheckFatherLinksIntern(term_SecondArgument(Term));
+ if (term_IsComplex(Term)) {
+ for (l=term_ArgumentList(Term); !list_Empty(l); l=list_Cdr(l)) {
+ TERM result;
+ if (term_Superterm((TERM) list_Car(l)) != Term)
+ return (TERM) list_Car(l);
+ result = fol_CheckFatherLinksIntern((TERM) list_Car(l));
+ if (result != NULL)
+ return result;
+ }
+ }
+ return NULL;
+}
+
+
+void fol_CheckFatherLinks(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: none.
+ SUMMARY: Checks if all superterm links except of those from
+ quantifier variables are set correctly.
+***************************************************************/
+{
+ TERM Result;
+
+ Result = fol_CheckFatherLinksIntern(Term);
+#ifdef CHECK
+ if (Result != NULL || term_Superterm(Term) != NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_CheckFatherLinks:");
+ misc_ErrorReport(" Found a term where the father links");
+ misc_ErrorReport(" are not correctly set.");
+ misc_FinishErrorReport();
+ }
+#endif
+}
+
+
+static void fol_PrettyPrintIntern(TERM Term, int Depth)
+/**************************************************************
+ INPUT: A term and a depth parameter for indentation.
+ RETURNS: none.
+ SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+ int i;
+ LIST scan;
+
+ for (i = 0; i < Depth; i++)
+ fputs(" ", stdout);
+ if (symbol_IsJunctor(term_TopSymbol(Term))) {
+ if (term_IsComplex(Term)) {
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ symbol_Print(term_TopSymbol(Term));
+ fputs("([", stdout);
+ for (scan=fol_QuantifierVariables(Term); !list_Empty(scan); scan=list_Cdr(scan)) {
+ symbol_Print(term_TopSymbol((TERM) list_Car(scan)));
+ if (!list_Empty(list_Cdr(scan)))
+ putchar(',');
+ }
+ fputs("],\n", stdout);
+ fol_PrettyPrintIntern(term_SecondArgument(Term), Depth+1);
+ }
+ else {
+ symbol_Print(term_TopSymbol(Term));
+ fputs("(\n", stdout);
+ for (scan=term_ArgumentList(Term); !list_Empty(scan); scan= list_Cdr(scan)) {
+ fol_PrettyPrintIntern((TERM) list_Car(scan), Depth+1);
+ if (!list_Empty(list_Cdr(scan)))
+ fputs(",\n", stdout);
+ }
+ putchar(')');
+ }
+ }
+ else {
+ if (term_IsVariable(Term)) {
+ symbol_Print(term_TopSymbol(Term));
+ }
+ else {
+ putchar('(');
+ symbol_Print(term_TopSymbol(Term));
+ putchar(')');
+ }
+ }
+ }
+ else {
+ term_PrintPrefix(Term);
+ }
+}
+
+
+void fol_PrettyPrint(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: none.
+ SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+ fol_PrettyPrintIntern(Term, 0);
+}
+
+
+LIST fol_GetSubstEquations(TERM Term)
+/**************************************************************
+ INPUT: A Term.
+ RETURNS: The list of all equations of the form x=t or t=x in <Term>
+ where x is a variable and t is a term not containing x.
+***************************************************************/
+{
+ LIST Result;
+ LIST Scan;
+
+ Result = list_Nil();
+
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return fol_GetSubstEquations(term_SecondArgument(Term));
+ if (fol_IsEquality(Term)) {
+ if (term_IsVariable(term_SecondArgument(Term))) {
+ if (!term_ContainsSymbol(term_FirstArgument(Term), term_TopSymbol(term_SecondArgument(Term))))
+ Result = list_Cons(Term, Result);
+ }
+ else {
+ if (term_IsVariable(term_FirstArgument(Term)))
+ if (!term_ContainsSymbol(term_SecondArgument(Term), term_TopSymbol(term_FirstArgument(Term))))
+ Result = list_Cons(Term, Result);
+ }
+ }
+ if (symbol_IsPredicate(term_TopSymbol(Term)))
+ return Result;
+ else
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ Result = list_Nconc(Result, fol_GetSubstEquations(list_Car(Scan)));
+
+ return Result;
+}
+
+
+TERM fol_GetBindingQuantifier(TERM Term, SYMBOL Symbol)
+/**************************************************************
+ INPUT: A symbol and a term containing the symbol.
+ RETURNS: The Quantifier binding the symbol.
+***************************************************************/
+{
+ LIST Scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !symbol_IsSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_GetBindingQuantifier: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ for ( Scan = fol_QuantifierVariables(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (symbol_Equal(Symbol, term_TopSymbol(list_Car(Scan)))) {
+ return Term;
+ }
+ }
+
+ return fol_GetBindingQuantifier(term_Superterm(Term), Symbol);
+}
+
+
+int fol_TermPolarity(TERM SubTerm, TERM Term)
+/**************************************************************
+ INPUT: Two terms, SubTerm subterm of Term.
+ It is assumed that the superterm links in <Term>
+ are established.
+ RETURNS: The polarity of SubTerm in Term.
+***************************************************************/
+{
+ TERM SuperTerm;
+
+#ifdef CHECK
+ if (!term_IsTerm(SubTerm) || !term_IsTerm(Term) || !term_FatherLinksEstablished(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_TermPolarity: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (SubTerm == Term)
+ return 1;
+
+ SuperTerm = term_Superterm(SubTerm);
+
+ if (SuperTerm) {
+ SYMBOL Top;
+ Top = term_TopSymbol(SuperTerm);
+
+ if (symbol_Equal(Top,fol_AND) || symbol_Equal(Top,fol_OR) || fol_IsQuantifier(Top))
+ return fol_TermPolarity(SuperTerm, Term);
+
+ if (symbol_Equal(Top,fol_NOT))
+ return (-fol_TermPolarity(SuperTerm, Term));
+
+ if (symbol_Equal(Top,fol_EQUIV))
+ return 0;
+
+ if (symbol_Equal(Top, fol_IMPLIES)) {
+ if (SubTerm == term_FirstArgument(SuperTerm))
+ return (-fol_TermPolarity(SuperTerm, Term));
+ else
+ return fol_TermPolarity(SuperTerm, Term);
+ }
+ if (symbol_Equal(Top, fol_IMPLIED)) {
+ if (SubTerm == term_SecondArgument(SuperTerm))
+ return (-fol_TermPolarity(SuperTerm, Term));
+ else
+ return fol_TermPolarity(SuperTerm, Term);
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_TermPolarity: Unknown first-order operator.\n");
+ misc_FinishErrorReport();
+ }
+
+ return 1;
+}
+
+
+static int fol_PolarCheckCount(TERM Nowterm, TERM SuperTerm, int Nowpolar)
+/**************************************************************
+ INPUT: Two terms, Nowterm and its superterm, and the polarity of
+ Nowterm.
+ RETURNS: The polarity of SuperTerm according to Nowterm.
+ COMMENT: Helpfunction for fol_PolarCheck.
+***************************************************************/
+{
+ SYMBOL Top;
+ Top = term_TopSymbol(SuperTerm);
+
+ if (Nowterm == SuperTerm)
+ return Nowpolar;
+
+ if (symbol_Equal(Top, fol_OR) || symbol_Equal(Top, fol_AND) || fol_IsQuantifier(Top) ||
+ (symbol_Equal(Top, fol_IMPLIES) && Nowterm == term_SecondArgument(SuperTerm)) ||
+ (symbol_Equal(Top, fol_IMPLIED) && Nowterm == term_FirstArgument(SuperTerm)))
+ return Nowpolar;
+
+ if (symbol_Equal(term_TopSymbol(SuperTerm), fol_EQUIV))
+ return 0;
+
+ return -Nowpolar;
+}
+
+
+static BOOL fol_PolarCheckAllquantor(TERM Subterm, TERM Term, int SubtermPolar)
+/**************************************************************
+ INPUT: Two terms, Subterm subterm of Term, and polarity of Subterm.
+ RETURNS: TRUE iff Subterm occurs in Term disjunctively.
+ COMMENT: Help function for fol_PolarCheck. Dual case to Exist quantor.
+***************************************************************/
+{
+ TERM SuperTerm;
+ SYMBOL Top;
+ int SubPolar;
+
+ if (Subterm == Term)
+ return TRUE;
+
+ SuperTerm = term_Superterm(Subterm);
+
+ if (SuperTerm == Term) /* Ugly, but it does not make sense to introduce a further function */
+ return TRUE;
+
+ Top = term_TopSymbol(SuperTerm);
+ SubPolar = fol_PolarCheckCount(Subterm, SuperTerm, SubtermPolar);
+
+ /* To be clarified: can the below condition generalized to universal quantifiers? */
+
+ if (symbol_Equal(Top,fol_NOT) ||
+ (symbol_Equal(Top, fol_OR) && SubPolar == 1) ||
+ (symbol_Equal(Top, fol_AND) && SubPolar == -1) ||
+ (symbol_Equal(Top,fol_IMPLIES) && SubPolar == 1) ||
+ (symbol_Equal(Top,fol_IMPLIED) && SubPolar == 1))
+ return fol_PolarCheckAllquantor(SuperTerm, Term, SubPolar);
+
+ return FALSE;
+}
+
+
+static BOOL fol_PolarCheckExquantor(TERM Subterm, TERM Term, int SubtermPolar)
+/**************************************************************
+ INPUT: Two terms, Subterm subterm of Term, and polarity of Subterm.
+ RETURNS: TRUE iff Subterm occurs in Term conjunctively.
+ COMMENT: Help function for fol_PolarCheck. Dual case to Allquantor.
+***************************************************************/
+{
+ TERM SuperTerm;
+ SYMBOL Top;
+ int SubPolar;
+
+ if (Subterm == Term)
+ return TRUE;
+
+ SuperTerm = term_Superterm(Subterm);
+
+ if (SuperTerm == Term) /* Ugly, but it does not make sense to introduce a further function */
+ return TRUE;
+
+ Top = term_TopSymbol(SuperTerm);
+ SubPolar = fol_PolarCheckCount(Subterm, SuperTerm, SubtermPolar);
+
+ /* To be clarified: can the below condition generalized to existential quantifiers? */
+
+ if (symbol_Equal(Top,fol_NOT) ||
+ (symbol_Equal(Top, fol_OR) && SubPolar == -1) ||
+ (symbol_Equal(Top, fol_AND) && SubPolar == 1) ||
+ (symbol_Equal(Top,fol_IMPLIES) && SubPolar == -1) ||
+ (symbol_Equal(Top,fol_IMPLIED) && SubPolar == -1))
+ return fol_PolarCheckExquantor(SuperTerm, Term, SubPolar);
+
+ return FALSE;
+}
+
+BOOL fol_PolarCheck(TERM Subterm, TERM Term)
+/**************************************************************
+ INPUT: Two terms, <Subterm> is of the form x=t, where x or t variable.
+ <Subterm> is a subterm of <Term> and the top symbol of
+ <Term> must be the binding quantifier of x or t.
+ RETURNS: BOOL if check is ok.
+***************************************************************/
+{
+ int SubtermPolar;
+ SYMBOL Top;
+
+ SubtermPolar = fol_TermPolarity(Subterm, Term);
+ Top = term_TopSymbol(Term);
+
+ if (SubtermPolar == -1 && symbol_Equal(Top, fol_ALL))
+ return fol_PolarCheckAllquantor(Subterm, Term, SubtermPolar);
+
+ if (SubtermPolar == 1 && symbol_Equal(Top, fol_EXIST))
+ return fol_PolarCheckExquantor(Subterm, Term, SubtermPolar);
+
+ return FALSE;
+}
+
+
+void fol_PopQuantifier(TERM Term)
+/**************************************************************
+ INPUT: A term whose top symbol is a quantifier.
+ RETURNS: Nothing.
+ EFFECT: Removes the quantifier.
+ If supertermlinks were set, they are updated.
+***************************************************************/
+{
+ TERM SubTerm;
+ LIST Scan;
+
+#ifdef CHECK
+ if (!fol_IsQuantifier(term_TopSymbol(Term))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_PopQuantifier: Top symbol of term isn't a quantifier.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_Delete(term_FirstArgument(Term));
+ SubTerm = term_SecondArgument(Term);
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,term_TopSymbol(SubTerm));
+ term_RplacArgumentList(Term,term_ArgumentList(SubTerm));
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (term_Superterm(list_Car(Scan)))
+ term_RplacSuperterm(list_Car(Scan),Term);
+ term_Free(SubTerm);
+}
+
+
+void fol_DeleteQuantifierVariable(TERM Quant,SYMBOL Var)
+/****************************************************************
+ INPUT: A term starting with a quantifier and a variable symbol.
+ RETURNS: Nothing.
+ EFFECT: The variable is deleted from the list of variables
+ bound by the quantor of <Quant>
+*****************************************************************/
+{
+ LIST Scan;
+
+ for (Scan=fol_QuantifierVariables(Quant);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (symbol_Equal(term_TopSymbol(list_Car(Scan)), Var)) {
+ term_Delete((TERM)list_Car(Scan));
+ list_Rplaca(Scan, (POINTER)NULL);
+ }
+ term_RplacArgumentList(term_FirstArgument(Quant),
+ list_PointerDeleteElement(fol_QuantifierVariables(Quant),(POINTER)NULL));
+ if (list_Empty(fol_QuantifierVariables(Quant)))
+ fol_PopQuantifier(Quant);
+}
+
+
+
+void fol_SetTrue(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Nothing.
+ EFFECT: Replaces Term destructively by fol_True().
+***************************************************************/
+{
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term, list_Nil());
+ term_RplacTop(Term, fol_True());
+}
+
+void fol_SetFalse(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Nothing.
+ EFFECT: Replaces Term destructively by fol_False().
+***************************************************************/
+{
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term, list_Nil());
+ term_RplacTop(Term, fol_False());
+}
+
+
+static void fol_ReplaceByArgCon(TERM Term)
+/**************************************************************
+ INPUT: A term of the form f(...)=f(...), where f is a function.
+ RETURNS: True.
+ EFFECT: Substitutes Term by <and(t1=s1, t2=s2, ..., tn=sn)>,
+ where ti and si are the arguments of both f's in Term.
+***************************************************************/
+{
+ LIST Scan, Bscan, List, Hlist;
+ TERM Func1, Func2, NewTerm;
+
+ Func1 = term_FirstArgument(Term);
+ Func2 = term_SecondArgument(Term);
+ List = term_ArgumentList(Term);
+ Scan = list_Nil();
+ term_RplacArgumentList(Term, list_Nil());
+ term_RplacTop(Term, fol_And());
+
+ for (Scan = term_ArgumentList(Func1),Bscan = term_ArgumentList(Func2);
+ !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Hlist = list_Nil();
+ Hlist = list_Cons(list_Car(Bscan), Hlist);
+ Hlist = list_Cons(list_Car(Scan), Hlist);
+ NewTerm = term_Create(fol_Equality(), Hlist);
+ term_RplacArgumentList(Term, list_Cons(NewTerm, term_ArgumentList(Term)));
+ Bscan = list_Cdr(Bscan);
+ }
+
+ list_Delete(term_ArgumentList(Func1));
+ list_Delete(term_ArgumentList(Func2));
+ term_RplacArgumentList(Func1, list_Nil());
+ term_RplacArgumentList(Func2, list_Nil());
+ term_Delete(Func1);
+ term_Delete(Func2);
+ list_Delete(List);
+}
+
+
+BOOL fol_PropagateFreeness(TERM Term)
+/**************************************************************
+ INPUT: A term and a list of functions.
+ RETURNS: True iff a subterm of the form f(...)=f(...) occurs in the term,
+ where f has property FREELY and GENERATED.
+ EFFECT: Substitutes all occurences of f=f by <and(t1=s1,...tn=sn)>,where
+ ti and si are the arguments of each f in f=f.
+***************************************************************/
+{
+ BOOL Free;
+ LIST Scan;
+ TERM Argum1, Argum2;
+
+ Free = FALSE;
+
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return fol_PropagateFreeness(term_SecondArgument(Term));
+
+ if (!term_IsAtom(Term)) {
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (fol_PropagateFreeness(list_Car(Scan)))
+ Free = TRUE;
+ }
+ else
+ if (fol_IsEquality(Term)) {
+ Argum1 = term_FirstArgument(Term);
+ Argum2 = term_SecondArgument(Term);
+ if (symbol_Equal(term_TopSymbol(Argum1), term_TopSymbol(Argum2)) &&
+ symbol_HasProperty(term_TopSymbol(Argum1), FREELY) &&
+ symbol_HasProperty(term_TopSymbol(Argum1), GENERATED)) {
+ fol_ReplaceByArgCon(Term);
+ return TRUE;
+ }
+ }
+
+ return Free;
+}
+
+
+static BOOL fol_PropagateWitnessIntern(TERM Equation, SYMBOL Variable)
+/**************************************************************
+ INPUT: A Term which is an equation where <Variable> is one
+ of the equation's arguments that does not occur in the
+ other argument. Father links must exist.
+ RETURNS: True in case of witness propagation.
+ EFFECT: Checks whether subterm the equation is part of
+ is of the form described in fol_PropagateWitness and
+ substitutes in case of a hit.
+***************************************************************/
+{
+ TERM SuperTerm, BindQuantor, Predicat;
+ SYMBOL SuperTop;
+
+ SuperTerm = term_Superterm(Equation);
+
+ if (SuperTerm == term_Null())
+ return FALSE;
+
+ SuperTop = term_TopSymbol(SuperTerm);
+ BindQuantor = term_Superterm(SuperTerm);
+
+ if (BindQuantor == term_Null())
+ return FALSE;
+
+ if (!fol_IsQuantifier(term_TopSymbol(BindQuantor)) ||
+ list_Length(term_ArgumentList(SuperTerm)) != 2)
+ return FALSE;
+
+ if (Equation == term_SecondArgument(SuperTerm))
+ Predicat = term_FirstArgument(SuperTerm);
+ else
+ Predicat = term_SecondArgument(SuperTerm);
+
+ if (symbol_Equal(term_TopSymbol(BindQuantor), fol_All()) &&
+ symbol_Equal(SuperTop, fol_Or()) &&
+ symbol_Equal(term_TopSymbol(Predicat), fol_Not()) &&
+ symbol_HasProperty(term_TopSymbol(term_FirstArgument(Predicat)), FREELY) &&
+ symbol_HasProperty(term_TopSymbol(term_FirstArgument(Predicat)), GENERATED) &&
+ symbol_Equal(term_TopSymbol(term_FirstArgument(term_FirstArgument(Predicat))), Variable)) {
+ fol_SetFalse(BindQuantor);
+ return TRUE;
+ }
+ if (!symbol_HasProperty(term_TopSymbol(Predicat), FREELY) ||
+ !symbol_HasProperty(term_TopSymbol(Predicat), GENERATED) ||
+ !symbol_Equal(Variable, term_TopSymbol(term_FirstArgument(Predicat))))
+ return FALSE;
+
+ if (symbol_Equal(term_TopSymbol(BindQuantor), fol_All())) {
+ if (symbol_Equal(SuperTop, fol_Implies()) &&
+ term_SecondArgument(SuperTerm) == Equation) {
+ fol_SetFalse(BindQuantor);
+ return TRUE;
+ }
+ if (symbol_Equal(SuperTop, fol_Implied()) &&
+ term_FirstArgument(SuperTerm) == Equation) {
+ fol_SetFalse(BindQuantor);
+ return TRUE;
+ }
+ }
+ else /* Exquantor */
+ if (symbol_Equal(SuperTop, fol_And())) {
+ fol_SetTrue(BindQuantor);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+BOOL fol_PropagateWitness(TERM Term)
+/**************************************************************
+ INPUT: A Term.
+ RETURNS: True in case of witness propagation.
+ EFFECT: Substitutes any subterm of Term of the form
+ forall([x],implies(P(x),x=t))
+ forall([x],implied(x=t,P(x)))
+ forall([x],or(notP(x),x=t)) by FALSE and
+ exists([x],and(P(x),x=t)) by TRUE, where
+ P has property FREELY and GENERATED, x doesn't occur in t.
+***************************************************************/
+{
+ BOOL Hit;
+ LIST Scan;
+
+ Hit = FALSE;
+
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return fol_PropagateWitness(term_SecondArgument(Term));
+ if (fol_IsEquality(Term)) {
+ if (term_IsVariable(term_SecondArgument(Term))) {
+ if (!term_ContainsSymbol(term_FirstArgument(Term), term_TopSymbol(term_SecondArgument(Term))))
+ Hit = fol_PropagateWitnessIntern(Term,term_TopSymbol(term_SecondArgument(Term)));
+ }
+ else {
+ if (term_IsVariable(term_FirstArgument(Term)))
+ if (!term_ContainsSymbol(term_SecondArgument(Term), term_TopSymbol(term_FirstArgument(Term))))
+ Hit = fol_PropagateWitnessIntern(Term,term_TopSymbol(term_FirstArgument(Term)));
+ }
+ }
+ if (symbol_IsPredicate(term_TopSymbol(Term)))
+ return FALSE;
+
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (fol_PropagateWitness(list_Car(Scan)))
+ Hit = TRUE;
+
+ return Hit;
+}
+
+BOOL fol_PropagateTautologies(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: True iff function replaced a subterm.
+ EFFECT: Replaces all occurences of t=t, or(A,not(A)) by TRUE
+ and and(A,not(A)) by FALSE.
+***************************************************************/
+{
+ BOOL Hit;
+ LIST Scan, Bscan, ArgumentList;
+ SYMBOL Top;
+
+ Top = term_TopSymbol(Term);
+ Hit = FALSE;
+ ArgumentList = term_ArgumentList(Term);
+
+ if (fol_IsQuantifier(Top))
+ return fol_PropagateTautologies(term_SecondArgument(Term));
+
+ if (fol_IsEquality(Term)) {
+ if (term_Equal(term_FirstArgument(Term), term_SecondArgument(Term))) {
+ fol_SetTrue(Term);
+ return TRUE;
+ }
+ }
+
+ if (symbol_Equal(Top, fol_Or()) || symbol_Equal(Top, fol_And())) {
+ for (Scan = ArgumentList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (symbol_Equal(term_TopSymbol(list_Car(Scan)), fol_Not())) {
+ for (Bscan = ArgumentList; !list_Empty(Bscan); Bscan = list_Cdr(Bscan)) {
+ if (list_Car(Scan) != list_Car(Bscan) &&
+ fol_AlphaEqual(term_FirstArgument(list_Car(Scan)), list_Car(Bscan))) {
+ if (symbol_Equal(Top, fol_Or()))
+ fol_SetTrue(Term);
+ else
+ fol_SetFalse(Term);
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ if (!term_IsAtom(Term))
+ for (Scan = ArgumentList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (fol_PropagateTautologies(list_Car(Scan)))
+ Hit = TRUE;
+ }
+
+ return Hit;
+}
+
+
+static BOOL fol_AlphaEqualIntern(TERM Term1, TERM Term2, NAT Mark)
+/**************************************************************
+ INPUT: Two terms which represent formulae and a binding mark.
+ RETURNS: True iff Term2 is equal to Term1 with respect to the
+ renaming of bound variables.
+***************************************************************/
+{
+ LIST Scan, Bscan;
+ SYMBOL Top1, Top2;
+
+ Top1 = term_TopSymbol(Term1);
+ Top2 = term_TopSymbol(Term2);
+
+ if (symbol_IsVariable(Top1) && symbol_IsVariable(Top2)) {
+ if (term_VarIsMarked(Top2, Mark))
+ return symbol_Equal(Top1, (SYMBOL)term_BindingValue(Top2));
+ else
+ return symbol_Equal(Top1, Top2);
+ }
+
+ if (!symbol_Equal(Top1, Top2))
+ return FALSE;
+
+ if (fol_IsQuantifier(Top1)) {
+ if (list_Length(fol_QuantifierVariables(Term1)) != list_Length(fol_QuantifierVariables(Term2)))
+ return FALSE;
+ for (Scan = fol_QuantifierVariables(Term1), Bscan = fol_QuantifierVariables(Term2);
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan), Bscan = list_Cdr(Bscan))
+ term_CreateValueBinding(term_TopSymbol(list_Car(Bscan)), Mark,
+ (POINTER)term_TopSymbol(list_Car(Scan)));
+
+ if (!fol_AlphaEqualIntern(term_SecondArgument(Term1), term_SecondArgument(Term2), Mark))
+ return FALSE;
+ for (Scan = fol_QuantifierVariables(Term1), Bscan = fol_QuantifierVariables(Term2);
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan), Bscan = list_Cdr(Bscan))
+ term_SetBindingMark(term_TopSymbol(list_Car(Bscan)), term_NullMark());
+ }
+ else {
+ if (list_Length(term_ArgumentList(Term1)) != list_Length(term_ArgumentList(Term2)))
+ return FALSE;
+
+ for (Scan = term_ArgumentList(Term1), Bscan = term_ArgumentList(Term2);
+ !list_Empty(Scan); Scan = list_Cdr(Scan), Bscan = list_Cdr(Bscan))
+ if (!fol_AlphaEqualIntern(list_Car(Scan), list_Car(Bscan), Mark))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+BOOL fol_AlphaEqual(TERM Term1, TERM Term2)
+/**************************************************************
+ INPUT: Two terms of the form Qx(<rest>). All variables that occur in
+ Term1 and Term2 must be bound by only one quantifier!
+ RETURNS: TRUE iff Term2 is bound renaming of Term1.
+***************************************************************/
+{
+ BOOL Hit;
+
+#ifdef CHECK
+ if (Term1 == term_Null() || Term2 == term_Null()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_AlphaEqual: Corrupted term as parameter.\n");
+ misc_FinishErrorReport();
+ }
+ if (fol_VarBoundTwice(Term1) || fol_VarBoundTwice(Term2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_AlphaEqual: Variables are bound more than once.\n");
+ misc_FinishErrorReport();
+ }
+ if (term_InBindingPhase()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_AlphaEqual: Term context is in binding phase.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+
+ Hit = fol_AlphaEqualIntern(Term1, Term2, term_ActMark());
+
+ term_StopBinding();
+
+ return Hit;
+}
+
+
+static BOOL fol_VarBoundTwiceIntern(TERM Term, NAT Mark)
+/**************************************************************
+ INPUT: A term, possibly a NULL Term and a valid binding mark.
+ RETURNS: TRUE iff a variable in <Term> is bound by more than one quantifier.
+***************************************************************/
+{
+ LIST Scan;
+
+ if (Term == term_Null())
+ return FALSE;
+
+ if (term_IsAtom(Term))
+ return FALSE;
+
+ if (!fol_IsQuantifier(term_TopSymbol(Term))) {
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (fol_VarBoundTwiceIntern(list_Car(Scan), Mark))
+ return TRUE;
+ }
+ else {
+ for (Scan = fol_QuantifierVariables(Term); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (!term_VarIsMarked(term_TopSymbol(list_Car(Scan)), Mark))
+ term_SetBindingMark(term_TopSymbol(list_Car(Scan)), Mark);
+ else
+ return TRUE;
+ }
+ if (fol_VarBoundTwiceIntern(term_SecondArgument(Term), Mark))
+ return TRUE;
+ for (Scan = fol_QuantifierVariables(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ term_SetBindingMark(term_TopSymbol(list_Car(Scan)), term_NullMark());
+ }
+ return FALSE;
+}
+
+
+BOOL fol_VarBoundTwice(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: TRUE iff a variable in term is bound by more than one quantifier.
+***************************************************************/
+{
+ BOOL Hit;
+
+#ifdef CHECK
+ if (term_InBindingPhase()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n\n Context in fol_VarBoundTwice: term in binding phase\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+
+ Hit = fol_VarBoundTwiceIntern(Term, (NAT)term_ActMark());
+
+ term_StopBinding();
+
+ return Hit;
+}
+
+
+NAT fol_Depth(TERM Term)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: The depth of the formula up to predicate level.
+***************************************************************/
+{
+ NAT Depth,Help;
+ LIST Scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_Depth: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Depth = 0;
+
+ if (symbol_IsPredicate(term_TopSymbol(Term)))
+ return 1;
+
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return (fol_Depth(term_SecondArgument(Term)) + 1);
+
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ Help = fol_Depth(list_Car(Scan));
+ if (Help > Depth)
+ Depth = Help;
+ }
+
+ return (Depth+1);
+}
+
+
+static void fol_ApplyContextToTermIntern(CONTEXT Context, TERM Term)
+/********************************************************************
+ INPUT: A context (Context) and a term (Term).
+ RETURN: void.
+ EFFECT: Term is destructively changed modulo Context.
+*********************************************************************/
+{
+ LIST Scan;
+
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ fol_ApplyContextToTermIntern(Context, term_SecondArgument(Term));
+ }
+ else if (symbol_IsVariable(term_TopSymbol(Term))) {
+ if (cont_VarIsBound(Context, term_TopSymbol(Term)))
+ Term = cont_ApplyBindingsModuloMatching(Context, Term, TRUE);
+ }
+ else {
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ fol_ApplyContextToTermIntern(Context, list_Car(Scan));
+ }
+}
+
+
+static BOOL fol_CheckApplyContextToTerm(CONTEXT Context, TERM Term)
+/*************************************************************
+ INPUT: A Context and a term.
+ RETURN: TRUE iff Context can be applied to Term.
+ COMMENT: Intern funktion of fol_ApplyContextToTerm.
+**************************************************************/
+{
+ LIST Scan;
+ BOOL Apply;
+
+ Apply = TRUE;
+
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ for (Scan=fol_QuantifierVariables(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (cont_VarIsBound(Context, term_TopSymbol(list_Car(Scan))))
+ return FALSE;
+ for (Scan=term_ArgumentList(term_SecondArgument(Term)); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ if (!fol_CheckApplyContextToTerm(Context, list_Car(Scan)))
+ Apply = FALSE;
+ }
+ }
+ else {
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (!fol_CheckApplyContextToTerm(Context, list_Car(Scan)))
+ Apply = FALSE;
+ }
+ return Apply;
+}
+
+
+BOOL fol_ApplyContextToTerm(CONTEXT Context, TERM Term)
+/***************************************************************
+ INPUT: A context (Context) and a term (Term).
+ RETURN: TRUE iff context could be applied on Term.
+ EFFECT: Term is destructively changed modulo Context iff possible.
+****************************************************************/
+{
+ if (fol_CheckApplyContextToTerm(Context, Term)) {
+ fol_ApplyContextToTermIntern(Context, Term);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+BOOL fol_SignatureMatchFormula(TERM Formula, TERM Instance, BOOL Variant)
+/********************************************************************
+ INPUT : Two formulas and a flag.
+ It is assumed that the symbol context is clean.
+ RETURN: TRUE iff <Formula> can be matched to <Instance> by matching
+ variables as well as signature symbols. If <Variant> is TRUE
+ variables must be matched to variables.
+ EFFECT: The symbol matches are stored in the symbol context.
+*********************************************************************/
+{
+ int Stack;
+ SYMBOL FormulaTop, InstanceTop;
+ NAT ActMark;
+ TERM ActFormula, ActInstance;
+
+#ifdef CHECK
+ if (!term_IsTerm(Formula) || term_InBindingPhase() ||
+ !term_IsTerm(Instance) || !symbol_ContextIsClean()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_SignatureMatchFormula: Illegal input or context.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+
+ Stack = stack_Bottom();
+ term_NewMark();
+ ActMark = term_OldMark();
+ ActFormula = Formula;
+ ActInstance = Instance;
+
+ do {
+ FormulaTop = term_TopSymbol(ActFormula);
+ InstanceTop = term_TopSymbol(ActInstance);
+
+ if (!symbol_IsVariable(FormulaTop)) {
+ if (!symbol_ContextIsBound(FormulaTop)) {
+ if (!symbol_IsJunctor(FormulaTop) && !symbol_IsJunctor(InstanceTop) &&
+ !fol_IsPredefinedPred(FormulaTop) && !fol_IsPredefinedPred(InstanceTop))
+ symbol_ContextSetValue(FormulaTop, InstanceTop); /* Symbols are ALWAYS bound !*/
+ else {
+ if (!symbol_Equal(FormulaTop, InstanceTop)) {
+ term_StopBinding();
+ return FALSE;
+ }
+ }
+ }
+ else {
+ if (symbol_ContextIsBound(FormulaTop) &&
+ !symbol_Equal(symbol_ContextGetValue(FormulaTop),InstanceTop)) {
+ term_StopBinding();
+ return FALSE;
+ }
+ }
+ }
+
+ if (list_Length(term_ArgumentList(ActFormula)) != list_Length(term_ArgumentList(ActInstance))) {
+ term_StopBinding();
+ return FALSE;
+ }
+
+ if (term_IsComplex(ActFormula)) {
+ stack_Push(term_ArgumentList(ActInstance));
+ stack_Push(term_ArgumentList(ActFormula));
+ }
+ else {
+ if (symbol_IsVariable(FormulaTop)) {
+ if (!term_VarIsMarked(FormulaTop, ActMark)) {
+ if (!Variant || symbol_IsVariable(InstanceTop))
+ term_CreateValueBinding(FormulaTop, ActMark, (POINTER)InstanceTop);
+ else {
+ term_StopBinding();
+ return FALSE;
+ }
+ }
+ else {
+ if (!symbol_Equal((SYMBOL)term_BindingValue(FormulaTop), InstanceTop)) {
+ term_StopBinding();
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top())) {
+ stack_Pop();
+ stack_Pop();
+ }
+ if (!stack_Empty(Stack)) {
+ ActFormula = (TERM)list_Car(stack_Top());
+ ActInstance = (TERM)list_Car(stack_NthTop(1));
+ stack_RplacTop(list_Cdr(stack_Top()));
+ stack_RplacNthTop(1,list_Cdr(stack_NthTop(1)));
+ }
+ } while (!stack_Empty(Stack));
+
+ term_StopBinding();
+
+ return TRUE;
+}
+
+
+BOOL fol_SignatureMatch(TERM Term, TERM Instance, LIST* Bindings, BOOL Variant)
+/*****************************************************************
+ INPUT : Two formulas, a binding list and a boolean flag.
+ RETURN: TRUE iff <Term> can be matched to <Instance> by matching
+ variables as well as signature symbols. If <Variant> is TRUE
+ variables must be matched to variables. Signature symbol
+ matchings have to be injective.
+ EFFECT: The symbol matches are stored in the symbol context.
+******************************************************************/
+{
+ int Stack;
+ SYMBOL TermTop, InstanceTop;
+ NAT ActMark;
+ TERM ActTerm, ActInstance;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !term_IsTerm(Instance)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_SignatureMatch: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Stack = stack_Bottom();
+ ActMark = term_OldMark();
+ ActTerm = Term;
+ ActInstance = Instance;
+
+ do {
+ TermTop = term_TopSymbol(ActTerm);
+ InstanceTop = term_TopSymbol(ActInstance);
+
+ if (!symbol_IsVariable(TermTop)) {
+ if (!symbol_ContextIsBound(TermTop)) {
+ if (!symbol_IsJunctor(TermTop) && !symbol_IsJunctor(InstanceTop) &&
+ !fol_IsPredefinedPred(TermTop) && !fol_IsPredefinedPred(InstanceTop) &&
+ !symbol_ContextIsMapped(InstanceTop)) {
+ symbol_ContextSetValue(TermTop, InstanceTop); /* Symbols are ALWAYS bound !*/
+ *Bindings = list_Cons((POINTER)TermTop,*Bindings);
+ }
+ else {
+ if (!symbol_Equal(TermTop, InstanceTop)) {
+ return FALSE;
+ }
+ }
+ }
+ else {
+ if (symbol_ContextIsBound(TermTop) &&
+ !symbol_Equal(symbol_ContextGetValue(TermTop),InstanceTop)) {
+ return FALSE;
+ }
+ }
+ }
+
+ if (list_Length(term_ArgumentList(ActTerm)) != list_Length(term_ArgumentList(ActInstance))) {
+ return FALSE;
+ }
+
+ if (term_IsComplex(ActTerm)) {
+ stack_Push(term_ArgumentList(ActInstance));
+ stack_Push(term_ArgumentList(ActTerm));
+ }
+ else {
+ if (symbol_IsVariable(TermTop)) {
+ if (!term_VarIsMarked(TermTop, ActMark)) {
+ if (!Variant || symbol_IsVariable(InstanceTop)) {
+ term_CreateValueBinding(TermTop, ActMark, (POINTER)InstanceTop);
+ *Bindings = list_Cons((POINTER)TermTop,*Bindings);
+ }
+ else
+ return FALSE;
+ }
+ else {
+ if (!symbol_Equal((SYMBOL)term_BindingValue(TermTop), InstanceTop)) {
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top())) {
+ stack_Pop();
+ stack_Pop();
+ }
+ if (!stack_Empty(Stack)) {
+ ActTerm = (TERM)list_Car(stack_Top());
+ ActInstance = (TERM)list_Car(stack_NthTop(1));
+ stack_RplacTop(list_Cdr(stack_Top()));
+ stack_RplacNthTop(1,list_Cdr(stack_NthTop(1)));
+ }
+ } while (!stack_Empty(Stack));
+
+ return TRUE;
+}
+
+
+BOOL fol_CheckFormula(TERM Formula)
+/*******************************************************************
+ INPUT : A term Formula.
+ RETURN: TRUE iff no free variables occure in Formula
+ and father links are properly set
+ and argument list lengths match arities
+********************************************************************/
+{
+ LIST FreeVars;
+
+ FreeVars = fol_FreeVariables(Formula);
+
+ if (!list_Empty(FreeVars)) {
+ list_Delete(FreeVars);
+ return FALSE;
+ }
+
+ return term_CheckTerm(Formula);
+}
diff --git a/test/spass/foldfg.h b/test/spass/foldfg.h
new file mode 100644
index 0000000..3704e44
--- /dev/null
+++ b/test/spass/foldfg.h
@@ -0,0 +1,303 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * FIRST ORDER LOGIC SYMBOLS * */
+/* * * */
+/* * $Module: FOL DFG * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _FOLDFG_
+#define _FOLDFG_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "flags.h"
+#include "unify.h"
+#include "context.h"
+#include "term.h"
+
+/**************************************************************/
+/* Global Variables and Constants (Only seen by macros) */
+/**************************************************************/
+
+extern SYMBOL fol_ALL;
+extern SYMBOL fol_EXIST;
+extern SYMBOL fol_AND;
+extern SYMBOL fol_OR;
+extern SYMBOL fol_NOT;
+extern SYMBOL fol_IMPLIES;
+extern SYMBOL fol_IMPLIED;
+extern SYMBOL fol_EQUIV;
+extern SYMBOL fol_VARLIST;
+extern SYMBOL fol_EQUALITY;
+extern SYMBOL fol_TRUE;
+extern SYMBOL fol_FALSE;
+
+/**************************************************************/
+/* Access to the first-order symbols. */
+/**************************************************************/
+
+static __inline__ SYMBOL fol_All(void)
+{
+ return fol_ALL;
+}
+
+static __inline__ SYMBOL fol_Exist(void)
+{
+ return fol_EXIST;
+}
+
+static __inline__ SYMBOL fol_And(void)
+{
+ return fol_AND;
+}
+
+static __inline__ SYMBOL fol_Or(void)
+{
+ return fol_OR;
+}
+
+static __inline__ SYMBOL fol_Not(void)
+{
+ return fol_NOT;
+}
+
+static __inline__ SYMBOL fol_Implies(void)
+{
+ return fol_IMPLIES;
+}
+
+static __inline__ SYMBOL fol_Implied(void)
+{
+ return fol_IMPLIED;
+}
+
+static __inline__ SYMBOL fol_Equiv(void)
+{
+ return fol_EQUIV;
+}
+
+static __inline__ SYMBOL fol_Varlist(void)
+{
+ return fol_VARLIST;
+}
+
+static __inline__ SYMBOL fol_Equality(void)
+{
+ return fol_EQUALITY;
+}
+
+static __inline__ SYMBOL fol_True(void)
+{
+ return fol_TRUE;
+}
+
+static __inline__ SYMBOL fol_False(void)
+{
+ return fol_FALSE;
+}
+
+/**************************************************************/
+/* Macros */
+/**************************************************************/
+
+static __inline__ BOOL fol_IsQuantifier(SYMBOL S)
+{
+ return symbol_Equal(fol_ALL,S) || symbol_Equal(fol_EXIST,S);
+}
+
+static __inline__ BOOL fol_IsTrue(TERM S)
+{
+ return symbol_Equal(fol_TRUE,term_TopSymbol(S));
+}
+
+static __inline__ BOOL fol_IsFalse(TERM S)
+{
+ return symbol_Equal(fol_FALSE,term_TopSymbol(S));
+}
+
+static __inline__ LIST fol_QuantifierVariables(TERM T)
+ /* T's top symbol must be a quantifier ! */
+{
+ return term_ArgumentList(term_FirstArgument(T));
+}
+
+static __inline__ BOOL fol_IsLiteral(TERM T)
+{
+ return symbol_IsPredicate(term_TopSymbol(T)) ||
+ (symbol_Equal(term_TopSymbol(T),fol_Not()) &&
+ symbol_IsPredicate(term_TopSymbol(term_FirstArgument(T))));
+}
+
+static __inline__ BOOL fol_IsNegativeLiteral(TERM T)
+{
+ return (symbol_Equal(term_TopSymbol(T),fol_Not()) &&
+ symbol_IsPredicate(term_TopSymbol(term_FirstArgument(T))));
+}
+
+
+static __inline__ BOOL fol_IsJunctor(SYMBOL S)
+{
+ return fol_IsQuantifier(S) || symbol_Equal(S, fol_AND) ||
+ symbol_Equal(S, fol_OR) || symbol_Equal(S, fol_NOT) ||
+ symbol_Equal(S, fol_IMPLIED) || symbol_Equal(S, fol_VARLIST) ||
+ symbol_Equal(S, fol_IMPLIES) || symbol_Equal(S, fol_EQUIV);
+}
+
+static __inline__ BOOL fol_IsPredefinedPred(SYMBOL S)
+{
+ return symbol_Equal(S, fol_EQUALITY) || symbol_Equal(S, fol_TRUE) ||
+ symbol_Equal(S, fol_FALSE);
+}
+
+static __inline__ TERM fol_Atom(TERM Lit)
+{
+ if (term_TopSymbol(Lit) == fol_NOT)
+ return term_FirstArgument(Lit);
+ else
+ return Lit;
+}
+
+static __inline__ BOOL fol_IsEquality(TERM Term)
+{
+ return term_TopSymbol(Term) == fol_EQUALITY;
+}
+
+
+static __inline__ BOOL fol_IsAssignment(TERM Term)
+{
+ return (term_TopSymbol(Term) == fol_EQUALITY &&
+ ((term_IsVariable(term_FirstArgument(Term)) &&
+ !term_ContainsVariable(term_SecondArgument(Term),
+ term_TopSymbol(term_FirstArgument(Term)))) ||
+ (term_IsVariable(term_SecondArgument(Term)) &&
+ !term_ContainsVariable(term_FirstArgument(Term),
+ term_TopSymbol(term_SecondArgument(Term))))));
+}
+
+
+static __inline__ LIST fol_DeleteFalseTermFromList(LIST List)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: The list where all terms equal to the 'False' term are removed.
+ EFFECTS: 'False' is a special predicate from the fol module.
+ Terms are compared with respect to the term_Equal function.
+ The terms are deleted, too.
+***************************************************************/
+{
+ return list_DeleteElementIfFree(List, (BOOL (*)(POINTER))fol_IsFalse,
+ (void (*)(POINTER))term_Delete);
+}
+
+
+static __inline__ LIST fol_DeleteTrueTermFromList(LIST List)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: The list where all terms equal to the 'True' term are removed.
+ EFFECTS: 'True' is a special predicate from the fol module.
+ Terms are compared with respect to the term_Equal function.
+ The terms are deleted, too.
+***************************************************************/
+{
+ return list_DeleteElementIfFree(List, (BOOL (*)(POINTER))fol_IsTrue,
+ (void (*)(POINTER))term_Delete);
+}
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void fol_Init(BOOL, PRECEDENCE);
+SYMBOL fol_IsStringPredefined(const char*);
+TERM fol_CreateQuantifier(SYMBOL, LIST, LIST);
+TERM fol_CreateQuantifierAddFather(SYMBOL, LIST, LIST);
+LIST fol_GetNonFOLPredicates(void);
+TERM fol_ComplementaryTerm(TERM);
+LIST fol_GetAssignments(TERM);
+void fol_Free(void);
+void fol_CheckFatherLinks(TERM);
+BOOL fol_FormulaIsClause(TERM);
+void fol_FPrintOtterOptions(FILE*, BOOL, FLAG_TDFG2OTTEROPTIONSTYPE);
+void fol_FPrintOtter(FILE*, LIST, FLAG_TDFG2OTTEROPTIONSTYPE);
+void fol_FPrintDFGSignature(FILE*);
+void fol_PrettyPrintDFG(TERM);
+void fol_PrintDFG(TERM);
+void fol_FPrintDFG(FILE*, TERM);
+void fol_FPrintDFGProblem(FILE*, const char*, const char*, const char*, const char*, LIST, LIST);
+void fol_PrintPrecedence(PRECEDENCE);
+void fol_FPrintPrecedence(FILE*, PRECEDENCE);
+LIST fol_Instances(TERM, TERM);
+LIST fol_Generalizations(TERM, TERM);
+TERM fol_MostGeneralFormula(LIST);
+void fol_NormalizeVars(TERM);
+void fol_NormalizeVarsStartingAt(TERM, SYMBOL);
+LIST fol_FreeVariables(TERM);
+LIST fol_BoundVariables(TERM);
+BOOL fol_VarOccursFreely(TERM,TERM);
+BOOL fol_AssocEquation(TERM, SYMBOL *);
+BOOL fol_DistributiveEquation(TERM, SYMBOL*, SYMBOL*);
+void fol_ReplaceVariable(TERM, SYMBOL, TERM);
+void fol_PrettyPrint(TERM);
+LIST fol_GetSubstEquations(TERM);
+TERM fol_GetBindingQuantifier(TERM, SYMBOL);
+int fol_TermPolarity(TERM, TERM);
+BOOL fol_PolarCheck(TERM, TERM);
+void fol_PopQuantifier(TERM);
+void fol_DeleteQuantifierVariable(TERM,SYMBOL);
+void fol_SetTrue(TERM);
+void fol_SetFalse(TERM);
+void fol_RemoveImplied(TERM);
+BOOL fol_PropagateFreeness(TERM);
+BOOL fol_PropagateWitness(TERM);
+BOOL fol_PropagateTautologies(TERM);
+BOOL fol_AlphaEqual(TERM, TERM);
+BOOL fol_VarBoundTwice(TERM);
+NAT fol_Depth(TERM);
+BOOL fol_ApplyContextToTerm(CONTEXT, TERM);
+BOOL fol_CheckFormula(TERM);
+BOOL fol_SignatureMatchFormula(TERM, TERM, BOOL);
+BOOL fol_SignatureMatch(TERM, TERM, LIST*, BOOL);
+
+#endif
diff --git a/test/spass/graph.c b/test/spass/graph.c
new file mode 100644
index 0000000..732fa0e
--- /dev/null
+++ b/test/spass/graph.c
@@ -0,0 +1,318 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * GRAPHS * */
+/* * * */
+/* * $Module: GRAPH * */
+/* * * */
+/* * Copyright (C) 1998, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "graph.h"
+
+
+static LIST graph_ROOTS; /* used as stack by SCC algorithm */
+static LIST graph_UNFINISHED; /* used as stack by SCC algorithm */
+
+
+void graph_NodePrint(GRAPHNODE Node)
+/**************************************************************
+ INPUT: A graph node.
+ RETURNS: Nothing.
+ EFFECT: Prints some node information to stdout.
+***************************************************************/
+{
+ printf("(%d,%d,%d) ", graph_NodeNumber(Node), graph_NodeDfsNum(Node),
+ graph_NodeCompNum(Node));
+}
+
+
+GRAPH graph_Create(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: A new graph without nodes and edges.
+***************************************************************/
+{
+ GRAPH result;
+
+ result = memory_Malloc(sizeof(GRAPH_STRUCT));
+ result->size = 0;
+ result->dfscount = 0;
+ result->compcount = 0;
+ result->nodes = list_Nil();
+ return result;
+}
+
+
+void graph_Delete(GRAPH Graph)
+/**************************************************************
+ INPUT: A graph.
+ RETURNS: Nothing.
+ EFFECT: All memory required by the graph and its nodes
+ is freed.
+***************************************************************/
+{
+ for ( ; !list_Empty(Graph->nodes); Graph->nodes = list_Pop(Graph->nodes)) {
+ list_Delete(graph_NodeNeighbors(list_Car(Graph->nodes)));
+ memory_Free(list_Car(Graph->nodes), sizeof(GRAPHNODE_STRUCT));
+ }
+ memory_Free(Graph, sizeof(GRAPH_STRUCT));
+}
+
+
+GRAPHNODE graph_GetNode(GRAPH Graph, NAT Number)
+/**************************************************************
+ INPUT: A graph and the ID of a node.
+ RETURNS: The node with the requested number or NULL
+ if such a node doesn't exist.
+***************************************************************/
+{
+ LIST scan;
+
+ for (scan = Graph->nodes; !list_Empty(scan); scan= list_Cdr(scan)) {
+ if (graph_NodeNumber(list_Car(scan)) == Number)
+ return list_Car(scan);
+ }
+
+ return NULL;
+}
+
+
+GRAPHNODE graph_AddNode(GRAPH Graph, NAT Number)
+/**************************************************************
+ INPUT: A graph and the ID of a node.
+ RETURNS: A node with the requested number.
+ EFFECT: If the graph has no such node, a new node is created.
+***************************************************************/
+{
+ GRAPHNODE result;
+
+ result = graph_GetNode(Graph, Number);
+ if (result == NULL) {
+ result = memory_Malloc(sizeof(GRAPHNODE_STRUCT));
+ Graph->nodes = list_Cons(result, Graph->nodes);
+ result->number = Number;
+ result->dfs_num = -1;
+ result->comp_num = -1;
+ result->info = NULL;
+ result->neighbors = list_Nil();
+ }
+ return result;
+}
+
+
+void graph_AddEdge(GRAPHNODE From, GRAPHNODE To)
+/**************************************************************
+ INPUT: Two graph nodes.
+ RETURNS: Nothing.
+ EFFECT: Adds a single (directed) edge (From, To).
+***************************************************************/
+{
+ From->neighbors = list_Cons(To, From->neighbors);
+}
+
+
+void graph_DeleteEdge(GRAPHNODE From, GRAPHNODE To)
+/**************************************************************
+ INPUT: Two graph nodes.
+ RETURNS: Nothing.
+ EFFECT: Removes ALL edges (From, To) from a graph.
+***************************************************************/
+{
+ From->neighbors = list_PointerDeleteElement(From->neighbors, To);
+}
+
+
+void graph_DeleteDuplicateEdges(GRAPH Graph)
+/**************************************************************
+ INPUT: A graph.
+ RETURNS: Nothing.
+ EFFECT: Removes duplicate edges between all nodes.
+***************************************************************/
+{
+ LIST scan;
+
+ for (scan = graph_Nodes(Graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+ GRAPHNODE n = list_Car(scan);
+ n->neighbors = list_PointerDeleteDuplicates(n->neighbors);
+ }
+}
+
+
+void graph_SortNodes(GRAPH Graph, BOOL (*SortFunction)(GRAPHNODE, GRAPHNODE))
+/**************************************************************
+ INPUT: A graph and a sorting function for graph nodes.
+ RETURNS: Nothing.
+ EFFECT: The node list is sorted with respect to the
+ sorting function.
+***************************************************************/
+{
+ Graph->nodes = list_Sort(graph_Nodes(Graph),
+ (BOOL (*) (POINTER, POINTER)) SortFunction);
+}
+
+
+static void graph_ReinitDFS(GRAPH Graph)
+/**************************************************************
+ INPUT: A graph.
+ RETURNS: Nothing.
+ EFFECT: Prepares the graph and its nodes for a new DFS run.
+ The DFS and COMP numbers are reset.
+***************************************************************/
+{
+ LIST scan;
+
+ Graph->dfscount = 0;
+ Graph->compcount = 0;
+
+ for (scan = graph_Nodes(Graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+ graph_NodeSetDfsNum(list_Car(scan), -1);
+ graph_NodeSetCompNum(list_Car(scan), -1);
+ }
+}
+
+
+static void graph_InternSCC(GRAPH Graph, GRAPHNODE Node)
+/**************************************************************
+ INPUT: A graph and a node of the graph.
+ RETURNS: Nothing.
+ EFFECT: This is an internal function used by
+ graph_StronglyConnnectedComponents.
+ It sets information in the graph structure which
+ specifies the strongly connected components of
+ the graph.
+***************************************************************/
+{
+ GRAPHNODE n;
+ LIST scan;
+ NAT act_dfs;
+
+ act_dfs = (Graph->dfscount)++;
+ graph_NodeSetDfsNum(Node, act_dfs);
+
+ graph_UNFINISHED = list_Push(Node, graph_UNFINISHED);
+ graph_ROOTS = list_Push(Node, graph_ROOTS);
+
+ /* putchar('\n'); list_Apply(graph_NodePrint, graph_UNFINISHED);
+ putchar('\n'); list_Apply(graph_NodePrint, graph_ROOTS);
+ fflush(stdout); DBG */
+
+ for (scan = graph_NodeNeighbors(Node);
+ !list_Empty(scan); scan = list_Cdr(scan)) {
+ n = list_Car(scan);
+ if (!graph_NodeVisited(n)) {
+ graph_InternSCC(Graph, n); /* Visit <n> */
+ } else if (!graph_NodeCompleted(n)) {
+ /* <n> was visited but is not yet in a permanent component */
+ NAT dfs_num_of_n = graph_NodeDfsNum(n);
+ while (!list_StackEmpty(graph_ROOTS) &&
+ graph_NodeDfsNum(list_Top(graph_ROOTS)) > dfs_num_of_n)
+ graph_ROOTS = list_Pop(graph_ROOTS);
+ /* putchar('\n'); list_Apply(symbol_Print, graph_UNFINISHED);
+ putchar('\n'); list_Apply(symbol_Print, graph_ROOTS);
+ fflush(stdout); DBG */
+ }
+ }
+
+ /* printf("\nDFS(%u) complete.", graph_NodeNumber(Node)); DBG */
+
+ if (Node == list_Top(graph_ROOTS)) {
+ /* Node is root of a component, so make this component permanent */
+ while (!list_StackEmpty(graph_UNFINISHED) &&
+ graph_NodeDfsNum(list_Top(graph_UNFINISHED)) >= act_dfs) {
+ n = list_Top(graph_UNFINISHED);
+ graph_UNFINISHED = list_Pop(graph_UNFINISHED);
+ graph_NodeSetCompNum(n, Graph->compcount);
+ }
+ Graph->compcount++;
+ graph_ROOTS = list_Pop(graph_ROOTS);
+ }
+
+ /* putchar('\n'); list_Apply(graph_NodePrint, graph_UNFINISHED);
+ putchar('\n'); list_Apply(graph_NodePrint, graph_ROOTS); fflush(stdout); DBG */
+}
+
+
+NAT graph_StronglyConnectedComponents(GRAPH Graph)
+/**************************************************************
+ INPUT: A graph.
+ RETURNS: The number of strongly connected components
+ in the graph.
+ EFFECT: This function sets the component numbers of all nodes.
+ Two nodes that belong to the same component will have
+ the same component number.
+ The algorithm is taken from the script
+ "Datenstrukturen und Algorithmen" by Kurt Mehlhorn
+ in winter semester 1997/98, pages 86-92.
+***************************************************************/
+{
+ LIST scan;
+
+ if (Graph->dfscount != 0)
+ graph_ReinitDFS(Graph); /* Reinitializations for Depth First Search */
+
+ graph_ROOTS = list_Nil();
+ graph_UNFINISHED = list_Nil();
+
+ for (scan = graph_Nodes(Graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+ if (!graph_NodeVisited(list_Car(scan)))
+ graph_InternSCC(Graph, list_Car(scan));
+ }
+ return Graph->compcount;
+}
+
+
+void graph_Print(GRAPH Graph)
+/**************************************************************
+ INPUT: A graph.
+ RETURNS: Nothing.
+ EFFECT: The adjacency list representation of the graph
+ is printed to stdout.
+***************************************************************/
+{
+ LIST scan1, scan2;
+
+ for (scan1 = graph_Nodes(Graph); !list_Empty(scan1); scan1 = list_Cdr(scan1)) {
+ printf("\n%u -> ", graph_NodeNumber(list_Car(scan1)));
+ for (scan2 = graph_NodeNeighbors(list_Car(scan1)); !list_Empty(scan2);
+ scan2 = list_Cdr(scan2)) {
+ printf("%u,", graph_NodeNumber(list_Car(scan2)));
+ }
+ }
+}
diff --git a/test/spass/graph.h b/test/spass/graph.h
new file mode 100644
index 0000000..411f4f2
--- /dev/null
+++ b/test/spass/graph.h
@@ -0,0 +1,148 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * GRAPHS * */
+/* * * */
+/* * $Module: GRAPH * */
+/* * * */
+/* * Copyright (C) 1998, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _GRAPH_
+#define _GRAPH_
+
+#include "list.h"
+
+typedef struct {
+ NAT number;
+ int dfs_num;
+ int comp_num; /* completion number */
+ POINTER info; /* user defined information */
+ LIST neighbors;
+} GRAPHNODE_STRUCT, *GRAPHNODE;
+
+typedef struct {
+ NAT size; /* number of nodes */
+ LIST nodes; /* list of GRAPHNODES */
+ NAT dfscount; /* used for DFS */
+ NAT compcount; /* used for DFS */
+} GRAPH_STRUCT, *GRAPH;
+
+static __inline__ NAT graph_NodeNumber(GRAPHNODE Node)
+{
+ return Node->number;
+}
+
+static __inline__ int graph_NodeDfsNum(GRAPHNODE Node)
+{
+ return Node->dfs_num;
+}
+
+static __inline__ void graph_NodeSetDfsNum(GRAPHNODE Node, int Number)
+{
+ Node->dfs_num = Number;
+}
+
+static __inline__ int graph_NodeCompNum(GRAPHNODE Node)
+{
+ return Node->comp_num;
+}
+
+static __inline__ void graph_NodeSetCompNum(GRAPHNODE Node, int Number)
+{
+ Node->comp_num = Number;
+}
+
+static __inline__ LIST graph_NodeNeighbors(GRAPHNODE Node)
+{
+ return Node->neighbors;
+}
+
+static __inline__ POINTER graph_NodeInfo(GRAPHNODE Node)
+{
+ return Node->info;
+}
+
+static __inline__ void graph_NodeSetInfo(GRAPHNODE Node, POINTER Info)
+{
+ Node->info = Info;
+}
+
+static __inline__ NAT graph_NodeOutdegree(GRAPHNODE Node)
+{
+ return list_Length(graph_NodeNeighbors(Node));
+}
+
+static __inline__ BOOL graph_NodeVisited(GRAPHNODE Node)
+{
+ return graph_NodeDfsNum(Node) >= 0;
+}
+
+static __inline__ BOOL graph_NodeCompleted(GRAPHNODE Node)
+{
+ return graph_NodeCompNum(Node) >= 0;
+}
+
+static __inline__ NAT graph_Size(GRAPH Graph)
+{
+ return Graph->size;
+}
+
+static __inline__ LIST graph_Nodes(GRAPH Graph)
+{
+ return Graph->nodes;
+}
+
+GRAPH graph_Create(void);
+void graph_Delete(GRAPH);
+
+GRAPHNODE graph_GetNode(GRAPH, NAT);
+GRAPHNODE graph_AddNode(GRAPH, NAT);
+
+void graph_AddEdge(GRAPHNODE, GRAPHNODE);
+void graph_DeleteEdge(GRAPHNODE, GRAPHNODE);
+void graph_DeleteDuplicateEdges(GRAPH);
+
+void graph_SortNodes(GRAPH, BOOL (*)(GRAPHNODE, GRAPHNODE));
+NAT graph_StronglyConnectedComponents(GRAPH);
+
+void graph_NodePrint(GRAPHNODE Node);
+void graph_Print(GRAPH);
+
+#endif
diff --git a/test/spass/hash.c b/test/spass/hash.c
new file mode 100644
index 0000000..d9f996c
--- /dev/null
+++ b/test/spass/hash.c
@@ -0,0 +1,115 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SIMPLE HASHING * */
+/* * * */
+/* * $Module: HASH * */
+/* * * */
+/* * Copyright (C) 1996, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "hash.h"
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+LIST hash_TABLE[hash__SIZE];
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void hash_Init(void)
+{
+ int i;
+
+ for (i = 0; i < hash__SIZE; i++)
+ hash_PutList(i, list_Nil());
+}
+
+void hash_Reset(void)
+{
+ int i;
+ LIST Scan;
+
+ for (i = 0; i < hash__SIZE; i++) {
+ Scan = hash_List(i);
+ while (!list_Empty(Scan)) {
+ list_Free(list_Car(Scan));
+ Scan = list_Cdr(Scan);
+ }
+ list_Delete(hash_List(i));
+ hash_PutList(i, list_Nil());
+ }
+}
+
+void hash_ResetWithValue(void (*ValueDelete)(POINTER))
+{
+ int i;
+ LIST Scan;
+
+ for (i = 0; i < hash__SIZE; i++) {
+ Scan = hash_List(i);
+ while (!list_Empty(Scan)) {
+ ValueDelete(list_PairSecond(list_Car(Scan)));
+ list_Free(list_Car(Scan));
+ Scan = list_Cdr(Scan);
+ }
+ list_Delete(hash_List(i));
+ hash_PutList(i, list_Nil());
+ }
+}
+
+POINTER hash_Get(POINTER key)
+{
+ LIST Scan;
+
+ Scan = hash_List(hash_Index(key));
+
+ while (!list_Empty(Scan)) {
+ if (list_PairFirst(list_Car(Scan)) == key)
+ return list_PairSecond(list_Car(Scan));
+ Scan = list_Cdr(Scan);
+ }
+
+ return NULL;
+}
diff --git a/test/spass/hash.h b/test/spass/hash.h
new file mode 100644
index 0000000..3556e5d
--- /dev/null
+++ b/test/spass/hash.h
@@ -0,0 +1,107 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SIMPLE HASHING * */
+/* * * */
+/* * $Module: HASH * */
+/* * * */
+/* * Copyright (C) 1996, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _HASH_
+#define _HASH_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "list.h"
+
+
+/**************************************************************/
+/* Structures */
+/**************************************************************/
+
+#define hash__SIZE 29 /* a prime */
+
+/* Each Entry is a list of pairs <key,value> */
+extern LIST hash_TABLE[hash__SIZE];
+
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+static __inline__ NAT hash_Index(POINTER Key)
+{
+ return (NAT)Key % hash__SIZE;
+}
+
+static __inline__ LIST hash_List(NAT Index)
+{
+ return hash_TABLE[Index];
+}
+
+static __inline__ void hash_PutList(NAT Index, LIST List)
+{
+ hash_TABLE[Index] = List;
+}
+
+static __inline__ void hash_Put(POINTER Key, POINTER Value)
+{
+ hash_PutList(hash_Index(Key), list_Cons(list_PairCreate((POINTER)Key, Value),
+ hash_List(hash_Index(Key))));
+}
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void hash_Init(void);
+void hash_Reset(void);
+void hash_ResetWithValue(void (*)(POINTER));
+
+POINTER hash_Get(POINTER);
+
+
+#endif
+
+
diff --git a/test/spass/hasharray.c b/test/spass/hasharray.c
new file mode 100644
index 0000000..9822b71
--- /dev/null
+++ b/test/spass/hasharray.c
@@ -0,0 +1,138 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * HASHING * */
+/* * * */
+/* * $Module: HASHARRAY * */
+/* * * */
+/* * Copyright (C) 1997, 1998, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "hasharray.h"
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+HASH hsh_Create(void)
+/**************************************************************
+ RETURNS: A new, empty hasharray
+***************************************************************/
+{
+ HASH h;
+ NAT l;
+ h = (LIST*) memory_Malloc(sizeof(LIST) * hsh__SIZE);
+ for (l=0; l < hsh__SIZE; l++)
+ h[l] = list_Nil();
+ return h;
+}
+
+void hsh_Reset(HASH H)
+/**************************************************************
+ INPUT: A hasharray
+ EFFECT: Deletes all information stored in the array but keeps
+ the array itself.
+ Keys and data items are not deleted !
+***************************************************************/
+{
+ int i;
+ LIST Scan, Pair;
+ for (i = 0; i < hsh__SIZE; i++) {
+ for (Scan = H[i]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ list_Delete(list_PairSecond(Pair));
+ list_PairFree(Pair);
+ }
+ list_Delete(H[i]);
+ H[i] = list_Nil();
+ }
+}
+
+void hsh_Delete(HASH H)
+/**************************************************************
+ INPUT: A hasharray
+ EFFECT: Deletes all information stored in the array and
+ the array itself.
+ Keys and data items are not deleted !
+***************************************************************/
+{
+ hsh_Reset(H);
+ memory_Free(H, sizeof(LIST) * hsh__SIZE);
+}
+
+LIST hsh_GetAllEntries(HASH H)
+/**************************************************************
+ INPUT: A hasharray
+ RETURNS: A new list of all data items stored in the hasharray
+***************************************************************/
+{
+ LIST Scan, Result;
+ NAT i;
+ Result = list_Nil();
+ for (i = 0; i < hsh__SIZE; i++) {
+ for (Scan = H[i]; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ Result = list_Nconc(Result, list_Copy(list_PairSecond(list_Car(Scan))));
+ }
+ return Result;
+}
+
+void hsh_Check(HASH H)
+/**************************************************************
+ INPUT: A hasharray
+ EFFECT: Traverses the whole array and the lists to find dangling pointers.
+***************************************************************/
+{
+ LIST Scan, Scan2, Pair;
+ NAT i;
+ unsigned long Key;
+ for (i = 0; i < hsh__SIZE; i++) {
+ for (Scan = H[i]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ Key = (unsigned long)list_PairFirst(Pair);
+ for (Scan2 = list_PairSecond(Pair); !list_Empty(Scan2); Scan2 = list_Cdr(Scan2)) {
+ POINTER Value;
+ char Z;
+ Value = list_Car(Scan2);
+ Z = * ((char*) Value);
+ }
+ }
+ }
+}
diff --git a/test/spass/hasharray.h b/test/spass/hasharray.h
new file mode 100644
index 0000000..de6e118
--- /dev/null
+++ b/test/spass/hasharray.h
@@ -0,0 +1,246 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * HASHING * */
+/* * * */
+/* * $Module: HASHARRAY * */
+/* * * */
+/* * Copyright (C) 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _HASHARRAY_
+#define _HASHARRAY_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "list.h"
+
+/**************************************************************/
+/* Structures */
+/**************************************************************/
+
+#define hsh__SIZE 29 /* a prime */
+
+/* Each Entry is a list of pairs <key,list of values> */
+
+typedef LIST* HASH;
+
+void hsh_Check(HASH H);
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+static __inline__ unsigned long hsh_Index(POINTER Key)
+/**************************************************************
+ INPUT: A pointer
+ RETURNS: A key for the hasharray
+***************************************************************/
+{
+ return (unsigned long)Key % hsh__SIZE;
+}
+
+static __inline__ void hsh_Put(HASH H, POINTER Key, POINTER Value)
+/**************************************************************
+ INPUT: A hasharray, a pointer used as key and a pointer to a data item
+ EFFECT: Add Value to the list of data items associated with the key,
+ if it isn't a member already
+***************************************************************/
+{
+ LIST Scan, Pair;
+ unsigned long HashKey;
+ HashKey = hsh_Index(Key);
+ for (Scan = H[HashKey]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ if (list_PairFirst(Pair) == Key) {
+ if (!list_PointerMember(list_PairSecond(Pair), Value))
+ list_Rplacd(Pair, list_Cons(Value, list_PairSecond(Pair)));
+#ifdef CHECK
+ hsh_Check(H);
+#endif
+ return;
+ }
+ }
+ H[HashKey] = list_Cons(list_PairCreate(Key, list_List(Value)), H[HashKey]);
+#ifdef CHECK
+ hsh_Check(H);
+#endif
+}
+
+static __inline__ void hsh_PutList(HASH H, POINTER Key, LIST List)
+/**************************************************************
+ INPUT: A hasharray, a pointer used as key and a list of data items
+ EFFECT: Add the list to the list of data items associated with the key,
+ and delete all duplicates.
+***************************************************************/
+{
+ LIST Scan, Pair;
+ unsigned long HashKey;
+
+ HashKey = hsh_Index(Key);
+ for (Scan = H[HashKey]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ if (list_PairFirst(Pair) == Key) {
+ list_Rplacd(Pair, list_Nconc(list_PairSecond(Pair), List));
+#ifdef CHECK
+ hsh_Check(H);
+#endif
+ return;
+ }
+ }
+ H[HashKey] = list_Cons(list_PairCreate(Key, List), H[HashKey]);
+#ifdef CHECK
+ hsh_Check(H);
+#endif
+}
+
+static __inline__ void hsh_PutListWithCompareFunc(HASH H, POINTER Key,
+ LIST List,
+ BOOL (*Test)(POINTER, POINTER),
+ unsigned long (*HashFunc)(POINTER))
+/**************************************************************
+ INPUT: A hasharray, a pointer used as key, a list of data
+ items, a test function for key equality and a
+ hashing function.
+ EFFECT: Add the list to the list of data items associated
+ with the key, and delete all duplicates.
+***************************************************************/
+{
+ LIST Scan, Pair;
+ unsigned long HashKey;
+
+ HashKey = (unsigned long) HashFunc(Key);
+ for (Scan = H[HashKey]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Pair = (LIST) list_Car(Scan);
+ if (Test(list_PairFirst(Pair), Key)) {
+ list_Rplacd(Pair, list_Nconc(list_PairSecond(Pair), List));
+#ifdef CHECK
+ hsh_Check(H);
+#endif
+ return;
+ }
+ }
+ H[HashKey] = list_Cons(list_PairCreate(Key, List), H[HashKey]);
+#ifdef CHECK
+ hsh_Check(H);
+#endif
+}
+
+static __inline__ LIST hsh_Get(HASH H, POINTER Key)
+/**************************************************************
+ INPUT: A hasharray and a pointer used as key
+ RETURNS: The list of data items associated with the key
+***************************************************************/
+{
+ LIST Scan, Pair;
+
+ for (Scan = H[hsh_Index(Key)]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ if (list_PairFirst(Pair) == Key)
+ return list_PairSecond(Pair);
+ }
+ return NULL;
+}
+
+static __inline__ void hsh_DelItem(HASH H, POINTER Key)
+/**************************************************************
+ INPUT: A hasharray and a pointer used as key
+ RETURNS: The information associated with the key is deleted
+***************************************************************/
+{
+ LIST Scan, Pair;
+ unsigned long k;
+
+ k = hsh_Index(Key);
+ for (Scan = H[k]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ if (list_PairFirst(Pair) == Key) {
+ list_Delete(list_PairSecond(Pair));
+ list_PairFree(Pair);
+ H[k] = list_PointerDeleteElement(H[k], Pair);
+ return;
+ }
+ }
+}
+
+static __inline__ LIST hsh_GetWithCompareFunc(HASH H, POINTER Key,
+ BOOL (*Test)(POINTER, POINTER),
+ unsigned long (*HashFunc)(POINTER))
+/**************************************************************
+ INPUT: A hasharray, a pointer used as key, a compare function
+ for keys and a hash function for keys.
+ RETURNS: The list of data items associated with the key
+***************************************************************/
+{
+ LIST Scan, Pair;
+
+ for (Scan = H[HashFunc(Key)]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ if (Test(list_PairFirst(Pair), Key))
+ return list_PairSecond(Pair);
+ }
+ return NULL;
+}
+
+
+static __inline__ unsigned long hsh_StringHashKey(const char* Label)
+{
+ unsigned long i, s;
+ s = 0;
+ for (i = 0; i <= strlen(Label); i++)
+ s += Label[i];
+ s = s % hsh__SIZE;
+ return s;
+}
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+HASH hsh_Create(void);
+void hsh_Reset(HASH H);
+void hsh_Delete(HASH H);
+LIST hsh_GetAllEntries(HASH H);
+
+#endif
+
+
diff --git a/test/spass/ia.h b/test/spass/ia.h
new file mode 100644
index 0000000..4cf2fb9
--- /dev/null
+++ b/test/spass/ia.h
@@ -0,0 +1,58 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INTERFACE FOR SPASS INTERACTICE MODE * */
+/* * * */
+/* * $Module: DFG * */
+/* * * */
+/* * Copyright (C) 1997, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _IA_
+#define _IA_
+
+#include <stdio.h>
+#include "list.h"
+#include "flags.h"
+
+/* Parser functions */
+LIST ia_GetNextRequest(FILE*,FLAGSTORE); /* Returns a pair! */
+
+#endif
diff --git a/test/spass/iaparser.c b/test/spass/iaparser.c
new file mode 100644
index 0000000..4fa8697
--- /dev/null
+++ b/test/spass/iaparser.c
@@ -0,0 +1,1773 @@
+/* A Bison parser, made from iaparser.y, by GNU bison 1.75. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ 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, 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. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+ names. */
+#define yyparse ia_parse
+#define yylex ia_lex
+#define yyerror ia_error
+#define yylval ia_lval
+#define yychar ia_char
+#define yydebug ia_debug
+#define yynerrs ia_nerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ IA_AND = 258,
+ IA_EQUAL = 259,
+ IA_EQUIV = 260,
+ IA_EXISTS = 261,
+ IA_FALSE = 262,
+ IA_FORALL = 263,
+ IA_IMPLIED = 264,
+ IA_IMPLIES = 265,
+ IA_NOT = 266,
+ IA_OR = 267,
+ IA_PROVE = 268,
+ IA_TRUE = 269,
+ IA_NUM = 270,
+ IA_ID = 271
+ };
+#endif
+#define IA_AND 258
+#define IA_EQUAL 259
+#define IA_EQUIV 260
+#define IA_EXISTS 261
+#define IA_FALSE 262
+#define IA_FORALL 263
+#define IA_IMPLIED 264
+#define IA_IMPLIES 265
+#define IA_NOT 266
+#define IA_OR 267
+#define IA_PROVE 268
+#define IA_TRUE 269
+#define IA_NUM 270
+#define IA_ID 271
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 48 "iaparser.y"
+
+
+#include "flags.h"
+#include "ia.h"
+#include "symbol.h"
+#include "term.h"
+#include "foldfg.h"
+#include "clause.h"
+
+extern NAT dfg_LINENUMBER; /* Defined in dfgparser.y */
+LIST ia_PROOFREQUEST; /* A pair! */
+FLAGSTORE ia_FLAGS;
+
+void yyerror(const char*);
+int yylex(void); /* Defined in iascanner.l */
+
+static SYMBOL ia_Symbol(char*, NAT);
+static TERM ia_CreateQuantifier(SYMBOL, LIST, TERM);
+
+static __inline__ void ia_StringFree(char* String)
+{
+ memory_Free(String, sizeof(char)*(strlen(String)+1));
+}
+
+static __inline__ TERM ia_TermCreate(char* Name, LIST Arguments)
+/* Look up the symbol, check its arity and create the term */
+{
+ return term_Create(ia_Symbol(Name,list_Length(Arguments)), Arguments);
+}
+
+/**************************************************************/
+/* Functions to check the arity of symbols */
+/**************************************************************/
+
+static void ia_SymCheck(SYMBOL, NAT);
+
+/**************************************************************/
+/* Functions that handle variable names */
+/**************************************************************/
+
+/* List of quantified variables in the current input formula. */
+/* This list is used to find symbols that by mistake weren't */
+/* declared in the symbol declaration section */
+/* --> free variables */
+/* This is a list of lists, since each time a quantifier is */
+/* reached, a new list is added to the global list. */
+static LIST ia_VARLIST;
+static BOOL ia_VARDECL;
+
+static void ia_VarStart(void);
+static void ia_VarStop(void);
+static void ia_VarBacktrack(void);
+static void ia_VarCheck(void);
+static SYMBOL ia_VarLookup(char*);
+
+#define YY_INPUT(buf,result,max_size) \
+{ \
+ int c = getc(ia_in); \
+ result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
+}
+
+#define YYERROR_VERBOSE
+
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#ifndef YYSTYPE
+#line 113 "iaparser.y"
+typedef union {
+ int number;
+ char* string;
+ SYMBOL symbol;
+ TERM term;
+ LIST list;
+} yystype;
+/* Line 193 of /opt/gnu//share/bison/yacc.c. */
+#line 187 "iaparser.c"
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#ifndef YYLTYPE
+typedef struct yyltype
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} yyltype;
+# define YYLTYPE yyltype
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 213 of /opt/gnu//share/bison/yacc.c. */
+#line 208 "iaparser.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# else
+# ifndef YYSTACK_USE_ALLOCA
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC malloc
+# define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAX)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 4
+#define YYLAST 83
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 23
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 16
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 36
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 77
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 271
+
+#define YYTRANSLATE(X) \
+ ((unsigned)(X) <= YYMAXUTOK ? yytranslate[X] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 17, 19, 2, 2, 18, 2, 20, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 21, 2, 22, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned char yyprhs[] =
+{
+ 0, 0, 3, 4, 14, 16, 20, 22, 24, 26,
+ 31, 38, 43, 48, 49, 50, 61, 62, 63, 74,
+ 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
+ 96, 100, 102, 107, 110, 114, 116
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+ 24, 0, -1, -1, 13, 17, 26, 18, 37, 18,
+ 15, 19, 20, -1, 26, -1, 25, 18, 26, -1,
+ 34, -1, 14, -1, 7, -1, 11, 17, 26, 19,
+ -1, 31, 17, 26, 18, 26, 19, -1, 32, 17,
+ 25, 19, -1, 34, 17, 25, 19, -1, -1, -1,
+ 33, 17, 21, 27, 35, 28, 22, 18, 26, 19,
+ -1, -1, -1, 34, 17, 21, 29, 35, 30, 22,
+ 18, 26, 19, -1, 4, -1, 5, -1, 9, -1,
+ 10, -1, 3, -1, 12, -1, 6, -1, 8, -1,
+ 16, -1, 15, -1, 36, -1, 35, 18, 36, -1,
+ 34, -1, 34, 17, 34, 19, -1, 21, 22, -1,
+ 21, 38, 22, -1, 34, -1, 38, 18, 34, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned char yyrline[] =
+{
+ 0, 136, 136, 137, 149, 150, 153, 154, 155, 156,
+ 158, 160, 162, 164, 165, 164, 170, 171, 170, 179,
+ 180, 181, 182, 185, 186, 189, 190, 193, 194, 197,
+ 198, 201, 211, 232, 233, 236, 237
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "IA_AND", "IA_EQUAL", "IA_EQUIV",
+ "IA_EXISTS", "IA_FALSE", "IA_FORALL", "IA_IMPLIED", "IA_IMPLIES",
+ "IA_NOT", "IA_OR", "IA_PROVE", "IA_TRUE", "IA_NUM", "IA_ID", "'('",
+ "','", "')'", "'.'", "'['", "']'", "$accept", "proofrequest",
+ "termlist", "term", "@1", "@2", "@3", "@4", "binsymbol", "nsymbol",
+ "quantsymbol", "id", "qtermlist", "qterm", "labellistopt", "labellist", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 40, 44, 41,
+ 46, 91, 93
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 23, 24, 24, 25, 25, 26, 26, 26, 26,
+ 26, 26, 26, 27, 28, 26, 29, 30, 26, 31,
+ 31, 31, 31, 32, 32, 33, 33, 34, 34, 35,
+ 35, 36, 36, 37, 37, 38, 38
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 0, 9, 1, 3, 1, 1, 1, 4,
+ 6, 4, 4, 0, 0, 10, 0, 0, 10, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 3, 1, 4, 2, 3, 1, 3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 2, 0, 0, 0, 1, 23, 19, 20, 25, 8,
+ 26, 21, 22, 0, 24, 7, 28, 27, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4, 13, 16, 0, 9, 33,
+ 35, 0, 0, 0, 0, 11, 0, 0, 12, 0,
+ 34, 0, 0, 5, 31, 14, 29, 17, 36, 0,
+ 10, 0, 0, 0, 0, 3, 0, 30, 0, 0,
+ 32, 0, 0, 0, 0, 15, 18
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+ -1, 2, 33, 34, 46, 63, 47, 64, 19, 20,
+ 21, 22, 55, 56, 31, 41
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -29
+static const yysigned_char yypact[] =
+{
+ -12, 12, 35, 0, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, 19, -29, -29, -29, -29, 20, 22,
+ 40, 41, 42, 0, 31, 0, 0, 43, 39, 18,
+ 8, 38, 44, 7, -29, -29, -29, 9, -29, -29,
+ -29, -5, 46, 0, 0, -29, 16, 16, -29, 16,
+ -29, 47, 48, -29, 53, 45, -29, 45, -29, 51,
+ -29, 16, 16, 50, 52, -29, 54, -29, 57, 58,
+ -29, 0, 0, 59, 60, -29, -29
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yysigned_char yypgoto[] =
+{
+ -29, -29, 37, -3, -29, -29, -29, -29, -29, -29,
+ -29, -28, 30, 21, -29, -29
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, parse error. */
+#define YYTABLE_NINF -1
+static const unsigned char yytable[] =
+{
+ 18, 1, 40, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 49, 15, 16, 17, 50, 54, 54,
+ 29, 58, 32, 16, 17, 44, 45, 44, 48, 3,
+ 39, 16, 17, 66, 54, 4, 23, 38, 24, 25,
+ 52, 53, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 30, 15, 16, 17, 42, 26, 27, 28,
+ 36, 51, 43, 62, 35, 37, 59, 60, 73, 74,
+ 61, 65, 68, 70, 69, 71, 72, 57, 75, 76,
+ 0, 0, 0, 67
+};
+
+static const yysigned_char yycheck[] =
+{
+ 3, 13, 30, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 18, 14, 15, 16, 22, 46, 47,
+ 23, 49, 25, 15, 16, 18, 19, 18, 19, 17,
+ 22, 15, 16, 61, 62, 0, 17, 19, 18, 17,
+ 43, 44, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 21, 14, 15, 16, 18, 17, 17, 17,
+ 21, 15, 18, 18, 21, 28, 19, 19, 71, 72,
+ 17, 20, 22, 19, 22, 18, 18, 47, 19, 19,
+ -1, -1, -1, 62
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 13, 24, 17, 0, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 14, 15, 16, 26, 31,
+ 32, 33, 34, 17, 18, 17, 17, 17, 17, 26,
+ 21, 37, 26, 25, 26, 21, 21, 25, 19, 22,
+ 34, 38, 18, 18, 18, 19, 27, 29, 19, 18,
+ 22, 15, 26, 26, 34, 35, 36, 35, 34, 19,
+ 19, 17, 18, 28, 30, 20, 34, 36, 22, 22,
+ 19, 18, 18, 26, 26, 19, 19
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up"); \
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current.first_line = Rhs[1].first_line; \
+ Current.first_column = Rhs[1].first_column; \
+ Current.last_line = Rhs[N].last_line; \
+ Current.last_column = Rhs[N].last_column;
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#define YYLEX yylex ()
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*-----------------------------.
+| Print this symbol on YYOUT. |
+`-----------------------------*/
+
+static void
+#if defined (__STDC__) || defined (__cplusplus)
+yysymprint (FILE* yyout, int yytype, YYSTYPE yyvalue)
+#else
+yysymprint (yyout, yytype, yyvalue)
+ FILE* yyout;
+ int yytype;
+ YYSTYPE yyvalue;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvalue;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyout, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyout, yytoknum[yytype], yyvalue);
+# endif
+ }
+ else
+ YYFPRINTF (yyout, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyout, ")");
+}
+#endif /* YYDEBUG. */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+#if defined (__STDC__) || defined (__cplusplus)
+yydestruct (int yytype, YYSTYPE yyvalue)
+#else
+yydestruct (yytype, yyvalue)
+ int yytype;
+ YYSTYPE yyvalue;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvalue;
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL
+# else
+# define YYPARSE_PARAM_ARG YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of parse errors so far. */
+int yynerrs;
+
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yychar1 = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with. */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more. */
+
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE (yychar);
+
+ /* We have to keep this `#if YYDEBUG', since we use variables
+ which are defined only if `YYDEBUG' is set. */
+ YYDPRINTF ((stderr, "Next token is "));
+ YYDSYMPRINT ((stderr, yychar1, yylval));
+ YYDPRINTF ((stderr, "\n"));
+ }
+
+ /* If the proper action on seeing token YYCHAR1 is to reduce or to
+ detect an error, take that action. */
+ yyn += yychar1;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yychar1)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %d (%s), ",
+ yychar, yytname[yychar1]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+
+#if YYDEBUG
+ /* We have to keep this `#if YYDEBUG', since we use variables which
+ are defined only if `YYDEBUG' is set. */
+ if (yydebug)
+ {
+ int yyi;
+
+ YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
+ yyn - 1, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyn]; yyrhs[yyi] >= 0; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+ YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+ switch (yyn)
+ {
+ case 2:
+#line 136 "iaparser.y"
+ { YYABORT; }
+ break;
+
+ case 3:
+#line 137 "iaparser.y"
+ {
+ ia_VarCheck();
+ ia_PROOFREQUEST = list_PairCreate(yyvsp[-6].term,yyvsp[-4].list);
+ flag_SetFlagValue(ia_FLAGS,flag_TIMELIMIT,yyvsp[-2].number);
+ YYACCEPT;
+ }
+ break;
+
+ case 4:
+#line 149 "iaparser.y"
+ { yyval.list = list_List(yyvsp[0].term); }
+ break;
+
+ case 5:
+#line 150 "iaparser.y"
+ { yyval.list = list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+ break;
+
+ case 6:
+#line 153 "iaparser.y"
+ { yyval.term = ia_TermCreate(yyvsp[0].string, list_Nil()); }
+ break;
+
+ case 7:
+#line 154 "iaparser.y"
+ { yyval.term = term_Create(fol_True(),list_Nil()); }
+ break;
+
+ case 8:
+#line 155 "iaparser.y"
+ { yyval.term = term_Create(fol_False(),list_Nil()); }
+ break;
+
+ case 9:
+#line 157 "iaparser.y"
+ { yyval.term = term_Create(fol_Not(),list_List(yyvsp[-1].term)); }
+ break;
+
+ case 10:
+#line 159 "iaparser.y"
+ { yyval.term = term_Create(yyvsp[-5].symbol, list_Cons(yyvsp[-3].term, list_List(yyvsp[-1].term))); }
+ break;
+
+ case 11:
+#line 161 "iaparser.y"
+ { yyval.term = term_Create(yyvsp[-3].symbol, yyvsp[-1].list); }
+ break;
+
+ case 12:
+#line 163 "iaparser.y"
+ { yyval.term = ia_TermCreate(yyvsp[-3].string, yyvsp[-1].list); }
+ break;
+
+ case 13:
+#line 164 "iaparser.y"
+ { ia_VarStart(); }
+ break;
+
+ case 14:
+#line 165 "iaparser.y"
+ { ia_VarStop(); }
+ break;
+
+ case 15:
+#line 167 "iaparser.y"
+ { ia_VarBacktrack();
+ yyval.term = ia_CreateQuantifier(yyvsp[-9].symbol,yyvsp[-5].list,yyvsp[-1].term);
+ }
+ break;
+
+ case 16:
+#line 170 "iaparser.y"
+ { ia_VarStart(); }
+ break;
+
+ case 17:
+#line 171 "iaparser.y"
+ { ia_VarStop(); }
+ break;
+
+ case 18:
+#line 173 "iaparser.y"
+ { misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: SPASS can't handle the quantifier %s.\n", dfg_LINENUMBER, yyvsp[-9].string);
+ misc_FinishUserErrorReport();
+ }
+ break;
+
+ case 19:
+#line 179 "iaparser.y"
+ { yyval.symbol = fol_Equality(); }
+ break;
+
+ case 20:
+#line 180 "iaparser.y"
+ { yyval.symbol = fol_Equiv(); }
+ break;
+
+ case 21:
+#line 181 "iaparser.y"
+ { yyval.symbol = fol_Implied(); }
+ break;
+
+ case 22:
+#line 182 "iaparser.y"
+ { yyval.symbol = fol_Implies(); }
+ break;
+
+ case 23:
+#line 185 "iaparser.y"
+ { yyval.symbol = fol_And(); }
+ break;
+
+ case 24:
+#line 186 "iaparser.y"
+ { yyval.symbol = fol_Or(); }
+ break;
+
+ case 25:
+#line 189 "iaparser.y"
+ { yyval.symbol = fol_Exist(); }
+ break;
+
+ case 26:
+#line 190 "iaparser.y"
+ { yyval.symbol = fol_All(); }
+ break;
+
+ case 27:
+#line 193 "iaparser.y"
+ { yyval.string = yyvsp[0].string; }
+ break;
+
+ case 28:
+#line 194 "iaparser.y"
+ { yyval.string = string_IntToString(yyvsp[0].number); }
+ break;
+
+ case 29:
+#line 197 "iaparser.y"
+ { yyval.list = list_List(yyvsp[0].term); }
+ break;
+
+ case 30:
+#line 198 "iaparser.y"
+ { yyval.list = list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+ break;
+
+ case 31:
+#line 201 "iaparser.y"
+ { SYMBOL s = ia_Symbol(yyvsp[0].string,0);
+ if (!symbol_IsVariable(s)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: %s",dfg_LINENUMBER,
+ symbol_Name(s));
+ misc_UserErrorReport(" is not a variable.\n");
+ misc_FinishUserErrorReport();
+ }
+ yyval.term = term_Create(s, list_Nil());
+ }
+ break;
+
+ case 32:
+#line 211 "iaparser.y"
+ { SYMBOL p, v;
+ p = ia_Symbol(yyvsp[-3].string, 1);
+ if (!symbol_IsPredicate(p)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: %s",dfg_LINENUMBER,
+ symbol_Name(p));
+ misc_UserErrorReport(" is not a predicate.\n");
+ misc_FinishUserErrorReport();
+ }
+ v = ia_Symbol(yyvsp[-1].string, 0);
+ if (!symbol_IsVariable(v)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: %s",dfg_LINENUMBER,
+ symbol_Name(v));
+ misc_UserErrorReport(" is not a variable.\n");
+ misc_FinishUserErrorReport();
+ }
+ yyval.term = term_Create(p, list_List(term_Create(v,list_Nil())));
+ }
+ break;
+
+ case 33:
+#line 232 "iaparser.y"
+ { yyval.list = list_Nil(); }
+ break;
+
+ case 34:
+#line 233 "iaparser.y"
+ { yyval.list = yyvsp[-1].list; }
+ break;
+
+ case 35:
+#line 236 "iaparser.y"
+ { yyval.list = list_List(yyvsp[0].string); }
+ break;
+
+ case 36:
+#line 237 "iaparser.y"
+ { yyval.list = list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].string)); }
+ break;
+
+
+ }
+
+/* Line 1016 of /opt/gnu//share/bison/yacc.c. */
+#line 1290 "iaparser.c"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+#if YYDEBUG
+ if (yydebug)
+ {
+ short *yyssp1 = yyss - 1;
+ YYFPRINTF (stderr, "state stack now");
+ while (yyssp1 != yyssp)
+ YYFPRINTF (stderr, " %d", *++yyssp1);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ char *yymsg;
+ int yyx, yycount;
+
+ yycount = 0;
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+ yysize += yystrlen ("parse error, unexpected ") + 1;
+ yysize += yystrlen (yytname[yytype]);
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yycount = 0;
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *));
+ yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ const char *yyq = ! yycount ? ", expecting " : " or ";
+ yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yycount++;
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("parse error");
+ }
+ goto yyerrlab1;
+
+
+/*----------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action. |
+`----------------------------------------------------*/
+yyerrlab1:
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ {
+ /* Pop the error token. */
+ YYPOPSTACK;
+ /* Pop the rest of the stack. */
+ while (yyssp > yyss)
+ {
+ YYDPRINTF ((stderr, "Error: popping "));
+ YYDSYMPRINT ((stderr,
+ yystos[*yyssp],
+ *yyvsp));
+ YYDPRINTF ((stderr, "\n"));
+ yydestruct (yystos[*yyssp], *yyvsp);
+ YYPOPSTACK;
+ }
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
+ yychar, yytname[yychar1]));
+ yydestruct (yychar1, yylval);
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ YYDPRINTF ((stderr, "Error: popping "));
+ YYDSYMPRINT ((stderr,
+ yystos[*yyssp], *yyvsp));
+ YYDPRINTF ((stderr, "\n"));
+
+ yydestruct (yystos[yystate], *yyvsp);
+ yyvsp--;
+ yystate = *--yyssp;
+
+
+#if YYDEBUG
+ if (yydebug)
+ {
+ short *yyssp1 = yyss - 1;
+ YYFPRINTF (stderr, "Error: state stack now");
+ while (yyssp1 != yyssp)
+ YYFPRINTF (stderr, " %d", *++yyssp1);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+#line 240 "iaparser.y"
+
+
+
+void yyerror(const char *s)
+{
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %i: %s\n", dfg_LINENUMBER, s);
+ misc_FinishUserErrorReport();
+
+}
+
+LIST ia_GetNextRequest(FILE* Input, FLAGSTORE Flags)
+/**************************************************************
+ INPUT: An input file containing one proof request from KIV.
+ RETURNS: The proof request as pair (formula, labellist),
+ list_Nil(), if EOF was reached.
+ EFFECT: Reads ONE proof request from the file.
+ <Input> may also be a UNIX pipe.
+***************************************************************/
+{
+ extern FILE* ia_in; /* defined in kivscanner */
+
+ ia_in = Input;
+ ia_PROOFREQUEST = list_Nil();
+ ia_FLAGS = Flags;
+ ia_parse();
+
+ return ia_PROOFREQUEST;
+}
+
+
+/**************************************************************/
+/* Static Functions */
+/**************************************************************/
+
+static SYMBOL ia_Symbol(char* Name, NAT Arity)
+/**************************************************************
+ INPUT: The name of a symbol and the actual arity of the symbol.
+ RETURNS: The corresponding SYMBOL.
+ EFFECT: This function checks if the <Name> was declared as
+ symbol or variable. If not, an error message is printed
+ to stderr.
+ The <Name> is deleted.
+***************************************************************/
+{
+ SYMBOL symbol;
+
+ symbol = symbol_Lookup(Name);
+ if (symbol != 0) {
+ ia_StringFree(Name);
+ ia_SymCheck(symbol, Arity); /* Check the arity */
+ } else {
+ /* Variable */
+ if (Arity > 0) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %d: Undefined symbol %s.\n",dfg_LINENUMBER,Name);
+ misc_FinishUserErrorReport();
+ }
+ symbol = ia_VarLookup(Name);
+ }
+ return symbol;
+}
+
+
+static TERM ia_CreateQuantifier(SYMBOL Symbol, LIST VarTermList, TERM Term)
+/**************************************************************
+ INPUT: A quantifier symbol, a list possibly containing sorts,
+ and a term.
+ RETURNS: The created quantifier term..
+***************************************************************/
+{
+ LIST varlist, sortlist, scan;
+ TERM helpterm;
+
+ /* First collect the variable symbols in varlist and the sorts in sortlist */
+ varlist = sortlist = list_Nil();
+ for ( ; !list_Empty(VarTermList); VarTermList = list_Pop(VarTermList)) {
+ helpterm = list_Car(VarTermList);
+ if (term_IsVariable(helpterm)) {
+ varlist = list_Nconc(varlist, list_List((POINTER)term_TopSymbol(helpterm)));
+ term_Delete(helpterm);
+ } else {
+ SYMBOL var = term_TopSymbol(term_FirstArgument(helpterm));
+ varlist = list_Nconc(varlist, list_List((POINTER)var));
+ sortlist = list_Nconc(sortlist, list_List(helpterm));
+ }
+ }
+
+ varlist = list_PointerDeleteDuplicates(varlist);
+ /* Now create terms from the variables */
+ for (scan = varlist; !list_Empty(scan); scan = list_Cdr(scan))
+ list_Rplaca(scan, term_Create((SYMBOL)list_Car(scan), list_Nil()));
+
+ if (!list_Empty(sortlist)) {
+ if (symbol_Equal(fol_All(), Symbol)) {
+ /* The conjunction of all sortterms implies the Term */
+ if (symbol_Equal(fol_Or(), term_TopSymbol(Term))) {
+ /* Special treatment if <Term> is a term with "or" like */
+ /* in clauses: add all sort terms negated to the args */
+ /* of the "or" */
+ for (scan = sortlist; !list_Empty(scan); scan = list_Cdr(scan))
+ /* Negate the sort terms */
+ list_Rplaca(scan, term_Create(fol_Not(), list_List(list_Car(scan))));
+ sortlist = list_Nconc(sortlist, term_ArgumentList(Term));
+ term_RplacArgumentList(Term, sortlist);
+ } else {
+ /* No "or" term, so build the implication term */
+ if (list_Empty(list_Cdr(sortlist))) {
+ /* Only one sort term */
+ list_Rplacd(sortlist, list_List(Term));
+ Term = term_Create(fol_Implies(), sortlist);
+ } else {
+ /* More than one sort term */
+ helpterm = term_Create(fol_And(), sortlist);
+ Term = term_Create(fol_Implies(), list_Cons(helpterm, list_List(Term)));
+ }
+ }
+ } else if (symbol_Equal(fol_Exist(), Symbol)) {
+ /* Quantify the conjunction of all sort terms and <Term> */
+ if (symbol_Equal(fol_And(), term_TopSymbol(Term))) {
+ /* Special treatment if <Term> has an "and" as top symbol: */
+ /* just add the sort terms to the args of the "and". */
+ sortlist = list_Nconc(sortlist, term_ArgumentList(Term));
+ term_RplacArgumentList(Term, sortlist);
+ } else {
+ sortlist = list_Nconc(sortlist, list_List(Term));
+ Term = term_Create(fol_And(), sortlist);
+ }
+ }
+ }
+ helpterm = fol_CreateQuantifier(Symbol, varlist, list_List(Term));
+ return helpterm;
+}
+
+
+/**************************************************************/
+/* Functions for the Symbol Table */
+/**************************************************************/
+
+static void ia_SymCheck(SYMBOL Symbol, NAT Arity)
+/**************************************************************
+ INPUT: A symbol and the current arity of this symbol.
+ RETURNS: Nothing.
+ EFFECT: This function compares the previous arity of 'Symbol'
+ with the actual 'Arity'. If these values differ
+ a warning is printed to stderr and the program exits.
+***************************************************************/
+{
+ /* Check if the specified arity corresponds with the actual arity */
+ if (symbol_Arity(Symbol) != symbol_ArbitraryArity() &&
+ symbol_Arity(Symbol) != Arity) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %u: Symbol %s", dfg_LINENUMBER, symbol_Name(Symbol));
+ misc_UserErrorReport(" was declared with arity %u.\n", symbol_Arity(Symbol));
+ misc_FinishUserErrorReport();
+ }
+}
+
+
+/**************************************************************/
+/* Functions for the Variable Table */
+/**************************************************************/
+
+typedef struct {
+ char* name;
+ SYMBOL symbol;
+} IA_VARENTRY, *IA_VAR;
+
+static __inline__ char* ia_VarName(IA_VAR Entry)
+{
+ return Entry->name;
+}
+
+static __inline__ SYMBOL ia_VarSymbol(IA_VAR Entry)
+{
+ return Entry->symbol;
+}
+
+static __inline__ IA_VAR ia_VarCreate(void)
+{
+ return (IA_VAR) memory_Malloc(sizeof(IA_VARENTRY));
+}
+
+static void ia_VarFree(IA_VAR Entry)
+{
+ ia_StringFree(Entry->name);
+ memory_Free(Entry, sizeof(IA_VARENTRY));
+}
+
+static void ia_VarStart(void)
+{
+ ia_VARLIST = list_Push(list_Nil(), ia_VARLIST);
+ ia_VARDECL = TRUE;
+}
+
+static void ia_VarStop(void)
+{
+ ia_VARDECL = FALSE;
+}
+
+static void ia_VarBacktrack(void)
+{
+ list_DeleteWithElement(list_Top(ia_VARLIST), (void (*)(POINTER)) ia_VarFree);
+ ia_VARLIST = list_Pop(ia_VARLIST);
+}
+
+static void ia_VarCheck(void)
+/* Should be called after a complete clause or formula was parsed */
+{
+ if (!list_Empty(ia_VARLIST)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ia_VarCheck: List of variables should be empty!\n");
+ misc_FinishErrorReport();
+ }
+ symbol_ResetStandardVarCounter();
+}
+
+static SYMBOL ia_VarLookup(char* Name)
+/**************************************************************
+ INPUT: A variable name.
+ RETURNS: The corresponding variable symbol.
+ EFFECT: If the variable name was quantified before, the
+ corresponding symbol is returned and the <Name> is freed.
+ If the variable name was not quantified, and <ia_VARDECL>
+ is TRUE, a new variable is created, else an error
+ message is printed and the program exits.
+***************************************************************/
+{
+ LIST scan, scan2;
+ SYMBOL symbol;
+
+ symbol = symbol_Null();
+
+ scan = ia_VARLIST;
+ scan2 = list_Nil();
+ while (!list_Empty(scan) && list_Empty(scan2)) {
+ scan2 = list_Car(scan);
+ while (!list_Empty(scan2) &&
+ !string_Equal(ia_VarName(list_Car(scan2)), Name))
+ scan2 = list_Cdr(scan2);
+ scan = list_Cdr(scan);
+ }
+
+ if (!list_Empty(scan2)) {
+ /* Found variable */
+ ia_StringFree(Name);
+ symbol = ia_VarSymbol(list_Car(scan2));
+ } else {
+ /* Variable not found */
+ if (ia_VARDECL) {
+ IA_VAR newEntry = ia_VarCreate();
+ newEntry->name = Name;
+ newEntry->symbol = symbol_CreateStandardVariable();
+ /* Add <newentry> to the first list in ia_VARLIST */
+ list_Rplaca(ia_VARLIST, list_Cons(newEntry,list_Car(ia_VARLIST)));
+ symbol = ia_VarSymbol(newEntry);
+ } else {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Line %u: Free Variable %s.\n", dfg_LINENUMBER, Name);
+ misc_FinishUserErrorReport();
+ }
+ }
+ return symbol;
+}
+
diff --git a/test/spass/iaparser.h b/test/spass/iaparser.h
new file mode 100644
index 0000000..32fb093
--- /dev/null
+++ b/test/spass/iaparser.h
@@ -0,0 +1,87 @@
+/* A Bison parser, made from iaparser.y, by GNU bison 1.75. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ 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, 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. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+#ifndef BISON_IAPARSER_H
+# define BISON_IAPARSER_H
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ IA_AND = 258,
+ IA_EQUAL = 259,
+ IA_EQUIV = 260,
+ IA_EXISTS = 261,
+ IA_FALSE = 262,
+ IA_FORALL = 263,
+ IA_IMPLIED = 264,
+ IA_IMPLIES = 265,
+ IA_NOT = 266,
+ IA_OR = 267,
+ IA_PROVE = 268,
+ IA_TRUE = 269,
+ IA_NUM = 270,
+ IA_ID = 271
+ };
+#endif
+#define IA_AND 258
+#define IA_EQUAL 259
+#define IA_EQUIV 260
+#define IA_EXISTS 261
+#define IA_FALSE 262
+#define IA_FORALL 263
+#define IA_IMPLIED 264
+#define IA_IMPLIES 265
+#define IA_NOT 266
+#define IA_OR 267
+#define IA_PROVE 268
+#define IA_TRUE 269
+#define IA_NUM 270
+#define IA_ID 271
+
+
+
+
+#ifndef YYSTYPE
+#line 113 "iaparser.y"
+typedef union {
+ int number;
+ char* string;
+ SYMBOL symbol;
+ TERM term;
+ LIST list;
+} yystype;
+/* Line 1281 of /opt/gnu//share/bison/yacc.c. */
+#line 80 "iaparser.h"
+# define YYSTYPE yystype
+#endif
+
+extern YYSTYPE ia_lval;
+
+
+#endif /* not BISON_IAPARSER_H */
+
diff --git a/test/spass/iascanner.c b/test/spass/iascanner.c
new file mode 100644
index 0000000..9677a81
--- /dev/null
+++ b/test/spass/iascanner.c
@@ -0,0 +1,1991 @@
+#define yy_create_buffer ia__create_buffer
+#define yy_delete_buffer ia__delete_buffer
+#define yy_scan_buffer ia__scan_buffer
+#define yy_scan_string ia__scan_string
+#define yy_scan_bytes ia__scan_bytes
+#define yy_flex_debug ia__flex_debug
+#define yy_init_buffer ia__init_buffer
+#define yy_flush_buffer ia__flush_buffer
+#define yy_load_buffer_state ia__load_buffer_state
+#define yy_switch_to_buffer ia__switch_to_buffer
+#define yyin ia_in
+#define yyleng ia_leng
+#define yylex ia_lex
+#define yyout ia_out
+#define yyrestart ia_restart
+#define yytext ia_text
+
+#line 19 "iascanner.c"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header$
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+static yyconst short yy_nxt[][24] =
+ {
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+ },
+
+ {
+ 3, 4, 5, 6, 7, 8, 9, 10, 9, 11,
+ 12, 13, 9, 9, 14, 15, 16, 9, 9, 9,
+ 17, 9, 9, 9
+ },
+
+ {
+ 3, 4, 5, 6, 7, 8, 9, 10, 9, 11,
+ 12, 13, 9, 9, 14, 15, 16, 9, 9, 9,
+ 17, 9, 9, 9
+ },
+
+ {
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
+
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
+ -3, -3, -3, -3
+ },
+
+ {
+ 3, -4, -4, -4, -4, -4, -4, -4, -4, -4,
+ -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
+ -4, -4, -4, -4
+ },
+
+ {
+ 3, -5, 18, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5
+ },
+
+ {
+ 3, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+
+ -6, -6, -6, -6
+ },
+
+ {
+ 3, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7
+ },
+
+ {
+ 3, -8, -8, -8, -8, 19, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -9, -9, -9, -9, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+
+ },
+
+ {
+ 3, -10, -10, -10, -10, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 21, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -11, -11, -11, -11, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 22, 20, 20,
+ 20, 20, 20, 23
+ },
+
+ {
+ 3, -12, -12, -12, -12, 20, 20, 24, 20, 20,
+ 20, 20, 20, 20, 20, 25, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -13, -13, -13, -13, 20, 20, 20, 20, 20,
+
+ 20, 20, 20, 26, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -14, -14, -14, -14, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 27, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -15, -15, -15, -15, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 28, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -16, -16, -16, -16, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 29, 20,
+
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -17, -17, -17, -17, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 30, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -18, 18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18
+ },
+
+ {
+ 3, -19, -19, -19, -19, 19, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+
+ },
+
+ {
+ 3, -20, -20, -20, -20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -21, -21, -21, -21, 20, 20, 20, 31, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -22, -22, -22, -22, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 32, 20, 20
+ },
+
+ {
+ 3, -23, -23, -23, -23, 20, 20, 20, 20, 20,
+
+ 20, 33, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -24, -24, -24, -24, 20, 20, 20, 20, 20,
+ 20, 20, 34, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -25, -25, -25, -25, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 35, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -26, -26, -26, -26, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 36, 20, 20, 20,
+
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -27, -27, -27, -27, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 37, 20, 20, 20
+ },
+
+ {
+ 3, -28, -28, -28, -28, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -29, -29, -29, -29, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 38, 20, 20, 20, 20,
+ 20, 20, 20, 20
+
+ },
+
+ {
+ 3, -30, -30, -30, -30, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 39, 20, 20
+ },
+
+ {
+ 3, -31, -31, -31, -31, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -32, -32, -32, -32, 20, 20, 40, 20, 20,
+ 20, 41, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -33, -33, -33, -33, 20, 20, 20, 20, 20,
+
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 42,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -34, -34, -34, -34, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 43,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -35, -35, -35, -35, 20, 20, 44, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -36, -36, -36, -36, 20, 20, 20, 20, 20,
+ 20, 20, 45, 20, 20, 20, 20, 20, 20, 20,
+
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -37, -37, -37, -37, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -38, -38, -38, -38, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 46, 20
+ },
+
+ {
+ 3, -39, -39, -39, -39, 20, 20, 20, 20, 47,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+
+ },
+
+ {
+ 3, -40, -40, -40, -40, 20, 20, 20, 20, 20,
+ 20, 20, 48, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -41, -41, -41, -41, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 49, 20
+ },
+
+ {
+ 3, -42, -42, -42, -42, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 50, 20, 20, 20
+ },
+
+ {
+ 3, -43, -43, -43, -43, 20, 20, 20, 20, 51,
+
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -44, -44, -44, -44, 20, 20, 20, 20, 20,
+ 20, 20, 52, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -45, -45, -45, -45, 20, 20, 20, 20, 20,
+ 20, 53, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -46, -46, -46, -46, 20, 20, 20, 20, 54,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -47, -47, -47, -47, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -48, -48, -48, -48, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -49, -49, -49, -49, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+
+ },
+
+ {
+ 3, -50, -50, -50, -50, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 55,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -51, -51, -51, -51, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -52, -52, -52, -52, 20, 20, 20, 20, 20,
+ 20, 20, 56, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -53, -53, -53, -53, 20, 20, 20, 20, 57,
+
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -54, -54, -54, -54, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -55, -55, -55, -55, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -56, -56, -56, -56, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -57, -57, -57, -57, 20, 20, 20, 58, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 59,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -58, -58, -58, -58, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+ },
+
+ {
+ 3, -59, -59, -59, -59, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20
+
+ },
+
+ } ;
+
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 19
+#define YY_END_OF_BUFFER 20
+static yyconst short int yy_accept[60] =
+ { 0,
+ 0, 0, 20, 18, 15, 16, 17, 13, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 15, 13, 14,
+ 14, 14, 14, 14, 14, 14, 14, 10, 14, 14,
+ 1, 14, 14, 14, 14, 14, 9, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 11, 2, 3, 14,
+ 5, 14, 14, 12, 4, 6, 14, 7, 8
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 1, 1, 1, 1, 1, 1, 4,
+ 4, 1, 1, 4, 4, 4, 1, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 1, 1, 1,
+ 1, 1, 1, 1, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 4, 1, 4, 1, 6, 1, 7, 6, 6, 8,
+
+ 9, 10, 6, 6, 11, 6, 6, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 6, 23,
+ 6, 6, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "iascanner.l"
+#define INITIAL 0
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SCANNER FOR SPASS INTERACTIVE MODULE * */
+/* * * */
+/* * $Module: KIV * */
+/* * * */
+/* * Copyright (C) 1997, 1998, 1999, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+/* $RCSfile$ */
+#line 49 "iascanner.l"
+
+#include <ctype.h> /* for isprint */
+#include <errno.h>
+#include "misc.h"
+#include "memory.h"
+#include "symbol.h"
+#include "term.h"
+#include "ia.h"
+#include "iaparser.h"
+
+extern NAT dfg_LINENUMBER; /* defined in dfgparser.y */
+
+/* Force the scanner to read the input character by character */
+#define YY_ALWAYS_INTERACTIVE 1
+#define YY_NO_UNPUT 1
+#line 803 "iascanner.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 68 "iascanner.l"
+
+
+#line 957 "iascanner.c"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ while ( (yy_current_state = yy_nxt[yy_current_state][yy_ec[YY_SC_TO_UI(*yy_cp)]]) > 0 )
+ ++yy_cp;
+
+ yy_current_state = -yy_current_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+case 1:
+YY_RULE_SETUP
+#line 70 "iascanner.l"
+return IA_AND;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 71 "iascanner.l"
+return IA_EQUAL;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 72 "iascanner.l"
+return IA_EQUIV;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 73 "iascanner.l"
+return IA_EXISTS;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 74 "iascanner.l"
+return IA_FALSE;
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 75 "iascanner.l"
+return IA_FORALL;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 76 "iascanner.l"
+return IA_IMPLIED;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 77 "iascanner.l"
+return IA_IMPLIES;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 78 "iascanner.l"
+return IA_NOT;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 79 "iascanner.l"
+return IA_OR;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 80 "iascanner.l"
+return IA_TRUE;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 81 "iascanner.l"
+return IA_PROVE;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 82 "iascanner.l"
+{ unsigned long n;
+ errno = 0;
+ n = strtoul(yytext, NULL, 10);
+ if (errno != 0 || n > INT_MAX) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Number too big in line %d.\n",
+ dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ ia_lval.number = (int) n;
+ return IA_NUM;
+ }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 94 "iascanner.l"
+{ ia_lval.string = (char*) memory_Malloc(yyleng+1);
+ strcpy(ia_lval.string, yytext);
+ return IA_ID;
+ }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 98 "iascanner.l"
+/* ignore */
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 99 "iascanner.l"
+dfg_LINENUMBER++;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 100 "iascanner.l"
+return yytext[0];
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 101 "iascanner.l"
+{ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Illegal character '");
+ if (isprint((int)yytext[0]))
+ misc_UserErrorReport("%c",yytext[0]);
+ else
+ misc_UserErrorReport("\\x%x", (unsigned int) yytext[0]);
+ misc_UserErrorReport("' in line %d.\n", dfg_LINENUMBER);
+ misc_FinishUserErrorReport();
+ }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 111 "iascanner.l"
+ECHO;
+ YY_BREAK
+#line 1130 "iascanner.c"
+ case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+
+ yy_current_state = yy_nxt[yy_current_state][1];
+ yy_is_jam = (yy_current_state <= 0);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 111 "iascanner.l"
+
diff --git a/test/spass/kbo.c b/test/spass/kbo.c
new file mode 100644
index 0000000..c598cbe
--- /dev/null
+++ b/test/spass/kbo.c
@@ -0,0 +1,593 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * EXTENDED KNUTH BENDIX ORDERING * */
+/* * * */
+/* * $Module: KBO * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "kbo.h"
+#include "order.h"
+
+const int kbo_MINWEIGHT = 1;
+
+/**************************************************************/
+/* Functions to implement an order on terms */
+/**************************************************************/
+
+static int kbo_ContCompVarCondAndWeightIntern(CONTEXT Context, TERM Term, int Index)
+/**************************************************************
+ INPUT:
+ EFFECT:
+***************************************************************/
+{
+ int Weight;
+
+ Weight = 0;
+ Term = cont_Deref(&Context,Term);
+
+ if (term_IsStandardVariable(Term)) {
+ ord_VARCOUNT[term_TopSymbol(Term)][Index]++;
+ Weight += kbo_MINWEIGHT;
+ }
+ else {
+ LIST Scan;
+ Weight += symbol_Weight(term_TopSymbol(Term));
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ Weight += kbo_ContCompVarCondAndWeightIntern(Context, list_Car(Scan), Index);
+ }
+
+ return Weight;
+}
+
+static int kbo_ContCompVarCondAndWeight(CONTEXT Context1, TERM Term1, BOOL *VarCond1,
+ CONTEXT Context2, TERM Term2, BOOL *VarCond2)
+/**************************************************************
+ INPUT: Two contexts, two terms and two pointers to booleans.
+ EFFECT: Sets the booleans with respect to the kbo variable condition.
+ Computes the kbo weight difference.
+ The terms are interpreted with respect to the bindings in the respective
+ contexts.
+***************************************************************/
+{
+ SYMBOL MaxVar1,MaxVar2;
+ int i,Weight;
+
+ *VarCond1 = *VarCond2 = TRUE;
+ MaxVar1 = cont_TermMaxVar(Context1,Term1);
+ MaxVar2 = cont_TermMaxVar(Context2,Term2);
+
+ if (MaxVar1 < MaxVar2)
+ MaxVar1 = MaxVar2;
+
+ for (i = 0; i <= MaxVar1; i++) {
+ ord_VARCOUNT[i][0] = 0;
+ ord_VARCOUNT[i][1] = 0;
+ }
+
+ Weight = kbo_ContCompVarCondAndWeightIntern(Context1, Term1, 0);
+ Weight = Weight - kbo_ContCompVarCondAndWeightIntern(Context2, Term2, 1);
+
+ for (i = 0; i <= MaxVar1; i++) {
+ if (ord_VARCOUNT[i][0] < ord_VARCOUNT[i][1]) {
+ *VarCond1 = FALSE;
+ if (!*VarCond2)
+ return Weight;
+ }
+ else if (ord_VARCOUNT[i][0] > ord_VARCOUNT[i][1]) {
+ *VarCond2 = FALSE;
+ if (!*VarCond1)
+ return Weight;
+ }
+ }
+ return Weight;
+}
+
+
+static int kbo_CompVarCondAndWeight(TERM Term1, BOOL *VarCond1, TERM Term2, BOOL *VarCond2)
+/**************************************************************
+ INPUT: Two terms and two pointers to booleans.
+ EFFECT: Sets the booleans with respect to the kbo variable condition.
+ Computes the kbo weight difference.
+***************************************************************/
+{
+ SYMBOL MaxVar1,MaxVar2;
+ TERM Term;
+ LIST Scan;
+ int i,Stack,Weight;
+
+ *VarCond1 = *VarCond2 = TRUE;
+ MaxVar1 = term_MaxVar(Term1);
+ MaxVar2 = term_MaxVar(Term2);
+ Stack = stack_Bottom();
+ Weight = 0;
+
+ if (MaxVar1 < MaxVar2)
+ MaxVar1 = MaxVar2;
+
+ for (i = 0; i <= MaxVar1; i++) {
+ ord_VARCOUNT[i][0] = 0;
+ ord_VARCOUNT[i][1] = 0;
+ }
+
+ Term = Term1;
+ if (term_IsStandardVariable(Term)) {
+ ord_VARCOUNT[term_TopSymbol(Term)][0]++;
+ Weight += kbo_MINWEIGHT;
+ }
+ else {
+ Weight += symbol_Weight(term_TopSymbol(Term));
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+ }
+ while (!stack_Empty(Stack)) {
+ Scan = stack_Top();
+ Term = (TERM)list_Car(Scan);
+ stack_RplacTop(list_Cdr(Scan));
+ if (term_IsStandardVariable(Term)) {
+ Weight += kbo_MINWEIGHT;
+ ord_VARCOUNT[term_TopSymbol(Term)][0]++;
+ }
+ else {
+ Weight += symbol_Weight(term_TopSymbol(Term));
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+ }
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ }
+
+ Term = Term2;
+ if (term_IsStandardVariable(Term)) {
+ Weight -= kbo_MINWEIGHT;
+ ord_VARCOUNT[term_TopSymbol(Term)][1]++;
+ }
+ else {
+ Weight -= symbol_Weight(term_TopSymbol(Term));
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+ }
+ while (!stack_Empty(Stack)) {
+ Scan = stack_Top();
+ Term = (TERM)list_Car(Scan);
+ stack_RplacTop(list_Cdr(Scan));
+ if (term_IsStandardVariable(Term)) {
+ Weight -= kbo_MINWEIGHT;
+ ord_VARCOUNT[term_TopSymbol(Term)][1]++;
+ }
+ else {
+ Weight -= symbol_Weight(term_TopSymbol(Term));
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+ }
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ }
+
+ for (i = 0; i <= MaxVar1; i++) {
+ if (ord_VARCOUNT[i][0] < ord_VARCOUNT[i][1]) {
+ *VarCond1 = FALSE;
+ if (!*VarCond2)
+ return Weight;
+ }
+ if (ord_VARCOUNT[i][0] > ord_VARCOUNT[i][1]) {
+ *VarCond2 = FALSE;
+ if (!*VarCond1)
+ return Weight;
+ }
+ }
+ return Weight;
+}
+
+
+static ord_RESULT kbo_CompareStruc(TERM Term1, TERM Term2, int WeightDiff)
+/**************************************************************
+ INPUT: Two terms where the kbo-variable condition for <Term1> and
+ <Term2> is satisfied and <WeightDiff> is the kbo weight difference
+ between <Term1> and <Term2>
+ RETURNS: ord_UNCOMPARABLE, if Term1 and Term2 are uncomparable
+ ord_EQUAL, if Term1 and Term2 are equal
+ ord_GREATER_THAN, if Term1 is greater than Term2
+ CAUTION: The precedence from the order module is used to determine
+ the precedence of symbols!
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+ SYMBOL Top1,Top2;
+
+ Top1 = term_TopSymbol(Term1);
+ Top2 = term_TopSymbol(Term2);
+
+ if (WeightDiff > 0)
+ return ord_GREATER_THAN;
+ else
+ if (WeightDiff == 0) {
+ if (symbol_IsStandardVariable(Top1)) {
+ if (symbol_IsStandardVariable(Top2))
+ return ord_EQUAL;
+ else
+ return ord_UNCOMPARABLE;
+ }
+ else
+ if (symbol_IsStandardVariable(Top2) ||
+ symbol_PrecedenceGreater(ord_PRECEDENCE, Top1, Top2))
+ return ord_GREATER_THAN;
+ else
+ if (Top1 == Top2) {
+ int RecWeightDiff;
+ BOOL T1VarCond, T2VarCond;
+ TERM RecTerm1,RecTerm2;
+ Scan1 = term_ArgumentList(Term1);
+ Scan2 = term_ArgumentList(Term2);
+ if (symbol_HasProperty(Top1,ORDRIGHT)) {
+ int i;
+ for (i = symbol_Arity(Top1);
+ i > 0 && term_Equal(list_NthElement(Scan1,i),list_NthElement(Scan2,i));
+ i--);
+ if (i > 0) {
+ RecTerm1 = (TERM)list_NthElement(Scan1,i);
+ RecTerm2 = (TERM)list_NthElement(Scan2,i);
+ }
+ else
+ return ord_EQUAL;
+ }
+ else {
+ while (!list_Empty(Scan1) && term_Equal(list_Car(Scan1),list_Car(Scan2))) {
+ Scan1 = list_Cdr(Scan1);
+ Scan2 = list_Cdr(Scan2);
+ }
+ if (list_Empty(Scan1)) /* Implies that list_Empty(Scan2) */
+ return ord_EQUAL;
+ else {
+ RecTerm1 = (TERM)list_Car(Scan1);
+ RecTerm2 = (TERM)list_Car(Scan2);
+ }
+ }
+ RecWeightDiff = kbo_CompVarCondAndWeight(RecTerm1,&T1VarCond,RecTerm2,&T2VarCond);
+ if (RecWeightDiff >= 0 && T1VarCond)
+ return kbo_CompareStruc(RecTerm1, RecTerm2, RecWeightDiff);
+ else
+ return ord_UNCOMPARABLE;
+ }
+ else
+ return ord_UNCOMPARABLE;
+ }
+ else
+ return ord_UNCOMPARABLE;
+
+ return ord_UNCOMPARABLE;
+}
+
+
+ord_RESULT kbo_Compare(TERM Term1, TERM Term2)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: ord_UNCOMPARABLE, if Term1 and Term2 are uncomparable because of
+ different variables,
+ ord_EQUAL, if Term1 and Term2 are comparable and have the
+ same weight,
+ ord_GREATER_THAN, if Term1 is greater than Term2 wrt the kbo with
+ the actual precedence and the given symbol weights,
+ ord_SMALLER_THAN, else.
+ CAUTION: The precedence from the order module is used to determine
+ the precedence of symbols!
+***************************************************************/
+{
+ int WeightDiff;
+ BOOL T1VarCond, T2VarCond;
+ ord_RESULT Result;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term1) || !term_IsTerm(Term2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In kbo_Compare:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+
+ WeightDiff = kbo_CompVarCondAndWeight(Term1,&T1VarCond,Term2,&T2VarCond);
+
+ if (T1VarCond && !T2VarCond)
+ return kbo_CompareStruc(Term1,Term2,WeightDiff);
+
+ if (!T1VarCond && T2VarCond)
+ return ord_Not(kbo_CompareStruc(Term2,Term1,-WeightDiff));
+
+ if (T1VarCond && T2VarCond) {
+ Result = kbo_CompareStruc(Term1,Term2,WeightDiff);
+ if (Result == ord_UNCOMPARABLE)
+ return ord_Not(kbo_CompareStruc(Term2,Term1,-WeightDiff));
+ else
+ return Result;
+ }
+
+ return ord_UNCOMPARABLE;
+}
+
+static ord_RESULT kbo_ContCompareStruc(CONTEXT Context1, TERM Term1,
+ CONTEXT Context2, TERM Term2,
+ int WeightDiff)
+/**************************************************************
+ INPUT: Two contexts and two terms where the kbo-variable condition
+ for <Term1> and <Term2> is satisfied and <WeightDiff> is the
+ kbo weight difference between <Term1> and <Term2>.
+ RETURNS: ord_UNCOMPARABLE, if Term1 and Term2 are uncomparable
+ ord_EQUAL, if Term1 and Term2 are equal
+ ord_GREATER_THAN, if Term1 is greater than Term2
+ The Terms are interpreted with respect to the contexts.
+ CAUTION: The precedence from the order module is used to determine
+ the precedence of symbols!
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+ SYMBOL Top1,Top2;
+
+ Term1 = cont_Deref(&Context1,Term1);
+ Term2 = cont_Deref(&Context2,Term2);
+ Top1 = term_TopSymbol(Term1);
+ Top2 = term_TopSymbol(Term2);
+
+ if (WeightDiff > 0)
+ return ord_GREATER_THAN;
+ else
+ if (WeightDiff == 0) {
+ if (symbol_IsStandardVariable(Top1)) {
+ if (symbol_IsStandardVariable(Top2))
+ return ord_EQUAL;
+ else
+ return ord_UNCOMPARABLE;
+ }
+ else
+ if (symbol_IsStandardVariable(Top2) ||
+ symbol_PrecedenceGreater(ord_PRECEDENCE, Top1,Top2))
+ return ord_GREATER_THAN;
+ else
+ if (Top1 == Top2) {
+ int RecWeightDiff;
+ BOOL T1VarCond, T2VarCond;
+ TERM RecTerm1,RecTerm2;
+ Scan1 = term_ArgumentList(Term1);
+ Scan2 = term_ArgumentList(Term2);
+ if (symbol_HasProperty(Top1,ORDRIGHT)) {
+ int i;
+ for (i = symbol_Arity(Top1);
+ i > 0 && cont_TermEqual(Context1,list_NthElement(Scan1,i),
+ Context2,list_NthElement(Scan2,i));
+ i--);
+ if (i > 0) {
+ RecTerm1 = cont_Deref(&Context1,list_NthElement(Scan1,i));
+ RecTerm2 = cont_Deref(&Context2,list_NthElement(Scan2,i));
+ }
+ else
+ return ord_EQUAL;
+ }
+ else {
+ while (!list_Empty(Scan1) && cont_TermEqual(Context1,list_Car(Scan1),Context2,list_Car(Scan2))) {
+ Scan1 = list_Cdr(Scan1);
+ Scan2 = list_Cdr(Scan2);
+ }
+ if (list_Empty(Scan1)) /* Implies that list_Empty(Scan2) */
+ return ord_EQUAL;
+ else {
+ RecTerm1 = cont_Deref(&Context1,list_Car(Scan1));
+ RecTerm2 = cont_Deref(&Context2,list_Car(Scan2));
+ }
+ }
+ RecWeightDiff = kbo_ContCompVarCondAndWeight(Context1,RecTerm1,&T1VarCond,
+ Context2,RecTerm2,&T2VarCond);
+ if (RecWeightDiff >= 0 && T1VarCond)
+ return kbo_ContCompareStruc(Context1, RecTerm1, Context2, RecTerm2, RecWeightDiff);
+ else
+ return ord_UNCOMPARABLE;
+ }
+ else
+ return ord_UNCOMPARABLE;
+ }
+ else
+ return ord_UNCOMPARABLE;
+
+ return ord_UNCOMPARABLE;
+}
+
+
+ord_RESULT kbo_ContCompare(CONTEXT Context1, TERM Term1, CONTEXT Context2, TERM Term2)
+/**************************************************************
+ INPUT: Two contexts and two terms.
+ RETURNS: ord_UNCOMPARABLE, if Term1 and Term2 are uncomparable because of
+ different variables,
+ ord_EQUAL, if Term1 and Term2 are comparable and have the
+ same weight,
+ ord_GREATER_THAN, if Term1 is greater than Term2 wrt the kbo with
+ the actual precedence kbo_Prec and the given
+ symbol_Weights,
+ ord_SMALLER_THAN, else.
+ The Terms are interpreted with respect to the contexts.
+ CAUTION: The precedence from the order module is used to determine
+ the precedence of symbols!
+***************************************************************/
+{
+ int WeightDiff;
+ BOOL T1VarCond, T2VarCond;
+ ord_RESULT Result;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term1) || !term_IsTerm(Term2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In kbo_Compare:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+
+ WeightDiff = kbo_ContCompVarCondAndWeight(Context1, Term1, &T1VarCond, Context2, Term2, &T2VarCond);
+
+ if (T1VarCond && !T2VarCond)
+ return kbo_ContCompareStruc(Context1,Term1,Context2,Term2,WeightDiff);
+
+ if (!T1VarCond && T2VarCond)
+ return ord_Not(kbo_ContCompareStruc(Context2,Term2,Context1,Term1,-WeightDiff));
+
+ if (T1VarCond && T2VarCond) {
+ Result = kbo_ContCompareStruc(Context1,Term1,Context2,Term2,WeightDiff);
+ if (Result == ord_UNCOMPARABLE)
+ return ord_Not(kbo_ContCompareStruc(Context2,Term2,Context1,Term1,-WeightDiff));
+ else
+ return Result;
+ }
+
+ return ord_UNCOMPARABLE;
+}
+
+static BOOL kbo_ContGreaterCompareStruc(CONTEXT Context1, TERM Term1,
+ CONTEXT Context2, TERM Term2)
+/**************************************************************
+ INPUT: Two contexts and two terms where the kbo-variable condition
+ for <Term1> and <Term2> is satisfied as well as the
+ weight difference between the terms is zero.
+ RETURNS: TRUE if Term1 is greater than Term2.
+ The Terms are interpreted with respect to the contexts.
+ CAUTION: The precedence from the order module is used to determine
+ the precedence of symbols!
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+ SYMBOL Top1,Top2;
+
+ Term1 = cont_Deref(&Context1,Term1);
+ Term2 = cont_Deref(&Context2,Term2);
+ Top1 = term_TopSymbol(Term1);
+ Top2 = term_TopSymbol(Term2);
+
+ if (symbol_IsStandardVariable(Top1)) {
+ if (symbol_IsStandardVariable(Top2))
+ return FALSE;
+ else
+ return FALSE;
+ }
+ else
+ if (symbol_IsStandardVariable(Top2) ||
+ symbol_PrecedenceGreater(ord_PRECEDENCE, Top1, Top2))
+ return TRUE;
+ else
+ if (Top1 == Top2) {
+ int RecWeightDiff;
+ BOOL T1VarCond, T2VarCond;
+ TERM RecTerm1,RecTerm2;
+ Scan1 = term_ArgumentList(Term1);
+ Scan2 = term_ArgumentList(Term2);
+ if (symbol_HasProperty(Top1,ORDRIGHT)) {
+ int i;
+ for (i = symbol_Arity(Top1);
+ i > 0 && cont_TermEqual(Context1,list_NthElement(Scan1,i),
+ Context2,list_NthElement(Scan2,i));
+ i--);
+ if (i > 0) {
+ RecTerm1 = cont_Deref(&Context1,list_NthElement(Scan1,i));
+ RecTerm2 = cont_Deref(&Context2,list_NthElement(Scan2,i));
+ }
+ else
+ return FALSE;
+ }
+ else {
+ while (!list_Empty(Scan1) && cont_TermEqual(Context1,list_Car(Scan1),Context2,list_Car(Scan2))) {
+ Scan1 = list_Cdr(Scan1);
+ Scan2 = list_Cdr(Scan2);
+ }
+ if (list_Empty(Scan1)) /* Implies that list_Empty(Scan2) */
+ return FALSE;
+ else {
+ RecTerm1 = cont_Deref(&Context1,list_Car(Scan1));
+ RecTerm2 = cont_Deref(&Context2,list_Car(Scan2));
+ }
+ }
+ RecWeightDiff = kbo_ContCompVarCondAndWeight(Context1,RecTerm1,&T1VarCond,
+ Context2,RecTerm2,&T2VarCond);
+
+ if (T1VarCond) {
+ if (RecWeightDiff > 0)
+ return TRUE;
+ else
+ if (RecWeightDiff == 0)
+ return kbo_ContGreaterCompareStruc(Context1, RecTerm1, Context2, RecTerm2);
+ }
+ }
+
+ return FALSE;
+}
+
+
+BOOL kbo_ContGreater(CONTEXT Context1, TERM Term1, CONTEXT Context2, TERM Term2)
+/**************************************************************
+ INPUT: Two contexts and two terms.
+ RETURNS: TRUE, if Term1 is greater than Term2 wrt the kbo with
+ the actual precedence kbo_Prec and the given symbol_Weights
+ CAUTION: The precedence from the order module is used to determine
+ the precedence of symbols!
+***************************************************************/
+{
+ int WeightDiff;
+ BOOL T1VarCond, T2VarCond;
+
+#ifdef CHECK
+ if ((!term_IsTerm(Term1)) || (!term_IsTerm(Term2)) ) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In kbo_ContGreater:");
+ misc_ErrorReport("\n Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+
+ WeightDiff = kbo_ContCompVarCondAndWeight(Context1, Term1, &T1VarCond, Context2, Term2, &T2VarCond);
+
+ if (T1VarCond) {
+ if (WeightDiff > 0)
+ return TRUE;
+ else
+ if (WeightDiff == 0)
+ return kbo_ContGreaterCompareStruc(Context1,Term1,Context2,Term2);
+ }
+ return FALSE;
+}
diff --git a/test/spass/kbo.h b/test/spass/kbo.h
new file mode 100644
index 0000000..00db284
--- /dev/null
+++ b/test/spass/kbo.h
@@ -0,0 +1,67 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * EXTENDED KNUTH BENDIX ORDERING * */
+/* * * */
+/* * $Module: KBO * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _KBO_
+#define _KBO_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "term.h"
+#include "context.h"
+#include "foldfg.h"
+#include "order.h"
+
+/**************************************************************/
+/* FUNCTIONS */
+/**************************************************************/
+
+ord_RESULT kbo_Compare(TERM, TERM);
+ord_RESULT kbo_ContCompare(CONTEXT, TERM, CONTEXT, TERM);
+BOOL kbo_ContGreater(CONTEXT, TERM, CONTEXT, TERM);
+
+#endif
diff --git a/test/spass/list.c b/test/spass/list.c
new file mode 100644
index 0000000..c956e1e
--- /dev/null
+++ b/test/spass/list.c
@@ -0,0 +1,1660 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * LISTS * */
+/* * * */
+/* * $Module: LIST * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "list.h"
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * MEMORY MANAGEMENT * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+LIST list_Copy(const LIST List)
+/**************************************************************
+ INPUT: A List.
+ RETURNS: The copy of the list.
+ CAUTION: The entries of the list are NOT copied !
+ the function needs time O(n), where <n> is the length
+ of the list.
+***************************************************************/
+{
+ LIST Copy;
+ LIST Scan1,Scan2;
+
+
+ if (list_Empty(List))
+ return list_Nil();
+
+ Copy = list_List(list_Car(List));
+ Scan1 = Copy;
+ Scan2 = list_Cdr(List);
+
+ while (!list_Empty(Scan2)) {
+ list_Rplacd(Scan1, list_List(list_Car(Scan2)));
+ Scan1 = list_Cdr(Scan1);
+ Scan2 = list_Cdr(Scan2);
+ }
+ return Copy;
+}
+
+
+LIST list_CopyWithElement(const LIST List, POINTER (*CopyElement)(POINTER))
+/**************************************************************
+ INPUT: A List and a copy function for the elements.
+ RETURNS: The copy of the list.
+ CAUTION: The entries of the list are NOT copied !
+ The function needs time O(n*c), where <n> is the length
+ of the list and <c> is the time for a call of the
+ element copy function.
+***************************************************************/
+{
+ LIST Copy;
+ LIST Scan1,Scan2;
+
+ if (list_Empty(List))
+ return list_Nil();
+
+ Copy = list_List(CopyElement(list_Car(List)));
+ Scan1 = Copy;
+ Scan2 = list_Cdr(List);
+
+ while (!list_Empty(Scan2)) {
+ list_Rplacd(Scan1, list_List(CopyElement(list_Car(Scan2))));
+ Scan1 = list_Cdr(Scan1);
+ Scan2 = list_Cdr(Scan2);
+ }
+ return Copy;
+}
+
+
+void list_InsertNext(LIST List, POINTER Pointer)
+/**************************************************************
+ INPUT: A list and a pointer to anything.
+ RETURNS: A list with Pointer being added at the position that
+ follows List.
+ SUMMARY: We enqueue the element at position list_Cdr(List);
+ The function needs time O(1).
+***************************************************************/
+{
+#ifdef CHECK
+ if (Pointer == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In list_InsertNext: NULL Pointer. ");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ list_Rplacd(List, list_Cons(Pointer, list_Cdr(List)));
+}
+
+
+void list_NMapCar(LIST List, POINTER (*ElementFunc)(POINTER))
+/**************************************************************
+ INPUT: A List and a function for the elements.
+ RETURNS: The List where all elements are replaced by the result of
+ the function calls of <ElementFunc> to the elements
+ CAUTION: The List is not copied !
+ The function needs time O(n*f), where <n> is the length
+ of the list and <f> is the time for a call of the
+ element function.
+***************************************************************/
+{
+ LIST Scan;
+
+ for (Scan = List; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ list_Rplaca(Scan, ElementFunc(list_Car(Scan)));
+}
+
+
+void list_Apply(void (*Function)(POINTER), LIST List)
+/**************************************************************
+ INPUT: A non-resulting function and a list.
+ SUMMARY: Apply the function to all members of the list.
+ The function needs time O(n*f), where <n> is the length
+ of the list and <f> is the time for a call of the
+ element function.
+***************************************************************/
+{
+ while (!list_Empty(List)) {
+ Function(list_Car(List));
+ List = list_Cdr(List);
+ }
+}
+
+
+LIST list_Reverse(const LIST List)
+/**************************************************************
+ INPUT: A list.
+ RETURNS: A new list where the order of the elements is reversed.
+ EFFECT: The function needs time O(n), where <n> is the length
+ of the list.
+***************************************************************/
+{
+ LIST ReverseList;
+ LIST Scan;
+
+ ReverseList = list_Nil();
+
+ for (Scan=List;!list_Empty(Scan);Scan=list_Cdr(Scan))
+ ReverseList = list_Cons(list_Car(Scan), ReverseList);
+
+ return ReverseList;
+}
+
+
+LIST list_NReverse(LIST List)
+/**************************************************************
+ INPUT: A list
+ RETURNS: The same list with reversed order of items.
+ CAUTION: Destructive.
+ The function needs time O(n), where <n> is the length
+ of the list.
+***************************************************************/
+{
+ LIST ReverseList;
+ LIST Scan1;
+ LIST Scan2;
+
+ ReverseList = list_Nil();
+
+ for (Scan1=List; !list_Empty(Scan1); Scan1=list_Cdr(Scan1))
+ ReverseList = list_Cons(list_Car(Scan1),ReverseList);
+
+ for (Scan1=List, Scan2=ReverseList;
+ !list_Empty(Scan1);
+ Scan1=list_Cdr(Scan1), Scan2=list_Cdr(Scan2))
+ list_Rplaca(Scan1, list_Car(Scan2));
+
+ list_Delete(ReverseList);
+ return List;
+}
+
+
+static __inline__ BOOL list_PointerLower (POINTER A, POINTER B)
+{
+ return (NAT) A < (NAT) B;
+}
+
+LIST list_PointerSort(LIST List)
+/**************************************************************
+ INPUT: A list
+ RETURNS: The same list where the elements are sorted as pointers.
+ EFFECT: The function needs time O(n log n), where <n> is the length
+ of the list.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ return list_Sort(List, list_PointerLower);
+}
+
+
+BOOL list_SortedInOrder(LIST L, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: A list, and an ordering function.
+ RETURNS: TRUE, if the list is ordered with respect to the
+ ordering function, FALSE otherwise.
+ EFFECT: The function needs time O(n), where <n> is the
+ length of the list.
+***************************************************************/
+{
+ LIST Scan1, Scan2;
+
+ if (!(list_Empty(L) || list_Empty(list_Cdr(L)))) {
+ Scan1 = L;
+ Scan2 = list_Cdr(Scan1);
+
+ /* Scan the list. */
+ do {
+ /* If all elements are ordered, then every element */
+ /* is <= its successor with respect to the ordering */
+ /* function. */
+ /* We might have a strictly ordering Test function, */
+ /* which implements < instead of <=, so let's test */
+ /* for equality first. */
+ if (!Test(list_Car(Scan1), list_Car(Scan2)) &&
+ Test(list_Car(Scan2), list_Car(Scan1)))
+ /* It is really strictly greater, so return FALSE. */
+ return FALSE;
+
+ Scan1 = list_Cdr(Scan1);
+ Scan2 = list_Cdr(Scan1);
+ } while (!list_Empty(Scan2));
+ }
+
+ return TRUE;
+}
+
+
+LIST list_Merge(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: Two sorted lists List1 and List2, and an ordering function.
+ RETURNS: The merged list ordered with respect to the ordering function.
+ EFFECT: The function needs time O(n), where <n> is the length of the list.
+***************************************************************/
+{
+
+ LIST Scan1, Scan2, Result, ResultStart;
+
+#ifdef CHECK
+ if (!list_SortedInOrder(List1, Test)) {
+ /* print an error message and exit */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In list_Merge: First argument is not sorted.");
+ misc_FinishErrorReport();
+ }
+ else if (!list_SortedInOrder (List2, Test)) {
+ /* print an error message and exit */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In list_Merge: Second argument is not sorted.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (list_Empty(List1))
+ return List2;
+
+ if (list_Empty(List2))
+ return List1;
+
+ /* This version is derived from list_NNumberMerge, but it doesn't need */
+ /* to allocate and deallocate memory, so it should be more efficient. */
+
+ /* Use the list with the least element as result list. */
+ if (Test(list_Car(List1), list_Car(List2))) {
+ ResultStart = List1;
+ Scan1 = list_Cdr(List1);
+ Scan2 = List2;
+ }
+ else {
+ ResultStart = List2;
+ Scan1 = List1;
+ Scan2 = list_Cdr(List2);
+ }
+
+ /* Result is the last element of the merged list. */
+
+ Result = ResultStart;
+
+ while (!list_Empty(Scan1) && !list_Empty(Scan2)) {
+ /* This function doesn't implement stable merging. */
+ /* Add another test if you need it. */
+
+ if (Test(list_Car(Scan1), list_Car(Scan2))) {
+ list_Rplacd(Result,Scan1);
+ Scan1 = list_Cdr(Scan1);
+ }
+ else {
+ list_Rplacd(Result,Scan2);
+ Scan2 = list_Cdr(Scan2);
+ }
+ Result = list_Cdr(Result);
+ }
+
+ if (list_Empty(Scan1))
+ list_Rplacd(Result, Scan2);
+ else
+ list_Rplacd(Result, Scan1);
+
+ return ResultStart;
+}
+
+
+void list_Split(LIST L, LIST *Half1, LIST *Half2)
+/**************************************************************
+ INPUT: A list, and two pointers to lists.
+ RETURNS: Nothing.
+ EFFECT: The input list is split in two. <Half1> and
+ <Half2> point to the resulting halves.
+ The input list is destructively changed!
+ If the list length is odd, <Half2> is assigned the
+ bigger part.
+ The function needs time O(n), where <n> is the
+ length of the input list.
+***************************************************************/
+{
+ /* Adapted code from proofcheck ... MergeSort. */
+
+ LIST SingleStep, DoubleStep, Prev;
+
+ if (list_Empty(L) || list_Empty(list_Cdr(L))) {
+ *Half1 = list_Nil();
+ *Half2 = L;
+ }
+ else {
+ /* divide list in two halves */
+ Prev = L;
+ SingleStep = list_Cdr(L);
+ DoubleStep = list_Cdr(SingleStep);
+
+ while (!list_Empty(DoubleStep) && !list_Empty(list_Cdr(DoubleStep))) {
+ Prev = SingleStep;
+ SingleStep = list_Cdr(SingleStep);
+ DoubleStep = list_Cdr(list_Cdr(DoubleStep));
+ }
+
+ *Half1 = L;
+ *Half2 = SingleStep;
+ list_Rplacd(Prev, list_Nil());
+ }
+}
+
+
+LIST list_MergeSort (LIST L, BOOL (*Test) (POINTER, POINTER))
+/**************************************************************
+ INPUT: A list, and an ordering function.
+ RETURNS: The list sorted with respect to the ordering function.
+ EFFECT: The function needs time O((n log n) * t), where
+ <n> is the length of the input list and <t> is the
+ execution time of the ordering function.
+***************************************************************/
+{
+ LIST Result;
+#ifdef CHECK
+ NAT originallength;
+
+ originallength = list_Length(L);
+#endif
+
+ /* Only sort if list has more than one element */
+ if (!list_Empty(L) && !list_Empty(list_Cdr(L))) {
+ LIST lowerhalf;
+ LIST greaterhalf;
+
+ LIST *lowerhalfptr;
+ LIST *greaterhalfptr;
+
+ lowerhalfptr = &lowerhalf;
+ greaterhalfptr = &greaterhalf;
+
+ list_Split(L, lowerhalfptr, greaterhalfptr);
+
+#ifdef CHECK
+ if((list_Length(lowerhalf) + list_Length(greaterhalf))
+ != originallength) {
+ /* output an error message and exit */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In list_MergeSort: Split lists' total sizes");
+ misc_ErrorReport("\n don't match original list's size.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ lowerhalf = list_MergeSort(lowerhalf, Test);
+
+ greaterhalf = list_MergeSort(greaterhalf, Test);
+
+#ifdef CHECK
+ if((list_Length(lowerhalf) + list_Length(greaterhalf))
+ != originallength) {
+ /* output an error message and exit */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In list_MergeSort: Mergesorted lists' total sizes");
+ misc_ErrorReport("\n don't match original list's size.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Merge(lowerhalf, greaterhalf, Test);
+
+#ifdef CHECK
+ if(list_Length(Result) != originallength) {
+ /* output an error message and exit */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In list_MergeSort: Merged list's size doesn't match ");
+ misc_ErrorReport("\n original list's size.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ }
+ else {
+ Result = L;
+ }
+
+ return Result;
+}
+
+
+LIST list_InsertionSort(LIST List, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: A list and a 'less' function on the elements.
+ RETURNS: The same list where the elements are sorted with
+ respect to Test.
+ EFFECT: The function needs time O(n^2*t), where <n> is the
+ length of the list and <t> is the time for the test
+ function.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ LIST Scan1,Scan2,Min;
+ POINTER Exchange;
+
+ for (Scan1=List; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) {
+ Min = Scan1;
+ for (Scan2 = list_Cdr(Scan1); !list_Empty(Scan2); Scan2 = list_Cdr(Scan2))
+ if (Test(list_Car(Scan2), list_Car(Min))) {
+ Exchange = list_Car(Min);
+ list_Rplaca(Min, list_Car(Scan2));
+ list_Rplaca(Scan2, Exchange);
+ }
+ }
+
+ return List;
+}
+
+
+LIST list_Sort(LIST List, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: A list and a 'less' function on the elements.
+ RETURNS: The same list where the elements are sorted with
+ respect to Test.
+ EFFECT: The function needs time O((n log n) *t), where <n>
+ is the length of the list and <t> is the time for
+ the test function.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ LIST Result;
+
+#ifdef CHECK
+ NAT originallength;
+
+ originallength = list_Length(List);
+#endif
+
+ Result = list_MergeSort(List, Test);
+
+#ifdef CHECK
+ if (!list_SortedInOrder(Result, Test)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In list_Sort: list_MergeSort did not sort properly.");
+ misc_FinishErrorReport();
+ }
+ if (list_Length(Result) != originallength) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In list_Sort: list_MergeSort lost elements. ");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return Result;
+}
+
+
+/* Help Variable used to store a pointer to the numbering function to use
+ in element comparisons.
+*/
+static NAT (*NumberFunction)(POINTER) = NULL;
+
+static __inline__ BOOL list_PointerNumberedLower(POINTER A, POINTER B)
+{
+ return (BOOL) (NumberFunction(A) < NumberFunction(B));
+}
+
+static __inline__ BOOL list_PointerNumberedLowerOrEqual(POINTER A, POINTER B)
+{
+ return (BOOL) (NumberFunction(A) <= NumberFunction(B));
+}
+
+static __inline__ BOOL list_PointerNumberedGreater(POINTER A, POINTER B)
+{
+ return (BOOL) (NumberFunction(A) > NumberFunction(B));
+}
+
+LIST list_NumberSort(LIST List, NAT (*Number)(POINTER))
+/**************************************************************
+ INPUT: A list and function mapping elements to numbers.
+ RETURNS: The same list where the elements are sorted with
+ respect to < and the Number function.
+ EFFECT: The function needs time O((n log n) * f), where <n>
+ is the length of the list and <f> is the time for a
+ call of the <Number> function.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ /* Use number function as temporary variable. It is used as
+ an implicit parameter in list_PointerLower.
+ We can't make it an explicit parameter, because of the
+ prototype of list_Sort.
+ */
+
+ NumberFunction = Number;
+
+ return list_Sort(List, list_PointerNumberedLower);
+
+}
+
+
+LIST list_GreaterNumberSort(LIST List, NAT (*Number)(POINTER))
+/**************************************************************
+ INPUT: A list and function mapping elements to numbers.
+ RETURNS: The same list where the elements are sorted with
+ respect to > and the Number function.
+ EFFECT: The function needs time O((n log n) * f), where <n>
+ is the length of the list and <f> is the time for a
+ call of the <Number> function.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ /* Use number function as temporary variable. It is used as
+ an implicit parameter in list_PointerLower.
+ We can't make it an explicit parameter, because of the
+ prototype of list_Sort.
+ */
+
+ NumberFunction = Number;
+
+ return list_Sort(List, list_PointerNumberedGreater);
+}
+
+
+LIST list_NNumberMerge(LIST List1, LIST List2, NAT (*Number)(POINTER))
+/**************************************************************
+ INPUT: Two sorted lists and function mapping elements to
+ numbers.
+ RETURNS: The merge of the lists where the elements are sorted
+ with respect to < and the Number function.
+ CAUTION: Destructive on both lists.
+***************************************************************/
+{
+ NumberFunction = Number;
+
+ return list_Merge(List1, List2, list_PointerNumberedLowerOrEqual);
+}
+
+
+POINTER list_DequeueNext(LIST List)
+/**************************************************************
+ INPUT: A list
+ RETURNS: A pointer to a dequeued element.
+ SUMMARY: We dequeue the element pointed to by list_Cdr(List).
+ The function needs time O(1).
+***************************************************************/
+{
+ POINTER Pointer;
+ LIST Memo;
+
+ if (list_Empty(List))
+ return NULL;
+
+ Memo = list_Cdr(List);
+ if (list_Empty(Memo))
+ return NULL;
+
+ Pointer = list_Car(Memo);
+ list_Rplacd(List, Memo->cdr);
+ list_Free(Memo);
+ return Pointer;
+}
+
+
+POINTER list_NthElement(LIST List, NAT Number)
+/**************************************************************
+ INPUT: A List and a natural number.
+ RETURNS: The <Number>th element of the list, NULL otherwise.
+ EFFECT: The function needs time O(Number).
+***************************************************************/
+{
+ while (!list_Empty(List) && --Number > 0)
+ List = list_Cdr(List);
+
+ if (list_Empty(List))
+ return NULL;
+ else
+ return list_Car(List);
+}
+
+
+void list_DeleteWithElement(LIST List, void (*ElementDelete)(POINTER))
+/**************************************************************
+ INPUT: A list and a delete function for the elements.
+ RETURNS: Nothing.
+ EFFECT: The list and all its elements are deleted.
+ The function needs time O(n*d), where <n> is the length
+ of the list and <d> is the time for the delete function.
+***************************************************************/
+{
+ LIST Scan;
+
+ while (!list_Empty(List)) {
+ Scan = list_Cdr(List);
+ ElementDelete(list_Car(List));
+ list_Free(List);
+ List = Scan;
+ }
+}
+
+
+NAT list_DeleteWithElementCount(LIST List, void (*ElementDelete)(POINTER))
+/**************************************************************
+ INPUT: A List and a delete function for the elements.
+ RETURNS: The number of deleted elements.
+ EFFECT: The List and all its elements are deleted.
+ The function needs time O(n*d), where <n> is the length
+ of the list and <d> is the time for the delete function.
+***************************************************************/
+{
+ int Result;
+ LIST Scan;
+
+ Result = 0;
+
+ while (!list_Empty(List)) {
+ Scan = list_Cdr(List);
+ ElementDelete(list_Car(List));
+ list_Free(List);
+ List = Scan;
+ Result++;
+ }
+
+ return Result;
+}
+
+
+LIST list_DeleteElement(LIST List, POINTER Element, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: A list, an element pointer, an equality test for
+ elements
+ RETURNS: The list where Element is deleted from List with
+ respect to Test.
+ EFFECTS: If List contains Element with respect to EqualityTest,
+ Element is deleted from List
+ CAUTION: Destructive. Be careful, the first element of a
+ list cannot be changed destructively by call by
+ reference.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ while (!list_Empty(List) && Test(Element, list_Car(List))) {
+ Scan1 = list_Cdr(List);
+ list_Free(List);
+ List = Scan1;
+ }
+
+ if (list_Empty(List))
+ return list_Nil();
+
+ Scan2 = List;
+ Scan1 = list_Cdr(List);
+
+ while (!list_Empty(Scan1)) {
+ if (Test(Element, list_Car(Scan1))) {
+ list_Rplacd(Scan2, list_Cdr(Scan1));
+ list_Free(Scan1);
+ Scan1 = list_Cdr(Scan2);
+ }
+ else {
+ Scan2 = Scan1;
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ return List;
+}
+
+
+LIST list_DeleteElementIf(LIST List, BOOL (*Test)(POINTER))
+/**************************************************************
+ INPUT: A list and a test for elements.
+ RETURNS: The list where an element is deleted if <Test> on it
+ succeeds.
+ CAUTION: Destructive. Be careful, the first element of a list
+ cannot be changed destructively by call by
+ reference.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ while (!list_Empty(List) && Test(list_Car(List))) {
+ Scan1 = list_Cdr(List);
+ list_Free(List);
+ List = Scan1;
+ }
+
+ if (list_Empty(List))
+ return list_Nil();
+
+ Scan2 = List;
+ Scan1 = list_Cdr(List);
+
+ while (!list_Empty(Scan1)) {
+ if (Test(list_Car(Scan1))) {
+ list_Rplacd(Scan2, list_Cdr(Scan1));
+ list_Free(Scan1);
+ Scan1 = list_Cdr(Scan2);
+ }
+ else {
+ Scan2 = Scan1;
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ return List;
+}
+
+
+LIST list_DeleteElementIfFree(LIST List, BOOL (*Test)(POINTER),
+ void (*Delete)(POINTER))
+/**************************************************************
+ INPUT: A list, a test for elements and a delete function
+ for elements.
+ RETURNS: The list where an element is deleted if <Test> on it
+ succeeds.
+ The element is deleted with <Delete>.
+ CAUTION: Destructive. Be careful, the first element of a list
+ cannot be changed destructively by call by reference.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ while (!list_Empty(List) && Test(list_Car(List))) {
+ Scan1 = list_Cdr(List);
+ Delete(list_Car(List));
+ list_Free(List);
+ List = Scan1;
+ }
+
+ if (list_Empty(List))
+ return list_Nil();
+
+ Scan2 = List;
+ Scan1 = list_Cdr(List);
+
+ while (!list_Empty(Scan1)) {
+ if (Test(list_Car(Scan1))) {
+ Delete(list_Car(Scan1));
+ list_Rplacd(Scan2, list_Cdr(Scan1));
+ list_Free(Scan1);
+ Scan1 = list_Cdr(Scan2);
+ }
+ else {
+ Scan2 = Scan1;
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ return List;
+}
+
+
+
+LIST list_DeleteElementFree(LIST List, POINTER Element,
+ BOOL (*Test)(POINTER, POINTER),
+ void (*Free)(POINTER))
+/**************************************************************
+ INPUT: A list, an element pointer, an equality test for
+ elements and a free function for elements.
+ RETURNS: The list where Element is deleted from List with
+ respect to Test.
+ EFFECTS: If the list contains <Element> with respect to <Test>,
+ <Element> is deleted from the list and freed.
+ CAUTION: Destructive. Be careful, the first element of a list
+ cannot be changed destructively by call by reference.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ while (!list_Empty(List) && Test(Element, list_Car(List))) {
+ Scan1 = list_Cdr(List);
+ Free(list_Car(List));
+ list_Free(List);
+ List = Scan1;
+ }
+
+ if (list_Empty(List))
+ return list_Nil();
+
+ Scan2 = List;
+ Scan1 = list_Cdr(List);
+
+ while (!list_Empty(Scan1)) {
+ if (Test(Element, list_Car(Scan1))) {
+ list_Rplacd(Scan2, list_Cdr(Scan1));
+ Free(list_Car(Scan1));
+ list_Free(Scan1);
+ Scan1 = list_Cdr(Scan2);
+ }
+ else {
+ Scan2 = Scan1;
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ return List;
+}
+
+
+LIST list_DeleteOneElement(LIST List, POINTER Element, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: A list, an element pointer and an equality test for
+ elements.
+ RETURNS: The list where at most one element was deleted from
+ <List> if the Test between <Element> and the element
+ succeeds.
+ EFFECT: The function needs time O(n*t) in the worst case, and
+ time O(t) in the best case, where <n> is the length of
+ the list and t is the time for a call of the test function.
+ CAUTION: Destructive. Be careful, the first element of a list
+ cannot be changed destructively by call by
+ reference.
+ The memory of the deleted element is not freed.
+***************************************************************/
+{
+ LIST scan1, scan2;
+
+ if (list_Empty(List))
+ return List;
+ else {
+ if (Test(Element, list_Car(List)))
+ return list_Pop(List);
+ }
+
+ for (scan2 = List, scan1 = list_Cdr(List); !list_Empty(scan1);
+ scan2 = scan1, scan1 = list_Cdr(scan1)) {
+ if (Test(Element, list_Car(scan1))) {
+ list_Rplacd(scan2, list_Cdr(scan1));
+ list_Free(scan1);
+ scan1 = list_Cdr(scan2);
+ return List;
+ }
+ }
+ return List;
+}
+
+
+LIST list_PointerDeleteElement(LIST List, POINTER Element)
+/**************************************************************
+ INPUT: A list and an element pointer
+ RETURNS: The list where Element is deleted from List with respect to
+ pointer equality.
+ EFFECTS: If <List> contains <Element> with respect to pointer equality,
+ <Element> is deleted from <List>.
+ This function needs time O(n), where <n> is the length of the list.
+ CAUTION: Destructive. Be careful, the first element of a list cannot
+ be changed destructively by call by reference.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ while (!list_Empty(List) && Element == list_Car(List)) {
+ Scan1 = list_Cdr(List);
+ list_Free(List);
+ List = Scan1;
+ }
+
+ if (list_Empty(List))
+ return list_Nil();
+
+ Scan2 = List;
+ Scan1 = list_Cdr(List);
+
+ while (!list_Empty(Scan1)) {
+ if (Element == list_Car(Scan1)) {
+ list_Rplacd(Scan2, list_Cdr(Scan1));
+ list_Free(Scan1);
+ Scan1 = list_Cdr(Scan2);
+ }
+ else {
+ Scan2 = Scan1;
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ return List;
+}
+
+LIST list_PointerDeleteElementFree(LIST List, POINTER Element,
+ void (*Free)(POINTER))
+/**************************************************************
+ INPUT: A list, an element pointer and a free function for
+ elements.
+ RETURNS: The list where Element is deleted from List with
+ respect to pointer equality and freed.
+ EFFECTS: If List contains Element with respect to pointer
+ equality, Element is deleted from List
+ CAUTION: Destructive. Be careful, the first element of a list
+ cannot be changed destructively by call by
+ reference.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ while (!list_Empty(List) && Element == list_Car(List)) {
+ Scan1 = list_Cdr(List);
+ Free(list_Car(List));
+ list_Free(List);
+ List = Scan1;
+ }
+
+ if (list_Empty(List))
+ return list_Nil();
+
+ Scan2 = List;
+ Scan1 = list_Cdr(List);
+
+ while (!list_Empty(Scan1)) {
+ if (Element == list_Car(Scan1)) {
+ list_Rplacd(Scan2, list_Cdr(Scan1));
+ Free(list_Car(Scan1));
+ list_Free(Scan1);
+ Scan1 = list_Cdr(Scan2);
+ }
+ else {
+ Scan2 = Scan1;
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ return List;
+}
+
+
+LIST list_PointerDeleteOneElement(LIST List, POINTER Element)
+/**************************************************************
+ INPUT: A list and an element pointer.
+ RETURNS: The list where one occurrence of Element is deleted from List
+ with respect to pointer equality.
+ EFFECTS: If List contains Element with respect to pointer equality,
+ Element is deleted from List.
+ CAUTION: Destructive. Be careful, the first element of a list cannot
+ be changed destructively by call by reference.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ if (list_Empty(List))
+ return List;
+ else {
+ if (Element == list_Car(List))
+ return list_Pop(List);
+ }
+
+ Scan2 = List;
+ Scan1 = list_Cdr(List);
+
+ while (!list_Empty(Scan1)) {
+ if (Element == list_Car(Scan1)) {
+ list_Rplacd(Scan2, list_Cdr(Scan1));
+ list_Free(Scan1);
+ Scan1 = list_Cdr(Scan2);
+ return List;
+ }
+ else {
+ Scan2 = Scan1;
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ return List;
+}
+
+
+BOOL list_DeleteFromList(LIST* List, POINTER Element)
+/**************************************************************
+ INPUT: A list and an element pointer
+ RETURNS: TRUE, if Element was deleted; FALSE, otherwise.
+ EFFECTS: If List contains Element with respect to pointer equality,
+ all occurrences of Element are deleted from List.
+ CAUTION: Destructive. Be careful, the first element of a list cannot
+ be changed destructively by call by reference.
+***************************************************************/
+{
+ BOOL Found;
+ LIST Scan1;
+
+ Found = FALSE;
+
+ while (list_Exist(*List) && Element == list_Car(*List)) {
+ Scan1 = list_Cdr(*List);
+ list_Free(*List);
+ *List = Scan1;
+ Found = TRUE;
+ }
+
+ if (list_Exist(*List)) {
+ LIST Scan2;
+
+ Scan2 = *List;
+ Scan1 = list_Cdr(*List);
+
+ while (list_Exist(Scan1)) {
+ if (Element == list_Car(Scan1)) {
+ list_Rplacd(Scan2, list_Cdr(Scan1));
+ list_Free(Scan1);
+ Scan1 = list_Cdr(Scan2);
+ Found = TRUE;
+ } else {
+ Scan2 = Scan1;
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ }
+
+ return Found;
+}
+
+
+BOOL list_DeleteOneFromList(LIST* List, POINTER Element)
+/**************************************************************
+ INPUT: A list and an element pointer
+ RETURNS: TRUE, if <Element> was deleted; FALSE, otherwise.
+ EFFECTS: If <List> contains <Element> with respect to pointer equality,
+ the first occurrence of <Element> is deleted from <List>.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ if (list_Exist(*List)) {
+ LIST Scan1;
+
+ /* special treatment for the first element */
+ if (Element == list_Car(*List)) {
+ Scan1 = list_Cdr(*List);
+ list_Free(*List);
+ *List = Scan1;
+ return TRUE;
+ } else {
+ LIST Scan2;
+
+ for (Scan2 = *List, Scan1 = list_Cdr(*List); list_Exist(Scan1); ) {
+ if (Element == list_Car(Scan1)) {
+ list_Rplacd(Scan2, list_Cdr(Scan1));
+ list_Free(Scan1);
+ Scan1 = list_Cdr(Scan2);
+ return TRUE;
+ } else {
+ Scan2 = Scan1;
+ Scan1 = list_Cdr(Scan1);
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+BOOL list_IsSetOfPointers(LIST L)
+/**************************************************************
+ INPUT: A list.
+ RETURNS: TRUE, if <L> is a set of pointers (without duplicates),
+ FALSE, otherwise.
+ EFFECT: The function needs n(n-1)/2 comparisons in the worst case,
+ where n is the length of the list. So its time complexity
+ is O(n^2).
+***************************************************************/
+{
+ for ( ; !list_Empty(L); L = list_Cdr(L)) {
+ if (list_PointerMember(list_Cdr(L), list_Car(L)))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+LIST list_DeleteDuplicates(LIST List, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: A list, an equality test for elements
+ RETURNS: The list where multiple occurrences are deleted.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ LIST Scan;
+
+ Scan = List;
+
+ while (!list_Empty(Scan)) {
+ list_Rplacd(Scan,
+ list_DeleteElement(list_Cdr(Scan), list_Car(Scan), Test));
+ Scan = list_Cdr(Scan);
+ }
+ return List;
+}
+
+
+LIST list_DeleteDuplicatesFree(LIST List, BOOL (*Test)(POINTER, POINTER),
+ void (*Free)(POINTER))
+/**************************************************************
+ INPUT: A list, an equality test for elements, and a free
+ function for elements.
+ RETURNS: The list where multiple occurrences are deleted.
+ CAUTION: Destructive and frees all duplicates.
+***************************************************************/
+{
+ LIST Scan;
+
+ Scan = List;
+
+ while (!list_Empty(Scan)) {
+ list_Rplacd(Scan, list_DeleteElementFree(list_Cdr(Scan), list_Car(Scan), Test, Free));
+ Scan = list_Cdr(Scan);
+ }
+ return List;
+}
+
+
+LIST list_PointerDeleteDuplicates(LIST List)
+/**************************************************************
+ INPUT: A list
+ RETURNS: The list where multiple occurrences are deleted.
+ CAUTION: Destructive.
+ EFFECT: The function needs
+***************************************************************/
+{
+ LIST Scan;
+
+ Scan = List;
+
+ while (!list_Empty(Scan)) {
+ list_Rplacd(Scan, list_PointerDeleteElement(list_Cdr(Scan),
+ list_Car(Scan)));
+ Scan = list_Cdr(Scan);
+ }
+ return List;
+}
+
+
+LIST list_NPointerUnion(LIST List1, LIST List2)
+/**************************************************************
+ INPUT: Two lists.
+ RETURNS: Regarding both lists as sets, the union of the sets.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ return list_PointerDeleteDuplicates(list_Nconc(List1,List2));
+}
+
+
+LIST list_NUnion(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: Two lists and an equality test for the elements.
+ RETURNS: Regarding both lists as sets, the union of the sets.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ return list_DeleteDuplicates(list_Nconc(List1,List2), Test);
+}
+
+
+LIST list_NListTimes(LIST List1, LIST List2)
+/**************************************************************
+ INPUT: Two lists of lists.
+ RETURNS: The list of combinations of element lists.
+ CAUTION: Destroys List1 and List2.
+***************************************************************/
+{
+ LIST Result, Scan1, Scan2;
+
+ Result = list_Nil();
+
+ if (!list_Empty(List2)) {
+ for (Scan1=List1; !list_Empty(Scan1); Scan1=list_Cdr(Scan1))
+ for (Scan2=List2; !list_Empty(Scan2); Scan2=list_Cdr(Scan2))
+ Result = list_Cons(list_Append(((LIST)list_Car(Scan1)),
+ list_Copy((LIST)list_Car(Scan2))),
+ Result);
+ }
+ list_DeleteWithElement(List1, (void (*)(POINTER))list_Delete);
+ list_DeleteWithElement(List2, (void (*)(POINTER))list_Delete);
+
+ return Result;
+}
+
+
+LIST list_NIntersect(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: Two lists and an equality test for the elements.
+ RETURNS: Regarding both lists as sets, the intersection of the sets.
+ CAUTION: Destructive on List1
+***************************************************************/
+{
+ LIST Scan1, Scan2;
+
+ while (!list_Empty(List1) && !list_Member(List2, list_Car(List1), Test)) {
+ Scan1 = list_Cdr(List1);
+ list_Free(List1);
+ List1 = Scan1;
+ }
+
+ if (list_Empty(List1))
+ return List1;
+
+ Scan1 = List1;
+ Scan2 = list_Cdr(List1);
+
+ while (!list_Empty(Scan2)) {
+ if (list_Member(List2, list_Car(Scan2), Test)) {
+ Scan2 = list_Cdr(Scan2);
+ Scan1 = list_Cdr(Scan1);
+ }
+ else {
+ list_Rplacd(Scan1, list_Cdr(Scan2));
+ list_Free(Scan2);
+ Scan2 = list_Cdr(Scan1);
+ }
+ }
+ return List1;
+}
+
+
+LIST list_NPointerIntersect(LIST List1, LIST List2)
+/**************************************************************
+ INPUT: Two lists.
+ RETURNS: Regarding both lists as sets, the intersection of the sets.
+ CAUTION: Destructive on List1
+***************************************************************/
+{
+ LIST Scan1, Scan2;
+
+ while (!list_Empty(List1) && !list_PointerMember(List2, list_Car(List1))) {
+ Scan1 = list_Cdr(List1);
+ list_Free(List1);
+ List1 = Scan1;
+ }
+
+ if (list_Empty(List1))
+ return List1;
+
+ Scan1 = List1;
+ Scan2 = list_Cdr(List1);
+
+ while (!list_Empty(Scan2)) {
+ if (list_PointerMember(List2, list_Car(Scan2))) {
+ Scan2 = list_Cdr(Scan2);
+ Scan1 = list_Cdr(Scan1);
+ }
+ else {
+ list_Rplacd(Scan1, list_Cdr(Scan2));
+ list_Free(Scan2);
+ Scan2 = list_Cdr(Scan1);
+ }
+ }
+ return List1;
+}
+
+
+void list_NInsert(LIST List1, LIST List2)
+/**************************************************************
+ INPUT: Two lists where <List1> must not be empty.
+ EFFECT: <List2> is destructively concatenated after
+ the first element of <List1>.
+ RETURNS: void.
+ CAUTION: Destructive on List1 and List2.
+***************************************************************/
+{
+ LIST Help;
+
+#ifdef CHECK
+ if (list_Empty(List1)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In list_NInsert: Empty list argument.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Help = list_Cdr(List1);
+ list_Rplacd(List1,List2);
+ List2 = List1;
+
+ while (!list_Empty(list_Cdr(List2)))
+ List2 = list_Cdr(List2);
+
+ list_Rplacd(List2,Help);
+}
+
+
+BOOL list_HasIntersection(LIST List1, LIST List2)
+/**************************************************************
+ INPUT: Two lists .
+ RETURNS: TRUE iff List1 and List2 have a common element.
+ EFFECT: The function needs time O(n*m), where n and m are the
+ lengths of the lists.
+***************************************************************/
+{
+ LIST Scan;
+
+ if (!list_Empty(List2)) {
+ for (Scan=List1; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (list_PointerMember(List2, list_Car(Scan)))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+LIST list_NPointerDifference(LIST List1, LIST List2)
+/**************************************************************
+ INPUT: Two lists.
+ RETURNS: The list List1-List2.
+ CAUTION: Destructive on List1.
+***************************************************************/
+{
+ LIST Scan;
+
+ if (!list_Empty(List1)) {
+ for (Scan=List2; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ List1 = list_PointerDeleteElement(List1, list_Car(Scan));
+ }
+ return List1;
+}
+
+
+LIST list_NDifference(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: Two lists and an equality test for elements.
+ RETURNS: The list List1-List2 wrt. <Test>.
+ CAUTION: Destructive on List1.
+***************************************************************/
+{
+ LIST Scan;
+
+ if (!list_Empty(List1)) {
+ for (Scan=List2; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ List1 = list_DeleteElement(List1, list_Car(Scan), Test);
+ }
+ return List1;
+}
+
+
+LIST list_NMultisetDifference(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: Two lists representing multisets and an equality
+ test for elements.
+ RETURNS: The multiset difference List1-List2 wrt. <Test>.
+ CAUTION: Destructive on List1. The memory of deleted
+ elements is not freed.
+***************************************************************/
+{
+ LIST scan;
+ /* Delete equal arguments */
+ if (!list_Empty(List1)) {
+ for (scan = List2; !list_Empty(scan); scan = list_Cdr(scan))
+ /* Delete at most one element from List1 equal to */
+ /* the actual element of List2. */
+ List1 = list_DeleteOneElement(List1, list_Car(scan), Test);
+ }
+ return List1;
+}
+
+
+BOOL list_PointerReplaceMember(LIST List, POINTER Old, POINTER New)
+/**************************************************************
+ INPUT: A list, a pointer to an old element, a pointer to a new element
+ RETURNS: TRUE iff <Old> was replaced.
+ EFFECT: The first occurrence of <Old> in the list is replaced by <New>.
+***************************************************************/
+{
+ while (!list_Empty(List)) {
+ if (Old == list_Car(List)) {
+ list_Rplaca(List, New);
+ return TRUE;
+ }
+ List = list_Cdr(List);
+ }
+ return FALSE;
+}
+
+
+void list_DeleteAssocListWithValues(LIST List, void (*ValueDelete)(POINTER))
+/**************************************************************
+ INPUT: An association list and a delete function for the values.
+ RETURNS: void.
+ EFFECT: The assoc list and its values are deleted.
+***************************************************************/
+{
+ LIST Scan;
+
+ for (Scan=List;!list_Empty(Scan);Scan = list_Cdr(Scan)) {
+ ValueDelete(list_PairSecond(list_Car(Scan)));
+ list_PairFree(list_Car(Scan));
+ }
+
+ list_Delete(List);
+}
+
+
+POINTER list_AssocListValue(LIST List, POINTER Key)
+/**************************************************************
+ INPUT: An association list and a key.
+ RETURNS: The value for <key> in the list. If <key> is not
+ contained, NULL.
+***************************************************************/
+{
+ LIST Scan;
+
+ for (Scan=List;!list_Empty(Scan);Scan = list_Cdr(Scan))
+ if (Key == list_PairFirst(list_Car(Scan)))
+ return list_PairSecond(list_Car(Scan));
+
+ return NULL;
+}
+
+
+LIST list_AssocListPair(LIST List, POINTER Key)
+/**************************************************************
+ INPUT: An association list and a key.
+ RETURNS: The (<key>.<value) in the list. If <key> is not
+ contained, the NULL pair.
+***************************************************************/
+{
+ LIST Scan;
+
+ for (Scan=List;!list_Empty(Scan);Scan = list_Cdr(Scan))
+ if (Key == list_PairFirst(list_Car(Scan)))
+ return list_Car(Scan);
+
+ return list_PairNull();
+}
+
+
+LIST list_MultisetDistribution(LIST Multiset)
+/**************************************************************
+ INPUT: A list representing a multiset.
+ RETURNS: The associative list of pairs (<element>.<occurrences>)
+ representing the distribution of elements in the list.
+ If the input multiset is empty, the NULL pair.
+***************************************************************/
+{
+ LIST Distribution;
+ LIST Scan;
+
+ Distribution = list_PairNull();
+
+ for (Scan = Multiset; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ LIST Count;
+ POINTER Element;
+ int Occurences;
+
+ Element = list_Car(Scan);
+ Count = list_AssocListPair(Distribution, Element);
+
+ if (Count != list_PairNull()) {
+ Occurences = (int) list_PairSecond(Count);
+ list_PairRplacSecond(Count, (POINTER) (Occurences + 1));
+ }
+ else {
+ Distribution = list_AssocCons(Distribution, Element, (POINTER) 1);
+ }
+ }
+
+ return Distribution;
+}
+
+
+int list_CompareElementDistribution(LIST LeftPair, LIST RightPair)
+/**************************************************************
+ INPUT: Two lists, representing single element frequency
+ counts.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two element frequencies.
+***************************************************************/
+{
+ if ((int) list_PairSecond(LeftPair) < (int) list_PairSecond(RightPair)) {
+ return -1;
+ }
+ else if ((int) list_PairSecond(LeftPair) > (int) list_PairSecond(RightPair)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+BOOL list_CompareElementDistributionLEQ(LIST LeftPair, LIST RightPair) {
+/**************************************************************
+ INPUT: Two lists, representing single element frequency
+ counts.
+ RETURNS: TRUE if left <= right, FALSE otherwise.
+ EFFECT: Compares two element frequencies.
+***************************************************************/
+ return (list_CompareElementDistribution(LeftPair, RightPair) <= 0);
+}
+
+
+static int list_CompareDistributions(LIST Left, LIST Right)
+/**************************************************************
+ INPUT: Two lists, representing element distributions.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares the two distributions by comparing the
+ element frequencies from left to right.
+ CAUTION: Expects the distributions to be sorted.
+***************************************************************/
+{
+ LIST scan, scan2;
+ int result;
+
+ result = 0;
+
+ scan = Left;
+ scan2 = Right;
+
+ /* Compare distributions. */
+
+ while ( !(list_Empty(scan) || list_Empty(scan2))) {
+ result = list_CompareElementDistribution(list_Car(scan), list_Car(scan2));
+ if (result != 0) {
+ break;
+ }
+
+ scan = list_Cdr(scan);
+ scan2 = list_Cdr(scan2);
+ }
+
+ /* If the result is 0, and a distribution still
+ has elements left, it is declared to be greater.
+ */
+ if (result == 0) {
+ if (list_Empty(scan) && !list_Empty(scan2))
+ result = -1;
+ else if (!list_Empty(scan) && list_Empty(scan2))
+ result = 1;
+ }
+
+ return result;
+}
+
+
+int list_CompareMultisetsByElementDistribution(LIST Left, LIST Right)
+/**************************************************************
+ INPUT: Two lists, representing multisets.
+ RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+ EFFECT: Compares two multisets by counting their element
+ frequencies, sorting them, and comparing the
+ resulting multisets over natural numbers.
+***************************************************************/
+{
+ LIST lmsd, rmsd; /* multiset distributions. */
+ int result;
+
+ /* Convert multiset of elements into a
+ multiset of pairs (element, occurrences).
+ */
+
+ lmsd = list_MultisetDistribution(Left);
+ rmsd = list_MultisetDistribution(Right);
+
+ /* Sort multiset distributions in order
+ to make them comparable.
+ */
+
+ lmsd = list_Sort(lmsd, (BOOL (*) (POINTER, POINTER)) list_CompareElementDistributionLEQ);
+ rmsd = list_Sort(rmsd, (BOOL (*) (POINTER, POINTER)) list_CompareElementDistributionLEQ);
+
+ result = list_CompareDistributions(lmsd, rmsd);
+
+ list_DeleteDistribution(lmsd);
+ list_DeleteDistribution(rmsd);
+
+ return result;
+}
+
+
+NAT list_Length(LIST List)
+/**************************************************************
+ INPUT: A List.
+ RETURNS: The number of elements..
+ EFFECT: The function needs time O(n), where <n> is the length
+ of the list.
+***************************************************************/
+{
+ NAT Result;
+
+ Result = 0;
+
+ while (!list_Empty(List)) {
+ Result++;
+ List = list_Cdr(List);
+ }
+
+ return Result;
+}
+
+
+NAT list_Bytes(LIST List)
+/**************************************************************
+ INPUT: A List.
+ RETURNS: The number of Bytes occupied by the list structure of <List>
+ EFFECT: the function needs time O(n), where <n> is the length
+ of the list.
+***************************************************************/
+{
+ return (list_Length(List)*sizeof(LIST_NODE));
+}
diff --git a/test/spass/list.h b/test/spass/list.h
new file mode 100644
index 0000000..fa390a3
--- /dev/null
+++ b/test/spass/list.h
@@ -0,0 +1,433 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * LISTS * */
+/* * * */
+/* * $Module: LIST * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _LIST_
+#define _LIST_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "memory.h"
+#include "misc.h"
+
+/**************************************************************/
+/* Structures */
+/**************************************************************/
+
+typedef struct LIST_HELP {
+ struct LIST_HELP *cdr;
+ POINTER car;
+} LIST_NODE;
+
+typedef LIST_NODE *LIST;
+
+/**************************************************************/
+/* Macros */
+/**************************************************************/
+
+static __inline__ void list_Free(LIST L)
+{
+ memory_Free(L, sizeof(LIST_NODE));
+}
+
+static __inline__ LIST list_Nil(void)
+{
+ return NULL;
+}
+
+static __inline__ BOOL list_Empty(LIST L)
+{
+ return L == NULL;
+}
+
+static __inline__ BOOL list_Exist(LIST L)
+{
+ return L != NULL;
+}
+
+static __inline__ POINTER list_Car(LIST L)
+{
+ return L->car;
+}
+
+static __inline__ POINTER list_NCar(LIST *L)
+{
+ POINTER Result;
+ LIST Help;
+
+ Result = (*L)->car;
+ Help = (*L)->cdr;
+ list_Free(*L);
+ *L = Help;
+ return Result;
+}
+
+static __inline__ LIST list_Cdr(LIST L)
+{
+ return L->cdr;
+}
+
+static __inline__ POINTER list_First(LIST L)
+{
+ return list_Car(L);
+}
+
+static __inline__ POINTER list_Second(LIST L)
+{
+ return list_Car(list_Cdr(L));
+}
+
+static __inline__ POINTER list_Third(LIST L)
+{
+ return list_Car(list_Cdr(list_Cdr(L)));
+}
+
+static __inline__ POINTER list_Fourth(LIST L)
+{
+ return(list_Third(list_Cdr(L)));
+}
+
+static __inline__ POINTER list_Fifth(LIST L)
+{
+ return(list_Fourth(list_Cdr(L)));
+}
+
+static __inline__ void list_Rplacd(LIST L1, LIST L2)
+{
+ L1->cdr = L2;
+}
+
+static __inline__ void list_Rplaca(LIST L, POINTER P)
+{
+ L->car = P;
+}
+
+static __inline__ void list_RplacSecond(LIST L, POINTER P)
+{
+ list_Rplaca(list_Cdr(L), P);
+}
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+LIST list_Copy(const LIST);
+LIST list_CopyWithElement(const LIST, POINTER (*)(POINTER));
+void list_InsertNext(LIST, POINTER);
+
+void list_NMapCar(LIST, POINTER (*)(POINTER));
+void list_Apply(void (*)(POINTER), LIST);
+
+LIST list_Reverse(const LIST);
+LIST list_NReverse(LIST);
+
+void list_Split(LIST, LIST *, LIST *);
+LIST list_PointerSort(LIST);
+LIST list_Merge(LIST, LIST, BOOL (*)(POINTER, POINTER));
+LIST list_MergeSort(LIST, BOOL (*)(POINTER, POINTER));
+LIST list_InsertionSort(LIST, BOOL (*)(POINTER, POINTER));
+LIST list_Sort(LIST, BOOL (*)(POINTER, POINTER));
+BOOL list_SortedInOrder(LIST, BOOL (*)(POINTER, POINTER));
+LIST list_NumberSort(LIST , NAT (*)(POINTER));
+LIST list_GreaterNumberSort(LIST , NAT (*)(POINTER));
+LIST list_NNumberMerge(LIST , LIST, NAT (*)(POINTER));
+
+POINTER list_DequeueNext(LIST);
+POINTER list_NthElement(LIST, NAT);
+void list_DeleteWithElement(LIST, void (*)(POINTER));
+NAT list_DeleteWithElementCount(LIST, void (*)(POINTER));
+LIST list_DeleteElement(LIST, POINTER, BOOL (*)(POINTER, POINTER));
+LIST list_DeleteElementIf(LIST, BOOL (*)(POINTER));
+LIST list_DeleteElementIfFree(LIST, BOOL (*)(POINTER), void (*)(POINTER));
+LIST list_DeleteElementFree(LIST, POINTER, BOOL (*)(POINTER, POINTER), void (*)(POINTER));
+LIST list_DeleteOneElement(LIST, POINTER, BOOL (*)(POINTER, POINTER));
+LIST list_PointerDeleteElement(LIST, POINTER);
+LIST list_PointerDeleteElementFree(LIST, POINTER, void (*)(POINTER));
+LIST list_PointerDeleteOneElement(LIST, POINTER);
+BOOL list_DeleteFromList(LIST*, POINTER);
+BOOL list_DeleteOneFromList(LIST*, POINTER);
+LIST list_DeleteDuplicates(LIST, BOOL (*)(POINTER, POINTER));
+LIST list_DeleteDuplicatesFree(LIST, BOOL (*)(POINTER, POINTER), void (*)(POINTER));
+LIST list_PointerDeleteDuplicates(LIST);
+
+BOOL list_IsSetOfPointers(LIST);
+LIST list_NPointerUnion(LIST, LIST);
+LIST list_NUnion(LIST, LIST, BOOL (*)(POINTER, POINTER));
+LIST list_NListTimes(LIST, LIST);
+LIST list_NIntersect(LIST, LIST, BOOL (*)(POINTER, POINTER));
+void list_NInsert(LIST, LIST);
+LIST list_NPointerIntersect(LIST, LIST);
+BOOL list_HasIntersection(LIST, LIST);
+LIST list_NPointerDifference(LIST, LIST);
+LIST list_NDifference(LIST, LIST, BOOL (*)(POINTER, POINTER));
+LIST list_NMultisetDifference(LIST, LIST, BOOL (*)(POINTER, POINTER));
+BOOL list_PointerReplaceMember(LIST, POINTER, POINTER);
+
+void list_DeleteAssocListWithValues(LIST, void (*)(POINTER));
+POINTER list_AssocListValue(LIST, POINTER);
+LIST list_AssocListPair(LIST, POINTER);
+
+LIST list_MultisetDistribution(LIST);
+int list_CompareMultisetsByElementDistribution(LIST, LIST);
+
+NAT list_Length(LIST);
+NAT list_Bytes(LIST);
+
+/**************************************************************/
+/* Functional Inline Functions */
+/**************************************************************/
+
+static __inline__ LIST list_Cons(POINTER Ptr, const LIST List)
+{
+ LIST Cell;
+
+ Cell = (LIST)memory_Malloc(sizeof(LIST_NODE));
+ Cell->car = Ptr;
+ Cell->cdr = List;
+ return Cell;
+}
+
+
+static __inline__ LIST list_Nconc(LIST List1, LIST List2)
+{
+ LIST Result;
+
+ if (list_Empty(List1))
+ return List2;
+
+ if (list_Empty(List2))
+ return List1;
+
+ Result = List1;
+ for (List1 = Result; !list_Empty(list_Cdr(List1)); List1 = list_Cdr(List1))
+ /* empty */;
+ List1->cdr = List2;
+ return Result;
+}
+
+
+static __inline__ LIST list_List(POINTER P)
+{
+ return list_Cons(P,list_Nil());
+}
+
+
+static __inline__ LIST list_Append(LIST List1, LIST List2)
+{
+ LIST Result;
+
+ if (list_Empty(List1))
+ return List2;
+ if (list_Empty(List2))
+ return list_Copy(List1);
+
+ Result = list_Copy(List1);
+ for (List1 = Result; !list_Empty(list_Cdr(List1)); List1 = list_Cdr(List1))
+ /* empty */;
+ List1->cdr = List2;
+ return Result;
+}
+
+
+static __inline__ void list_Delete(LIST L)
+{
+ LIST Current;
+
+ Current = L;
+ while (!list_Empty(Current)) {
+ L = list_Cdr(L);
+ list_Free(Current);
+ Current = L;
+ }
+}
+
+static __inline__ BOOL list_Member(LIST List, POINTER Element,
+ BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+ INPUT: A list and an element pointer and an equality test for two elements.
+ RETURNS: TRUE iff Element is in List with respect to Test
+***************************************************************/
+{
+ while (!list_Empty(List)) {
+ if (Test(Element, list_Car(List)))
+ return TRUE;
+ List = list_Cdr(List);
+ }
+
+ return FALSE;
+}
+
+
+static __inline__ BOOL list_PointerMember(LIST List, POINTER Element)
+/**************************************************************
+ INPUT: A list and an element pointer.
+ RETURNS: TRUE iff Element is in List with respect to pointer equality.
+***************************************************************/
+{
+ while (!list_Empty(List)) {
+ if (Element == list_Car(List))
+ return TRUE;
+ List = list_Cdr(List);
+ }
+
+ return FALSE;
+}
+
+/**************************************************************/
+/* Stack Macros */
+/**************************************************************/
+
+static __inline__ LIST list_StackBottom(void)
+{
+ return list_Nil();
+}
+
+
+static __inline__ BOOL list_StackEmpty(LIST S)
+{
+ return list_Empty(S);
+}
+
+
+static __inline__ LIST list_Push(POINTER I, LIST L)
+{
+ return list_Cons(I, L);
+}
+
+
+static __inline__ POINTER list_Top(LIST L)
+{
+ return list_Car(L);
+}
+
+
+static __inline__ LIST list_Pop(LIST L)
+{
+ LIST Aux = L;
+
+ L = list_Cdr(L);
+ list_Free(Aux);
+ return L;
+}
+
+
+static __inline__ void list_RplacTop(LIST L, POINTER P)
+{
+ list_Rplaca(L, P);
+}
+
+
+static __inline__ LIST list_StackFree(LIST L)
+{
+ while (!list_StackEmpty(L))
+ L = list_Pop(L);
+ return list_Nil();
+}
+
+
+/**************************************************************/
+/* Pair Macros */
+/**************************************************************/
+
+static __inline__ LIST list_PairNull(void)
+{
+ return list_Nil();
+}
+
+
+static __inline__ LIST list_PairCreate(POINTER P1, POINTER P2)
+{
+ return list_Cons(P1, P2);
+}
+
+
+static __inline__ void list_PairFree(LIST L)
+{
+ list_Free(L);
+}
+
+
+static __inline__ POINTER list_PairFirst(LIST L)
+{
+ return list_Car(L);
+}
+
+
+static __inline__ POINTER list_PairSecond(LIST L)
+{
+ return (POINTER)list_Cdr(L);
+}
+
+static __inline__ void list_PairRplacSecond(LIST L, POINTER P)
+{
+ list_Rplacd(L,P);
+}
+
+static __inline__ void list_DeletePairList(LIST L)
+ /* Delete a list of pairs */
+{
+ list_DeleteWithElement(L, (void (*)(POINTER))list_PairFree);
+}
+
+static __inline__ void list_DeleteDistribution(LIST L)
+{
+ list_DeletePairList(L);
+}
+
+/**************************************************************/
+/* Assoc Lists */
+/**************************************************************/
+
+
+static __inline__ LIST list_AssocCons(LIST L, POINTER Key, POINTER Value)
+{
+ return list_Cons(list_PairCreate(Key, Value), L);
+}
+
+#endif
diff --git a/test/spass/memory.c b/test/spass/memory.c
new file mode 100644
index 0000000..a785515
--- /dev/null
+++ b/test/spass/memory.c
@@ -0,0 +1,1595 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * DYNAMIC MEMORY MANAGEMENT MODULE * */
+/* * * */
+/* * $Module: MEMORY * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "memory.h"
+
+unsigned int memory_PAGESIZE; /* size of a page */
+long memory_MAXMEM; /* amount of memory available for allocation */
+static int memory__EOF = EOF; /* internal "End Of Memory" marker */
+unsigned long memory_NEWBYTES; /* number of allocated bytes */
+unsigned long memory_FREEDBYTES; /* number of freed bytes */
+
+const unsigned int memory_ALIGN = sizeof(POINTER);
+/* Crucial: hardware must support access to words
+ of size POINTER.
+*/
+
+#ifdef CHECK
+unsigned int memory_LEFTTAG; /* size of left debug mark */
+unsigned int memory_OFFSET; /* alignment-correct size of left debug mark */
+unsigned int memory_MARKSIZE; /* total size of debug marks */
+
+BOOL memory_MANAGEMENT_INITIALIZED = FALSE;
+
+#else /* CHECK not defined */
+unsigned int memory_MARKSIZE = 0;
+unsigned int memory_OFFSET = 0;
+#endif /* CHECK */
+
+const unsigned int memory_MAGICMALLOC = 1; /* "block allocated" marker */
+const unsigned int memory_MAGICFREE = 2; /* "block freed" marker */
+
+/* Internal array of resources for different block sizes */
+/* ... + 1 to support odd values for memory__SHAREDPAGES like 7 */
+static MEMORY_RESOURCE memory_PAGES[memory__DYNMAXSIZE/memory__SHAREDPAGES + 1];
+
+
+/* Resources for all administrated block sizes */
+MEMORY_RESOURCE * memory_ARRAY[memory__DYNMAXSIZE];
+
+/* double linked list for administering blocks of memory
+ whose size is greater or equal to memory__DYNMAXSIZE.
+*/
+MEMORY_BIGBLOCKHEADER memory_BIGBLOCKS = NULL;
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INITIALIZATION * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+#ifdef CHECK
+static BOOL memory_ManagementInitialized(void)
+/**********************************************************
+ INPUT : None.
+ RETURNS: TRUE if memory management is already initialized,
+ else FALSE.
+ SUMMARY: Checks if memory_Init was called.
+**********************************************************/
+{
+ return memory_MANAGEMENT_INITIALIZED;
+}
+#endif /* CHECK */
+
+void memory_Init(long Maxmem)
+/*************************************************************
+ INPUT : The maximal amount of memory available in bytes
+ for the memory module; if Maxmem < 0 the module
+ allocates as much memory as available from the
+ system.
+ RETURNS: None.
+ SUMMARY: Initializes the memory management. It has to be
+ called before you can perform any module operation.
+ This function automatically increases the default
+ page size if it is too small for two objects of
+ size memory__DYNMAXSIZE.
+*************************************************************/
+{
+ int i;
+ int extra; /* size of internally used space on each page */
+
+ memory_FREEDBYTES = 0; /* set total number of freed bytes to zero */
+ memory_NEWBYTES = 0; /* set total number of allocated bytes to zero */
+
+ /* set the size of a page we allocate from the operating system */
+ memory_PAGESIZE = memory__DEFAULTPAGESIZE;
+
+#ifdef CHECK
+
+ /* Test if memory management has already been initialized */
+
+ if (!memory_ManagementInitialized()) {
+ /* if that is not the case, set check variable to TRUE */
+ memory_MANAGEMENT_INITIALIZED = TRUE;
+ }
+ else {
+ /* otherwise the user is trying initialize it for a
+ second time, so print an error and exit.
+ */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_Init:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Trying to initialize memory management");
+ misc_UserErrorReport(" for a second time.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ /* Calculate the size of debug marks */
+ memory_LEFTTAG = sizeof(MEMORY_INFONODE) + sizeof(unsigned int);
+
+ if ((sizeof(MEMORY_INFONODE) + sizeof(unsigned int)) % memory_ALIGN == 0) {
+ memory_OFFSET = memory_LEFTTAG;
+ }
+ else {
+ memory_OFFSET = memory_LEFTTAG + memory_ALIGN
+ - (memory_LEFTTAG % memory_ALIGN);
+ }
+
+ if ((sizeof(unsigned int) % memory_ALIGN) == 0) {
+ memory_MARKSIZE = memory_OFFSET + sizeof(unsigned int);
+ }
+ else {
+ memory_MARKSIZE = memory_OFFSET + sizeof(unsigned int) + memory_ALIGN
+ - (sizeof(unsigned int) % memory_ALIGN);
+ }
+#endif
+
+ /* Calculate the size of internally used space on each page */
+ /* extra: One pointer for chaining pages, one for EOF (+ marksize) */
+ extra = 2*sizeof(POINTER) + memory_MARKSIZE;
+
+
+ /* Test whether page size is reasonable with respect
+ to dynamic allocation threshold
+ */
+ while (memory_PAGESIZE < (2*(memory__DYNMAXSIZE + memory_MARKSIZE) + extra)) {
+ /* Minimum two objects per allocated page */
+ memory_PAGESIZE += memory__DEFAULTPAGESIZE/2;
+ }
+
+ /* Set amount of memory available to the module for allocation */
+ if (Maxmem <= 0) {
+ /* unlimited (limited only by the operating system) */
+ memory_MAXMEM = memory__UNLIMITED;
+ }
+ else {
+ /* Maxmem bytes */
+ memory_MAXMEM = Maxmem;
+ }
+
+ /* Initialize memory_ARRAY and memory_RESOURCEs */
+ for (i=1; i<memory__DYNMAXSIZE; i++) {
+ MEMORY_RESOURCE *CurrentResource;
+ int TotalSize;
+
+ /* Map memory_ARRAY[i] to appropriate Resource */
+ memory_ARRAY[i] = &memory_PAGES[(i-1)/memory__SHAREDPAGES];
+
+ CurrentResource = memory_ARRAY[i];
+
+ CurrentResource->free = &memory__EOF; /* no blocks freed */
+ CurrentResource->next = &memory__EOF; /* no blocks allocated */
+ CurrentResource->end_of_page = &memory__EOF; /* no (end of) page */
+ CurrentResource->page = &memory__EOF; /* no page allocated */
+
+ /* Size of a properly aligned block of requested size i */
+ CurrentResource->aligned_size = memory_CalculateRealBlockSize(i);
+
+ /* Total block size including debug marks */
+ CurrentResource->total_size = memory_MARKSIZE
+ + CurrentResource->aligned_size;
+
+ TotalSize = CurrentResource->total_size;
+
+ /* last block´s offset */
+ CurrentResource->offset =
+ ((memory_PAGESIZE-extra)/TotalSize)*TotalSize
+ + sizeof(POINTER) + memory_OFFSET;
+ }
+}
+
+
+void memory_Restrict(long Maxmem)
+/*************************************************************
+ INPUT : The maximal amount of memory available for further
+ allocation (in bytes); if Maxmem < 0 future
+ allocations are unrestricted.
+ RETURNS: None.
+ SUMMARY: Sets the maximal amount of memory available for
+ future allocations. If the user tries to allocate
+ more memory, the module displays an error message
+ and terminates the program by calling the exit()
+ function.
+*************************************************************/
+{
+ /* Reset the maximum amount of memory available */
+ if (Maxmem <= 0) {
+ /* unlimited */
+ memory_MAXMEM = memory__UNLIMITED;
+ }
+ else {
+ /* Maxmem bytes */
+ memory_MAXMEM = Maxmem;
+ }
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CHECK CODE * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+#ifdef CHECK
+static void memory_CheckIfModuleIsInitialized(const char * Function,
+ const char * File,
+ unsigned short int Line)
+/********************************************************
+ INPUT : The name of the function that requests the
+ check, the name of the file and the line,
+ where the requesting function was called, and
+ the line.
+ RETURNS: None.
+ SUMMARY: Checks if the memory management module has
+ been properly initialized. You need to
+ initialize the module by calling memory_Init
+ before you use any functions from the module.
+ If the check fails, this function prints an
+ error message and exits the application.
+*********************************************************/
+{
+ if (!memory_ManagementInitialized()) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In %s:", Function);
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Memory management is not initialized.");
+ misc_UserErrorReport("\n You have to call memory_Init()");
+ misc_UserErrorReport(" before you can use memory management functions.\n");
+ misc_UserErrorReport("\n Error occurred in %s", Function);
+ misc_UserErrorReport(" called from file %s at line %d.\n",
+ File, Line);
+ misc_FinishUserErrorReport();
+ }
+}
+
+static void memory_CheckIfPointerIsAlreadyFreed(POINTER Pointer,
+ const char * Function,
+ const char * File,
+ unsigned short int Line)
+/********************************************************
+ INPUT : The pointer to be checked, the name of the
+ function that requests the check, the name of
+ the file and the line, where the requesting
+ function was called, and the line.
+ RETURNS: None.
+ SUMMARY: Checks if the pointer has already been freed.
+ If the check fails, this function prints an
+ error message and exits the application.
+*********************************************************/
+{
+ if ( memory_GetBlockStatus(Pointer) == memory_MAGICFREE) {
+ MEMORY_INFO Info; /* block´s debug information */
+
+ Info = (MEMORY_INFO) ((char *) Pointer - memory_OFFSET);
+
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In %s:", Function);
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Pointer %p was allocated in file %s at line %d.",
+ Pointer, Info->mallocInFile, Info->mallocAtLine);
+ misc_UserErrorReport("\n It has already been freed in file %s at line %d.",
+ Info->freeInFile, Info->freeAtLine);
+ misc_UserErrorReport("\n Size of memory block is %d bytes.",
+ memory_GetBlockSize(Pointer));
+ misc_UserErrorReport("\n Error occurred in %s", Function);
+ misc_UserErrorReport(" called from file %s at line %d.\n",
+ File, Line);
+ misc_FinishUserErrorReport();
+ }
+}
+
+static void memory_CheckPointer(POINTER Pointer, unsigned int Size)
+/*********************************************************
+ INPUT : A pointer to a block of memory, and its size.
+ RETURNS: Nothing.
+ SUMMARY: Checks whether a pointer points to a valid
+ block of memory.
+
+ This function performs the following tests:
+
+ Is Pointer a NULL pointer?
+
+ Is Size equal to zero?
+
+ Is the Pointer alignment correct?
+
+ Did someone write over the memory block
+ boundaries?
+
+ Is Size still correct?
+
+ If Size is greater than memory__DYNMAXSIZE:
+ Is it properly administrated by the module?
+
+ If the memory block was freed: Did someone
+ write to it after deallocation?
+*********************************************************/
+{
+
+ MEMORY_INFO Info;
+ unsigned int BlockSize, RealBlockSize, BlockStatus;
+
+ Info = (MEMORY_INFO) ((char *) Pointer - memory_OFFSET);
+
+ RealBlockSize = memory_LookupRealBlockSize(Size);
+
+ if (Pointer == NULL) {
+ /* NULL pointers must not be dereferenced */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_CheckPointer:");
+ misc_UserErrorReport("\n Memory Error. Pointer is a NULL pointer.\n");
+ misc_FinishUserErrorReport();
+ }
+
+
+ if (Size == 0) {
+ /* We don´t allocate 0 byte sized blocks */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_CheckPointer:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Pointer %p points to a block of memory", Pointer);
+ misc_UserErrorReport(" with size 0.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ if ((unsigned long)Pointer % (unsigned long)memory_ALIGN){
+ /* we expect all pointers to be correctly aligned */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_CheckPointer:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Pointer %p is not a legal pointer.\n", Pointer);
+ misc_FinishUserErrorReport();
+ }
+
+ /* BlockStatus and BlockSize are initialized after
+ we can be sure Pointer is properly aligned.
+ */
+
+ BlockStatus = memory_GetBlockStatus(Pointer);
+ BlockSize = memory_GetBlockSize(Pointer);
+
+ if (BlockStatus != memory_MAGICMALLOC
+ && BlockStatus != memory_MAGICFREE) {
+
+ /* we expect block status to be either
+ memory_MAGICMALLOC or memory_MAGICFREE.
+ Other values might result from overwriting,
+ trying to return an unallocated block,
+ or trying to return a block allocated with
+ another allocator.
+ */
+
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_CheckPointer:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Pointer %p was not (de)allocated by the module,",
+ Pointer);
+ misc_UserErrorReport("\n or the memory block was corrupted.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ if (BlockStatus == memory_MAGICMALLOC) {
+ if (BlockSize != Size) {
+
+ /* we expect block size in a block´s debug
+ information and given block size to match.
+ */
+
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_CheckPointer:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Pointer %p was apparently allocated for",
+ Pointer);
+ misc_UserErrorReport(" a block of size %d,",
+ BlockSize);
+ misc_UserErrorReport("\n but it is expected to be a block of size %d.",
+ Size);
+ misc_UserErrorReport("\n Probably the memory block was corrupted.\n");
+ misc_FinishUserErrorReport();
+
+ /* since the left dog tag seems to be corrupted we can not safely assume
+ that our memory info structure is still valid so we can't print it*/
+ }
+
+ if ((Size % memory_ALIGN) || (Size % memory__SHAREDPAGES)) {
+ /* check the fillbytes between used storage
+ and dog tag for overwriting */
+ char * ptr, * limit;
+
+ limit = (char *)Pointer + RealBlockSize;
+
+ for (ptr = (char *)Pointer + Size; ptr < limit; ptr++) {
+ if (*ptr != memory__FREESHREDDER) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_CheckPointer:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Pointer %p was allocated in file %s at line %d,",
+ Pointer, Info->mallocInFile, Info->mallocAtLine);
+ misc_UserErrorReport("\n for a block of size %d.",
+ BlockSize);
+ misc_UserErrorReport("\n The memory block was corrupted.\n");
+ misc_FinishUserErrorReport();
+ }
+ }
+ }
+ }
+
+ if (Size >= memory__DYNMAXSIZE) {
+ /* we expect big blocks to be correctly linked */
+ MEMORY_BIGBLOCKHEADER BigBlockHeader;
+
+ BigBlockHeader = (MEMORY_BIGBLOCKHEADER) ((char *) Pointer - memory_OFFSET
+ - sizeof(MEMORY_BIGBLOCKHEADERNODE));
+
+ /* this test might crash the program
+ if something is wrong with the pointers,
+ so you may not get a message every time.
+ */
+ if (((BigBlockHeader->previous != NULL)
+ && (BigBlockHeader->previous->next != BigBlockHeader))
+ || ((BigBlockHeader->previous == NULL)
+ && (memory_BIGBLOCKS != BigBlockHeader))
+ || ((BigBlockHeader->next != NULL)
+ && (BigBlockHeader->next->previous != BigBlockHeader))) {
+
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_CheckPointer:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Pointer %p was not allocated by the module,",
+ Pointer);
+ misc_UserErrorReport("\n or the memory block was corrupted.\n");
+ misc_FinishUserErrorReport();
+ }
+ }
+
+ if (BlockStatus == memory_MAGICFREE) {
+ /* test if someone wrote over freed memory */
+ char * ptr, * limit;
+
+ limit = (char *)Pointer + RealBlockSize;
+
+ for (ptr = (char *)Pointer + sizeof(POINTER); ptr < limit ; ptr++){
+ /* first sizeof(POINTER) bytes are reserved for the
+ pointer to the next freed block in the list. All
+ other bytes in the block should still have the value
+ of memory__FREESHREDDER
+ */
+ if (*ptr != memory__FREESHREDDER) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_CheckPointer:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Pointer %p was allocated in file %s at line %d",
+ Pointer, Info->mallocInFile, Info->mallocAtLine);
+ misc_UserErrorReport("\n for a block of size %d",BlockSize);
+ misc_UserErrorReport("\n and freed in file %s at line %d.",
+ Info->freeInFile, Info->freeAtLine);
+ misc_UserErrorReport("\n The memory block was used after deallocation.\n");
+ misc_FinishUserErrorReport();
+ }
+ }
+ }
+}
+
+void memory_CheckFree(POINTER Freepointer, unsigned int Size,
+ unsigned int RealBlockSize, const char * File,
+ unsigned short int Line)
+/**********************************************************
+ INPUT : The pointer to be freed, the size of the block
+ it is supposed to point to, the real size of
+ that block, the file and line where memory_Free
+ was called.
+ RETURNS: None.
+ SUMMARY: Checks if memory management was initialized,
+ the given pointer is legal, and not freed
+ already. It also zeroes the freed memory, and
+ sets the block's debug and administration
+ information.
+**********************************************************/
+{
+ MEMORY_INFO Info; /* block´s debug information */
+
+ /* Check if memory management was initialized */
+ memory_CheckIfModuleIsInitialized("memory_Free", File, Line);
+
+ /* Check if given pointer is legal */
+ memory_CheckPointer(Freepointer, Size);
+
+ /* Check if current pointer is being freed for a second time */
+ memory_CheckIfPointerIsAlreadyFreed(Freepointer, "memory_Free", File, Line);
+
+ /* Set all bytes to zero, so we can detect overwriting of freed memory */
+ memset (Freepointer, memory__FREESHREDDER, RealBlockSize);
+
+ /* Get current block´s debug information */
+ Info = (MEMORY_INFO) ((char *) Freepointer - memory_OFFSET);
+
+ /* Set block´s debug and administration information */
+ memory_SetInfo(Info,Info->mallocInFile, Info->mallocAtLine, File, Line);
+ memory_SetBlockStatusAndSize(Freepointer, memory_MAGICFREE, Size);
+}
+#endif /* CHECK */
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * MALLOC * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+#ifdef NO_MEMORY_MANAGEMENT
+
+POINTER memory_Malloc(unsigned int Bytes)
+{
+ char *mem; /* pointer to memory block obtained from malloc */
+
+ /* Pass the call through to compiler´s malloc */
+ mem = (char *)malloc(Bytes);
+
+ /* If malloc fails print an error message and exit */
+ if (mem == NULL) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_Malloc:");
+ misc_UserErrorReport("\n Memory Error. Out of memory.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ return mem;
+}
+
+#else
+
+#ifdef CHECK
+POINTER memory_MallocIntern(unsigned int Bytes,
+ const char * File,
+ unsigned short int Line)
+#else
+POINTER memory_Malloc(unsigned int Bytes)
+#endif
+/********************************************************
+ INPUT : The size of the requested memory block.
+ RETURNS: A pointer to a block of <Bytes> bytes.
+ SUMMARY: Allocates a memory block of requested length.
+ EXCEPT : Trying to allocate 0 bytes, violating a memory
+ restriction, or running out of system memory
+ cause the function to print an error message and
+ call exit().
+*********************************************************/
+{
+ char *NewMemory; /* pointer to allocated memory */
+
+ MEMORY_RESOURCE *Resource; /* current page resource,
+ required if we do not allocate
+ a big block */
+
+#ifdef CHECK
+ MEMORY_INFO NewInfo; /* Storage for file and line
+ of allocation */
+#endif
+
+
+#ifdef CHECK
+ /* Is the module initialized? */
+ memory_CheckIfModuleIsInitialized("memory_Malloc", File, Line);
+
+ /* Is it a request for a block of zero bytes? */
+ if (Bytes == 0) {
+ /* The latest draft for the ANSI C 9X standard says in section 7.20.3:
+
+ "If the size of the space requested is zero, the behavior is
+ implementation-defined: either a null pointer is returned, or
+ the behavior is as if the size were some nonzero value,
+ except that the pointer shall not be used to access an object."
+
+ We have decided to print an error and exit upon such requests
+ since they are often originated by a bug.
+
+ Nonstandard but hopefully helpful.
+ */
+
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_Malloc:");
+ misc_UserErrorReport("\n Memory Error. Tried to allocate 0 Bytes!");
+ misc_UserErrorReport("\n Error occurred in memory_Malloc");
+ misc_UserErrorReport(" called from file %s at line %d.\n",
+ File, Line);
+ misc_FinishUserErrorReport();
+ }
+#endif
+
+ /* If it is a big block, then it has to be
+ administrated in a special way
+ */
+ if (Bytes >= memory__DYNMAXSIZE) {
+ unsigned int RealBigBlockSize; /* real block size including
+ padding,header
+ and debug marks */
+
+ /* This is what a big block looks like:
+
+ --------------------------------------------------------------------
+ | MEMORY_BIGBLOCKHEADERNODE | debug marks | char * | debug marks |
+ | previous and next big block |in debug mode| block |in debug mode|
+ --------------------------------------------------------------------
+ */
+
+
+ /* Calculate the real size of the big block,
+ from the size of administration information,
+ the size of debug marks and the requested block size
+ */
+
+ RealBigBlockSize = sizeof(MEMORY_BIGBLOCKHEADERNODE) +
+ memory_MARKSIZE + memory_CalculateRealBlockSize(Bytes);
+
+ /* Check for violation of maximum allocation limit */
+ if (memory_MAXMEM >= 0) {
+ /* there is a maximum allocation limit,
+ let´s see if there is enough left
+ */
+ if ((unsigned int)memory_MAXMEM < RealBigBlockSize) {
+ /* if it is not print an error message and exit */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_Malloc:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Terminated by user given memory restriction,\n");
+ misc_UserErrorReport("\n while trying to allocate %lu bytes.\n",
+ RealBigBlockSize);
+ misc_UserErrorReport("\n Maximum amount of memory");
+ misc_UserErrorReport(" left for allocation is %l bytes.\n",
+ memory_MAXMEM);
+#ifdef CHECK
+ misc_UserErrorReport("\n Error occurred in memory_Malloc");
+ misc_UserErrorReport(" called from file %s at line %d.\n",
+ File, Line);
+#endif
+ misc_FinishUserErrorReport();
+ }
+ else
+ /* otherwise subtract the real block size
+ from the amount of memory available for
+ allocation
+ */
+ memory_MAXMEM -= RealBigBlockSize;
+ }
+
+ /* allocate a fresh block of memory via a call to malloc */
+ NewMemory = (char *)malloc(RealBigBlockSize);
+
+ /* Check if allocation was successful */
+ if (NewMemory != NULL) {
+
+ /* if it was, then administrate the fresh block:
+ insert it into the big block list. The list
+ is double linked for fast deletion
+ */
+
+ MEMORY_BIGBLOCKHEADER NewBigBlock; /* new block´s administration
+ information */
+
+ /* insert the fresh block as the first list element */
+ NewBigBlock = (MEMORY_BIGBLOCKHEADER) NewMemory;
+ NewBigBlock->next = memory_BIGBLOCKS;
+ NewBigBlock->previous = NULL;
+
+ /* if there are already elements in the big block list,
+ change the first element´s pointer to the previous block
+ to point to the fresh block´s administration information
+ */
+ if (memory_BIGBLOCKS != NULL) {
+ memory_BIGBLOCKS->previous = NewBigBlock;
+ }
+
+ /* reset the big block list pointer to point to the fresh block */
+ memory_BIGBLOCKS = NewBigBlock;
+
+ /* skip the administration information */
+ NewMemory += sizeof(MEMORY_BIGBLOCKHEADERNODE);
+
+#ifdef CHECK
+ /* set the debug information address */
+ NewInfo = (MEMORY_INFO) NewMemory;
+
+ /* skip left debug mark */
+ NewMemory += memory_OFFSET;
+#endif
+
+ /* add block´s real size to the total sum of allocated bytes */
+ memory_NEWBYTES += RealBigBlockSize;
+ }
+ else {
+ /* NewMemory == NULL.
+ malloc could not allocate a memory block of required size,
+ so we print an error message and exit
+ */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_MallocIntern:");
+ misc_UserErrorReport("\n Memory Error. Out of memory.");
+ misc_UserErrorReport("\n Failed to allocate %d bytes.\n",
+ RealBigBlockSize);
+#ifdef CHECK
+ misc_UserErrorReport("\n Error occurred in memory_Malloc");
+ misc_UserErrorReport(" called from file %s at line %d.\n",
+ File, Line);
+#endif
+ misc_FinishUserErrorReport();
+ }
+ }
+ else {
+ /* Bytes < memory__DYNMAXSIZE.
+ A memory request for a manageable size
+ */
+
+ /* Initialize the memory resource for the given size */
+ Resource = memory_ARRAY[Bytes];
+
+
+ /* Check if there are freed blocks of that size */
+ if (*((int *)Resource->free) != EOF) {
+
+ /* if that is the case, then use an already freed block */
+
+ NewMemory = (char *) Resource->free;
+
+ /* update the free blocks list for that size */
+ Resource->free = *((POINTER *)(NewMemory));
+
+ /* subtract block´s total size from the sum of freed bytes */
+ memory_FREEDBYTES -= Resource->total_size;
+
+#ifdef CHECK
+ /* calculate the address of the block´s debug information */
+ NewInfo = (MEMORY_INFO) ((char*) NewMemory - memory_OFFSET);
+
+ /* Check if the block has been used after deallocation */
+ memory_CheckPointer(NewMemory, Bytes);
+#endif
+ }
+ else {
+ /* there are no already freed blocks of that size */
+
+ /* Check if there is enough space left on current page */
+ if (Resource->next != Resource->end_of_page) {
+
+ /* if that is the case, then use a fresh block from current page */
+ NewMemory = (char *)Resource->next;
+
+ /* update the pointer to the next usable block */
+ Resource->next = NewMemory + Resource->total_size;
+
+ /* add block´s total size to the sum of allocated bytes */
+ memory_NEWBYTES += Resource->total_size;
+
+#ifdef CHECK
+ /* Check if the fresh block´s address is sane */
+ if ((char *)NewMemory > (char *) Resource->end_of_page) {
+ /* if it is not, then we have detected an internal error
+ in the module itself. Oops! So we print an error message
+ and abort, hoping that the core dump will enable us to
+ trace the error back to its origin
+ */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In memory_Malloc:");
+ misc_ErrorReport("\n Memory Error. Address overflow %d.",Bytes);
+ misc_ErrorReport("\n Error occurred in memory_Malloc");
+ misc_ErrorReport(" called from file %s at line %d.\n", File, Line);
+ misc_FinishErrorReport();
+ }
+
+ /* if all is well, we initialize the pointer to fresh block´s
+ debug information
+ */
+ NewInfo = (MEMORY_INFO)((char*) NewMemory - memory_OFFSET);
+#endif
+
+ }
+ else {
+ /* Check for violation of maximum allocation limit */
+ if (memory_MAXMEM >=0) {
+ /* there is a maximum allocation limit,
+ let´s see if there is enough left
+ */
+ if ((unsigned int)memory_MAXMEM < memory_PAGESIZE) {
+ /* if it is not, then print an error message and exit */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_Malloc:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Terminated by user given memory restriction.\n");
+#ifdef CHECK
+ misc_UserErrorReport("\n Error occurred in memory_Malloc");
+ misc_UserErrorReport(" called from file %s at line %d.\n",
+ File, Line);
+#endif
+ misc_FinishUserErrorReport();
+ }
+ else {
+ /* otherwise subtract the page size from the limit */
+ memory_MAXMEM -= memory_PAGESIZE;
+ }
+ }
+
+ /* try to allocate a new page via malloc */
+ NewMemory=(char *)malloc(memory_PAGESIZE);
+
+ /* check if allocation was successful */
+ if (NewMemory == NULL) {
+ /* if it wasn´t print an error message and exit */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_Malloc:");
+ misc_UserErrorReport("\n Memory Error.");
+ misc_UserErrorReport(" Terminated, ran out of system memory.\n");
+#ifdef CHECK
+ misc_UserErrorReport("\n Error occurred in memory_Malloc");
+ misc_UserErrorReport(" called from file %s at line %d.\n",
+ File, Line);
+#endif
+ misc_FinishUserErrorReport();
+ }
+
+ /* otherwise administrate the fresh page,
+ i.e insert it as the first element of the
+ page list for the given size
+ */
+ *((POINTER *)NewMemory) = Resource->page;
+ Resource->page = NewMemory;
+
+ /* add block´s total size to the sum of allocated bytes */
+ memory_NEWBYTES += Resource->total_size;
+
+ /* set the end of page pointer for the fresh page */
+ Resource->end_of_page = (char *) NewMemory + Resource->offset;
+
+ /* skip the page list */
+ NewMemory += sizeof(POINTER);
+
+#ifdef CHECK
+ /* set the debug information address */
+ NewInfo = (MEMORY_INFO) NewMemory;
+
+ /* skip the left debug mark */
+ NewMemory += memory_OFFSET;
+#endif
+
+ /* update the pointer to the next usable block */
+ Resource->next = NewMemory + Resource->total_size;
+ }
+ }
+ }
+
+#ifdef CHECK
+ /* Set block´s debug information */
+ memory_SetInfo(NewInfo, File, Line, NULL, 0);
+ memory_SetBlockStatusAndSize(NewMemory,
+ memory_MAGICMALLOC, Bytes);
+
+ /* delete all block´s usable bytes with a shredder value */
+ memset(NewMemory, memory__FREESHREDDER,
+ memory_LookupRealBlockSize(Bytes));
+#endif
+
+ return NewMemory;
+}
+
+#endif
+
+
+
+#ifdef NO_MEMORY_MANAGEMENT
+
+POINTER memory_Calloc(unsigned int Elements, unsigned int Bytes)
+{
+ char *mem; /* pointer to memory block obtained from calloc */
+
+ /* Pass call through to compiler´s calloc */
+ mem = (char *)calloc(Elements, Bytes);
+
+ /* If calloc fails print an error message and exit */
+ if (mem == NULL) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_Calloc:");
+ misc_UserErrorReport("\n Memory Error. Out of memory.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ return mem;
+}
+
+#else
+
+#ifdef CHECK
+POINTER memory_CallocIntern(unsigned int Elements, unsigned int Bytes,
+ const char * File, unsigned short int Line)
+#else
+POINTER memory_Calloc(unsigned int Elements, unsigned int Bytes)
+#endif
+/********************************************************
+ INPUT : The number of requested equally huge blocks,
+ and each block's size.
+ RETURNS: A pointer to a block of (Bytes * Elements) bytes.
+ SUMMARY: Allocates a memory block of requested length
+ filled with char value '\0'.
+*********************************************************/
+{
+ char * mem; /* pointer to memory block obtained from the module */
+
+ /* Allocate memory via our memory management */
+#ifdef CHECK
+ mem = (char *)memory_MallocIntern(Elements * Bytes, File, Line);
+#else
+ mem = (char *)memory_Malloc(Elements * Bytes);
+#endif
+
+ /* If allocation was successful set all bytes to zero */
+ if (mem != NULL) {
+ memset(mem,0, Elements * Bytes);
+ }
+ /* otherwise print an error message and exit */
+ else {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_Calloc:");
+ misc_UserErrorReport("\n Memory Error. Out of memory.\n");
+#ifdef CHECK
+ misc_UserErrorReport("\n Error occurred in memory_Calloc");
+ misc_UserErrorReport(" called from file %s at line %d.\n",
+ File, Line);
+#endif
+ misc_FinishUserErrorReport();
+ }
+
+ return mem;
+}
+#endif
+
+void memory_FreeAllMem(void)
+/**************************************************************
+ INPUT : None.
+ RETURNS: None.
+ SUMMARY: Frees all memory allocated by calls to the module.
+***************************************************************/
+{
+ int i;
+
+ /* delete all pages first by going through the memory_ARRAY.
+ This is slower than traversing the array memory_PAGES
+ directly, but is easier to implement correctly. Since
+ the only reasonable way to call memory_FreeAllMem is
+ before the program exits, a minimal performance penalty
+ should be acceptable
+ */
+
+ for (i = 1; i < memory__DYNMAXSIZE; i++) {
+ POINTER thispage, nextpage;
+ MEMORY_RESOURCE * Resource;
+
+ Resource = memory_ARRAY[i];
+
+ thispage = Resource->page;
+
+ if (*((int *)thispage) != EOF) {
+ do {
+ nextpage = *((POINTER *)thispage);
+ free(thispage);
+ thispage = nextpage;
+ } while (*((int *)thispage) != EOF);
+
+ /* and reset the resource structure */
+ Resource->page = &memory__EOF;
+ Resource->free = &memory__EOF;
+ Resource->next = &memory__EOF;
+ Resource->end_of_page = &memory__EOF;
+ }
+ }
+
+ /* now delete all big blocks left */
+
+ if (memory_BIGBLOCKS != NULL) {
+ MEMORY_BIGBLOCKHEADER thisblock, nextblock;
+
+ for (thisblock = memory_BIGBLOCKS;
+ thisblock != NULL;
+ thisblock = nextblock) {
+ nextblock = thisblock->next;
+ free(thisblock);
+ }
+
+ /* and reset the list pointer */
+ memory_BIGBLOCKS = NULL;
+ }
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * DEBUGGING INFORMATION * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+void memory_Print(void)
+/**************************************************************
+ INPUT : None.
+ RETURNS: None.
+ SUMMARY: Prints module status information to stdout:
+ the fixed size of an internal memory page, the size
+ of debug marks for a block of memory, the size of
+ demanded and freed memory in kilobytes, remaining
+ memory in bytes and the number of allocated pages of
+ memory.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+ /* Call memory_FPrint to print status information to stdout */
+ memory_FPrint(stdout);
+#endif
+}
+
+void memory_FPrint(FILE* File)
+/**************************************************************
+ INPUT : A file pointer.
+ RETURNS: None.
+ SUMMARY: Prints module status information to given File:
+ the fixed size of an internal memory page, the size
+ of debug marks for a block of memory, the size of
+ demanded and freed memory in kilobytes, remaining
+ memory in bytes and the number of allocated pages of
+ memory.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+ int Pages; /* number of allocated pages */
+ int i;
+ POINTER ActPage; /* current page in page list for a block size */
+
+ /* Calculate the total number of pages */
+ Pages = 0;
+ for (i = 1; i < memory__DYNMAXSIZE; i+=memory__SHAREDPAGES) {
+ /* increase i by memory_SHAREDPAGES due to page sharing */
+ ActPage = memory_ARRAY[i]->page;
+
+ /* Traverse the page list */
+ while (*((int *)ActPage) != EOF) {
+ Pages++;
+ ActPage = *((POINTER *)ActPage);
+ }
+ }
+
+ /* Print status information */
+ fputs("\n###\n", File);
+ fprintf(File,"### Pagesize: %d\n",
+ memory_PAGESIZE);
+ fprintf(File,"### Marksize: %d\n",
+ (int)memory_MARKSIZE);
+ fprintf(File,"### Memory demanded: %lu KBytes\n",
+ memory_NEWBYTES/memory__KILOBYTE);
+ fprintf(File,"### Memory freed: %lu KBytes\n",
+ memory_FREEDBYTES/memory__KILOBYTE);
+ fprintf(File,"### Memory remaining: %lu Bytes\n",
+ memory_NEWBYTES-memory_FREEDBYTES);
+ fprintf(File,"### Pages allocated: %d Pages\n",
+ Pages);
+ fputs("###\n", File);
+#endif
+}
+
+void memory_PrintAllocatedBlocks(unsigned int Size)
+/**************************************************************
+ INPUT : Block size.
+ RETURNS: None.
+ SUMMARY: Prints addresses of allocated memory blocks with
+ given Size to stdout, if Size is less than
+ memory_DYNMAXSIZE.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+ MEMORY_RESOURCE *Resource; /* current resource */
+
+ POINTER ActPage; /* current page */
+ POINTER ActNext; /* next usable block on current page */
+ POINTER ActEndOfPage; /* end of current page */
+
+ unsigned int BlockSize; /* current block size */
+
+#ifdef CHECK
+ MEMORY_INFO Info; /* current block´s debug information */
+#endif
+
+ /* Allocated blocks are administered
+ in two ways depending on their
+ size. If the size is less than
+ memory__DYNMAXSIZE the block is
+ allocated from the appropriate
+ page. Otherwise the block is
+ allocated directly via a call
+ to malloc or calloc.
+
+ Thus we have two functions to
+ print the allocated blocks:
+ memory_PrintAllocatedBlocks and
+ memory_PrintAlocatedBigBlocks.
+ */
+
+
+ /* Check if memory_PrintAllocatedBlocks has been called for
+ a legal block size
+ */
+
+ if (Size >= memory__DYNMAXSIZE) {
+ /* if that´s not the case print an error message and exit */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_PrintAllocatedBlocks:");
+ misc_UserErrorReport("\n Parameter size is too big: %d.",
+ Size);
+ misc_UserErrorReport("\n Maximal allowed value is: %d.\n",
+ memory__DYNMAXSIZE);
+ misc_FinishUserErrorReport();
+ }
+ else {
+ /* otherwise size is legal */
+
+ /* initialize the variables */
+ Resource = memory_ARRAY[Size];
+ ActPage = Resource->page;
+ ActNext = Resource->next;
+ ActEndOfPage = Resource->end_of_page;
+ BlockSize = Resource->total_size;
+
+ /* Test if there were any requests made for blocks of that size */
+ if (*((int *)ActPage) == EOF) {
+ /* Check if pointers are consistent */
+ if (*((int *)ActNext) == EOF) {
+ /* If that is true, print that information to stdout */
+ puts(" No request so far");
+ }
+ else {
+ /* Otherwise print an error message and abort */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In memory_PrintAllocatedBlocks:");
+ misc_ErrorReport("\n Memory Error. No Page entry but Next entry.\n");
+ misc_FinishErrorReport();
+ }
+ }
+ else {
+ /* We have received some requests for blocks of that size */
+#ifdef CHECK
+
+ POINTER ActData; /* current block */
+
+
+ /* Traverse through the page list for given block size */
+ while (*((int *)ActPage) != EOF) {
+
+ /* Initialize the variables */
+ ActData = (char *)ActPage + sizeof(POINTER) + memory_OFFSET;
+ ActEndOfPage = (char *)ActPage + Resource->offset;
+
+ /* Visit blocks on current page until the end of
+ page is reached, or an allocated block is found
+ */
+ while (ActData != ActNext
+ && ActData != ActEndOfPage
+ && memory_GetBlockStatus(ActData) != memory_MAGICMALLOC) {
+ ActData = (char *)ActData + BlockSize;
+ }
+
+ /* Check if there were any allocated blocks from current page */
+ if (ActData == ActNext || ActData == ActEndOfPage) {
+ /* if that´s not the case print the information to stdout */
+ printf("\n\n No memory allocated from page at address %p\n", ActPage);
+ }
+ else {
+ /* otherwise print address and origin of (de)allocation of
+ all allocated blocks on current page, starting
+ with the block just found
+ */
+ fputs("\n\n Allocated but not freed: ", stdout);
+ do {
+ Info = (MEMORY_INFO) ((char *) ActData - memory_OFFSET);
+ if (memory_GetBlockStatus(ActData) == memory_MAGICMALLOC
+ && memory_GetBlockSize(ActData) == Size) {
+ printf("\n\t%p allocated in file %s at line %d ",
+ ActData, Info->mallocInFile, Info->mallocAtLine);
+ }
+ ActData = (char *)ActData + BlockSize;
+ } while (ActData != ActNext && ActData != ActEndOfPage);
+ }
+
+ /* go to the next page in the page list for given block size */
+ ActPage = *((POINTER *)ActPage);
+ }
+#endif
+ }
+ }
+#endif
+}
+
+void memory_PrintFreedBlocks(unsigned int Size)
+/**************************************************************
+ INPUT : Block size.
+ RETURNS: None.
+ SUMMARY: Prints addresses of freed memory blocks with given
+ Size to stdout, if Size is less than
+ memory_DYNMAXSIZE.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+ POINTER ActFree; /* current block */
+
+#ifdef CHECK
+ MEMORY_INFO Info; /* current block´s debug information */
+#endif
+
+ /* since we don´t recycle blocks whose size is
+ greater or equal to memory__DYNMAXSIZE,
+ memory_PrintFreedBlocks is meaningless
+ for such block sizes.
+ */
+
+ /* test if given block size is legal */
+ if (Size >= memory__DYNMAXSIZE) {
+ /* if that´s not the case print an error message and exit */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_PrintFreedBlocks.");
+ misc_UserErrorReport("\n Parameter Size is too big: %d.",
+ Size);
+ misc_UserErrorReport("\n Maximal allowed value is: %d.\n",
+ memory__DYNMAXSIZE);
+ misc_FinishUserErrorReport();
+ }
+ else {
+ /* otherwise size is legal */
+
+ /* start at the first element of the free block list
+ for the given block size
+ */
+ ActFree = memory_ARRAY[Size]->free;
+
+ /* test if the free block list is empty */
+ if (*((int *)ActFree) == EOF) {
+ /* if that´s true, print that information to stdout */
+ puts("\n\n No freed memory");
+ }
+ else {
+ /* otherwise traverse the list of freed blocks */
+
+ fputs("\n\n Free: ", stdout);
+ while (*((int *)ActFree) != EOF) {
+#ifdef CHECK
+ /* in debug mode print current block´s address
+ and origin of (de)allocation
+ */
+
+ /* check if block´s size is correct */
+ if ( memory_GetBlockSize(ActFree) == Size) {
+ /* if that´s true than print block´s information */
+ Info = (MEMORY_INFO) ((char *) ActFree - memory_OFFSET);
+ printf("\n\t%p\tallocated in file %s at line %d",
+ ActFree, Info->mallocInFile, Info->mallocAtLine);
+ printf("\n\t\tfreed in file %s at line %d",
+ Info->freeInFile, Info->freeAtLine);
+ }
+ else {
+ /* otherwise if we are sharing pages among different
+ block sizes, the block is uncorrupted, despite not
+ matching assumed and real size. But if we are
+ not sharing pages then the block is probably corrupted,
+ so print an error message and exit
+ */
+
+ /* test if we are not in page sharing mode */
+ if (memory__SHAREDPAGES == 1) {
+ /* if that´s true print an error message and exit */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In memory_PrintFreedBlocks:");
+ misc_UserErrorReport("\n Memory Error. Memory block size mismatch.");
+ misc_UserErrorReport("\n Expected %d found %d for memory block at %p.\n",
+ Size, memory_GetBlockSize(ActFree), ActFree);
+ misc_UserErrorReport("\n Probably the memory block was corrupted.\n");
+ misc_FinishUserErrorReport();
+ }
+ }
+
+#endif
+
+ /* go to the next free block in list */
+ ActFree = *((POINTER *)ActFree);
+ }
+ }
+ }
+#endif
+}
+
+
+void memory_PrintAllocatedBigBlocks(void)
+/**************************************************************
+ INPUT : None.
+ RETURNS: None.
+ SUMMARY: Prints addresses of all allocated memory blocks,
+ that are greater than memory_DYNMAXSIZE to stdout.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+#ifdef CHECK
+ MEMORY_BIGBLOCKHEADER Ptr; /* current big block in list */
+ MEMORY_INFO Info; /* block´s debug information */
+ char * BlockStart; /* block´s start address */
+
+ /* start with the first block in the big block list */
+ Ptr = memory_BIGBLOCKS;
+
+ /* check whether big block list isn´t empty */
+ if (Ptr != NULL) {
+ /* if that´s the case traverse through the list
+ and print each block´s address, size and
+ origin of (de)allocation information
+ */
+ do {
+ BlockStart = (char *)Ptr + memory_OFFSET
+ + sizeof(MEMORY_BIGBLOCKHEADERNODE);
+
+ Info = (MEMORY_INFO) (BlockStart - memory_OFFSET);
+ printf("\n\t%p %d bytes allocated in file %s at line %d ",
+ (void*)BlockStart, memory_GetBlockSize(BlockStart),
+ Info->mallocInFile, Info->mallocAtLine);
+ Ptr = Ptr->next;
+ } while (Ptr != NULL);
+ puts("");
+ }
+ else {
+ /* otherwise there are no big blocks allocated */
+ puts(" No request so far");
+ }
+#endif
+#endif
+}
+
+void memory_PrintDetailed(void)
+/**************************************************************
+ INPUT : None.
+ RETURNS: None.
+ SUMMARY: Prints addresses of all pages, and allocated and freed
+ blocks on them.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+ MEMORY_RESOURCE *Resource; /* current resource */
+
+ POINTER ActPage; /* current page */
+ POINTER ActData; /* current block */
+ POINTER ActEndOfPage; /* end of current page */
+ unsigned int BlockSize; /* total size of a block of current size */
+ unsigned int PageOffset; /* current page´s offset */
+
+ unsigned int i;
+
+
+ /* print end-of-memory pointer´s address */
+ printf("\n\nEOF Pointer: %p\n", (void*)&memory__EOF);
+
+ /* for all administrated block sizes print detailed information */
+ for (i=1; i<memory__DYNMAXSIZE; i++) {
+ /* initialize variables for requested block size i */
+ Resource = memory_ARRAY[i];
+ ActPage = Resource->page;
+ ActData = Resource->next;
+ ActEndOfPage = Resource->end_of_page;
+ PageOffset = Resource->offset;
+ BlockSize = Resource->total_size;
+
+ /* print requested block size, aligned block size
+ and block size including debug marks
+ */
+ printf("\n\n Entry: %d aligned size: %d total size: %d\n",
+ i , Resource->aligned_size, BlockSize);
+
+ /* Check if there were any requests for blocks of size i */
+ if (*((int *)ActPage) == EOF) {
+ /* if that´s not the case check if memory management is consistent */
+ if (*((int *)ActData) == EOF) {
+ /* if that´s true, print that no requests occurred to stdout */
+ puts(" No request so far");
+ }
+ else {
+ /* our memory management is no longer consistent,
+ so print an error message and abort. We hope that
+ the core dump will help us to find the bug
+ */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In memory_PrintDetailed:");
+ misc_ErrorReport("\n Memory Error. No Page entry but Next entry.\n");
+ misc_FinishErrorReport();
+ }
+ }
+ else {
+ /* we have received requests for blocks of size i */
+
+ /* traverse the list of pages for size i */
+ while (*((int *)ActPage) != EOF) {
+ /* print information about current page */
+ printf("\n\n Page: %p Next Page: %p\n",
+ ActPage, *((POINTER *)ActPage));
+
+ /* initialize variables for current page */
+ ActData = ((char *)ActPage + sizeof(POINTER) + memory_OFFSET);
+ ActEndOfPage = (char *)ActPage + PageOffset;
+
+ /* print addresses of all blocks on current page */
+ fputs(" Data: ", stdout);
+ while (ActData != ActEndOfPage) {
+ int column;
+
+ fputs("\n\t\t", stdout);
+ for (column = 0; column < 6; column++) {
+ printf("%p ", ActData);
+ ActData = (char *)ActData + BlockSize;
+ if (ActData == ActEndOfPage) {
+ break;
+ }
+ }
+ }
+
+ /* go to next page in list */
+ ActPage = *((POINTER *)ActPage);
+ }
+
+ /* print allocated and freed blocks of size i */
+ memory_PrintAllocatedBlocks(i);
+ memory_PrintFreedBlocks(i);
+ }
+ }
+
+#ifdef CHECK
+ /* print allocated blocks of size >= memory_DYNMAXSIZE */
+ printf("\n\n Allocated blocks of size >= %d\n",
+ memory__DYNMAXSIZE);
+ memory_PrintAllocatedBigBlocks();
+#endif
+#endif
+}
+
+
+void memory_PrintLeaks(void)
+/**************************************************************
+ INPUT : None.
+ RETURNS: None.
+ SUMMARY: Prints addresses of all allocated blocks. Should be
+ used at the end of a program before the call to
+ memory_FreeAllMem.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+ POINTER ActPage; /* current page */
+ POINTER ActNext; /* next fresh block on current page */
+ POINTER ActEndOfPage; /* end of current page */
+ MEMORY_RESOURCE *Resource; /* current resource */
+ unsigned int Size; /* current size */
+ unsigned int BlockSize; /* total block size */
+
+ /* Check if some memory is still allocated */
+ if (memory_UsedBytes() != 0L) {
+
+ /* If that´s true, print all allocated blocks */
+
+ /* Start with blocks administered by our memory management */
+ for (Size = 1; Size < memory__DYNMAXSIZE; Size++) {
+ /* Initialize variables for current block size */
+ Resource = memory_ARRAY[Size];
+ ActPage = Resource->page;
+ ActNext = Resource->next;
+ ActEndOfPage = Resource->end_of_page;
+ BlockSize = Resource->total_size;
+
+ /* Check if there were any requests for
+ memory blocks of that size */
+ if (*((int *)ActPage) != EOF) {
+
+ /* if that´s true, browse through all blocks on all pages
+ to find a block that is still allocated
+ */
+#ifdef CHECK
+
+ POINTER ActData;
+ BOOL LeakFound;
+
+ LeakFound = FALSE;
+
+ while (*((int *)ActPage) != EOF) {
+
+ /* search through all pages for a block that is still allocated */
+
+ ActData = (char *)ActPage + sizeof(POINTER) + memory_OFFSET;
+ ActEndOfPage = (char *)ActPage + Resource->offset;
+
+ while (ActData != ActNext && ActData != ActEndOfPage) {
+ if (memory_GetBlockStatus(ActData) == memory_MAGICMALLOC) {
+ LeakFound = TRUE;
+ break;
+ }
+ ActData = (char *)ActData + BlockSize;
+ }
+
+ if (LeakFound) {
+
+ /* if we have found one, than call memory_PrintAllocatedBlocks
+ to print its address */
+
+ printf("\n\n Leaked blocks of size %d:", Size);
+
+ memory_PrintAllocatedBlocks(Size);
+ putchar('\n');
+ /* since memory_PrintAllocatedblocks prints
+ *all* allocated blocks of specific size, we can
+ break out of the while loop
+ */
+ break;
+ }
+ else {
+ /* go to next page */
+ ActPage = *((POINTER *)ActPage);
+ }
+ }
+
+#endif
+
+ }
+ }
+
+#ifdef CHECK
+ /* Print allocated blocks of size >= memory__DYNMAXSIZE */
+ if (memory_BIGBLOCKS != NULL) {
+ printf("\n\n Leaked blocks of size >= %d\n",
+ memory__DYNMAXSIZE);
+ memory_PrintAllocatedBigBlocks();
+ putchar('\n');
+ }
+#endif
+
+ }
+#endif
+}
diff --git a/test/spass/memory.h b/test/spass/memory.h
new file mode 100644
index 0000000..d0edac1
--- /dev/null
+++ b/test/spass/memory.h
@@ -0,0 +1,478 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * DYNAMIC MEMORY MANAGEMENT MODULE * */
+/* * * */
+/* * $Module: MEMORY * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _MEMORY_
+#define _MEMORY_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "misc.h"
+
+/**************************************************************/
+/* Data structures and constants */
+/**************************************************************/
+
+#ifndef memory__DYNMAXSIZE
+#define memory__DYNMAXSIZE 1024 /* At most blocks of size memory__DYNMAXSIZE
+ bytes are administrated by the
+ module, larger requests are
+ directly mapped to system calls */
+#endif
+
+#ifndef memory__SHAREDPAGES
+#define memory__SHAREDPAGES 1 /* Number of block sizes sharing an allocated
+ page. By setting memory__SHAREDPAGES to 4,
+ the module would administrate requests
+ for 1, 2, 3 and 4 bytes on the same set of
+ pages, requests for 5, 6, 7 and 8 on another
+ one, etc. By default every block size has
+ its own set of pages */
+#endif
+
+#ifndef memory__FREESHREDDER
+#define memory__FREESHREDDER 'S' /* The decimal number 83, which can also be
+ read as 53 hexadecimal, or the character
+ 'S' in ASCII code */
+#endif
+
+#define memory__KILOBYTE 1024
+
+#ifndef memory__DEFAULTPAGESIZE
+#define memory__DEFAULTPAGESIZE (8 * memory__KILOBYTE)
+ /* Used to set the default size of a page.
+ If the default page size is too small to
+ contain two objects of size memory__DYNMAXSIZE
+ the default page size is automatically
+ increased by the function memory_Init */
+#endif
+
+#ifndef memory__UNLIMITED
+#define memory__UNLIMITED (-1)
+ /* Used to set the maximal amount of memory
+ available for the memory module to
+ "unlimited" when calling memory_Init. */
+#endif
+
+typedef struct MEMORY_RESOURCEHELP {
+ POINTER free; /* pointer to the next free block in list */
+ POINTER next; /* pointer to the next fresh block */
+ POINTER page; /* pointer to head of page list */
+ POINTER end_of_page; /* pointer to the end of current page */
+ int total_size; /* total block size inc. debug marks */
+ int aligned_size; /* block size without debug marks */
+ int offset; /* offset of last usable block on page */
+} MEMORY_RESOURCE;
+
+extern MEMORY_RESOURCE * memory_ARRAY[];
+
+#if defined(CHECK)
+typedef struct MEMORY_INFOHELP {
+ const char * mallocInFile; /* origin of allocation request: file */
+ const char * freeInFile; /* origin of deallocation request: file */
+ unsigned short int mallocAtLine; /* origin of allocation request: line */
+ unsigned short int freeAtLine; /* origin of deallocation request: line */
+} MEMORY_INFONODE, * MEMORY_INFO;
+
+#endif
+
+typedef struct MEMORY_BIGBLOCKHEADERHELP {
+ struct MEMORY_BIGBLOCKHEADERHELP * previous, * next;
+} MEMORY_BIGBLOCKHEADERNODE, * MEMORY_BIGBLOCKHEADER;
+
+extern long memory_MAXMEM;
+
+extern unsigned long memory_NEWBYTES;
+extern unsigned long memory_FREEDBYTES;
+
+extern const unsigned int memory_MAGICMALLOC;
+extern const unsigned int memory_MAGICFREE;
+
+extern const unsigned int memory_ALIGN;
+
+extern MEMORY_BIGBLOCKHEADER memory_BIGBLOCKS;
+
+/**************************************************************/
+/* Debug Information */
+/**************************************************************/
+
+extern unsigned int memory_MARKSIZE;
+extern unsigned int memory_OFFSET;
+
+/**************************************************************/
+/* Check Functions */
+/**************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef CHECK
+void memory_CheckFree(POINTER Freepointer, unsigned int Size, unsigned int RealBlockSize, const char * File, unsigned short int Line);
+#endif /* CHECK */
+
+#ifdef __cplusplus
+}
+#endif
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+
+static __inline__ unsigned int memory_CalculateRealBlockSize(unsigned int
+ BlockSize)
+/**********************************************************
+ INPUT : Size of a block of memory.
+ RETURNS: its real size.
+ SUMMARY: Calculates the size of a memory block,
+ including padding due to memory alignment and
+ page sharing
+**********************************************************/
+{
+ unsigned int RealSize;
+
+ RealSize = BlockSize;
+
+ if (RealSize % memory__SHAREDPAGES) {
+ RealSize += memory__SHAREDPAGES - (RealSize % memory__SHAREDPAGES);
+ }
+
+ if (RealSize % memory_ALIGN) {
+ RealSize += memory_ALIGN - (RealSize % memory_ALIGN);
+ }
+
+ return RealSize;
+
+}
+
+static __inline__ unsigned int memory_LookupRealBlockSize(unsigned int
+ BlockSize)
+/**********************************************************
+ INPUT : Size of a block of memory.
+ RETURNS: its real size.
+ SUMMARY: Returns the size of a memory block,
+ including padding due to memory alignment and
+ page sharing.
+**********************************************************/
+{
+
+ unsigned int RealSize;
+
+ if (BlockSize < memory__DYNMAXSIZE) {
+ RealSize = memory_ARRAY[BlockSize]->aligned_size;
+ }
+ else {
+ RealSize = memory_CalculateRealBlockSize(BlockSize);
+ }
+
+ return RealSize;
+
+}
+
+#ifdef CHECK
+static __inline__ void memory_SetBlockStatusAndSize(POINTER Mem,
+ unsigned int Status,
+ unsigned int Size)
+/**********************************************************
+ INPUT : a pointer to a block of memory, its status
+ (memory_MAGICMALLOC or memory_MAGICFREE), and
+ size.
+ RETURNS: None.
+ SUMMARY: Sets a status flag (memory_MAGICMALLOC or
+ memory_MAGICFREE) and block size.
+**********************************************************/
+{
+ *((int *)Mem - 1) = Size;
+ *((int *)((char *)Mem + memory_LookupRealBlockSize(Size))) = Status;
+}
+
+static __inline__ unsigned int memory_GetBlockSize(POINTER Mem)
+/**********************************************************
+ INPUT : A pointer to a block of memory.
+ RETURNS: its size.
+ SUMMARY: Returns the size of a memory block.
+**********************************************************/
+{
+ return *((int *)Mem - 1);
+}
+
+static __inline__ unsigned int memory_GetRealBlockSize(POINTER Mem)
+/**********************************************************
+ INPUT : A pointer to a block of memory.
+ RETURNS: its real size.
+ SUMMARY: Returns the real size of a memory block,
+ including padding bytes.
+**********************************************************/
+{
+ return memory_LookupRealBlockSize(memory_GetBlockSize(Mem));
+}
+
+static __inline__ unsigned int memory_GetBlockStatus(POINTER Mem)
+/**********************************************************
+ INPUT : A pointer to a block of memory.
+ RETURNS: its status.
+ SUMMARY: Returns the status of a memory block.
+**********************************************************/
+{
+ unsigned int Size;
+
+ Size = memory_GetBlockSize(Mem);
+
+ return *((int *)((char *)Mem + memory_LookupRealBlockSize(Size)));
+}
+
+static __inline__ void memory_SetInfo(MEMORY_INFO Info,
+ const char * MallocInFile,
+ unsigned short int MallocAtLine,
+ const char * FreeInFile,
+ unsigned short int FreeAtLine)
+/**********************************************************
+ INPUT : a memory info structure, strings for files where
+ the block was allocated and freed, and short
+ integers for the corresponding lines.
+ RETURNS: None.
+ SUMMARY: Sets the debugging information for a memory block
+**********************************************************/
+{
+ if (!Info) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In memory_SetInfo:");
+ misc_ErrorReport("\n Memory Error. Info is a NULL pointer.\n");
+ misc_FinishErrorReport();
+ }
+
+ Info->mallocAtLine = MallocAtLine;
+ Info->mallocInFile = MallocInFile;
+ Info->freeAtLine = FreeAtLine;
+ Info->freeInFile = FreeInFile;
+}
+#endif
+
+static __inline__ unsigned long memory_DemandedBytes(void)
+/**********************************************************
+ INPUT : Nothing.
+ RETURNS: Maximum number of bytes allocated at the same
+ time by the module.
+ SUMMARY: Returns maximum number of allocated bytes at the
+ same time.
+**********************************************************/
+{
+ return memory_NEWBYTES;
+}
+
+
+static __inline__ unsigned long memory_UsedBytes(void)
+/**********************************************************
+ INPUT : Nothing.
+ RETURNS: Number of bytes currently in use by your program.
+ SUMMARY: Returns number of bytes currently allocated.
+**********************************************************/
+{
+ return memory_NEWBYTES-memory_FREEDBYTES;
+}
+
+#ifdef NO_MEMORY_MANAGEMENT
+
+static __inline__ void memory_Free(POINTER Freepointer, unsigned int Size)
+{
+ free((char*)Freepointer);
+}
+
+#else
+
+#ifdef CHECK
+static __inline__ void memory_FreeIntern(POINTER Freepointer,
+ unsigned int Size,
+ const char * File,
+ unsigned short int Line)
+#else
+static __inline__ void memory_Free(POINTER Freepointer, unsigned int Size)
+#endif
+/**********************************************************
+ INPUT : Pointer to the block of memory to be freed,
+ and the block's size
+ RETURNS: Nothing.
+ SUMMARY: Frees a block of memory for reallocation.
+ This function performs correctness checks
+ in debugging mode.
+**********************************************************/
+{
+ unsigned int RealBlockSize; /* block´s alignment correct size */
+
+ RealBlockSize = memory_LookupRealBlockSize(Size);
+
+#ifdef CHECK
+ memory_CheckFree(Freepointer, Size, RealBlockSize, File, Line);
+#endif
+
+
+ /* Check if current block is a big block */
+ if (Size >= memory__DYNMAXSIZE) {
+ /* if that´s true, remove it from the double linked big block list */
+ MEMORY_BIGBLOCKHEADER BigBlockHeader;
+
+ BigBlockHeader =
+ (MEMORY_BIGBLOCKHEADER) ((char *) Freepointer - memory_OFFSET
+ - sizeof(MEMORY_BIGBLOCKHEADERNODE));
+
+ /* Check if current big block is the first block in the list */
+ if (BigBlockHeader->previous != NULL) {
+ /* if that´s not true, set previous block´s successor
+ to current block´s successor
+ */
+ BigBlockHeader->previous->next = BigBlockHeader->next;
+ }
+ else {
+ /* otherwise set the first block in the big blocks list
+ to current block´s successor
+ */
+ memory_BIGBLOCKS = BigBlockHeader->next;
+ }
+
+ /* Check if current block is the last block in the list */
+ if (BigBlockHeader->next != NULL) {
+ /* if that´s not true, set next block´ predecessor to
+ current block´s predecessor
+ */
+ BigBlockHeader->next->previous = BigBlockHeader->previous;
+ }
+
+ /* Adapt total number of freed bytes
+ and number of bytes available for allocation
+ accordingly
+ */
+ memory_FREEDBYTES += RealBlockSize + memory_MARKSIZE +
+ sizeof(MEMORY_BIGBLOCKHEADERNODE);
+
+ if (memory_MAXMEM >= 0) {
+ memory_MAXMEM += RealBlockSize + memory_MARKSIZE +
+ sizeof(MEMORY_BIGBLOCKHEADERNODE);
+ }
+
+ /* pass the call though to free() with correct pointer value */
+#ifdef CHECK
+ free((char *)Freepointer - memory_OFFSET
+ - sizeof(MEMORY_BIGBLOCKHEADERNODE));
+#else
+ free((char*) Freepointer - sizeof(MEMORY_BIGBLOCKHEADERNODE));
+#endif
+ }
+ else {
+ /* current block is not a big block */
+ /* Adapt number of allocated bytes
+ and the freed blocks list accordingly
+ */
+ memory_FREEDBYTES += memory_ARRAY[Size]->total_size;
+ *(POINTER *)Freepointer = memory_ARRAY[Size]->free;
+ memory_ARRAY[Size]->free = Freepointer;
+ }
+
+}
+
+#endif
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void memory_Init(long);
+void memory_Restrict(long);
+
+void memory_Print(void);
+void memory_FPrint(FILE*);
+
+void memory_PrintLeaks(void);
+void memory_PrintDetailed(void);
+void memory_PrintAllocatedBlocks(unsigned int Size);
+void memory_PrintFreedBlocks(unsigned int Size);
+void memory_PrintAllocatedBigBlocks(void);
+
+void memory_FreeAllMem(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(CHECK) && !defined(NO_MEMORY_MANAGEMENT)
+/* declare drop-in debug versions memory functions */
+#ifdef __cplusplus
+extern "C" {
+#endif
+POINTER memory_MallocIntern(unsigned int, const char *, unsigned short int);
+POINTER memory_CallocIntern(unsigned int,
+ unsigned int,
+ const char *,
+ unsigned short int);
+#ifdef __cplusplus
+}
+#endif
+#define memory_Malloc(Size) memory_MallocIntern((Size), __FILE__, __LINE__)
+#define memory_Calloc(Elements, Size) \
+memory_CallocIntern((Elements), (Size), __FILE__, __LINE__)
+#define memory_Free(Pointer, Size) \
+memory_FreeIntern((Pointer), (Size), __FILE__, __LINE__)
+#else
+#ifdef __cplusplus
+extern "C" {
+#endif
+POINTER memory_Malloc(unsigned int);
+POINTER memory_Calloc(unsigned int, unsigned int);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif
diff --git a/test/spass/misc.c b/test/spass/misc.c
new file mode 100644
index 0000000..3a63396
--- /dev/null
+++ b/test/spass/misc.c
@@ -0,0 +1,147 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * MISCELLANEOUS * */
+/* * * */
+/* * $Module: MISC * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "misc.h"
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+#if 0
+void misc_ErrorReport(const char * Format, ...)
+{
+ va_list args;
+ va_start(args,Format);
+ vfprintf(misc_ERROROUT,Format,args);
+ va_end(args);
+}
+
+void misc_UserErrorReport(const char * Format, ...)
+{
+ va_list args;
+ va_start(args,Format);
+ vfprintf(misc_USERERROROUT,Format,args);
+ va_end(args);
+}
+#endif
+
+void misc_DumpCoreOut(const char* String)
+/**************************************************************
+ INPUT: A string.
+ RETURNS: Nothing.
+ EFFECT: Prints <String> and then dumps a core.
+***************************************************************/
+{
+ fprintf(stderr, "\n %s \n", String);
+ misc_DumpCore();
+}
+
+
+
+int misc_ReturnValue(void)
+{
+ return 0;
+}
+
+
+int misc_Max(int a, int b)
+{
+ if (a > b)
+ return a;
+ else
+ return b;
+}
+
+FILE* misc_OpenFile(const char* Name, const char* Mode)
+/**************************************************************
+ INPUT: The name of a file and a string containing the mode
+ for opening the file (see fopen(3)).
+ Examples for Mode are "r" for reading and "w" for writing.
+ RETURNS: The FILE pointer, if the file was successfully opened.
+ EFFECT: If it wasn't possible to open the file with the
+ requested mode, an error message is printed and the
+ program exits.
+***************************************************************/
+{
+ FILE* File;
+
+ File = fopen(Name,Mode);
+
+ if (File == (FILE*)NULL) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n\tError in opening file %s for %s !\n\n", Name,
+ (Mode[0] == 'r' ? "reading" :
+ (Mode[0] == 'w' ? "writing" : "i/o operations")));
+ misc_FinishUserErrorReport();
+ }
+
+ return File;
+}
+
+void misc_CloseFile(FILE* File, const char* Name)
+/**************************************************************
+ INPUT: A FILE and its name.
+ RETURNS: Nothing.
+ EFFECT: Closes the file. If an error occurs, a message is
+ printed and the program exits.
+***************************************************************/
+{
+ int Result;
+
+ Result = fclose(File);
+
+ if (Result != 0) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n\tError in closing file %s !\n\n", Name);
+ misc_FinishUserErrorReport();
+ }
+}
+
diff --git a/test/spass/misc.h b/test/spass/misc.h
new file mode 100644
index 0000000..69d929d
--- /dev/null
+++ b/test/spass/misc.h
@@ -0,0 +1,161 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * MISCELLANEOUS * */
+/* * * */
+/* * $Module: MISC * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _MISC_
+#define _MISC_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#define __USE_FIXED_PROTOTYPES__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <limits.h>
+#include <stdarg.h>
+
+/**************************************************************/
+/* More basic types and macros */
+/**************************************************************/
+
+#if defined(TRUE)
+#undef TRUE
+#endif
+
+#if defined(FALSE)
+#undef FALSE
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+
+#define misc_ERROROUT stderr
+#define misc_USERERROROUT stderr
+
+typedef enum { FALSE=0, TRUE=1 } BOOL;
+
+#define misc_VERSION "V 2.1"
+
+
+typedef void* POINTER;
+typedef unsigned int NAT;
+
+/* Limits for EARL data types */
+#define NAT_MAX UINT_MAX
+
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+#define misc_ReportStandardErrorMessage(Stream) fputs("\n Please report this error via email to spass@mpi-sb.mpg.de including\n the SPASS version, input problem, options, operating system.\n",Stream)
+
+static __inline__ void misc_Error(void)
+{
+ fflush(misc_USERERROROUT);
+ fflush(stdout);
+ fflush(stderr);
+ exit(EXIT_FAILURE);
+}
+
+
+static __inline__ void misc_DumpCore(void)
+{
+ fputs("\n\n", misc_ERROROUT);
+ fflush(misc_ERROROUT);
+ fflush(stdout);
+ fflush(stderr);
+ abort();
+}
+
+
+static __inline__ void misc_PrintChar(NAT Number, char Character)
+{
+ NAT Counter;
+ for (Counter = 1; Counter <= Number; Counter++)
+ putchar(Character);
+}
+
+static __inline__ BOOL misc_SmallerThan(int i, int j)
+{
+ return (BOOL)(i < j);
+}
+
+#define misc_StartErrorReport() { fflush(stdout); fprintf(misc_ERROROUT,"\n\tError in file %s at line %d\n",__FILE__,__LINE__); }
+#define misc_FinishErrorReport() { misc_ReportStandardErrorMessage(misc_ERROROUT); misc_DumpCore(); }
+
+#define misc_StartUserErrorReport() fflush(stdout)
+#define misc_FinishUserErrorReport() misc_Error()
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define misc_ErrorReport(...) fprintf(misc_ERROROUT, __VA_ARGS__)
+#define misc_UserErrorReport(...) fprintf(misc_USERERROROUT, __VA_ARGS__)
+
+void misc_DumpCoreOut(const char*);
+int misc_ReturnValue(void);
+int misc_Max(int, int);
+
+FILE* misc_OpenFile(const char*, const char*);
+void misc_CloseFile(FILE*, const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/test/spass/options.c b/test/spass/options.c
new file mode 100644
index 0000000..c9e84b5
--- /dev/null
+++ b/test/spass/options.c
@@ -0,0 +1,1889 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SPASS OPTIONS HANDLING * */
+/* * * */
+/* * $Module: OPTIONS * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* $Revision: 35442 $ * */
+/* $State$ * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+
+/***************************************************************
+
+ COPYRIGHT NOTICE:
+
+ This file contains code that
+ has been copied with minor modifications
+ from the 'getopt' module in the
+ GNU gcc library 2.0. The copyright for
+ this code is claimed by
+
+ Copyright 1991 Regents of the
+ University of California.
+ All rights reserved.
+
+ The copying and modification of the
+ original code is in accordance
+ with the copyright conditions for the
+ GNU gcc library, which are listed below.
+
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+
+ Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ This software is provided by the regents and contributors ``as is'' and
+ any express or implied warranties, including, but not limited to, the
+ implied warranties of merchantability and fitness for a particular purpose
+ are disclaimed. in no event shall the regents or contributors be liable
+ for any direct, indirect, incidental, special, exemplary, or consequential
+ damages (including, but not limited to, procurement of substitute goods
+ or services; loss of use, data, or profits; or business interruption)
+ however caused and on any theory of liability, whether in contract, strict
+ liability, or tort (including negligence or otherwise) arising in any way
+ out of the use of this software, even if advised of the possibility of
+ such damage.
+
+************************************************************************
+************************************************************************/
+
+#include "options.h"
+#include "stringsx.h"
+
+/**************************************************************/
+/* Local variables and types */
+/**************************************************************/
+
+/* all option declarations. List with *DECL entries */
+static LIST opts_DECLARATIONS;
+
+/* list of <option id/value string> tupels that holds all parameters and their values */
+static LIST opts_PARAMETERS;
+
+static OPTID opts_IdNextAvailable;
+
+
+/**************************************************************/
+/* Forwarding functions */
+/**************************************************************/
+
+static void opts_AddParam(OPTID, const char*);
+static BOOL opts_AddParamCheck(OPTID, const char*);
+
+static int opts_GetOptLongOnly(int, const char* [], const char*,
+ const struct OPTION *, int *);
+
+static OPTDECL* opts_DeclGetById(OPTID);
+static void opts_PrintDeclarationList(LIST);
+static OPTID opts_IdNext(OPTID);
+static OPTID opts_IdEqual(OPTID, OPTID);
+
+
+/*************************************************************
+ Local variables and types from the former getopt module code.
+**************************************************************/
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `opts_Ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `opts_Ind' != ARGC. */
+
+static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } opts_Ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *opts_PosixlyCorrect;
+
+static int opts_FirstNonOpt;
+static int opts_LastNonOpt;
+
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+static int opts_NonOptionFlagslen;
+
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `opts_Ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+static const char *opts_Arg = NULL;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+static int opts_Ind = 1;
+
+/* Formerly, initialization of getopt depended on opts_Ind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+static int opts_GetOptInitialized = 0;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static const char *opts_NextChar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+static int opts_Err = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+static int opts_Opt = '?';
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+OPTID opts_IdFirst(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: First option id that is used in option declarations.
+***************************************************************/
+{
+ return opts_IDFIRST;
+}
+
+static __inline__ OPTID opts_IdNull(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: An NULL id that is never used for option declarations
+ (used as indicator for errors etc.).
+***************************************************************/
+{
+ return -1;
+}
+
+BOOL opts_IdIsNull(OPTID Id)
+/**************************************************************
+ INPUT: An option id.
+ RETURNS: TRUE iff it is the NULL id.
+***************************************************************/
+{
+ return opts_IdEqual(opts_IdNull(), Id);
+}
+
+static __inline__ void opts_IdIncAvailable(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECTS: Increases the counter for next available id.
+***************************************************************/
+{
+ opts_IdNextAvailable = opts_IdNext(opts_IdNextAvailable);
+}
+
+static __inline__ OPTID opts_IdGetNextAvailable(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECTS: Returns the counter for the next available id.
+***************************************************************/
+{
+ return opts_IdNextAvailable;
+}
+
+static __inline__ void opts_DeclSetClName(OPTDECL* D, char* s)
+/**************************************************************
+ INPUT: An option declaration, a string.
+ RETURNS: Nothing.
+ EFFECTS: Sets the command line name of <D> to <s>.
+***************************************************************/
+{
+ D->clname = s;
+}
+
+static __inline__ char* opts_DeclGetClName(OPTDECL* D)
+/**************************************************************
+ INPUT: An option declaration.
+ RETURNS: The command line name in <D>.
+***************************************************************/
+{
+ return D->clname;
+}
+
+
+static __inline__ void opts_DeclSetType(OPTDECL* D, OPTTYPE type)
+/**************************************************************
+ INPUT: An option declaration and an option type.
+ RETURNS: Nothing.
+ EFFECTS: Set the option type of <D> to <type>.
+***************************************************************/
+{
+ D->type = type;
+}
+
+static __inline__ OPTTYPE opts_DeclGetType(OPTDECL* D)
+/**************************************************************
+ INPUT: An option declaration.
+ RETURNS: The option type of <D>.
+***************************************************************/
+{
+ return D->type;
+}
+
+static __inline__ BOOL opts_DeclIsShortOpt(OPTDECL* D)
+/**************************************************************
+ INPUT: An option declaration.
+ RETURNS: TRUE iff <D> is a declaration of a short option
+ (with a single character command line name).
+***************************************************************/
+{
+ return (strlen(opts_DeclGetClName(D)) == 1);
+}
+
+static __inline__ BOOL opts_DeclHasOptArg(OPTDECL* D)
+/**************************************************************
+ INPUT: An option declaration.
+ RETURNS: TRUE iff <D> is a declaration of an option
+ with an optional argument.
+***************************************************************/
+{
+ return (opts_DeclGetType(D) == opts_OPTARGTYPE);
+}
+
+static __inline__ BOOL opts_DeclHasReqArg(OPTDECL* D)
+/**************************************************************
+ INPUT: An option declaration.
+ RETURNS: TRUE iff <D> is a declaration of an option
+ with a required argument.
+***************************************************************/
+{
+ return (opts_DeclGetType(D) == opts_REQARGTYPE);
+}
+
+static __inline__ BOOL opts_DeclHasNoArg(OPTDECL* D)
+/**************************************************************
+ INPUT: An option declaration.
+ RETURNS: TRUE iff <D> is a declaration of an option
+ with a required argument.
+***************************************************************/
+{
+ return (opts_DeclGetType(D) == opts_NOARGTYPE );
+
+}
+
+OPTID opts_Declare(const char* ClName, OPTTYPE OptType)
+/* declare option by name/shorthand/argtype (command line name) */
+/**************************************************************
+ INPUT: An option name (its command line name) and an option type.
+ RETURNS: An option id.
+ EFFECTS: Appends the declaration to opts_DECLARATIONS.
+***************************************************************/
+{
+ OPTDECL* D;
+ OPTID Id;
+
+ if (!opts_IdIsNull(opts_Id(ClName))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("internal error: option with command line name '%s' redeclared.\n", ClName);
+ misc_FinishErrorReport(); }
+
+ D = memory_Malloc(sizeof(OPTDECL));
+
+ opts_DeclSetClName(D, string_StringCopy(ClName));
+ opts_DeclSetType(D,OptType);
+
+ opts_DECLARATIONS = list_Nconc(opts_DECLARATIONS, list_List(D));
+
+ Id = opts_IdGetNextAvailable();
+ opts_IdIncAvailable();
+
+ return Id;
+}
+
+OPTID opts_DeclareVector(OPTDECL Decls[])
+/**************************************************************
+ INPUT: An option declaration vector, which must have
+ a NULL pointer in the clname field of the last
+ declaration.
+ RETURNS: The id of the last declared option.
+ EFFECTS: All option declarations are added to opts_DECLARATIONS.
+***************************************************************/
+{
+ int i;
+
+ i = 0;
+ while (strlen(opts_DeclGetClName(&Decls[i])) != 0) {
+ opts_Declare(opts_DeclGetClName(&Decls[i]), opts_DeclGetType(&Decls[i]));
+ i++;
+ }
+ return opts_IdGetNextAvailable();
+}
+
+static char* opts_TranslateShortOptDeclarations(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: A string that codes the option declarations in
+ opts_DECLARATIONS in a string as required by the
+ GNU getopt module.
+***************************************************************/
+{
+ LIST Scan;
+ char* ShortDecl;
+ OPTDECL* Decl;
+
+ ShortDecl = string_StringCopy("\0");
+
+ Scan = opts_DECLARATIONS;
+
+ while (Scan) {
+ /* option is short iff:
+ - it was declared with a one letter command line name or
+ - it has an abbreviation
+ */
+ Decl = (OPTDECL*)list_Car(Scan);
+
+ if (opts_DeclIsShortOpt(Decl)) {
+ ShortDecl = string_Nconc(ShortDecl, string_StringCopy(opts_DeclGetClName(Decl)));
+
+ /*
+ add colon if optional or required argument
+ */
+ if (opts_DeclHasReqArg(Decl)||opts_DeclHasOptArg(Decl))
+ ShortDecl = string_Nconc(ShortDecl, string_StringCopy(":"));
+ }
+ Scan = list_Cdr(Scan);
+ }
+
+ /* add leading colon if any short options exist */
+ if (strlen(ShortDecl) != 0) {
+ ShortDecl = string_Nconc(string_StringCopy(":"),ShortDecl); }
+
+ return ShortDecl;
+}
+
+static LIST opts_GetLongOptDeclarations(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: A list of all 'long option' (with command line name
+ length > 1) declarations in opts_DECLARATIONS.
+ EFFECTS: Allocates list.
+***************************************************************/
+{
+ LIST Scan, Long;
+ OPTDECL* Decl;
+
+ Scan = opts_DECLARATIONS;
+ Long = list_Nil();
+
+ while (!list_Empty(Scan)) {
+ Decl = list_Car(Scan);
+
+ if (!opts_DeclIsShortOpt(Decl)) {
+ Long = list_Cons(Decl, Long);
+ }
+ Scan = list_Cdr(Scan);
+ }
+ return Long;
+}
+
+static __inline__ struct OPTION *opts_GetLongOptsArray(int OptNum)
+/**************************************************************
+ INPUT: An option number .
+ RETURNS: An array with <OptNum> entries for OPTION structs
+ as needed by GetOptLongOnly.
+ EFFECTS: Allocates array.
+***************************************************************/
+{
+ return (struct OPTION*)memory_Malloc(sizeof(struct OPTION)*(OptNum+1));
+}
+
+static void opts_FreeLongOptsArray(struct OPTION *LongOpts)
+/**************************************************************
+ INPUT: An array with entries for OPTION structs
+ RETURNS: Nothing
+ EFFECTS: Frees array. End of array is marked by a struct OPTION
+ entry with a NULL pointer in the 'name' field.
+***************************************************************/
+{
+ int i;
+
+ for (i=0; LongOpts[i].name != 0; i++) /* empty */;
+
+ memory_Free(LongOpts, (i+1)*sizeof(struct OPTION));
+}
+
+
+static struct OPTION* opts_TranslateLongOptDeclarations(void)
+/**************************************************************
+ INPUT : None
+ RETURNS: Translates opts_DECLARATIONS into an array as needed
+ by GetLongOptOnly
+ EFFECTS: Allocates the array
+***************************************************************/
+{
+ LIST Scan;
+ LIST LongDeclarations;
+ int OptNum;
+ int OptCnt;
+ struct OPTION* LongOpts;
+
+ OPTDECL* Decl;
+
+ LongDeclarations = opts_GetLongOptDeclarations();
+ OptNum = list_Length(LongDeclarations);
+ LongOpts = opts_GetLongOptsArray(OptNum);
+ OptCnt = 0;
+ Scan = LongDeclarations;
+
+ while (!list_Empty(Scan)) {
+ Decl = list_Car(Scan);
+
+ LongOpts[OptCnt].name = opts_DeclGetClName(Decl);
+
+ if (opts_DeclHasOptArg(Decl))
+ LongOpts[OptCnt].has_arg = 2;
+ else if (opts_DeclHasReqArg(Decl))
+ LongOpts[OptCnt].has_arg = 1;
+ else
+ LongOpts[OptCnt].has_arg = 0;
+ LongOpts[OptCnt].flag = 0;
+ LongOpts[OptCnt].val = 0;
+
+ Scan = list_Cdr(Scan);
+ OptCnt++;
+ }
+ /* set last field to 0 as required by getopt */
+ LongOpts[OptCnt].name = NULL;
+ LongOpts[OptCnt].has_arg = 0;
+ LongOpts[OptCnt].flag = 0;
+ LongOpts[OptCnt].val = 0;
+
+ list_Delete(LongDeclarations);
+
+ return LongOpts;
+}
+
+
+static void opts_PrintLongOpts(struct OPTION *LongOpts)
+/**************************************************************
+ INPUT: An array with OPTIONS structs
+ RETURNS: Nothing
+ EFFECTS: Prints contents of array
+***************************************************************/
+{
+ int i;
+
+ if (LongOpts == NULL) {
+ puts("\nPrintLongOpts gets NULL pointer.");
+ return;
+ }
+ puts("\nLong options array:");
+
+ i = 0;
+ while (LongOpts[i].name != NULL) {
+ printf("\nentry %d:\n",i);
+
+ printf("Name: %s\n", LongOpts[i].name);
+ printf("has_arg: %d\n", LongOpts[i].has_arg);
+ printf("flag; : %d\n", (int)LongOpts[i].flag);
+ printf("val : %d\n", LongOpts[i].val);
+ i++;
+ }
+}
+
+static __inline__ OPTID opts_IdCmp(OPTID Id1, OPTID Id2)
+/**************************************************************
+ INPUT: Two option ids
+ RETURNS: Analogously to strcmp:
+ '0' if Id1 == Id2
+ '<0' if Id1 < Id2
+ '>0' if Id1 > Id2
+***************************************************************/
+{
+ return (Id1-Id2);
+}
+
+static OPTID opts_IdEqual(OPTID Id1, OPTID Id2)
+/**************************************************************
+ INPUT: Two options ids
+ RETURNS: TRUE if they are equal
+***************************************************************/
+{
+ return (opts_IdCmp(Id1,Id2) == 0);
+}
+
+static OPTID opts_IdNext(OPTID Id)
+/**************************************************************
+ INPUT: An option id
+ RETURNS: The next option id in the ordering
+***************************************************************/
+{
+ return (Id+1);
+}
+
+
+const char* opts_ClName(OPTID Id)
+/**************************************************************
+ INPUT: An option id
+ RETURNS: Its command line name
+***************************************************************/
+{
+ OPTDECL* Decl;
+
+ Decl = opts_DeclGetById(Id);
+ return opts_DeclGetClName(Decl);
+}
+
+OPTID opts_Id(const char* ClName)
+/**************************************************************
+ INPUT: The command line name of an option
+ RETURNS: The corresponding id of the option,
+ the NULL id if no option with <ClName> exist.
+***************************************************************/
+{
+ LIST Scan;
+ BOOL found;
+ OPTID Id;
+
+ Scan = opts_DECLARATIONS;
+ Id = opts_IdFirst();
+ found = FALSE;
+
+ while (!found && !list_Empty(Scan)) {
+ if (string_Equal(opts_DeclGetClName(list_Car(Scan)), ClName)) {
+ found = TRUE;
+ } else {
+ Scan = list_Cdr(Scan);
+ Id = opts_IdNext(Id);
+ }
+ }
+ if (!found)
+ Id = opts_IdNull();
+ return Id;
+}
+
+static OPTID opts_ShortOptId(char c)
+/**************************************************************
+ INPUT: A character
+ RETURNS: The id of a short option <c>, NULL id
+ if it does not exist.
+***************************************************************/
+{
+ char Str[2];
+
+ Str[0] = c;
+ Str[1] = '\0';
+
+ return opts_Id(Str);
+}
+
+void opts_Init(void)
+/**************************************************************
+ INPUT: None
+ RETURNS: Nothing
+ EFFECT: Initialize option module
+***************************************************************/
+{
+ opts_DECLARATIONS = list_Nil();
+ opts_PARAMETERS = list_Nil();
+ opts_Err = 1; /* let getopt generate its own error messages */
+ opts_IdNextAvailable = opts_IdFirst();
+}
+
+void opts_DeclareSPASSFlagsAsOptions(void)
+/**************************************************************
+ INPUT: None
+ RETURNS: Nothing
+ EFFECT: Initialize option for use with SPASS:
+ declares all SPASS flags as command line opts.
+ MEMORY: Allocates space for declarations
+***************************************************************/
+{
+ int i;
+
+ for (i=0; i < flag_MAXFLAG; i++) {
+ opts_Declare(flag_Name(i), opts_OPTARGTYPE);
+ }
+}
+
+static void opts_FreeParameterPair(LIST Pair)
+/**************************************************************
+ INPUT : An (id/string) pair
+ RETURNS: Nothing
+ EFFECTS: Frees memory of list element and string
+***************************************************************/
+{
+ string_StringFree(list_PairSecond(Pair));
+
+ list_PairFree(Pair);
+}
+
+static void opts_FreeDecl(OPTDECL* D)
+/**************************************************************
+ INPUT: An options declaration
+ RETURNS: Nothing
+ EFFECTS: Frees memory of struct.
+***************************************************************/
+{
+ string_StringFree((char*)opts_DeclGetClName(D));
+ memory_Free(D, sizeof(OPTDECL));
+}
+
+void opts_Free(void)
+/**************************************************************
+ INPUT: None
+ RETURNS: Nothing
+ EFFECT: Free memory of module
+***************************************************************/
+{
+ list_DeleteWithElement(opts_PARAMETERS, (void (*)(POINTER))opts_FreeParameterPair);
+ list_DeleteWithElement(opts_DECLARATIONS,(void (*)(POINTER))opts_FreeDecl);
+}
+
+static void opts_PrintDeclarationList(LIST Scan)
+/**************************************************************
+ INPUT: A list with option declarations
+ RETURNS: Nothing
+ EFFECTS: Prints the list
+***************************************************************/
+{
+ OPTDECL* Decl;
+ OPTID Id;
+
+ Id = opts_IdFirst();
+
+ while (Scan) {
+ Decl = (OPTDECL*)list_Car(Scan);
+ printf("Id:%-6d Name:%-18s Type:%d\n", Id, opts_DeclGetClName(Decl),
+ opts_DeclGetType(Decl));
+ Scan = list_Cdr(Scan);
+ Id = opts_IdNext(Id);
+ }
+}
+
+static __inline__ void opts_PrintDeclarations(void)
+/**************************************************************
+ INPUT: None
+ RETURNS: Nothing
+ EFFECTS: Prints all currently declared options
+***************************************************************/
+{
+ opts_PrintDeclarationList(opts_DECLARATIONS);
+}
+
+static void opts_PrintParameters(void)
+/**************************************************************
+ INPUT: None
+ RETURNS: Nothing
+ EFFECTS: Prints all values of options read so far
+***************************************************************/
+{
+ LIST Scan;
+ LIST Pair;
+
+ Scan = opts_PARAMETERS;
+
+ while (!list_Empty(Scan)) {
+
+ Pair = list_Car(Scan);
+ printf("\nId: %d ", (OPTID)list_PairFirst(Pair));
+ printf("Par: %s", (char*) list_PairSecond(Pair));
+
+ Scan = list_Cdr(Scan);
+ }
+}
+
+
+void opts_PrintSPASSNames(void)
+/**************************************************************
+ INPUT: None
+ RETURNS: Nothing
+ EFFECT: Prints all options in three rows
+***************************************************************/
+{
+ int i,j;
+
+ for (i=0; i < flag_MAXFLAG; i=i+4) {
+ for (j =0; j <=3; j++) {
+ if (i+j < flag_MAXFLAG)
+ printf("%-18s ", flag_Name(i+j)); }
+ putchar('\n');
+ }
+}
+
+static OPTDECL* opts_DeclGetById(OPTID Id)
+/**************************************************************
+ INPUT : An option id
+ RETURNS: The declaration corresponding to option <id>
+***************************************************************/
+{
+ OPTID ScanId;
+ LIST Scan;
+
+ ScanId = opts_IdFirst();
+ Scan = opts_DECLARATIONS;
+
+ while (!list_Empty(Scan)) {
+ if (opts_IdEqual(Id, ScanId))
+ return list_Car(Scan);
+ Scan = list_Cdr(Scan);
+ ScanId = opts_IdNext(ScanId);
+ }
+
+ return (OPTDECL*)NULL;
+}
+
+
+/* Currently unused */
+/*static*/ OPTDECL* opts_DeclGetByClName(const char* ClName)
+/**************************************************************
+ INPUT : A command line name
+ RETURNS: The declaration of the option with <ClName> as command
+ line name, NULL if there's no such option
+***************************************************************/
+{
+ OPTID Id;
+
+ Id = opts_Id(ClName);
+ if (opts_IdIsNull(Id))
+ return NULL;
+ return opts_DeclGetById(Id);
+}
+
+
+BOOL opts_Read(int argc, const char* argv[])
+/**************************************************************
+ INPUT: Program parameter data
+ RETURNS: TRUE iff options are correctly specified
+ EFFECT: Errors are commented
+ MEMORY: Builds up opts_PARAMETERS while reading
+ options and their values.
+***************************************************************/
+{
+ int OptIndex, c;
+ char *ShortOpts;
+ BOOL Ok;
+ OPTID OptId;
+ OPTDECL *OptDecl;
+ const char *OptName;
+ struct OPTION *LongOpts;
+
+ Ok = TRUE;
+
+ ShortOpts = opts_TranslateShortOptDeclarations();
+ LongOpts = opts_TranslateLongOptDeclarations();
+
+ while (Ok && (c = opts_GetOptLongOnly(argc, argv, ShortOpts,
+ LongOpts, &OptIndex)) != -1) {
+ /*
+ for following eval of opts_GetOptLongOnly result see
+ GNU getopt documentation. In short, opts_GetOptLongOnly
+ returns a char if it has found that char as an option in
+ the command line, and this option is declared in opts_DECLARATIONS.
+ It returns 0 if it has found a declared long option.
+
+ */
+ if (c == '?') {
+ /**** unknown option ****/
+
+ /* This has already been commented by opts_GetOptLongOnly */
+ return FALSE;
+ } else if (c == 0) {
+ /**** its a long option ****/
+
+ OptName = LongOpts[OptIndex].name;
+ OptId = opts_Id(OptName);
+ OptDecl = opts_DeclGetById(OptId);
+
+ if (opts_Arg == NULL) {
+ /* if argument required and no arg specified, error */
+ if (opts_DeclHasReqArg(OptDecl)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\nerror, option %s requires argument.\n", OptName);
+ misc_FinishUserErrorReport();
+ return FALSE;
+ }
+
+ /* otherwise, set default value */
+ Ok = opts_AddParamCheck(OptId,opts_DEFAULTOPTARG);
+ } else
+ Ok = opts_AddParamCheck(OptId,opts_Arg);
+ } else {
+ /**** its a short option ****/
+
+ /* handle missing but required arguments. So far, this is left
+ to opts_GetOptLongOnly */
+ if (c == ':')
+ return FALSE;
+
+ /*
+
+ One further special case: if a short option has an optional
+ argument, but this argument is a '--', then take the
+ default argument value. '--' normally signifies: no further
+ options and is not interpreted nor returned by getopt as
+ an argument value of an option with argument. As we
+ permit default values for options with args, we have to declare
+ all options with args. Therefore, getopt takes
+
+ -o --
+
+ '-o with arg --' if "o:" is the declaration. We interpret
+ this as '-o with default value'.
+
+ */
+
+ else {
+ OptId = opts_ShortOptId(c);
+ if (opts_IdIsNull(OptId)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\ninternal error: option %c not found.\n", c);
+ misc_FinishErrorReport();
+ }
+ OptDecl = opts_DeclGetById(OptId);
+
+ if (opts_DeclHasReqArg(OptDecl)) {
+ if (!opts_Arg) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\nerror: option %c requires argument.\n",c);
+ misc_FinishUserErrorReport();
+ Ok = FALSE;
+ } else if (string_Equal(opts_Arg, opts_ENDMARKER)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\nerror: option %c has delimiter -- as argument.\n",c);
+ misc_FinishUserErrorReport();
+ Ok = FALSE;
+ } else
+ Ok = opts_AddParamCheck(OptId,opts_Arg);
+ }
+ /* options with args */
+ else if (opts_DeclHasOptArg(OptDecl)) {
+ /* if arg is present, check for endmarker */
+ if (opts_Arg) {
+ if (string_Equal(opts_Arg, opts_ENDMARKER))
+ Ok = opts_AddParamCheck(OptId,opts_DEFAULTOPTARG);
+ else
+ Ok = opts_AddParamCheck(OptId,opts_Arg); }
+ else
+ Ok = opts_AddParamCheck(OptId,opts_DEFAULTOPTARG);
+ }
+ /* default for options without args */
+ else
+ Ok = opts_AddParamCheck(OptId,opts_DEFAULTOPTARG);
+ }
+ }
+ }
+
+ string_StringFree(ShortOpts);
+ opts_FreeLongOptsArray(LongOpts);
+
+ return Ok;
+}
+
+
+BOOL opts_ReadOptionsFromString(const char* Options)
+/**************************************************************
+ INPUT: A string containing program parameter data
+ RETURNS: TRUE iff the string contains only valid options.
+ The function returns FALSE if the string contains
+ any substring that isn't a option or invalid option
+ settings.
+ EFFECT: Errors are commented (via stderr).
+ MEMORY: Builds up opts_PARAMETERS while reading options and
+ their values.
+ CAUTION: The function cannot !! be used in context with the
+ other option evaluation functions like opts_Read.
+***************************************************************/
+{
+ char **argv;
+ char *Copy;
+ int argc, i;
+ BOOL Result;
+
+ /* Copy the options string since "string_Tokens" modifies it temporarily */
+ Copy = string_StringCopy(Options);
+ /* Split the string into substrings without whitespace. */
+ /* Collect the substrings in an array similar to "argv" for main(). */
+ argv = string_Tokens(Copy, &argc);
+
+ /* Check whether all options are valid. */
+ Result = opts_Read(argc, (const char**)argv);
+ /* Check whether the string contains only option settings. */
+ if (opts_Indicator() < argc)
+ Result = FALSE;
+
+ /* Cleanup */
+ for (i = argc-1; i >= 0; i--)
+ string_StringFree(argv[i]);
+ memory_Free(argv, sizeof(char)*(argc+1));
+ string_StringFree(Copy);
+
+ return Result;
+}
+
+
+BOOL opts_GetValueByName(const char* Name, const char** Value)
+/**************************************************************
+ INPUT: An option command line name, a string by ref.
+ RETURNS: TRUE if an option with this name exists
+ in opts_PARAMETERS (as set by opts_Read()),
+ and the assigned value of this option in <Value>.
+ FALSE otherwise
+ EFFECTS: <*Value> is changed
+***************************************************************/
+{
+ LIST Scan;
+ LIST Pair;
+ BOOL found;
+
+ found = FALSE;
+ Pair = list_Nil(); /* to quiet gcc */
+
+ for (Scan = opts_PARAMETERS;
+ (!found && !list_Empty(Scan)); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ if (string_Equal(Name, opts_ClName((OPTID)list_PairFirst(Pair))))
+ found = TRUE;
+ }
+
+ if (found)
+ (*Value) = list_PairSecond(Pair);
+
+ return found;
+}
+
+BOOL opts_GetValue(OPTID Id, const char** s)
+/**************************************************************
+ INPUT: An option id, a string by reference
+ RETURNS: TRUE if an option with this id exists
+ in opts_PARAMETERS (as set by opts_Read()),
+ and the assigned value of this option in <Value>.
+ FALSE otherwise
+ EFFECTS: <s*> is changed
+***************************************************************/
+{
+ LIST Scan;
+ LIST Pair;
+ BOOL found;
+
+ Pair = list_Nil();
+ found = FALSE;
+
+ for (Scan = opts_PARAMETERS;
+ (!found && !list_Empty(Scan)); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ if (opts_IdEqual(Id, (OPTID)list_PairFirst(Pair)))
+ found = TRUE;
+ }
+
+ if (found)
+ (*s) = list_PairSecond(Pair);
+
+ return found;
+}
+
+
+BOOL opts_GetIntValueByName(const char* Name, int* Val)
+/**************************************************************
+ INPUT: An options name, an integer by reference
+ RETURNS: TRUE
+ if an option with <Name> exists
+ in opts_PARAMETERS (as set by opts_Read()) and
+ if its assigned value is an integer.
+ The assigned value of this option is returned in <Val>.
+ FALSE
+ otherwise
+ EFFECTS: <Val*> is changed
+***************************************************************/
+{
+ const char* ValStr ;
+
+ if (!opts_GetValueByName(Name, &ValStr))
+ return FALSE;
+
+ return string_StringToInt(ValStr, FALSE, Val);
+}
+
+BOOL opts_GetIntValue(OPTID Id, int* i)
+/**************************************************************
+ INPUT: An options name, an integer by reference
+ RETURNS: TRUE
+ if an option with <Id> exists
+ in opts_PARAMETERS (as set by opts_Read()) and
+ if its assigned value is an integer.
+ T he assigned value of this option is returned in <*i>.
+ FALSE
+ otherwise
+ EFFECTS: <*i> is changed
+***************************************************************/
+{
+ return opts_GetIntValueByName(opts_ClName(Id), i);
+}
+
+
+
+BOOL opts_IsSet(OPTID Id)
+/**************************************************************
+ INPUT: An option id
+ RETURNS: TRUE iff the option has been set in the command line
+ (that is, is listed in opts_PARAMETERS)
+***************************************************************/
+{
+ LIST Scan;
+ LIST Pair;
+ BOOL found;
+
+ found = FALSE;
+
+ for (Scan = opts_PARAMETERS;
+ (!found && !list_Empty(Scan)); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ if (opts_IdEqual(Id, (OPTID)list_Car(Pair)))
+ found = TRUE;
+ }
+ return found;
+}
+
+
+/* Currently unused */
+/*static*/ BOOL opts_IsSetByName(const char* Name)
+/**************************************************************
+ INPUT: An option name
+ RETURNS: TRUE iff option with this name has been set in command line
+***************************************************************/
+{
+ LIST Scan;
+ LIST Pair;
+ BOOL found;
+
+ found = FALSE;
+
+ for (Scan = opts_PARAMETERS;
+ (!found && !list_Empty(Scan)); Scan = list_Cdr(Scan)) {
+ Pair = list_Car(Scan);
+ if (string_Equal(Name, opts_ClName((OPTID)list_PairFirst(Pair))))
+ found = TRUE;
+ }
+ return found;
+}
+
+void opts_SetFlags(FLAGSTORE Store)
+/**************************************************************
+ INPUT: A flag store.
+ RETURNS: Nothing
+ EFFECT : Transfer options into SPASS flags in <Store>
+ CAUTION: To connect SPASS flags and options, we assume that
+ all flag names and command line names of all options
+ are the same!
+***************************************************************/
+{
+ int IntValue;
+ OPTID Id;
+ FLAG_ID i;
+
+ for (i = 0; i < flag_MAXFLAG; i++) {
+ Id = opts_Id(flag_Name(i));
+ if (opts_IsSet(Id)) {
+ if (opts_GetIntValue(Id, &IntValue)) {
+ flag_SetFlagValue(Store, Id, IntValue);
+ } else {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\nerror: argument of option %s must be integer.\n",flag_Name(i));
+ misc_FinishUserErrorReport();
+ }
+ }
+ }
+}
+
+void opts_Transfer(FLAGSTORE Store)
+/**************************************************************
+ INPUT: A flag store.
+ RETURNS: Nothing
+ EFFECT: Transfer options from 'opts_PARAMETERS' list into SPASS
+ flags in <Store>
+ CAUTION: To connect SPASS flags and options, we assume that
+ all flag names and command line names of all options
+ are the same!
+***************************************************************/
+{
+ LIST Scan;
+ LIST Pair;
+ int IntValue;
+ const char *Name, *ValStr;
+ OPTID Id;
+ BOOL ok;
+
+ Scan = opts_PARAMETERS;
+
+ while (!list_Empty(Scan)) {
+ Pair = list_Car(Scan);
+ Id = (int)list_PairFirst(Pair);
+ ValStr = (const char*)list_PairSecond(Pair);
+ Name = opts_ClName(Id);
+
+ ok = string_StringToInt(ValStr, FALSE, &IntValue);
+ if (!ok) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\nerror: argument '%s' of option '%s' must be integer.\n",
+ ValStr, Name);
+ misc_FinishUserErrorReport();
+ } else {
+ flag_SetFlagValue(Store, flag_Id(Name), IntValue);
+ }
+ Scan = list_Cdr(Scan);
+ }
+}
+
+
+static void opts_AddParam(OPTID Id, const char* ValueString)
+/**************************************************************
+ INPUT: An option id and a string with its assigned value
+ RETURNS: Nothing.
+ EFFECT: Add (Id, ValueString) tupel to 'opts_PARAMETERS' list
+***************************************************************/
+{
+ LIST Pair;
+ Pair = list_PairCreate((POINTER)Id, string_StringCopy(ValueString));
+ opts_PARAMETERS = list_Cons(Pair, opts_PARAMETERS);
+}
+
+
+static BOOL opts_AddParamCheck(OPTID Id, const char* ValueString)
+/**************************************************************
+ INPUT: An option id and a string
+ RETURNS: TRUE iff option with <Id> has not been defined
+ EFFECTS: Adds (<Id>,<ValueString>) tupel to opts_PARAMETERS
+***************************************************************/
+{
+ const char* Dummy;
+ if (opts_GetValue(Id, &Dummy)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("error: option %s is multiply defined.\n", opts_ClName(Id));
+ misc_FinishUserErrorReport();
+ return FALSE;
+ }
+ opts_AddParam(Id, ValueString);
+ return TRUE;
+}
+
+
+int opts_Indicator(void)
+/**************************************************************
+ INPUT: None
+ RETURNS: Integer variable indicating position of next argument
+***************************************************************/
+{
+ return opts_Ind;
+}
+
+
+static void opts_Exchange (const char *argv[])
+/**************************************************************
+ INPUT: Reference to string
+ RETURNS: Nothing
+ EFFECT: See below
+***************************************************************/
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [opts_FirstNonOpt,opts_LastNonOpt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [opts_LastNonOpt,opts_Ind), which contains all
+ the options processed since those non-options were skipped.
+
+ `opts_FirstNonOpt' and `opts_LastNonOpt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+{
+ int bottom = opts_FirstNonOpt;
+ int middle = opts_LastNonOpt;
+ int top = opts_Ind;
+ const char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+ while (top > middle && middle > bottom) {
+ if (top - middle > middle - bottom) {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++) {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++) {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ opts_FirstNonOpt += (opts_Ind - opts_LastNonOpt);
+ opts_LastNonOpt = opts_Ind;
+}
+
+
+static const char *opts_GetOptInitialize (int argc, const char *const argv[],
+ const char *optstring)
+/**************************************************************
+ INPUT: The command line arguments ('argc', 'argv') and
+ a string describing options ('optstring')
+ RETURNS: a possibly modified 'optstring'
+ EFFECT: Several static variables related to options
+ processing are influenced (see below).
+ MEMORY: None
+***************************************************************/
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ opts_FirstNonOpt = opts_LastNonOpt = opts_Ind = 1;
+
+ opts_NextChar = NULL;
+
+ opts_PosixlyCorrect = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-') {
+ opts_Ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+') {
+ opts_Ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (opts_PosixlyCorrect != NULL)
+ opts_Ordering = REQUIRE_ORDER;
+ else
+ opts_Ordering = PERMUTE;
+
+ opts_NonOptionFlagslen = 0;
+
+ return optstring;
+}
+
+static int opts_GetOptInternal (int argc, const char* argv[],
+ const char *optstring,
+ const struct OPTION *longopts, int *longind,
+ int long_only)
+/**************************************************************
+ INPUT: An array of pointers to arguments (strings),
+ and format information. See below for extensive
+ description
+ RETURNS: -1 only if there are no more options, otherwise
+ a value identifying a read option. See below.
+ EFFECT: Affects statics opts_Ind, opts_Arg, opts_Opt,
+ opts_NextChar and argument array. See below.
+ MEMORY: See below.
+***************************************************************/
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `opts_Ind' and `opts_NextChar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `opts_Ind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opts_Err' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `opts_Arg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `opts_Arg', otherwise `opts_Arg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct OPTION' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+{
+ opts_Arg = NULL;
+
+ if (!opts_GetOptInitialized || opts_Ind == 0) {
+ optstring = opts_GetOptInitialize(argc, argv, optstring);
+ opts_Ind = 1; /* Don't scan ARGV[0], the program name. */
+ opts_GetOptInitialized = 1;
+ }
+
+ /* Test whether ARGV[opts_Ind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+
+
+ if (opts_NextChar == NULL || *opts_NextChar == '\0') {
+ /* Advance to the next ARGV-element. */
+
+ /* Give OPTS_FIRSTNONOPT & LAST_NONOPT rational values if OPTS_IND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (opts_LastNonOpt > opts_Ind)
+ opts_LastNonOpt = opts_Ind;
+ if (opts_FirstNonOpt > opts_Ind)
+ opts_FirstNonOpt = opts_Ind;
+
+ if (opts_Ordering == PERMUTE) {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (opts_FirstNonOpt != opts_LastNonOpt && opts_LastNonOpt != opts_Ind)
+ opts_Exchange(argv);
+ else if (opts_LastNonOpt != opts_Ind)
+ opts_FirstNonOpt = opts_Ind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (opts_Ind < argc && (argv[opts_Ind][0] != '-' || argv[opts_Ind][1] == '\0'))
+ opts_Ind++;
+ opts_LastNonOpt = opts_Ind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (opts_Ind != argc && !strcmp(argv[opts_Ind], "--")) {
+ opts_Ind++;
+
+ if (opts_FirstNonOpt != opts_LastNonOpt && opts_LastNonOpt != opts_Ind)
+ opts_Exchange(argv);
+ else if (opts_FirstNonOpt == opts_LastNonOpt)
+ opts_FirstNonOpt = opts_Ind;
+ opts_LastNonOpt = argc;
+
+ opts_Ind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (opts_Ind == argc) {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (opts_FirstNonOpt != opts_LastNonOpt)
+ opts_Ind = opts_FirstNonOpt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if ( (argv[opts_Ind][0] != '-' || argv[opts_Ind][1] == '\0')) {
+ if (opts_Ordering == REQUIRE_ORDER)
+ return -1;
+ opts_Arg = argv[opts_Ind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ opts_NextChar = (argv[opts_Ind] + 1
+ + (longopts != NULL && argv[opts_Ind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[opts_Ind][1] == '-'
+ || (long_only && (argv[opts_Ind][2] || !strchr(optstring, argv[opts_Ind][1]))))) {
+ const char *nameend;
+ const struct OPTION *p;
+ const struct OPTION *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = opts_NextChar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, opts_NextChar, nameend - opts_NextChar)) {
+ if ((unsigned int) (nameend - opts_NextChar)
+ == (unsigned int) strlen(p->name)) {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL) {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact) {
+ if (opts_Err) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: option `%s' is ambiguous\n", argv[0], argv[opts_Ind]);
+ misc_FinishUserErrorReport();
+ }
+ opts_NextChar += strlen(opts_NextChar);
+ opts_Ind++;
+ opts_Opt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL) {
+ option_index = indfound;
+ opts_Ind++;
+ if (*nameend) {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ opts_Arg = nameend + 1;
+ else {
+ if (opts_Err) {
+ if (argv[opts_Ind - 1][1] == '-') {
+ /* --option */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: option `--%s' doesn't allow an argument\n",argv[0], pfound->name);
+ misc_FinishUserErrorReport();
+ }
+ else {
+ /* +option or -option */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: option `%c%s' doesn't allow an argument\n",
+ argv[0], argv[opts_Ind - 1][0], pfound->name);
+ misc_FinishUserErrorReport();
+ }
+ }
+ opts_NextChar += strlen(opts_NextChar);
+
+ opts_Opt = pfound->val;
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1) {
+ if (opts_Ind < argc)
+ opts_Arg = argv[opts_Ind++];
+ else {
+ if (opts_Err) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: option `%s' requires an argument\n",
+ argv[0], argv[opts_Ind - 1]);
+ misc_FinishUserErrorReport();
+ }
+ opts_NextChar += strlen(opts_NextChar);
+ opts_Opt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ opts_NextChar += strlen(opts_NextChar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag) {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not opts_GetOptLong_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[opts_Ind][1] == '-'
+ || strchr(optstring, *opts_NextChar) == NULL) {
+ if (opts_Err) {
+ if (argv[opts_Ind][1] == '-') {
+ /* --option */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: unrecognized option `--%s'\n",argv[0], opts_NextChar);
+ misc_FinishUserErrorReport();
+ }
+ else {
+ /* +option or -option */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: unrecognized option `%c%s'\n",
+ argv[0], argv[opts_Ind][0], opts_NextChar);
+ misc_FinishUserErrorReport();
+ }
+ }
+ opts_NextChar = "";
+ opts_Ind++;
+ opts_Opt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *opts_NextChar++;
+ char *temp = strchr(optstring, c);
+
+ /* Increment `opts_Ind' when we start to process its last character. */
+ if (*opts_NextChar == '\0')
+ ++opts_Ind;
+
+ if (temp == NULL || c == ':') {
+ if (opts_Err) {
+ if (opts_PosixlyCorrect) {
+ /* 1003.2 specifies the format of this message. */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: illegal option -- %c\n", argv[0], c);
+ misc_FinishUserErrorReport();
+ }
+ else {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: invalid option -- %c\n", argv[0], c);
+ misc_FinishUserErrorReport();
+ }
+ }
+ opts_Opt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';') {
+ const char *nameend;
+ const struct OPTION *p;
+ const struct OPTION *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*opts_NextChar != '\0') {
+ opts_Arg = opts_NextChar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ opts_Ind++;
+ }
+ else if (opts_Ind == argc) {
+ if (opts_Err) {
+ /* 1003.2 specifies the format of this message. */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: option requires an argument -- %c\n", argv[0], c);
+ misc_FinishUserErrorReport();
+ }
+ opts_Opt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `opts_Ind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ opts_Arg = argv[opts_Ind++];
+
+ /* opts_Arg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (opts_NextChar = nameend = opts_Arg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, opts_NextChar, nameend - opts_NextChar)) {
+ if ((unsigned int) (nameend - opts_NextChar) == strlen(p->name)) {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL) {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact) {
+ if (opts_Err) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: option `-W %s' is ambiguous\n", argv[0], argv[opts_Ind]);
+ misc_FinishUserErrorReport();
+ }
+ opts_NextChar += strlen(opts_NextChar);
+ opts_Ind++;
+ return '?';
+ }
+ if (pfound != NULL) {
+ option_index = indfound;
+ if (*nameend) {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ opts_Arg = nameend + 1;
+ else {
+ if (opts_Err) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: option `-W %s' doesn't allow an argument\n", argv[0], pfound->name);
+ misc_FinishUserErrorReport();
+ }
+
+ opts_NextChar += strlen(opts_NextChar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1) {
+ if (opts_Ind < argc)
+ opts_Arg = argv[opts_Ind++];
+ else {
+ if (opts_Err) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("%s: option `%s' requires an argument\n", argv[0], argv[opts_Ind - 1]);
+ misc_FinishUserErrorReport();
+ }
+ opts_NextChar += strlen(opts_NextChar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ opts_NextChar += strlen(opts_NextChar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag) {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ opts_NextChar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':') {
+ if (temp[2] == ':') {
+ /* This is an option that accepts an argument optionally. */
+ if (*opts_NextChar != '\0') {
+ opts_Arg = opts_NextChar;
+ opts_Ind++;
+ }
+ else
+ opts_Arg = NULL;
+ opts_NextChar = NULL;
+ }
+ else {
+ /* This is an option that requires an argument. */
+ if (*opts_NextChar != '\0') {
+ opts_Arg = opts_NextChar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ opts_Ind++;
+ }
+ else if (opts_Ind == argc) {
+ if (opts_Err) {
+ /* 1003.2 specifies the format of this message. */
+ misc_StartUserErrorReport();
+ misc_UserErrorReport(("%s: option requires an argument -- %c\n"), argv[0], c);
+ misc_FinishUserErrorReport();
+ }
+ opts_Opt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `opts_Ind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ opts_Arg = argv[opts_Ind++];
+ opts_NextChar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+
+/* Like opts_GetOptLong, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+static int opts_GetOptLongOnly(int argc, const char* argv[], const char *options,
+ const struct OPTION *long_options, int *opt_index)
+/**************************************************************
+ FUNCTIONALITY: See opts_GetOptInternal
+***************************************************************/
+{
+ return opts_GetOptInternal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+static void opts_Dummy(void)
+/**************************************************************
+ Assemble all unused functions to quiet gcc
+***************************************************************/
+{
+ if (FALSE) {
+ opts_PrintParameters();
+ opts_PrintDeclarations();
+ opts_DeclHasNoArg(NULL);
+ opts_PrintLongOpts((struct OPTION*)NULL);
+ opts_Dummy();
+ }
+}
diff --git a/test/spass/options.h b/test/spass/options.h
new file mode 100644
index 0000000..f41da83
--- /dev/null
+++ b/test/spass/options.h
@@ -0,0 +1,127 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SPASS OPTIONS HANDLING * */
+/* * * */
+/* * $Module: OPTIONS * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+
+#ifndef _OPTIONS_
+#define _OPTIONS_
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "flags.h"
+#include "list.h"
+
+
+/**************************************************************/
+/* Data Structures and Constants */
+/**************************************************************/
+
+/* option type */
+typedef int OPTTYPE;
+
+#define opts_NOARGTYPE 0 /* no argument */
+#define opts_REQARGTYPE 1 /* required argument */
+#define opts_OPTARGTYPE 2 /* optional argument */
+
+/* option id */
+typedef int OPTID;
+#define opts_IDFIRST 0 /* option id to start with */
+
+/* struct for declaration of options */
+typedef struct {
+ char* clname; /* option name in the command line */
+ OPTTYPE type; /* argument type: required, optional, non */
+} OPTDECL;
+
+#define opts_ENDMARKER "--" /* double hyphen: marks end of all options */
+#define opts_DEFAULTOPTARG "1" /* default value of options with optional arguments */
+
+/**************************************************************
+ from the getopt.h file
+ **************************************************************/
+struct OPTION
+{
+ char *name;
+
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void opts_Init(void);
+void opts_Free(void);
+OPTID opts_DeclareVector(OPTDECL []);
+OPTID opts_Declare(const char*, OPTTYPE);
+BOOL opts_Read(int, const char* []);
+BOOL opts_ReadOptionsFromString(const char*);
+int opts_Indicator(void);
+
+BOOL opts_IsSet(OPTID);
+BOOL opts_GetIntValueByName(const char*, int*);
+BOOL opts_GetValueByName(const char*, const char**);
+BOOL opts_GetValue(OPTID, const char**);
+BOOL opts_GetIntValue(OPTID, int*) ;
+
+const char* opts_ClName(OPTID);
+OPTID opts_IdFirst(void);
+OPTID opts_Id(const char*);
+BOOL opts_IdIsNull(OPTID);
+
+/* specials for SPASS */
+void opts_Transfer(FLAGSTORE);
+void opts_SetFlags(FLAGSTORE);
+void opts_DeclareSPASSFlagsAsOptions(void);
+void opts_PrintSPASSNames(void);
+
+#endif
diff --git a/test/spass/order.c b/test/spass/order.c
new file mode 100644
index 0000000..48a1dd3
--- /dev/null
+++ b/test/spass/order.c
@@ -0,0 +1,516 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INTERFACE FOR ALL ORDERING IMPLEMENTATIONS * */
+/* * * */
+/* * $Module: ORDER * */
+/* * * */
+/* * Copyright (C) 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "flags.h"
+#include "order.h"
+#include "kbo.h"
+#include "rpos.h"
+#include "symbol.h"
+
+NAT ord_VARCOUNT[symbol__MAXSTANDARDVAR][2];
+PRECEDENCE ord_PRECEDENCE;
+
+
+static ord_RESULT ord_CheckDomPred(TERM T1, TERM T2, PRECEDENCE P)
+/**************************************************************
+ INPUT: Two terms and a precedence.
+ RETURNS: An ordering result with respect to a possible domination
+ of leading predicates in <T1> or <T2>.
+***************************************************************/
+{
+ if ((term_IsAtom(T1) && symbol_HasProperty(term_TopSymbol(T1), DOMPRED)) ||
+ (term_IsAtom(T2) && symbol_HasProperty(term_TopSymbol(T2), DOMPRED))) {
+ if (term_IsAtom(T1)) {
+ if (term_IsAtom(T2)) {
+ if (symbol_HasProperty(term_TopSymbol(T1), DOMPRED) &&
+ (!symbol_HasProperty(term_TopSymbol(T2), DOMPRED) ||
+ symbol_PrecedenceGreater(P,term_TopSymbol(T1),term_TopSymbol(T2))))
+ return ord_GREATER_THAN;
+ if (!symbol_HasProperty(term_TopSymbol(T1), DOMPRED) ||
+ term_TopSymbol(T1) != term_TopSymbol(T2))
+ return ord_SMALLER_THAN;
+ /* If the top symbols are equal, do the normal comparison */
+ } else {
+ /* T1 is an atom, T2 is not, so T1 is greater */
+ return ord_GREATER_THAN;
+ }
+ } else {
+ /* T1 is not an atom, so T2 must be an atom */
+ return ord_SMALLER_THAN;
+ }
+ }
+ return ord_UNCOMPARABLE;
+}
+
+
+ord_RESULT ord_Compare(TERM T1, TERM T2, FLAGSTORE FlagStore, PRECEDENCE P)
+/**************************************************************
+ INPUT:
+ RETURNS:
+***************************************************************/
+{
+ ord_RESULT Aux;
+
+#ifdef CHECK
+ if (fol_IsEquality(T1) || fol_IsEquality(T2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ord_Compare:");
+ misc_ErrorReport("\n Illegal input. One input term is an equality.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Aux = ord_CheckDomPred(T1, T2, P);
+ if (Aux != ord_UNCOMPARABLE)
+ return Aux;
+ else {
+ ord_PRECEDENCE = P;
+ switch(flag_GetFlagValue(FlagStore, flag_ORD)) {
+ case flag_ORDKBO: return kbo_Compare(T1, T2); break;
+ case flag_ORDRPOS: return rpos_Compare(T1, T2); break;
+ default:
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ord_Compare:");
+ misc_ErrorReport("\n Illegal ordering type.");
+ misc_FinishErrorReport();
+ }
+ }
+ return ord_UNCOMPARABLE;
+}
+
+
+BOOL ord_CompareEqual(TERM T1, TERM T2, FLAGSTORE Flags)
+/**************************************************************
+ INPUT: Two terms and a flag store.
+ RETURNS: TRUE, iff the two terms are equal with respect to the
+ reduction ordering selected by the 'flag_ORD' flag.
+***************************************************************/
+{
+ switch(flag_GetFlagValue(Flags, flag_ORD)) {
+ case flag_ORDKBO: return term_Equal(T1, T2); break;
+ case flag_ORDRPOS: return rpos_Equal(T1, T2); break;
+ default:
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ord_Compare: Illegal ordering type.");
+ misc_FinishErrorReport();
+ return FALSE; /* unreachable code ... */
+ }
+}
+
+ord_RESULT ord_ContCompare(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2,
+ FLAGSTORE FlagStore, PRECEDENCE P)
+{
+ ord_RESULT Aux;
+
+#ifdef CHECK
+ if (fol_IsEquality(T1) || fol_IsEquality(T2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ord_ContCompare:");
+ misc_ErrorReport("\n Illegal input. One input term is an equality.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Aux = ord_CheckDomPred(T1, T2, P);
+ if (Aux != ord_UNCOMPARABLE)
+ return Aux;
+ else {
+ ord_PRECEDENCE = P;
+ switch(flag_GetFlagValue(FlagStore, flag_ORD)) {
+ case flag_ORDKBO: return kbo_ContCompare(C1, T1, C2, T2); break;
+ case flag_ORDRPOS: return rpos_ContCompare(C1, T1, C2, T2); break;
+ default:
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ord_ContCompare:");
+ misc_ErrorReport("\n Illegal ordering type.");
+ misc_FinishErrorReport();
+ }
+ }
+ return ord_UNCOMPARABLE;
+}
+
+
+BOOL ord_ContGreater(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2,
+ FLAGSTORE FlagStore, PRECEDENCE P)
+{
+ ord_RESULT Aux;
+
+#ifdef CHECK
+ if (fol_IsEquality(T1) || fol_IsEquality(T2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ord_ContGreater:");
+ misc_ErrorReport("\n Illegal input. One input term is an equality.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Aux = ord_CheckDomPred(T1, T2, P);
+ if (Aux != ord_UNCOMPARABLE)
+ return (Aux == ord_GREATER_THAN);
+ else {
+ ord_PRECEDENCE = P;
+ switch(flag_GetFlagValue(FlagStore, flag_ORD)) {
+ case flag_ORDKBO: return kbo_ContGreater(C1, T1, C2, T2); break;
+ case flag_ORDRPOS: return rpos_ContGreater(C1, T1, C2, T2); break;
+ default:
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ord_ContGreater:");
+ misc_ErrorReport("\n Illegal ordering type.");
+ misc_FinishErrorReport();
+ }
+ }
+ return FALSE; /* This line is never reached ... */
+}
+
+
+ord_RESULT ord_Not(ord_RESULT Result)
+/**************************************************************
+ INPUT: An ord_RESULT
+ RETURNS: The negation with respect to argument switching.
+***************************************************************/
+{
+ if (Result == ord_UNCOMPARABLE || Result == ord_EQUAL)
+ return Result;
+
+ if (Result == ord_GREATER_THAN)
+ return ord_SMALLER_THAN;
+
+ return ord_GREATER_THAN;
+}
+
+
+void ord_Print(ord_RESULT Result)
+/**************************************************************
+ INPUT: An ord_Result.
+ RETURNS: None, prints the Result as a string to stdout.
+***************************************************************/
+{
+ switch(Result) {
+ case ord_UNCOMPARABLE: fputs(" uncomparable ",stdout); break;
+ case ord_EQUAL: fputs(" equal ",stdout); break;
+ case ord_GREATER_THAN: fputs(" greater than ",stdout); break;
+ case ord_SMALLER_THAN: fputs(" smaller than ",stdout); break;
+ default: fputs(" Nonsense! ",stdout);
+ }
+}
+
+
+ord_RESULT ord_LiteralCompare(TERM Lit1, BOOL Orient1, TERM Lit2, BOOL Orient2,
+ BOOL Check, FLAGSTORE FlagStore,
+ PRECEDENCE Precedence)
+/*********************************************************
+ INPUT: Two term literals and two flags indicating whether these
+ two literals are oriented equalities.
+ Additionally a check flag that indicates whether
+ the orientation flags are sufficient or necessary and sufficient:
+ If Check=TRUE then if flag is FALSE it is interpreted that it is not
+ known whether the (possible) equation can be oriented oriented.
+ However, if flag is TRUE we assume that it is oriented.
+ A flag store.
+ A precedence.
+ RETURNS: The result if these literals are compared with
+ respect to the ordering. Dependent on their sign, the literals
+ are compared as multiset of their topsymbol terms,
+ where any literal is considered to be an equation
+ and non equational literals are considered to be
+ equations with the artificial, non-existent, minimal
+ constant tt.
+ EFFECT: The arguments of the literals are possibly, destructively flipped.
+**********************************************************/
+{
+ ord_RESULT result,auxResult,AuxRl1r2,AuxRr1r2,AuxRr1l2,Comp1,Comp2;
+ BOOL pos1,pos2;
+
+ pos1 = pos2 = TRUE;
+ Comp1 = Comp2 = result = ord_UNCOMPARABLE;
+ if (symbol_Equal(term_TopSymbol(Lit1),fol_Not())) {
+ Lit1 = term_FirstArgument(Lit1);
+ pos1 = FALSE;
+ }
+ if (symbol_Equal(term_TopSymbol(Lit2),fol_Not())) {
+ Lit2 = term_FirstArgument(Lit2);
+ pos2 = FALSE;
+ }
+
+ if (fol_IsEquality(Lit1)) { /* Real equation */
+ if (fol_IsEquality(Lit2)) {
+ TERM l1,r1,l2,r2,aux;
+ l1 = term_FirstArgument(Lit1);
+ r1 = term_SecondArgument(Lit1);
+ l2 = term_FirstArgument(Lit2);
+ r2 = term_SecondArgument(Lit2);
+ if (Orient1 ||
+ (Check &&
+ ((Comp1 = ord_Compare(l1,r1,FlagStore,Precedence)) == ord_GREATER_THAN ||
+ Comp1 == ord_SMALLER_THAN))) {
+ if (Comp1 == ord_SMALLER_THAN) {
+ aux = l1; l1 = r1; r1 = aux;
+ }
+ if (Orient2 ||
+ (Check &&
+ ((Comp2 = ord_Compare(l2,r2,FlagStore,Precedence))==ord_GREATER_THAN ||
+ Comp2 == ord_SMALLER_THAN))) {
+ /* Both equations are oriented */
+ if (Comp2 == ord_SMALLER_THAN) {
+ aux = l2; l2 = r2; r2 = aux;
+ }
+ result = ord_Compare(l1,l2, FlagStore, Precedence);
+ if (result == ord_EQUAL) {
+ if (pos1) {
+ if (pos2)
+ return ord_Compare(r1,r2, FlagStore, Precedence);
+ else
+ return ord_SMALLER_THAN;
+ }
+ else
+ if (pos2)
+ return ord_GREATER_THAN;
+ else
+ return ord_Compare(r1,r2, FlagStore, Precedence);
+ }
+ return result;
+ }
+ else { /* Lit2 is not oriented equation */
+ if (term_Equal(l1,l2)) {
+ result = ord_Compare(r1,r2, FlagStore, Precedence);
+ if (result == ord_EQUAL) {
+ if (pos1 && !pos2)
+ return ord_SMALLER_THAN;
+ else
+ if (!pos1 && pos2)
+ return ord_GREATER_THAN;
+ }
+ return result;
+ }
+ if (term_Equal(l1,r2)) {
+ result = ord_Compare(r1,l2, FlagStore, Precedence);
+ if (result == ord_EQUAL) {
+ if (pos1 && !pos2)
+ return ord_SMALLER_THAN;
+ else
+ if (!pos1 && pos2)
+ return ord_GREATER_THAN;
+ }
+ return result;
+ }
+ result = ord_Compare(l1,l2, FlagStore, Precedence);
+ AuxRl1r2 = ord_Compare(l1,r2, FlagStore, Precedence);
+ if (result == AuxRl1r2)
+ return result;
+ AuxRr1r2 = ord_Compare(r1,r2, FlagStore, Precedence);
+ if (result == AuxRr1r2)
+ return result;
+ if (AuxRl1r2 == AuxRr1r2 && AuxRl1r2 == ord_SMALLER_THAN)
+ return ord_SMALLER_THAN;
+ AuxRr1l2 = ord_Compare(r1,l2, FlagStore, Precedence);
+ if (result == AuxRr1l2 && result == ord_SMALLER_THAN)
+ return ord_SMALLER_THAN;
+ return ord_UNCOMPARABLE;
+ }
+ }
+ else /* Lit1 is unorientable equation */
+ if (Orient2 ||
+ (Check &&
+ ((Comp2 = ord_Compare(term_FirstArgument(Lit2),
+ term_SecondArgument(Lit2),
+ FlagStore, Precedence) == ord_GREATER_THAN) ||
+ Comp2 == ord_SMALLER_THAN))) { /* Lit2 is orientable equation */
+ if (Comp2 == ord_SMALLER_THAN) {
+ aux = l2; l2 = r2; r2 = aux;
+ }
+ if (term_Equal(l1,l2)) {
+ result = ord_Compare(r1,r2, FlagStore, Precedence);
+ if (result == ord_EQUAL) {
+ if (pos1 && !pos2)
+ return ord_SMALLER_THAN;
+ else
+ if (!pos1 && pos2)
+ return ord_GREATER_THAN;
+ }
+ return result;
+ }
+ if (term_Equal(r1,l2)) {
+ result = ord_Compare(l1,r2, FlagStore, Precedence);
+ if (result == ord_EQUAL) {
+ if (pos1 && !pos2)
+ return ord_SMALLER_THAN;
+ else
+ if (!pos1 && pos2)
+ return ord_GREATER_THAN;
+ }
+ return result;
+ }
+
+ result = ord_Compare(l1,l2, FlagStore, Precedence);
+ AuxRr1l2 = ord_Compare(r1,l2, FlagStore, Precedence);
+ if (result == AuxRr1l2)
+ return result;
+ AuxRr1r2 = ord_Compare(r1,r2, FlagStore, Precedence);
+ if (result == AuxRr1r2)
+ return result;
+ if (AuxRr1l2 == AuxRr1r2 && AuxRr1l2 == ord_GREATER_THAN)
+ return ord_GREATER_THAN;
+ AuxRl1r2 = ord_Compare(l1,r2, FlagStore, Precedence);
+ if (result == AuxRl1r2 && result == ord_GREATER_THAN)
+ return ord_GREATER_THAN;
+ return ord_UNCOMPARABLE;
+ }
+ else { /* Both literals are unorientable equations */
+ if (term_Equal(l1,l2)) {
+ result = ord_Compare(r1,r2, FlagStore, Precedence);
+ if (result == ord_EQUAL) {
+ if (pos1 && !pos2)
+ return ord_SMALLER_THAN;
+ else if (!pos1 && pos2)
+ return ord_GREATER_THAN;
+ }
+ return result;
+ }
+ if (term_Equal(r1,l2)) {
+ result = ord_Compare(l1,r2, FlagStore, Precedence);
+ if (result == ord_EQUAL) {
+ if (pos1 && !pos2)
+ return ord_SMALLER_THAN;
+ else if (!pos1 && pos2)
+ return ord_GREATER_THAN;
+ }
+ return result;
+ }
+ if (term_Equal(l1,r2)) {
+ result = ord_Compare(r1,l2, FlagStore, Precedence);
+ if (result == ord_EQUAL) {
+ if (pos1 && !pos2)
+ return ord_SMALLER_THAN;
+ else if (!pos1 && pos2)
+ return ord_GREATER_THAN;
+ }
+ return result;
+ }
+ if (term_Equal(r1,r2)) {
+ result = ord_Compare(l1,l2, FlagStore, Precedence);
+ if (result == ord_EQUAL) {
+ if (pos1 && !pos2)
+ return ord_SMALLER_THAN;
+ else if (!pos1 && pos2)
+ return ord_GREATER_THAN;
+ }
+ return result;
+ }
+ result = ord_Compare(l1,l2, FlagStore, Precedence);
+ if (result == ord_UNCOMPARABLE) {
+ result = ord_Compare(l1,r2, FlagStore, Precedence);
+ if (result == ord_UNCOMPARABLE) {
+ if (ord_Compare(r1,l2, FlagStore, Precedence) == ord_GREATER_THAN &&
+ ord_Compare(r1,r2, FlagStore, Precedence) == ord_GREATER_THAN)
+ return ord_GREATER_THAN;
+ return ord_UNCOMPARABLE;
+ }
+ if (result == ord_GREATER_THAN) {
+ if (ord_Compare(r1,l2, FlagStore, Precedence) == ord_GREATER_THAN)
+ return ord_GREATER_THAN;
+ return ord_UNCOMPARABLE;
+ }
+ if (result == ord_SMALLER_THAN) {
+ if (ord_Compare(r1,l2, FlagStore, Precedence) == ord_SMALLER_THAN ||
+ ord_Compare(r1,r2, FlagStore, Precedence) == ord_SMALLER_THAN)
+ return ord_SMALLER_THAN;
+ return ord_UNCOMPARABLE;
+ }
+ }
+ if (result == ord_GREATER_THAN) {
+ if ((result = ord_Compare(l1,r2,FlagStore,Precedence)) == ord_GREATER_THAN ||
+ (auxResult = ord_Compare(r1,r2,FlagStore,Precedence)) == ord_GREATER_THAN)
+ return ord_GREATER_THAN;
+ if (result == ord_UNCOMPARABLE || auxResult == ord_UNCOMPARABLE)
+ return ord_UNCOMPARABLE;
+ return ord_SMALLER_THAN;
+ }
+ if (result == ord_SMALLER_THAN) {
+ if ((result = ord_Compare(r1,l2,FlagStore,Precedence)) == ord_SMALLER_THAN ||
+ (auxResult = ord_Compare(r1,r2,FlagStore,Precedence)) == ord_SMALLER_THAN)
+ return ord_SMALLER_THAN;
+ if (result == ord_UNCOMPARABLE || auxResult == ord_UNCOMPARABLE)
+ return ord_UNCOMPARABLE;
+ return ord_GREATER_THAN;
+ }
+ }
+ }
+ else {/* Second Atom is not an equation */
+ /* They can't be equal ! */
+ result = ord_Compare(term_FirstArgument(Lit1),Lit2,FlagStore,Precedence);
+ if (!Orient1 && result != ord_GREATER_THAN) {
+ auxResult = ord_Compare(term_SecondArgument(Lit1),Lit2,FlagStore,Precedence);
+ if (auxResult == ord_GREATER_THAN)
+ result = ord_GREATER_THAN;
+ else if (result != auxResult)
+ result = ord_UNCOMPARABLE;
+ }
+ }
+ }
+ else /* First Atom is not an equation */
+ /* They can't be equal ! */
+ if (fol_IsEquality(Lit2)) {
+ result = ord_Compare(Lit1,term_FirstArgument(Lit2), FlagStore, Precedence);
+ if (!Orient2 && result != ord_SMALLER_THAN) {
+ auxResult = ord_Compare(Lit1,term_SecondArgument(Lit2),FlagStore,Precedence);
+ if (auxResult == ord_SMALLER_THAN)
+ result = ord_SMALLER_THAN;
+ else if (result != auxResult)
+ result = ord_UNCOMPARABLE;
+ }
+ } else { /* None of the atoms is an equation */
+ result = ord_Compare(Lit1,Lit2, FlagStore, Precedence);
+ if (result == ord_EQUAL) {
+ if (pos1 && !pos2)
+ result = ord_SMALLER_THAN;
+ else if (!pos1 && pos2)
+ result = ord_GREATER_THAN;
+ }
+ }
+
+ return result;
+}
diff --git a/test/spass/order.h b/test/spass/order.h
new file mode 100644
index 0000000..3817576
--- /dev/null
+++ b/test/spass/order.h
@@ -0,0 +1,147 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INTERFACE FOR ALL ORDERING IMPLEMENTATIONS * */
+/* * * */
+/* * $Module: ORDER * */
+/* * * */
+/* * Copyright (C) 1997, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _ORDER_
+#define _ORDER_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "term.h"
+#include "context.h"
+#include "flags.h"
+#include "symbol.h"
+
+/**************************************************************/
+/* TYPES and GLOBAL VARIABLES */
+/**************************************************************/
+
+typedef enum { ord_UNCOMPARABLE,
+ ord_SMALLER_THAN,
+ ord_EQUAL,
+ ord_GREATER_THAN } ord_RESULT;
+
+/* This array is used to count variable occurrences in two terms. */
+/* It may be used by any available ordering. */
+extern NAT ord_VARCOUNT[symbol__MAXSTANDARDVAR][2];
+
+/* A precedence is needed in almost every ordering function. */
+/* For performance reasons it is stored in a global variable, */
+/* instead of passing it to all those functions, which are */
+/* often recursive. Nevertheless this variable must not be */
+/* set externally! */
+extern PRECEDENCE ord_PRECEDENCE;
+
+/**************************************************************/
+/* INLINE FUNCTIONS */
+/**************************************************************/
+
+static __inline__ ord_RESULT ord_Uncomparable(void)
+{
+ return ord_UNCOMPARABLE;
+}
+
+static __inline__ ord_RESULT ord_Equal(void)
+{
+ return ord_EQUAL;
+}
+
+static __inline__ ord_RESULT ord_GreaterThan(void)
+{
+ return ord_GREATER_THAN;
+}
+
+static __inline__ ord_RESULT ord_SmallerThan(void)
+{
+ return ord_SMALLER_THAN;
+}
+
+static __inline__ BOOL ord_IsGreaterThan(ord_RESULT Res)
+{
+ return ord_GREATER_THAN == Res;
+}
+
+static __inline__ BOOL ord_IsNotGreaterThan(ord_RESULT Res)
+{
+ return ord_GREATER_THAN != Res;
+}
+
+static __inline__ BOOL ord_IsSmallerThan(ord_RESULT Res)
+{
+ return ord_SMALLER_THAN == Res;
+}
+
+static __inline__ BOOL ord_IsNotSmallerThan(ord_RESULT Res)
+{
+ return ord_SMALLER_THAN != Res;
+}
+
+static __inline__ BOOL ord_IsEqual(ord_RESULT Res)
+{
+ return ord_EQUAL == Res;
+}
+
+static __inline__ BOOL ord_IsUncomparable(ord_RESULT Res)
+{
+ return ord_UNCOMPARABLE == Res;
+}
+
+
+
+/**************************************************************/
+/* FUNCTIONS */
+/**************************************************************/
+
+ord_RESULT ord_Not(ord_RESULT);
+ord_RESULT ord_Compare(TERM, TERM, FLAGSTORE, PRECEDENCE);
+ord_RESULT ord_ContCompare(CONTEXT, TERM, CONTEXT, TERM, FLAGSTORE, PRECEDENCE);
+BOOL ord_CompareEqual(TERM, TERM, FLAGSTORE);
+BOOL ord_ContGreater(CONTEXT, TERM, CONTEXT, TERM, FLAGSTORE, PRECEDENCE);
+ord_RESULT ord_LiteralCompare(TERM,BOOL,TERM,BOOL,BOOL, FLAGSTORE, PRECEDENCE);
+void ord_Print(ord_RESULT);
+
+#endif
diff --git a/test/spass/partition.c b/test/spass/partition.c
new file mode 100644
index 0000000..ac060da
--- /dev/null
+++ b/test/spass/partition.c
@@ -0,0 +1,287 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * PARTITION * */
+/* * * */
+/* * $Module: PARTITION * */
+/* * * */
+/* * Copyright (C) 1999, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/**************************************************************/
+/* Include */
+/**************************************************************/
+
+#include "partition.h"
+
+
+/**************************************************************/
+/* Inline functions */
+/**************************************************************/
+
+static __inline__ ECLASS part_GetClass(PARTITION p, ELEMENT e)
+{
+ return p[e];
+}
+
+
+static __inline__ PARTITION part_SetClass(PARTITION p, ELEMENT e, ECLASS c)
+{
+ p[e] = c;
+ return p;
+}
+
+
+static __inline__ int part_GetClassSize(PARTITION p, ELEMENT e)
+{
+ return p[p[part_CARD] + e];
+}
+
+
+static __inline__ PARTITION part_SetClassSize(PARTITION p, ELEMENT e, int
+ classsize)
+{
+ p[p[part_CARD] + e] = classsize;
+ return p;
+}
+
+
+static __inline__ int part_GetStamp(PARTITION p, ELEMENT e)
+{
+ return p[-part_HEAD - 1 - e];
+}
+
+
+static __inline__ PARTITION part_SetStamp(PARTITION p, ELEMENT e, int stamp)
+{
+ p[-part_HEAD - 1 - e] = stamp;
+ return p;
+}
+
+
+static __inline__ BOOL part_Stamped(PARTITION p, ELEMENT e)
+{
+ return part_GetStamp(p, e) == p[part_STAMPCOUNTER];
+}
+
+
+static __inline__ ELEMENT part_DelayedInit(PARTITION p, ELEMENT e)
+/***************************************************************
+ RETURNS: the (now stamped) element
+ EFFECT: establishes the equivalence class {e} in p, thus
+ partially initializing p
+***************************************************************/
+{
+ if (!part_Stamped(p, e)) {
+ part_SetClass(p, e, -e - 1); /* representative e (>= 0) of {e} is coded */
+ /* as -e - 1 (< 0) */
+ part_SetClassSize(p, e, 1);
+ part_SetStamp(p, e, p[part_STAMPCOUNTER]);
+ }
+ return e;
+}
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+PARTITION part_Create(int size)
+/****************************************************************
+ RETURNS: the initial partition {{0}, {1}, {2}, ..., {size - 1}}
+ of the set {0, 1, 2, ..., size - 1}
+****************************************************************/
+{
+ PARTITION result;
+
+#ifdef CHECK
+ if (size < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In part_Create: negative size %d.", size);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = (PARTITION) memory_Calloc(size * 3 + part_HEAD, sizeof(int))
+ + size + part_HEAD; /* move pointer to the middle of the array */
+ /* to allow negative indices */
+ result[part_CARD] = size;
+ result[part_ALLOC] = size * 3 + part_HEAD;
+ result[part_STAMPCOUNTER] = 1;
+ return result;
+}
+
+
+PARTITION part_Init(PARTITION p, int size)
+/****************************************************************
+ RETURNS: the initial partition {{0}, {1}, {2}, ..., {size - 1}}
+ of the set {0, 1, 2, ..., size - 1}
+ EFFECT: stores the initial partition to p if it's big enough,
+ otherwise creates a new partition, therefore
+ CAUTION: must be called inside an assignment like:
+ p = part_Init(p, ...)
+****************************************************************/
+{
+ int alloc, i;
+
+#ifdef CHECK
+ if (size < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In part_Init: negative size %d.", size);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ alloc = (p[part_ALLOC] - part_HEAD) / 3;
+ if (size > alloc) {
+ part_Free(p);
+ p = part_Create(size);
+ }
+ else {
+ p[part_CARD] = size;
+ p[part_STAMPCOUNTER]++;
+
+ /* if a stamp overflow occurs, reinit stamps: */
+ if (p[part_STAMPCOUNTER] <= 0) {
+ for (i = 0; i < alloc; i++)
+ part_SetStamp(p, i, 0);
+ p[part_STAMPCOUNTER] = 1;
+ }
+
+ }
+ return p;
+}
+
+
+static ELEMENT part_NF(PARTITION p, ELEMENT e)
+/***************************************************************
+ RETURNS: the normal form element of the class [e]; this is an
+ element of [e] that sometimes differ from the
+ representative
+ EFFECT: makes the normal form to the direct parent of all
+ elements visited on the search path from e to this
+ normal form ("path compression")
+***************************************************************/
+{
+ ELEMENT nf, aux;
+
+#ifdef CHECK
+ if (!part_Element(p, e)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In part_NF: %d not in partitioned set.", e);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ nf = e;
+ while (part_GetClass(p, part_DelayedInit(p, nf)) >= 0)
+ nf = part_GetClass(p, nf);
+
+ /* path compression: */
+ while (e != nf) {
+ aux = part_GetClass(p, e);
+ part_SetClass(p, e, nf);
+ e = aux;
+ }
+
+ return nf;
+}
+
+
+ECLASS part_Find(PARTITION p, ELEMENT e)
+/***************************************************************
+ RETURNS: (the representative of) class [e]
+***************************************************************/
+{
+
+#ifdef CHECK
+ if (!part_Element(p, e)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In part_Find: %d not in partitioned set.", e);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return -part_GetClass(p, part_NF(p, e)) - 1;
+ /* representative e is coded as -e - 1 (cf. part_DelayedInit) */
+}
+
+
+PARTITION part_Union(PARTITION p, ECLASS c1, ECLASS c2)
+/***************************************************************
+ RETURNS: the union of the classes
+ EFFECT: the representative of c1 is the representative of the
+ union
+***************************************************************/
+{
+ ELEMENT nf1, nf2, aux;
+
+#ifdef CHECK
+ if (!part_Element(p, c1)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In part_Union: first class %d not in partitioned set.",
+ c1);
+ misc_FinishErrorReport();
+ }
+ if (!part_Element(p, c2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport
+ ("\n In part_Union: second class %d not in partitioned set.", c2);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ nf1 = part_NF(p, c1);
+ nf2 = part_NF(p, c2);
+ if (nf1 != nf2) {
+
+ /* make [nf1] the bigger (or at least not smaller) class: */
+ if (part_GetClassSize(p, nf1) < part_GetClassSize(p, nf2)) {
+ aux = nf1;
+ nf1 = nf2;
+ nf2 = aux;
+ part_SetClass(p, nf1, part_GetClass(p, nf2));
+ part_SetClass(p, -part_GetClass(p, nf2) - 1, nf1);
+ }
+
+ part_SetClass(p, nf2, nf1);
+ part_SetClassSize(p, nf1,
+ part_GetClassSize(p, nf1) + part_GetClassSize(p, nf2));
+ }
+ return p;
+}
+
diff --git a/test/spass/partition.h b/test/spass/partition.h
new file mode 100644
index 0000000..2de3aad
--- /dev/null
+++ b/test/spass/partition.h
@@ -0,0 +1,127 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * PARTITION * */
+/* * * */
+/* * $Module: PARTITION * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* module manages partitions (i. e. sets of equivalence classes) of the set */
+/* {0, 1, 2, ..., size - 1} */
+
+#ifndef _PARTITION_
+#define _PARTITION_
+
+
+/**************************************************************/
+/* Include */
+/**************************************************************/
+
+#include "memory.h"
+
+
+/**************************************************************/
+/* Constants and types */
+/**************************************************************/
+
+#define part_CARD -1 /* index of cardinality of partitioned set */
+#define part_ALLOC -2 /* index of size of allocated space */
+#define part_STAMPCOUNTER -3 /* index of stampcounter */
+#define part_HEAD 3 /* length of head for management purposes */
+
+
+typedef int ELEMENT;
+typedef ELEMENT ECLASS, *PARTITION;
+
+/* an equivalence class is represented by one of its elements, the */
+/* _representative_; a partition is an array to hold the size of the */
+/* partitioned set and of the allocated space, the equivalence classes, */
+/* their sizes and stamps and the stampcounter: */
+/* STAMPCOUNTER ALLOC CARD */
+/* | | | */
+/* -size - 3, ..., -4, -3, -2, -1, 0, ..., size - 1, size, ..., 2 * size - 1 */
+/* <--- stamp[] ----| |--- class[] --> |---- classsize[] ----> */
+
+
+/**************************************************************/
+/* Prototypes */
+/**************************************************************/
+
+PARTITION part_Create(int);
+PARTITION part_Init(PARTITION, int);
+ECLASS part_Find(PARTITION, ELEMENT);
+ /* gets (the representative of) the class of the second argument */
+PARTITION part_Union(PARTITION, ECLASS, ECLASS);
+ /* unions the classes, the representative of the first class is the */
+ /* representative of the union */
+
+
+/**************************************************************/
+/* Inline functions */
+/**************************************************************/
+
+static __inline__ void part_Free(PARTITION p)
+{
+ if (p != NULL)
+ memory_Free(
+ p - (p[part_ALLOC] - part_HEAD) / 3 - part_HEAD,
+ p[part_ALLOC] * sizeof(int)
+ );
+}
+
+
+static __inline__ int part_Size(PARTITION p)
+{
+ return p[part_CARD];
+}
+
+
+static __inline__ BOOL part_Element(PARTITION p, ELEMENT e)
+{
+ return 0 <= e && e < part_Size(p);
+}
+
+
+static __inline__ BOOL part_Equivalent(PARTITION p, ELEMENT e1, ELEMENT e2)
+{
+ return part_Find(p, e1) == part_Find(p, e2);
+}
+
+
+#endif
+
diff --git a/test/spass/problem.dfg b/test/spass/problem.dfg
new file mode 100644
index 0000000..4527e6a
--- /dev/null
+++ b/test/spass/problem.dfg
@@ -0,0 +1,718 @@
+%--------------------------------------------------------------------------
+% File : SET505-6 : TPTP v2.2.1. Bugfixed v2.1.0.
+% Domain : Set Theory
+% Problem : Corollary 2 to universal class not set
+% Version : [Qua92] axioms.
+% English :
+
+% Refs : [BL+86] Boyer et al. (1986), Set Theory in First-Order Logic:
+% : [Qua92] Quaife (1992), Automated Deduction in von Neumann-Bern
+% Source : [Quaife]
+% Names : SP6 cor.2 [Qua92]
+
+% Status : unsatisfiable
+% Rating : 0.83 v2.2.0, 0.67 v2.1.0
+% Syntax : Number of clauses : 113 ( 8 non-Horn; 38 unit; 80 RR)
+% Number of literals : 219 ( 49 equality)
+% Maximal clause size : 5 ( 1 average)
+% Number of predicates : 11 ( 0 propositional; 1-3 arity)
+% Number of functors : 47 ( 13 constant; 0-3 arity)
+% Number of variables : 214 ( 32 singleton)
+% Maximal term depth : 6 ( 1 average)
+
+% Comments : Quaife proves all these problems by augmenting the axioms with
+% all previously proved theorems. With a few exceptions (the
+% problems that correspond to [BL+86] problems), the TPTP has
+% retained the order in which Quaife presents the problems. The
+% user may create an augmented version of this problem by adding
+% all previously proved theorems (the ones that correspond to
+% [BL+86] are easily identified and positioned using Quaife's
+% naming scheme).
+% : tptp2X -f dfg -t rm_equality:rstfp SET505-6.p
+% Bugfixes : v1.0.1 - Bugfix in SET004-1.ax.
+% : v2.1.0 - Bugfix in SET004-0.ax.
+%--------------------------------------------------------------------------
+
+begin_problem(TPTP_Problem).
+
+list_of_descriptions.
+name({*[ File : SET505-6 : TPTP v2.2.1. Bugfixed v2.1.0.],[ Names : SP6 cor.2 [Qua92]]*}).
+author({*[ Source : [Quaife]]*}).
+status(unsatisfiable).
+description({*[ Refs : [BL+86] Boyer et al. (1986), Set Theory in First-Order Logic: , : [Qua92] Quaife (1992), Automated Deduction in von Neumann-Bern]*}).
+end_of_list.
+
+list_of_symbols.
+functions[(application_function,0), (apply,2), (cantor,1), (choice,0), (complement,1), (compose,2), (compose_class,1), (composition_function,0), (cross_product,2), (diagonalise,1), (domain,3), (domain_of,1), (domain_relation,0), (element_relation,0), (first,1), (flip,1), (identity_relation,0), (image,2), (intersection,2), (inverse,1), (not_homomorphism1,3), (not_homomorphism2,3), (not_subclass_element,2), (null_class,0), (omega,0), (ordered_pair,2), (power_class,1), (range,3), (range_of,1), (regular,1), (restrict,3), (rotate,1), (second,1), (single_valued1,1), (single_valued2,1), (single_valued3,1), (singleton,1), (singleton_relation,0), (subset_relation,0), (successor,1), (successor_relation,0), (sum_class,1), (symmetric_difference,2), (union,2), (universal_class,0), (unordered_pair,2), (y,0)].
+predicates[(compatible,3), (function,1), (homomorphism,3), (inductive,1), (maps,3), (member,2), (one_to_one,1), (operation,1), (single_valued_class,1), (subclass,2)].
+end_of_list.
+
+list_of_clauses(axioms,cnf).
+
+clause(
+forall([U,X,Y],
+or( not(subclass(X,Y)),
+ not(member(U,X)),
+ member(U,Y))),
+subclass_members ).
+
+clause(
+forall([X,Y],
+or( member(not_subclass_element(X,Y),X),
+ subclass(X,Y))),
+not_subclass_members1 ).
+
+clause(
+forall([X,Y],
+or( not(member(not_subclass_element(X,Y),Y)),
+ subclass(X,Y))),
+not_subclass_members2 ).
+
+clause(
+forall([X],
+or( subclass(X,universal_class))),
+class_elements_are_sets ).
+
+clause(
+forall([X,Y],
+or( not(equal(X,Y)),
+ subclass(X,Y))),
+equal_implies_subclass1 ).
+
+clause(
+forall([X,Y],
+or( not(equal(X,Y)),
+ subclass(Y,X))),
+equal_implies_subclass2 ).
+
+clause(
+forall([X,Y],
+or( not(subclass(X,Y)),
+ not(subclass(Y,X)),
+ equal(X,Y))),
+subclass_implies_equal ).
+
+clause(
+forall([U,X,Y],
+or( not(member(U,unordered_pair(X,Y))),
+ equal(U,X),
+ equal(U,Y))),
+unordered_pair_member ).
+
+clause(
+forall([X,Y],
+or( not(member(X,universal_class)),
+ member(X,unordered_pair(X,Y)))),
+unordered_pair2 ).
+
+clause(
+forall([X,Y],
+or( not(member(Y,universal_class)),
+ member(Y,unordered_pair(X,Y)))),
+unordered_pair3 ).
+
+clause(
+forall([X,Y],
+or( member(unordered_pair(X,Y),universal_class))),
+unordered_pairs_in_universal ).
+
+clause(
+forall([X],
+or( equal(unordered_pair(X,X),singleton(X)))),
+singleton_set ).
+
+clause(
+forall([X,Y],
+or( equal(unordered_pair(singleton(X),unordered_pair(X,singleton(Y))),ordered_pair(X,Y)))),
+ordered_pair ).
+
+clause(
+forall([U,V,X,Y],
+or( not(member(ordered_pair(U,V),cross_product(X,Y))),
+ member(U,X))),
+cartesian_product1 ).
+
+clause(
+forall([U,V,X,Y],
+or( not(member(ordered_pair(U,V),cross_product(X,Y))),
+ member(V,Y))),
+cartesian_product2 ).
+
+clause(
+forall([U,V,X,Y],
+or( not(member(U,X)),
+ not(member(V,Y)),
+ member(ordered_pair(U,V),cross_product(X,Y)))),
+cartesian_product3 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(Z,cross_product(X,Y))),
+ equal(ordered_pair(first(Z),second(Z)),Z))),
+cartesian_product4 ).
+
+clause(
+or( subclass(element_relation,cross_product(universal_class,universal_class))),
+element_relation1 ).
+
+clause(
+forall([X,Y],
+or( not(member(ordered_pair(X,Y),element_relation)),
+ member(X,Y))),
+element_relation2 ).
+
+clause(
+forall([X,Y],
+or( not(member(ordered_pair(X,Y),cross_product(universal_class,universal_class))),
+ not(member(X,Y)),
+ member(ordered_pair(X,Y),element_relation))),
+element_relation3 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(Z,intersection(X,Y))),
+ member(Z,X))),
+intersection1 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(Z,intersection(X,Y))),
+ member(Z,Y))),
+intersection2 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(Z,X)),
+ not(member(Z,Y)),
+ member(Z,intersection(X,Y)))),
+intersection3 ).
+
+clause(
+forall([X,Z],
+or( not(member(Z,complement(X))),
+ not(member(Z,X)))),
+complement1 ).
+
+clause(
+forall([X,Z],
+or( not(member(Z,universal_class)),
+ member(Z,complement(X)),
+ member(Z,X))),
+complement2 ).
+
+clause(
+forall([X,Y],
+or( equal(complement(intersection(complement(X),complement(Y))),union(X,Y)))),
+union ).
+
+clause(
+forall([X,Y],
+or( equal(intersection(complement(intersection(X,Y)),complement(intersection(complement(X),complement(Y)))),symmetric_difference(X,Y)))),
+symmetric_difference ).
+
+clause(
+forall([X,Xr,Y],
+or( equal(intersection(Xr,cross_product(X,Y)),restrict(Xr,X,Y)))),
+restriction1 ).
+
+clause(
+forall([X,Xr,Y],
+or( equal(intersection(cross_product(X,Y),Xr),restrict(Xr,X,Y)))),
+restriction2 ).
+
+clause(
+forall([X,Z],
+or( not(equal(restrict(X,singleton(Z),universal_class),null_class)),
+ not(member(Z,domain_of(X))))),
+domain1 ).
+
+clause(
+forall([X,Z],
+or( not(member(Z,universal_class)),
+ equal(restrict(X,singleton(Z),universal_class),null_class),
+ member(Z,domain_of(X)))),
+domain2 ).
+
+clause(
+forall([X],
+or( subclass(rotate(X),cross_product(cross_product(universal_class,universal_class),universal_class)))),
+rotate1 ).
+
+clause(
+forall([U,V,W,X],
+or( not(member(ordered_pair(ordered_pair(U,V),W),rotate(X))),
+ member(ordered_pair(ordered_pair(V,W),U),X))),
+rotate2 ).
+
+clause(
+forall([U,V,W,X],
+or( not(member(ordered_pair(ordered_pair(V,W),U),X)),
+ not(member(ordered_pair(ordered_pair(U,V),W),cross_product(cross_product(universal_class,universal_class),universal_class))),
+ member(ordered_pair(ordered_pair(U,V),W),rotate(X)))),
+rotate3 ).
+
+clause(
+forall([X],
+or( subclass(flip(X),cross_product(cross_product(universal_class,universal_class),universal_class)))),
+flip1 ).
+
+clause(
+forall([U,V,W,X],
+or( not(member(ordered_pair(ordered_pair(U,V),W),flip(X))),
+ member(ordered_pair(ordered_pair(V,U),W),X))),
+flip2 ).
+
+clause(
+forall([U,V,W,X],
+or( not(member(ordered_pair(ordered_pair(V,U),W),X)),
+ not(member(ordered_pair(ordered_pair(U,V),W),cross_product(cross_product(universal_class,universal_class),universal_class))),
+ member(ordered_pair(ordered_pair(U,V),W),flip(X)))),
+flip3 ).
+
+clause(
+forall([Y],
+or( equal(domain_of(flip(cross_product(Y,universal_class))),inverse(Y)))),
+inverse ).
+
+clause(
+forall([Z],
+or( equal(domain_of(inverse(Z)),range_of(Z)))),
+range_of ).
+
+clause(
+forall([X,Y,Z],
+or( equal(first(not_subclass_element(restrict(Z,X,singleton(Y)),null_class)),domain(Z,X,Y)))),
+domain ).
+
+clause(
+forall([X,Y,Z],
+or( equal(second(not_subclass_element(restrict(Z,singleton(X),Y),null_class)),range(Z,X,Y)))),
+range ).
+
+clause(
+forall([X,Xr],
+or( equal(range_of(restrict(Xr,X,universal_class)),image(Xr,X)))),
+image ).
+
+clause(
+forall([X],
+or( equal(union(X,singleton(X)),successor(X)))),
+successor ).
+
+clause(
+or( subclass(successor_relation,cross_product(universal_class,universal_class))),
+successor_relation1 ).
+
+clause(
+forall([X,Y],
+or( not(member(ordered_pair(X,Y),successor_relation)),
+ equal(successor(X),Y))),
+successor_relation2 ).
+
+clause(
+forall([X,Y],
+or( not(equal(successor(X),Y)),
+ not(member(ordered_pair(X,Y),cross_product(universal_class,universal_class))),
+ member(ordered_pair(X,Y),successor_relation))),
+successor_relation3 ).
+
+clause(
+forall([X],
+or( not(inductive(X)),
+ member(null_class,X))),
+inductive1 ).
+
+clause(
+forall([X],
+or( not(inductive(X)),
+ subclass(image(successor_relation,X),X))),
+inductive2 ).
+
+clause(
+forall([X],
+or( not(member(null_class,X)),
+ not(subclass(image(successor_relation,X),X)),
+ inductive(X))),
+inductive3 ).
+
+clause(
+or( inductive(omega)),
+omega_is_inductive1 ).
+
+clause(
+forall([Y],
+or( not(inductive(Y)),
+ subclass(omega,Y))),
+omega_is_inductive2 ).
+
+clause(
+or( member(omega,universal_class)),
+omega_in_universal ).
+
+clause(
+forall([X],
+or( equal(domain_of(restrict(element_relation,universal_class,X)),sum_class(X)))),
+sum_class_definition ).
+
+clause(
+forall([X],
+or( not(member(X,universal_class)),
+ member(sum_class(X),universal_class))),
+sum_class2 ).
+
+clause(
+forall([X],
+or( equal(complement(image(element_relation,complement(X))),power_class(X)))),
+power_class_definition ).
+
+clause(
+forall([U],
+or( not(member(U,universal_class)),
+ member(power_class(U),universal_class))),
+power_class2 ).
+
+clause(
+forall([Xr,Yr],
+or( subclass(compose(Yr,Xr),cross_product(universal_class,universal_class)))),
+compose1 ).
+
+clause(
+forall([Xr,Y,Yr,Z],
+or( not(member(ordered_pair(Y,Z),compose(Yr,Xr))),
+ member(Z,image(Yr,image(Xr,singleton(Y)))))),
+compose2 ).
+
+clause(
+forall([Xr,Y,Yr,Z],
+or( not(member(Z,image(Yr,image(Xr,singleton(Y))))),
+ not(member(ordered_pair(Y,Z),cross_product(universal_class,universal_class))),
+ member(ordered_pair(Y,Z),compose(Yr,Xr)))),
+compose3 ).
+
+clause(
+forall([X],
+or( not(single_valued_class(X)),
+ subclass(compose(X,inverse(X)),identity_relation))),
+single_valued_class1 ).
+
+clause(
+forall([X],
+or( not(subclass(compose(X,inverse(X)),identity_relation)),
+ single_valued_class(X))),
+single_valued_class2 ).
+
+clause(
+forall([Xf],
+or( not(function(Xf)),
+ subclass(Xf,cross_product(universal_class,universal_class)))),
+function1 ).
+
+clause(
+forall([Xf],
+or( not(function(Xf)),
+ subclass(compose(Xf,inverse(Xf)),identity_relation))),
+function2 ).
+
+clause(
+forall([Xf],
+or( not(subclass(Xf,cross_product(universal_class,universal_class))),
+ not(subclass(compose(Xf,inverse(Xf)),identity_relation)),
+ function(Xf))),
+function3 ).
+
+clause(
+forall([X,Xf],
+or( not(function(Xf)),
+ not(member(X,universal_class)),
+ member(image(Xf,X),universal_class))),
+replacement ).
+
+clause(
+forall([X],
+or( equal(X,null_class),
+ member(regular(X),X))),
+regularity1 ).
+
+clause(
+forall([X],
+or( equal(X,null_class),
+ equal(intersection(X,regular(X)),null_class))),
+regularity2 ).
+
+clause(
+forall([Xf,Y],
+or( equal(sum_class(image(Xf,singleton(Y))),apply(Xf,Y)))),
+apply ).
+
+clause(
+or( function(choice)),
+choice1 ).
+
+clause(
+forall([Y],
+or( not(member(Y,universal_class)),
+ equal(Y,null_class),
+ member(apply(choice,Y),Y))),
+choice2 ).
+
+clause(
+forall([Xf],
+or( not(one_to_one(Xf)),
+ function(Xf))),
+one_to_one1 ).
+
+clause(
+forall([Xf],
+or( not(one_to_one(Xf)),
+ function(inverse(Xf)))),
+one_to_one2 ).
+
+clause(
+forall([Xf],
+or( not(function(inverse(Xf))),
+ not(function(Xf)),
+ one_to_one(Xf))),
+one_to_one3 ).
+
+clause(
+or( equal(intersection(cross_product(universal_class,universal_class),intersection(cross_product(universal_class,universal_class),complement(compose(complement(element_relation),inverse(element_relation))))),subset_relation)),
+subset_relation ).
+
+clause(
+or( equal(intersection(inverse(subset_relation),subset_relation),identity_relation)),
+identity_relation ).
+
+clause(
+forall([Xr],
+or( equal(complement(domain_of(intersection(Xr,identity_relation))),diagonalise(Xr)))),
+diagonalisation ).
+
+clause(
+forall([X],
+or( equal(intersection(domain_of(X),diagonalise(compose(inverse(element_relation),X))),cantor(X)))),
+cantor_class ).
+
+clause(
+forall([Xf],
+or( not(operation(Xf)),
+ function(Xf))),
+operation1 ).
+
+clause(
+forall([Xf],
+or( not(operation(Xf)),
+ equal(cross_product(domain_of(domain_of(Xf)),domain_of(domain_of(Xf))),domain_of(Xf)))),
+operation2 ).
+
+clause(
+forall([Xf],
+or( not(operation(Xf)),
+ subclass(range_of(Xf),domain_of(domain_of(Xf))))),
+operation3 ).
+
+clause(
+forall([Xf],
+or( not(function(Xf)),
+ not(equal(cross_product(domain_of(domain_of(Xf)),domain_of(domain_of(Xf))),domain_of(Xf))),
+ not(subclass(range_of(Xf),domain_of(domain_of(Xf)))),
+ operation(Xf))),
+operation4 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(compatible(Xh,Xf1,Xf2)),
+ function(Xh))),
+compatible1 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(compatible(Xh,Xf1,Xf2)),
+ equal(domain_of(domain_of(Xf1)),domain_of(Xh)))),
+compatible2 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(compatible(Xh,Xf1,Xf2)),
+ subclass(range_of(Xh),domain_of(domain_of(Xf2))))),
+compatible3 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(function(Xh)),
+ not(equal(domain_of(domain_of(Xf1)),domain_of(Xh))),
+ not(subclass(range_of(Xh),domain_of(domain_of(Xf2)))),
+ compatible(Xh,Xf1,Xf2))),
+compatible4 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(homomorphism(Xh,Xf1,Xf2)),
+ operation(Xf1))),
+homomorphism1 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(homomorphism(Xh,Xf1,Xf2)),
+ operation(Xf2))),
+homomorphism2 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(homomorphism(Xh,Xf1,Xf2)),
+ compatible(Xh,Xf1,Xf2))),
+homomorphism3 ).
+
+clause(
+forall([X,Xf1,Xf2,Xh,Y],
+or( not(homomorphism(Xh,Xf1,Xf2)),
+ not(member(ordered_pair(X,Y),domain_of(Xf1))),
+ equal(apply(Xf2,ordered_pair(apply(Xh,X),apply(Xh,Y))),apply(Xh,apply(Xf1,ordered_pair(X,Y)))))),
+homomorphism4 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(operation(Xf1)),
+ not(operation(Xf2)),
+ not(compatible(Xh,Xf1,Xf2)),
+ member(ordered_pair(not_homomorphism1(Xh,Xf1,Xf2),not_homomorphism2(Xh,Xf1,Xf2)),domain_of(Xf1)),
+ homomorphism(Xh,Xf1,Xf2))),
+homomorphism5 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(operation(Xf1)),
+ not(operation(Xf2)),
+ not(compatible(Xh,Xf1,Xf2)),
+ not(equal(apply(Xf2,ordered_pair(apply(Xh,not_homomorphism1(Xh,Xf1,Xf2)),apply(Xh,not_homomorphism2(Xh,Xf1,Xf2)))),apply(Xh,apply(Xf1,ordered_pair(not_homomorphism1(Xh,Xf1,Xf2),not_homomorphism2(Xh,Xf1,Xf2)))))),
+ homomorphism(Xh,Xf1,Xf2))),
+homomorphism6 ).
+
+clause(
+forall([X],
+or( subclass(compose_class(X),cross_product(universal_class,universal_class)))),
+compose_class_definition1 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(Y,Z),compose_class(X))),
+ equal(compose(X,Y),Z))),
+compose_class_definition2 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(Y,Z),cross_product(universal_class,universal_class))),
+ not(equal(compose(X,Y),Z)),
+ member(ordered_pair(Y,Z),compose_class(X)))),
+compose_class_definition3 ).
+
+clause(
+or( subclass(composition_function,cross_product(universal_class,cross_product(universal_class,universal_class)))),
+definition_of_composition_function1 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(X,ordered_pair(Y,Z)),composition_function)),
+ equal(compose(X,Y),Z))),
+definition_of_composition_function2 ).
+
+clause(
+forall([X,Y],
+or( not(member(ordered_pair(X,Y),cross_product(universal_class,universal_class))),
+ member(ordered_pair(X,ordered_pair(Y,compose(X,Y))),composition_function))),
+definition_of_composition_function3 ).
+
+clause(
+or( subclass(domain_relation,cross_product(universal_class,universal_class))),
+definition_of_domain_relation1 ).
+
+clause(
+forall([X,Y],
+or( not(member(ordered_pair(X,Y),domain_relation)),
+ equal(domain_of(X),Y))),
+definition_of_domain_relation2 ).
+
+clause(
+forall([X],
+or( not(member(X,universal_class)),
+ member(ordered_pair(X,domain_of(X)),domain_relation))),
+definition_of_domain_relation3 ).
+
+clause(
+forall([X],
+or( equal(first(not_subclass_element(compose(X,inverse(X)),identity_relation)),single_valued1(X)))),
+single_valued_term_defn1 ).
+
+clause(
+forall([X],
+or( equal(second(not_subclass_element(compose(X,inverse(X)),identity_relation)),single_valued2(X)))),
+single_valued_term_defn2 ).
+
+clause(
+forall([X],
+or( equal(domain(X,image(inverse(X),singleton(single_valued1(X))),single_valued2(X)),single_valued3(X)))),
+single_valued_term_defn3 ).
+
+clause(
+or( equal(intersection(complement(compose(element_relation,complement(identity_relation))),element_relation),singleton_relation)),
+compose_can_define_singleton ).
+
+clause(
+or( subclass(application_function,cross_product(universal_class,cross_product(universal_class,universal_class)))),
+application_function_defn1 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(X,ordered_pair(Y,Z)),application_function)),
+ member(Y,domain_of(X)))),
+application_function_defn2 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(X,ordered_pair(Y,Z)),application_function)),
+ equal(apply(X,Y),Z))),
+application_function_defn3 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(X,ordered_pair(Y,Z)),cross_product(universal_class,cross_product(universal_class,universal_class)))),
+ not(member(Y,domain_of(X))),
+ member(ordered_pair(X,ordered_pair(Y,apply(X,Y))),application_function))),
+application_function_defn4 ).
+
+clause(
+forall([X,Xf,Y],
+or( not(maps(Xf,X,Y)),
+ function(Xf))),
+maps1 ).
+
+clause(
+forall([X,Xf,Y],
+or( not(maps(Xf,X,Y)),
+ equal(domain_of(Xf),X))),
+maps2 ).
+
+clause(
+forall([X,Xf,Y],
+or( not(maps(Xf,X,Y)),
+ subclass(range_of(Xf),Y))),
+maps3 ).
+
+clause(
+forall([Xf,Y],
+or( not(function(Xf)),
+ not(subclass(range_of(Xf),Y)),
+ maps(Xf,domain_of(Xf),Y))),
+maps4 ).
+
+end_of_list.
+
+list_of_clauses(conjectures,cnf).
+
+clause( %(conjecture)
+or( member(ordered_pair(universal_class,y),cross_product(universal_class,universal_class))),
+prove_corollary_2_to_universal_class_not_set_1 ).
+
+end_of_list.
+
+end_problem.
+%--------------------------------------------------------------------------
diff --git a/test/spass/proofcheck.c b/test/spass/proofcheck.c
new file mode 100644
index 0000000..15010d9
--- /dev/null
+++ b/test/spass/proofcheck.c
@@ -0,0 +1,1391 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * PROOF CHECKING * */
+/* * * */
+/* * Copyright (C) 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+
+/* $RCSfile$ */
+
+#include "proofcheck.h"
+
+
+/* options */
+int pcheck_Timelimit;
+const char *pcheck_ProofFileSuffix;
+BOOL pcheck_Quiet;
+
+/* options for graph generation */
+BOOL pcheck_ClauseCg;
+BOOL pcheck_GenNamedCg, pcheck_GenRedCg;
+const char *pcheck_CgName, *pcheck_RedCgName;
+GRAPHFORMAT pcheck_GraphFormat;
+
+
+static int pcheck_MaxSplitLevel(LIST Clauses)
+/**************************************************************
+ INPUT: A list of clauses.
+ RETURNS: The maximum split level of a clause.
+***************************************************************/
+{
+ int Max;
+ int Act;
+
+ Max = 0;
+ while (!list_Empty(Clauses)) {
+ Act = clause_SplitLevel(list_Car(Clauses));
+ if (Act > Max)
+ Max = Act;
+ Clauses = list_Cdr(Clauses);
+ }
+ return Max;
+}
+
+
+static __inline__ int pcheck_MaxParentSplitLevel(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause
+ RETURNS: The max split level of the parent clauses
+***************************************************************/
+{
+ return pcheck_MaxSplitLevel(clause_ParentClauses(Clause));
+}
+
+
+static BOOL pcheck_ClauseIsFromLeftSplit(CLAUSE Clause)
+/**************************************************************
+ INPUT : A Clause
+ RETURNS: TRUE iff the clause is the left half of a split
+ CAUTION: This works also for clauses without parents, since
+ pcheck_MaxParentSplitLevel returns 0 in that case.
+***************************************************************/
+{
+ return (clause_SplitLevel(Clause) > pcheck_MaxParentSplitLevel(Clause));
+}
+
+
+static BOOL pcheck_ClauseIsFromRightSplit(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause
+ RETURNS: TRUE iff the clause is from the right half of a split
+***************************************************************/
+{
+ if (list_Empty(clause_ParentClauses(Clause)))
+ return FALSE;
+
+ return clause_IsEmptyClause(list_Car(clause_ParentClauses(Clause)));
+}
+
+static BOOL pcheck_ClauseIsFromSplit(CLAUSE Clause)
+/**************************************************************
+ INPUT : A clause
+ RETURNS: TRUE iff the clause is from a split
+***************************************************************/
+{
+ return (pcheck_ClauseIsFromRightSplit(Clause) ||
+ pcheck_ClauseIsFromLeftSplit(Clause));
+}
+
+
+static int pcheck_LabelToNumber(const char* Label)
+/**************************************************************
+ INPUT: A clause label
+ RETURNS: The label converted to a number.
+ EFFECT: If the conversion fails an error message is printed
+ and the program exits.
+***************************************************************/
+{
+ int Number;
+
+ if (!string_StringToInt(Label, FALSE, &Number)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In pcheck_LabelToNumber:");
+ misc_UserErrorReport(" Could not convert clause");
+ misc_UserErrorReport(" label %s to a number.\n", Label);
+ misc_FinishUserErrorReport();
+ }
+
+ return Number;
+}
+
+
+static int pcheck_CompareNumberAndClause(const void* Number, const void* ClausePtr)
+/**************************************************************
+ INPUT: A number and a pointer to a CLAUSE.
+ RETURNS: 1) a negative number if <number> is < number of <Clause>
+ 2) 0 if <Number> is equal to the number of <Clause>
+ 3) a positive number if <Number> is > number of <Clause>
+ EFFECT: This function is used as parameter to the bsearch function.
+***************************************************************/
+{
+ return (int)Number - clause_Number(*(const CLAUSE*)ClausePtr);
+}
+
+
+static void pcheck_ParentNumbersToPointersInVector(CLAUSE* ClauseVector, int Size)
+/**************************************************************
+ INPUT: A clause vector without duplicate clauses and the maximal
+ number of elements in the vector
+ EFFECTS: All clause parent numbers are replaced by pointers
+ to the parents.
+ CAUTION: The clause vector has to be sorted by increasing
+ clause numbers, since this function performs a binary search
+ on the vector.
+***************************************************************/
+{
+ int Position;
+ LIST NewParents, OldParents;
+ LIST ScanParents;
+ int ParentNum;
+ CLAUSE* Parent;
+
+ for (Position = 0; Position < Size; Position++) {
+ OldParents = clause_ParentClauses(ClauseVector[Position]);
+ NewParents = list_Copy(OldParents);
+
+ for (ScanParents = NewParents; !list_Empty(ScanParents); ScanParents = list_Cdr(ScanParents)) {
+ ParentNum = (int)list_Car(ScanParents);
+ /* Binary search for parent clause with number <ParentNum>. */
+ Parent = bsearch((const void*)ParentNum, ClauseVector, Size,
+ sizeof(CLAUSE), pcheck_CompareNumberAndClause);
+ if (Parent != NULL)
+ list_Rplaca(ScanParents, *Parent);
+ else {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Missing parent clause %d of clause %d.\n",
+ ParentNum, clause_Number(ClauseVector[Position]));
+ misc_FinishUserErrorReport();
+ }
+ }
+ clause_SetParentClauses(ClauseVector[Position], NewParents);
+ list_Delete(OldParents);
+ }
+}
+
+
+static LIST pcheck_ForceParentNumbersToPointersInVector(CLAUSE* ClauseVector,
+ int Size)
+/**************************************************************
+ INPUT: A clause vector, possibly with duplicates
+ RETURNS: All numbers of clauses <c> that are missing a parent clause
+ from the transitive hull of parent clauses of <c>.
+ EFFECTS: All MARKED and HIDDEN flags of the clauses are changed.
+ All parent numbers are converted to pointers, if the
+ parents exist, otherwise the parent number is deleted
+ from the list.
+ The parent literal list is changed accordingly.
+ A clause <c> is marked as HIDDEN, if any clause
+ from the transitive hull of parent clauses of <c>
+ was missing in <ClauseVector>.
+***************************************************************/
+{
+ int Position;
+ LIST NewParents, NewPLits, Parents, PLits, Missing;
+ int ParentNum, PLitNum;
+ CLAUSE *Parent, Clause;
+
+ Missing = list_Nil();
+
+ for (Position = 0; Position < Size; Position++) {
+ clause_RemoveFlag(ClauseVector[Position], MARKED);
+ clause_RemoveFlag(ClauseVector[Position], HIDDEN);
+ }
+
+ for (Position = 0; Position < Size; Position++) {
+ Clause = ClauseVector[Position];
+ if (!clause_GetFlag(Clause, MARKED)) {
+ clause_SetFlag(Clause, MARKED);
+ Parents = clause_ParentClauses(Clause);
+ PLits = clause_ParentLiterals(Clause);
+ NewParents = list_Nil();
+ NewPLits = list_Nil();
+
+ while (!list_Empty(Parents)) {
+ ParentNum = (int)list_Car(Parents);
+ PLitNum = (int)list_Car(PLits);
+ /* Binary search for parent clause with number <ParentNum>. */
+ Parent = bsearch((const void*)ParentNum, ClauseVector, Size,
+ sizeof(CLAUSE), pcheck_CompareNumberAndClause);
+ if (Parent == NULL) {
+ Missing = list_Cons((POINTER)ParentNum, Missing);
+ clause_SetFlag(Clause, HIDDEN);
+ } else {
+ if (clause_GetFlag(*Parent, HIDDEN))
+ clause_SetFlag(Clause, HIDDEN);
+ NewParents = list_Cons((POINTER)*Parent, NewParents);
+ NewPLits = list_Cons((POINTER)PLitNum, NewPLits);
+ }
+ Parents = list_Cdr(Parents);
+ PLits = list_Cdr(PLits);
+ }
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+ NewParents = list_NReverse(NewParents);
+ NewPLits = list_NReverse(NewPLits);
+ clause_SetParentClauses(Clause, NewParents);
+ clause_SetParentLiterals(Clause, NewPLits);
+ } /* if clause is not marked */
+ } /* for all clauses */
+
+ return Missing;
+}
+
+
+static int pcheck_CompareClauseNumber(const void* C1, const void* C2)
+/**************************************************************
+ INPUT : Two pointers to CLAUSEs.
+ RETURNS: 1) a negative number if the number of C1 is < number of C2.
+ 2) 0 if C1 and C2 have the same clause number
+ (that means a possible bug in SPASS)
+ 3) a positive number if number of C1 > number of C2
+ EFFECT: This function is used as parameter to the qsort function.
+************************************************************/
+{
+ return clause_Number(*(const CLAUSE*)C1) - clause_Number(*(const CLAUSE*)C2);
+}
+
+
+static LIST pcheck_ConvertParentsInList(LIST List)
+/**************************************************************
+ INPUT: A list of clauses.
+ RETURNS: The list of missing parent clause numbers from the list
+ EFFECTS: Parent numbers are converted to pointers
+***************************************************************/
+{
+ int Size, Index;
+ CLAUSE* ClauseVector;
+ LIST Missing;
+
+ Size = list_Length(List);
+ if (Size == 0)
+ return list_Nil();
+
+ /* convert list into vector for binary search */
+ ClauseVector = (CLAUSE*)memory_Malloc(sizeof(CLAUSE) * Size);
+ for (Index = 0; !list_Empty(List); List = list_Cdr(List), Index++)
+ ClauseVector[Index] = list_Car(List);
+
+ /* sort the clauses in vector by increasing clause number */
+ qsort(ClauseVector, Size, sizeof(CLAUSE), pcheck_CompareClauseNumber);
+
+ /* convert parent lists */
+ Missing = pcheck_ForceParentNumbersToPointersInVector(ClauseVector, Size);
+
+ memory_Free(ClauseVector, sizeof(CLAUSE) * Size);
+ return Missing;
+}
+
+
+LIST pcheck_ConvertParentsInSPASSProof(PROOFSEARCH Search, LIST EmptyClauses)
+/**************************************************************
+ INPUT : A proofsearch object with clauses sorted by weight
+ and an unsorted list <EmptyClauses>
+ RETURNS: The lists, where the clauses in <EmptyClauses> are
+ now sorted by weight, and parent numbers
+ in the clauses are replaced by parent pointers
+***************************************************************/
+{
+ LIST AllLists;
+ LIST Missing;
+
+ AllLists = list_Nconc(list_Copy(prfs_DocProofClauses(Search)),
+ list_Copy(EmptyClauses));
+ AllLists = list_Nconc(list_Copy(prfs_UsableClauses(Search)), AllLists);
+ AllLists = list_Nconc(list_Copy(prfs_WorkedOffClauses(Search)), AllLists);
+
+ AllLists = pcheck_ClauseNumberMergeSort(AllLists);
+ Missing = pcheck_ConvertParentsInList(AllLists);
+ list_Delete(AllLists);
+
+ return Missing;
+}
+
+
+static LIST pcheck_ParentNumbersToParents(LIST Proof)
+/**************************************************************
+ INPUT: A list of clauses, representing a proof.
+ RETURNS: The list, where parent numbers in the
+ parent list of clauses are replaced
+ by the parents (pointers).
+ CAUTION: For finding the clause corresponding to a
+ a clause number, the <Proof> list is searched
+ with binary search. This is correct only if
+ the clause numbers in <Proof> are increasing.
+************************************************************/
+{
+ LIST ScanClauses;
+ int ProofLength, Position;
+ CLAUSE* ClauseVector;
+
+ if (list_Empty(Proof))
+ return list_Nil();
+
+ /* convert list into vector for binary search */
+ ProofLength = list_Length(Proof);
+ ClauseVector = (CLAUSE*) memory_Malloc(ProofLength * sizeof(CLAUSE));
+
+ for (ScanClauses = Proof, Position = 0; !list_Empty(ScanClauses);
+ ScanClauses = list_Cdr(ScanClauses), Position++) {
+ ClauseVector[Position] = list_Car(ScanClauses);
+ }
+
+ /* sort the clauses in vector by increasing clause number */
+ qsort(ClauseVector, ProofLength, sizeof(CLAUSE), pcheck_CompareClauseNumber);
+
+ /* convert parent lists */
+ pcheck_ParentNumbersToPointersInVector(ClauseVector, ProofLength);
+
+ memory_Free(ClauseVector, ProofLength * sizeof(CLAUSE));
+
+ return Proof;
+}
+
+
+LIST pcheck_ParentPointersToParentNumbers(LIST Clauses)
+/**************************************************************
+ INPUT : A list of clauses
+ RETURNS: The list with parent pointers replaced by
+ parent numbers
+ EFFECTS: Sets marks on all clauses.
+***************************************************************/
+{
+ LIST ScanClauses;
+ LIST ScanParents;
+
+ pcheck_ClauseListRemoveFlag(Clauses, MARKED);
+
+ for (ScanClauses = Clauses; !list_Empty(ScanClauses); ScanClauses = list_Cdr(ScanClauses)) {
+ if (!clause_GetFlag(list_Car(ScanClauses), MARKED)) {
+ for (ScanParents = clause_ParentClauses(list_Car(ScanClauses)); !list_Empty(ScanParents);
+ ScanParents = list_Cdr(ScanParents))
+ list_Rplaca(ScanParents, (POINTER)clause_Number(list_Car(ScanParents)));
+ clause_SetFlag(list_Car(ScanClauses), MARKED);
+ }
+ }
+ return Clauses;
+}
+
+
+LIST pcheck_ConvertTermListToClauseList(LIST ProofRest, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A list of quintupels (lists) representing a proof,
+ a flag store, and a precedence.
+ RETURNS: The conversion of this list into the internal clause
+ structure. For each clause, the numbers of parent
+ clauses are replaced by pointers to the parents.
+***************************************************************/
+{
+ LIST Clauses;
+ LIST ProofLine;
+ TERM ClauseTerm;
+ CLAUSE Clause;
+ int Level;
+ int ClauseNumber;
+ LIST ParentLabels;
+ LIST ParentIds;
+ LIST ParentLits; /* this is a dummy list; parent lits are not yet specified in a SPASS proof */
+ RULE Origin;
+ char* ClauseLabel;
+
+ Clauses = list_Nil(); /* result */
+
+ while (!list_Empty(ProofRest)) {
+ /* break proof line into components */
+ ProofLine = list_Car(ProofRest);
+
+ ClauseLabel = list_First(ProofLine);
+ ClauseTerm = list_Second(ProofLine);
+ /* replace by NULL clause, since dfg_CreateClauseFromTerm deletes clause ! */
+ list_Rplaca(list_Cdr(ProofLine), clause_Null());
+ ParentLabels = (LIST)list_Third(ProofLine);
+ Level = (int)list_Fourth(ProofLine);
+ Origin = (RULE)list_Fifth(ProofLine);
+
+ /* Conversion */
+ Clause = dfg_CreateClauseFromTerm(ClauseTerm, TRUE, Flags,Precedence);
+ /* It's necessary to update the weight since dfg_CreateClauseFromTerm */
+ /* doesn't set it. */
+ clause_UpdateWeight(Clause, Flags);
+ ClauseNumber = pcheck_LabelToNumber(ClauseLabel);
+ ParentIds = list_Nil();
+ ParentLits = list_Nil();
+
+ while (!list_Empty(ParentLabels)) {
+ ParentIds = list_Cons((POINTER)pcheck_LabelToNumber(list_Car(ParentLabels)), ParentIds);
+ ParentLits = list_Cons(0, ParentLits);
+ ParentLabels = list_Cdr(ParentLabels);
+ }
+
+ /* set all data */
+ clause_SetNumber(Clause, ClauseNumber);
+ ParentIds = list_NReverse(ParentIds);
+ clause_SetParentClauses(Clause, ParentIds);
+ clause_SetParentLiterals(Clause, ParentLits);
+ Clause->origin = Origin;
+
+ clause_SetSplitLevel(Clause, Level);
+ if (Level > 0) {
+ clause_ClearSplitField(Clause);
+ clause_SetSplitFieldBit(Clause, Level);
+ } else
+ clause_SetSplitField(Clause, (SPLITFIELD)NULL,0);
+
+ clause_RemoveFlag(Clause, MARKED);
+ Clauses = list_Cons(Clause, Clauses);
+ ProofRest = list_Cdr(ProofRest);
+ }
+ Clauses = list_NReverse(Clauses);
+
+ /* convert parent numbers to pointers */
+ Clauses = pcheck_ParentNumbersToParents(Clauses);
+
+ return Clauses;
+}
+
+
+static BOOL pcheck_ClauseIsUnmarked(CLAUSE C)
+/**************************************************************
+ INPUT: A clause
+ RETURNS: The value of the clauses MARKED flag
+***************************************************************/
+{
+ return !clause_GetFlag(C, MARKED);
+}
+
+
+static void pcheck_RemoveUnmarkedFromTableau(TABLEAU T)
+/**************************************************************
+ INPUT: A tableau
+ RETURNS: Nothing.
+ EFFECTS: Delete all clauses that have the MARKED flag
+ set from tableau.
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return;
+
+ tab_SetClauses(T, list_DeleteElementIf(tab_Clauses(T),
+ (BOOL (*)(POINTER))pcheck_ClauseIsUnmarked));
+
+ pcheck_RemoveUnmarkedFromTableau(tab_LeftBranch(T));
+ pcheck_RemoveUnmarkedFromTableau(tab_RightBranch(T));
+}
+
+
+static void pcheck_CollectUnmarkedSplits(TABLEAU T, LIST* Splits)
+/**************************************************************
+ INPUT: A tableau, a list of clauses by reference
+ RETURNS: Nothing.
+ EFFECTS: Add all split clauses in the tableau that are not
+ marked to the <Splits> list.
+***************************************************************/
+{
+ LIST Scan;
+
+ if (tab_IsEmpty(T))
+ return;
+
+ for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (!clause_GetFlag(list_Car(Scan), MARKED) && clause_IsFromSplitting(list_Car(Scan)))
+ (*Splits) = list_Cons(list_Car(Scan), *Splits);
+ }
+
+ pcheck_CollectUnmarkedSplits(tab_LeftBranch(T), Splits);
+ pcheck_CollectUnmarkedSplits(tab_RightBranch(T), Splits);
+}
+
+
+/* EK: unused, only recursive */
+static void pcheck_TableauSplitsComplete(TABLEAU T)
+/**************************************************************
+ INPUT : A tableau
+ RETURNS: Checks that every split has exactly two or no
+ successors. This condition must be true after
+ tab_RemoveRedundantSplits has been called.
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return;
+
+ if (tab_RightBranchIsEmpty(T) && !tab_LeftBranchIsEmpty(T)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Split of clause %d has no right branch.\n",
+ clause_Number(tab_SplitClause(T)));
+ misc_FinishUserErrorReport();
+ }
+
+ if (!tab_RightBranchIsEmpty(T) && tab_LeftBranchIsEmpty(T)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Split of clause %d has no left branch.\n",
+ clause_Number(tab_SplitClause(T)));
+ misc_FinishUserErrorReport();
+ }
+
+ pcheck_TableauSplitsComplete(tab_LeftBranch(T));
+ pcheck_TableauSplitsComplete(tab_RightBranch(T));
+}
+
+
+static void pcheck_RightSplitParents(CLAUSE SplitClause, CLAUSE RightSplitClause,
+ CLAUSE LeftSplitClause)
+/**************************************************************
+ INPUT: A split clause, and its left and right successors
+ EFFECTS: Prints an error message if the split is not correctly
+ closed.
+***************************************************************/
+{
+ LIST Scan;
+ BOOL HasEmpty, ContainsSplitClause;
+
+ HasEmpty = ContainsSplitClause = FALSE;
+
+ for (Scan = clause_ParentClauses(RightSplitClause);
+ !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (clause_IsEmptyClause(list_Car(Scan)))
+ HasEmpty = TRUE;
+ if (clause_Number(list_Car(Scan)) == clause_Number(SplitClause))
+ ContainsSplitClause = TRUE;
+ }
+
+ if (!HasEmpty) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Right split clause %d has no empty clause as parent.\n",
+ clause_Number(SplitClause));
+ misc_FinishUserErrorReport();
+ }
+
+ if (!ContainsSplitClause) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Right split clause %d", clause_Number(SplitClause));
+ misc_UserErrorReport(" does not have its split parent as parent clause.\n");
+ misc_FinishUserErrorReport();
+ }
+}
+
+
+
+/* EK: unused, only recursive */
+static void pcheck_SplitFormats(TABLEAU T)
+/**************************************************************
+ INPUT : A tableau
+ RETURNS: TRUE iff all splits:
+ - have generated negations of the left split clause
+ if the left split clause is ground
+ - the conditions for right split clauses are
+ as demanded in pcheck_RightSplitParents
+***************************************************************/
+{
+ LIST Scan;
+
+ if (tab_IsEmpty(T))
+ return;
+
+ /* for right splits, check that parents have an empty clause */
+ /* and the split clause as a parent */
+
+ for (Scan = tab_RightSplitClauses(T); !list_Empty(Scan);
+ Scan = list_Cdr(Scan)) {
+ pcheck_RightSplitParents(tab_SplitClause(T), list_Car(Scan),
+ tab_LeftSplitClause(T));
+ }
+
+ pcheck_SplitFormats(tab_RightBranch(T));
+ pcheck_SplitFormats(tab_LeftBranch(T));
+}
+
+
+static void pcheck_SplitLevels(TABLEAU T)
+/**************************************************************
+ INPUT : A Tableau
+ RETURNS: TRUE iff all clauses in the tableau that
+ are not splitting clauses have the max split
+ level of their parents.
+ CAUTION: We assume that <T> has correct and complete split
+ entries. See pcheck_SplitToProblems.
+***************************************************************/
+{
+ LIST Scan;
+ CLAUSE Clause;
+ int CorrectLevel;
+
+ if (tab_IsEmpty(T))
+ return;
+
+ /* check split levels */
+ for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Clause = list_Car(Scan);
+ if (!list_Empty(clause_ParentClauses(Clause))
+ && !clause_IsFromSplitting(Clause)) {
+
+ CorrectLevel = pcheck_MaxParentSplitLevel(Clause);
+ if (clause_SplitLevel(Clause) != CorrectLevel) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Split level of clause %d should be %d.\n",
+ clause_Number(Clause), CorrectLevel);
+ misc_FinishUserErrorReport();
+ }
+ }
+ }
+
+ pcheck_SplitLevels(tab_RightBranch(T));
+ pcheck_SplitLevels(tab_LeftBranch(T));
+}
+
+
+/* EK: unused, only recursive */
+static void pcheck_SplitPrecheck(TABLEAU T)
+/**************************************************************
+ INPUT : A tableau.
+ EFFECTS: Stops and prints an error message if a left half
+ of a split does not subsume its parents, or
+ if negations have been generated for a non-ground
+ left split clause.
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return;
+
+ if (!subs_Subsumes(tab_LeftSplitClause(T), tab_SplitClause(T), -1, -1)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Incorrect split of %d,", tab_SplitClause(T));
+ misc_UserErrorReport(" left half of split does not subsume splitted clause.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ if (list_Length(tab_RightSplitClauses(T)) > 1 &&
+ !clause_IsGround(tab_LeftSplitClause(T))) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Incorrect split of %d,", tab_SplitClause(T));
+ misc_UserErrorReport(" non-ground split generated more than two clause.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ pcheck_SplitPrecheck(tab_LeftBranch(T));
+ pcheck_SplitPrecheck(tab_RightBranch(T));
+}
+
+
+BOOL pcheck_BuildTableauFromProof(LIST Proof, TABLEAU* Tableau)
+/**************************************************************
+ INPUT : A list of clauses representing a proof, and a pointer
+ to a tableau used as return value.
+ RETURNS: TRUE iff no errors occurred, FALSE otherwise.
+ If TRUE is returned <Tableau> is set to a tableau
+ representing the proof.
+ EFFECTS: Errors are commented when they occur.
+***************************************************************/
+{
+ LIST ProofRest;
+ TABLEAU SplitPos;
+ TABPATH Path;
+ CLAUSE Clause;
+ int ClauseLevel, SplitLevel;
+ int ProofDepth;
+
+ if (list_Empty(Proof)) {
+ *Tableau = tab_EmptyTableau();
+ return TRUE;
+ }
+
+ ProofDepth = pcheck_MaxSplitLevel(Proof);
+ *Tableau = tab_CreateNode();
+ Path = tab_PathCreate(ProofDepth, *Tableau);
+
+ ProofRest = Proof;
+ while (!list_Empty(ProofRest)) {
+
+ SplitLevel = tab_PathLength(Path);
+ Clause = list_Car(ProofRest);
+ ClauseLevel = clause_SplitLevel(Clause);
+
+ /* Special treatment for clauses that result from a splitting step */
+ if (pcheck_ClauseIsFromSplit(Clause)) {
+
+ if (ClauseLevel == 0) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Split level of split clause %d is 0.\n", clause_Number(Clause));
+ misc_FinishUserErrorReport();
+ }
+
+ if (ClauseLevel > SplitLevel+1) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Split level of split clause %d", clause_Number(Clause));
+ misc_UserErrorReport(" is not increment of current split level.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ SplitPos = tab_PathNthNode(Path, ClauseLevel-1);
+
+ if (pcheck_ClauseIsFromLeftSplit(Clause)) {
+ /* Left branch of a splitting step */
+ if (!tab_LeftBranchIsEmpty(SplitPos)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Multiple left splits for clause %d.\n",
+ clause_Number(tab_SplitClause(SplitPos)));
+ misc_FinishUserErrorReport();
+ }
+
+ Path = tab_PathPrefix(ClauseLevel-1, Path);
+ tab_SetSplitClause(SplitPos, list_Car(clause_ParentClauses(Clause)));
+ tab_SetLeftSplitClause(SplitPos, Clause);
+ tab_AddSplitAtCursor(Path, TRUE);
+ } else {
+ /* Right branch of a splitting step */
+ if (tab_RightBranchIsEmpty(SplitPos)) {
+
+ if (tab_LeftBranchIsEmpty(SplitPos)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Right split with incorrect split level, clause %d.\n",
+ clause_Number(Clause));
+ misc_FinishUserErrorReport();
+ }
+
+ Path = tab_PathPrefix(ClauseLevel-1, Path);
+ tab_AddSplitAtCursor(Path, FALSE);
+ }
+ tab_AddRightSplitClause(SplitPos, Clause);
+ } /* clause from right split */
+ } /* clause from split */
+
+ if (ClauseLevel > tab_PathLength(Path)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Split level of clause %d greater than current level.\n",
+ clause_Number(Clause));
+ misc_FinishUserErrorReport();
+ }
+ tab_AddClauseOnItsLevel(Clause, Path);
+
+ ProofRest = list_Cdr(ProofRest);
+ } /* while proof is not empty */
+
+
+ tab_PathDelete(Path);
+
+ return TRUE;
+}
+
+
+static BOOL pcheck_TableauJustificationsRec(TABLEAU T, TABPATH Path)
+/**************************************************************
+ INPUT : A Tableau <T>, a <Path> in the tableau
+ RETURNS: TRUE iff all clauses in the last node of the
+ path are correctly justified.
+***************************************************************/
+{
+ CLAUSE Clause;
+ LIST ScanClauses;
+ LIST ScanParents;
+ LIST Parents;
+ CLAUSE Parent;
+ BOOL Ok, RightSplit;
+
+ if (tab_IsEmpty(T))
+ return TRUE;
+
+ Ok = TRUE;
+
+ /* for each clause, check that its parents have been justified */
+
+ for (ScanClauses = tab_Clauses(tab_PathTop(Path));
+ !list_Empty(ScanClauses); ScanClauses = list_Cdr(ScanClauses)) {
+
+ Clause = list_Car(ScanClauses);
+ Parents = clause_ParentClauses(Clause);
+
+ RightSplit = pcheck_ClauseIsFromRightSplit(Clause);
+
+ /* check all parents */
+
+ for (ScanParents = Parents; !list_Empty(ScanParents);
+ ScanParents = list_Cdr(ScanParents)) {
+
+ Parent = list_Car(ScanParents);
+
+ if ((!(RightSplit && clause_IsEmptyClause(Parent)) &&
+ !(RightSplit && pcheck_ClauseIsFromLeftSplit(Parent))) ||
+ (clause_Number(Parent) > clause_Number(Clause)) ) {
+ if (!tab_PathContainsClause(Path, Parent)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Parent clause with number %d is not yet justified.\n",
+ clause_Number(Parent));
+ misc_FinishUserErrorReport();
+ }
+ }
+ }
+ } /* for all clauses in current node */
+
+
+ /* Recursion */
+
+ if (!tab_LeftBranchIsEmpty(T)) {
+ Path = tab_PathPush(tab_LeftBranch(T), Path);
+ Ok = Ok && pcheck_TableauJustificationsRec(tab_LeftBranch(T), Path);
+ Path = tab_PathPop(Path);
+ }
+
+ if (!tab_RightBranchIsEmpty(T)) {
+ Path = tab_PathPush(tab_RightBranch(T), Path);
+ Ok = Ok && pcheck_TableauJustificationsRec(tab_RightBranch(T), Path);
+ Path = tab_PathPop(Path);
+ }
+
+ return Ok;
+}
+
+static BOOL pcheck_TableauJustifications(TABLEAU T)
+/**************************************************************
+ INPUT : A Tableau
+ RETURNS: TRUE iff for each clause in tableau, all its parent
+ clauses have been derived in a split on the same level
+ or below.
+***************************************************************/
+{
+ TABPATH Path;
+ BOOL Ok;
+
+ Path = tab_PathCreate(tab_Depth(T),T);
+ Ok = pcheck_TableauJustificationsRec(T,Path);
+ tab_PathDelete(Path);
+
+ return Ok;
+}
+
+BOOL pcheck_TableauProof(TABLEAU* Tableau, LIST Proof)
+/**************************************************************
+ INPUT:
+ RETURNS:
+***************************************************************/
+{
+ LIST RedundantClauses;
+ LIST EmptyClauses;
+ LIST UnmarkedSplits;
+
+ tab_LabelNodes(*Tableau);
+ /* print out current tableau */
+ if (pcheck_GenNamedCg)
+ tab_WriteTableau(*Tableau, pcheck_CgName, pcheck_GraphFormat);
+
+ RedundantClauses = list_Nil();
+ if (!pcheck_Quiet) {
+ fputs("pruning closed branches...", stdout);
+ fflush(stdout);
+ }
+ (*Tableau) = tab_PruneClosedBranches(*Tableau, &RedundantClauses); /* delete descendants of already closed branches */
+ if (!pcheck_Quiet)
+ puts("finished.");
+
+ if (!pcheck_Quiet) {
+ fputs("removing incomplete splits...", stdout);
+ fflush(stdout);
+ }
+ (*Tableau) = tab_RemoveIncompleteSplits(*Tableau, &RedundantClauses); /* reduce open node redundancies */
+ if (!pcheck_Quiet)
+ puts("finished.");
+
+ list_Delete(RedundantClauses);
+
+ /* remove all clauses that are not needed for the empty clauses */
+ /* of the proof or for the tableau structure (splits) */
+
+ EmptyClauses = list_Nil();
+ tab_GetEarliestEmptyClauses(*Tableau, &EmptyClauses);
+ pcheck_ClauseListRemoveFlag(Proof, MARKED);
+ pcheck_MarkRecursive(EmptyClauses);
+ UnmarkedSplits = list_Nil();
+ pcheck_CollectUnmarkedSplits(*Tableau, &UnmarkedSplits);
+ pcheck_MarkRecursive(UnmarkedSplits);
+ pcheck_RemoveUnmarkedFromTableau(*Tableau);
+ list_Delete(UnmarkedSplits);
+ list_Delete(EmptyClauses);
+
+ /* print reduced graph */
+ if (pcheck_GenRedCg)
+ tab_WriteTableau(*Tableau, pcheck_RedCgName, pcheck_GraphFormat);
+
+ tab_SetSplitLevels(*Tableau);
+ pcheck_SplitLevels(*Tableau);
+ tab_CheckEmpties(*Tableau);
+
+ if (!tab_IsClosed(*Tableau)) {
+ puts("\nerror: tableau is not closed.");
+ return FALSE;
+ }
+
+ /* check justifications */
+ if (!pcheck_Quiet) {
+ fputs("checking justifications...", stdout);
+ fflush(stdout);
+ }
+ if (!pcheck_TableauJustifications(*Tableau))
+ return FALSE;
+ if (!pcheck_Quiet)
+ puts("finished.");
+
+ return TRUE;
+}
+
+
+void pcheck_MarkRecursive(LIST Clauses)
+/**************************************************************
+ INPUT: A list of clauses
+ RETURNS: Nothing.
+ EFFECTS: Marks all <Clauses> and its ancestors with the
+ MARKED clause flag.
+***************************************************************/
+{
+ CLAUSE Clause;
+
+ for (; !list_Empty(Clauses); Clauses = list_Cdr(Clauses)) {
+ Clause = list_Car(Clauses);
+ if (!clause_GetFlag(Clause, MARKED)) {
+ pcheck_MarkRecursive(clause_ParentClauses(Clause));
+ clause_SetFlag(Clause, MARKED);
+ }
+ }
+}
+
+
+static LIST pcheck_CollectTermVariables(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: A list of terms. For each variable in <Term> the list
+ contains exactly one term representing the variable.
+ EFFECT: Memory is allocated for the terms.
+***************************************************************/
+{
+ LIST Result, Scan;
+
+ Result = term_VariableSymbols(Term);
+ for (Scan = Result; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ list_Rplaca(Scan, term_Create((SYMBOL)list_Car(Scan), list_Nil()));
+
+ return Result;
+}
+
+
+static BOOL pcheck_IsRightSplitHalf(CLAUSE C)
+/**************************************************************
+ INPUT : A clause.
+ RETURNS: TRUE iff the following conditions are fulfilled:
+ - the first parent clause is an empty clause
+ - the clause subsumes its second parent
+***************************************************************/
+{
+ LIST Parents;
+ BOOL Ok;
+
+ Parents = list_Copy(clause_ParentClauses(C));
+ Parents = list_PointerDeleteDuplicates(Parents);
+
+ Ok = FALSE;
+ if (list_Length(Parents) == 2 && clause_IsEmptyClause(list_First(Parents)))
+ Ok = subs_Subsumes(C, list_Second(Parents), -1, -1);
+
+ list_Delete(Parents);
+
+ return Ok;
+}
+
+
+static TERM pcheck_UnivClosure(TERM T)
+/**************************************************************
+ INPUT: A term, representing a formula.
+ RETURNS: The universal closure of the term.
+ EFFECTS: <T> is part of the returned term!
+***************************************************************/
+{
+ LIST Vars;
+
+ Vars = pcheck_CollectTermVariables(T);
+
+ if (list_Empty(Vars))
+ return T;
+ return fol_CreateQuantifier(fol_All(), Vars, list_List(T));
+}
+
+
+static TERM pcheck_ClauseToTerm(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: The clause represented as a TERM.
+***************************************************************/
+{
+ int LitScan;
+ LIST Args;
+ TERM Lit;
+ TERM ClauseTerm;
+
+ Args = list_Nil();
+
+ for (LitScan = clause_FirstLitIndex(); LitScan <= clause_LastLitIndex(Clause);
+ LitScan++) {
+ Lit = clause_LiteralSignedAtom(clause_GetLiteral(Clause, LitScan));
+ Args = list_Cons(term_Copy(Lit), Args);
+ }
+
+ if (list_Empty(Args))
+ Args = list_List(term_Create(fol_False(), list_Nil()));
+
+ /* Build the disjunction of the literals */
+ if (list_Empty(list_Cdr(Args))) { /* only one arg */
+ ClauseTerm = list_Car(Args);
+ list_Delete(Args);
+ } else
+ ClauseTerm = term_Create(fol_Or(), Args);
+ ClauseTerm = pcheck_UnivClosure(ClauseTerm);
+
+ return ClauseTerm;
+}
+
+
+static LIST pcheck_ClauseListToTermList(LIST Clauses)
+/**************************************************************
+ INPUT : A list of clauses.
+ RETURNS: A new list containing the clauses represented as TERMs.
+***************************************************************/
+{
+ LIST Terms;
+
+ Terms = list_Nil();
+ for (; !list_Empty(Clauses); Clauses = list_Cdr(Clauses))
+ Terms = list_Cons(pcheck_ClauseToTerm(list_Car(Clauses)), Terms);
+
+ return Terms;
+}
+
+
+static void pcheck_SaveNumberedDFGProblem(int Number, LIST Axioms,
+ LIST Conjectures,
+ const char* ProofFileName,
+ const char* DestPrefix)
+/**************************************************************
+ INPUT : A (clause) number, a list of axioms and conjectures,
+ and a filename (of the proof file of the currently
+ checked proof)
+ RETURNS: Nothing.
+ EFFECTS: Saves a DFG file containing <Axioms> and <Conjectures>
+ under the name "<DestPrefix><Number>_<ProofFileName>"
+***************************************************************/
+{
+ char *Filename, *Tmp, *NumStr;
+ FILE *File;
+
+ NumStr = string_IntToString(Number);
+ Tmp = pcheck_GenericFilename(ProofFileName, NumStr);
+ Filename = string_Conc(DestPrefix, Tmp);
+
+ File = misc_OpenFile(Filename, "w");
+ fol_FPrintDFGProblem(File, "{*Sub Proof*}", "{* Proof Checker *}",
+ "unsatisfiable",
+ "{* The problem is the correctness test for a single proof line *}",
+ Axioms, Conjectures);
+ misc_CloseFile(File, Filename);
+
+ string_StringFree(NumStr);
+ string_StringFree(Tmp);
+ string_StringFree(Filename);
+}
+
+
+static void pcheck_SplitToProblems(TABLEAU T, const char* ProofFileName,
+ const char* DestPrefix)
+/**************************************************************
+ INPUT: A tableau, which isn't a leaf of the tableau tree,
+ the name of a proof file and a file name prefix used for
+ generating files.
+ RETURNS: Nothing.
+ EFFECT: This function generates proof check tasks for clauses
+ resulting from splitting steps and writes them to
+ output files.
+ CAUTION: We assume that we get non-null clauses when calling
+ tab_SplitClause and tab_LeftSplitClause.
+***************************************************************/
+{
+ TERM SplitClauseTerm, LeftClauseTerm, RightClauseTerm;
+ TERM Equiv, Disj, Tmp;
+ LIST Conj, Args, Negations;
+
+#ifdef CHECK
+ if (tab_IsLeaf(T)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In pcheck_SplitToProblems: Tableau is a leaf of the ");
+ misc_ErrorReport("tableau tree.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ SplitClauseTerm = pcheck_ClauseToTerm(tab_SplitClause(T));
+ LeftClauseTerm = pcheck_ClauseToTerm(tab_LeftSplitClause(T));
+
+ /* by default, take all right split clauses as negations */
+ /* if the first clause is the second half of a split clause, */
+ /* take only the rest of the right split clauses as negations. */
+
+ Negations = tab_RightSplitClauses(T);
+ if (!list_Empty(Negations) && pcheck_IsRightSplitHalf(list_Car(Negations))) {
+ /* EK: Meiner Meinung nach ist es eine Invariante, daß die erste */
+ /* Elternklausel die rechte Hälfte eines Splittings ist??? */
+ Negations = list_Cdr(Negations);
+ /* build C <=> C' v C'' */
+ RightClauseTerm = pcheck_ClauseToTerm(list_Car(tab_RightSplitClauses(T)));
+ Disj = term_Create(fol_Or(), list_Cons(LeftClauseTerm, list_List(RightClauseTerm)));
+ Equiv = term_Create(fol_Equiv(), list_Cons(SplitClauseTerm, list_List(Disj)));
+ Conj = list_List(Equiv);
+
+ pcheck_SaveNumberedDFGProblem(clause_Number(tab_LeftSplitClause(T)),
+ list_Nil(), Conj, ProofFileName, DestPrefix);
+ term_DeleteTermList(Conj);
+ }
+
+ Args = list_Nil();
+
+ /* build conjunction of negations, if there are any. */
+ if (!list_Empty(Negations)) {
+ LeftClauseTerm = pcheck_ClauseToTerm(tab_LeftSplitClause(T));
+ Args = pcheck_ClauseListToTermList(Negations);
+ /* Build the conjunction */
+ if (list_Empty(list_Cdr(Args))) { /* only one arg */
+ Tmp = list_Car(Args);
+ list_Delete(Args);
+ } else
+ Tmp = term_Create(fol_And(), Args);
+ Tmp = term_Create(fol_Not(), list_List(Tmp));
+ Equiv = term_Create(fol_Implies(),list_Cons(Tmp,list_List(LeftClauseTerm)));
+ Conj = list_List(Equiv);
+
+ /* problem id is number of right part of split clause, if it exists,
+ number of first negation otherwise */
+ pcheck_SaveNumberedDFGProblem(clause_Number(list_Car(tab_RightSplitClauses(T))),
+ list_Nil(), Conj, ProofFileName, DestPrefix);
+ term_DeleteTermList(Conj);
+ }
+}
+
+
+void pcheck_TableauToProofTask(TABLEAU T, const char* ProofFileName,
+ const char* DestPrefix)
+/**************************************************************
+ INPUT: A Tableau, two strings for filename generation.
+ RETURNS: Nothing.
+ EFFECTS: Generates DFG problem files for each clause in the tableau.
+ The problem asserts that the clause follows from
+ its parents. For splits, see pcheck_SplitToProblems
+***************************************************************/
+{
+ LIST Scan;
+ LIST Axioms, Conj, Help;
+ CLAUSE Clause;
+
+ if (tab_IsEmpty(T))
+ return;
+
+ /* treat the splitting clauses at inner nodes of the tableau tree */
+ if (!tab_IsLeaf(T))
+ pcheck_SplitToProblems(T, ProofFileName, DestPrefix);
+
+ /* treat derived clauses that don't result from splitting */
+ for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Clause = list_Car(Scan);
+ if (!clause_IsFromSplitting(Clause) &&
+ !list_Empty(clause_ParentClauses(Clause))) {
+ Axioms = list_Copy(clause_ParentClauses(Clause));
+ Axioms = list_PointerDeleteDuplicates(Axioms);
+ Help = Axioms;
+ Axioms = pcheck_ClauseListToTermList(Axioms);
+ list_Delete(Help);
+ Conj = list_List(pcheck_ClauseToTerm(Clause));
+ pcheck_SaveNumberedDFGProblem(clause_Number(Clause), Axioms, Conj,
+ ProofFileName, DestPrefix);
+ term_DeleteTermList(Axioms);
+ term_DeleteTermList(Conj);
+ }
+ }
+
+ /* recursion */
+ pcheck_TableauToProofTask(tab_RightBranch(T), ProofFileName, DestPrefix);
+ pcheck_TableauToProofTask(tab_LeftBranch(T), ProofFileName, DestPrefix);
+}
+
+
+int pcheck_SeqProofDepth(LIST Proof)
+/**************************************************************
+ INPUT : A sequential proof (list of clauses)
+ RETURNS: The maximum clause depth in the proof
+***************************************************************/
+{
+ int Max;
+
+ Max = 0;
+ for ( ; !list_Empty(Proof); Proof = list_Cdr(Proof))
+ if (clause_Depth(list_Car(Proof)) > Max)
+ Max = clause_Depth(list_Car(Proof));
+
+ return Max;
+}
+
+
+LIST pcheck_ReduceSPASSProof(LIST Proof)
+/**************************************************************
+ INPUT: A list of clauses representing a SPASS proof.
+ Parents are pointers.
+ RETURNS: A list of clauses were incomplete splits
+ and closed branches with descendants have been
+ removed.
+***************************************************************/
+{
+ LIST EmptyClauses, RedundantClauses;
+ LIST ReducedProof;
+ TABLEAU Tableau;
+ LIST UnmarkedSplits;
+
+ if (!pcheck_BuildTableauFromProof(Proof, &Tableau)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Proof could not be translated into a closed tableau.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ RedundantClauses = list_Nil();
+ Tableau = tab_PruneClosedBranches(Tableau, &RedundantClauses);
+ Tableau = tab_RemoveIncompleteSplits(Tableau, &RedundantClauses);
+ list_Delete(RedundantClauses);
+
+ tab_SetSplitLevels(Tableau);
+
+ /*
+ * get minimal proof: First find earliest derived empty clauses,
+ * then recursively mark ancestors of these clauses. Put
+ * only marked clauses in <ReducedProof>.
+ */
+
+ EmptyClauses = list_Nil();
+ tab_GetEarliestEmptyClauses(Tableau, &EmptyClauses);
+ pcheck_ClauseListRemoveFlag(Proof, MARKED);
+ pcheck_MarkRecursive(EmptyClauses);
+ UnmarkedSplits = list_Nil();
+ pcheck_CollectUnmarkedSplits(Tableau, &UnmarkedSplits);
+ pcheck_MarkRecursive(UnmarkedSplits);
+ pcheck_RemoveUnmarkedFromTableau(Tableau);
+ list_Delete(UnmarkedSplits);
+
+ ReducedProof = list_Nil();
+ tab_ToClauseList(Tableau, &ReducedProof);
+ ReducedProof = pcheck_ClauseNumberMergeSort(ReducedProof);
+
+ tab_Delete(Tableau);
+ list_Delete(EmptyClauses);
+
+ return ReducedProof;
+}
+
+
+void pcheck_DeleteProof(LIST Proof)
+/**************************************************************
+ INPUT: A Proof
+ RETURNS: Nothing.
+ EFFECTS: Frees memory associated with proof
+**************************************************************/
+{
+ LIST Line, Scan2, Scan1;
+
+ Scan1 = Proof;
+ while (!list_Empty(Scan1)) {
+ Line = list_Car(Scan1);
+
+ string_StringFree(list_Car(Line));
+ if (list_Second(Line) != clause_Null()) /* clause */
+ term_Delete(list_Second(Line));
+
+ /* delete labels in justification list and list itself */
+
+ for (Scan2 = list_Third(Line); !list_Empty(Scan2); Scan2 = list_Cdr(Scan2))
+ string_StringFree(list_Car(Scan2));
+ list_Delete(list_Third(Line));
+
+ /* now contents of line are deleted. Delete line. */
+ list_Delete(Line);
+ Scan1 = list_Cdr(Scan1);
+ }
+ list_Delete(Proof);
+}
+
+
+char* pcheck_GenericFilename(const char* Filename, const char* Id)
+/**************************************************************
+ INPUT: Two strings.
+ RETURNS: A string with Suffix as new extension to Filename
+ (Filename = name.ext -> name_<Id>.prf)
+ EFFECTS: Memory is allocated for the returned string.
+**************************************************************/
+{
+ char *Help1, *Help2;
+ int i;
+
+ Help1 = string_Conc("_", Id);
+ Help2 = string_Conc(Help1, pcheck_ProofFileSuffix);
+ string_StringFree(Help1);
+
+ /* remove filename extension */
+ for (i = 0; Filename[i] != '.' && i < strlen(Filename); i++)
+ /* empty */;
+ Help1 = string_Prefix(Filename, i);
+
+ return string_Nconc(Help1, Help2); /* Help1 and Help2 are freed, too */
+}
+
+
+void pcheck_ClauseListRemoveFlag(LIST Clauses, CLAUSE_FLAGS Flag)
+/**************************************************************
+ INPUT: A list of clauses and a clause flag
+ RETURNS: Nothing.
+ EFFECTS: Removes the <Flag> in all clauses in the list
+**************************************************************/
+{
+ for (; !list_Empty(Clauses); Clauses = list_Cdr(Clauses))
+ clause_RemoveFlag(list_Car(Clauses), Flag);
+}
+
+
+LIST pcheck_ClauseNumberMergeSort(LIST L)
+/**************************************************************
+ INPUT: A list of clauses
+ RETURNS: The sorted list: clause_Number(L[i]) < clause_Number(L[i+1])
+ EFFECTS: Destructive
+***************************************************************/
+{
+ return clause_NumberSort(L);
+}
diff --git a/test/spass/proofcheck.h b/test/spass/proofcheck.h
new file mode 100644
index 0000000..4f69746
--- /dev/null
+++ b/test/spass/proofcheck.h
@@ -0,0 +1,82 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * PROOF CHECKING * */
+/* * * */
+/* * Copyright (C) 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+
+/* $RCSfile$ */
+
+#ifndef _PROOFCHECK_H_
+#define _PROOFCHECK_H_
+
+#include "options.h"
+
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include "list.h"
+#include "vector.h"
+
+#include "misc.h"
+#include "dfg.h"
+#include "foldfg.h"
+#include "flags.h"
+#include "clause.h"
+#include "tableau.h"
+#include "search.h"
+#include "dfg.h"
+
+
+LIST pcheck_ReduceSPASSProof(LIST);
+char* pcheck_GenericFilename(const char*, const char*);
+int pcheck_SeqProofDepth(LIST);
+void pcheck_DeleteProof(LIST);
+BOOL pcheck_BuildTableauFromProof(LIST, TABLEAU*);
+LIST pcheck_ConvertTermListToClauseList(LIST, FLAGSTORE, PRECEDENCE);
+void pcheck_TableauToProofTask(TABLEAU, const char*, const char*);
+BOOL pcheck_TableauProof(TABLEAU*, LIST);
+LIST pcheck_ParentPointersToParentNumbers(LIST);
+LIST pcheck_ConvertParentsInSPASSProof(PROOFSEARCH, LIST);
+void pcheck_MarkRecursive(LIST);
+LIST pcheck_ClauseNumberMergeSort(LIST);
+void pcheck_ClauseListRemoveFlag(LIST, CLAUSE_FLAGS);
+
+#endif
+
+
+
diff --git a/test/spass/ras.h b/test/spass/ras.h
new file mode 100644
index 0000000..9e3f423
--- /dev/null
+++ b/test/spass/ras.h
@@ -0,0 +1,298 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * RANDOM ACCESS STACK * */
+/* * * */
+/* * $Module: RAS * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+#ifndef _RAS_
+#define _RAS_
+
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "misc.h"
+#include "memory.h"
+
+
+/**************************************************************/
+/* Constants and types */
+/**************************************************************/
+
+#define ras_alloc -1 /* index of size of allocated space */
+#define ras_top -2 /* index of next free element */
+#define ras_head 2 /* size of stack head for management purposes */
+#define ras_stdsize 16 /* standard stack size */
+
+
+typedef POINTER *RAS;
+
+/* A RAS (Random Access Stack) is a pointer to an array of elements */
+/* where the actual size of the stack and its current top pointer */
+/* are stored one and two cells before the array pointer. */
+
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+static __inline__ RAS ras_CreateWithSize(int size)
+/****************************************************************
+ INPUT: The maximal expected size of the stack to create.
+ RETURNS: A new empty stack.
+*****************************************************************/
+{
+ RAS result;
+
+#ifdef CHECK
+ if (size <= 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ras_CreateWithSize: size not positive.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = (RAS) memory_Malloc((size + ras_head) * sizeof(POINTER));
+ result = result + ras_head; /* leave space for head */
+ result[ras_alloc] = (POINTER) size;
+ result[ras_top] = (POINTER) 0;
+ return result;
+}
+
+
+static __inline__ RAS ras_Create(void)
+{
+ return ras_CreateWithSize(ras_stdsize);
+}
+
+
+static __inline__ void ras_Free(RAS ras)
+{
+ if (ras != NULL) {
+ memory_Free (
+ ras - ras_head,
+ (ras_head + (int) ras[ras_alloc]) * sizeof(POINTER)
+ );
+ }
+}
+
+
+static __inline__ RAS ras_InitWithSize(RAS ras, int size)
+/****************************************************************
+ INPUT: A random access stack the maximal expected size of the
+ stack to init.
+ RETURNS: The initialized and potentially new stack.
+ CAUTION: Because it potentially frees the old stack this
+ function must be called inside an assignment like:
+ stack = ras_InitWithSize(stack, ...)
+*****************************************************************/
+{
+
+#ifdef CHECK
+ if (size <= 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ras_InitWithSize: size not positive.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (size > (int) ras[ras_alloc]) {
+ ras_Free(ras);
+ ras = ras_CreateWithSize(size);
+ }
+ else
+ ras[ras_top] = (POINTER) 0;
+ return ras;
+}
+
+
+static __inline__ RAS ras_Init(RAS ras)
+/****************************************************************
+ INPUT: A random access stack.
+ RETURNS: The initialized and potentially new stack.
+ CAUTION: Because it potentially frees the old stack this
+ function must be called inside an assignment like:
+ stack = ras_InitWithSize(stack, ...)
+*****************************************************************/
+{
+ return ras_InitWithSize(ras, ras_stdsize);
+}
+
+
+static __inline__ int ras_Size(RAS ras)
+{
+ return (int) ras[ras_top];
+}
+
+
+static __inline__ RAS ras_FastPush(RAS ras, POINTER entry)
+/*********************************************************
+ INPUT: A random access stack and an element to push.
+ RETURNS: The modified stack.
+ CAUTION: The function does not care about stack overflow!
+**********************************************************/
+{
+ int top;
+
+#ifdef CHECK
+ if (ras_Size(ras) == (int) ras[ras_alloc]) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ras_FastPush: stack overflow.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ top = ras_Size(ras);
+ ras[top++] = entry;
+ ras[ras_top] = (POINTER) top;
+ return ras;
+}
+
+
+static __inline__ RAS ras_Push(RAS ras, POINTER entry)
+/*********************************************************
+ INPUT: A random access stack and an element to push.
+ RETURNS: The modified and potentially new stack.
+ SUMMARY: Before the push the stack is checked for overflow
+ and in case of overflow its size is doubled while
+ elements are copied to the (new) stack.
+ CAUTION: Must be called inside an assignment:
+ stack = ras_Push(stack, ...)
+**********************************************************/
+{
+ RAS old;
+ int oldsize;
+ POINTER *oldscan, *scan;
+
+ /* if not enough space allocated, double it: */
+ if (ras_Size(ras) == (int) ras[ras_alloc]) {
+ old = ras;
+ oldsize = (int) old[ras_alloc];
+ ras = ras_CreateWithSize(oldsize * 2);
+ ras[ras_top] = (POINTER) oldsize;
+
+ /* copy entries: */
+ for (oldscan = old + oldsize - 1,scan = ras + oldsize - 1; oldscan >= old;
+ oldscan--, scan--)
+ *scan = *oldscan;
+
+ ras_Free(old);
+ }
+
+ return ras_FastPush(ras, entry);
+}
+
+
+static __inline__ BOOL ras_LegalIndex(RAS ras, int index)
+{
+ return 0 <= index && index < ras_Size(ras);
+}
+
+
+static __inline__ POINTER ras_Get(RAS ras, int index)
+{
+#ifdef CHECK
+ if (!ras_LegalIndex(ras, index)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ras_Get: illegal stack index.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return ras[index];
+}
+
+
+static __inline__ RAS ras_Set(RAS ras, int index, POINTER entry)
+{
+#ifdef CHECK
+ if (!ras_LegalIndex(ras, index)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ras_Set: illegal stack index.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ ras[index] = entry;
+ return ras;
+}
+
+
+static __inline__ BOOL ras_Empty(RAS ras)
+{
+ return ras_Size(ras) == 0;
+}
+
+
+static __inline__ POINTER ras_Pop(RAS ras)
+{
+ int top;
+
+#ifdef CHECK
+ if (ras_Empty(ras)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ras_Pop: empty stack.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ top = ras_Size(ras) - 1;
+ ras[ras_top] = (POINTER) top;
+ return ras[top];
+}
+
+
+static __inline__ POINTER ras_Top(RAS ras)
+{
+#ifdef CHECK
+ if (ras_Empty(ras)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ras_Top: empty stack.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return ras[ras_Size(ras) - 1];
+}
+
+
+#endif
+
diff --git a/test/spass/renaming.c b/test/spass/renaming.c
new file mode 100644
index 0000000..55c89c5
--- /dev/null
+++ b/test/spass/renaming.c
@@ -0,0 +1,1508 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * RENAMING * */
+/* * * */
+/* * $Module: RENAMING * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "renaming.h"
+
+static NAT ren_STAMPID;
+
+static BOOL ren_RootDistanceSmaller(RENAMING,RENAMING);
+static BOOL ren_AFactorOk(TERM,TERM);
+static BOOL ren_BFactorOk(TERM,TERM);
+static BOOL ren_AExtraFactorOk(TERM,TERM);
+static BOOL ren_BExtraFactorOk(TERM,TERM);
+static BOOL ren_AFactorBigger3(TERM,TERM);
+static BOOL ren_BFactorBigger3(TERM,TERM);
+static TERM ren_FormulaRename(TERM, LIST, PRECEDENCE, LIST*);
+static LIST ren_GetRenamings(TERM, TERM, int);
+static BOOL ren_HasBenefit(TERM, TERM, int);
+static int ren_Polarity(TERM);
+static BOOL ren_PFactorOk(TERM);
+static BOOL ren_PExtraFactorOk(TERM);
+static BOOL ren_PFactorBigger3(TERM);
+static BOOL ren_NotPFactorOk(TERM);
+static BOOL ren_NotPExtraFactorOk(TERM);
+static BOOL ren_NotPFactorBigger3(TERM);
+static void ren_ResetTermStamp(TERM);
+
+void ren_Init(void)
+/**********************************************************
+ INPUT: None.
+ RETURNS: void.
+ EFFECT: Initializes the renaming module, in particular
+ the stamp id used in this module.
+***********************************************************/
+{
+ ren_STAMPID = term_GetStampID();
+}
+
+static BOOL ren_RootDistanceSmaller(RENAMING Ren1, RENAMING Ren2)
+{
+ return term_RootDistanceSmaller(ren_Hit(Ren1), ren_Hit(Ren2));
+}
+
+
+static void ren_ResetTermStamp(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: void.
+ EFFECT: The Term stamp of term as well as the stamps of
+ all its subterms (up to atom level) are reset.
+***********************************************************/
+{
+ SYMBOL Top;
+
+ term_ResetTermStamp(Term);
+ Top = term_TopSymbol(Term);
+
+ if (!symbol_IsPredicate(Top)) {
+ if (fol_IsQuantifier(Top))
+ ren_ResetTermStamp(term_SecondArgument(Term));
+ else {
+ LIST Scan;
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ ren_ResetTermStamp(list_Car(Scan));
+ }
+ }
+}
+
+static BOOL ren_HasNEquivFathers(TERM Term1, TERM Term2, NAT n)
+/**********************************************************
+ INPUT: Two terms, where <Term2> is a proper subterm of <Term1>
+ and a number.
+ RETURNS: TRUE if <Term2> has a <n>-father that are equivalences
+ and below <Term1>
+***********************************************************/
+{
+ Term2 = term_Superterm(Term2);
+
+ while (Term1 != Term2) {
+ if (symbol_Equal(term_TopSymbol(Term2),fol_Equiv())) {
+ n--;
+ if (n == 0)
+ return TRUE;
+ }
+ Term2 = term_Superterm(Term2);
+ }
+
+ return FALSE;
+}
+
+
+static BOOL ren_PExtraFactorOk(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: TRUE if transforming the term <Term> in positive polarity context
+ results in more than two clauses.
+***********************************************************/
+{
+ SYMBOL Top;
+ TERM T1, T2;
+ BOOL Ok;
+
+ /* if <Term> has the stamp, it will be renamed */
+ if (term_HasTermStamp(Term) || term_IsAtom(Term))
+ return FALSE;
+
+ Top = term_TopSymbol(Term);
+
+ if (fol_IsQuantifier(Top))
+ return ren_PExtraFactorOk(term_SecondArgument(Term));
+
+ if (symbol_Equal(Top,fol_Not()))
+ return ren_NotPExtraFactorOk(term_FirstArgument(Term));
+
+ if (symbol_Equal(Top,fol_Equiv())) {
+ T1 = term_FirstArgument(Term);
+ T2 = term_SecondArgument(Term);
+ return (ren_PFactorOk(T1) || ren_NotPFactorOk(T2) ||
+ ren_NotPFactorOk(T1) || ren_PFactorOk(T2));
+ }
+ if (symbol_Equal(Top,fol_And())) {
+ return (list_Length(term_ArgumentList(Term)) > 2 ||
+ ren_PFactorOk(term_FirstArgument(Term)) ||
+ ren_PFactorOk(term_SecondArgument(Term)));
+ }
+ if (symbol_Equal(Top,fol_Implies())) {
+ T1 = term_FirstArgument(Term);
+ T2 = term_SecondArgument(Term);
+ Ok = ren_PFactorOk(T2);
+ return ((ren_NotPFactorOk(T1) && (Ok || ren_NotPExtraFactorOk(T1))) ||
+ (Ok && ren_PExtraFactorOk(T2)));
+ }
+
+ if (symbol_Equal(Top,fol_Or())) {
+ LIST Scan;
+ Ok = FALSE; /* is set to TRUE if a subterm with p factor >1 occurred */
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (ren_PFactorOk(list_Car(Scan))) {
+ if (Ok || ren_PExtraFactorOk(list_Car(Scan)))
+ return TRUE; /* if two subterms with p>1 or one subterm with p>2 */
+ Ok = TRUE;
+ }
+ }
+
+ return FALSE; /* <Term> is a trivial disjunction */
+}
+
+static BOOL ren_PFactorOk(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: TRUE if transforming the term <Term> in positive polarity context
+ results in more than one clause.
+***********************************************************/
+{
+ SYMBOL Top;
+
+ /* if <Term> has the stamp, it will be renamed */
+ if (term_HasTermStamp(Term) || term_IsAtom(Term))
+ return FALSE;
+
+ Top = term_TopSymbol(Term);
+
+ if (symbol_Equal(Top,fol_Equiv()) || symbol_Equal(Top,fol_And()))
+ return TRUE;
+
+ if (symbol_Equal(Top,fol_Not()))
+ return ren_NotPFactorOk(term_FirstArgument(Term));
+
+ if (fol_IsQuantifier(Top))
+ return ren_PFactorOk(term_SecondArgument(Term));
+
+ if (symbol_Equal(Top,fol_Implies()))
+ return (ren_NotPFactorOk(term_FirstArgument(Term)) ||
+ ren_PFactorOk(term_SecondArgument(Term)));
+
+ if (symbol_Equal(Top,fol_Or())) {
+ LIST Scan;
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (ren_PFactorOk(list_Car(Scan)))
+ return TRUE;
+ }
+
+ return FALSE; /* <Term> is a trivial disjunction */
+}
+
+
+static BOOL ren_NotPExtraFactorOk(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: TRUE if transforming the term <Term> in negative polarity context
+ results in more than two clauses.
+***********************************************************/
+{
+ SYMBOL Top;
+
+ /* if <Term> has the stamp, it will be renamed */
+ if (term_HasTermStamp(Term) || term_IsAtom(Term))
+ return FALSE;
+
+ Top = term_TopSymbol(Term);
+
+ if (symbol_Equal(Top,fol_Not()))
+ return ren_PExtraFactorOk(term_FirstArgument(Term));
+
+ if (fol_IsQuantifier(Top))
+ return ren_NotPExtraFactorOk(term_SecondArgument(Term));
+
+ if (symbol_Equal(Top,fol_Equiv())) {
+ TERM T1, T2;
+ T1 = term_FirstArgument(Term);
+ T2 = term_SecondArgument(Term);
+ return (ren_PFactorOk(T1) || ren_PFactorOk(T2) ||
+ ren_NotPFactorOk(T1) || ren_NotPFactorOk(T2));
+ }
+ if (symbol_Equal(Top,fol_Or())) {
+ if (list_Length(term_ArgumentList(Term))>2 ||
+ ren_NotPFactorOk(term_FirstArgument(Term)) ||
+ ren_NotPFactorOk(term_SecondArgument(Term)))
+ return TRUE;
+ else
+ return FALSE;
+ }
+ if (symbol_Equal(Top,fol_Implies())) {
+ if (ren_PFactorOk(term_FirstArgument(Term)) ||
+ ren_NotPFactorOk(term_SecondArgument(Term)))
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ if (symbol_Equal(Top,fol_And())) {
+ LIST Scan;
+ BOOL Ok;
+ Ok = FALSE;
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (ren_NotPFactorOk(list_Car(Scan))) {
+ if (Ok || ren_NotPExtraFactorOk(list_Car(Scan)))
+ return TRUE; /* if two subterms with -p>1 or one subterm with -p>2 */
+ Ok = TRUE;
+ }
+ }
+
+ return FALSE; /* Either <Term> is a trivial conjunction or an atom */
+}
+
+
+static BOOL ren_NotPFactorOk(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: TRUE if transforming the term <Term> in negative polarity context
+ results in more than one clause.
+***********************************************************/
+{
+ SYMBOL Top;
+
+ /* if <Term> has the stamp, it will be renamed */
+ if (term_HasTermStamp(Term) || term_IsAtom(Term))
+ return FALSE;
+
+ Top = term_TopSymbol(Term);
+
+ if (symbol_Equal(Top,fol_Equiv()) || symbol_Equal(Top,fol_Or()) ||
+ symbol_Equal(Top,fol_Implies()))
+ return TRUE;
+
+ if (symbol_Equal(Top,fol_Not()))
+ return ren_PFactorOk(term_FirstArgument(Term));
+
+ if (fol_IsQuantifier(Top))
+ return ren_NotPFactorOk(term_SecondArgument(Term));
+
+ if (symbol_Equal(Top,fol_And())) {
+ LIST Scan;
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (ren_NotPFactorOk(list_Car(Scan)))
+ return TRUE;
+ }
+
+ return FALSE; /* <Term> is a trivial conjunction */
+}
+
+
+static BOOL ren_PFactorBigger3(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: TRUE if transforming the term <Term> in positive
+ polarity context results in more than three clauses.
+***********************************************************/
+{
+ SYMBOL Top;
+ TERM T1, T2;
+ LIST Scan;
+ BOOL Ok;
+
+ /* if <Term> has the stamp, it will be renamed */
+ if (term_HasTermStamp(Term) || term_IsAtom(Term))
+ return FALSE;
+
+ Top = term_TopSymbol(Term);
+
+ if (fol_IsQuantifier(Top))
+ return ren_PFactorBigger3(term_SecondArgument(Term));
+
+ if (symbol_Equal(Top, fol_Not()))
+ return ren_NotPFactorBigger3(term_FirstArgument(Term));
+
+ if (symbol_Equal(Top, fol_And())) {
+ unsigned char Limit; /* invariant: p >= Limit */
+ Limit = list_Length(term_ArgumentList(Term));
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan) && Limit<=3;
+ Scan=list_Cdr(Scan))
+ if (ren_PFactorOk(list_Car(Scan))) {
+ Limit++;
+ if (Limit<=3 && ren_PExtraFactorOk(list_Car(Scan))) {
+ Limit++;
+ if (Limit<=3 && ren_PFactorBigger3(list_Car(Scan)))
+ Limit++; /* works for unary conjunction, too */
+ }
+ }
+ return (Limit>3);
+ }
+ if (symbol_Equal(Top, fol_Or())) {
+ Ok = FALSE; /* is set to TRUE if a subterm with p factor >1 occurred */
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (ren_PFactorOk(list_Car(Scan))) {
+ if (Ok || ren_PFactorBigger3(list_Car(Scan)))
+ return TRUE; /* if two subterms with p>1 or one subterm with p>3 */
+ Ok = TRUE;
+ }
+ return FALSE;
+ }
+
+ T1 = term_FirstArgument(Term);
+ T2 = term_SecondArgument(Term);
+
+ if (symbol_Equal(Top, fol_Implies())) {
+ Ok = ren_PFactorOk(T2);
+ /* return TRUE if -p(T1)>3 || p(T2)>3 || (-p(T1)>1 && p(T2)>1) */
+ return ((ren_NotPFactorOk(T1) && (Ok || ren_NotPFactorBigger3(T1))) ||
+ (Ok && ren_PFactorBigger3(T2)));
+ }
+ if (symbol_Equal(Top, fol_Equiv())) {
+ unsigned char T1Limit, T2Limit, NotT1Limit, NotT2Limit;
+ T1Limit = ren_PFactorOk(T1) ? 1 : 0;
+ NotT1Limit = ren_NotPFactorOk(T1) ? 1 : 0;
+ T2Limit = ren_PFactorOk(T2) ? 1 : 0;
+ NotT2Limit = ren_NotPFactorOk(T2) ? 1 : 0;
+ /* return TRUE, if p(T1)>2 || p(T2)>2 || -p(T1)>2 || -p(T2)>2 or at */
+ /* least two values out of { p(T1),p(T2),-p(T1),-p(T2) } are > 1 */
+ return ((T1Limit + NotT2Limit + NotT1Limit + T2Limit >= 2) ||
+ (T1Limit!=0 && ren_PExtraFactorOk(T1)) ||
+ (T2Limit!=0 && ren_PExtraFactorOk(T2)) ||
+ (NotT1Limit!=0 && ren_NotPExtraFactorOk(T1)) ||
+ (NotT2Limit!=0 && ren_NotPExtraFactorOk(T2)));
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport(" \n In ren_PFactorBigger3: unknown first order operator.");
+ misc_FinishErrorReport();
+ return FALSE;
+}
+
+
+static BOOL ren_NotPFactorBigger3(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: TRUE if transforming the term <Term> in negative
+ polarity context results in more than three clauses.
+***********************************************************/
+{
+ SYMBOL Top;
+ TERM T1, T2;
+ LIST Scan;
+ BOOL Ok;
+
+ /* if <Term> has the stamp, it will be renamed */
+ if (term_HasTermStamp(Term) || term_IsAtom(Term))
+ return FALSE;
+
+ Top = term_TopSymbol(Term);
+
+ if (fol_IsQuantifier(Top))
+ return ren_NotPFactorBigger3(term_SecondArgument(Term));
+
+ if (symbol_Equal(Top, fol_Not()))
+ return ren_PFactorBigger3(term_FirstArgument(Term));
+
+ if (symbol_Equal(Top, fol_Or())) {
+ unsigned char Limit; /* invariant: -p >= Limit */
+ Limit = list_Length(term_ArgumentList(Term));
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan) && Limit<=3;
+ Scan=list_Cdr(Scan))
+ if (ren_NotPFactorOk(list_Car(Scan))) {
+ Limit++;
+ if (Limit<=3 && ren_NotPExtraFactorOk(list_Car(Scan))) {
+ Limit++;
+ if (Limit<=3 && ren_NotPFactorBigger3(list_Car(Scan)))
+ Limit++; /* works for unary disjunction, too */
+ }
+ }
+ return (Limit>3);
+ }
+ if (symbol_Equal(Top, fol_And())) {
+ Ok = FALSE; /* is set to TRUE if a subterm with -p factor >1 occurred */
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (ren_NotPFactorOk(list_Car(Scan))) {
+ if (Ok || ren_NotPFactorBigger3(list_Car(Scan)))
+ return TRUE; /* if two subterms with -p>1 or one subterm with -p>3 */
+ Ok = TRUE;
+ }
+ return FALSE;
+ }
+
+ T1 = term_FirstArgument(Term);
+ T2 = term_SecondArgument(Term);
+
+ if (symbol_Equal(Top, fol_Implies())) {
+ Ok = ren_NotPFactorOk(T2);
+ /* return TRUE if p(T1)>2 || -p(T2)>2 || (p(T1)>1 && -p(T2)>1) */
+ return ((ren_PFactorOk(T1) && (Ok || ren_PExtraFactorOk(T1))) ||
+ (Ok && ren_NotPExtraFactorOk(T2)));
+ }
+ if (symbol_Equal(Top, fol_Equiv())) {
+ unsigned char T1Limit, T2Limit, NotT1Limit, NotT2Limit;
+ T1Limit = ren_PFactorOk(T1) ? 1 : 0;
+ NotT1Limit = ren_NotPFactorOk(T1) ? 1 : 0;
+ T2Limit = ren_PFactorOk(T2) ? 1 : 0;
+ NotT2Limit = ren_NotPFactorOk(T2) ? 1 : 0;
+ /* return TRUE, if p(T1)>2 || p(T2)>2 || -p(T1)>2 || -p(T2)>2 or at */
+ /* least two values out of { p(T1),p(T2),-p(T1),-p(T2) } are > 1 */
+ return ((T1Limit + NotT2Limit + NotT1Limit + T2Limit >= 2) ||
+ (T1Limit!=0 && ren_PExtraFactorOk(T1)) ||
+ (T2Limit!=0 && ren_PExtraFactorOk(T2)) ||
+ (NotT1Limit!=0 && ren_NotPExtraFactorOk(T1)) ||
+ (NotT2Limit!=0 && ren_NotPExtraFactorOk(T2)));
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport(" \n In ren_NotPFactorBigger3: unknown first order operator.");
+ misc_FinishErrorReport();
+ return FALSE;
+}
+
+
+static BOOL ren_AFactorOk(TERM Term1, TERM Term2)
+/**********************************************************
+ INPUT: Two terms where <Term1> is a superterm of <Term2>
+ RETURNS: TRUE if the A-Factor of Term2 in Term1 is larger than one.
+***********************************************************/
+{
+ SYMBOL Top;
+ TERM Super;
+
+ if (Term1 == Term2)
+ return FALSE;
+
+ Super = term_Superterm(Term2);
+ Top = term_TopSymbol(Super);
+
+ if (symbol_Equal(Top,fol_And()) || fol_IsQuantifier(Top))
+ return ren_AFactorOk(Term1, Super);
+
+ if (symbol_Equal(Top,fol_Not()))
+ return ren_BFactorOk(Term1, Super);
+
+ if (symbol_Equal(Top,fol_Or())) {
+ LIST Scan;
+ TERM Sub;
+ for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Sub = (TERM)list_Car(Scan);
+ if (Sub != Term2 && ren_PFactorOk(Sub))
+ return TRUE;
+ }
+ return ren_AFactorOk(Term1, Super);
+ }
+
+ if (symbol_Equal(Top,fol_Implies())) {
+ if (Term2 == term_FirstArgument(Super))
+ return ren_BFactorOk(Term1, Super);
+ else
+ return (ren_NotPFactorOk(term_FirstArgument(Super)) || ren_AFactorOk(Term1, Super));
+ }
+ if (symbol_Equal(Top,fol_Equiv())) {
+ int Pol;
+ Pol = ren_Polarity(Super);
+ if (Pol == 0)
+ return TRUE;
+ if (Term2 == term_FirstArgument(Super))
+ Term2 = term_SecondArgument(Super);
+ else
+ Term2 = term_FirstArgument(Super);
+
+ if (Pol == 1)
+ return (ren_NotPFactorOk(Term2) || ren_AFactorOk(Term1,Super));
+ else
+ return (ren_PFactorOk(Term2) || ren_BFactorOk(Term1,Super));
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("In ren_AFactorOk: Unknown first order operator.");
+ misc_FinishErrorReport();
+ return FALSE;
+}
+
+static BOOL ren_AExtraFactorOk(TERM Term1, TERM Term2)
+/**********************************************************
+ INPUT: Two terms where <Term1> is a superterm of <Term2>
+ RETURNS: TRUE if the A-Factor of Term2 in Term1 is larger than two.
+***********************************************************/
+{
+ SYMBOL Top;
+ TERM Super;
+ BOOL Ok;
+
+ if (Term1 == Term2)
+ return FALSE;
+
+ Super = term_Superterm(Term2);
+ Top = term_TopSymbol(Super);
+
+ if (symbol_Equal(Top,fol_And()) || fol_IsQuantifier(Top))
+ return ren_AExtraFactorOk(Term1, Super);
+
+ if (symbol_Equal(Top,fol_Not()))
+ return ren_BExtraFactorOk(Term1, Super);
+
+ if (symbol_Equal(Top,fol_Or())) {
+ LIST Scan;
+ TERM Sub;
+ Ok = FALSE;
+ for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Sub = (TERM)list_Car(Scan);
+ if (Sub != Term2 && ren_PFactorOk(Sub)) {
+ if (Ok || ren_PExtraFactorOk(Sub))
+ return TRUE;
+ Ok = TRUE;
+ }
+ }
+ /* return TRUE if (p>1 for one subterm and a>1) or a>2 */
+ return (ren_AFactorOk(Term1,Super) &&
+ (Ok || ren_AExtraFactorOk(Term1, Super)));
+ }
+
+ if (symbol_Equal(Top,fol_Implies())) {
+ if (Term2 == term_FirstArgument(Super))
+ return ren_BExtraFactorOk(Term1, Super);
+ else {
+ TERM T1;
+ T1 = term_FirstArgument(Super);
+ Ok = ren_AFactorOk(Term1, Super);
+ /* return TRUE if (-p>1 and a>1) or -p>2 or a>2 */
+ return ((ren_NotPFactorOk(T1) && (Ok || ren_NotPExtraFactorOk(T1))) ||
+ (Ok && ren_AExtraFactorOk(Term1,Super)));
+ }
+ }
+ if (symbol_Equal(Top,fol_Equiv())) {
+ if (Term2 == term_FirstArgument(Super))
+ Term2 = term_SecondArgument(Super);
+ else
+ Term2 = term_FirstArgument(Super);
+
+ switch (ren_Polarity(Super)) {
+ case 0:
+ return (ren_PFactorOk(Term2) || ren_NotPFactorOk(Term2) ||
+ ren_AFactorOk(Term1,Super) || ren_BFactorOk(Term1,Super));
+ case 1:
+ Ok = ren_AFactorOk(Term1, Super);
+ return ((ren_NotPFactorOk(Term2) && (Ok || ren_NotPExtraFactorOk(Term2))) ||
+ (Ok && ren_AExtraFactorOk(Term1,Super)));
+ case -1:
+ Ok = ren_BFactorOk(Term1, Super);
+ return ((ren_PFactorOk(Term2) && (Ok || ren_PExtraFactorOk(Term2))) ||
+ (Ok && ren_BExtraFactorOk(Term1,Super)));
+ }
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("In ren_AExtraFactorOk: Unknown first order operator.");
+ misc_FinishErrorReport();
+ return FALSE;
+}
+
+
+static BOOL ren_AFactorBigger3(TERM Term1, TERM Term2)
+/**********************************************************
+ INPUT: Two terms where <Term1> is a superterm of <Term2>
+ RETURNS: TRUE if the A-Factor of Term2 in Term1 is larger than three.
+***********************************************************/
+{
+ TERM Super;
+ SYMBOL Top;
+ BOOL Ok;
+
+ if (Term1 == Term2)
+ return FALSE;
+
+ Super = term_Superterm(Term2);
+ Top = term_TopSymbol(Super);
+
+ if (symbol_Equal(Top,fol_And()) || fol_IsQuantifier(Top))
+ return ren_AFactorBigger3(Term1, Super);
+
+ if (symbol_Equal(Top,fol_Not()))
+ return ren_BFactorBigger3(Term1, Super);
+
+ if (symbol_Equal(Top, fol_Or())) {
+ LIST Scan;
+ TERM Sub;
+ Ok = FALSE; /* is set to TRUE if a subterm with p factor >1 occurred */
+ for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Sub = list_Car(Scan);
+ if (Term2 != Sub && ren_PFactorOk(Sub)) {
+ if (Ok || ren_PFactorBigger3(Sub))
+ return TRUE; /* if two subterms with p>1 or one subterm with p>3 */
+ Ok = TRUE;
+ }
+ }
+ return (ren_AFactorOk(Term1, Super) &&
+ (Ok || ren_AFactorBigger3(Term1, Super)));
+ }
+ if (symbol_Equal(Top,fol_Implies())) {
+ if (Term2 == term_FirstArgument(Super))
+ return ren_BFactorBigger3(Term1, Super);
+ else {
+ TERM T1;
+ T1 = term_FirstArgument(Super);
+ Ok = ren_AFactorOk(Term1, Super);
+ /* return TRUE if (-p>1 and a>1) or -p>3 or a>3 */
+ return ((ren_NotPFactorOk(T1) && (Ok || ren_NotPFactorBigger3(T1))) ||
+ (Ok && ren_AFactorBigger3(Term1, Super)));
+ }
+ }
+ if (symbol_Equal(Top,fol_Equiv())) {
+ if (Term2 == term_FirstArgument(Super))
+ Term2 = term_SecondArgument(Super);
+ else
+ Term2 = term_FirstArgument(Super);
+
+ switch (ren_Polarity(Super)) {
+ case 0: {
+ unsigned ALimit, BLimit, PLimit, NotPLimit;
+ ALimit = ren_AFactorOk(Term1, Super) ? 1 : 0;
+ BLimit = ren_BFactorOk(Term1, Super) ? 1 : 0;
+ PLimit = ren_PFactorOk(Term2) ? 1 : 0;
+ NotPLimit = ren_NotPFactorOk(Term2) ? 1 : 0;
+ /* return TRUE if a>2 || b>2 || p>2 || -p>2 or at least */
+ /* two values out of { a, b, p, -p } are > 1 */
+ return ((ALimit + BLimit + PLimit + NotPLimit >= 2) ||
+ (PLimit!=0 && ren_PExtraFactorOk(Term2)) ||
+ (NotPLimit!=0 && ren_NotPExtraFactorOk(Term2)) ||
+ (ALimit!=0 && ren_AExtraFactorOk(Term1,Super)) ||
+ (BLimit!=0 && ren_BExtraFactorOk(Term1,Super)));
+ }
+ case 1:
+ Ok = ren_AFactorOk(Term1, Super);
+ /* return TRUE if a>3 || -p>3 || (a>1 && -p>1) */
+ return ((ren_NotPFactorOk(Term2) && (Ok || ren_NotPFactorBigger3(Term2))) ||
+ (Ok && ren_AFactorBigger3(Term1, Super)));
+ case -1:
+ Ok = ren_BFactorOk(Term1, Super);
+ /* return TRUE if b>3 || p>3 || (b>1 && p>1) */
+ return ((ren_PFactorOk(Term2) && (Ok || ren_PFactorBigger3(Term2))) ||
+ (Ok && ren_BFactorBigger3(Term1, Super)));
+ }
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("In ren_AFactorBigger3: Unknown first order operator.");
+ misc_FinishErrorReport();
+ return FALSE;
+}
+
+
+static BOOL ren_BFactorOk(TERM Term1, TERM Term2)
+/**********************************************************
+ INPUT: Two terms where <Term1> is a superterm of <Term2>
+ RETURNS: TRUE if the B-Factor of Term2 in Term1 is larger than one.
+***********************************************************/
+{
+ SYMBOL Top;
+ TERM Super;
+
+ if (Term1 == Term2)
+ return FALSE;
+
+ Super = term_Superterm(Term2);
+ Top = term_TopSymbol(Super);
+
+ if (symbol_Equal(Top,fol_Or()) || fol_IsQuantifier(Top))
+ return ren_BFactorOk(Term1, Super);
+
+ if (symbol_Equal(Top,fol_Not()))
+ return ren_AFactorOk(Term1, Super);
+
+ if (symbol_Equal(Top,fol_And())) {
+ LIST Scan;
+ TERM Sub;
+ for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Sub = (TERM)list_Car(Scan);
+ if (Sub != Term2 && ren_NotPFactorOk(Sub))
+ return TRUE;
+ }
+ return ren_BFactorOk(Term1, Super);
+ }
+
+ if (symbol_Equal(Top,fol_Implies())) {
+ if (Term2 == term_FirstArgument(Super))
+ return (ren_PFactorOk(term_SecondArgument(Super)) || ren_AFactorOk(Term1, Super));
+ else
+ return ren_BFactorOk(Term1, Super);
+ }
+ if (symbol_Equal(Top,fol_Equiv())) {
+ int Pol;
+ Pol = ren_Polarity(Super);
+ if (Pol == 0)
+ return TRUE;
+ if (Term2 == term_FirstArgument(Super))
+ Term2 = term_SecondArgument(Super);
+ else
+ Term2 = term_FirstArgument(Super);
+
+ if (Pol == 1)
+ return (ren_PFactorOk(Term2) || ren_AFactorOk(Term1,Super));
+ else
+ return (ren_NotPFactorOk(Term2) || ren_BFactorOk(Term1,Super));
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("In ren_BFactorOk: Unknown first order operator.");
+ misc_FinishErrorReport();
+ return FALSE;
+}
+
+static BOOL ren_BExtraFactorOk(TERM Term1, TERM Term2)
+/**********************************************************
+ INPUT: Two terms where <Term1> is a superterm of <Term2>
+ RETURNS: TRUE if the B-Factor of Term2 in Term1 is larger than two.
+***********************************************************/
+{
+ SYMBOL Top;
+ TERM Super;
+ BOOL Ok;
+
+ if (Term1 == Term2)
+ return FALSE;
+
+ Super = term_Superterm(Term2);
+ Top = term_TopSymbol(Super);
+
+ if (symbol_Equal(Top,fol_Or()) || fol_IsQuantifier(Top))
+ return ren_BExtraFactorOk(Term1, Super);
+
+ if (symbol_Equal(Top,fol_Not()))
+ return ren_AExtraFactorOk(Term1, Super);
+
+ if (symbol_Equal(Top,fol_And())) {
+ LIST Scan;
+ TERM Sub;
+ Ok = FALSE;
+ for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Sub = (TERM)list_Car(Scan);
+ if (Sub != Term2 && ren_NotPFactorOk(Sub)) {
+ if (Ok || ren_NotPExtraFactorOk(Sub))
+ return TRUE;
+ Ok = TRUE;
+ }
+ }
+ /* return TRUE if (-p>1 for one subterm and b>1) or b>2 */
+ return (ren_BFactorOk(Term1,Super) &&
+ (Ok || ren_BExtraFactorOk(Term1, Super)));
+ }
+
+ if (symbol_Equal(Top,fol_Implies())) {
+ if (Term2 == term_FirstArgument(Super)) {
+ TERM T2;
+ T2 = term_SecondArgument(Super);
+ Ok = ren_AFactorOk(Term1, Super);
+ /* return TRUE if (p>1 and a>1) or p>2 or a>2 */
+ return ((ren_PFactorOk(T2) && (Ok || ren_PExtraFactorOk(T2))) ||
+ (Ok && ren_AExtraFactorOk(Term1, Super)));
+ }
+ else
+ return ren_BExtraFactorOk(Term1, Super);
+ }
+ if (symbol_Equal(Top,fol_Equiv())) {
+ if (Term2 == term_FirstArgument(Super))
+ Term2 = term_SecondArgument(Super);
+ else
+ Term2 = term_FirstArgument(Super);
+
+ switch (ren_Polarity(Super)) {
+ case 0:
+ return (ren_PFactorOk(Term2) || ren_NotPFactorOk(Term2) ||
+ ren_AFactorOk(Term1,Super) || ren_BFactorOk(Term1,Super));
+ case 1:
+ Ok = ren_AFactorOk(Term1, Super);
+ return ((ren_PFactorOk(Term2) && (Ok || ren_PExtraFactorOk(Term2))) ||
+ (Ok && ren_AExtraFactorOk(Term1,Super)));
+ case -1:
+ Ok = ren_BFactorOk(Term1, Super);
+ return ((ren_NotPFactorOk(Term2) && (Ok || ren_NotPExtraFactorOk(Term2))) ||
+ (Ok && ren_BExtraFactorOk(Term1,Super)));
+ }
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("In ren_BExtraFactorOk: Unknown first order operator.");
+ misc_FinishErrorReport();
+ return FALSE;
+}
+
+static BOOL ren_BFactorBigger3(TERM Term1, TERM Term2)
+/**********************************************************
+ INPUT: Two terms where <Term1> is a superterm of <Term2>
+ RETURNS: TRUE if the B-Factor of Term2 in Term1 is larger than three.
+***********************************************************/
+{
+ TERM Super;
+ SYMBOL Top;
+ BOOL Ok;
+
+ if (Term1 == Term2)
+ return FALSE;
+
+ Super = term_Superterm(Term2);
+ Top = term_TopSymbol(Super);
+
+ if (fol_IsQuantifier(Top) || symbol_Equal(Top, fol_Or()))
+ return ren_BFactorBigger3(Term1, Super);
+
+ if (symbol_Equal(Top, fol_Not()))
+ return ren_AFactorBigger3(Term1, Super);
+
+ if (symbol_Equal(Top, fol_And())) {
+ LIST Scan;
+ TERM Sub;
+ Ok = FALSE; /* is set to TRUE if a subterm with -p factor >1 occurred */
+ for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Sub = list_Car(Scan);
+ if (Term2 != Sub && ren_NotPFactorOk(Sub)) {
+ if (Ok || ren_NotPFactorBigger3(Sub))
+ return TRUE; /* if two subterms with -p>1 or one subterm with -p>3 */
+ Ok = TRUE;
+ }
+ }
+ return (ren_BFactorOk(Term1, Super) &&
+ (Ok || ren_BFactorBigger3(Term1, Super)));
+ }
+ if (symbol_Equal(Top,fol_Implies())) {
+ if (Term2 == term_FirstArgument(Super)) {
+ TERM T2;
+ T2 = term_SecondArgument(Super);
+ Ok = ren_AFactorOk(Term1, Super);
+ /* return TRUE if (p>1 and a>1) or p>3 or a>3 */
+ return ((ren_PFactorOk(T2) && (Ok || ren_PFactorBigger3(T2))) ||
+ (Ok && ren_AFactorBigger3(Term1, Super)));
+ }
+ else
+ return ren_BFactorBigger3(Term1, Super);
+ }
+ if (symbol_Equal(Top,fol_Equiv())) {
+ if (Term2 == term_FirstArgument(Super))
+ Term2 = term_SecondArgument(Super);
+ else
+ Term2 = term_FirstArgument(Super);
+
+ switch (ren_Polarity(Super)) {
+ case 0: {
+ unsigned ALimit, BLimit, PLimit, NotPLimit;
+ ALimit = ren_AFactorOk(Term1, Super) ? 1 : 0;
+ BLimit = ren_BFactorOk(Term1, Super) ? 1 : 0;
+ PLimit = ren_PFactorOk(Term2) ? 1 : 0;
+ NotPLimit = ren_NotPFactorOk(Term2) ? 1 : 0;
+ /* return TRUE if a>2 || b>2 || p>2 || -p>2 or at least */
+ /* two values out of { a, b, p, -p } are > 1 */
+ return ((ALimit + BLimit + PLimit + NotPLimit >= 2) ||
+ (PLimit!=0 && ren_PExtraFactorOk(Term2)) ||
+ (NotPLimit!=0 && ren_NotPExtraFactorOk(Term2)) ||
+ (ALimit!=0 && ren_AExtraFactorOk(Term1,Super)) ||
+ (BLimit!=0 && ren_BExtraFactorOk(Term1,Super)));
+ }
+ case 1:
+ Ok = ren_AFactorOk(Term1, Super);
+ /* return TRUE if a>3 || -p>3 || (a>1 && -p>1) */
+ return ((ren_PFactorOk(Term2) && (Ok || ren_PFactorBigger3(Term2))) ||
+ (Ok && ren_AFactorBigger3(Term1, Super)));
+ case -1:
+ Ok = ren_BFactorOk(Term1, Super);
+ /* return TRUE if b>3 || p>3 || (b>1 && p>1) */
+ return ((ren_NotPFactorOk(Term2) && (Ok || ren_NotPFactorBigger3(Term2))) ||
+ (Ok && ren_BFactorBigger3(Term1, Super)));
+ }
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("In ren_BFactorBigger3: Unknown first order operator.");
+ misc_FinishErrorReport();
+ return FALSE;
+}
+
+
+static BOOL ren_HasBenefit(TERM Term1, TERM Term2, int Pol)
+/**********************************************************
+ INPUT: Two terms and the polarity of the 2nd term in the overall formula.
+ RETURNS: TRUE if renaming <Term1> in <Term2> results in a positive benefit.
+ CAUTION: It is assumed that all superterms are set !
+***********************************************************/
+{
+ BOOL PFacOk, NotPFacOk, AFacOk, BFacOk;
+
+ switch (Pol) {
+
+ case 0:
+ PFacOk = ren_PFactorOk(Term2);
+ NotPFacOk = ren_NotPFactorOk(Term2);
+ AFacOk = ren_AFactorOk(Term1,Term2);
+ BFacOk = ren_BFactorOk(Term1,Term2);
+ return ((AFacOk && BFacOk && PFacOk && NotPFacOk) ||
+ (AFacOk && PFacOk && (ren_PExtraFactorOk(Term2) || ren_AExtraFactorOk(Term1,Term2))) ||
+ (BFacOk && NotPFacOk && (ren_NotPExtraFactorOk(Term2) || ren_BExtraFactorOk(Term1,Term2))));
+ break;
+
+ case 1:
+ return (ren_PFactorOk(Term2) && ren_AFactorOk(Term1,Term2));
+ break;
+
+ case -1:
+ return (ren_NotPFactorOk(Term2) && ren_BFactorOk(Term1,Term2));
+ break;
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("In ren_HasBenefit: Unknown polarity.");
+ misc_FinishErrorReport();
+ return FALSE;
+}
+
+static BOOL ren_HasNonZeroBenefit(TERM Term1, int Pol1, TERM Term2, int Pol2)
+/**********************************************************
+ INPUT: Two terms and the polarity of the terms in the overall formula.
+ RETURNS: TRUE if renaming <Term1> in <Term2> results in non-zero positive benefit.
+ CAUTION: It is assumed that all superterms are set !
+***********************************************************/
+{
+ BOOL PFacOk, NotPFacOk, AFacOk, BFacOk, PEFacOk, NotPEFacOk, AEFacOk, BEFacOk;
+ switch (Pol2) {
+ case 0:
+ PFacOk = ren_PFactorOk(Term2);
+ NotPFacOk = ren_NotPFactorOk(Term2);
+ AFacOk = ren_AFactorOk(Term1,Term2);
+ BFacOk = ren_BFactorOk(Term1,Term2);
+ PEFacOk = PFacOk && ren_PExtraFactorOk(Term2);
+ NotPEFacOk = NotPFacOk && ren_NotPExtraFactorOk(Term2);
+ AEFacOk = AFacOk && ren_AExtraFactorOk(Term1,Term2);
+ BEFacOk = BFacOk && ren_BExtraFactorOk(Term1,Term2);
+
+ return ((AFacOk && BFacOk && PFacOk && NotPFacOk && (AEFacOk || BEFacOk || PEFacOk || NotPEFacOk)) ||
+ (PEFacOk && AEFacOk) || (NotPEFacOk && BEFacOk) ||
+ (AFacOk && ren_PFactorBigger3(Term2)) ||
+ (BFacOk && ren_NotPFactorBigger3(Term2)) ||
+ (PFacOk && ren_AFactorBigger3(Term1, Term2)) ||
+ (NotPFacOk && ren_BFactorBigger3(Term1, Term2)) ||
+ /* The following conditions don't imply benefit > 0, but allow */
+ /* some additional renamings with benefit 0. */
+ (Pol1 == 0 && (symbol_Equal(term_TopSymbol(Term2),fol_Equiv()) ||
+ ren_HasNEquivFathers(Term1,Term2,1))) ||
+ ren_HasNEquivFathers(Term1,Term2,2));
+ break;
+
+ case 1:
+ /* return TRUE if (p>1 && a>2) || (p>2 && a>1) */
+ AFacOk = ren_AFactorOk(Term1,Term2);
+ return ((ren_PFactorOk(Term2) && (AFacOk || ren_AFactorOk(Term1,Term2))) ||
+ (AFacOk && ren_AExtraFactorOk(Term1,Term2)));
+ break;
+
+ case -1:
+ /* return TRUE if (-p>1 && b>2) || (-p>2 && b>1) */
+ BFacOk = ren_BFactorOk(Term1,Term2);
+ return ((ren_NotPFactorOk(Term2) && (BFacOk || ren_NotPExtraFactorOk(Term2))) ||
+ (BFacOk && ren_BExtraFactorOk(Term1,Term2)));
+ break;
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("In ren_HasNonZeroBenefit: Unknown polarity.");
+ misc_FinishErrorReport();
+ return FALSE;
+}
+
+
+static LIST ren_GetRenamings(TERM Term1, TERM Term2, int Pol)
+/**********************************************************
+ INPUT: Two terms and the polarity of the 2nd term in the overall formula.
+ RETURNS: The list of subterms below <Term2> that have a positive renaming
+ benefit.
+ EFFECT: All renamed formulae are stamped.
+***********************************************************/
+{
+ SYMBOL Top;
+ LIST Result,Scan;
+
+ Result = list_Nil();
+
+ /* Don't rename formulae starting with "not" */
+ while (symbol_Equal(term_TopSymbol(Term2), fol_Not())) {
+ Term2 = term_FirstArgument(Term2);
+ Pol = -Pol;
+ }
+
+ if (term_IsAtom(Term2))
+ return Result;
+
+ Top = term_TopSymbol(Term2);
+
+ /* Don't rename arguments of a quantifier */
+ if (term_Superterm(Term2) &&
+ !fol_IsQuantifier(term_TopSymbol(term_Superterm(Term2))) &&
+ ren_HasBenefit(Term1, Term2, Pol)) {
+ Result = list_Cons(Term2,Result);
+ term_SetTermStamp(Term2);
+ Term1 = Term2;
+ }
+
+ if (fol_IsQuantifier(Top))
+ Result = list_Nconc(Result,ren_GetRenamings(Term1, term_SecondArgument(Term2), Pol));
+ else if (symbol_Equal(Top,fol_And()) || symbol_Equal(Top,fol_Or()))
+ for (Scan=term_ArgumentList(Term2);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ Result = list_Nconc(Result,ren_GetRenamings(Term1,list_Car(Scan),Pol));
+ else if (symbol_Equal(Top,fol_Implies())) {
+ Result = list_Nconc(Result,ren_GetRenamings(Term1,term_FirstArgument(Term2),-Pol));
+ Result = list_Nconc(Result,ren_GetRenamings(Term1,term_SecondArgument(Term2),Pol));
+ } else if (symbol_Equal(Top,fol_Equiv())) {
+ Result = list_Nconc(Result, ren_GetRenamings(Term1,term_FirstArgument(Term2),0));
+ Result = list_Nconc(Result, ren_GetRenamings(Term1,term_SecondArgument(Term2),0));
+ } else {
+ misc_StartErrorReport();
+ misc_ErrorReport("In ren_GetRenamings: Unknown first-order operator.");
+ misc_FinishErrorReport();
+ }
+
+ return Result;
+}
+
+static int ren_Polarity(TERM Term)
+/**********************************************************
+ INPUT: A term where the existence of superterms is assumed!.
+ RETURNS: The polarity of Term with respect to its superterms.
+***********************************************************/
+{
+ TERM SuperTerm;
+
+ SuperTerm = term_Superterm(Term);
+
+ if (SuperTerm) {
+ SYMBOL Top;
+ Top = term_TopSymbol(SuperTerm);
+ if (symbol_Equal(Top,fol_And()) || symbol_Equal(Top,fol_Or()) ||
+ fol_IsQuantifier(Top))
+ return ren_Polarity(SuperTerm);
+ if (symbol_Equal(Top,fol_Not()))
+ return (-ren_Polarity(SuperTerm));
+ if (symbol_Equal(Top,fol_Equiv()))
+ return 0;
+ if (symbol_Equal(Top,fol_Implies())) {
+ if (Term == term_FirstArgument(SuperTerm))
+ return (-ren_Polarity(SuperTerm));
+ else
+ return ren_Polarity(SuperTerm);
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("In ren_Polarity: Unknown first-order operator.");
+ misc_FinishErrorReport();
+ }
+
+ return 1;
+}
+
+
+static LIST ren_RemoveTerm(TERM Term, LIST Renamings)
+/**********************************************************
+ INPUT: A formula and a list of renamings.
+ RETURNS: The renaming list where <Term> is removed from
+ the renamings.
+ CAUTION: The list and the renamings are destructively changed.
+***********************************************************/
+{
+ LIST Scan;
+ RENAMING Renaming;
+
+ /* Remove the Term from all renamings. In case the Hit term equals <Term> */
+ /* turn the renaming into a general renaming */
+ for (Scan=Renamings;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Renaming = (RENAMING)list_Car(Scan);
+ if (ren_Hit(Renaming) == Term) {
+ if (list_Empty(ren_Matches(Renaming))) {
+ ren_Delete(Renaming);
+ list_Rplaca(Scan, NULL);
+ }
+ else
+ ren_SetGeneral(Renaming, TRUE);
+ }
+ else
+ ren_SetMatches(Renaming, list_PointerDeleteElement(ren_Matches(Renaming), Term));
+ }
+
+ /* Take care for the NULL pointers */
+ Renamings = list_PointerDeleteElement(Renamings, NULL);
+
+ return Renamings;
+}
+
+static LIST ren_RemoveAllSubterms(TERM Term, LIST Renamings)
+/**********************************************************
+ INPUT: A formula and a list of renamings.
+ RETURNS: The renaming list where <Term> and all its subterms are
+ removed from the renamings.
+ CAUTION: The list and the renamings are destructively changed.
+***********************************************************/
+{
+ Renamings = ren_RemoveTerm(Term, Renamings);
+
+ if (!symbol_IsPredicate(term_TopSymbol(Term))) {
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ Renamings = ren_RemoveAllSubterms(term_SecondArgument(Term), Renamings);
+ else {
+ LIST Scan;
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ Renamings = ren_RemoveAllSubterms(list_Car(Scan), Renamings);
+ }
+ }
+
+ return Renamings;
+}
+
+
+
+static LIST ren_SolveDependencies(LIST Renamings)
+/**********************************************************
+ INPUT: A list of renamings sorted by depth of the hits.
+ RETURNS: The renaming list where dependences are solved, i.e., if
+ a formula occurs in the matches of some renaming, then
+ all its subterms are removed from other renamings, since
+ the formulae of additional matches completely disappear
+ after application of the renaming.
+ In case a subterm is the hit of another renaming but this
+ renaming has further matches, the further matches are turned
+ into new individual renamings.
+ CAUTION: The list and the renamings are destructively changed.
+***********************************************************/
+{
+ LIST Scan;
+ RENAMING Renaming;
+ TERM ActMatch;
+
+ if (list_Empty(Renamings))
+ return Renamings;
+
+ Renaming = (RENAMING)list_Car(Renamings);
+ for (Scan=ren_Matches(Renaming);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ ActMatch = (TERM)list_Car(Scan);
+ list_Rplacd(Renamings, ren_RemoveAllSubterms(ActMatch, list_Cdr(Renamings)));
+ }
+ list_Rplacd(Renamings, ren_SolveDependencies(list_Cdr(Renamings)));
+
+ return Renamings;
+}
+
+
+static TERM ren_FormulaRename(TERM Term, LIST Renamings, PRECEDENCE Precedence,
+ LIST *SkolemSymbols)
+/**********************************************************
+ INPUT: A term and a list of renamings where all
+ dependencies between the renaming terms are
+ solved and a precedence.
+ RETURNS: The renamed formula with respect to the renaming
+ list and all newly introduced Skolem symbols for
+ renamings are added to <SkolemSymbols>.
+ EFFECT: New Skolem predicates are created, and their precedence
+ is set in <Precedence>.
+ CAUTION: The formula <Term> is destructively changed.
+ The renamings are destructively changed.
+***********************************************************/
+{
+ TERM Result,ActTerm,Hit,DefTerm,Superterm,NewTerm;
+ LIST Scan,FreeVariables,Args,AllMatches;
+ SYMBOL ActSymbol;
+ RENAMING Renaming;
+
+ DefTerm = (TERM)NULL;
+ AllMatches = list_Nil();
+
+ if (!list_Empty(Renamings))
+ Result = term_Create(fol_And(),list_List(Term));
+ else
+ return Term;
+
+ ActSymbol = 0;
+
+ while (!list_Empty(Renamings)) {
+
+ Renaming = (RENAMING)list_Car(Renamings);
+ Renamings = list_Cdr(Renamings);
+ Hit = ren_Hit(Renaming);
+ Superterm = term_Superterm(Hit);
+ FreeVariables = fol_FreeVariables(Hit);
+ ActSymbol = symbol_CreateSkolemPredicate(list_Length(FreeVariables),
+ Precedence);
+ *SkolemSymbols = list_Cons((POINTER)ActSymbol,*SkolemSymbols);
+
+ /* printf("\n");fol_PrettyPrintDFG(ren_Hit(Renaming));printf("\n");*/
+
+ /* Install Definition */
+ if (ren_General(Renaming)) /* for general renamings the hit formula will be eventually deleted */
+ Hit = term_Copy(Hit);
+ NewTerm = term_Create(ActSymbol, term_CopyTermList(FreeVariables));
+ switch (ren_OverallPolarity(Renaming)) {
+ case 0:
+ DefTerm = term_Create(fol_Equiv(),list_Cons(term_Copy(NewTerm),list_List(Hit)));
+ break;
+
+ case 1:
+ DefTerm = term_Create(fol_Implies(),list_Cons(term_Copy(NewTerm),list_List(Hit)));
+ break;
+
+ case -1:
+ DefTerm = term_Create(fol_Implies(),list_Cons(Hit,list_List(term_Copy(NewTerm))));
+ break;
+ }
+ term_RplacSuperterm(term_FirstArgument(DefTerm),DefTerm);
+ term_RplacSuperterm(term_SecondArgument(DefTerm),DefTerm);
+ if (!list_Empty(FreeVariables))
+ DefTerm = fol_CreateQuantifier(fol_All(), term_CopyTermList(FreeVariables),
+ list_List(DefTerm));
+ term_RplacArgumentList(Result,list_Nconc(term_ArgumentList(Result),list_List(DefTerm)));
+
+ /* Replace hit if renaming is not general */
+ if (!ren_General(Renaming)) {
+ term_RplacSuperterm(NewTerm, Superterm);
+ for (Args=term_ArgumentList(Superterm);!list_Empty(Args); Args=list_Cdr(Args))
+ if ((TERM)list_Car(Args) == Hit) {
+ list_Rplaca(Args, NewTerm);
+ break;
+ }
+ }
+ else
+ term_Delete(NewTerm);
+
+
+ for (Scan=ren_Matches(Renaming); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+
+ ActTerm = (TERM)list_Car(Scan);
+ Superterm = term_Superterm(ActTerm);
+
+ /* Always make new predicate term */
+ NewTerm = term_Create(ActSymbol, term_CopyTermList(FreeVariables));
+ /* Bind the variables correctly */
+ /*puts("\n"); fol_PrettyPrintDFG(Result);
+ printf("\n Hit:\n"); term_PrettyPrint(Hit);
+ printf("\n ActTerm:\n"); term_PrettyPrint(ActTerm); printf("\n");*/
+ cont_StartBinding();
+ if (unify_MatchFlexible(cont_LeftContext(), Hit, ActTerm))
+ cont_ApplyBindingsModuloMatching(cont_LeftContext(), NewTerm, TRUE);
+ else {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In ren_FormulaRename: Further match is no instance of hit.\n");
+ misc_FinishErrorReport();
+ }
+ cont_BackTrack();
+
+ /* Now replace match */
+ term_RplacSuperterm(NewTerm, Superterm);
+ for (Args=term_ArgumentList(Superterm);!list_Empty(Args); Args=list_Cdr(Args))
+ if (list_Car(Args) == ActTerm) {
+ list_Rplaca(Args, NewTerm);
+ break;
+ }
+ }
+ AllMatches = list_Nconc(ren_Matches(Renaming), AllMatches); /* Delete later due to dependencies */
+ ren_SetMatches(Renaming, list_Nil());
+ list_Delete(FreeVariables);
+ }
+ list_DeleteWithElement(AllMatches, (void (*)(POINTER)) term_Delete);
+ return Result;
+}
+
+static LIST ren_FreeRenaming(LIST Renamings)
+/**********************************************************
+ INPUT: A list of renamings.
+ RETURNS: The list of candidates without renamings that have
+ benefit zero.
+ CAUTION: Destructive.
+***********************************************************/
+{
+ LIST Scan;
+ TERM Father, Term;
+ RENAMING Candidate;
+
+ for (Scan=Renamings;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Candidate = (RENAMING)list_Car(Scan);
+ if (list_Empty(ren_Matches(Candidate))) {
+ Term = ren_Hit(Candidate);
+ Father = term_Superterm(Term);
+ while (!term_HasTermStamp(Father) && term_Superterm(Father)) {
+ Father = term_Superterm(Father);
+ }
+
+ term_ResetTermStamp(Term); /* Needed for P-Factor check */
+ if (ren_General(Candidate) || /* a general renaming without matches is useless */
+ !ren_HasNonZeroBenefit(Father, ren_Polarity(Father),
+ Term, ren_OverallPolarity(Candidate))) {
+ ren_Delete(Candidate);
+ list_Rplaca(Scan,NULL);
+ } else {
+ /* Term will be renamed */
+ term_SetTermStamp(Term); /* Undo temporary change */
+ }
+ }
+ }
+
+ Renamings = list_PointerDeleteElement(Renamings,NULL);
+
+ return Renamings;
+}
+
+static LIST ren_FurtherMatches(TERM Formula, LIST Formulas)
+/**********************************************************
+ INPUT: A formula and a list of formulas that are candidates
+ for renaming inside the formula.
+ RETURNS: A list of renamings where additional matches of
+ the already found formulas in <Formula> are considered.
+ First the most general formula <Hit> of any renaming inside
+ <Formula> is computed, then all instances of <Hit> inside
+ <Formula> built the actual renaming.
+ No formula occurs twice in the resulting renamings.
+***********************************************************/
+{
+ LIST Scan1, Scan2, Allmatches, Matchables, Renamings;
+ TERM Hit;
+ int Polarity, NewPol;
+
+ Allmatches = list_Nil();
+ Renamings = list_Nil();
+
+ for (Scan1=Formulas; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) {
+ Hit = (TERM)list_Car(Scan1);
+
+ if (!list_PointerMember(Allmatches, Hit)) {
+ Matchables = list_Cons(Hit, fol_Generalizations(Formula, Hit));
+ Hit = fol_MostGeneralFormula(Matchables); /* Could be further improved: construct it ! */
+ list_Delete(Matchables);
+
+ if (!list_PointerMember(Allmatches, Hit)) { /* Potentially <Hit> is now different */
+ Allmatches = list_Cons(Hit,Allmatches);
+ Matchables = fol_Instances(Formula, Hit);
+ Polarity = ren_Polarity(Hit);
+
+ for (Scan2=Matchables; !list_Empty(Scan2); Scan2=list_Cdr(Scan2)) {
+ if (list_PointerMember(Allmatches, list_Car(Scan2)))
+ list_Rplaca(Scan2, NULL);
+ else {
+ NewPol = ren_Polarity(list_Car(Scan2));
+ if (NewPol != Polarity)
+ Polarity = 0;
+ }
+ }
+ Matchables = list_PointerDeleteElement(Matchables, NULL);
+ Allmatches = list_Nconc(list_Copy(Matchables), Allmatches);
+ Renamings = list_Cons(ren_Create(Hit, Matchables, Polarity),Renamings);
+ }
+ }
+ }
+ list_Delete(Allmatches);
+
+ return Renamings;
+}
+
+
+TERM ren_Rename(TERM Term, PRECEDENCE Precedence, LIST *SkolemSymbols,
+ BOOL Document, BOOL Match)
+/**********************************************************
+ INPUT: A term, a precedence, a pointer to a list of
+ Skolem symbols, a flag indicating whether the
+ renamings should be documented and a flag
+ indicating whether matching subterms should be
+ renamed using the same predicate.
+ RETURNS: The possibly changed Term where subformulae are renamed
+ if this results in a smaller clause normal form, with
+ respect to the number of clauses. The newly introduced
+ Skolem predicates are added to <SkolemSymbols>.
+ The precedence of the new symbols is set in <Precedence>.
+ CAUTION: Formulae are changed destructively.
+ This function expects that both conjunctions and disjunction
+ have at least two arguments!
+***********************************************************/
+{
+ LIST Renamings, Scan, Formulas;
+
+ Renamings = list_Nil();
+ Formulas = list_Nil();
+
+ if (term_StampOverflow(ren_STAMPID))
+ ren_ResetTermStamp(Term);
+
+#ifdef CHECK
+ fol_CheckFatherLinks(Term);
+#endif
+
+ term_StartStamp();
+
+ Formulas = ren_GetRenamings(Term, Term, 1);
+
+ /* Formulas = list_GreaterNumberSort(Formulas, (NAT (*)(POINTER)) fol_Depth); */
+
+ if (Match)
+ Renamings = ren_FurtherMatches(Term, Formulas);
+ else {
+ for (Scan=Formulas;!list_Empty(Scan);Scan=list_Cdr(Scan))
+ Renamings = list_Cons(ren_Create(list_Car(Scan),list_Nil(),ren_Polarity(list_Car(Scan))),Renamings);
+ }
+
+ Renamings = ren_FreeRenaming(Renamings);
+
+ Renamings = list_Sort(Renamings, (BOOL (*) (POINTER, POINTER))ren_RootDistanceSmaller);
+ /* for dependencies sort renamings top down */
+
+ Renamings = ren_SolveDependencies(Renamings); /* dependencies in further matches */
+
+ Renamings = ren_FreeRenaming(Renamings); /* possibly depency solving has created non-zero benefit renamings */
+
+ if (!list_Empty(Renamings) && Document) {
+ puts("\n\n\t Renaming term:");
+ fol_PrettyPrintDFG(Term);
+ for (Scan=Renamings;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ puts("\n");
+ ren_PrettyPrint((RENAMING)list_Car(Scan));
+ }
+ puts("\n");
+ }
+
+ Term = ren_FormulaRename(Term, Renamings, Precedence, SkolemSymbols);
+
+ if (!list_Empty(Renamings) && Document) {
+ puts("\n\n\t Renamed term:");
+ fol_PrettyPrintDFG(Term);
+ puts("\n");
+ }
+
+ list_DeleteWithElement(Renamings, (void (*)(POINTER)) ren_Delete);
+ list_Delete(Formulas);
+
+ term_StopStamp();
+
+ return Term;
+}
+
+void ren_PrettyPrint(RENAMING Ren)
+/**********************************************************
+ INPUT: A renaming.
+ EFFECT: pretty prints the renaming to <stdout>
+***********************************************************/
+{
+ LIST Matches;
+
+ puts("\t Renaming:");
+ puts("\n\t ========= \n");
+ fol_PrettyPrintDFG(ren_Hit(Ren));
+ puts("\n\n\t Instances:");
+ for (Matches=ren_Matches(Ren); !list_Empty(Matches); Matches=list_Cdr(Matches)) {
+ fol_PrettyPrintDFG(list_Car(Matches));
+ puts("\n");
+ }
+ printf("\n\t Polarity: %d\n", ren_OverallPolarity(Ren));
+ printf("\n\t General : %d\n", (ren_General(Ren) ? 1 : 0));
+}
diff --git a/test/spass/renaming.h b/test/spass/renaming.h
new file mode 100644
index 0000000..663363e
--- /dev/null
+++ b/test/spass/renaming.h
@@ -0,0 +1,168 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * RENAMING * */
+/* * * */
+/* * $Module: REN * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _SPASS_RENAMING_
+#define _SPASS_RENAMING_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "misc.h"
+#include "foldfg.h"
+#include "unify.h"
+#include "vector.h"
+
+/**************************************************************/
+/* Data Structures and Constants */
+/**************************************************************/
+
+typedef struct {
+ TERM hit;
+ LIST matches;
+ BOOL general;
+ int polarity;
+} *RENAMING, RENAMING_NODE;
+
+/* <hit> is the formula that has a positive benefit */
+/* <matches> are further matches of <hit> in the overall formula */
+/* <general> is TRUE iff the <hit> formula must not be replaced but */
+/* is a generalzation of the matches formulae that are to */
+/* be replaced */
+/* <polarity> is the most general polarity of <hit> and all <matches> */
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+
+static __inline__ int ren_OverallPolarity(RENAMING ren)
+{
+ return ren->polarity;
+}
+
+static __inline__ TERM ren_Hit(RENAMING ren)
+{
+ return ren->hit;
+}
+
+static __inline__ LIST ren_Matches(RENAMING ren)
+{
+ return ren->matches;
+}
+
+static __inline__ BOOL ren_General(RENAMING ren)
+{
+ return ren->general;
+}
+
+static __inline__ void ren_SetMatches(RENAMING ren, LIST matches)
+{
+ ren->matches = matches;
+}
+
+static __inline__ void ren_SetHit(RENAMING ren, TERM hit)
+{
+ ren->hit = hit;
+}
+
+static __inline__ void ren_SetOverallPolarity(RENAMING ren, int polarity)
+{
+ ren->polarity = polarity;
+}
+
+static __inline__ void ren_SetGeneral(RENAMING ren, BOOL general)
+{
+ ren->general = general;
+}
+
+
+
+static __inline__ RENAMING ren_Create(TERM hit, LIST matches, int polarity)
+/**************************************************************
+ INPUT: A formula, a list of further matching formulae
+ and the overall polarity of the <hit> and the further <matches>.
+ RETURNS: A new renaming object, which is initialized.
+ General is set to false.
+ MEMORY: Allocates memory for the RENAMING.
+***************************************************************/
+{
+ RENAMING Result;
+
+ Result = (RENAMING)memory_Malloc(sizeof(RENAMING_NODE));
+ Result->hit = hit;
+ Result->matches = matches;
+ Result->polarity = polarity;
+ Result->general = FALSE;
+
+ return Result;
+}
+
+static __inline__ void ren_Delete(RENAMING ren)
+/**************************************************************
+ INPUT: A renaming.
+ RETURNS: void.
+ MEMORY: Frees memory for the RENAMING and the matches list.
+ Formulae are not deleted.
+***************************************************************/
+{
+ list_Delete(ren->matches);
+ memory_Free(ren,sizeof(RENAMING_NODE));
+}
+
+
+/**************************************************************/
+/* Function Prototypes */
+/**************************************************************/
+
+void ren_Init(void);
+TERM ren_Rename(TERM, PRECEDENCE, LIST*,BOOL, BOOL);
+void ren_PrettyPrint(RENAMING);
+
+#endif
diff --git a/test/spass/resolution.c b/test/spass/resolution.c
new file mode 100644
index 0000000..96e4bff
--- /dev/null
+++ b/test/spass/resolution.c
@@ -0,0 +1,178 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * RESOLUTION * */
+/* * * */
+/* * $Module: RESOLUTION * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "resolution.h"
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+
+void res_InsertClauseIndex(CLAUSE clause, st_INDEX stindex)
+/**********************************************************
+ INPUT: A st_INDEX and a clause.
+ RETURNS: Inserts the clause in the st_INDEX stindex.
+ CAUTION: None.
+***********************************************************/
+{
+ int n,j;
+
+ n = clause_Length(clause);
+ for (j = 0; j < n; j++)
+ st_EntryCreate(stindex,
+ clause_GetLiteral(clause,j),
+ clause_GetLiteralTerm(clause,j),
+ cont_LeftContext());
+}
+
+
+void res_DeleteClauseIndex(CLAUSE clause, st_INDEX stindex)
+/**********************************************************
+ INPUT: A st_INDEX and a clause.
+ RETURNS: Deletes the clause from the st_INDEX stindex.
+ CAUTION: None.
+***********************************************************/
+{
+ int n, j;
+
+ n = clause_Length(clause);
+ for (j = 0; j < n; j++)
+ if (!st_EntryDelete(stindex,
+ clause_GetLiteral(clause,j),
+ clause_GetLiteralTerm(clause,j),
+ cont_LeftContext()))
+ misc_DumpCore();
+}
+
+
+
+CLAUSE res_SelectLightestClause(LIST clauselist)
+/**********************************************************
+ INPUT: A list of clauses.
+ RETURNS: The lightest clause of the clauselist.
+ CAUTION: None.
+***********************************************************/
+{
+ CLAUSE clause;
+ LIST scan;
+ int min;
+
+ clause = list_Car(clauselist);
+ min = clause_Weight(clause);
+
+ for (scan=list_Cdr(clauselist); !list_Empty(scan); scan=list_Cdr(scan)) {
+ if (clause_Weight(list_Car(scan)) < min) {
+ clause = list_Car(scan);
+ min = clause_Weight(clause);
+ }
+ }
+ return clause;
+}
+
+
+BOOL res_HasTautology(CLAUSE clause)
+/**********************************************************
+ INPUT: A clauses.
+ RETURNS: TRUE if the clause contains a complementary
+ literal pair and FALSE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ BOOL found;
+ TERM literal1;
+ int i, j, n;
+
+ found = FALSE;
+ n = clause_Length(clause);
+
+ for (i = 0; i < n && !found; i++) {
+ literal1 = fol_ComplementaryTerm(clause_GetLiteralTerm(clause,i));
+ for (j = 0; j < n && !found; j++)
+ if (j != i && term_Equal(literal1, clause_GetLiteralTerm(clause,j)))
+ found = TRUE;
+
+ term_Delete(literal1);
+ }
+ return found;
+}
+
+
+
+BOOL res_BackSubWithLength(CLAUSE clause, st_INDEX stindex)
+/**********************************************************
+ INPUT: A clauses and an index.
+ RETURNS: TRUE if a clause of the index subsumes the clause clause
+ and length(clause) >= length(clause of index).
+ CAUTION: None.
+***********************************************************/
+{
+ int n,i;
+ LIST scan,generals;
+ TERM term;
+ LITERAL litres;
+
+ n = clause_Length(clause);
+ for (i = 0; i < n; i++) {
+ term = clause_GetLiteralTerm(clause,i);
+ generals = st_GetGen(cont_LeftContext(), stindex, term);
+ for (scan = generals; !list_Empty(scan); scan = list_Cdr(scan)) {
+ litres = (LITERAL) list_Car(scan);
+ if (litres == clause_GetLiteral(clause_LiteralOwningClause(litres),0) &&
+ clause_Length(clause) >= clause_Length(clause_LiteralOwningClause(litres)) &&
+ clause_Weight(clause) >= clause_Weight(clause_LiteralOwningClause(litres)) &&
+ subs_Idc(clause_LiteralOwningClause(litres),clause)) {
+ list_Delete(generals);
+ return TRUE;
+ }
+ }
+ list_Delete(generals);
+ }
+ return FALSE;
+}
+
+
diff --git a/test/spass/resolution.h b/test/spass/resolution.h
new file mode 100644
index 0000000..1b29779
--- /dev/null
+++ b/test/spass/resolution.h
@@ -0,0 +1,73 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * RESOLUTION * */
+/* * * */
+/* * $Module: RESOLUTION * */
+/* * * */
+/* * Copyright (C) 1996, 1998, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+#ifndef _RESOLUTION_
+#define _RESOLUTION_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "misc.h"
+#include "unify.h"
+#include "symbol.h"
+#include "foldfg.h"
+#include "st.h"
+#include "subsumption.h"
+#include "condensing.h"
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+
+void res_InsertClauseIndex(CLAUSE, st_INDEX); /* used by cnf */
+void res_DeleteClauseIndex(CLAUSE, st_INDEX); /* used by cnf */
+CLAUSE res_SelectLightestClause(LIST); /* used by cnf */
+BOOL res_BackSubWithLength(CLAUSE, st_INDEX); /* used by cnf */
+BOOL res_HasTautology(CLAUSE); /* used by cnf */
+
+#endif
diff --git a/test/spass/rpos.c b/test/spass/rpos.c
new file mode 100644
index 0000000..edd1b8b
--- /dev/null
+++ b/test/spass/rpos.c
@@ -0,0 +1,521 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * RECURSIVE PATH ORDERING WITH STATUS * */
+/* * * */
+/* * $Module: RPOS * */
+/* * * */
+/* * Copyright (C) 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "rpos.h"
+
+
+/**************************************************************/
+/* Top Down Version */
+/**************************************************************/
+
+static LIST rpos_MultisetDifference(TERM T1, TERM T2)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: The multiset difference between the arguments
+ of both terms with respect to rpos_Equal.
+***************************************************************/
+{
+ LIST result;
+
+ result = list_Copy(term_ArgumentList(T1));
+ result = list_NMultisetDifference(result, term_ArgumentList(T2),
+ (BOOL (*)(POINTER,POINTER)) rpos_Equal);
+ return result;
+}
+
+
+static ord_RESULT rpos_MulGreaterEqual(TERM T1, TERM T2)
+/**************************************************************
+ INPUT: Two terms with equal top symbols and multiset status.
+ RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>,
+ ord_EQUAL if both terms are equal and
+ ord_UNCOMPARABLE otherwise.
+***************************************************************/
+{
+ LIST l1, l2;
+
+ l1 = rpos_MultisetDifference(T1, T2);
+ if (list_Empty(l1))
+ /* If |M| = |N| and M-N = {} then N-M = {} */
+ return ord_Equal(); /* Terms are equal */
+ else {
+ LIST scan;
+ BOOL greater;
+
+ l2 = rpos_MultisetDifference(T2, T1);
+
+ for (greater = TRUE; !list_Empty(l2) && greater; l2 = list_Pop(l2)) {
+ for (scan = l1, greater = FALSE; !list_Empty(scan) && !greater; scan = list_Cdr(scan))
+ greater = rpos_Greater(list_Car(scan), list_Car(l2));
+ }
+ list_Delete(l1); /* l2 was freed in the outer for loop */
+ if (greater)
+ return ord_GreaterThan();
+ else
+ return ord_Uncomparable();
+ }
+}
+
+static ord_RESULT rpos_LexGreaterEqual(TERM T1, TERM T2)
+/**************************************************************
+ INPUT: Two terms with equal top symbols and lexicographic status.
+ RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>,
+ ord_EQUAL if both terms are equal and
+ ord_UNCOMPARABLE otherwise.
+***************************************************************/
+{
+ ord_RESULT result;
+ LIST l1, l2, scan1, scan2;
+
+ if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
+ l1 = list_Reverse(term_ArgumentList(T1)); /* Create new lists */
+ l2 = list_Reverse(term_ArgumentList(T2));
+ } else {
+ l1 = term_ArgumentList(T1);
+ l2 = term_ArgumentList(T2);
+ }
+ /* First ignore equal arguments */
+ result = ord_Equal();
+ for (scan1 = l1, scan2 = l2; !list_Empty(scan1);
+ scan1 = list_Cdr(scan1), scan2 = list_Cdr(scan2)) {
+ result = rpos_GreaterEqual(list_Car(scan1), list_Car(scan2));
+ if (!ord_IsEqual(result))
+ break;
+ }
+
+ if (ord_IsEqual(result)) /* All arguments are equal, so the terms */
+ /* empty */; /* are equal with respect to RPOS */
+ else if (ord_IsGreaterThan(result)) {
+ /* Check if T1 > each remaining argument of T2 */
+ for (scan2 = list_Cdr(scan2); !list_Empty(scan2) && rpos_Greater(T1, list_Car(scan2));
+ scan2 = list_Cdr(scan2)); /* Empty body */
+ if (list_Empty(scan2))
+ result = ord_GreaterThan();
+ else
+ result = ord_Uncomparable();
+ }
+ else {
+ /* Argument of T1 was not >= argument of T2. */
+
+ /* Try to find an argument of T1 that is >= T2 */
+ for (scan1 = list_Cdr(scan1), result = ord_Uncomparable();
+ !list_Empty(scan1) && !ord_IsGreaterThan(result);
+ scan1 = list_Cdr(scan1)) {
+ if (!ord_IsUncomparable(rpos_GreaterEqual(list_Car(scan1), T2)))
+ result = ord_GreaterThan();
+ }
+ }
+
+ if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
+ list_Delete(l1); /* Delete the lists create above */
+ list_Delete(l2);
+ }
+ return result;
+}
+
+
+BOOL rpos_Equal(TERM T1, TERM T2)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: TRUE, if <T1> is equal to <T2> and
+ FALSE otherwise.
+***************************************************************/
+{
+ LIST l1, l2;
+
+ if (!term_EqualTopSymbols(T1, T2))
+ return FALSE;
+ else if (!term_IsComplex(T1)) /* Equal variable or constant */
+ return TRUE;
+ else {
+ if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) { /* MUL case */
+ l1 = rpos_MultisetDifference(T1, T2);
+ if (list_Empty(l1))
+ return TRUE;
+ else {
+ list_Delete(l1);
+ return FALSE;
+ }
+ } else { /* LEX case */
+ for (l1 = term_ArgumentList(T1), l2 = term_ArgumentList(T2);
+ !list_Empty(l1) && rpos_Equal(list_Car(l1), list_Car(l2));
+ l1 = list_Cdr(l1), l2 = list_Cdr(l2))
+ /* empty */;
+ return list_Empty(l1); /* All arguments were equal */
+ }
+ }
+}
+
+
+ord_RESULT rpos_GreaterEqual(TERM T1, TERM T2)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>
+ ord_EQUAL if both terms are equal
+ ord_UNCOMPARABLE otherwise.
+ CAUTION: The precedence from the order module is used to determine
+ the precedence of symbols!
+***************************************************************/
+{
+ LIST scan;
+
+ if (term_IsVariable(T1)) {
+ if (term_EqualTopSymbols(T1, T2))
+ return ord_Equal(); /* T2 is the same variable */
+ else
+ /* A variable can't be greater than another term */
+ return ord_Uncomparable();
+ } else if (term_IsVariable(T2)) { /* T1 isn't a variable */
+ if (term_ContainsSymbol(T1, term_TopSymbol(T2)))
+ return ord_GreaterThan();
+ else
+ return ord_Uncomparable();
+ } else if (term_EqualTopSymbols(T1, T2)) {
+ if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL))
+ return rpos_MulGreaterEqual(T1, T2);
+ else
+ return rpos_LexGreaterEqual(T1, T2);
+ } else {
+ if (symbol_PrecedenceGreater(ord_PRECEDENCE, term_TopSymbol(T1),
+ term_TopSymbol(T2))) {
+ /* Different top symbols, symbol of T1 > symbol of T2. */
+ /* Try if T1 > each argument of T2. */
+ for (scan = term_ArgumentList(T2); !list_Empty(scan); scan = list_Cdr(scan))
+ if (!rpos_Greater(T1, list_Car(scan)))
+ return ord_Uncomparable();
+ return ord_GreaterThan();
+ } else {
+ /* Try to find an argument of T1 that is >= T2 */
+ for (scan = term_ArgumentList(T1); !list_Empty(scan); scan = list_Cdr(scan))
+ if (!ord_IsUncomparable(rpos_GreaterEqual(list_Car(scan), T2)))
+ return ord_GreaterThan(); /* Argument of T1 >= T2 */
+ return ord_Uncomparable();
+ }
+ }
+}
+
+ord_RESULT rpos_Compare(TERM T1, TERM T2)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: The relation between the two terms with respect to the
+ RPOS ordering:
+ ord_GREATER_THAN if <T1> is greater than <T2>,
+ ord_EQUAL if both terms are equal,
+ ord_SMALLER_THAN if <T2> is greater than <T1> and
+ ord_UNCOMPARABLE otherwise.
+ CAUTION: The precedence from the order module is used to determine
+ the precedence of symbols!
+***************************************************************/
+{
+ ord_RESULT result;
+
+ result = rpos_GreaterEqual(T1, T2);
+ if (!ord_IsUncomparable(result))
+ return result;
+ else if (rpos_Greater(T2, T1))
+ return ord_SmallerThan();
+ else
+ return ord_UNCOMPARABLE;
+}
+
+/**************************************************************/
+/* Term comparison with respect to bindings */
+/**************************************************************/
+
+static LIST rpos_ContMultisetDifference(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2)
+/**************************************************************
+ INPUT: Two contexts and two terms.
+ RETURNS: The multiset difference between the arguments
+ of both terms with respect to rpos_ContEqual.
+ EFFECT: Variable bindings are considered.
+***************************************************************/
+{
+ LIST result, scan1, scan2;
+
+ /* Don't apply bindings at top level, since that happened */
+ /* in rpos_ContGreaterEqual */
+
+ /* We can't use list_NMultisetDifference, since that function */
+ /* expects an equality functions for terms that takes two terms */
+ /* as arguments. We also need the two contexts resolve variable */
+ /* bindings. */
+ result = list_Copy(term_ArgumentList(T1));
+ for (scan2 = term_ArgumentList(T2); !list_Empty(scan2);
+ scan2 = list_Cdr(scan2)) {
+ /* Delete at most one occurrence of the */
+ /* current element of list2 from list1 */
+ for (scan1 = result; !list_Empty(scan1); scan1 = list_Cdr(scan1)) {
+ if (list_Car(scan1) != NULL &&
+ rpos_ContEqual(C1, list_Car(scan1), C2, list_Car(scan2))) {
+ /* arg of list1 wasn't deleted earlier and terms are equal */
+ list_Rplaca(scan1, NULL); /* Mark argument of T1 as deleted */
+ break;
+ }
+ }
+ }
+ return list_PointerDeleteElement(result, NULL); /* Delete all marked terms */
+}
+
+
+static ord_RESULT rpos_ContMulGreaterEqual(CONTEXT C1, TERM T1,
+ CONTEXT C2, TERM T2)
+/**************************************************************
+ INPUT: Two contexts and two terms with equal top symbols
+ and multiset status.
+ RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>,
+ ord_EQUAL if both terms are equal and
+ ord_UNCOMPARABLE otherwise.
+ EFFECT: Variable bindings are considered.
+***************************************************************/
+{
+ LIST l1, l2;
+
+ /* Don't apply bindings at top level, since that happened */
+ /* in rpos_ContGreaterEqual. */
+
+ l1 = rpos_ContMultisetDifference(C1, T1, C2, T2);
+ if (list_Empty(l1))
+ /* If |M| = |N| and M-N = {} then N-M = {} */
+ return ord_Equal(); /* Terms are equal */
+ else {
+ LIST scan;
+ BOOL greater;
+
+ l2 = rpos_ContMultisetDifference(C2, T2, C1, T1);
+
+ for (greater = TRUE; !list_Empty(l2) && greater; l2 = list_Pop(l2)) {
+ for (scan = l1, greater = FALSE; !list_Empty(scan) && !greater;
+ scan = list_Cdr(scan))
+ greater = rpos_ContGreater(C1, list_Car(scan), C2, list_Car(l2));
+ }
+ list_Delete(l1); /* l2 was freed in the outer for loop */
+ if (greater)
+ return ord_GreaterThan();
+ else
+ return ord_Uncomparable();
+ }
+}
+
+static ord_RESULT rpos_ContLexGreaterEqual(CONTEXT C1, TERM T1,
+ CONTEXT C2, TERM T2)
+/**************************************************************
+ INPUT: Two contexts and two terms with equal top symbols
+ and lexicographic status.
+ RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>,
+ ord_EQUAL if both terms are equal and
+ ord_UNCOMPARABLE otherwise.
+ EFFECT: Variable bindings are considered.
+***************************************************************/
+{
+ ord_RESULT result;
+ LIST l1, l2, scan1, scan2;
+
+ /* Don't apply bindings at top level, since that happened */
+ /* in rpos_ContGreaterEqual */
+
+ if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
+ l1 = list_Reverse(term_ArgumentList(T1)); /* Create new lists */
+ l2 = list_Reverse(term_ArgumentList(T2));
+ } else {
+ l1 = term_ArgumentList(T1);
+ l2 = term_ArgumentList(T2);
+ }
+ /* First ignore equal arguments */
+ result = ord_Equal();
+ for (scan1 = l1, scan2 = l2; !list_Empty(scan1);
+ scan1 = list_Cdr(scan1), scan2 = list_Cdr(scan2)) {
+ result = rpos_ContGreaterEqual(C1, list_Car(scan1), C2, list_Car(scan2));
+ if (!ord_IsEqual(result))
+ break;
+ }
+
+ if (ord_IsEqual(result)) /* All arguments are equal, so the terms */
+ /* empty */; /* are equal with respect to RPOS */
+ else if (ord_IsGreaterThan(result)) {
+ /* Check if T1 > each remaining argument of T2 */
+ for (scan2 = list_Cdr(scan2);
+ !list_Empty(scan2) && rpos_ContGreater(C1, T1, C2, list_Car(scan2));
+ scan2 = list_Cdr(scan2)); /* Empty body */
+ if (list_Empty(scan2))
+ result = ord_GreaterThan();
+ else
+ result = ord_Uncomparable();
+ }
+ else {
+ /* Argument of T1 was not >= argument of T2. */
+ /* Try to find an argument of T1 that is >= T2 */
+ for (scan1 = list_Cdr(scan1), result = ord_Uncomparable();
+ !list_Empty(scan1) && !ord_IsGreaterThan(result);
+ scan1 = list_Cdr(scan1)) {
+ if (!ord_IsUncomparable(rpos_ContGreaterEqual(C1,list_Car(scan1),C2,T2)))
+ result = ord_GreaterThan();
+ }
+ }
+
+ if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
+ list_Delete(l1); /* Delete the lists create above */
+ list_Delete(l2);
+ }
+ return result;
+}
+
+
+BOOL rpos_ContEqual(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2)
+/**************************************************************
+ INPUT: Two contexts and two terms.
+ RETURNS: TRUE, if <T1> is equal to <T2> and
+ FALSE otherwise.
+ EFFECT: Variable bindings are considered.
+***************************************************************/
+{
+ LIST l1, l2;
+
+ T1 = cont_Deref(&C1, T1);
+ T2 = cont_Deref(&C2, T2);
+
+ if (!term_EqualTopSymbols(T1, T2))
+ return FALSE;
+ else if (!term_IsComplex(T1))
+ return TRUE;
+ else {
+ if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) {
+ l1 = rpos_ContMultisetDifference(C1, T1, C2, T2);
+ if (list_Empty(l1))
+ return TRUE;
+ else {
+ list_Delete(l1);
+ return FALSE;
+ }
+ } else { /* LEX case */
+ for (l1 = term_ArgumentList(T1), l2 = term_ArgumentList(T2);
+ !list_Empty(l1) && rpos_ContEqual(C1,list_Car(l1),C2,list_Car(l2));
+ l1 = list_Cdr(l1), l2 = list_Cdr(l2)); /* empty body */
+ return list_Empty(l1); /* All arguments were equal */
+ }
+ }
+}
+
+
+ord_RESULT rpos_ContGreaterEqual(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2)
+/**************************************************************
+ INPUT: Two contexts and two terms.
+ RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>
+ ord_EQUAL if both terms are equal
+ ord_UNCOMPARABLE otherwise.
+ EFFECT: Variable bindings are considered.
+ CAUTION: The precedence from the order module is used to determine
+ the precedence of symbols!
+***************************************************************/
+{
+ LIST scan;
+
+ T1 = cont_Deref(&C1, T1);
+ T2 = cont_Deref(&C2, T2);
+
+ if (term_IsVariable(T1)) {
+ if (term_EqualTopSymbols(T1, T2))
+ return ord_Equal(); /* T2 is the same variable */
+ else
+ /* A variable can't be greater than another term */
+ return ord_Uncomparable();
+ } else if (term_IsVariable(T2)) { /* T1 isn't a variable */
+ if (cont_TermContainsSymbol(C1, T1, term_TopSymbol(T2)))
+ return ord_GreaterThan();
+ else
+ return ord_Uncomparable();
+ } else if (term_EqualTopSymbols(T1, T2)) {
+ if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL))
+ return rpos_ContMulGreaterEqual(C1, T1, C2, T2);
+ else
+ return rpos_ContLexGreaterEqual(C1, T1, C2, T2);
+ } else {
+ if (symbol_PrecedenceGreater(ord_PRECEDENCE, term_TopSymbol(T1),
+ term_TopSymbol(T2))) {
+ /* Different top symbols, symbol of T1 > symbol of T2. */
+ /* Try if T1 > each argument of T2. */
+ for (scan = term_ArgumentList(T2); !list_Empty(scan); scan = list_Cdr(scan))
+ if (!rpos_ContGreater(C1, T1, C2, list_Car(scan)))
+ return ord_Uncomparable();
+ return ord_GreaterThan();
+ } else {
+ /* Try to find an argument of T1 that is >= T2 */
+ for (scan = term_ArgumentList(T1); !list_Empty(scan); scan = list_Cdr(scan))
+ if (!ord_IsUncomparable(rpos_ContGreaterEqual(C1,list_Car(scan),C2,T2)))
+ return ord_GreaterThan(); /* Argument of T1 >= T2 */
+ return ord_Uncomparable();
+ }
+ }
+}
+
+ord_RESULT rpos_ContCompare(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2)
+/**************************************************************
+ INPUT: Two contexts and two terms.
+ RETURNS: The relation between the two terms with respect to the
+ RPOS ordering:
+ ord_GREATER_THAN if <T1> is greater than <T2>,
+ ord_EQUAL if both terms are equal,
+ ord_SMALLER_THAN if <T2> is greater than <T1> and
+ ord_UNCOMPARABLE otherwise.
+ EFFECT: Variable bindings are considered.
+ CAUTION: The precedence from the order module is used to determine
+ the precedence of symbols!
+***************************************************************/
+{
+ ord_RESULT result;
+
+ T1 = cont_Deref(&C1, T1);
+ T2 = cont_Deref(&C2, T2);
+
+ result = rpos_ContGreaterEqual(C1, T1, C2, T2);
+ if (!ord_IsUncomparable(result))
+ return result;
+ else if (rpos_ContGreater(C2, T2, C1, T1))
+ return ord_SmallerThan();
+ else
+ return ord_UNCOMPARABLE;
+}
+
diff --git a/test/spass/rpos.h b/test/spass/rpos.h
new file mode 100644
index 0000000..6cef9e8
--- /dev/null
+++ b/test/spass/rpos.h
@@ -0,0 +1,82 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * RECURSIVE PATH ORDERING WITH STATUS * */
+/* * * */
+/* * $Module: RPOS * */
+/* * * */
+/* * Copyright (C) 1997, 1998 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _RPOS_
+#define _RPOS_
+
+#include "misc.h"
+#include "term.h"
+#include "order.h"
+#include "context.h"
+
+/**************************************************************/
+/* Function Prototypes */
+/**************************************************************/
+
+BOOL rpos_Equal(TERM, TERM);
+ord_RESULT rpos_GreaterEqual(TERM, TERM);
+ord_RESULT rpos_Compare(TERM, TERM);
+
+BOOL rpos_ContEqual(CONTEXT, TERM, CONTEXT, TERM);
+ord_RESULT rpos_ContGreaterEqual(CONTEXT, TERM, CONTEXT, TERM);
+ord_RESULT rpos_ContCompare(CONTEXT, TERM, CONTEXT, TERM);
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+static __inline__ BOOL rpos_Greater(TERM T1, TERM T2)
+{
+ return ord_IsGreaterThan(rpos_GreaterEqual(T1, T2));
+}
+
+static __inline__ BOOL rpos_ContGreater(CONTEXT C1, TERM T1,
+ CONTEXT C2, TERM T2)
+{
+ return ord_IsGreaterThan(rpos_ContGreaterEqual(C1, T1, C2, T2));
+}
+
+#endif
diff --git a/test/spass/rules-inf.c b/test/spass/rules-inf.c
new file mode 100644
index 0000000..38bbaa6
--- /dev/null
+++ b/test/spass/rules-inf.c
@@ -0,0 +1,4281 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INFERENCE RULES * */
+/* * * */
+/* * $Module: INFRULES * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "rules-inf.h"
+
+
+/**************************************************************/
+/* Some auxiliary functions for testing postconditions */
+/**************************************************************/
+
+static BOOL inf_LitMax(CLAUSE Clause, int i, int j, SUBST Subst, BOOL Strict,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, the index of a maximal literal, another
+ literal index, a substitution, a boolean flag, a
+ flag store and a precedence.
+ RETURNS: If <Strict>=FALSE the function returns TRUE iff the
+ literal at index <i> is still maximal in the
+ instantiated clause.
+ If <Strict>=TRUE the function returns TRUE iff the
+ literal is STRICTLY maximal in the instantiated
+ clause. The literal at index j is omitted at literal
+ comparison.
+ However, setting j to a negative number ensures that
+ all literals are compared with the literal at
+ index <i>.
+ CAUTION: DON'T call this function with a clause with selected
+ literals!
+***************************************************************/
+{
+ TERM Max, LitTerm;
+ LITERAL Lit;
+ ord_RESULT Compare;
+ int k, l;
+
+#ifdef CHECK
+ if (!clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)) ||
+ (Strict &&
+ !clause_LiteralGetFlag(clause_GetLiteral(Clause, i), STRICTMAXIMAL))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_LitMax: Literal %d isn't %smaximal.",
+ i, Strict ? "strictly " : "");
+ misc_FinishErrorReport();
+ }
+ if (i < clause_FirstAntecedentLitIndex(Clause) ||
+ i > clause_LastSuccedentLitIndex(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_LitMax: Literal index %d is out of range.", i);
+ misc_FinishErrorReport();
+ }
+ /* If literal <i> is selected, there's no need to check for maximality, */
+ /* if <i> isn't selected, but there're other literals selected, */
+ /* inferences with literal <i> are forbidden. */
+ if (clause_GetFlag(Clause, CLAUSESELECT)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_LitMax: There're selected literals.", i);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Lit = clause_GetLiteral(Clause, i);
+ /* Check necessary condition */
+ if (!clause_LiteralIsMaximal(Lit) ||
+ (Strict && !clause_LiteralGetFlag(Lit, STRICTMAXIMAL)))
+ return FALSE;
+ /* Only antecedent and succedent literals are compared, so if there's */
+ /* only one such literal, it's maximal. */
+ /* If the substitution is empty, the necessary condition tested above */
+ /* is sufficient, too. */
+ if ((clause_NumOfAnteLits(Clause) + clause_NumOfSuccLits(Clause) == 1) ||
+ subst_Empty(Subst))
+ return TRUE;
+
+ l = clause_LastSuccedentLitIndex(Clause);
+ Max = subst_Apply(Subst,term_Copy(clause_GetLiteralTerm(Clause,i)));
+
+ for (k = clause_FirstAntecedentLitIndex(Clause); k <= l; k++)
+ if (k != i && k != j &&
+ clause_LiteralIsMaximal(clause_GetLiteral(Clause, k))) {
+ /* Only compare with maximal literals, since for every non-maximal */
+ /* literal, there's at least one maximal literal, that is bigger. */
+ LitTerm = subst_Apply(Subst,term_Copy(clause_GetLiteralTerm(Clause,k)));
+ Compare = ord_LiteralCompare(Max,
+ clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)),
+ LitTerm,
+ clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,k)),
+ TRUE, Flags, Precedence);
+ if (Compare == ord_SmallerThan() || (Strict && Compare == ord_Equal())) {
+ term_Delete(Max);
+ term_Delete(LitTerm);
+ return FALSE;
+ }
+ term_Delete(LitTerm);
+ }
+ term_Delete(Max);
+
+ return TRUE;
+}
+
+
+static BOOL inf_LiteralsMax(CLAUSE Clause, int i, SUBST Subst,
+ CLAUSE PartnerClause, int j, SUBST PartnerSubst,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: The parents of a resolution inference, the respective
+ literal indices and substitutions, a flag store and
+ a precedence.
+ RETURNS: TRUE iff the positive/negative literals are still
+ strictly maximal/maximal in the instantiated clause.
+ If a negative literal is selected, no comparison
+ is made.
+***************************************************************/
+{
+#ifdef CHECK
+ if ((clause_GetFlag(Clause, CLAUSESELECT) &&
+ !clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT)) ||
+ (clause_GetFlag(PartnerClause, CLAUSESELECT) &&
+ !clause_LiteralGetFlag(clause_GetLiteral(PartnerClause,j),LITSELECT))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_LiteralsMax: Another literal is selected.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!clause_GetFlag(Clause, CLAUSESELECT) &&
+ !inf_LitMax(Clause,i,-1,Subst,
+ i>clause_LastAntecedentLitIndex(Clause),Flags, Precedence))
+ return FALSE;
+ if (!clause_GetFlag(PartnerClause, CLAUSESELECT) &&
+ !inf_LitMax(PartnerClause,j,-1,PartnerSubst,
+ j>clause_LastAntecedentLitIndex(PartnerClause), Flags, Precedence))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+static BOOL inf_LitMaxWith2Subst(CLAUSE Clause, int i, int j, SUBST Subst2,
+ SUBST Subst1, BOOL Strict, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, the index of a maximal literal, another
+ literal index, two substitutions, a boolean flag,
+ a flag store and a precedence.
+ RETURNS: In contrast to the function inf_LitMax this function
+ compares the literals with respect to the composition
+ of the two substitutions Subst2 ° Subst1.
+ If <Strict>=FALSE the function returns TRUE iff the
+ literal at index <i> is still maximal in the
+ instantiated clause.
+ If <Strict>=TRUE the function returns TRUE iff the
+ literal is STRICTLY maximal in the instantiated
+ clause.
+ The literal at index j is omitted at literal
+ comparison.
+ However, setting j to a negative number ensures that
+ all literals are compared with the literal at
+ index <i>.
+ CAUTION: DON'T call this function with a clause with selected
+ literals!
+***************************************************************/
+{
+ TERM Max, LitTerm;
+ LITERAL Lit;
+ ord_RESULT Compare;
+ int k, l;
+
+#ifdef CHECK
+ if (!clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)) ||
+ (Strict &&
+ !clause_LiteralGetFlag(clause_GetLiteral(Clause, i), STRICTMAXIMAL))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_LitMaxWith2Subst: Literal %d isn't %smaximal.",
+ i, Strict ? "strictly " : "");
+ misc_FinishErrorReport();
+ }
+ if (i < clause_FirstAntecedentLitIndex(Clause) ||
+ i > clause_LastSuccedentLitIndex(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_LitMaxWith2Subst: Literal index %d is out of range.", i);
+ misc_FinishErrorReport();
+ }
+ /* If literal <i> is selected, there's no need to check for maximality, */
+ /* if <i> isn't selected, but there're other literals selected, */
+ /* inferences with literal <i> are forbidden. */
+ if (clause_GetFlag(Clause, CLAUSESELECT)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_LitMaxWith2Subst: There're selected literals.", i);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Lit = clause_GetLiteral(Clause, i);
+ /* Check necessary condition */
+ if (!clause_LiteralIsMaximal(Lit) ||
+ (Strict && !clause_LiteralGetFlag(Lit, STRICTMAXIMAL)))
+ return FALSE;
+ /* Only antecedent and succedent literals are compared, so if there's */
+ /* only one such literal, it's maximal. */
+ /* If both substitutions are empty, the necessary condition tested above */
+ /* is sufficient, too. */
+ if ((clause_NumOfAnteLits(Clause) + clause_NumOfSuccLits(Clause) == 1) ||
+ (subst_Empty(Subst1) && subst_Empty(Subst2)))
+ return TRUE;
+
+ l = clause_LastSuccedentLitIndex(Clause);
+ Max = subst_Apply(Subst1, term_Copy(clause_GetLiteralTerm(Clause,i)));
+ Max = subst_Apply(Subst2, Max);
+
+ for (k = clause_FirstAntecedentLitIndex(Clause); k <= l; k++)
+ if (k != i && k != j &&
+ clause_LiteralIsMaximal(clause_GetLiteral(Clause, k))) {
+ /* Only compare with maximal literals, since for every non-maximal */
+ /* literal, there's at least one maximal literal, that is bigger. */
+ LitTerm = subst_Apply(Subst1,term_Copy(clause_GetLiteralTerm(Clause,k)));
+ LitTerm = subst_Apply(Subst2, LitTerm);
+ Compare = ord_LiteralCompare(Max,
+ clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)),
+ LitTerm,
+ clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,k)),
+ TRUE, Flags, Precedence);
+ if (Compare == ord_SmallerThan() || (Strict && Compare == ord_Equal())) {
+ term_Delete(Max);
+ term_Delete(LitTerm);
+ return FALSE;
+ }
+ term_Delete(LitTerm);
+ }
+ term_Delete(Max);
+
+ return TRUE;
+}
+
+
+static BOOL inf_LiteralsMaxWith2Subst(CLAUSE Clause, int i, CLAUSE PartnerClause,
+ int j, SUBST Subst2, SUBST Subst1,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: The parents of a resolution inference, the
+ respective literal indices and substitutions, a
+ flag store and a precedence.
+ RETURNS: In contrast to the function inf_LiteralsMax
+ the composition Subst2 ° Subst1 is applied to both
+ clauses.
+ The function returns TRUE iff the positive/negative
+ literals are still strictly maximal/maximal in the
+ instantiated clause.
+ If a negative literal is selected, no comparison
+ is made.
+***************************************************************/
+{
+#ifdef CHECK
+ if ((clause_GetFlag(Clause, CLAUSESELECT) &&
+ !clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT)) ||
+ (clause_GetFlag(PartnerClause, CLAUSESELECT) &&
+ !clause_LiteralGetFlag(clause_GetLiteral(PartnerClause,j),LITSELECT))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_LiteralsMaxWith2Subst: Another literal is selected.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!clause_GetFlag(Clause, CLAUSESELECT) &&
+ !inf_LitMaxWith2Subst(Clause, i, -1, Subst2, Subst1,
+ i>clause_LastAntecedentLitIndex(Clause), Flags, Precedence))
+ return FALSE;
+ if (!clause_GetFlag(PartnerClause, CLAUSESELECT) &&
+ !inf_LitMaxWith2Subst(PartnerClause, j, -1, Subst2, Subst1,
+ j>clause_LastAntecedentLitIndex(PartnerClause), Flags, Precedence))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/**************************************************************/
+/* Inference rules */
+/**************************************************************/
+
+LIST inf_EqualityResolution(CLAUSE GivenClause, BOOL Ordered, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause and a flag determining whether ordering
+ constraints apply.
+ For <Ordered>=TRUE the function makes Equality Resolution
+ inferences, for <Ordered>=FALSE Reflexivity Resolution
+ inferences are made.
+ A flag store.
+ A precedence.
+ RETURNS: A list of clauses inferred from the GivenClause by
+ Equality/Reflexivity Resolution.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result;
+ LITERAL ActLit;
+ int i, last;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_EqualityResolution: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (clause_HasEmptyAntecedent(GivenClause) ||
+ !clause_HasSolvedConstraint(GivenClause)) {
+ return list_Nil();
+ }
+
+ Result = list_Nil();
+ last = clause_LastAntecedentLitIndex(GivenClause);
+
+ for (i = clause_FirstAntecedentLitIndex(GivenClause); i <= last; i++) {
+ ActLit = clause_GetLiteral(GivenClause, i);
+
+ if (clause_LiteralIsEquality(ActLit) &&
+ (clause_LiteralGetFlag(ActLit,LITSELECT) ||
+ (!clause_GetFlag(GivenClause,CLAUSESELECT) &&
+ (!Ordered || clause_LiteralIsMaximal(ActLit))))) {
+ TERM Atom;
+
+ Atom = clause_GetLiteralAtom(GivenClause, i);
+
+ cont_Check();
+ if (unify_UnifyCom(cont_LeftContext(),
+ term_FirstArgument(Atom),
+ term_SecondArgument(Atom))) {
+ SUBST mgu;
+ CLAUSE NewClause;
+ int j, k, bound;
+
+ subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+ /* Check postcondition */
+ if (clause_LiteralGetFlag(ActLit,LITSELECT) ||
+ !Ordered || inf_LitMax(GivenClause, i, -1, mgu,
+ FALSE, Flags, Precedence)) {
+
+ NewClause = clause_CreateBody(clause_Length(GivenClause) - 1);
+ clause_SetNumOfConsLits(NewClause, clause_NumOfConsLits(GivenClause));
+ clause_SetNumOfAnteLits(NewClause,
+ (clause_NumOfAnteLits(GivenClause) - 1));
+ clause_SetNumOfSuccLits(NewClause, clause_NumOfSuccLits(GivenClause));
+
+ bound = clause_LastLitIndex(GivenClause);
+ /* j iterates over the given clause, k iterates over the new one */
+ for (j = k = clause_FirstLitIndex(); j <= bound; j++) {
+ if (j != i) {
+ clause_SetLiteral(NewClause, k,
+ clause_LiteralCreate(subst_Apply(mgu,
+ term_Copy(clause_GetLiteralTerm(GivenClause,j))),NewClause));
+ k++;
+ }
+ }
+ clause_SetDataFromFather(NewClause, GivenClause, i, Flags, Precedence);
+ clause_SetFromEqualityResolution(NewClause);
+
+ Result = list_Cons(NewClause, Result);
+ }
+ subst_Delete(mgu);
+ }
+ cont_Reset();
+ } /* end of if 'ActLit is maximal'. */
+ } /*end of for 'all literals'. */
+ return(Result);
+}
+
+static CLAUSE inf_ApplyEqualityFactoring(CLAUSE Clause, TERM Left, TERM Right,
+ int i, int j, SUBST Subst,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, two terms, two indices in the clause,
+ a substitution, a flag store and a precedence.
+ RETURNS: A new clause, where <Left>=<Right> is added as antecedent atom,
+ the <i>th literal is deleted, the <j>th kept and
+ <Subst> is applied to a copy of <clause>.
+***************************************************************/
+{
+ CLAUSE NewClause;
+ TERM Atom;
+ int k,c,a,s;
+
+ NewClause = clause_CreateBody(clause_Length(Clause));
+
+ c = clause_LastConstraintLitIndex(Clause);
+ clause_SetNumOfConsLits(NewClause, clause_NumOfConsLits(Clause));
+ a = clause_LastAntecedentLitIndex(Clause);
+ clause_SetNumOfAnteLits(NewClause, clause_NumOfAnteLits(Clause) + 1);
+ s = clause_LastSuccedentLitIndex(Clause);
+ clause_SetNumOfSuccLits(NewClause, clause_NumOfSuccLits(Clause) - 1);
+
+ for (k = clause_FirstLitIndex(); k <= c; k++) {
+ clause_SetLiteral(NewClause, k,
+ clause_LiteralCreate(subst_Apply(Subst,
+ term_Copy(clause_GetLiteralTerm(Clause, k))),NewClause));
+ }
+
+ for ( ; k <= a; k++) {
+ clause_SetLiteral(NewClause, k,
+ clause_LiteralCreate(subst_Apply(Subst,
+ term_Copy(clause_GetLiteralTerm(Clause, k))),NewClause));
+ }
+
+ Atom = term_Create(fol_Equality(),
+ list_Cons(term_Copy(Left),list_List(term_Copy(Right))));
+
+ clause_SetLiteral(NewClause, k, clause_LiteralCreate(
+ term_Create(fol_Not(), list_List(subst_Apply(Subst,Atom))), NewClause));
+
+ a = 1; /* Shift */
+
+ for ( ; k <= s; k++) {
+ if (k == i)
+ a = 0;
+ else {
+ clause_SetLiteral(NewClause, (k + a),
+ clause_LiteralCreate(subst_Apply(Subst,
+ term_Copy(clause_GetLiteralTerm(Clause, k))),NewClause));
+ }
+ }
+
+ clause_AddParentClause(NewClause, clause_Number(Clause));
+ clause_AddParentLiteral(NewClause, j);
+ clause_SetDataFromFather(NewClause, Clause, i, Flags, Precedence);
+
+ clause_SetFromEqualityFactoring(NewClause);
+
+ return NewClause;
+}
+
+
+static BOOL inf_EqualityFactoringApplicable(CLAUSE Clause, int i, TERM Left,
+ TERM Right, SUBST Subst,
+ FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause <Clause>, the index <i> of a maximal
+ equality literal in <Clause> <j>, <Left> and
+ <Right> are the left and right side of the literal,
+ where <Right> is not greater than <Left> wrt the
+ ordering, a unifier <Subst>, a flag store and a
+ precedence.
+ RETURNS: TRUE iff the literal at index <i> is strictly
+ maximal in the instantiated clause and <Right> is
+ not greater than or equal to <Left> after
+ application of the substitution.
+ Otherwise, the function returns FALSE.
+***************************************************************/
+{
+ ord_RESULT Help;
+
+ /* Literal oriented? */
+ if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause, i))) {
+ TERM NLeft, NRight;
+ NLeft = subst_Apply(Subst, term_Copy(Left));
+ NRight = subst_Apply(Subst, term_Copy(Right));
+ if ((Help = ord_Compare(NLeft,NRight,Flags, Precedence)) == ord_SmallerThan() ||
+ Help == ord_Equal()) {
+ term_Delete(NLeft);
+ term_Delete(NRight);
+ return FALSE;
+ }
+ term_Delete(NLeft);
+ term_Delete(NRight);
+ }
+ /* Literal maximal? */
+ return inf_LitMax(Clause, i, -1, Subst, FALSE, Flags, Precedence);
+}
+
+
+LIST inf_EqualityFactoring(CLAUSE GivenClause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a flag store and a precedence.
+ RETURNS: A list of clauses derivable from 'GivenClause' by EF.
+***************************************************************/
+{
+ LIST Result;
+ LITERAL ActLit;
+ int i, j, last;
+ SUBST mgu;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_EqualityFactoring: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (clause_HasEmptySuccedent(GivenClause) ||
+ clause_GetFlag(GivenClause, CLAUSESELECT) ||
+ !clause_HasSolvedConstraint(GivenClause)) {
+ return list_Nil();
+ }
+
+ Result = list_Nil();
+
+ last = clause_LastSuccedentLitIndex(GivenClause);
+
+ for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= last; i++) {
+
+ ActLit = clause_GetLiteral(GivenClause, i);
+
+ if (clause_LiteralIsMaximal(ActLit) &&
+ clause_LiteralIsEquality(ActLit)) {
+ TERM Atom, Left, Right;
+ LITERAL PartnerLit;
+
+ Atom = clause_LiteralAtom(ActLit);
+ Left = term_FirstArgument(Atom);
+ Right = term_SecondArgument(Atom);
+
+ for (j = clause_FirstSuccedentLitIndex(GivenClause); j <= last; j++) {
+ PartnerLit = clause_GetLiteral(GivenClause, j);
+ if (i != j && clause_LiteralIsEquality(PartnerLit)) {
+ /* i==j can be excluded since this inference would either generate */
+ /* a copy of the given clause (if one side of the equality is */
+ /* unified with itself), or generate a tautology (if different */
+ /* sides of the equality are unified). */
+ TERM PartnerAtom, PartnerLeft, PartnerRight;
+
+ PartnerAtom = clause_LiteralAtom(PartnerLit);
+ PartnerLeft = term_FirstArgument(PartnerAtom);
+ PartnerRight = term_SecondArgument(PartnerAtom);
+
+ /* try <Left> and <PartnerLeft> */
+ cont_Check();
+ if (unify_UnifyCom(cont_LeftContext(), Left, PartnerLeft)) {
+ subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+ if (inf_EqualityFactoringApplicable(GivenClause, i, Left, Right,
+ mgu, Flags, Precedence))
+ Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Right,
+ PartnerRight,i,j,
+ mgu,Flags,
+ Precedence),
+ Result);
+ subst_Delete(mgu);
+ }
+ cont_Reset();
+
+ /* try <Left> and <PartnerRight> */
+ cont_Check();
+ if (unify_UnifyCom(cont_LeftContext(), Left, PartnerRight)) {
+ subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+
+ if (inf_EqualityFactoringApplicable(GivenClause, i, Left, Right,
+ mgu, Flags, Precedence))
+ Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Right,
+ PartnerLeft,i,j,
+ mgu,Flags,
+ Precedence),
+ Result);
+ subst_Delete(mgu);
+ }
+ cont_Reset();
+
+ if (!clause_LiteralIsOrientedEquality(ActLit)) {
+ /* try <Right> and <PartnerLeft> */
+ cont_Check();
+ if (unify_UnifyCom(cont_LeftContext(), Right, PartnerLeft)) {
+ subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+
+ if (inf_EqualityFactoringApplicable(GivenClause, i, Right, Left,
+ mgu, Flags, Precedence))
+ Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Left,
+ PartnerRight,i,j,
+ mgu,Flags,
+ Precedence),
+ Result);
+ subst_Delete(mgu);
+ }
+ cont_Reset();
+
+ /* try <Right> and <PartnerRight> */
+ cont_Check();
+ if (unify_UnifyCom(cont_LeftContext(), Right, PartnerRight)) {
+ subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+
+ if (inf_EqualityFactoringApplicable(GivenClause, i, Right, Left,
+ mgu, Flags, Precedence))
+ Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Left,
+ PartnerLeft,i,j,
+ mgu,Flags,
+ Precedence),
+ Result);
+ subst_Delete(mgu);
+ }
+ cont_Reset();
+ }
+ }
+ }
+ }
+ }
+ return Result;
+}
+
+
+/* START of block with new term replacement */
+
+static BOOL inf_NAllTermsRplac(TERM Term, TERM TestTerm, TERM RplacTerm,
+ SUBST Subst)
+/**************************************************************
+ INPUT: Three terms, a substitution and an integer.
+ All occurrences of <TestTerm> in <Term> are replaced
+ by <RplacTerm>. The substitution <Subst> is applied to <Term>.
+ RETURNS: TRUE, if TestTerm was replaced by RplacTerm,
+ FALSE otherwise.
+ EFFECT: <Term> is destructively changed!
+***************************************************************/
+{
+ LIST ArgListNode;
+ BOOL Replaced;
+ int Bottom;
+
+ Replaced = FALSE;
+
+ /* check if whole term must be replaced */
+ if (term_Equal(Term, TestTerm)) {
+ term_RplacTop(Term,term_TopSymbol(RplacTerm));
+ ArgListNode = term_ArgumentList(Term);
+ term_RplacArgumentList(Term, term_CopyTermList(term_ArgumentList(RplacTerm)));
+ term_DeleteTermList(ArgListNode);
+ return TRUE;
+ }
+
+ if (term_IsVariable(Term))
+ subst_Apply(Subst, Term);
+
+ /* if not, scan whole term. */
+ if (!list_Empty(term_ArgumentList(Term))) {
+
+ Bottom = stack_Bottom();
+ stack_Push(term_ArgumentList(Term));
+
+ while (!stack_Empty(Bottom)) {
+ ArgListNode = stack_Top();
+ Term = (TERM)list_Car(ArgListNode);
+ stack_RplacTop(list_Cdr(ArgListNode));
+
+ if (term_Equal(Term, TestTerm)) {
+ Replaced = TRUE;
+ list_Rplaca(ArgListNode, term_Copy(RplacTerm));
+ term_Delete(Term);
+ }
+ else {
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+ else if (term_IsVariable(Term))
+ subst_Apply(Subst,Term);
+ }
+
+ /* remove empty lists (corresponding to scanned terms) */
+ while (!stack_Empty(Bottom) && list_Empty(stack_Top()))
+ stack_Pop();
+ }
+ }
+ return Replaced;
+}
+
+
+static TERM inf_AllTermsRplac(TERM Term, TERM TestTerm, TERM RplacTerm,
+ SUBST Subst)
+/**************************************************************
+ INPUT: Three terms, a substitution.
+ All occurrences of <TestTerm> in A COPY of <Term> are replaced
+ by <RplacTerm>. The substitution <Subst> is applied to
+ the copy of <Term>. If no occurrence is found,
+ NULL is returned.
+ This function is not destructive
+ like NAllTermRplac.
+ RETURNS: TRUE, if TestTerm was replaced by RplacTerm,
+ FALSE otherwise.
+***************************************************************/
+{
+ TERM ActTerm = term_Copy(Term);
+
+ if (!inf_NAllTermsRplac(ActTerm,TestTerm, RplacTerm, Subst )) {
+ term_Delete(ActTerm);
+ ActTerm = NULL;
+ }
+
+ return(ActTerm);
+}
+
+static TERM inf_AllTermsSideRplacs(TERM Term, TERM TestTerm, TERM RplacTerm,
+ SUBST Subst, BOOL Right)
+/**************************************************************
+ INPUT: Three terms, a substitution and a boolean flag.
+ <Term> is typically an equality term.
+ RETURNS: If <TestTerm> occurs in the right (Right=TRUE) or
+ left side (Right=FALSE) of <Term>:
+
+ A copy of the term where all occurrences of <TestTerm>
+ in the ENTIRE <Term> are replaced by <RplacTerm> and
+ the substitution <Subst> is applied to all other subterms.
+
+ If <TestTerm> does not occur in the right/left side of
+ <Term>, NULL is returned.
+
+ In non-equality terms, The 'sides' correspond to the
+ first and second argument of the term.
+***************************************************************/
+{
+ TERM ActTerm = term_Copy(Term);
+ TERM ReplSide, OtherSide; /* ReplSide is the side in which terms are
+ replaced */
+
+ if (Right) {
+ ReplSide = term_SecondArgument(ActTerm);
+ OtherSide = term_FirstArgument(ActTerm);
+ }
+ else {
+ ReplSide = term_FirstArgument(ActTerm);
+ OtherSide = term_SecondArgument(ActTerm);
+ }
+
+ if (inf_NAllTermsRplac(ReplSide, TestTerm, RplacTerm, Subst))
+ /* If <TestTerm> occurs in <ReplSide> also replace it in <OtherSide>. */
+ inf_NAllTermsRplac(OtherSide, TestTerm, RplacTerm, Subst);
+ else {
+ term_Delete(ActTerm);
+ ActTerm = NULL;
+ }
+
+ return ActTerm;
+}
+
+
+static TERM inf_AllTermsRightRplac(TERM Term, TERM TestTerm, TERM RplacTerm,
+ SUBST Subst)
+/**************************************************************
+ INPUT: Three terms, a substitution.
+ <Term> is typically an equality term.
+ RETURNS: See inf_AllTermSideRplac with argument
+ 'Right' set to TRUE
+**************************************************************/
+{
+ return(inf_AllTermsSideRplacs(Term, TestTerm, RplacTerm, Subst, TRUE));
+}
+
+
+static TERM inf_AllTermsLeftRplac(TERM Term, TERM TestTerm, TERM RplacTerm,
+ SUBST Subst)
+/**************************************************************
+ INPUT: Three terms, a substitution.
+ <Term> is typically an equality term.
+ RETURNS: See inf_AllTermSideRplac with argument
+ 'Right' set to FALSE.
+***************************************************************/
+{
+ return(inf_AllTermsSideRplacs(Term, TestTerm, RplacTerm, Subst, FALSE));
+}
+
+
+/* END of block with new term replacement */
+
+
+static CLAUSE inf_ApplyGenSuperposition(CLAUSE Clause, int ci, SUBST Subst,
+ CLAUSE PartnerClause, int pci,
+ SUBST PartnerSubst, TERM SupAtom,
+ BOOL Right, BOOL OrdPara, BOOL MaxPara,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: Two clauses where a generalized superposition inference can be
+ applied using the positive equality literal <i> from <Clause> with
+ subst <Subst> using the literal <j> from <PartnerClause> with subst
+ <PartnerSubst> where SupAtom is a derivable atom. Returns
+ NULL if SupAtom is NULL.
+
+ Right is TRUE if the inference is a superposition right inference
+ Right is FALSE if the inference is a superposition left inference,
+
+ where the inference is selected by MaxPara and OrdPara:
+ (see also inf_GenSuperpositionLeft)
+
+ OrdPara=TRUE, MaxPara=TRUE
+ -> Superposition (Left or Right)
+
+ OrdPara=TRUE, MaxPara=FALSE
+ -> ordered Paramodulation
+
+ OrdPara=FALSE, MaxPara=FALSE
+ -> simple Paramodulation
+
+ OrdPara=FALSE, MaxPara=TRUE
+ -> not defined
+
+ A flag store.
+ A precedence.
+ RETURNS: The new clause.
+ MEMORY: Memory for the new clause is allocated.
+***************************************************************/
+{
+ CLAUSE NewClause;
+ int j,lc,la,ls,pls,pla,plc,help;
+
+#ifdef CHECK
+ if (!OrdPara && MaxPara) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_ApplyGenSuperposition : Illegal inference");
+ misc_ErrorReport("\n rule selection, OrdPara=FALSE and MaxPara=TRUE.");
+ misc_FinishErrorReport();
+ }
+ if (SupAtom == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_ApplyGenSuperposition: Atom is NULL.");
+ misc_FinishErrorReport();
+ return clause_Null();
+ }
+#endif
+
+ pls = clause_LastSuccedentLitIndex(PartnerClause);
+ pla = clause_LastAntecedentLitIndex(PartnerClause);
+ plc = clause_LastConstraintLitIndex(PartnerClause);
+
+ ls = clause_LastSuccedentLitIndex(Clause);
+ la = clause_LastAntecedentLitIndex(Clause);
+ lc = clause_LastConstraintLitIndex(Clause);
+
+
+ NewClause = clause_CreateBody(clause_Length(Clause) - 1 +
+ clause_Length(PartnerClause));
+
+ clause_SetNumOfConsLits(NewClause, (clause_NumOfConsLits(Clause) +
+ clause_NumOfConsLits(PartnerClause)));
+ clause_SetNumOfAnteLits(NewClause, (clause_NumOfAnteLits(Clause) +
+ clause_NumOfAnteLits(PartnerClause)));
+ clause_SetNumOfSuccLits(NewClause, ((clause_NumOfSuccLits(Clause) -1)+
+ clause_NumOfSuccLits(PartnerClause)));
+
+ /* First set the literals from the Clause : */
+
+ for (j = clause_FirstLitIndex(); j <= lc; j++) {
+ clause_SetLiteral(NewClause, j,
+ clause_LiteralCreate(subst_Apply(Subst, term_Copy(
+ clause_GetLiteralTerm(Clause, j))),NewClause));
+ }
+
+ /* help = number of literals to leave empty */
+ help = clause_NumOfConsLits(PartnerClause);
+
+ for ( ; j <= la; j++) {
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(subst_Apply(Subst, term_Copy(
+ clause_GetLiteralTerm(Clause, j))),NewClause));
+ }
+
+ /* help = number of literals to leave empty */
+ help += clause_NumOfAnteLits(PartnerClause);
+
+ for ( ; j <= ls; j++) {
+ if (j != ci) {
+ /* The literal used in the inference isn't copied */
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(subst_Apply(Subst,
+ term_Copy(clause_GetLiteralTerm(Clause, j))),NewClause));
+
+ } else {
+ /*the index has to be decreased to avoid an empty literal! */
+ help--;
+ }
+ }
+
+ /* Now we consider the PartnerClause : */
+
+ /* help = number of already set constraint (Clause) literals */
+ help = clause_NumOfConsLits(Clause);
+
+ for (j = clause_FirstLitIndex(); j <= plc; j++) {
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(subst_Apply(PartnerSubst,
+ term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+ }
+
+ /* help = number of already set constraint and antecedent Given-literals */
+ help += clause_NumOfAnteLits(Clause);
+
+ for ( ; j <= pla; j++) {
+ if (j != pci) {
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(subst_Apply(PartnerSubst,
+ term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+ } else {
+ /* The PartnerLit is modified appropriately! */
+ clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(
+ term_Create(fol_Not(),list_List(SupAtom)), NewClause));
+ }
+ }
+
+
+ /* help = number of already set Given-literals */
+ help = clause_Length(Clause) - 1;
+
+ for ( ; j <= pls; j++) {
+ if (j != pci) {
+ /* The PartnerLit isn't copied! */
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(subst_Apply(PartnerSubst,
+ term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+
+ } else {
+ /* The PartnerLit is modified appropriately! */
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(SupAtom, NewClause));
+ }
+ }
+
+ /*
+ * Set inference type. Note that, in the case of (ordered) paramodulation,
+ * we do not distinguish which side was paramodulated into, as compared
+ * to the case of superposition.
+ */
+
+ if (OrdPara && MaxPara) {
+ if (Right)
+ clause_SetFromSuperpositionRight(NewClause);
+ else
+ clause_SetFromSuperpositionLeft(NewClause);
+ }
+ else if (OrdPara && !MaxPara)
+ clause_SetFromOrderedParamodulation(NewClause);
+ else
+ clause_SetFromParamodulation(NewClause);
+
+ clause_SetDataFromParents(NewClause, PartnerClause, pci, Clause, ci, Flags,
+ Precedence);
+
+ return NewClause;
+}
+
+
+/* START of block with new superposition right rule */
+
+static LIST inf_GenLitSPRight(CLAUSE Clause, TERM Left, TERM Right, int i,
+ SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause (unshared) with a positive equality literal
+ at position <i> where <Left> and <Right> are the arguments
+ of just that literal and <Right> is not greater wrt. the
+ ordering than <Left>,
+ two boolean flags for controlling inference
+ preconditions (see inf_GenSuperpositionRight),
+ a flag store and a precedence.
+ RETURNS: A list of clauses derivable with the literals owning
+ clause by general superposition right wrt. the Index.
+ (see inf_GenSuperpositionRight for selection of inference
+ rule by OrdPara/MaxPara)
+ MEMORY: The list of clauses is extended, where memory for the
+ list and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result, Terms;
+
+ Result = list_Nil();
+ Terms = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+ cont_RightContext(), Left);
+
+ for ( ; !list_Empty(Terms); Terms = list_Pop(Terms)) {
+ LIST Lits;
+ TERM Term;
+
+ Term = (TERM)list_First(Terms);
+
+ if (!term_IsVariable(Term) && !symbol_IsPredicate(term_TopSymbol(Term))) {
+
+ Lits = sharing_GetDataList(Term, ShIndex);
+
+ for ( ; !list_Empty(Lits); Lits = list_Pop(Lits)) {
+ LITERAL PartnerLit;
+ TERM PartnerAtom;
+ CLAUSE PartnerClause;
+ int pli;
+
+ PartnerLit = (LITERAL)list_Car(Lits);
+ PartnerAtom = clause_LiteralAtom(PartnerLit);
+ pli = clause_LiteralGetIndex(PartnerLit);
+ PartnerClause = clause_LiteralOwningClause(PartnerLit);
+
+ if (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+ (!MaxPara || clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+ !clause_GetFlag(PartnerClause,NOPARAINTO) &&
+ clause_LiteralIsPositive(PartnerLit) &&
+ clause_HasSolvedConstraint(PartnerClause)) {
+
+ SUBST Subst, PartnerSubst;
+ TERM NewLeft,NewRight;
+ SYMBOL PartnerMaxVar;
+ TERM SupAtom;
+
+ SupAtom = (TERM)NULL;
+
+ PartnerMaxVar = clause_MaxVar(PartnerClause);
+ NewLeft = Left;
+ clause_RenameVarsBiggerThan(Clause, PartnerMaxVar);
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), Left, cont_RightContext(), Term);
+ subst_ExtractUnifier(cont_LeftContext(), &Subst, cont_RightContext(), &PartnerSubst);
+ cont_Reset();
+ if (!MaxPara ||
+ inf_LiteralsMax(Clause, i, Subst, PartnerClause, pli,
+ PartnerSubst, Flags, Precedence)) {
+ NewRight = subst_Apply(Subst, term_Copy(Right));
+ if (OrdPara &&
+ !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)))
+ NewLeft = subst_Apply(Subst, term_Copy(Left));
+ if (!OrdPara ||
+ NewLeft == Left || /* TRUE, if oriented */
+ ord_Compare(NewLeft,NewRight, Flags, Precedence) != ord_SmallerThan()) {
+ if (!MaxPara || clause_LiteralIsPredicate(PartnerLit)) {
+ SupAtom = inf_AllTermsRplac(PartnerAtom, Term,
+ NewRight, PartnerSubst);
+ } else {
+ /* Superposition and <PartnerLit> is equality */
+ if (clause_LiteralIsOrientedEquality(PartnerLit))
+ SupAtom = inf_AllTermsLeftRplac(PartnerAtom, Term,
+ NewRight, PartnerSubst);
+ else {
+ TERM NewPartnerLeft,NewPartnerRight;
+ NewPartnerLeft =
+ subst_Apply(PartnerSubst,
+ term_Copy(term_FirstArgument(PartnerAtom)));
+ NewPartnerRight =
+ subst_Apply(PartnerSubst,
+ term_Copy(term_SecondArgument(PartnerAtom)));
+ switch (ord_Compare(NewPartnerLeft,NewPartnerRight,
+ Flags, Precedence)) {
+ case ord_SMALLER_THAN:
+ SupAtom = inf_AllTermsRightRplac(PartnerAtom,Term,
+ NewRight,PartnerSubst);
+ break;
+ case ord_GREATER_THAN:
+ SupAtom = inf_AllTermsLeftRplac(PartnerAtom,Term,
+ NewRight,PartnerSubst);
+ break;
+ default:
+ SupAtom = inf_AllTermsRplac(PartnerAtom,Term,
+ NewRight,PartnerSubst);
+ }
+ term_Delete(NewPartnerLeft);
+ term_Delete(NewPartnerRight);
+ }
+ }
+
+ if (SupAtom != NULL)
+ Result =
+ list_Cons(inf_ApplyGenSuperposition(Clause, i, Subst,
+ PartnerClause, pli,
+ PartnerSubst, SupAtom,
+ TRUE, OrdPara, MaxPara,
+ Flags, Precedence),
+ Result);
+ }
+ if (NewLeft != Left)
+ term_Delete(NewLeft);
+ term_Delete(NewRight);
+ }
+ subst_Delete(Subst);
+ subst_Delete(PartnerSubst);
+ }
+ }
+ }
+ }
+ return Result;
+}
+
+
+static LIST inf_GenSPRightEqToGiven(CLAUSE Clause, int i, BOOL Left,
+ SHARED_INDEX ShIndex, BOOL OrdPara,
+ BOOL MaxPara, BOOL Unit, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: An unshared clause, the index of a succedent literal
+ that is an equality literal and a boolean value which
+ argument to use:
+ If Left==TRUE then the left argument is used
+ otherwise the right argument.
+ Three boolean flags for controlling inference
+ preconditions (see inf_GenSuperpositionRight).
+ A flag store.
+ A precedence.
+ RETURNS: A list of clauses derivable from general superposition right on the
+ GivenCopy wrt. the Index.
+ (see inf_GenSuperpositionRight for selection of inference
+ rule by OrdPara/MaxPara)
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result, TermList, Parents;
+ int Bottom;
+ LITERAL Lit;
+ TERM Atom, Term, PartnerTerm, PartnerEq;
+
+ Result = list_Nil();
+ Lit = clause_GetLiteral(Clause,i);
+ Atom = clause_LiteralAtom(Lit);
+
+#ifdef CHECK
+ if (!fol_IsEquality(Atom) ||
+ (MaxPara && clause_LiteralIsOrientedEquality(Lit) && !Left) ||
+ (MaxPara && !clause_LiteralGetFlag(Lit, STRICTMAXIMAL))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSPRightEqToGiven: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Bottom = stack_Bottom();
+ if (Left) /* Top Level considered in inf_LitSPRight */
+ sharing_PushListOnStack(term_ArgumentList(term_FirstArgument(Atom)));
+ else
+ sharing_PushListOnStack(term_ArgumentList(term_SecondArgument(Atom)));
+
+ while (!stack_Empty(Bottom)) {
+ Term = (TERM)stack_PopResult();
+ if (!term_IsVariable(Term)) {
+ /* Superposition into variables is not necessary */
+ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+ cont_RightContext(), Term);
+ for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+ PartnerTerm = (TERM)list_Car(TermList);
+ for (Parents = term_SupertermList(PartnerTerm);
+ !list_Empty(Parents); Parents = list_Cdr(Parents)) {
+ PartnerEq = (TERM)list_Car(Parents);
+ if (fol_IsEquality(PartnerEq)) {
+ CLAUSE PartnerClause;
+ LITERAL PartnerLit;
+ LIST Scl;
+ int j;
+ for (Scl = sharing_NAtomDataList(PartnerEq);
+ !list_Empty(Scl); Scl = list_Cdr(Scl)) {
+ PartnerLit = (LITERAL)list_Car(Scl);
+ j = clause_LiteralGetIndex(PartnerLit);
+ PartnerClause = clause_LiteralOwningClause(PartnerLit);
+ if (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+ (!MaxPara ||
+ clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+ (!OrdPara || PartnerTerm==term_FirstArgument(PartnerEq) ||
+ !clause_LiteralIsOrientedEquality(PartnerLit)) &&
+ clause_LiteralIsPositive(PartnerLit) &&
+ clause_Number(PartnerClause) != clause_Number(Clause) &&
+ (!Unit || clause_Length(PartnerClause) == 1) &&
+ clause_HasSolvedConstraint(PartnerClause)) {
+ /* We exclude the same clause since that inference will be */
+ /* made by the "forward" function inf_GenLitSPRight. */
+ SYMBOL MaxVar;
+ SUBST Subst, PartnerSubst;
+
+ MaxVar = clause_MaxVar(PartnerClause);
+ clause_RenameVarsBiggerThan(Clause, MaxVar);
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), Term, cont_RightContext(),
+ PartnerTerm);
+ subst_ExtractUnifier(cont_LeftContext(), &Subst,
+ cont_RightContext(), &PartnerSubst);
+ cont_Reset();
+ if (!MaxPara ||
+ inf_LiteralsMax(Clause, i, Subst, PartnerClause, j,
+ PartnerSubst, Flags, Precedence)) {
+ TERM PartnerLeft,PartnerRight;
+ BOOL Check, PartnerCheck;
+ PartnerLeft = PartnerRight = NULL;
+ PartnerCheck = Check = TRUE;
+ if (OrdPara &&
+ !clause_LiteralIsOrientedEquality(PartnerLit)) {
+ /* Check post condition for partner literal */
+ if (PartnerTerm == term_FirstArgument(PartnerEq))
+ PartnerRight = term_SecondArgument(PartnerEq);
+ else
+ PartnerRight = term_FirstArgument(PartnerEq);
+ PartnerLeft = subst_Apply(PartnerSubst,
+ term_Copy(PartnerTerm));
+ PartnerRight = subst_Apply(PartnerSubst,
+ term_Copy(PartnerRight));
+ PartnerCheck = (ord_Compare(PartnerLeft, PartnerRight,
+ Flags, Precedence)
+ != ord_SmallerThan());
+ }
+ if (PartnerCheck &&
+ MaxPara && !clause_LiteralIsOrientedEquality(Lit)) {
+ /* Check post condition for literal in given clause */
+ TERM NewLeft, NewRight;
+ if (Left) {
+ NewLeft = term_FirstArgument(Atom);
+ NewRight = term_SecondArgument(Atom);
+ } else {
+ NewLeft = term_SecondArgument(Atom);
+ NewRight = term_FirstArgument(Atom);
+ }
+ NewLeft = subst_Apply(Subst, term_Copy(NewLeft));
+ NewRight = subst_Apply(Subst, term_Copy(NewRight));
+ Check = (ord_Compare(NewLeft, NewRight, Flags, Precedence)
+ != ord_SmallerThan());
+ term_Delete(NewLeft);
+ term_Delete(NewRight);
+ }
+ if (Check && PartnerCheck) {
+ /* Make inference only if both tests were successful */
+ TERM SupAtom;
+ SupAtom = NULL;
+ if (PartnerRight == NULL) {
+ if (PartnerTerm==term_FirstArgument(PartnerEq))
+ PartnerRight = term_SecondArgument(PartnerEq);
+ else
+ PartnerRight = term_FirstArgument(PartnerEq);
+ PartnerRight = subst_Apply(PartnerSubst,
+ term_Copy(PartnerRight));
+ }
+ if (Left)
+ SupAtom = inf_AllTermsLeftRplac(Atom, Term,
+ PartnerRight, Subst);
+ else
+ SupAtom = inf_AllTermsRightRplac(Atom, Term,
+ PartnerRight, Subst);
+#ifdef CHECK
+ if (SupAtom == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSPRightEqToGiven:");
+ misc_ErrorReport(" replacement wasn't possible.");
+ misc_FinishErrorReport();
+ }
+#endif
+ Result =
+ list_Cons(inf_ApplyGenSuperposition(PartnerClause, j,
+ PartnerSubst, Clause,
+ i, Subst, SupAtom,
+ TRUE,OrdPara,MaxPara,
+ Flags, Precedence),
+ Result);
+ }
+ if (PartnerLeft != term_Null())
+ term_Delete(PartnerLeft);
+ if (PartnerRight != term_Null())
+ term_Delete(PartnerRight);
+ }
+ subst_Delete(Subst);
+ subst_Delete(PartnerSubst);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Result;
+}
+
+
+static LIST inf_GenSPRightLitToGiven(CLAUSE Clause, int i, TERM Atom,
+ SHARED_INDEX ShIndex, BOOL OrdPara,
+ BOOL MaxPara, BOOL Unit, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: An unshared clause, the index of a succedent literal
+ that is not an equality literal and its atom,
+ three boolean flags for controlling inference
+ preconditions (see inf_GenSuperpositionRight),
+ a flag store and a precedence.
+ RETURNS: A list of clauses derivable from general superposition right on the
+ GivenCopy wrt. the Index.
+ (see inf_GenSuperpositionRight for selection of inference
+ rule by OrdPara/MaxPara)
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result, TermList, ParentList;
+ int Bottom;
+ TERM Term, PartnerTerm, PartnerEq;
+
+ Result = list_Nil();
+
+ Bottom = stack_Bottom();
+ sharing_PushListOnStack(term_ArgumentList(Atom));
+
+ while (!stack_Empty(Bottom)) {
+ Term = (TERM)stack_PopResult();
+ if (!term_IsVariable(Term)) {
+ /* Superposition into variables is not necessary */
+ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+ cont_RightContext(), Term);
+ for ( ; !list_Empty(TermList); TermList=list_Pop(TermList)) {
+ PartnerTerm = (TERM)list_Car(TermList);
+ for (ParentList = term_SupertermList(PartnerTerm);
+ !list_Empty(ParentList); ParentList = list_Cdr(ParentList)) {
+ PartnerEq = (TERM)list_Car(ParentList);
+ if (fol_IsEquality(PartnerEq)) {
+ CLAUSE PartnerClause;
+ LITERAL PartnerLit;
+ LIST Scl;
+ int j;
+ for (Scl = sharing_NAtomDataList(PartnerEq);
+ !list_Empty(Scl); Scl = list_Cdr(Scl)) {
+ PartnerLit = (LITERAL)list_Car(Scl);
+ j = clause_LiteralGetIndex(PartnerLit);
+ PartnerClause = clause_LiteralOwningClause(PartnerLit);
+ if (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+ (!MaxPara ||
+ clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+ (!OrdPara || PartnerTerm==term_FirstArgument(PartnerEq) ||
+ !clause_LiteralIsOrientedEquality(PartnerLit)) &&
+ clause_LiteralIsPositive(PartnerLit) &&
+ clause_Number(PartnerClause) != clause_Number(Clause) &&
+ (!Unit || clause_Length(PartnerClause) == 1) &&
+ clause_HasSolvedConstraint(PartnerClause)) {
+ /* We exclude the same clause since that inference will be */
+ /* made by the "forward" function inf_GenLitSPRight. */
+ SYMBOL MaxVar;
+ TERM PartnerLeft,PartnerRight;
+ SUBST Subst, PartnerSubst;
+ TERM SupAtom;
+
+ SupAtom = (TERM)NULL;
+ MaxVar = clause_MaxVar(PartnerClause);
+ clause_RenameVarsBiggerThan(Clause,MaxVar);
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), Term,
+ cont_RightContext(),PartnerTerm);
+ subst_ExtractUnifier(cont_LeftContext(), &Subst,
+ cont_RightContext(),&PartnerSubst);
+ cont_Reset();
+
+ if (!MaxPara ||
+ inf_LiteralsMax(Clause, i, Subst, PartnerClause, j,
+ PartnerSubst, Flags, Precedence)) {
+ PartnerLeft = subst_Apply(PartnerSubst,
+ term_Copy(PartnerTerm));
+ if (PartnerTerm == term_FirstArgument(PartnerEq))
+ PartnerRight =
+ subst_Apply(PartnerSubst,
+ term_Copy(term_SecondArgument(PartnerEq)));
+ else
+ PartnerRight =
+ subst_Apply(PartnerSubst,
+ term_Copy(term_FirstArgument(PartnerEq)));
+
+ if (!OrdPara ||
+ clause_LiteralIsOrientedEquality(PartnerLit) ||
+ ord_Compare(PartnerLeft,PartnerRight, Flags, Precedence)
+ != ord_SmallerThan()) {
+ SupAtom = inf_AllTermsRplac(Atom,Term,PartnerRight,Subst);
+#ifdef CHECK
+ if (SupAtom == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSPRightLitToGiven:");
+ misc_ErrorReport(" replacement wasn't possible.");
+ misc_FinishErrorReport();
+ }
+#endif
+ Result =
+ list_Cons(inf_ApplyGenSuperposition(PartnerClause, j,
+ PartnerSubst, Clause,
+ i, Subst, SupAtom,
+ TRUE,OrdPara,MaxPara,
+ Flags, Precedence),
+ Result);
+
+ }
+ term_Delete(PartnerLeft);
+ term_Delete(PartnerRight);
+ }
+ subst_Delete(Subst);
+ subst_Delete(PartnerSubst);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Result;
+}
+
+
+static LIST inf_GenSPRightToGiven(CLAUSE Clause, int i, SHARED_INDEX ShIndex,
+ BOOL OrdPara, BOOL MaxPara, BOOL Unit,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: An unshared clause, the index of a succedent literal
+ and an index of shared clauses,
+ three boolean flags for controlling inference
+ preconditions (see inf_GenSuperpositionRight),
+ a flag store and a precedence.
+ RETURNS: A list of clauses derivable from superposition right on the
+ GivenCopy wrt. the Index.
+ (see inf_GenSuperpositionRight for selection of inference
+ rule by OrdPara/MaxPara)
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ TERM Atom;
+ LIST Result;
+
+#ifdef CHECK
+ if (clause_GetFlag(Clause, NOPARAINTO) ||
+ clause_GetFlag(Clause, CLAUSESELECT) ||
+ (MaxPara &&
+ !clause_LiteralGetFlag(clause_GetLiteral(Clause,i), STRICTMAXIMAL))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSPRightToGiven: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+ Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+
+ if (fol_IsEquality(Atom)) {
+ Result = list_Nconc(inf_GenSPRightEqToGiven(Clause,i,TRUE,ShIndex,OrdPara,
+ MaxPara,Unit,Flags, Precedence),
+ Result);
+
+ if (!MaxPara ||
+ !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)))
+ /* For SPm and OPm always try other direction, for SpR try it */
+ /* only if the literal is not oriented. */
+ Result = list_Nconc(inf_GenSPRightEqToGiven(Clause, i, FALSE, ShIndex,
+ OrdPara,MaxPara,Unit,
+ Flags, Precedence),
+ Result);
+ } else
+ Result = list_Nconc(inf_GenSPRightLitToGiven(Clause,i,Atom,ShIndex,
+ OrdPara,MaxPara,Unit,
+ Flags, Precedence),
+ Result);
+
+ return Result;
+}
+
+
+LIST inf_GenSuperpositionRight(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+ BOOL OrdPara, BOOL MaxPara, BOOL Unit,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause and an Index, usually the WorkedOffIndex,
+ three boolean flags for controlling inference
+ preconditions, a flag store and a precedence.
+ RETURNS: A list of clauses derivable from the given clause by
+ superposition right wrt. the Index.
+
+ OrdPara=TRUE, MaxPara=TRUE
+ -> Superposition Right
+
+ OrdPara=TRUE, MaxPara=FALSE
+ -> ordered Paramodulation
+
+ OrdPara=FALSE, MaxPara=FALSE
+ -> simple Paramodulation
+
+ OrdPara=FALSE, MaxPara=TRUE
+ -> not defined
+
+ If <Unit>==TRUE the clause with the maximal equality
+ additionally must be a unit clause.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result;
+ TERM Atom;
+ CLAUSE Copy;
+ int i, n;
+ LITERAL ActLit;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSuperpositionRight: Illegal input.");
+ misc_FinishErrorReport();
+ }
+ if (!OrdPara && MaxPara) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSuperpositionRight: Illegal inference");
+ misc_ErrorReport("\n rule selection, OrdPara=FALSE & MaxPara=TRUE.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (clause_GetFlag(GivenClause,CLAUSESELECT) ||
+ clause_HasEmptySuccedent(GivenClause) ||
+ !clause_HasSolvedConstraint(GivenClause))
+ return list_Nil();
+
+ Result = list_Nil();
+
+ Copy = clause_Copy(GivenClause);
+ n = clause_LastSuccedentLitIndex(Copy);
+
+ for (i = clause_FirstSuccedentLitIndex(Copy); i <= n; i++) {
+
+ ActLit = clause_GetLiteral(Copy, i);
+ Atom = clause_LiteralSignedAtom(ActLit);
+
+ if (!MaxPara ||
+ clause_LiteralGetFlag(ActLit,STRICTMAXIMAL)) {
+ if (fol_IsEquality(Atom) &&
+ (!Unit || clause_Length(GivenClause) == 1)) {
+
+ Result = list_Nconc(inf_GenLitSPRight(Copy, term_FirstArgument(Atom),
+ term_SecondArgument(Atom), i,
+ ShIndex,OrdPara,MaxPara,Flags,
+ Precedence),
+ Result);
+
+ if (!OrdPara ||
+ !clause_LiteralIsOrientedEquality(ActLit))
+ Result = list_Nconc(inf_GenLitSPRight(Copy,
+ term_SecondArgument(Atom),
+ term_FirstArgument(Atom), i,
+ ShIndex,OrdPara,MaxPara,Flags,
+ Precedence),
+ Result);
+ }
+ if (!clause_GetFlag(Copy, NOPARAINTO))
+ Result = list_Nconc(inf_GenSPRightToGiven(Copy, i, ShIndex, OrdPara,
+ MaxPara,Unit,Flags,Precedence),
+ Result);
+ }
+ }
+ clause_Delete(Copy);
+
+ return Result;
+}
+
+
+
+/* END of block with new superposition right rule */
+
+
+static LIST inf_ApplyMParamod(CLAUSE C1, CLAUSE C2, int i, int j, int k,
+ TERM u_tau, TERM v, TERM s2, TERM t,
+ TERM v2_sigma, SUBST tau, SUBST rho,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: Two clauses, <i> is a literal index in <C1>, <j> and <k>
+ are literal indices in <C2>, <u_tau> with <rho> applied
+ is used as left side of the two new literals, <v> with
+ subterm <s2> replaced by <t> is used as right side of
+ the first new literal, <v2_sigma> as right side of the
+ second new literal, two substitutions and a flag store.
+ The substitution <rho> is applied after <tau>.
+ A flag store.
+ A precedence.
+ RETURNS: A list containing one clause derived from the given
+ clauses and literals by merging paramodulation.
+ MEMORY: Memory for the list and the clause is allocated.
+***************************************************************/
+{
+ CLAUSE newClause;
+ TERM u_sigma;
+ int m, lc, la, ls, pls, pla, plc, help;
+
+ pls = clause_LastSuccedentLitIndex(C2);
+ pla = clause_LastAntecedentLitIndex(C2);
+ plc = clause_LastConstraintLitIndex(C2);
+
+ ls = clause_LastSuccedentLitIndex(C1);
+ la = clause_LastAntecedentLitIndex(C1);
+ lc = clause_LastConstraintLitIndex(C1);
+
+ newClause = clause_CreateBody(clause_Length(C1) + clause_Length(C2) - 1);
+
+ clause_SetNumOfConsLits(newClause, (clause_NumOfConsLits(C1) +
+ clause_NumOfConsLits(C2)));
+ clause_SetNumOfAnteLits(newClause, (clause_NumOfAnteLits(C1) +
+ clause_NumOfAnteLits(C2)));
+ clause_SetNumOfSuccLits(newClause, (clause_NumOfSuccLits(C1) - 1 +
+ clause_NumOfSuccLits(C2)));
+
+ for (m = clause_FirstLitIndex(); m <= lc; m++)
+ clause_SetLiteral(newClause, m,
+ clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau,
+ term_Copy(clause_GetLiteralTerm(C1, m)))), newClause));
+
+ /* help = number of literals to leave empty */
+ help = clause_NumOfConsLits(C2);
+
+ for ( ; m <= la; m++)
+ clause_SetLiteral(newClause, (m + help),
+ clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau,
+ term_Copy(clause_GetLiteralTerm(C1, m)))), newClause));
+
+ /* help = number of literals to leave empty */
+ help += clause_NumOfAnteLits(C2);
+
+ for ( ; m <= ls; m++) {
+ if (m != i)
+ /* The literal used in the inference isn't copied */
+ clause_SetLiteral(newClause, (m + help),
+ clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau,
+ term_Copy(clause_GetLiteralTerm(C1, m)))),newClause));
+ else
+ /* the index has to be decreased to avoid an empty literal! */
+ help--;
+ }
+
+ /* Now we consider the PartnerClause : */
+
+ /* help = number of already set constraint (Clause) literals */
+ help = clause_NumOfConsLits(C1);
+
+ for (m = clause_FirstLitIndex(); m <= plc; m++)
+ clause_SetLiteral(newClause, (m + help),
+ clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau,
+ term_Copy(clause_GetLiteralTerm(C2, m)))),newClause));
+
+ /* help = number of already set constraint and antecedent Given-literals */
+ help += clause_NumOfAnteLits(C1);
+
+ for ( ; m <= pla; m++)
+ clause_SetLiteral(newClause, (m + help),
+ clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau,
+ term_Copy(clause_GetLiteralTerm(C2, m)))),newClause));
+
+ /* help = number of already set literals */
+ help += clause_NumOfSuccLits(C1) - 1;
+ /*help = clause_Length(Clause) - 1;*/
+
+ u_sigma = subst_Apply(rho, term_Copy(u_tau));
+
+ for ( ; m <= pls; m++) {
+ TERM newAtom;
+
+ if (m == j) {
+ /* The first partner literal is modified appropriately! */
+ TERM right;
+ if (v == s2)
+ /* Necessary because term_ReplaceSubtermBy doesn't treat top level */
+ right = term_Copy(t);
+ else {
+ right = term_Copy(v);
+ term_ReplaceSubtermBy(right, s2, t);
+ }
+ newAtom = term_Create(fol_Equality(), list_Cons(term_Copy(u_sigma),
+ list_List(subst_Apply(rho, subst_Apply(tau, right)))));
+ } else if (m == k) {
+ /* The second partner lit is modified appropriately! */
+ newAtom = term_Create(fol_Equality(), list_Cons(term_Copy(u_sigma),
+ list_List(term_Copy(v2_sigma))));
+ } else {
+ /* Apply substitutions to all other literals */
+ newAtom = subst_Apply(rho, subst_Apply(tau,
+ term_Copy(clause_GetLiteralTerm(C2, m))));
+ }
+
+ clause_SetLiteral(newClause, (m + help),
+ clause_LiteralCreate(newAtom, newClause));
+ }
+
+ term_Delete(u_sigma);
+
+ clause_SetFromMergingParamodulation(newClause);
+
+ clause_AddParentClause(newClause, clause_Number(C2));
+ clause_AddParentLiteral(newClause, k);
+ clause_SetDataFromParents(newClause, C2, j, C1, k, Flags, Precedence);
+
+ return list_List(newClause);
+}
+
+
+static LIST inf_Lit2MParamod(CLAUSE C1, CLAUSE C2, int i, int j, TERM s, TERM t,
+ TERM s2, TERM v, TERM u_tau, SUBST tau,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: Two clauses, the index <i> of a strict maximal literal
+ in <C1>, the index <j> of a strict maximal index in <C2>,
+ <s> and <t> are from literal <i>, <s2> is a subterm
+ of <v>, <v> is from literal <j>, <u_tau> is <u> with
+ substitution <tau> applied, a flag store, and a precedence.
+ <u_tau> must be greater than <v>tau wrt. the ordering.
+ RETURNS: A list of clauses derivable from the given data
+ by merging paramodulation.
+ This function searches <C2> for a second positive literal
+ u'=v', where u' is unifiable with <u_tau>.
+ MEMORY: Memory is allocated for the list and the clauses.
+***************************************************************/
+{
+ LIST result;
+ int k, last;
+
+ result = list_Nil();
+
+ /* Now find the 3rd literal u' = v' in C2 */
+ last = clause_LastSuccedentLitIndex(C2); /* Last index */
+ for (k = clause_FirstSuccedentLitIndex(C2); k <= last; k++) {
+ LITERAL partnerLit2 = clause_GetLiteral(C2, k);
+ TERM partnerAtom2 = clause_LiteralSignedAtom(partnerLit2);
+
+ if (k != j && fol_IsEquality(partnerAtom2)) {
+ /* partnerLit2: u' = v' or v' = u' */
+ SUBST rho;
+ TERM pLeft2, pRight2, s_sigma, t_sigma, v2_sigma;
+ ord_RESULT ordResult;
+ BOOL checkPassed;
+
+ pLeft2 = subst_Apply(tau, term_Copy(term_FirstArgument(partnerAtom2)));
+ pRight2 = subst_Apply(tau, term_Copy(term_SecondArgument(partnerAtom2)));
+
+ /* First try unification with left side */
+ cont_Check();
+
+ if (unify_UnifyCom(cont_LeftContext(), u_tau, pLeft2)) {
+ subst_ExtractUnifierCom(cont_LeftContext(), &rho);
+
+ s_sigma = t_sigma = (TERM) NULL;
+ checkPassed = TRUE;
+
+ if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(C1,i))) {
+ s_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(s)));
+ t_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(t)));
+ ordResult = ord_Compare(s_sigma, t_sigma, Flags, Precedence);
+ if (ordResult == ord_SmallerThan() || ordResult == ord_Equal())
+ checkPassed = FALSE;
+ }
+
+ if (checkPassed && inf_LiteralsMaxWith2Subst(C1,i,C2,j,rho,tau,
+ Flags, Precedence)) {
+ v2_sigma = subst_Apply(rho, term_Copy(pRight2));
+ result = list_Nconc(inf_ApplyMParamod(C1,C2,i,j,k,u_tau,v,s2,
+ t,v2_sigma,tau,rho,
+ Flags, Precedence),
+ result);
+ term_Delete(v2_sigma);
+ }
+ /* Now cleanup */
+ if (s_sigma != NULL) { /* Also t_sigma != NULL */
+ term_Delete(s_sigma);
+ term_Delete(t_sigma);
+ }
+ subst_Delete(rho);
+ }
+
+ cont_Reset();
+
+ /* Now try unification with right side */
+ if (unify_UnifyCom(cont_LeftContext(), u_tau, pRight2)) {
+ subst_ExtractUnifierCom(cont_LeftContext(), &rho);
+
+ s_sigma = t_sigma = (TERM) NULL;
+ checkPassed = TRUE;
+
+ if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(C1,i))) {
+ s_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(s)));
+ t_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(t)));
+ ordResult = ord_Compare(s_sigma, t_sigma, Flags, Precedence);
+ if (ordResult == ord_SmallerThan() || ordResult == ord_Equal())
+ checkPassed = FALSE;
+ }
+
+ if (checkPassed && inf_LiteralsMaxWith2Subst(C1,i,C2,j,rho,tau,
+ Flags, Precedence)) {
+ v2_sigma = subst_Apply(rho, term_Copy(pLeft2));
+ result = list_Nconc(inf_ApplyMParamod(C1,C2,i,j,k,u_tau,v,s2,
+ t,v2_sigma,tau,rho,
+ Flags, Precedence),
+ result);
+ term_Delete(v2_sigma);
+ }
+ /* Now cleanup */
+ if (s_sigma != NULL) { /* Also t_sigma != NULL */
+ term_Delete(s_sigma);
+ term_Delete(t_sigma);
+ }
+ subst_Delete(rho);
+ }
+
+ cont_Reset();
+
+ term_Delete(pLeft2);
+ term_Delete(pRight2);
+ } /* k != j */
+ } /* for k */
+
+ return result;
+}
+
+
+static LIST inf_LitMParamod(CLAUSE Clause, int i, BOOL Turn,
+ SHARED_INDEX ShIndex, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause with a strict maximal equality literal at
+ position <i>, a boolean value, a shared index, a
+ flag store and a precedence.
+ If <Turn> is TRUE, the left and right term of the
+ equality are exchanged.
+ RETURNS: A list of clauses derivable from the given clause
+ by merging paramodulation.
+ This function searches a second clause with at least
+ two positive equalities, where the first equation
+ has a subterm s', that is unifiable with the left
+ (or right) side of the given equation.
+***************************************************************/
+{
+ LIST result, unifiers, literals;
+ LITERAL actLit;
+ TERM s, t, help;
+
+ actLit = clause_GetLiteral(Clause, i);
+ s = term_FirstArgument(clause_LiteralSignedAtom(actLit));
+ t = term_SecondArgument(clause_LiteralSignedAtom(actLit));
+ if (Turn) {
+ /* Exchange s and t */
+ help = s;
+ s = t;
+ t = help;
+ }
+ result = list_Nil();
+
+ unifiers = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+ cont_RightContext(), s);
+
+ for ( ; !list_Empty(unifiers); unifiers = list_Pop(unifiers)) {
+ TERM s2 = (TERM) list_Car(unifiers); /* Unifiable with s */
+
+ if (!term_IsVariable(s2) && !term_IsAtom(s2)) {
+ for (literals = sharing_GetDataList(s2, ShIndex);
+ !list_Empty(literals);
+ literals = list_Pop(literals)) {
+ LITERAL partnerLit = (LITERAL) list_Car(literals); /* u = v[s'] */
+ CLAUSE partnerClause = clause_LiteralOwningClause(partnerLit);
+ TERM partnerAtom = clause_LiteralAtom(partnerLit);
+ int pli = clause_LiteralGetIndex(partnerLit);
+
+ if (!clause_GetFlag(partnerClause, CLAUSESELECT) &&
+ clause_LiteralGetFlag(partnerLit, STRICTMAXIMAL) &&
+ clause_LiteralIsPositive(partnerLit) && /* succedent literal */
+ clause_LiteralIsEquality(partnerLit) &&
+ clause_NumOfSuccLits(partnerClause) > 1 && /* > 1 pos. literals */
+ clause_HasSolvedConstraint(partnerClause)) {
+ TERM partnerLeft = term_FirstArgument(partnerAtom);
+ TERM partnerRight = term_SecondArgument(partnerAtom);
+ BOOL inPartnerRight = term_HasPointerSubterm(partnerRight, s2);
+
+ if (!clause_LiteralIsOrientedEquality(partnerLit) || inPartnerRight){
+ /* Don't do this if u=v is oriented and s2 is not a subterm of v */
+ TERM newPLeft, newPRight;
+ SUBST tau;
+ SYMBOL partnerMaxVar;
+ ord_RESULT ordResult;
+
+ partnerMaxVar = clause_MaxVar(partnerClause);
+ clause_RenameVarsBiggerThan(Clause, partnerMaxVar);
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), s, cont_RightContext(), s2);
+ subst_ExtractUnifierCom(cont_LeftContext(), &tau);
+ cont_Reset();
+
+ newPLeft = subst_Apply(tau, term_Copy(partnerLeft));
+ newPRight = subst_Apply(tau, term_Copy(partnerRight));
+ if (clause_LiteralIsOrientedEquality(partnerLit))
+ ordResult = ord_GreaterThan();
+ else
+ ordResult = ord_Compare(newPLeft, newPRight, Flags, Precedence);
+
+ if (inPartnerRight && ord_IsGreaterThan(ordResult)) {
+ /* Take a look at right side */
+ result = list_Nconc(inf_Lit2MParamod(Clause,partnerClause,i,pli,
+ s, t,s2,partnerRight,newPLeft,
+ tau, Flags, Precedence),
+ result);
+ }
+ if (ord_IsSmallerThan(ordResult) &&
+ (!inPartnerRight || term_HasPointerSubterm(partnerLeft, s2))) {
+ /* If s2 is not in partnerRight, it MUST be in partnerLeft,
+ else really do the test */
+ /* Take a look at left side */
+ result = list_Nconc(inf_Lit2MParamod(Clause,partnerClause,i,pli,
+ s,t,s2,partnerLeft,newPRight,
+ tau,Flags, Precedence),
+ result);
+ }
+
+ term_Delete(newPLeft);
+ term_Delete(newPRight);
+ subst_Delete(tau);
+ }
+ }
+ } /* for all Literals containing s2 */
+ } /* if s2 isn't a variable */
+ } /* for all unifiers s2 */
+
+ return result;
+}
+
+
+static LIST inf_MParamodLitToGiven(CLAUSE Clause, int j, BOOL Turn,
+ SHARED_INDEX ShIndex, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause with a strict maximal equality literal at
+ position <j>, a boolean value, a shared index a
+ flag store and a precedence.
+ If <Turn> is TRUE, the left and right term of the
+ equality are exchanged.
+ RETURNS: A list of clauses derivable from the given clause
+ by merging paramodulation with this literal as second
+ literal of the rule.
+***************************************************************/
+{
+ LIST result, unifiers, superterms, literals;
+ LITERAL actLit;
+ TERM u, v;
+ int bottom;
+
+ if (clause_NumOfSuccLits(Clause) < 2)
+ return list_Nil(); /* There must be at least two positive literals */
+
+ actLit = clause_GetLiteral(Clause, j);
+ u = term_FirstArgument(clause_LiteralSignedAtom(actLit));
+ v = term_SecondArgument(clause_LiteralSignedAtom(actLit));
+ if (Turn) {
+ /* Exchange s and t */
+ TERM help = u;
+ u = v;
+ v = help;
+ }
+ result = list_Nil();
+ bottom = stack_Bottom();
+
+ sharing_PushReverseOnStack(v); /* Without variables! */
+
+ while (!stack_Empty(bottom)) {
+ TERM s2 = (TERM) stack_PopResult();
+
+ for (unifiers = st_GetUnifier(cont_LeftContext(),sharing_Index(ShIndex),
+ cont_RightContext(), s2);
+ !list_Empty(unifiers);
+ unifiers = list_Pop(unifiers)) {
+ TERM s = (TERM) list_Car(unifiers);
+
+ for (superterms = term_SupertermList(s);
+ !list_Empty(superterms);
+ superterms = list_Cdr(superterms)) {
+ TERM partnerAtom = (TERM) list_Car(superterms);
+
+ if (fol_IsEquality(partnerAtom)) {
+ for (literals = sharing_NAtomDataList(partnerAtom);
+ !list_Empty(literals);
+ literals = list_Cdr(literals)) {
+ LITERAL partnerLit = (LITERAL) list_Car(literals);
+ CLAUSE partnerClause = clause_LiteralOwningClause(partnerLit);
+ int i = clause_LiteralGetIndex(partnerLit);
+
+ if (!clause_GetFlag(partnerClause,CLAUSESELECT) &&
+ clause_LiteralGetFlag(partnerLit,STRICTMAXIMAL) &&
+ clause_LiteralIsPositive(partnerLit) &&
+ (s == term_FirstArgument(partnerAtom) ||
+ !clause_LiteralIsOrientedEquality(partnerLit)) &&
+ clause_HasSolvedConstraint(partnerClause) &&
+ clause_Number(partnerClause) != clause_Number(Clause)) {
+ /* We don't allow self inferences (both clauses having the */
+ /* same number) here, because they're already made in function */
+ /* inf_LitMParamod. */
+ SYMBOL partnerMaxVar;
+ SUBST tau;
+ TERM u_tau, v_tau;
+ BOOL checkPassed;
+
+ partnerMaxVar = clause_MaxVar(partnerClause);
+ clause_RenameVarsBiggerThan(Clause, partnerMaxVar);
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), s, cont_RightContext(), s2);
+ subst_ExtractUnifierCom(cont_LeftContext(), &tau);
+ cont_Reset();
+
+ u_tau = v_tau = (TERM) NULL;
+ checkPassed = TRUE;
+
+ /* u_tau must be greater than v_tau */
+ if (!clause_LiteralIsOrientedEquality(actLit)) {
+ u_tau = subst_Apply(tau, term_Copy(u));
+ v_tau = subst_Apply(tau, term_Copy(v));
+ if (ord_Compare(u_tau, v_tau, Flags, Precedence) != ord_GreaterThan())
+ checkPassed = FALSE;
+ }
+
+ if (checkPassed) {
+ /* u_tau > v_tau */
+ TERM t;
+
+ if (s == term_FirstArgument(partnerAtom))
+ t = term_SecondArgument(partnerAtom);
+ else
+ t = term_FirstArgument(partnerAtom);
+ if (u_tau == (TERM)NULL) {
+ u_tau = subst_Apply(tau, term_Copy(u));
+ v_tau = subst_Apply(tau, term_Copy(v));
+ }
+
+ result = list_Nconc(inf_Lit2MParamod(partnerClause,Clause,i,j,
+ s,t,s2,v,u_tau, tau,Flags,
+ Precedence),
+ result);
+ }
+
+ /* Now cleanup */
+ if (u_tau != (TERM)NULL) {
+ term_Delete(u_tau);
+ term_Delete(v_tau);
+ }
+ subst_Delete(tau);
+ clause_Normalize(Clause);
+ }
+ }
+ } /* partnerAtom is equality */
+ }
+ }
+ }
+
+ return result;
+}
+
+
+LIST inf_MergingParamodulation(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a shared index, a flag store and a
+ precedence.
+ RETURNS: A list of clauses derivable from the given clause
+ by merging paramodulation.
+ MEMORY: Memory is allocated for the list and the clauses.
+***************************************************************/
+{
+ LIST result;
+ CLAUSE copy;
+ int last, i;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_MergingParamodulation: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (clause_GetFlag(GivenClause, CLAUSESELECT) ||
+ clause_HasEmptySuccedent(GivenClause) ||
+ !clause_HasSolvedConstraint(GivenClause))
+ return list_Nil();
+
+ result = list_Nil();
+ copy = clause_Copy(GivenClause);
+ last = clause_LastSuccedentLitIndex(copy);
+
+ for (i = clause_FirstSuccedentLitIndex(copy); i <= last; i++) {
+ LITERAL actLit = clause_GetLiteral(copy, i);
+ TERM atom = clause_LiteralSignedAtom(actLit);
+
+ if (clause_LiteralGetFlag(actLit, STRICTMAXIMAL) &&
+ fol_IsEquality(atom)) {
+
+ result = list_Nconc(inf_LitMParamod(copy,i,FALSE,ShIndex,
+ Flags, Precedence),
+ result);
+ /* Assume GivenClause is the second clause of the rule */
+ result = list_Nconc(inf_MParamodLitToGiven(copy,i,FALSE,ShIndex,
+ Flags, Precedence),
+ result);
+
+ if (!clause_LiteralIsOrientedEquality(actLit)) {
+ /* First check rule with left and right side exchanged */
+ result = list_Nconc(inf_LitMParamod(copy, i, TRUE, ShIndex,
+ Flags, Precedence),
+ result);
+ /* Now assume GivenClause is the second clause of the rule */
+ /* Check with sides exchanged */
+ result = list_Nconc(inf_MParamodLitToGiven(copy,i,TRUE,ShIndex,
+ Flags, Precedence),
+ result);
+ }
+ }
+ } /* for */
+ clause_Delete(copy);
+
+ return result;
+}
+
+
+static CLAUSE inf_ApplyGenRes(LITERAL PosLit, LITERAL NegLit, SUBST SubstTermS,
+ SUBST SubstPartnerTermS, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause to use for Resolution, the index of a
+ positive non-equality literal, a unifiable literal,
+ the substitutions for the terms to unify, a flag
+ store and a precedence.
+ RETURNS: A clause derivable from the literals owning
+ clause by Resolution wrt. the Index.
+ MEMORY: Memory for the new clause is allocated.
+***************************************************************/
+{
+ CLAUSE NewClause, GivenClause, PartnerClause;
+ int i,j,lc,la,ls,pi,pls,pla,plc,help,ConNeg,AntNeg; /* p=Partner,l=last */
+
+ PartnerClause = clause_LiteralOwningClause(NegLit);
+ GivenClause = clause_LiteralOwningClause(PosLit);
+
+ pls = clause_LastSuccedentLitIndex(PartnerClause);
+ pla = clause_LastAntecedentLitIndex(PartnerClause);
+ plc = clause_LastConstraintLitIndex(PartnerClause);
+
+ pi = clause_LiteralGetIndex(NegLit);
+
+ ls = clause_LastSuccedentLitIndex(GivenClause);
+ la = clause_LastAntecedentLitIndex(GivenClause);
+ lc = clause_LastConstraintLitIndex(GivenClause);
+
+ i = clause_LiteralGetIndex(PosLit);
+
+ if (pi <= plc) {
+ ConNeg = 1;
+ AntNeg = 0;
+ }
+ else {
+ ConNeg = 0;
+ AntNeg = 1;
+ }
+
+ NewClause = clause_CreateBody((clause_Length(GivenClause) -1) +
+ clause_Length(PartnerClause) -1);
+
+ clause_SetNumOfConsLits(NewClause,
+ (clause_NumOfConsLits(GivenClause) +
+ (clause_NumOfConsLits(PartnerClause)-ConNeg)));
+
+ clause_SetNumOfAnteLits(NewClause,
+ (clause_NumOfAnteLits(GivenClause) +
+ (clause_NumOfAnteLits(PartnerClause)-AntNeg)));
+
+ clause_SetNumOfSuccLits(NewClause,
+ ((clause_NumOfSuccLits(GivenClause) -1)+
+ clause_NumOfSuccLits(PartnerClause)));
+
+
+ /* First set the literals from the GivenClause : */
+ for (j = clause_FirstLitIndex(); j <= lc; j++) {
+ clause_SetLiteral(NewClause, j,
+ clause_LiteralCreate(subst_Apply(SubstTermS,
+ term_Copy(clause_GetLiteralTerm(GivenClause, j))),NewClause));
+ }
+
+ /* help = number of literals to leave empty */
+ help = clause_NumOfConsLits(PartnerClause)-ConNeg;
+
+ for ( ; j <= la; j++) {
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(subst_Apply(SubstTermS,
+ term_Copy(clause_GetLiteralTerm(GivenClause, j))),NewClause));
+ }
+
+ /* help = number of literals to leave empty */
+ help += clause_NumOfAnteLits(PartnerClause)-AntNeg;
+
+
+
+ for ( ; j <= ls; j++) {
+ if (j != i) {
+ /* The ActLit isn't copied! */
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(subst_Apply(SubstTermS,
+ term_Copy(clause_GetLiteralTerm(GivenClause, j))),NewClause));
+
+ } else {
+ /*the index has to be decreased to avoid an empty literal! */
+ help--;
+ }
+ }
+
+ /* Now we consider the PartnerClause : */
+
+ /* help = number of already set constraint (GivenClause-) literals */
+ help = clause_NumOfConsLits(GivenClause);
+
+ for (j = clause_FirstLitIndex(); j <= plc; j++) {
+ if (j != pi) {
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(subst_Apply(SubstPartnerTermS,
+ term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+ } else {
+ help--;
+ }
+ }
+
+ /* help = number of already set constraint and antecedent Given-literals */
+ help += clause_NumOfAnteLits(GivenClause);
+
+ for ( ; j <= pla; j++) {
+
+ if (j != pi) {
+ /* The NegLit isn't copied! */
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(subst_Apply(SubstPartnerTermS,
+ term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+
+ } else {
+ /* The index has to be shifted as above. */
+ help--;
+ }
+ }
+
+ /* help = number of already set (GivenClause-) literals */
+ help += clause_NumOfSuccLits(GivenClause) - 1;
+
+ for ( ; j <= pls; j++) {
+ clause_SetLiteral(NewClause, (j + help),
+ clause_LiteralCreate(subst_Apply(SubstPartnerTermS,
+ term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+ } /* end of NewClause creation (last for loop). */
+
+
+ clause_SetDataFromParents(NewClause,PartnerClause,pi,GivenClause,i,
+ Flags, Precedence);
+ clause_SetFromGeneralResolution(NewClause);
+
+ return(NewClause);
+}
+
+
+LIST inf_GeneralResolution(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+ BOOL Ordered, BOOL Equations,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause and an Index, usually the WorkedOffIndex,
+ two boolean flags, a flag store and a precedence.
+ RETURNS: A list of clauses derivable from the GivenClause by
+ GeneralResolution wrt. the Index.
+ If <Ordered>=TRUE, this function generates ordered
+ resolution inferences (the literals must be selected or
+ (strict) maximal), otherwise it generates standard
+ resolution inferences.
+ If <Equations>=TRUE, equations are allowed for inferences,
+ else no inferences with equations are generated. The
+ default is <Equations>=FALSE..
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ CLAUSE GivenCopy;
+ LIST Result;
+ LITERAL ActLit;
+ TERM Atom;
+ int i,n;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GeneralResolution: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!clause_HasSolvedConstraint(GivenClause))
+ return list_Nil();
+
+ Result = list_Nil();
+ GivenCopy = clause_Copy(GivenClause);
+
+ if (clause_GetFlag(GivenCopy,CLAUSESELECT))
+ n = clause_LastAntecedentLitIndex(GivenCopy);
+ else
+ n = clause_LastSuccedentLitIndex(GivenCopy);
+
+ for (i = clause_FirstAntecedentLitIndex(GivenCopy); i <= n; i++) {
+
+ ActLit = clause_GetLiteral(GivenCopy, i);
+ Atom = clause_LiteralAtom(ActLit);
+
+ if ((Equations || !fol_IsEquality(Atom)) &&
+ (clause_LiteralGetFlag(ActLit,LITSELECT) ||
+ (!clause_GetFlag(GivenCopy,CLAUSESELECT) &&
+ (!Ordered || clause_LiteralIsMaximal(ActLit)))) &&
+ (!Ordered || clause_LiteralIsFromAntecedent(ActLit) ||
+ clause_LiteralGetFlag(ActLit,STRICTMAXIMAL))) {
+ /* Positive literals must be strict maximal for ORe, */
+ /* negative literals must be either selected or maximal. */
+ LIST TermList;
+ BOOL Swapped;
+
+ Swapped = FALSE;
+
+ /* The 'endless' loop may run twice for equations, once for other atoms */
+ while (TRUE) {
+ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+ cont_RightContext(), Atom);
+
+ for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+ LIST LitList;
+ TERM PartnerAtom;
+
+ PartnerAtom = list_First(TermList);
+
+ if (!term_IsVariable(PartnerAtom)) {
+ LITERAL PartnerLit;
+ int j;
+ CLAUSE PartnerClause;
+
+ for (LitList = sharing_NAtomDataList(PartnerAtom);
+ !list_Empty(LitList); LitList = list_Cdr(LitList)) {
+ PartnerLit = list_Car(LitList);
+ j = clause_LiteralGetIndex(PartnerLit);
+ PartnerClause = clause_LiteralOwningClause(PartnerLit);
+
+ if (clause_LiteralsAreComplementary(PartnerLit,ActLit) &&
+ clause_HasSolvedConstraint(PartnerClause) &&
+ /* Negative literals must be from the antecedent */
+ (clause_LiteralIsPositive(PartnerLit) ||
+ clause_LiteralIsFromAntecedent(PartnerLit)) &&
+ /* Check whether literal is selected or maximal */
+ (clause_LiteralGetFlag(PartnerLit,LITSELECT) ||
+ (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+ (!Ordered || clause_LiteralIsMaximal(PartnerLit)))) &&
+ /* Positive literals must be strict maximal for ORe */
+ (!Ordered || clause_LiteralIsNegative(PartnerLit) ||
+ clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+ /* Avoid duplicate self-inferences */
+ (clause_LiteralIsPositive(PartnerLit) ||
+ clause_Number(GivenClause) != clause_Number(PartnerClause))) {
+ SUBST Subst, PartnerSubst;
+ SYMBOL MaxVar;
+
+ MaxVar = clause_MaxVar(PartnerClause);
+ clause_RenameVarsBiggerThan(GivenCopy, MaxVar);
+
+ cont_Check();
+ if (!unify_UnifyNoOC(cont_LeftContext(), Atom, cont_RightContext(),
+ PartnerAtom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GeneralResolution: Unification failed.");
+ misc_FinishErrorReport();
+ }
+ subst_ExtractUnifier(cont_LeftContext(), &Subst,
+ cont_RightContext(), &PartnerSubst);
+ cont_Reset();
+
+ if (!Ordered ||
+ inf_LiteralsMax(GivenCopy, i, Subst, PartnerClause, j,
+ PartnerSubst, Flags, Precedence)) {
+ if (clause_LiteralIsNegative(PartnerLit))
+ Result = list_Cons(inf_ApplyGenRes(ActLit,PartnerLit,Subst,
+ PartnerSubst,
+ Flags, Precedence),
+ Result);
+ else
+ Result = list_Cons(inf_ApplyGenRes(PartnerLit, ActLit,
+ PartnerSubst,Subst,
+ Flags, Precedence),
+ Result);
+ }
+ subst_Delete(Subst);
+ subst_Delete(PartnerSubst);
+ }
+ } /* end of for (LitList = sharing_NAtomDataList ...). */
+ } /* end of if (!term_IsVariable(PartnerAtom)). */
+ } /* end of for (TermList = st_GetUnifier...). */
+ if (!Swapped && fol_IsEquality(Atom)) {
+ term_EqualitySwap(Atom); /* Atom is from copied clause */
+ Swapped = TRUE;
+ } else
+ break;
+ } /* end of 'endless' loop */
+ } /* end of if (clause_LiteralIsMaximal(ActLit)). */
+ } /* end of for 'all antecedent and succedent literals'. */
+
+ clause_Delete(GivenCopy);
+
+ return Result;
+}
+
+
+LIST inf_UnitResolution(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+ BOOL Equations, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause and an Index, usually the WorkedOffIndex,
+ a boolean flag, a flag store and a precedence.
+ RETURNS: A list of clauses derivable from the Givenclause by
+ Unit Resolution wrt. the Index.
+ This function does the same inferences as standard resolution,
+ except that at least one of the clauses must be a unit clause.
+ The involved literals don't have to be maximal.
+ If <Equations>=TRUE, equations are allowed for inferences,
+ else no inferences with equations are made. The
+ default is <Equations>=FALSE..
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ CLAUSE GivenCopy;
+ LIST Result;
+ LITERAL ActLit;
+ TERM Atom;
+ BOOL GivenIsUnit;
+ int i,n;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_UnitResolution: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!clause_HasSolvedConstraint(GivenClause))
+ return list_Nil();
+
+ Result = list_Nil();
+
+ GivenCopy = clause_Copy(GivenClause);
+ GivenIsUnit = (clause_Length(GivenCopy) == 1);
+
+ if (clause_GetFlag(GivenCopy,CLAUSESELECT))
+ n = clause_LastAntecedentLitIndex(GivenCopy);
+ else
+ n = clause_LastSuccedentLitIndex(GivenCopy);
+
+ for (i=clause_FirstAntecedentLitIndex(GivenCopy); i <= n; i++) {
+
+ ActLit = clause_GetLiteral(GivenCopy, i);
+ Atom = clause_LiteralAtom(ActLit);
+
+ if ((Equations || !fol_IsEquality(Atom)) &&
+ (clause_LiteralGetFlag(ActLit,LITSELECT) ||
+ !clause_GetFlag(GivenCopy,CLAUSESELECT))) {
+ LIST TermList;
+ BOOL Swapped;
+
+ Swapped = FALSE;
+
+ /* The 'endless' loop runs twice for equations, once for other atoms */
+ while (TRUE) {
+ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+ cont_RightContext(), Atom);
+
+ for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+ LIST LitList;
+ TERM PartnerAtom;
+
+ PartnerAtom = list_First(TermList);
+
+ if (!term_IsVariable(PartnerAtom)) {
+ LITERAL PartnerLit;
+ CLAUSE PartnerClause;
+
+ for (LitList = sharing_NAtomDataList(PartnerAtom);
+ !list_Empty(LitList); LitList = list_Cdr(LitList)) {
+ PartnerLit = list_Car(LitList);
+ PartnerClause = clause_LiteralOwningClause(PartnerLit);
+
+ if ((GivenIsUnit || clause_Length(PartnerClause) == 1) &&
+ clause_LiteralsAreComplementary(PartnerLit,ActLit) &&
+ clause_HasSolvedConstraint(PartnerClause) &&
+ /* Negative literals must be from the antecedent */
+ (clause_LiteralIsPositive(PartnerLit) ||
+ clause_LiteralIsFromAntecedent(PartnerLit)) &&
+ /* Either the literal is selected or no literal is selected */
+ (clause_LiteralGetFlag(PartnerLit,LITSELECT) ||
+ !clause_GetFlag(PartnerClause,CLAUSESELECT))) {
+ /* Self-inferences aren't possible, since then the clause must */
+ /* be a unit and a single literal can't be both positive and */
+ /* negative. */
+ SUBST Subst, PartnerSubst;
+ SYMBOL MaxVar;
+
+ MaxVar = clause_MaxVar(PartnerClause);
+ clause_RenameVarsBiggerThan(GivenCopy, MaxVar);
+
+ cont_Check();
+ if (!unify_UnifyNoOC(cont_LeftContext(), Atom,
+ cont_RightContext(), PartnerAtom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_UnitResolution: Unification failed.");
+ misc_FinishErrorReport();
+ }
+ subst_ExtractUnifier(cont_LeftContext(), &Subst,
+ cont_RightContext(), &PartnerSubst);
+ cont_Reset();
+
+ if (clause_LiteralIsNegative(PartnerLit))
+ Result = list_Cons(inf_ApplyGenRes(ActLit, PartnerLit, Subst,
+ PartnerSubst,
+ Flags, Precedence),
+ Result);
+ else
+ Result = list_Cons(inf_ApplyGenRes(PartnerLit, ActLit,
+ PartnerSubst,Subst,
+ Flags, Precedence),
+ Result);
+ subst_Delete(Subst);
+ subst_Delete(PartnerSubst);
+ }
+ } /* end of for (LitList = sharing_NAtomDataList ...). */
+ } /* end of if (!term_IsVariable(PartnerAtom)). */
+ } /* end of for (TermList = st_GetUnifier...). */
+ if (!Swapped && fol_IsEquality(Atom)) {
+ term_EqualitySwap(Atom); /* Atom is from copied clause */
+ Swapped = TRUE;
+ } else
+ break;
+ } /* end of 'endless' loop */
+ } /* end of if (clause_LiteralIsMaximal(ActLit)). */
+ } /* end of for 'all antecedent and succedent literals'. */
+
+ clause_Delete(GivenCopy);
+
+ return Result;
+}
+
+LIST inf_BoundedDepthUnitResolution(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+ BOOL ConClause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause and an Index, usually the WorkedOffIndex,
+ a flag indicating whether the partner clause must be
+ a conjecture clause, a flag store and a precedence.
+ RETURNS: A list of clauses derivable from the Givenclause by
+ bounded depth unit resolution wrt. the Index.
+ This acts similar to inf_UnitResolution, except that
+ it limits the depth of resolvents to the maximum
+ depth of its parent clauses.
+ MEMORY: A list of clauses is produced, where memory for the
+ list and the clauses is allocated.
+***************************************************************/
+ /* GivenClause is always a CONCLAUSE */
+{
+ CLAUSE GivenCopy;
+ LIST Result;
+ LITERAL ActLit;
+ TERM Atom;
+ int i,n,depth;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_BoundedDepthUnitResolution: Illegal input.");
+ misc_FinishErrorReport();
+ }
+ cont_Check();
+#endif
+
+ Result = list_Nil();
+ GivenCopy = clause_Copy(GivenClause);
+ n = clause_LastLitIndex(GivenCopy);
+ depth = clause_ComputeTermDepth(GivenCopy);
+
+ for (i = clause_FirstLitIndex(); i <= n; i++) {
+ LIST TermList;
+ BOOL Swapped;
+
+ ActLit = clause_GetLiteral(GivenCopy, i);
+ Atom = clause_LiteralAtom(ActLit);
+ Swapped = FALSE;
+
+ /* The 'endless' loop runs twice for equations, once for other atoms */
+ while (TRUE) {
+ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+ cont_RightContext(), Atom);
+
+ for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+ LIST LitList;
+ TERM PartnerAtom;
+
+ PartnerAtom = list_First(TermList);
+
+ if (!term_IsVariable(PartnerAtom)) {
+ LITERAL PartnerLit;
+ CLAUSE PartnerClause;
+
+ for (LitList = sharing_NAtomDataList(PartnerAtom);
+ !list_Empty(LitList); LitList = list_Cdr(LitList)) {
+ PartnerLit = list_Car(LitList);
+ PartnerClause = clause_LiteralOwningClause(PartnerLit);
+
+ if (clause_LiteralsAreComplementary(PartnerLit,ActLit) &&
+ (clause_Length(GivenCopy)==1 || clause_Length(PartnerClause)==1) &&
+ (clause_GetFlag(GivenCopy,CONCLAUSE) ||
+ clause_GetFlag(PartnerClause,CONCLAUSE)) &&
+ (!ConClause || clause_GetFlag(PartnerClause,CONCLAUSE))) {
+ SUBST Subst, PartnerSubst;
+ SYMBOL MaxVar;
+ int maxdepth;
+ CLAUSE Resolvent;
+
+ maxdepth = misc_Max(depth, clause_ComputeTermDepth(PartnerClause));
+ MaxVar = clause_MaxVar(PartnerClause);
+ clause_RenameVarsBiggerThan(GivenCopy, MaxVar);
+
+ cont_Check();
+ if (!unify_UnifyNoOC(cont_LeftContext(), Atom,
+ cont_RightContext(), PartnerAtom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_BoundedDepthUnitResolution: Unification failed.");
+ misc_FinishErrorReport();
+ }
+ subst_ExtractUnifier(cont_LeftContext(), &Subst,
+ cont_RightContext(), &PartnerSubst);
+ cont_Reset();
+
+ if (clause_LiteralIsNegative(PartnerLit))
+ Resolvent = inf_ApplyGenRes(ActLit, PartnerLit, Subst,
+ PartnerSubst, Flags, Precedence);
+ else
+ Resolvent = inf_ApplyGenRes(PartnerLit, ActLit, PartnerSubst,
+ Subst, Flags, Precedence);
+
+ if (clause_ComputeTermDepth(Resolvent) > maxdepth)
+ clause_Delete(Resolvent);
+ else {
+ Result = list_Cons(Resolvent,Result);
+ }
+ subst_Delete(Subst);
+ subst_Delete(PartnerSubst);
+ }
+ }
+ }
+ }
+ if (!Swapped && fol_IsEquality(Atom)) {
+ term_EqualitySwap(Atom); /* Given Clause is a copy */
+ Swapped = TRUE;
+ } else
+ break;
+ } /* end of 'endless' loop */
+ }
+
+ clause_Delete(GivenCopy);
+
+ return(Result);
+}
+
+static CLAUSE inf_ApplyGeneralFactoring(CLAUSE Clause, NAT i, NAT j,
+ SUBST Subst, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause an index in the clause, a substitution a
+ flag store and a precedence.
+ RETURNS: A new clause obtained from <Clause> by applying <Subst>
+ and deleting literal <j> keeping literal <i>
+***************************************************************/
+{
+ CLAUSE NewClause;
+
+ NewClause = clause_Copy(Clause);
+ clause_ClearFlags(NewClause);
+ clause_SubstApply(Subst, NewClause);
+
+ clause_DeleteLiteral(NewClause, i, Flags, Precedence);
+
+ list_Delete(clause_ParentClauses(NewClause));
+ list_Delete(clause_ParentLiterals(NewClause));
+ clause_SetParentLiterals(NewClause,list_Nil());
+ clause_SetParentClauses(NewClause,list_Nil());
+
+ clause_SetDataFromFather(NewClause, Clause, j, Flags, Precedence);
+ clause_SetFromGeneralFactoring(NewClause);
+
+ clause_AddParentClause(NewClause, clause_Number(Clause));
+ clause_AddParentLiteral(NewClause, i);
+
+ clause_NewNumber(NewClause);
+
+ return NewClause;
+}
+
+
+LIST inf_GeneralFactoring(CLAUSE GivenClause, BOOL Ordered, BOOL Left,
+ BOOL Equations, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, three boolean flags, a flag store and a
+ precedence.
+ If <Ordered>=TRUE, this function generates ordered
+ factoring inferences, otherwise standard factoring
+ inferences.
+ If <Left> is FALSE, this function only makes factoring
+ right inferences, otherwise it also makes factoring left
+ inferences.
+ If <Equations>=TRUE, equations are allowed for inferences,
+ else no inferences with equations are generated. The
+ default is <Equations>=TRUE.
+ RETURNS: A list of clauses derivable from <GivenClause> by GF.
+***************************************************************/
+{
+ LIST Result;
+ LITERAL ActLit;
+ int i,j,last;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GeneralFactoring: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!clause_HasSolvedConstraint(GivenClause))
+ return list_Nil();
+
+ Result = list_Nil();
+
+ /* Always try Factoring Right inferences */
+ last = clause_LastSuccedentLitIndex(GivenClause);
+ if (!clause_GetFlag(GivenClause,CLAUSESELECT)) {
+ for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= last; i++) {
+ ActLit = clause_GetLiteral(GivenClause, i);
+ if ((!Ordered || clause_LiteralIsMaximal(ActLit)) &&
+ (Equations || !clause_LiteralIsEquality(ActLit))) {
+ TERM Atom, PartnerAtom;
+ LITERAL PartnerLit;
+ Atom = clause_LiteralAtom(ActLit);
+ for (j = clause_FirstSuccedentLitIndex(GivenClause); j <= last; j++) {
+ if (i != j) {
+ PartnerLit = clause_GetLiteral(GivenClause, j);
+ PartnerAtom = clause_LiteralAtom(PartnerLit);
+ if ((j>i ||(Ordered && !clause_LiteralIsMaximal(PartnerLit))) &&
+ term_EqualTopSymbols(Atom, PartnerAtom)) {
+ /* This condition avoids duplicate inferences */
+ cont_Check();
+ if (unify_UnifyCom(cont_LeftContext(), Atom, PartnerAtom)) {
+ SUBST mgu;
+ subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+ if (!Ordered || inf_LitMax(GivenClause,i,j,mgu,FALSE,
+ Flags, Precedence))
+ Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j,
+ mgu,Flags,
+ Precedence),
+ Result);
+ subst_Delete(mgu);
+ }
+ cont_Reset();
+ if (fol_IsEquality(Atom) && /* PartnerAtom is equality, too */
+ unify_UnifyCom(cont_LeftContext(),
+ term_SecondArgument(Atom),
+ term_FirstArgument(PartnerAtom)) &&
+ unify_UnifyCom(cont_LeftContext(),
+ term_FirstArgument(Atom),
+ term_SecondArgument(PartnerAtom))) {
+ SUBST mgu;
+ subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+ if (!Ordered || inf_LitMax(GivenClause,i,j,mgu,FALSE,
+ Flags, Precedence))
+ Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j,
+ mgu,Flags,
+ Precedence),
+ Result);
+ subst_Delete(mgu);
+ }
+ cont_Reset();
+ }
+ }
+ }
+ }
+ }
+ }
+ /* Try Factoring Left inferences only if <Left>==TRUE */
+ if (Left) {
+ last = clause_LastAntecedentLitIndex(GivenClause);
+ for (i = clause_FirstAntecedentLitIndex(GivenClause); i <= last; i++) {
+ ActLit = clause_GetLiteral(GivenClause, i);
+ if ((Equations || !clause_LiteralIsEquality(ActLit)) &&
+ (clause_LiteralGetFlag(ActLit,LITSELECT) ||
+ (!clause_GetFlag(GivenClause,CLAUSESELECT) &&
+ (!Ordered || clause_LiteralIsMaximal(ActLit))))) {
+ TERM Atom, PartnerAtom;
+ LITERAL PartnerLit;
+ Atom = clause_LiteralAtom(ActLit);
+ for (j = clause_FirstAntecedentLitIndex(GivenClause);j <= last; j++) {
+ if (i != j) {
+ PartnerLit = clause_GetLiteral(GivenClause, j);
+ PartnerAtom = clause_LiteralAtom(PartnerLit);
+ /* In order to avoid duplicate inferences, we do the following */
+ /* somewhat "tricky" test. What we want is something like */
+ /* "if (j>i || j wasn't considered within the outer loop) {...} */
+ /* This lengthy condition can be transformed into the following */
+ /* condition, because only one negative literal is selected. */
+ /* This implies that the literal at index j can't be selected. */
+ if ((j>i || clause_LiteralGetFlag(ActLit,LITSELECT) ||
+ (Ordered && !clause_LiteralIsMaximal(PartnerLit))) &&
+ term_EqualTopSymbols(Atom, PartnerAtom)) {
+ PartnerAtom = clause_LiteralAtom(PartnerLit);
+ cont_Check();
+ if (unify_UnifyCom(cont_LeftContext(), Atom, PartnerAtom)) {
+ SUBST mgu;
+ subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+ if (!Ordered || clause_LiteralGetFlag(ActLit,LITSELECT) ||
+ inf_LitMax(GivenClause,i,j,mgu,FALSE,Flags, Precedence))
+ Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j,
+ mgu,Flags,
+ Precedence),
+ Result);
+ subst_Delete(mgu);
+ }
+ cont_Reset();
+ if (fol_IsEquality(Atom) && /* PartnerAtom is equality, too */
+ unify_UnifyCom(cont_LeftContext(),
+ term_SecondArgument(Atom),
+ term_FirstArgument(PartnerAtom)) &&
+ unify_UnifyCom(cont_LeftContext(),
+ term_FirstArgument(Atom),
+ term_SecondArgument(PartnerAtom))) {
+ SUBST mgu;
+ subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+ if (!Ordered || clause_LiteralGetFlag(ActLit,LITSELECT) ||
+ inf_LitMax(GivenClause,i,j,mgu,FALSE,Flags, Precedence))
+ Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j,
+ mgu,Flags,
+ Precedence),
+ Result);
+ subst_Delete(mgu);
+ }
+ cont_Reset();
+ }
+ }
+ }
+ }
+ }
+ }
+ cont_Check();
+
+ return Result;
+}
+
+
+/***************************************************************/
+/* START of code for new Superposition Left rule */
+/***************************************************************/
+
+
+static LIST inf_GenLitSPLeft(CLAUSE Clause, TERM Left, TERM Right, int i,
+ SHARED_INDEX ShIndex,BOOL OrdPara, BOOL MaxPara,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause (unshared) with a positive equality literal
+ at position <i> where <Left> and <Right> are the
+ arguments of just that literal, two boolean flags,
+ a flag store and a precedence.
+ For Ordered Paramodulation and Superposition <Right>
+ mustn't be greater wrt. the ordering than <Left>.
+ For Superposition the literal must be strictly maximal.
+ RETURNS: A list of clauses derivable with the literals owning
+ clause by Superposition Left wrt. the Index.
+ MEMORY: The list of clauses is extended, where memory for the
+ list and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result, Terms;
+
+#ifdef CHECK
+ if (clause_GetFlag(Clause, CLAUSESELECT) ||
+ (OrdPara &&
+ clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)) &&
+ Left == term_SecondArgument(clause_GetLiteralAtom(Clause,i))) ||
+ (MaxPara &&
+ !clause_LiteralGetFlag(clause_GetLiteral(Clause,i), STRICTMAXIMAL))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenLitSPLeft: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+ Terms = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+ cont_RightContext(), Left);
+
+ for ( ; !list_Empty(Terms); Terms = list_Pop(Terms)) {
+ LIST Lits;
+ TERM Term;
+
+ Term = (TERM)list_First(Terms);
+
+ if (!term_IsVariable(Term) && !symbol_IsPredicate(term_TopSymbol(Term))) {
+
+ Lits = sharing_GetDataList(Term, ShIndex);
+
+ for ( ; !list_Empty(Lits); Lits = list_Pop(Lits)){
+
+ LITERAL PartnerLit;
+ TERM PartnerAtom;
+ CLAUSE PartnerClause;
+ int pli;
+
+ PartnerLit = (LITERAL)list_Car(Lits); /* Antecedent Literal ! */
+ PartnerAtom = clause_LiteralAtom(PartnerLit);
+ pli = clause_LiteralGetIndex(PartnerLit);
+ PartnerClause = clause_LiteralOwningClause(PartnerLit);
+
+ if ((clause_LiteralGetFlag(PartnerLit,LITSELECT) ||
+ (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+ (!MaxPara || clause_LiteralIsMaximal(PartnerLit)))) &&
+ clause_LiteralIsNegative(PartnerLit) &&
+ !clause_GetFlag(PartnerClause,NOPARAINTO) &&
+ clause_HasSolvedConstraint(PartnerClause)) {
+ /* If <PartnerClause> has a solved constraint and <PartnerLit> */
+ /* is negative then <PartnerLit> is from the antecedent. */
+
+ SUBST Subst, PartnerSubst;
+ TERM NewLeft,NewRight;
+ SYMBOL PartnerMaxVar;
+ TERM SupAtom;
+
+ SupAtom = (TERM)NULL;
+ PartnerMaxVar = clause_MaxVar(PartnerClause);
+ NewLeft = Left;
+ clause_RenameVarsBiggerThan(Clause, PartnerMaxVar);
+
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), Left, cont_RightContext(), Term);
+ subst_ExtractUnifier(cont_LeftContext(), &Subst,
+ cont_RightContext(), &PartnerSubst);
+ cont_Reset();
+
+ if (!MaxPara ||
+ inf_LiteralsMax(Clause, i, Subst, PartnerClause, pli,
+ PartnerSubst, Flags, Precedence)) {
+ NewRight = subst_Apply(Subst, term_Copy(Right));
+ if (OrdPara &&
+ !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)))
+ NewLeft = subst_Apply(Subst, term_Copy(Left));
+ if (!OrdPara ||
+ NewLeft == Left ||
+ ord_Compare(NewLeft,NewRight,Flags, Precedence) != ord_SmallerThan()) {
+ if (!MaxPara || clause_LiteralIsPredicate(PartnerLit)) {
+ SupAtom = inf_AllTermsRplac(PartnerAtom,Term,NewRight,
+ PartnerSubst);
+ } else {
+ /* Superposition and <PartnerLit> is equality */
+ if (clause_LiteralIsOrientedEquality(PartnerLit))
+ SupAtom = inf_AllTermsLeftRplac(PartnerAtom,Term,NewRight,
+ PartnerSubst);
+ else {
+ TERM NewPartnerLeft,NewPartnerRight;
+ NewPartnerLeft = subst_Apply(PartnerSubst,
+ term_Copy(term_FirstArgument(PartnerAtom)));
+ NewPartnerRight = subst_Apply(PartnerSubst,
+ term_Copy(term_SecondArgument(PartnerAtom)));
+ switch (ord_Compare(NewPartnerLeft,NewPartnerRight,
+ Flags, Precedence)) {
+ case ord_SMALLER_THAN:
+ SupAtom = inf_AllTermsRightRplac(PartnerAtom,Term,
+ NewRight,PartnerSubst);
+ break;
+ case ord_GREATER_THAN:
+ SupAtom = inf_AllTermsLeftRplac(PartnerAtom,Term,
+ NewRight,PartnerSubst);
+ break;
+ default:
+ SupAtom = inf_AllTermsRplac(PartnerAtom,Term,
+ NewRight,PartnerSubst);
+ }
+ term_Delete(NewPartnerLeft);
+ term_Delete(NewPartnerRight);
+ }
+ }
+
+ if (SupAtom != NULL)
+ Result = list_Cons(inf_ApplyGenSuperposition(Clause, i, Subst,
+ PartnerClause, pli,
+ PartnerSubst,
+ SupAtom, FALSE,
+ OrdPara, MaxPara,
+ Flags, Precedence),
+ Result);
+ }
+ if (NewLeft != Left)
+ term_Delete(NewLeft);
+ term_Delete(NewRight);
+ }
+ subst_Delete(Subst);
+ subst_Delete(PartnerSubst);
+ }
+ }
+ }
+ }
+ return Result;
+}
+
+
+static LIST inf_GenSPLeftEqToGiven(CLAUSE Clause, int i, BOOL Left,
+ SHARED_INDEX ShIndex, BOOL OrdPara,
+ BOOL MaxPara, BOOL Unit, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: An unshared clause, the index of an antecedent
+ literal that is an equality literal, a boolean
+ value, a shared index, three boolean flags
+ controlling inference preconditions, a flag store
+ and a precedence.
+ If Left==TRUE then the left argument of the literal is used
+ otherwise the right argument.
+ OrdPara and MaxPara control inference conditions.
+ If <Unit>==TRUE the clause with the maximal, positive
+ equality must be a unit clause.
+ RETURNS: A list of clauses derivable from generalized
+ superposition Left on the
+ GivenCopy wrt. the Index. See GenSuperpositionLeft
+ for effects of OrdPara and MaxPara
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result, TermList, ParentList;
+ int Bottom;
+ LITERAL Lit;
+ TERM Atom, Term, PartnerTerm, PartnerEq;
+
+ Result = list_Nil();
+ Lit = clause_GetLiteral(Clause,i); /* Is an antecedent Literal ! */
+ Atom = clause_LiteralAtom(Lit);
+
+#ifdef CHECK
+ if (clause_GetFlag(Clause, NOPARAINTO) ||
+ !clause_LiteralIsEquality(Lit) ||
+ !clause_LiteralIsFromAntecedent(Lit) ||
+ (MaxPara && clause_LiteralIsOrientedEquality(Lit) && !Left) ||
+ (!clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT) &&
+ (clause_GetFlag(Clause, CLAUSESELECT) ||
+ (MaxPara && !clause_LiteralIsMaximal(clause_GetLiteral(Clause,i)))))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSPLeftEqToGiven: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Bottom = stack_Bottom();
+ if (Left)
+ sharing_PushOnStack(term_FirstArgument(Atom));
+ else
+ sharing_PushOnStack(term_SecondArgument(Atom));
+
+ while (!stack_Empty(Bottom)) {
+ Term = (TERM)stack_PopResult();
+ if (!term_IsVariable(Term)) {
+ /* Superposition into variables is not necessary */
+ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+ cont_RightContext(), Term);
+ for ( ;!list_Empty(TermList); TermList = list_Pop(TermList)) {
+ PartnerTerm = (TERM)list_Car(TermList);
+ for (ParentList = term_SupertermList(PartnerTerm);
+ !list_Empty(ParentList); ParentList = list_Cdr(ParentList)) {
+ PartnerEq = (TERM)list_Car(ParentList);
+ if (fol_IsEquality(PartnerEq)) {
+ CLAUSE PartnerClause;
+ LITERAL PartnerLit;
+ LIST Scl;
+ int j;
+ for (Scl = sharing_NAtomDataList(PartnerEq);
+ !list_Empty(Scl); Scl = list_Cdr(Scl)) {
+ PartnerLit = (LITERAL)list_Car(Scl);
+ j = clause_LiteralGetIndex(PartnerLit);
+ PartnerClause = clause_LiteralOwningClause(PartnerLit);
+
+ if (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+ (!MaxPara ||
+ clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+ (!OrdPara ||
+ PartnerTerm == term_FirstArgument(PartnerEq) ||
+ !clause_LiteralIsOrientedEquality(PartnerLit)) &&
+ clause_LiteralIsPositive(PartnerLit) &&
+ clause_Number(PartnerClause) != clause_Number(Clause) &&
+ (!Unit || clause_Length(PartnerClause) == 1) &&
+ clause_HasSolvedConstraint(PartnerClause)) {
+ SYMBOL MaxVar;
+ SUBST Subst, PartnerSubst;
+
+ MaxVar = clause_MaxVar(PartnerClause);
+ clause_RenameVarsBiggerThan(Clause,MaxVar);
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), Term,
+ cont_RightContext(),PartnerTerm);
+ subst_ExtractUnifier(cont_LeftContext(), &Subst,
+ cont_RightContext(),&PartnerSubst);
+ cont_Reset();
+ if (!MaxPara ||
+ inf_LiteralsMax(Clause, i, Subst, PartnerClause, j,
+ PartnerSubst, Flags, Precedence)) {
+ TERM PartnerLeft,PartnerRight;
+ BOOL Check, PartnerCheck;
+ PartnerLeft = PartnerRight = NULL;
+ PartnerCheck = Check = TRUE;
+ if (OrdPara &&
+ !clause_LiteralIsOrientedEquality(PartnerLit)) {
+ /* Check post condition for partner literal */
+ if (PartnerTerm == term_FirstArgument(PartnerEq))
+ PartnerRight = term_SecondArgument(PartnerEq);
+ else
+ PartnerRight = term_FirstArgument(PartnerEq);
+ PartnerLeft = subst_Apply(PartnerSubst,
+ term_Copy(PartnerTerm));
+ PartnerRight = subst_Apply(PartnerSubst,
+ term_Copy(PartnerRight));
+ PartnerCheck = (ord_Compare(PartnerLeft,PartnerRight,
+ Flags, Precedence)
+ != ord_SmallerThan());
+ }
+ if (PartnerCheck &&
+ MaxPara && !clause_LiteralIsOrientedEquality(Lit)) {
+ /* Check post condition for literal in given clause */
+ TERM NewLeft, NewRight;
+ if (Left) {
+ NewLeft = term_FirstArgument(Atom);
+ NewRight = term_SecondArgument(Atom);
+ } else {
+ NewLeft = term_SecondArgument(Atom);
+ NewRight = term_FirstArgument(Atom);
+ }
+ NewLeft = subst_Apply(Subst, term_Copy(NewLeft));
+ NewRight = subst_Apply(Subst, term_Copy(NewRight));
+ Check = (ord_Compare(NewLeft, NewRight, Flags, Precedence)
+ != ord_SmallerThan());
+ term_Delete(NewLeft);
+ term_Delete(NewRight);
+ }
+ if (Check && PartnerCheck) {
+ /* Make inference only if both tests were successful */
+ TERM SupAtom;
+ SupAtom = NULL;
+ if (PartnerRight == NULL) {
+ if (PartnerTerm==term_FirstArgument(PartnerEq))
+ PartnerRight = term_SecondArgument(PartnerEq);
+ else
+ PartnerRight = term_FirstArgument(PartnerEq);
+ PartnerRight = subst_Apply(PartnerSubst,
+ term_Copy(PartnerRight));
+ }
+ if (Left)
+ SupAtom = inf_AllTermsLeftRplac(Atom, Term,
+ PartnerRight, Subst);
+ else
+ SupAtom = inf_AllTermsRightRplac(Atom, Term,
+ PartnerRight, Subst);
+#ifdef CHECK
+ if (SupAtom == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSPLeftEqToGiven:");
+ misc_ErrorReport(" replacement wasn't possible.");
+ misc_FinishErrorReport();
+ }
+#endif
+ Result =
+ list_Cons(inf_ApplyGenSuperposition(PartnerClause, j,
+ PartnerSubst,Clause,
+ i,Subst,SupAtom,
+ FALSE,OrdPara,
+ MaxPara,Flags,
+ Precedence),
+ Result);
+ }
+ if (PartnerLeft != term_Null())
+ term_Delete(PartnerLeft);
+ if (PartnerRight != term_Null())
+ term_Delete(PartnerRight);
+ }
+ subst_Delete(Subst);
+ subst_Delete(PartnerSubst);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Result;
+}
+
+
+static LIST inf_GenSPLeftLitToGiven(CLAUSE Clause, int i, TERM Atom,
+ SHARED_INDEX ShIndex, BOOL OrdPara,
+ BOOL MaxPara, BOOL Unit, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: An unshared clause, the index of an antecedent
+ literal that is not an equality literal and its
+ atom, a shared index, three boolean flags
+ controlling inference preconditions (see also
+ inf_GenSuperpositionLeft), a flag store and a
+ precedence.
+ RETURNS: A list of clauses derivable from superposition left on the
+ GivenCopy wrt. the Index.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result, TermList, ParentList;
+ int Bottom;
+ LITERAL Lit;
+ TERM Term, PartnerTerm, PartnerEq;
+
+ Result = list_Nil();
+ Lit = clause_GetLiteral(Clause,i);
+
+#ifdef CHECK
+ if (clause_LiteralIsEquality(Lit) || !clause_LiteralIsFromAntecedent(Lit)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSPLeftLitToGiven: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Bottom = stack_Bottom();
+ sharing_PushListOnStack(term_ArgumentList(Atom));
+
+ while (!stack_Empty(Bottom)) {
+ Term = (TERM)stack_PopResult();
+ if (!term_IsVariable(Term)) {
+ /* Superposition into variables is not necessary */
+ TermList = st_GetUnifier(cont_LeftContext(),
+ sharing_Index(ShIndex),
+ cont_RightContext(),
+ Term);
+ for ( ; !list_Empty(TermList); TermList=list_Pop(TermList)) {
+ PartnerTerm = (TERM)list_Car(TermList);
+ for (ParentList = term_SupertermList(PartnerTerm);
+ !list_Empty(ParentList); ParentList = list_Cdr(ParentList)) {
+ PartnerEq = (TERM)list_Car(ParentList);
+ if (fol_IsEquality(PartnerEq)) {
+ CLAUSE PartnerClause;
+ LITERAL PartnerLit;
+ TERM PartnerAtom;
+ LIST Scl;
+ int j;
+ for (Scl = sharing_NAtomDataList(PartnerEq);
+ !list_Empty(Scl); Scl = list_Cdr(Scl)) {
+ PartnerLit = (LITERAL)list_Car(Scl);
+ j = clause_LiteralGetIndex(PartnerLit);
+ PartnerClause = clause_LiteralOwningClause(PartnerLit);
+ PartnerAtom = clause_LiteralAtom(PartnerLit);
+ if (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+ (!MaxPara ||
+ clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+ (!OrdPara ||
+ PartnerTerm == term_FirstArgument(PartnerAtom) ||
+ !clause_LiteralIsOrientedEquality(PartnerLit)) &&
+ clause_LiteralIsPositive(PartnerLit) &&
+ clause_Number(PartnerClause) != clause_Number(Clause) &&
+ (!Unit || clause_Length(PartnerClause) == 1) &&
+ clause_HasSolvedConstraint(PartnerClause)) {
+ SYMBOL MaxVar;
+ TERM PartnerLeft,PartnerRight;
+ SUBST Subst, PartnerSubst;
+ TERM SupAtom;
+
+ SupAtom = (TERM)NULL;
+ MaxVar = clause_MaxVar(PartnerClause);
+ clause_RenameVarsBiggerThan(Clause,MaxVar);
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(),Term,cont_RightContext(),PartnerTerm);
+ subst_ExtractUnifier(cont_LeftContext(),&Subst,cont_RightContext(),&PartnerSubst);
+ cont_Reset();
+ if (!MaxPara ||
+ inf_LiteralsMax(Clause, i, Subst, PartnerClause, j,
+ PartnerSubst, Flags, Precedence)) {
+ PartnerLeft = subst_Apply(PartnerSubst,
+ term_Copy(PartnerTerm));
+ if (PartnerTerm == term_FirstArgument(PartnerAtom))
+ PartnerRight = subst_Apply(PartnerSubst,
+ term_Copy(term_SecondArgument(PartnerAtom)));
+ else
+ PartnerRight = subst_Apply(PartnerSubst,
+ term_Copy(term_FirstArgument(PartnerAtom)));
+
+ if (!OrdPara ||
+ clause_LiteralIsOrientedEquality(PartnerLit) ||
+ ord_Compare(PartnerLeft,PartnerRight,Flags, Precedence)
+ != ord_SmallerThan()) {
+ SupAtom = inf_AllTermsRplac(Atom,Term,PartnerRight,Subst);
+#ifdef CHECK
+ if (SupAtom == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSPRightLitToGiven:");
+ misc_ErrorReport(" replacement wasn't possible.");
+ misc_FinishErrorReport();
+ }
+#endif
+ Result =
+ list_Cons(inf_ApplyGenSuperposition(PartnerClause, j,
+ PartnerSubst, Clause,
+ i, Subst, SupAtom,
+ FALSE, OrdPara,
+ MaxPara, Flags,
+ Precedence),
+ Result);
+
+ }
+ term_Delete(PartnerLeft);
+ term_Delete(PartnerRight);
+ }
+ subst_Delete(Subst);
+ subst_Delete(PartnerSubst);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Result;
+}
+
+
+static LIST inf_GenSPLeftToGiven(CLAUSE Clause, int i, SHARED_INDEX ShIndex,
+ BOOL OrdPara, BOOL MaxPara, BOOL Unit,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: An unshared clause, the index of an antecedent
+ literal, an index of shared clauses, three boolean
+ flags for controlling inference preconditions (see
+ inf_GenSuperpositionLeft), a flag store and a
+ precedence.
+ RETURNS: A list of clauses derivable from Superposition Left
+ on the GivenCopy wrt. the Index.
+ MEMORY: A list of clauses is produced, where memory for the
+ list and the clauses is allocated.
+***************************************************************/
+{
+ TERM Atom;
+ LIST Result;
+
+#ifdef CHECK
+ if (clause_GetFlag(Clause, NOPARAINTO) ||
+ (!clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT) &&
+ (clause_GetFlag(Clause, CLAUSESELECT) ||
+ (MaxPara && !clause_LiteralIsMaximal(clause_GetLiteral(Clause,i)))))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSPLeftToGiven: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+ Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+
+ if (fol_IsEquality(Atom)) {
+ Result = list_Nconc(inf_GenSPLeftEqToGiven(Clause,i, TRUE,ShIndex, OrdPara,
+ MaxPara, Unit, Flags,Precedence),
+ Result);
+ if (!MaxPara ||
+ !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)))
+ /* For SPm and OPm always try other direction, for SpR try it */
+ /* only if the literal is not oriented. */
+ Result = list_Nconc(inf_GenSPLeftEqToGiven(Clause,i,FALSE,ShIndex,OrdPara,
+ MaxPara,Unit,Flags,Precedence),
+ Result);
+ } else
+ Result = list_Nconc(inf_GenSPLeftLitToGiven(Clause,i,Atom,ShIndex,OrdPara,
+ MaxPara,Unit,Flags,Precedence),
+ Result);
+
+ return Result;
+}
+
+
+LIST inf_GenSuperpositionLeft(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+ BOOL OrdPara, BOOL MaxPara, BOOL Unit,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause and an Index, usually the WorkedOffIndex,
+ two boolean flags for controlling inference
+ preconditions, a flag store and a precedence.
+ RETURNS: A list of clauses derivable from the Givenclause by
+ one of the following inference rules wrt. the Index:
+
+ OrdPara=TRUE, MaxPara=TRUE
+ -> Superposition Left
+
+ OrdPara=TRUE, MaxPara=FALSE
+ -> ordered Paramodulation
+
+ OrdPara=FALSE, MaxPara=FALSE
+ -> simple Paramodulation
+
+ OrdPara=FALSE, MaxPara=TRUE
+ -> not defined
+
+ If <Unit>==TRUE the clause with the maximal equality
+ additionally must be a unit clause.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result;
+ TERM Atom;
+ CLAUSE Copy;
+ int i, n;
+ LITERAL ActLit;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSuperpositionLeft: Illegal input.");
+ misc_FinishErrorReport();
+ }
+ if (!OrdPara && MaxPara) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GenSuperpositionLeft: Illegal inference rule selection,");
+ misc_ErrorReport("\n OrdPara=FALSE & MaxPara=TRUE.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+
+ if (!clause_HasSolvedConstraint(GivenClause))
+ return Result;
+
+ Copy = clause_Copy(GivenClause);
+ n = clause_LastSuccedentLitIndex(Copy);
+
+ if (!clause_GetFlag(Copy, CLAUSESELECT) &&
+ (!Unit || clause_Length(Copy) == 1)) {
+ for (i = clause_FirstSuccedentLitIndex(Copy); i <= n; i++) {
+ ActLit = clause_GetLiteral(Copy, i);
+ Atom = clause_LiteralSignedAtom(ActLit);
+
+ if (fol_IsEquality(Atom) &&
+ (!MaxPara ||
+ clause_LiteralGetFlag(ActLit,STRICTMAXIMAL))) {
+
+ Result =
+ list_Nconc(inf_GenLitSPLeft(Copy, term_FirstArgument(Atom),
+ term_SecondArgument(Atom), i, ShIndex,
+ OrdPara, MaxPara, Flags, Precedence),
+ Result);
+ if (!OrdPara || !clause_LiteralIsOrientedEquality(ActLit))
+ /* For SPm always try the other direction, for OPm and SpL */
+ /* only try it if the literal is not oriented. */
+ Result =
+ list_Nconc(inf_GenLitSPLeft(Copy, term_SecondArgument(Atom),
+ term_FirstArgument(Atom), i, ShIndex,
+ OrdPara, MaxPara, Flags, Precedence),
+ Result);
+ }
+ }
+ }
+
+ n = clause_LastAntecedentLitIndex(Copy);
+ if (!clause_GetFlag(Copy,NOPARAINTO)) {
+ for (i = clause_FirstAntecedentLitIndex(Copy); i <= n; i++) {
+ ActLit = clause_GetLiteral(Copy, i);
+
+ if (clause_LiteralGetFlag(ActLit, LITSELECT) ||
+ (!clause_GetFlag(Copy, CLAUSESELECT) &&
+ (!MaxPara || clause_LiteralIsMaximal(ActLit))))
+ Result = list_Nconc(inf_GenSPLeftToGiven(Copy, i, ShIndex, OrdPara,
+ MaxPara,Unit,Flags,Precedence),
+ Result);
+ }
+ }
+ clause_Delete(Copy);
+
+ return(Result);
+}
+
+
+
+LIST inf_ApplyDefinition(PROOFSEARCH Search, CLAUSE Clause,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A proof search object, a clause, a flag store and a
+ precedence.
+ RETURNS: A list of clauses derivable from the given clause by
+ applying the (potential) definitions in <Search>.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result, Defs;
+ DEF Def;
+
+ Result = list_Nil();
+ for (Defs=prfs_Definitions(Search); !list_Empty(Defs); Defs=list_Cdr(Defs)) {
+ Def = (DEF)list_Car(Defs);
+ Result = list_Nconc(def_ApplyDefToClauseOnce(Def, Clause, Flags, Precedence),
+ Result);
+ }
+ return Result;
+}
+
+
+/**************************************************************
+ block with hyperresolution code starts here
+***************************************************************/
+
+typedef struct {
+ LITERAL NucleusLit;
+ LITERAL ElectronLit;
+ SUBST ElectronSubst;
+} INF_MAPNODE, *INF_MAPITEM;
+
+
+static void inf_CopyHyperElectron(CLAUSE Clause, SUBST Subst2, SUBST Subst1,
+ int PLitInd, LIST* Constraint,
+ LIST* Succedent)
+/**************************************************************
+ INPUT: An electron clause, a substitution, an index of a
+ succedent literal in this clause (the matched one),
+ and two lists by reference.
+ RETURNS: Nothing.
+ EFFECTS: The constraint and succedent literals are copied into
+ the corresponding lists except for the literal with
+ the given index. The composition <Subst2> ° <Subst1>
+ is applied to all copied literals.
+ The antecedent of the electron clause is empty, so
+ there's no need for a third list by reference.
+***************************************************************/
+{
+ TERM Atom;
+ int n, lc, j;
+
+#ifdef CHECK
+ if (clause_NumOfAnteLits(Clause) != 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_CopyHyperElectron: Electron contains antecedent literals.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ n = clause_LastSuccedentLitIndex(Clause);
+ lc = clause_LastConstraintLitIndex(Clause);
+
+ for (j = clause_FirstConstraintLitIndex(Clause); j <= n; j++) {
+ if (j != PLitInd) {
+ Atom = subst_Apply(Subst1, term_Copy(clause_GetLiteralAtom(Clause, j)));
+ Atom = subst_Apply(Subst2, Atom);
+ if (j <= lc)
+ *Constraint = list_Cons(Atom, *Constraint);
+ else /* Literal must be from succedent */
+ *Succedent = list_Cons(Atom, *Succedent);
+ }
+ }
+}
+
+
+static CLAUSE inf_BuildHyperResolvent(CLAUSE Nucleus, SUBST Subst,
+ LIST FoundMap, BOOL StrictlyMaximal,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause <Nucleus> with solved sort constraint,
+ the substitution <Subst> for <Nucleus>, a mapping
+ <FoundMap> of literals of already found partner
+ clauses, a boolean flag indicating whether this is
+ a ordered or a standard hyper resolution inference
+ a flag store and a precedence.
+ RETURNS: The newly created hyper resolvent.
+***************************************************************/
+{
+ CLAUSE NewClause;
+ LIST Constraint, Succedent, Parents, ParentNum, ParentLits, Scan;
+ int i, bound, Depth;
+ LITERAL Lit;
+ SUBST ESubst;
+ INF_MAPITEM MapItem;
+
+ Parents = list_List(Nucleus); /* parent clauses */
+ ParentNum = list_Nil(); /* parent clause numbers */
+ ParentLits = list_Nil(); /* literal indices */
+ Constraint = Succedent = list_Nil(); /* literals of the new clause */
+
+ /* Get constraint literals from nucleus */
+ bound = clause_LastConstraintLitIndex(Nucleus);
+ for (i = clause_FirstConstraintLitIndex(Nucleus); i <= bound; i++)
+ Constraint =
+ list_Cons(subst_Apply(Subst,term_Copy(clause_GetLiteralAtom(Nucleus,i))),
+ Constraint);
+ /* Get succedent literals from nucleus */
+ bound = clause_LastSuccedentLitIndex(Nucleus);
+ for (i = clause_FirstSuccedentLitIndex(Nucleus); i <= bound; i++)
+ Succedent =
+ list_Cons(subst_Apply(Subst,term_Copy(clause_GetLiteralAtom(Nucleus,i))),
+ Succedent);
+
+ /* Now get the remaining data for the resolvent */
+ Depth = clause_Depth(Nucleus);
+ bound = clause_LastAntecedentLitIndex(Nucleus);
+ for (i = clause_FirstAntecedentLitIndex(Nucleus); i <= bound; i++) {
+ /* Search <FoundMap> for the nucleus literal with index <i> */
+ Lit = clause_GetLiteral(Nucleus, i);
+ for (Scan = FoundMap, MapItem = NULL; !list_Empty(Scan);
+ Scan = list_Cdr(Scan)) {
+ MapItem = list_Car(Scan);
+ if (MapItem->NucleusLit == Lit)
+ break;
+ }
+
+ if (MapItem == NULL || MapItem->NucleusLit != Lit) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_BuildHyperResolvent: Map entry not found.");
+ misc_FinishErrorReport();
+ }
+
+ Lit = MapItem->ElectronLit;
+ NewClause = clause_LiteralOwningClause(Lit);
+ ESubst = MapItem->ElectronSubst;
+
+ Depth = misc_Max(Depth, clause_Depth(NewClause));
+ Parents = list_Cons(NewClause, Parents);
+ ParentNum = list_Cons((POINTER) clause_Number(Nucleus), ParentNum);
+ ParentLits = list_Cons((POINTER) i, ParentLits);
+ ParentNum = list_Cons((POINTER) clause_Number(NewClause), ParentNum);
+ ParentLits = list_Cons((POINTER) clause_LiteralGetIndex(Lit), ParentLits);
+
+ /* Get the remaining constraint and succedent literals from electron */
+ inf_CopyHyperElectron(NewClause,Subst,ESubst,clause_LiteralGetIndex(Lit),
+ &Constraint, &Succedent);
+ }
+
+ /* create new clause and set clause data */
+ NewClause = clause_Create(Constraint, list_Nil(), Succedent, Flags,Precedence);
+
+ if (StrictlyMaximal)
+ clause_SetFromOrderedHyperResolution(NewClause);
+ else
+ clause_SetFromSimpleHyperResolution(NewClause);
+
+ clause_SetDepth(NewClause, Depth + 1);
+
+ clause_SetSplitDataFromList(NewClause, Parents);
+
+ clause_SetParentClauses(NewClause, list_NReverse(ParentNum));
+ clause_SetParentLiterals(NewClause, list_NReverse(ParentLits));
+
+ /* clean up */
+ list_Delete(Parents);
+ list_Delete(Constraint);
+ list_Delete(Succedent);
+
+ return NewClause;
+}
+
+
+static LIST inf_GetHyperResolutionPartnerLits(TERM Atom, SHARED_INDEX Index,
+ BOOL StrictlyMaximal)
+/**************************************************************
+ INPUT: An atom, a clause index, and a boolean flag.
+ RETURNS: A list of literals from purely positive clauses
+ from the index where either <StrictlyMaximal> is
+ false or the literals are strictly maximal in their
+ respective clauses.
+***************************************************************/
+{
+ LIST Result, TermList, LitScan;
+ LITERAL NextLit;
+ CLAUSE Clause;
+
+#ifdef CHECK
+ if (!term_IsAtom(Atom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GetHyperResolutionPartnerLits: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(Index),
+ cont_RightContext(), Atom);
+
+ for (; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+ if (!term_IsVariable(list_Car(TermList))) {
+ for (LitScan = sharing_NAtomDataList(list_Car(TermList));
+ !list_Empty(LitScan);
+ LitScan = list_Cdr(LitScan)) {
+ NextLit = list_Car(LitScan);
+ Clause = clause_LiteralOwningClause(NextLit);
+ if (clause_LiteralIsFromSuccedent(NextLit) &&
+ (!StrictlyMaximal || clause_LiteralGetFlag(NextLit, STRICTMAXIMAL)) &&
+ clause_HasSolvedConstraint(Clause) &&
+ clause_HasEmptyAntecedent(Clause))
+ Result = list_Cons(NextLit, Result);
+ }
+ }
+ }
+ return Result;
+}
+
+static LIST inf_HyperResolvents(CLAUSE Clause, SUBST Subst, LIST Restlits,
+ int GlobalMaxVar, LIST FoundMap,
+ BOOL StrictlyMaximal, SHARED_INDEX Index,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A nucleus <Clause> where the sort constraint is
+ solved,
+ a substitution, that has to be applied to the
+ nucleus,
+ a list <Restlits> of antecedent literals for which
+ a partner clause is searched,
+ a list <FoundMap> of map items (n,e,s), where
+ n is an antecedent literal from the nucleus,
+ e is a positive literal from an electron clause,
+ that is unifiable with n and s is a substitution
+ that has to be applied to the electron clause,
+ a flag store and
+ a precedence.
+ A main invariant of our algorithm is that all involved
+ clauses are pairwise variable disjoint. For that reason
+ we need, when building the resolvent, only apply the electron
+ specific substitution and the composed substitution <Subst>
+ to the electron clauses, and only <Subst> to the nucleus clause.
+ RETURNS: The list of hyper-resolvents.
+***************************************************************/
+{
+ LITERAL Lit, PLit;
+
+ if (list_Empty(Restlits)) {
+ /* This case stops the recursion */
+ LIST Scan;
+ INF_MAPITEM MapItem;
+
+ /* A posteriori test for the electron literals */
+ if (StrictlyMaximal) { /* only for ordered hyper resolution */
+ for (Scan = FoundMap; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ MapItem = list_Car(Scan);
+ Lit = MapItem->ElectronLit;
+ if (!inf_LitMaxWith2Subst(clause_LiteralOwningClause(Lit),
+ clause_LiteralGetIndex(Lit), -1, Subst,
+ MapItem->ElectronSubst,TRUE,Flags,Precedence))
+ return list_Nil();
+ }
+ }
+ /* Build the resolvent */
+ return list_List(inf_BuildHyperResolvent(Clause, Subst, FoundMap,
+ StrictlyMaximal,Flags,Precedence));
+ }
+ else {
+ CLAUSE PartnerCopy;
+ LIST Result, NextLits;
+ TERM AtomCopy;
+ SUBST NewSubst, RightSubst, HelpSubst;
+ SYMBOL NewMaxVar;
+ int PLitInd;
+ BOOL Swapped;
+ INF_MAPNODE MapNode;
+
+ Result = list_Nil();
+ Restlits = clause_MoveBestLiteralToFront(list_Copy(Restlits), Subst,
+ GlobalMaxVar,
+ clause_HyperLiteralIsBetter);
+ Lit = list_Car(Restlits);
+ Restlits = list_Pop(Restlits);
+ AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit)));
+
+ Swapped = FALSE;
+
+ /* The 'endless' loop may run twice for equations, once for other atoms */
+ while (TRUE) {
+ NextLits = inf_GetHyperResolutionPartnerLits(AtomCopy,Index,
+ StrictlyMaximal);
+
+ for ( ; !list_Empty(NextLits); NextLits = list_Pop(NextLits)) {
+
+ PLit = list_Car(NextLits);
+ PLitInd = clause_LiteralGetIndex(PLit);
+ PartnerCopy = clause_Copy(clause_LiteralOwningClause(PLit));
+
+ clause_RenameVarsBiggerThan(PartnerCopy, GlobalMaxVar);
+ PLit = clause_GetLiteral(PartnerCopy, PLitInd);
+
+ NewMaxVar = term_MaxVar(clause_LiteralAtom(PLit));
+ NewMaxVar = symbol_GreaterVariable(GlobalMaxVar, NewMaxVar) ?
+ GlobalMaxVar : NewMaxVar;
+
+ cont_Check();
+ if (!unify_UnifyNoOC(cont_LeftContext(), AtomCopy, cont_RightContext(),
+ clause_LiteralAtom(PLit))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_HyperResolvents: Unification failed.");
+ misc_FinishErrorReport();
+ }
+ subst_ExtractUnifier(cont_LeftContext(), &NewSubst,
+ cont_RightContext(), &RightSubst);
+ cont_Reset();
+
+ HelpSubst = NewSubst;
+ NewSubst = subst_Compose(NewSubst, subst_Copy(Subst));
+ subst_Delete(HelpSubst);
+
+ MapNode.NucleusLit = Lit;
+ MapNode.ElectronLit = PLit;
+ MapNode.ElectronSubst = RightSubst;
+ FoundMap = list_Cons(&MapNode, FoundMap);
+
+ Result = list_Nconc(inf_HyperResolvents(Clause, NewSubst, Restlits,
+ NewMaxVar, FoundMap,
+ StrictlyMaximal, Index, Flags,
+ Precedence),
+ Result);
+
+ subst_Delete(NewSubst);
+ subst_Delete(RightSubst);
+ clause_Delete(PartnerCopy);
+ FoundMap = list_Pop(FoundMap);
+ }
+ if (!Swapped && fol_IsEquality(AtomCopy)) {
+ term_EqualitySwap(AtomCopy);
+ Swapped = TRUE;
+ } else
+ break;
+ } /* end of 'endless' loop */
+
+ list_Delete(Restlits);
+ term_Delete(AtomCopy);
+
+ return Result;
+ }
+}
+
+
+static LIST inf_GetAntecedentLiterals(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause
+ RETURNS: The list of all antecedent literals of the clause.
+***************************************************************/
+{
+ int lc, i;
+ LIST Result;
+
+ Result = list_Nil();
+ lc = clause_LastAntecedentLitIndex(Clause);
+ for (i = clause_FirstAntecedentLitIndex(Clause); i <= lc ; i++) {
+ Result = list_Cons(clause_GetLiteral(Clause, i), Result);
+ }
+ return Result;
+}
+
+
+static LIST inf_ForwardHyperResolution(CLAUSE GivenClause, SHARED_INDEX Index,
+ BOOL StrictlyMaximal, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause with an solved sort constraint, an 'Index'
+ of clauses, a boolean flag, a flag store and a
+ precedence.
+ RETURNS: A list of clauses inferred from <GivenClause> by
+ hyper resolution wrt. the index.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result, RestLits;
+;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_ForwardHyperResolution: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (clause_HasEmptyAntecedent(GivenClause))
+ return list_Nil();
+
+ Result = list_Nil();
+
+ /* Build up list of all antecedent literals. */
+ RestLits = inf_GetAntecedentLiterals(GivenClause);
+
+ Result = list_Nconc(inf_HyperResolvents(GivenClause, subst_Nil(),
+ RestLits,clause_MaxVar(GivenClause),
+ list_Nil(),StrictlyMaximal,Index,
+ Flags, Precedence),
+ Result);
+ list_Delete(RestLits);
+
+ return Result;
+}
+
+
+static LIST inf_BackwardHyperResolution(CLAUSE Electron, SHARED_INDEX Index,
+ BOOL StrictlyMaximal, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause with an solved sort constraint,
+ an 'Index' of clauses, a boolean flag, a flag store,
+ and a precedence.
+ RETURNS: A list of clauses inferred by hyper resolution
+ wrt. the index with <Electron> as an electron.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ CLAUSE ElectronCopy;
+ LIST Result;
+ int i, ls;
+
+ if (!clause_HasEmptyAntecedent(Electron) ||
+ clause_HasEmptySuccedent(Electron))
+ return list_Nil();
+
+ Result = list_Nil();
+
+ ElectronCopy = clause_Copy(Electron);
+
+ /* Search succedent literal in <Electron> */
+ ls = clause_LastSuccedentLitIndex(ElectronCopy);
+ for (i = clause_FirstSuccedentLitIndex(Electron); i <= ls; i++) {
+ LITERAL ElecLit;
+ TERM ElecAtom;
+
+ ElecLit = clause_GetLiteral(ElectronCopy, i);
+ ElecAtom = clause_LiteralAtom(ElecLit);
+
+ if (!StrictlyMaximal || clause_LiteralGetFlag(ElecLit, STRICTMAXIMAL)) {
+ LIST CandAtoms;
+ BOOL Swapped;
+
+ Swapped = FALSE;
+
+ /* The 'endless' loop may run twice for equations, once for other atoms */
+ while (TRUE) {
+ /* Get unifiable antecedent literals in nucleus */
+ CandAtoms = st_GetUnifier(cont_LeftContext(), sharing_Index(Index),
+ cont_RightContext(), ElecAtom);
+
+ for ( ; !list_Empty(CandAtoms); CandAtoms = list_Pop(CandAtoms)) {
+ if (!term_IsVariable(list_Car(CandAtoms))) {
+ LIST CandLits;
+
+ CandLits = sharing_NAtomDataList(list_Car(CandAtoms));
+
+ for (; !list_Empty(CandLits); CandLits = list_Cdr(CandLits)) {
+ LITERAL NucLit;
+ TERM NucAtom;
+ CLAUSE Nucleus;
+
+ NucLit = list_Car(CandLits);
+ NucAtom = clause_LiteralAtom(NucLit);
+ Nucleus = clause_LiteralOwningClause(NucLit);
+
+ if (clause_LiteralIsFromAntecedent(NucLit) &&
+ clause_HasSolvedConstraint(Nucleus)) {
+ LIST FoundMap, RestLits;
+ SUBST LeftSubst, RightSubst;
+ SYMBOL GlobalMaxVar, MaxVar;
+ INF_MAPNODE MapNode;
+
+ GlobalMaxVar = clause_MaxVar(Nucleus);
+ clause_RenameVarsBiggerThan(ElectronCopy, GlobalMaxVar);
+ MaxVar = clause_SearchMaxVar(ElectronCopy);
+ GlobalMaxVar = symbol_GreaterVariable(GlobalMaxVar, MaxVar) ?
+ GlobalMaxVar : MaxVar;
+ /* Now ElecLit is renamed, too */
+
+ RestLits = inf_GetAntecedentLiterals(Nucleus);
+ RestLits = list_PointerDeleteElement(RestLits, NucLit);
+
+ /* Get unifier */
+ cont_Check();
+ if (!unify_UnifyNoOC(cont_LeftContext(), NucAtom,
+ cont_RightContext(), ElecAtom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_BackwardHyperResolution: Unification failed.");
+ misc_FinishErrorReport();
+ }
+ subst_ExtractUnifier(cont_LeftContext(), &LeftSubst,
+ cont_RightContext(), &RightSubst);
+ cont_Reset();
+
+ MapNode.NucleusLit = NucLit;
+ MapNode.ElectronLit = ElecLit;
+ MapNode.ElectronSubst = RightSubst;
+ FoundMap = list_List(&MapNode);
+
+ Result = list_Nconc(inf_HyperResolvents(Nucleus, LeftSubst,
+ RestLits, GlobalMaxVar,
+ FoundMap,StrictlyMaximal,
+ Index, Flags,Precedence),
+ Result);
+
+ /* clean up */
+ subst_Delete(LeftSubst);
+ subst_Delete(RightSubst);
+ list_Delete(RestLits);
+ list_Free(FoundMap);
+ } /* if a nucleus has been found */
+ } /* for all nucleus candidate literals */
+ } /* if term is atom */
+ } /* for all nucleus candidate atoms */
+ if (!Swapped && fol_IsEquality(ElecAtom)) {
+ term_EqualitySwap(ElecAtom); /* Atom is from copied clause */
+ Swapped = TRUE;
+ } else
+ break;
+ } /* end of 'endless' loop */
+ } /* for all lits usable in electron for hyper resolution */
+ } /* for all lits in succedent */
+ clause_Delete(ElectronCopy);
+
+ return Result;
+}
+
+
+LIST inf_GeneralHyperResolution(CLAUSE GivenClause, SHARED_INDEX Index,
+ BOOL Ordered, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, an 'Index' of clauses, a boolean flag,
+ a flag store and a precedence.
+ RETURNS: A list of clauses inferred by
+ (ordered) hyper resolution wrt. the index.
+ If <Ordered>=TRUE then ordered hyper resolution
+ inferences are made, else standard hyper resolution
+ inferences.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result;
+
+ Result = list_Nil();
+ if (clause_HasSolvedConstraint(GivenClause)) {
+ Result = inf_ForwardHyperResolution(GivenClause, Index, Ordered,
+ Flags, Precedence);
+ Result = list_Nconc(inf_BackwardHyperResolution(GivenClause, Index, Ordered,
+ Flags, Precedence),
+ Result);
+ }
+ return Result;
+}
+
+
+LIST inf_DerivableClauses(PROOFSEARCH Search, CLAUSE GivenClause)
+/**************************************************************
+ INPUT: A clause and an Index, usually the WorkedOffIndex.
+ RETURNS: A list of clauses derivable from 'GivenClause' wrt index.
+ EFFECT: Allocates memory for the clauselistnodes and new clauses.
+***************************************************************/
+{
+ LIST ListOfDerivedClauses;
+ SHARED_INDEX ShIndex;
+ SORTTHEORY Dynamic;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_DerivableClauses: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ ListOfDerivedClauses = list_Nil();
+ ShIndex = prfs_WorkedOffSharingIndex(Search);
+ Dynamic = prfs_DynamicSortTheory(Search);
+
+ if (Dynamic && !clause_HasSolvedConstraint(GivenClause)) {
+
+ if (clause_HasTermSortConstraintLits(GivenClause)) {
+ if (flag_GetFlagValue(Flags, flag_ISOR))
+ ListOfDerivedClauses =
+ list_Nconc(inf_ForwardSortResolution(GivenClause,
+ sort_TheoryIndex(Dynamic),
+ Dynamic, FALSE, Flags,Precedence),
+ ListOfDerivedClauses);
+ }
+ else
+ if (flag_GetFlagValue(Flags, flag_IEMS))
+ ListOfDerivedClauses =
+ list_Nconc(inf_ForwardEmptySort(GivenClause,
+ sort_TheoryIndex(Dynamic), Dynamic,
+ FALSE, Flags, Precedence),
+ ListOfDerivedClauses);
+ } else { /* Given with solved Constraint! */
+
+ if (Dynamic && flag_GetFlagValue(Flags, flag_IEMS))
+ ListOfDerivedClauses =
+ list_Nconc(inf_BackwardEmptySort(GivenClause, sharing_Index(ShIndex),
+ Dynamic, FALSE, Flags, Precedence),
+ ListOfDerivedClauses);
+
+ if (Dynamic && flag_GetFlagValue(Flags, flag_ISOR))
+ ListOfDerivedClauses =
+ list_Nconc(inf_BackwardSortResolution(GivenClause,
+ sharing_Index(ShIndex), Dynamic,
+ FALSE, Flags, Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_IEQR))
+ ListOfDerivedClauses =
+ list_Nconc(inf_EqualityResolution(GivenClause, TRUE, Flags, Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_IERR))
+ ListOfDerivedClauses =
+ list_Nconc(inf_EqualityResolution(GivenClause, FALSE, Flags, Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_IMPM))
+ ListOfDerivedClauses =
+ list_Nconc(inf_MergingParamodulation(GivenClause, ShIndex, Flags,
+ Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_IEQF))
+ ListOfDerivedClauses =
+ list_Nconc(inf_EqualityFactoring(GivenClause,Flags, Precedence),
+ ListOfDerivedClauses);
+
+ switch (flag_GetFlagValue(Flags, flag_IOFC)) {
+ case flag_FACTORINGOFF:
+ break; /* Do nothing */
+ case flag_FACTORINGONLYRIGHT:
+ ListOfDerivedClauses =
+ list_Nconc(inf_GeneralFactoring(GivenClause, TRUE, FALSE,TRUE, Flags,
+ Precedence),
+ ListOfDerivedClauses);
+ break;
+ case flag_FACTORINGRIGHTANDLEFT:
+ ListOfDerivedClauses =
+ list_Nconc(inf_GeneralFactoring(GivenClause, TRUE, TRUE, TRUE, Flags,
+ Precedence),
+ ListOfDerivedClauses);
+ break;
+ default:
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Flag \"IOFC\" has invalid value.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ if (flag_GetFlagValue(Flags, flag_ISFC))
+ ListOfDerivedClauses =
+ list_Nconc(inf_GeneralFactoring(GivenClause, FALSE, TRUE, TRUE, Flags,
+ Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_ISPR))
+ ListOfDerivedClauses =
+ list_Nconc(inf_SuperpositionRight(GivenClause,ShIndex,Flags,Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_ISPM))
+ ListOfDerivedClauses =
+ list_Nconc(inf_Paramodulation(GivenClause, ShIndex, Flags, Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_IOPM))
+ ListOfDerivedClauses =
+ list_Nconc(inf_OrderedParamodulation(GivenClause, ShIndex, Flags,
+ Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_ISPL))
+ ListOfDerivedClauses =
+ list_Nconc(inf_SuperpositionLeft(GivenClause, ShIndex, Flags,Precedence),
+ ListOfDerivedClauses);
+
+ switch (flag_GetFlagValue(Flags, flag_IORE)) {
+ case flag_ORDEREDRESOLUTIONOFF:
+ break; /* Do nothing */
+ case flag_ORDEREDRESOLUTIONNOEQUATIONS: /* no equations */
+ ListOfDerivedClauses =
+ list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,TRUE,FALSE,Flags,
+ Precedence),
+ ListOfDerivedClauses);
+ break;
+
+ case flag_ORDEREDRESOLUTIONWITHEQUATIONS: /* allow equations */
+ ListOfDerivedClauses =
+ list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,TRUE,TRUE, Flags,
+ Precedence),
+ ListOfDerivedClauses);
+ break;
+ default:
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Flag \"IORE\" has invalid value.\n");
+ misc_FinishUserErrorReport();
+ }
+
+
+ switch (flag_GetFlagValue(Flags, flag_ISRE)) {
+ case flag_STANDARDRESOLUTIONOFF:
+ break; /* Do nothing */
+ case flag_STANDARDRESOLUTIONNOEQUATIONS: /* no equations */
+ ListOfDerivedClauses =
+ list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,FALSE,FALSE,Flags,
+ Precedence),
+ ListOfDerivedClauses);
+ break;
+ case flag_STANDARDRESOLUTIONWITHEQUATIONS: /* allow equations */
+ ListOfDerivedClauses =
+ list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,FALSE,TRUE,Flags,
+ Precedence),
+ ListOfDerivedClauses);
+ break;
+ default:
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error: Flag \"ISRE\" has invalid value.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ if (flag_GetFlagValue(Flags, flag_IUNR))
+ ListOfDerivedClauses =
+ list_Nconc(inf_UnitResolution(GivenClause, ShIndex, FALSE,
+ Flags, Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_IBUR))
+ ListOfDerivedClauses =
+ list_Nconc(inf_BoundedDepthUnitResolution(GivenClause,ShIndex,FALSE,
+ Flags, Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_ISHY))
+ ListOfDerivedClauses =
+ list_Nconc(inf_GeneralHyperResolution(GivenClause,ShIndex,FALSE,Flags,
+ Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_IOHY))
+ ListOfDerivedClauses =
+ list_Nconc(inf_GeneralHyperResolution(GivenClause,ShIndex,TRUE,Flags,
+ Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_IURR))
+ ListOfDerivedClauses =
+ list_Nconc(inf_URResolution(GivenClause, ShIndex, Flags, Precedence),
+ ListOfDerivedClauses);
+
+ if (flag_GetFlagValue(Flags, flag_IDEF))
+ ListOfDerivedClauses =
+ list_Nconc(inf_ApplyDefinition(Search, GivenClause, Flags, Precedence),
+ ListOfDerivedClauses);
+ }
+
+ return ListOfDerivedClauses;
+}
diff --git a/test/spass/rules-inf.h b/test/spass/rules-inf.h
new file mode 100644
index 0000000..d900bc5
--- /dev/null
+++ b/test/spass/rules-inf.h
@@ -0,0 +1,165 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INFERENCE RULES * */
+/* * * */
+/* * $Module: INFRULES * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _INFRULES_
+#define _INFRULES_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "search.h"
+#include "rules-split.h"
+#include "rules-sort.h"
+#include "rules-ur.h"
+#include "subst.h"
+#include "unify.h"
+#include "st.h"
+#include "defs.h"
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+LIST inf_DerivableClauses(PROOFSEARCH, CLAUSE);
+
+LIST inf_EqualityResolution(CLAUSE, BOOL, FLAGSTORE, PRECEDENCE);
+LIST inf_EqualityFactoring(CLAUSE, FLAGSTORE, PRECEDENCE);
+
+LIST inf_MergingParamodulation(CLAUSE, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+
+LIST inf_GenSuperpositionLeft(CLAUSE,SHARED_INDEX,BOOL,BOOL,BOOL,FLAGSTORE, PRECEDENCE);
+LIST inf_GenSuperpositionRight(CLAUSE,SHARED_INDEX,BOOL,BOOL,BOOL,FLAGSTORE, PRECEDENCE);
+
+LIST inf_BoundedDepthUnitResolution(CLAUSE, SHARED_INDEX, BOOL, FLAGSTORE, PRECEDENCE);
+LIST inf_UnitResolution(CLAUSE, SHARED_INDEX, BOOL, FLAGSTORE, PRECEDENCE);
+LIST inf_GeneralResolution(CLAUSE, SHARED_INDEX, BOOL, BOOL, FLAGSTORE, PRECEDENCE);
+
+BOOL inf_HyperLiteralIsBetter(LITERAL, NAT, LITERAL, NAT);
+LIST inf_GeneralHyperResolution(CLAUSE, SHARED_INDEX, BOOL, FLAGSTORE, PRECEDENCE);
+
+LIST inf_GeneralFactoring(CLAUSE, BOOL, BOOL, BOOL, FLAGSTORE, PRECEDENCE);
+
+LIST inf_ApplyDefinition(PROOFSEARCH, CLAUSE, FLAGSTORE, PRECEDENCE);
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+static __inline__ LIST inf_Paramodulation(CLAUSE GivenClause,
+ SHARED_INDEX ShIndex,
+ FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, an Index, usually the WorkedOffIndex, a
+ flag store and a precedence.
+ RETURNS: A list of clauses derivable from the GivenClause by
+ paramodulation wrt. the Index.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ return list_Nconc(inf_GenSuperpositionLeft(GivenClause, ShIndex, FALSE,
+ FALSE, FALSE, Flags, Precedence),
+ inf_GenSuperpositionRight(GivenClause, ShIndex, FALSE,
+ FALSE, FALSE, Flags, Precedence));
+}
+
+static __inline__ LIST inf_OrderedParamodulation(CLAUSE GivenClause,
+ SHARED_INDEX ShIndex,
+ FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, an Index, usually the WorkedOffIndex, a
+ flag store and a precedence.
+ RETURNS: A list of clauses derivable from the Givenclause by
+ ordered paramodulation wrt. the Index.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ return list_Nconc(inf_GenSuperpositionLeft(GivenClause, ShIndex, TRUE,
+ FALSE, FALSE, Flags, Precedence),
+ inf_GenSuperpositionRight(GivenClause, ShIndex, TRUE,
+ FALSE, FALSE, Flags, Precedence));
+}
+
+static __inline__ LIST inf_SuperpositionLeft(CLAUSE GivenClause,
+ SHARED_INDEX ShIndex,
+ FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, an Index, usually the WorkedOffIndex, a
+ flag store, and a precedence.
+ RETURNS: A list of clauses derivable from the Givenclause by
+ superposition left wrt. the Index.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ return inf_GenSuperpositionLeft(GivenClause,ShIndex,TRUE,TRUE,FALSE,Flags, Precedence);
+}
+
+static __inline__ LIST inf_SuperpositionRight(CLAUSE GivenClause,
+ SHARED_INDEX ShIndex,
+ FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, an Index, usually the WorkedOffIndex, a
+ flag store and a precedence.
+ RETURNS: A list of clauses derivable from the Givenclause by
+ superposition right wrt. the Index.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ return inf_GenSuperpositionRight(GivenClause,ShIndex,TRUE,TRUE,FALSE,Flags, Precedence);
+}
+
+
+#endif
+
diff --git a/test/spass/rules-red.c b/test/spass/rules-red.c
new file mode 100644
index 0000000..609b3cf
--- /dev/null
+++ b/test/spass/rules-red.c
@@ -0,0 +1,4508 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * REDUCTION RULES * */
+/* * * */
+/* * $Module: REDRULES * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "rules-red.h"
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * Globals * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* Needed for term stamping in red_RewriteRedUnitClause */
+static NAT red_STAMPID;
+
+const NAT red_USABLE = 1;
+const NAT red_WORKEDOFF = 2;
+const NAT red_ALL = 3;
+
+
+/**************************************************************/
+/* FUNTION PROTOTYPES */
+/**************************************************************/
+
+static BOOL red_SortSimplification(SORTTHEORY, CLAUSE, NAT, BOOL, FLAGSTORE,
+ PRECEDENCE, CLAUSE*);
+static BOOL red_SelectedStaticReductions(PROOFSEARCH, CLAUSE*, CLAUSE*, LIST*,
+ NAT);
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * Functions * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+
+static void red_HandleRedundantIndexedClauses(PROOFSEARCH Search, LIST Blocked,
+ CLAUSE RedClause)
+/*********************************************************
+ INPUT: A proof search object, a list <Blocked> of clauses from
+ the proof search object and a clause that causes the
+ already indexed clauses in <Blocked> to be redundant.
+ RETURNS: Nothing.
+**********************************************************/
+{
+ FLAGSTORE Flags;
+ CLAUSE Clause;
+ LIST Scan;
+
+ Flags = prfs_Store(Search);
+ for (Scan = Blocked; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ if (prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause),
+ prfs_LastBacktrackLevel(Search)))
+ split_DeleteClauseAtLevel(Search, Clause, clause_SplitLevel(RedClause));
+ else {
+ if (clause_GetFlag(Clause, WORKEDOFF)) {
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ prfs_MoveWorkedOffDocProof(Search, Clause);
+ else
+ prfs_DeleteWorkedOff(Search, Clause);
+ }
+ else
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ prfs_MoveUsableDocProof(Search, Clause);
+ else
+ prfs_DeleteUsable(Search, Clause);
+ }
+ }
+}
+
+static void red_HandleRedundantDerivedClauses(PROOFSEARCH Search, LIST Blocked,
+ CLAUSE RedClause)
+/*********************************************************
+ INPUT: A proof search object, a list <Blocked> of clauses from
+ the proof search object and a clause that causes the
+ derived clauses in <Blocked> to be redundant.
+ RETURNS: Nothing.
+**********************************************************/
+{
+ CLAUSE Clause;
+ LIST Scan;
+
+ for (Scan = Blocked; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ if (prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause),
+ prfs_LastBacktrackLevel(Search))) {
+ split_KeepClauseAtLevel(Search, Clause, clause_SplitLevel(RedClause));
+ }
+ else {
+ if (flag_GetFlagValue(prfs_Store(Search), flag_DOCPROOF))
+ prfs_InsertDocProofClause(Search, Clause);
+ else
+ clause_Delete(Clause);
+ }
+ }
+}
+
+
+void red_Init(void)
+/*********************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECT: Initializes the Reduction module, in particular
+ its stampid to stamp terms.
+**********************************************************/
+{
+ red_STAMPID = term_GetStampID();
+}
+
+
+static void red_DocumentObviousReductions(CLAUSE Clause, LIST Indexes)
+/*********************************************************
+ INPUT: A clause and a list of literal indexes removed by
+ obvious reductions.
+ RETURNS: None
+ MEMORY: The <Indexes> list is consumed.
+**********************************************************/
+{
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+ clause_SetParentClauses(Clause, list_Nil());
+ clause_SetParentLiterals(Clause, Indexes);
+
+ clause_AddParentClause(Clause,clause_Number(Clause)); /* Has to be done before increasing it! */
+
+ clause_SetNumber(Clause, clause_IncreaseCounter());
+ clause_SetFromObviousReductions(Clause);
+}
+
+
+static BOOL red_ObviousReductions(CLAUSE Clause, BOOL Document,
+ FLAGSTORE Flags, PRECEDENCE Precedence,
+ CLAUSE *Changed)
+/**********************************************************
+ INPUT: A clause, a boolean flag for proof
+ documentation, a flag store and a precedence.
+ RETURNS: TRUE iff obvious reductions are possible.
+ If <Document> is false the clause is
+ destructively changed,
+ else a reduced copy of the clause is returned
+ in <*Changed>.
+ EFFECT: Multiple occurrences of the same literal as
+ well as trivial equations are removed.
+********************************************************/
+{
+ int i, j, end;
+ LIST Indexes;
+ TERM Atom, PartnerAtom;
+
+#ifdef CHECK
+ clause_Check(Clause, Flags, Precedence);
+#endif
+
+ Indexes = list_Nil();
+ end = clause_LastAntecedentLitIndex(Clause);
+
+ for (i = clause_FirstConstraintLitIndex(Clause); i <= end; i++) {
+ Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+ if (fol_IsEquality(Atom) &&
+ !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause, i)) &&
+ term_Equal(term_FirstArgument(Atom),term_SecondArgument(Atom))) {
+ Indexes = list_Cons((POINTER)i,Indexes);
+ }
+ else
+ for (j = i+1; j <= end; j++) {
+ PartnerAtom = clause_LiteralAtom(clause_GetLiteral(Clause,j));
+ if (term_Equal(PartnerAtom, Atom) ||
+ (fol_IsEquality(Atom) &&
+ fol_IsEquality(PartnerAtom) &&
+ term_Equal(term_FirstArgument(Atom),term_SecondArgument(PartnerAtom)) &&
+ term_Equal(term_FirstArgument(PartnerAtom),term_SecondArgument(Atom)))) {
+ Indexes = list_Cons((POINTER)i,Indexes);
+ j = end;
+ }
+ }
+ }
+
+ end = clause_LastSuccedentLitIndex(Clause);
+
+ for (i = clause_FirstSuccedentLitIndex(Clause); i <= end; i++) {
+ Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+ for (j = i+1; j <= end; j++) {
+ PartnerAtom = clause_LiteralAtom(clause_GetLiteral(Clause,j));
+ if (term_Equal(PartnerAtom,Atom) ||
+ (fol_IsEquality(Atom) &&
+ fol_IsEquality(PartnerAtom) &&
+ term_Equal(term_FirstArgument(Atom),term_SecondArgument(PartnerAtom)) &&
+ term_Equal(term_FirstArgument(PartnerAtom),term_SecondArgument(Atom)))) {
+ Indexes = list_Cons((POINTER)i,Indexes);
+ j = end;
+ }
+ }
+ }
+
+ if (clause_Length(Clause) == 1 &&
+ clause_NumOfAnteLits(Clause) == 1 &&
+ !list_PointerMember(Indexes,(POINTER)clause_FirstAntecedentLitIndex(Clause)) &&
+ fol_IsEquality(clause_GetLiteralAtom(Clause,clause_FirstAntecedentLitIndex(Clause)))) {
+ cont_StartBinding();
+ if (unify_UnifyCom(cont_LeftContext(),
+ term_FirstArgument(clause_LiteralAtom(clause_GetLiteral(Clause,clause_FirstAntecedentLitIndex(Clause)))),
+ term_SecondArgument(clause_LiteralAtom(clause_GetLiteral(Clause,clause_FirstAntecedentLitIndex(Clause))))))
+ Indexes = list_Cons((POINTER)clause_FirstAntecedentLitIndex(Clause),Indexes);
+ cont_BackTrack();
+ }
+
+ if (!list_Empty(Indexes)) {
+ if (flag_GetFlagValue(Flags, flag_POBV)) {
+ fputs("\nObvious: ", stdout);
+ clause_Print(Clause);
+ fputs(" ==> ", stdout);
+ }
+ if (Document) {
+ CLAUSE Copy;
+ Copy = clause_Copy(Clause);
+ clause_DeleteLiterals(Copy,Indexes, Flags, Precedence);
+ red_DocumentObviousReductions(Copy,Indexes); /* Indexes is consumed */
+ if (flag_GetFlagValue(Flags, flag_POBV))
+ clause_Print(Copy);
+ *Changed = Copy;
+ }
+ else {
+ clause_DeleteLiterals(Clause,Indexes, Flags, Precedence);
+ list_Delete(Indexes);
+ if (flag_GetFlagValue(Flags, flag_POBV))
+ clause_Print(Clause);
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void red_DocumentCondensing(CLAUSE Clause, LIST Indexes)
+/*********************************************************
+ INPUT: A clause and a list of literal indexes removed by condensing.
+ RETURNS: Nothing.
+ MEMORY: The <Indexes> list is consumed.
+**********************************************************/
+{
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+ clause_SetParentClauses(Clause, list_Nil());
+ clause_SetParentLiterals(Clause, Indexes);
+
+ clause_AddParentClause(Clause,clause_Number(Clause)); /* Has to be done before increasing it! */
+
+ clause_SetNumber(Clause, clause_IncreaseCounter());
+ clause_SetFromCondensing(Clause);
+}
+
+static BOOL red_Condensing(CLAUSE Clause, BOOL Document, FLAGSTORE Flags,
+ PRECEDENCE Precedence, CLAUSE *Changed)
+/**********************************************************
+ INPUT: A non-empty unshared clause, a boolean flag
+ concerning proof documentation, a flag store and
+ a precedence.
+ RETURNS: TRUE iff condensing is applicable to <Clause>.
+ If <Document> is false the clause is
+ destructively changed else a condensed copy of
+ the clause is returned in <*Changed>.
+***********************************************************/
+{
+ LIST Indexes;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence) ||
+ (*Changed != (CLAUSE)NULL)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_Condensing : ");
+ misc_ErrorReport("Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(Clause, Flags, Precedence);
+#endif
+
+ Indexes = cond_CondFast(Clause);
+
+ if (!list_Empty(Indexes)) {
+ if (flag_GetFlagValue(Flags, flag_PCON)) {
+ fputs("\nCondensing: ", stdout);
+ clause_Print(Clause);
+ fputs(" ==> ", stdout);
+ }
+ if (Document) {
+ CLAUSE Copy;
+ Copy = clause_Copy(Clause);
+ clause_DeleteLiterals(Copy, Indexes, Flags, Precedence);
+ red_DocumentCondensing(Copy, Indexes);
+ if (flag_GetFlagValue(Flags, flag_PCON))
+ clause_Print(Copy);
+ *Changed = Copy;
+ }
+ else {
+ clause_DeleteLiterals(Clause, Indexes, Flags, Precedence);
+ list_Delete(Indexes);
+ if (flag_GetFlagValue(Flags, flag_PCON))
+ clause_Print(Clause);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static void red_DocumentAssignmentEquationDeletion(CLAUSE Clause, LIST Indexes,
+ NAT NonTrivClauseNumber)
+/*********************************************************
+ INPUT: A clause and a list of literal indexes pointing to
+ redundant equations and the clause number of a clause
+ implying a non-trivial domain.
+ RETURNS: Nothing.
+ MEMORY: The <Indexes> list is consumed.
+**********************************************************/
+{
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+ clause_SetParentClauses(Clause, list_Nil());
+ clause_SetParentLiterals(Clause, Indexes);
+
+ clause_AddParentClause(Clause,clause_Number(Clause)); /* Has to be done before increasing it! */
+
+ clause_SetNumber(Clause, clause_IncreaseCounter());
+ clause_SetFromAssignmentEquationDeletion(Clause);
+
+ if (NonTrivClauseNumber != 0) { /* Such a clause exists */
+ clause_AddParentClause(Clause, NonTrivClauseNumber);
+ clause_AddParentLiteral(Clause, 0); /* The non triv clause has exactly one negative literal */
+ }
+}
+
+
+static BOOL red_AssignmentEquationDeletion(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence, CLAUSE *Changed,
+ NAT NonTrivClauseNumber,
+ BOOL NonTrivDomain)
+/**********************************************************
+ INPUT: A non-empty unshared clause, a flag store, a
+ precedence, the clause number of a clause
+ implying a non-trivial domain and a boolean
+ flag indicating whether the current domain has
+ more than one element.
+ RETURNS: TRUE iff equations are removed.
+ If the <DocProof> flag is false the clause is
+ destructively changed else a copy of the clause
+ where redundant equations are removed is
+ returned in <*Changed>.
+***********************************************************/
+{
+ LIST Indexes; /* List of indexes of redundant equations*/
+ NAT i;
+ TERM LeftArg, RightArg;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence) ||
+ (*Changed != (CLAUSE)NULL) ||
+ (NonTrivDomain && NonTrivClauseNumber == 0) ||
+ (!NonTrivDomain && NonTrivClauseNumber > 0)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_AssignmentEquationDeletion: ");
+ misc_ErrorReport("Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(Clause, Flags, Precedence);
+#endif
+
+ Indexes = list_Nil();
+
+ if (clause_ContainsNegativeEquations(Clause)) {
+ for (i = clause_FirstAntecedentLitIndex(Clause); i <= clause_LastAntecedentLitIndex(Clause); i++) {
+ if (clause_LiteralIsEquality(clause_GetLiteral(Clause,i))) {
+ LeftArg = term_FirstArgument(clause_GetLiteralAtom(Clause,i));
+ RightArg = term_SecondArgument(clause_GetLiteralAtom(Clause,i));
+ if ((term_IsVariable(LeftArg) &&
+ clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(LeftArg)) == 1) ||
+ (term_IsVariable(RightArg) &&
+ clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(RightArg)) == 1))
+ Indexes = list_Cons((POINTER)i, Indexes);
+ }
+ }
+ }
+ else
+ if (NonTrivDomain && clause_ContainsPositiveEquations(Clause)) {
+ for (i = clause_FirstSuccedentLitIndex(Clause); i <= clause_LastSuccedentLitIndex(Clause); i++) {
+ if (clause_LiteralIsEquality(clause_GetLiteral(Clause,i))) {
+ LeftArg = term_FirstArgument(clause_GetLiteralAtom(Clause,i));
+ RightArg = term_SecondArgument(clause_GetLiteralAtom(Clause,i));
+ if ((term_IsVariable(LeftArg) &&
+ clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(LeftArg)) == 1) ||
+ (term_IsVariable(RightArg) &&
+ clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(RightArg)) == 1))
+ Indexes = list_Cons((POINTER)i, Indexes);
+ }
+ }
+ }
+
+ if (!list_Empty(Indexes)) {
+ if (flag_GetFlagValue(Flags, flag_PAED)) {
+ fputs("\nAED: ", stdout);
+ clause_Print(Clause);
+ fputs(" ==> ", stdout);
+ }
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+ CLAUSE Copy;
+ Copy = clause_Copy(Clause);
+ clause_DeleteLiterals(Copy, Indexes, Flags, Precedence);
+ red_DocumentAssignmentEquationDeletion(Copy, Indexes, NonTrivClauseNumber);
+ if (flag_GetFlagValue(Flags, flag_PAED))
+ clause_Print(Copy);
+ *Changed = Copy;
+ }
+ else {
+ clause_DeleteLiterals(Clause, Indexes, Flags, Precedence);
+ list_Delete(Indexes);
+ if (flag_GetFlagValue(Flags, flag_PAED))
+ clause_Print(Clause);
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static BOOL red_Tautology(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**********************************************************
+ INPUT: A non-empty clause, a flag store and a
+ precedence.
+ RETURNS: The boolean value TRUE if 'Clause' is a
+ tautology.
+***********************************************************/
+{
+ TERM Atom;
+ int i,j, la,n;
+ BOOL Result;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_Tautology :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(Clause, Flags, Precedence);
+#endif
+
+ la = clause_LastAntecedentLitIndex(Clause);
+ n = clause_Length(Clause);
+ Result = FALSE;
+
+ for (j = clause_FirstSuccedentLitIndex(Clause); j < n && !Result; j++) {
+
+ Atom = clause_LiteralAtom(clause_GetLiteral(Clause, j));
+
+ if (fol_IsEquality(Atom) &&
+ !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause, j)) &&
+ term_Equal(term_FirstArgument(Atom),term_SecondArgument(Atom)))
+ Result = TRUE;
+
+ for (i = clause_FirstLitIndex(); i <= la && !Result; i++)
+ if (term_Equal(Atom, clause_LiteralAtom(clause_GetLiteral(Clause, i))))
+ Result = TRUE;
+ }
+
+
+ if (!Result &&
+ flag_GetFlagValue(Flags, flag_RTAUT) == flag_RTAUTSEMANTIC &&
+ clause_NumOfAnteLits(Clause) != 0 &&
+ clause_NumOfSuccLits(Clause) != 0) {
+ Result = cc_Tautology(Clause);
+ }
+
+ if (Result && flag_GetFlagValue(Flags, flag_PTAUT)) {
+ fputs("\nTautology: ", stdout);
+ clause_Print(Clause);
+ }
+ return Result;
+}
+
+static LITERAL red_GetMRResLit(LITERAL ActLit, SHARED_INDEX ShIndex)
+/**************************************************************
+ INPUT: A literal and an Index.
+ RETURNS: The most valid clause with a complementary literal,
+ (CLAUSE)NULL, if no such clause exists.
+***************************************************************/
+{
+ LITERAL NextLit;
+ int i;
+ CLAUSE ActClause;
+ TERM CandTerm;
+ LIST LitScan;
+
+ NextLit = (LITERAL)NULL;
+ ActClause = clause_LiteralOwningClause(ActLit);
+ i = clause_LiteralGetIndex(ActLit);
+ CandTerm = st_ExistGen(cont_LeftContext(),
+ sharing_Index(ShIndex),
+ clause_LiteralAtom(ActLit));
+
+ while (CandTerm) { /* First check units */
+ if (!term_IsVariable(CandTerm)) { /* Has to be an Atom! */
+ LitScan = sharing_NAtomDataList(CandTerm); /* CAUTION !!! the List is not a copy */
+ while (!list_Empty(LitScan)) {
+ NextLit = list_Car(LitScan);
+ if (clause_LiteralsAreComplementary(ActLit,NextLit))
+ if (clause_Length(clause_LiteralOwningClause(NextLit)) == 1 ||
+ subs_SubsumesBasic(clause_LiteralOwningClause(NextLit),ActClause,
+ clause_LiteralGetIndex(NextLit),i)) {
+ st_CancelExistRetrieval();
+ return NextLit;
+ }
+ LitScan = list_Cdr(LitScan);
+ }
+ }
+ CandTerm = st_NextCandidate();
+ }
+ return (LITERAL)NULL;
+}
+
+static void red_DocumentMatchingReplacementResolution(CLAUSE Clause, LIST LitInds,
+ LIST ClauseNums, LIST PLitInds)
+/*********************************************************
+ INPUT: A clause, the involved literals indices in <Clause>,
+ the literal indices of the reduction literals
+ and the clauses number.
+ RETURNS: Nothing.
+ MEMORY: All input lists are consumed.
+**********************************************************/
+{
+ LIST Scan,Help;
+
+ Help = list_Nil();
+
+ for (Scan=LitInds; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Help = list_Cons((POINTER)clause_Number(Clause), Help);
+ /* Has to be done before increasing the clause number! */
+ }
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+ clause_SetParentClauses(Clause, list_Nconc(Help,ClauseNums));
+ clause_SetParentLiterals(Clause, list_Nconc(LitInds,PLitInds));
+
+ clause_SetNumber(Clause, clause_IncreaseCounter());
+ clause_SetFromMatchingReplacementResolution(Clause);
+}
+
+static BOOL red_MatchingReplacementResolution(CLAUSE Clause, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence,
+ CLAUSE *Changed, int Level)
+/**************************************************************
+ INPUT: A clause, an Index, a flag store, a precedence and a
+ split level indicating the need of a copy if
+ <Clause> is reduced by a clause of higher split
+ level than <Level>.
+ RETURNS: TRUE if reduction wrt the indexed clauses was
+ possible.
+ If the <DocProof> flag is true or the clauses used
+ for reductions have a higher split level then a
+ changed copy is returned in <*Changed>.
+ Otherwise <Clause> is destructively changed.
+***************************************************************/
+{
+ CLAUSE PClause,Copy;
+ LITERAL ActLit,PLit;
+ int i, j, length;
+ LIST ReducedBy,ReducedLits,PLits,Scan1,Scan2;
+ BOOL Document;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence) ||
+ (*Changed != (CLAUSE)NULL)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_MatchingReplacementResolution:");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(Clause, Flags, Precedence);
+#endif
+
+ Copy = Clause;
+ length = clause_Length(Clause);
+ ReducedBy = list_Nil();
+ ReducedLits = list_Nil();
+ PLits = list_Nil();
+ i = clause_FirstLitIndex();
+ j = 0;
+ Document = flag_GetFlagValue(Flags, flag_DOCPROOF);
+
+ while (i < length) {
+ ActLit = clause_GetLiteral(Copy, i);
+
+ if (!fol_IsEquality(clause_LiteralAtom(ActLit)) || /* Reduce with negative equations. */
+ clause_LiteralIsPositive(ActLit)) {
+ PLit = red_GetMRResLit(ActLit, ShIndex);
+ if (clause_LiteralExists(PLit)) {
+ if (list_Empty(PLits) && flag_GetFlagValue(Flags, flag_PMRR)) {
+ fputs("\nFMatchingReplacementResolution: ", stdout);
+ clause_Print(Copy);
+ }
+ PClause = clause_LiteralOwningClause(PLit);
+ ReducedBy = list_Cons((POINTER)clause_Number(PClause), ReducedBy);
+ PLits = list_Cons((POINTER)clause_LiteralGetIndex(PLit),PLits);
+ ReducedLits = list_Cons((POINTER)(i+j), ReducedLits);
+ if (Copy == Clause &&
+ (Document || prfs_SplitLevelCondition(clause_SplitLevel(PClause),clause_SplitLevel(Copy),Level)))
+ Copy = clause_Copy(Clause);
+ clause_UpdateSplitDataFromPartner(Copy, PClause);
+ clause_DeleteLiteral(Copy,i, Flags, Precedence);
+ length--;
+ j++;
+ }
+ else
+ i++;
+ }
+ else
+ i++;
+ }
+
+ if (!list_Empty(ReducedBy)) {
+ if (Document) {
+ ReducedBy = list_NReverse(ReducedBy);
+ ReducedLits = list_NReverse(ReducedLits);
+ PLits = list_NReverse(PLits);
+ red_DocumentMatchingReplacementResolution(Copy, ReducedLits, ReducedBy, PLits); /* Lists are consumed */
+ if (flag_GetFlagValue(Flags, flag_PMRR)) {
+ fputs(" ==> [ ", stdout);
+ for(Scan1=ReducedBy,Scan2=ReducedLits;!list_Empty(Scan1);
+ Scan1=list_Cdr(Scan1),Scan2=list_Cdr(Scan2))
+ printf("%d.%d ",(NAT)list_Car(Scan1),(NAT)list_Car(Scan2));
+ fputs("] ", stdout);
+ clause_Print(Copy);
+ }
+ }
+ else {
+ if (flag_GetFlagValue(Flags, flag_PMRR)) {
+ fputs(" ==> [ ", stdout);
+ for(Scan1=ReducedBy,Scan2=ReducedLits;!list_Empty(Scan1);
+ Scan1=list_Cdr(Scan1),Scan2=list_Cdr(Scan2))
+ printf("%d.%d ",(NAT)list_Car(Scan1),(NAT)list_Car(Scan2));
+ fputs("] ", stdout);
+ clause_Print(Copy);
+ }
+ list_Delete(ReducedBy);
+ list_Delete(ReducedLits);
+ list_Delete(PLits);
+ }
+ if (Copy != Clause)
+ *Changed = Copy;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void red_DocumentUnitConflict(CLAUSE Clause, LIST LitInds,
+ LIST ClauseNums, LIST PLitInds)
+/*********************************************************
+ INPUT: A clause, the involved literals indices and the clauses number.
+ RETURNS: Nothing.
+ MEMORY: All input lists are consumed.
+**********************************************************/
+{
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+ clause_SetParentClauses(Clause, list_Nconc(list_List((POINTER)clause_Number(Clause)),ClauseNums));
+ clause_SetParentLiterals(Clause, list_Nconc(LitInds,PLitInds));
+
+ clause_SetNumber(Clause, clause_IncreaseCounter());
+ clause_SetFromUnitConflict(Clause);
+}
+
+
+static BOOL red_UnitConflict(CLAUSE Clause, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence,
+ CLAUSE *Changed, int Level)
+/**************************************************************
+ INPUT: A clause, an Index, a flag store and a splitlevel
+ indicating the need of a copy if <Clause> is reduced
+ by a clause of higher split level than <Level>.
+ RETURNS: TRUE if a unit conflict with <Clause> and the
+ clauses in <ShIndex> happened.
+ If the <DocProof> flag is true or the clauses used for
+ reductions have a higher split level then a changed
+ copy is returned in <*Changed>.
+ Otherwise <Clause> is destructively changed.
+***************************************************************/
+{
+ CLAUSE PClause,Copy;
+ LITERAL ActLit,PLit;
+ LIST Scan;
+ TERM CandTerm;
+ BOOL Document;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence) || (*Changed != (CLAUSE)NULL)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_ForwardUnitConflict :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(Clause, Flags, Precedence);
+#endif
+
+ if (clause_Length(Clause) == 1) {
+ Copy = Clause;
+ Document = flag_GetFlagValue(Flags, flag_DOCPROOF);
+ ActLit = clause_GetLiteral(Copy, clause_FirstLitIndex());
+ PLit = (LITERAL)NULL;
+ CandTerm = st_ExistUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(),
+ clause_LiteralAtom(ActLit));
+ while (PLit == (LITERAL)NULL && CandTerm) {
+ if (!term_IsVariable(CandTerm)) {
+ Scan = sharing_NAtomDataList(CandTerm); /* CAUTION !!! the List is not a copy */
+ while (!list_Empty(Scan)) {
+ PLit = list_Car(Scan);
+ if (clause_LiteralsAreComplementary(ActLit,PLit) &&
+ clause_Length(clause_LiteralOwningClause(PLit)) == 1) {
+ st_CancelExistRetrieval();
+ Scan = list_Nil();
+ }
+ else {
+ PLit = (LITERAL)NULL;
+ Scan = list_Cdr(Scan);
+ }
+ }
+ }
+ if (PLit == (LITERAL)NULL)
+ CandTerm = st_NextCandidate();
+ }
+
+ if (PLit == (LITERAL)NULL && fol_IsEquality(clause_LiteralAtom(ActLit))) {
+ TERM Atom;
+ Atom = term_Create(fol_Equality(),list_Reverse(term_ArgumentList(clause_LiteralAtom(ActLit))));
+ CandTerm = st_ExistUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Atom);
+ while (PLit == (LITERAL)NULL && CandTerm) {
+ if (!term_IsVariable(CandTerm)) {
+ Scan = sharing_NAtomDataList(CandTerm); /* CAUTION !!! the List is not a copy */
+ while (!list_Empty(Scan)) {
+ PLit = list_Car(Scan);
+ if (clause_LiteralsAreComplementary(ActLit,PLit) &&
+ clause_Length(clause_LiteralOwningClause(PLit)) == 1) {
+ st_CancelExistRetrieval();
+ Scan = list_Nil();
+ }
+ else {
+ PLit = (LITERAL)NULL;
+ Scan = list_Cdr(Scan);
+ }
+ }
+ }
+ if (PLit == (LITERAL)NULL)
+ CandTerm = st_NextCandidate();
+ }
+ list_Delete(term_ArgumentList(Atom));
+ term_Free(Atom);
+ }
+
+ if (clause_LiteralExists(PLit)) {
+ if (flag_GetFlagValue(Flags, flag_PUNC)) {
+ fputs("\nUnitConflict: ", stdout);
+ clause_Print(Copy);
+ }
+ PClause = clause_LiteralOwningClause(PLit);
+ if (Copy == Clause &&
+ (Document || prfs_SplitLevelCondition(clause_SplitLevel(PClause),clause_SplitLevel(Copy),Level)))
+ Copy = clause_Copy(Clause);
+ clause_UpdateSplitDataFromPartner(Copy, PClause);
+ clause_DeleteLiteral(Copy,clause_FirstLitIndex(), Flags, Precedence);
+ if (Document)
+ red_DocumentUnitConflict(Copy, list_List((POINTER)clause_FirstLitIndex()),
+ list_List((POINTER)clause_Number(PClause)),
+ list_List((POINTER)clause_FirstLitIndex()));
+ if (flag_GetFlagValue(Flags, flag_PUNC)) {
+ printf(" ==> [ %d.%d ]", clause_Number(PClause), clause_FirstLitIndex());
+ clause_Print(Copy);
+ }
+ if (Copy != Clause)
+ *Changed = Copy;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+static CLAUSE red_ForwardSubsumer(CLAUSE RedCl, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**********************************************************
+ INPUT: A pointer to a non-empty clause, an index of
+ clauses, a flag store and a precedence.
+ RETURNS: A clause that subsumes <RedCl>, or NULL if no such
+ clause exists.
+***********************************************************/
+{
+ TERM Atom,AtomGen;
+ CLAUSE CandCl;
+ LITERAL CandLit;
+ LIST LitScan;
+ int i, lc, fa, la, fs, ls;
+
+#ifdef CHECK
+ if (!clause_IsClause(RedCl, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_ForwardSubsumer:");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedCl, Flags, Precedence);
+#endif
+
+ lc = clause_LastConstraintLitIndex(RedCl);
+ fa = clause_FirstAntecedentLitIndex(RedCl);
+ la = clause_LastAntecedentLitIndex(RedCl);
+ fs = clause_FirstSuccedentLitIndex(RedCl);
+ ls = clause_LastSuccedentLitIndex(RedCl);
+
+ for (i = 0; i <= ls; i++) {
+ Atom = clause_GetLiteralAtom(RedCl, i);
+ AtomGen = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), Atom);
+
+ while (AtomGen) {
+ if (!term_IsVariable(AtomGen)) {
+ for (LitScan = sharing_NAtomDataList(AtomGen);
+ !list_Empty(LitScan);
+ LitScan = list_Cdr(LitScan)) {
+ CandLit = list_Car(LitScan);
+ CandCl = clause_LiteralOwningClause(CandLit);
+
+ if (CandCl != RedCl &&
+ clause_GetLiteral(CandCl,clause_FirstLitIndex()) == CandLit &&
+ /* Literals must be from same part of the clause */
+ ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) ||
+ (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) ||
+ (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) &&
+ subs_SubsumesBasic(CandCl, RedCl, clause_FirstLitIndex(), i)) {
+ st_CancelExistRetrieval();
+ return (CandCl);
+ }
+ }
+ }
+ AtomGen = st_NextCandidate();
+ }
+
+ if (fol_IsEquality(Atom) &&
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(RedCl,i))) {
+ Atom = term_Create(fol_Equality(),list_Reverse(term_ArgumentList(Atom)));
+ AtomGen = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), Atom);
+ while (AtomGen) {
+ if (!term_IsVariable(AtomGen)) {
+ for (LitScan = sharing_NAtomDataList(AtomGen);
+ !list_Empty(LitScan);
+ LitScan = list_Cdr(LitScan)) {
+ CandLit = list_Car(LitScan);
+ CandCl = clause_LiteralOwningClause(CandLit);
+ if (CandCl != RedCl &&
+ clause_GetLiteral(CandCl,clause_FirstLitIndex()) == CandLit &&
+ /* Literals must be from same part of the clause */
+ ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) ||
+ (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) ||
+ (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) &&
+ subs_SubsumesBasic(CandCl, RedCl, clause_FirstLitIndex(), i)) {
+ st_CancelExistRetrieval();
+ list_Delete(term_ArgumentList(Atom));
+ term_Free(Atom);
+ return (CandCl);
+ }
+ }
+ }
+ AtomGen = st_NextCandidate();
+ }
+ list_Delete(term_ArgumentList(Atom));
+ term_Free(Atom);
+ }
+ }
+
+ return((CLAUSE)NULL);
+}
+
+
+static CLAUSE red_ForwardSubsumption(CLAUSE RedClause, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**********************************************************
+ INPUT: A clause, an index of clauses, a flag store and
+ a precedence.
+ RETURNS: The clause <RedClause> is subsumed by in <ShIndex>.
+***********************************************************/
+{
+ CLAUSE Subsumer;
+
+#ifdef CHECK
+ if (!clause_IsClause(RedClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_ForwardSubsumption:");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ Subsumer = red_ForwardSubsumer(RedClause, ShIndex, Flags, Precedence);
+
+ if (flag_GetFlagValue(Flags, flag_PSUB) && Subsumer) {
+ fputs("\nFSubsumption: ", stdout);
+ clause_Print(RedClause);
+ printf(" by %d %d ",clause_Number(Subsumer),clause_SplitLevel(Subsumer));
+ }
+
+ return Subsumer;
+}
+
+
+static void red_DocumentRewriting(CLAUSE Clause, int i, CLAUSE Rule, int ri)
+/*********************************************************
+ INPUT: Two clauses and the literal indices involved in the rewrite step.
+ RETURNS: Nothing.
+ EFFECT: Documentation in <Clause> is set.
+**********************************************************/
+{
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+ clause_SetParentClauses(Clause,
+ list_List((POINTER)clause_Number(Clause)));
+ /* Has to be done before increasing the number! */
+
+ clause_SetParentLiterals(Clause, list_List((POINTER)i));
+ clause_NewNumber(Clause);
+ clause_SetFromRewriting(Clause);
+
+ clause_AddParentClause(Clause,clause_Number(Rule));
+ clause_AddParentLiteral(Clause,ri);
+}
+
+
+static void red_DocumentFurtherRewriting(CLAUSE Clause, int i, CLAUSE Rule, int ri)
+/*********************************************************
+ INPUT: Two clauses and the literal indices involved in the rewrite step.
+ RETURNS: Nothing.
+ EFFECT: Documentation in <Clause> is set.
+**********************************************************/
+{
+ clause_AddParentClause(Clause,
+ (int) list_Car(list_Cdr(clause_ParentClauses(Clause))));
+ clause_AddParentLiteral(Clause, i);
+ clause_AddParentClause(Clause, clause_Number(Rule));
+ clause_AddParentLiteral(Clause, ri);
+}
+
+
+static BOOL red_RewriteRedUnitClause(CLAUSE RedClause, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence,
+ CLAUSE *Changed, int Level)
+/**************************************************************
+ INPUT: A unit (!) clause, an Index, a flag store, a
+ precedence and a split level indicating the need of
+ a copy if <Clause> is reduced by a clause of higher
+ split level than <Level>.
+ RETURNS: TRUE iff rewriting was possible.
+ If the <DocProof> flag is true or the split level of
+ the rewrite rule is higher a copy of RedClause that
+ is rewritten wrt. the indexed clauses is returned in
+ <*Changed>.
+ Otherwise the clause is destructively rewritten.
+***************************************************************/
+{
+ TERM RedAtom, RedTermS;
+ int B_Stack;
+ BOOL Rewritten, Result, Oriented, Renamed, Document;
+ TERM TermS,PartnerEq;
+ LIST EqList,EqScan,LitScan;
+ CLAUSE Copy;
+
+#ifdef CHECK
+ if (!clause_IsClause(RedClause, Flags, Precedence) ||
+ *Changed != (CLAUSE)NULL ||
+ clause_Length(RedClause) != 1) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_RewriteRedUnitClause :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ Result = FALSE;
+ Renamed = FALSE;
+ Copy = RedClause;
+ RedAtom = clause_GetLiteralAtom(Copy, clause_FirstLitIndex());
+ Rewritten = TRUE;
+ Document = flag_GetFlagValue(Flags, flag_DOCPROOF);
+
+ /* Don't apply this rule on constraint or propositional literals */
+ if (clause_FirstLitIndex() <= clause_LastConstraintLitIndex(RedClause) ||
+ list_Empty(term_ArgumentList(RedAtom)))
+ return Result;
+
+ if (term_StampOverflow(red_STAMPID))
+ term_ResetTermStamp(clause_LiteralSignedAtom(clause_GetLiteral(RedClause, clause_FirstLitIndex())));
+ term_StartStamp();
+
+ while (Rewritten) {
+ Rewritten = FALSE;
+ B_Stack = stack_Bottom();
+ sharing_PushListOnStackNoStamps(term_ArgumentList(RedAtom));
+
+ while (!stack_Empty(B_Stack)) {
+ RedTermS = (TERM)stack_PopResult();
+ TermS = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), RedTermS);
+ while (TermS && !Rewritten) {
+ EqList = term_SupertermList(TermS);
+ for (EqScan = EqList; !list_Empty(EqScan) && !Rewritten;
+ EqScan = list_Cdr(EqScan)) {
+ PartnerEq = list_Car(EqScan);
+ if (fol_IsEquality(PartnerEq)) {
+ CLAUSE RewriteClause;
+ LITERAL RewriteLit;
+ TERM Right;
+
+ if (TermS == term_FirstArgument(PartnerEq))
+ Right = term_SecondArgument(PartnerEq);
+ else
+ Right = term_FirstArgument(PartnerEq);
+
+ for (LitScan = sharing_NAtomDataList(PartnerEq);
+ !list_Empty(LitScan) && !Rewritten;
+ LitScan = list_Cdr(LitScan)) {
+ RewriteLit = list_Car(LitScan);
+ RewriteClause = clause_LiteralOwningClause(RewriteLit);
+ if (clause_LiteralIsPositive(RewriteLit) &&
+ clause_Length(RewriteClause) == 1) {
+ Oriented = (clause_LiteralIsOrientedEquality(RewriteLit) &&
+ TermS == term_FirstArgument(PartnerEq));
+ if (!Oriented && !clause_LiteralIsOrientedEquality(RewriteLit)) {
+ Renamed = TRUE; /* If oriented, no renaming needed! */
+ term_StartMaxRenaming(clause_MaxVar(RewriteClause));
+ term_Rename(RedAtom); /* Renaming destructive, no extra match needed !! */
+ Oriented = ord_ContGreater(cont_LeftContext(), TermS,
+ cont_LeftContext(), Right,
+ Flags, Precedence);
+
+ /*if (Oriented) {
+ fputs("\n\n\tRedAtom: ",stdout);term_PrintPrefix(RedAtom);
+ fputs("\n\tSubTerm: ",stdout);term_PrintPrefix(RedTermS);
+ fputs("\n\tGenTerm: ",stdout);term_PrintPrefix(TermS);
+ fputs("\n\tGenRight: ",stdout);term_PrintPrefix(Right);
+ putchar('\n');cont_PrintCurrentTrail();putchar('\n');
+ }*/
+ }
+ if (Oriented) {
+ TERM TermT;
+
+ if (RedClause == Copy &&
+ (Document ||
+ prfs_SplitLevelCondition(clause_SplitLevel(RewriteClause),
+ clause_SplitLevel(RedClause),Level))) {
+ Copy = clause_Copy(RedClause);
+ RedAtom = clause_GetLiteralAtom(Copy, clause_FirstLitIndex());
+ }
+
+ if (!Result)
+ if (flag_GetFlagValue(Flags, flag_PREW)) {
+ fputs("\nFRewriting: ", stdout);
+ clause_Print(Copy);
+ fputs(" ==>[ ", stdout);
+ }
+
+ if (Document) {
+ if (!Result)
+ red_DocumentRewriting(Copy, clause_FirstLitIndex(),
+ RewriteClause, clause_FirstLitIndex());
+ else
+ red_DocumentFurtherRewriting(Copy, clause_FirstLitIndex(),
+ RewriteClause, clause_FirstLitIndex());
+ }
+ Result = TRUE;
+ TermT = cont_ApplyBindingsModuloMatching(cont_LeftContext(), term_Copy(Right), TRUE);
+ if (cont_BindingsAreRenamingModuloMatching(cont_RightContext()))
+ term_SetTermSubtermStamp(TermT);
+ term_ReplaceSubtermBy(RedAtom, RedTermS, TermT);
+ Rewritten = TRUE;
+ clause_UpdateSplitDataFromPartner(Copy, RewriteClause);
+ term_Delete(TermT);
+ stack_SetBottom(B_Stack);
+
+ if (flag_GetFlagValue(Flags, flag_PREW))
+ printf("%d.%d ",clause_Number(RewriteClause), clause_FirstLitIndex());
+ clause_UpdateWeight(Copy, Flags);
+ }
+ }
+ }
+ }
+ }
+ if (!Rewritten)
+ TermS = st_NextCandidate();
+ }
+ st_CancelExistRetrieval();
+ if (!Rewritten)
+ term_SetTermStamp(RedTermS);
+ }
+ }
+ term_StopStamp();
+
+ if (Result) {
+ clause_OrientAndReInit(Copy, Flags, Precedence);
+ if (Copy != RedClause)
+ clause_OrientAndReInit(RedClause, Flags, Precedence);
+ if (flag_GetFlagValue(Flags, flag_PREW)) {
+ fputs("] ", stdout);
+ clause_Print(Copy);
+ }
+ if (Copy != RedClause)
+ *Changed = Copy;
+ }
+ else
+ if (Renamed)
+ clause_OrientAndReInit(Copy, Flags, Precedence);
+
+
+#ifdef CHECK
+ clause_Check(Copy, Flags, Precedence);
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ return Result;
+}
+
+
+static BOOL red_RewriteRedClause(CLAUSE RedClause, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence,
+ CLAUSE *Changed, int Level)
+/**************************************************************
+ INPUT: A clause, an Index, a flag store, a precedence and
+ a split level indicating the need of a copy if
+ <Clause> is reduced by a clause of higher split
+ level than <Level>.
+ RETURNS: NULL, if no rewriting was possible.
+ If the <DocProof> flag is true or the split level of
+ the rewrite rule is higher a copy of RedClause
+ that is rewritten wrt. the indexed clauses.
+ Otherwise the clause is destructively rewritten and
+ returned.
+***************************************************************/
+{
+ TERM RedAtom, RedTermS;
+ int B_Stack;
+ int ci, length;
+ BOOL Rewritten, Result, Document;
+ TERM TermS,PartnerEq;
+ LIST EqScan,LitScan;
+ CLAUSE Copy;
+
+#ifdef CHECK
+ if (!clause_IsClause(RedClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_RewriteRedClause :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ length = clause_Length(RedClause);
+ Document = flag_GetFlagValue(Flags, flag_DOCPROOF);
+
+ if (length == 1)
+ return red_RewriteRedUnitClause(RedClause, ShIndex, Flags, Precedence,
+ Changed, Level);
+
+ Result = FALSE;
+ Copy = RedClause;
+
+ /* Don't apply this rule on constraint literals! */
+ for (ci = clause_FirstAntecedentLitIndex(RedClause); ci < length; ci++) {
+ Rewritten = TRUE;
+ if (!list_Empty(term_ArgumentList(clause_GetLiteralAtom(Copy, ci)))) {
+ while (Rewritten) {
+ Rewritten = FALSE;
+ RedAtom = clause_GetLiteralAtom(Copy, ci);
+
+ B_Stack = stack_Bottom();
+ /* push subterms on stack except variables */
+ sharing_PushListReverseOnStack(term_ArgumentList(RedAtom));
+
+ while (!stack_Empty(B_Stack)) {
+ RedTermS = (TERM)stack_PopResult();
+ TermS = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), RedTermS);
+
+ while (TermS && !Rewritten) {
+ /* A variable can't be greater than any other term, */
+ /* so don't consider any variables here */
+ if (!term_IsVariable(TermS)) {
+ EqScan = term_SupertermList(TermS);
+
+ for ( ; !list_Empty(EqScan) && !Rewritten;
+ EqScan = list_Cdr(EqScan)) {
+ PartnerEq = list_Car(EqScan);
+ if (fol_IsEquality(PartnerEq) &&
+ (term_FirstArgument(PartnerEq) == TermS)) {
+ CLAUSE RewriteClause;
+ LITERAL RewriteLit;
+ int ri;
+
+ for (LitScan = sharing_NAtomDataList(PartnerEq);
+ !list_Empty(LitScan) && !Rewritten;
+ LitScan = list_Cdr(LitScan)) {
+ RewriteLit = list_Car(LitScan);
+ RewriteClause = clause_LiteralOwningClause(RewriteLit);
+ ri = clause_LiteralGetIndex(RewriteLit);
+
+ if (clause_LiteralIsPositive(RewriteLit) &&
+ clause_LiteralIsOrientedEquality(RewriteLit) &&
+ subs_SubsumesBasic(RewriteClause, Copy, ri, ci)) {
+ TERM TermT;
+
+ if (RedClause == Copy &&
+ (Document ||
+ prfs_SplitLevelCondition(clause_SplitLevel(RewriteClause),
+ clause_SplitLevel(RedClause),Level))) {
+ Copy = clause_Copy(RedClause);
+ RedAtom = clause_GetLiteralAtom(Copy, ci);
+ }
+
+ if (!Result) {
+ if (flag_GetFlagValue(Flags, flag_PREW)) {
+ fputs("\nFRewriting: ", stdout);
+ clause_Print(Copy);
+ fputs(" ==>[ ", stdout);
+ }
+ }
+
+ if (Document) {
+ if (!Result)
+ red_DocumentRewriting(Copy, ci, RewriteClause, ri);
+ else
+ red_DocumentFurtherRewriting(Copy,ci,RewriteClause,ri);
+ }
+ Result = TRUE;
+ /* Since <TermS> is the bigger term of an oriented */
+ /* equation and all variables in <TermS> are bound, */
+ /* all variables in the smaller term are bound, too. */
+ /* So the strict version of cont_Apply... will work. */
+ TermT = cont_ApplyBindingsModuloMatching(cont_LeftContext(),
+ term_Copy(term_SecondArgument(PartnerEq)),
+ TRUE);
+
+ /* No variable renaming is necessary before creation */
+ /* of bindings and replacement of subterms because all */
+ /* variables of <TermT> are from <RedClause>/<Copy>. */
+ term_ReplaceSubtermBy(RedAtom, RedTermS, TermT);
+ Rewritten = TRUE;
+ clause_UpdateSplitDataFromPartner(Copy,RewriteClause);
+ term_Delete(TermT);
+ stack_SetBottom(B_Stack);
+
+ if (flag_GetFlagValue(Flags, flag_PREW))
+ printf("%d.%d ",clause_Number(RewriteClause), ri);
+ clause_UpdateWeight(Copy, Flags);
+ }
+ }
+ }
+ }
+ }
+ if (!Rewritten)
+ TermS = st_NextCandidate();
+ }
+ st_CancelExistRetrieval();
+ }
+ }
+ }
+ }
+ if (Result) {
+ clause_OrientAndReInit(Copy, Flags, Precedence);
+ if (flag_GetFlagValue(Flags, flag_PREW)) {
+ fputs("] ", stdout);
+ clause_Print(Copy);
+ }
+ if (Copy != RedClause) {
+ clause_OrientAndReInit(RedClause, Flags, Precedence);
+ *Changed = Copy;
+ }
+ }
+
+#ifdef CHECK
+ clause_Check(Copy, Flags, Precedence);
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ return Result;
+}
+
+
+/**************************************************************/
+/* FORWARD CONTEXTUAL REWRITING */
+/**************************************************************/
+
+static BOOL red_LeftTermOfEquationIsStrictlyMaximalTerm(CLAUSE Clause,
+ LITERAL Equation,
+ FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a literal of the clause, that is an
+ oriented equation, a flag store and a precedence.
+ RETURNS: TRUE, iff the bigger (i.e. left) term of the equation
+ is the strictly maximal term of the clause.
+ A term s is strictly maximal in a clause, iff for every atom
+ u=v (A=tt) of the clause s > u and s > v (s > A).
+***************************************************************/
+{
+ int i, except, last;
+ TERM LeftTerm, Atom;
+ LITERAL ActLit;
+
+#ifdef CHECK
+ if (!clause_LiteralIsOrientedEquality(Equation)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_LeftTermOfEquationIsStrictlyMaximalTerm: ");
+ misc_ErrorReport("literal is not oriented");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ LeftTerm = term_FirstArgument(clause_LiteralSignedAtom(Equation));
+ except = clause_LiteralGetIndex(Equation);
+
+ /* Compare <LeftTerm> with all terms in the clause */
+ last = clause_LastLitIndex(Clause);
+ for (i = clause_FirstLitIndex() ; i <= last; i++) {
+ if (i != except) {
+ ActLit = clause_GetLiteral(Clause, i);
+ Atom = clause_LiteralAtom(ActLit);
+ if (fol_IsEquality(Atom)) {
+ /* Atom is an equation */
+ if (ord_Compare(LeftTerm, term_FirstArgument(Atom), Flags, Precedence)
+ != ord_GREATER_THAN ||
+ (!clause_LiteralIsOrientedEquality(ActLit) &&
+ ord_Compare(LeftTerm, term_SecondArgument(Atom), Flags, Precedence)
+ != ord_GREATER_THAN))
+ /* Compare only with left (i.e. greater) subterm if the atom is */
+ /* an oriented equation. */
+ return FALSE;
+ } else {
+ /* Atom is not an equation */
+ if (ord_Compare(LeftTerm, Atom, Flags, Precedence) != ord_GREATER_THAN)
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+
+static void red_CRwCalculateAdditionalParents(CLAUSE Reduced,
+ LIST RedundantClauses,
+ CLAUSE Subsumer,
+ int OriginalClauseNumber)
+/**************************************************************
+ INPUT: A clause that was just reduced by forward reduction,
+ a list of intermediate clauses that were derived from
+ the original clause, a clause that subsumes <Reduced>
+ (NULL, if <Reduced> is not subsumed), and the clause
+ number of <Reduced> before it was reduced.
+ RETURNS: Nothing.
+ EFFECT: This function collects the information about parent
+ clauses and parent literals that is necessary for
+ proof documentation for Contextual Rewriting
+ and sets the parent information of <Reduced> accordingly.
+ The clause <Reduced> was derived in several steps
+ C1 -> C2 -> ... Cn -> <Reduced> from some clause C1.
+ <RedundantClauses> contains all those clauses C1, ..., Cn.
+ This function first collects the parent information from
+ the clauses C1, C2, ..., Cn, <Reduced>. All those clauses
+ were needed to derive <Reduced>, but for proof documentation
+ of the rewriting step we have to delete the numbers of
+ all clauses C1,...,Cn,Reduced.
+
+ As a simplification this function doesn't set the
+ correct parent literals. It simply assumes that every
+ reduction step was done by literal 0.
+ This isn't a problem since only the correct parent
+ clause numbers are really needed for proof documentation.
+***************************************************************/
+{
+ LIST Parents, Scan;
+ int ActNum;
+
+ /* First collect all parent clause numbers from the redundant clauses. */
+ /* Also add number of <Subsumer> if it exists. */
+ Parents = clause_ParentClauses(Reduced);
+ clause_SetParentClauses(Reduced, list_Nil());
+ for (Scan = RedundantClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ Parents = list_Append(clause_ParentClauses(list_Car(Scan)), Parents);
+ if (Subsumer != NULL)
+ Parents = list_Cons((POINTER)clause_Number(Subsumer), Parents);
+
+ /* Now delete <OriginalClauseNumber> and the numbers of all clauses */
+ /* that were derived from it. */
+ Parents = list_PointerDeleteElement(Parents, (POINTER) OriginalClauseNumber);
+ for (Scan = RedundantClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ ActNum = clause_Number(list_Car(Scan));
+ Parents = list_PointerDeleteElement(Parents, (POINTER) ActNum);
+ }
+
+ /* Finally set data of result clause <Reduced>. */
+ Parents = list_PointerDeleteDuplicates(Parents);
+ clause_SetParentClauses(Reduced, Parents);
+ /* Build list of literal numbers: in this simple version we just build */
+ /* a list with the same length as the parent clauses containing only the */
+ /* literal indices 0. */
+ Parents = list_Copy(Parents);
+ for (Scan = Parents; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ list_Rplaca(Scan, (POINTER)0);
+ list_Delete(clause_ParentLiterals(Reduced));
+ clause_SetParentLiterals(Reduced, Parents);
+}
+
+
+static BOOL red_LiteralIsDefinition(LITERAL Literal)
+/**************************************************************
+ INPUT: A literal.
+ RETURNS: TRUE, iff the literal is a definition, i.e. an equation x=t,
+ where x is a variable and x doesn't occur in t.
+ The function needs time O(1), it is independent of the size
+ of the literal.
+ CAUTION: The orientation of the literal must be correct.
+***************************************************************/
+{
+ TERM Atom;
+
+ Atom = clause_LiteralAtom(Literal);
+ if (fol_IsEquality(Atom) &&
+ !clause_LiteralIsOrientedEquality(Literal) &&
+ (term_IsVariable(term_FirstArgument(Atom)) ||
+ term_IsVariable(term_SecondArgument(Atom))) &&
+ !term_VariableEqual(term_FirstArgument(Atom),
+ term_SecondArgument(Atom)))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+static BOOL red_PropagateDefinitions(CLAUSE Clause, TERM LeadingTerm,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a term, a flag store and a precedence.
+ RETURNS: TRUE, iff any definitions in <Clause> where propagated,
+ false otherwise.
+
+ Here, a definitions means a negative literal x=t, where
+ x is a variable and x doesn't occur in t.
+ Definitions are only propagated if all terms in the
+ resulting clause would be smaller than <LeadingTerm>.
+ The flag store and the precedence are only needed for
+ term comparisons with respect to the reduction ordering.
+ CAUTION: <Clause> is changed destructively!
+***************************************************************/
+{
+ LITERAL Lit;
+ TERM Term, Atom;
+ SYMBOL Var;
+ int i, last, j, lj;
+ BOOL success, applied;
+ LIST litsToRemove;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_PropagateDefinitions: clause is corrupted.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ applied = FALSE;
+ litsToRemove = list_Nil(); /* collect indices of redundant literals */
+ last = clause_LastAntecedentLitIndex(Clause);
+
+ for (i = clause_FirstAntecedentLitIndex(Clause); i <= last; i++) {
+ Lit = clause_GetLiteral(Clause, i);
+
+ if (red_LiteralIsDefinition(Lit)) {
+ /* <Lit> is an equation x=t where the variable x doesn't occur in t. */
+
+ Term = term_FirstArgument(clause_LiteralAtom(Lit));
+ if (term_IsVariable(Term)) {
+ Var = term_TopSymbol(Term);
+ Term = term_SecondArgument(clause_LiteralAtom(Lit));
+ } else {
+ Var = term_TopSymbol(term_SecondArgument(clause_LiteralAtom(Lit)));
+ }
+
+ /* Establish variable binding x -> t in context */
+#ifdef CHECK
+ cont_SaveState();
+#endif
+ cont_StartBinding();
+ cont_CreateBinding(cont_LeftContext(), Var, cont_InstanceContext(), Term);
+
+ /* Check that for each literal u=v (A=tt) the conditions */
+ /* u{x->t} < LeadingTerm and v{x->t} < LeadingTerm (A < LeadingTerm) */
+ /* hold. */
+ success = TRUE;
+ Lit = NULL;
+ lj = clause_LastLitIndex(Clause);
+
+ for (j = clause_FirstLitIndex(); j <= lj && success; j++) {
+ if (j != i) {
+ success = FALSE;
+ Lit = clause_GetLiteral(Clause, j);
+ Atom = clause_LiteralAtom(Lit);
+ if (fol_IsEquality(Atom)) {
+ /* Atom is an equation */
+ if (ord_ContGreater(cont_InstanceContext(), LeadingTerm,
+ cont_LeftContext(), term_FirstArgument(Atom),
+ Flags, Precedence) &&
+ (clause_LiteralIsOrientedEquality(Lit) ||
+ ord_ContGreater(cont_InstanceContext(), LeadingTerm,
+ cont_LeftContext(), term_SecondArgument(Atom),
+ Flags, Precedence)))
+ /* Compare only with left (i.e. greater) subterm if the atom is */
+ /* an oriented equation. */
+ success = TRUE;
+ } else {
+ /* Atom is not an equation */
+ if (ord_ContGreater(cont_InstanceContext(), LeadingTerm,
+ cont_LeftContext(), Atom, Flags, Precedence))
+ success = TRUE;
+ }
+ }
+ }
+
+ cont_BackTrack();
+
+#ifdef CHECK
+ cont_CheckState();
+#endif
+
+ if (success) {
+ /* Replace variable <Var> in <Clause> by <Term> */
+ clause_ReplaceVariable(Clause, Var, Term);
+ /* The clause literals aren't reoriented here. For the detection of */
+ /* definitions it suffices to know the non-oriented literals in the */
+ /* original clause. */
+ litsToRemove = list_Cons((POINTER)i, litsToRemove);
+ applied = TRUE;
+ }
+ }
+ }
+
+ if (applied) {
+ /* Now remove the definition literals. */
+ clause_DeleteLiterals(Clause, litsToRemove, Flags, Precedence);
+ list_Delete(litsToRemove);
+
+ /* Equations have to be reoriented. */
+ clause_OrientEqualities(Clause, Flags, Precedence);
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_PropagateDefinitions: clause is corrupted ");
+ misc_ErrorReport("after propagation of definitions");
+ misc_FinishErrorReport();
+ }
+#endif
+ }
+
+ return applied;
+}
+
+
+static CLAUSE red_CRwLitTautologyCheck(PROOFSEARCH Search, CLAUSE RedClause,
+ int Except, CLAUSE RuleClause, int i,
+ TERM LeadingTerm, NAT Mode)
+/**************************************************************
+ INPUT: A proof search object, two clauses, two literal indices
+ (one per clause), a mode defining the clause index used
+ for intermediate reductions.
+ RETURNS: NULL, if the tautology check for literal <i> in <RuleClause>
+ failed.
+
+ If the test succeeds an auxiliary clause is returned that
+ contains part of the splitting information for the current
+ rewriting step. If the 'DocProof' flag is set, the necessary
+ parent information is set, too.
+ MEMORY: Remember to delete the returned clause!
+***************************************************************/
+{
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+ CLAUSE aux, NewClause;
+ LITERAL Lit;
+ TERM Atom;
+ BOOL DocProof, Negative, Redundant;
+ LIST NegLits, PosLits, RedundantList;
+ int OrigNum;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+ DocProof = flag_GetFlagValue(Flags, flag_DOCPROOF);
+
+ Lit = clause_GetLiteral(RuleClause, i);
+ Atom = clause_LiteralAtom(Lit);
+ Negative = clause_LiteralIsNegative(Lit);
+
+#ifdef CRW_DEBUG
+ printf("\n ----------\n ");
+ if (Negative)
+ printf((i <= clause_LastConstraintLitIndex(RuleClause)) ? "Cons" : "Ante");
+ else
+ printf("Succ");
+ printf(" aux = ");
+#endif
+
+ if (i <= clause_LastConstraintLitIndex(RuleClause)) {
+
+ /* Apply Sort Simplification for constraint literals only */
+ NegLits = list_List(term_Copy(Atom));
+ aux = clause_Create(NegLits, list_Nil(), list_Nil(), Flags, Precedence);
+ clause_SetTemporary(aux);
+ list_Delete(NegLits);
+
+#ifdef CRW_DEBUG
+ clause_Print(aux);
+#endif
+
+ NewClause = NULL;
+ OrigNum = clause_Number(aux);
+ if (red_SortSimplification(prfs_DynamicSortTheory(Search), aux, NAT_MAX,
+ DocProof, Flags, Precedence, &NewClause)) {
+ /* Sort Simplification was possible, so the unit clause was reduced */
+ /* to the empty clause. */
+
+ /* The splitting information is already set in <aux> or <NewClause>. */
+ if (DocProof)
+ /* If 'DocProof' is turned on, a copy was created and assigned */
+ /* to <NewClause>. */
+ red_CRwCalculateAdditionalParents(NewClause, list_Nil(), NULL, OrigNum);
+
+ if (NewClause != NULL) {
+ clause_Delete(aux);
+ return NewClause;
+ } else
+ return aux;
+ }
+ clause_Delete(aux);
+
+#ifdef CRW_DEBUG
+ printf("\n Cons aux2 = ");
+#endif
+ }
+
+ /* Collect literals for tautology test */
+ if (Negative) {
+ if (i <= clause_LastConstraintLitIndex(RuleClause))
+ NegLits = clause_CopyConstraint(RedClause);
+ else
+ NegLits = clause_CopyAntecedentExcept(RedClause, Except);
+ PosLits = list_List(term_Copy(Atom));
+ } else {
+ NegLits = list_List(term_Copy(Atom));
+ PosLits = clause_CopySuccedentExcept(RedClause, Except);
+ }
+
+ /* Create clause for tautology test */
+ aux = clause_Create(list_Nil(), NegLits, PosLits, Flags, Precedence);
+ clause_SetTemporary(aux);
+ list_Delete(NegLits);
+ list_Delete(PosLits);
+
+#ifdef CRW_DEBUG
+ clause_Print(aux);
+#endif
+
+ /* Apply special reduction. Propagate definitions x=t if for all literals */
+ /* u=v (A=tt) of the resulting clause the conditions holds: */
+ /* LeadingTerm > u{x->t} and LeadingTerm > v{x->t} (LeadingTerm > A{x->t}. */
+ if (red_PropagateDefinitions(aux, LeadingTerm, Flags, Precedence)) {
+#ifdef CRW_DEBUG
+ printf("\n After propagation of definitions:\n aux = ");
+ clause_Print(aux);
+#endif
+ }
+
+ /* Invoke forward reduction and tautology test */
+ NewClause = NULL;
+ RedundantList = list_Nil();
+ OrigNum = clause_Number(aux);
+ Redundant = red_SelectedStaticReductions(Search, &aux, &NewClause,
+ &RedundantList, Mode);
+ clause_SetTemporary(aux);
+ /* <aux> was possibly changed by some reductions, so mark it as */
+ /* temporary again. */
+
+ /* Invoke tautology test if <aux> isn't redundant. */
+ if (Redundant || (!clause_IsEmptyClause(aux) && cc_Tautology(aux))) {
+
+ if (NewClause != NULL)
+ /* <aux> is subsumed by <NewClause> */
+ clause_UpdateSplitDataFromPartner(aux, NewClause);
+
+ if (DocProof)
+ red_CRwCalculateAdditionalParents(aux, RedundantList, NewClause, OrigNum);
+ } else {
+ /* test failed */
+
+ clause_Delete(aux);
+ aux = NULL;
+ }
+
+#ifdef CRW_DEBUG
+ if (aux != NULL) {
+ if (NewClause != NULL) {
+ printf("\n Subsumer = ");
+ clause_Print(NewClause);
+ }
+ if (!list_Empty(RedundantList)) {
+ printf("\n RedundantList: ");
+ clause_ListPrint(RedundantList);
+ }
+
+ printf("\n aux reduced = ");
+ clause_Print(aux);
+ }
+ printf("\n ----------");
+#endif
+
+ /* Delete list of redundant clauses */
+ clause_DeleteClauseList(RedundantList);
+
+ return aux;
+}
+
+
+static BOOL red_CRwTautologyCheck(PROOFSEARCH Search, CLAUSE RedClause, int i,
+ TERM TermSInstance, CLAUSE RuleClause,
+ int j, NAT Mode, CLAUSE *Result)
+/**************************************************************
+ INPUT: A proof search object, two clauses, two literal indices
+ (one per clause), <TermSInstance> is a subterm of
+ literal <i> in <RedClause>, a mode defining the clause
+ index used for intermediate reductions, and a pointer
+ to a clause used as return value.
+ RETURNS: FALSE, if the clauses failed some tautology test or
+ the literal <i> in <RedClause> is not greater than literal
+ <j> in <RedClause> with the substitution <sigma> applied.
+ In this case <Result> is set to NULL.
+
+ TRUE is returned if the clauses passed all tautology tests
+ and literal <i> in <RedClause> is greater than literal <j>
+ in <RuleClause> with the substitution <sigma> applied.
+ In some cases <Result> is set to some auxiliary clause.
+ This is done if some clauses from the index were used to
+ reduce the intermediate clauses before the tautology test.
+ The auxiliary clause is used to return the necessary splitting
+ information for the current rewriting step.
+ If the <DocProof> flag is true, the information about
+ parent clauses is set in <Result>, too.
+ MEMORY: Remember to delete the <Result> clause if it is not NULL.
+***************************************************************/
+{
+ FLAGSTORE Flags, BackupFlags;
+ PRECEDENCE Precedence;
+ CLAUSE RuleCopy, aux;
+ TERM TermS;
+ int last, h;
+ BOOL Rewrite;
+
+#ifdef CHECK
+ if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(RuleClause, j))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_CRwTautologyCheck:");
+ misc_ErrorReport(" literal %d in <RuleClause> %d", j,
+ clause_Number(RuleClause));
+ misc_ErrorReport(" isn't an oriented equation");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+ *Result = NULL;
+
+ /* copy <RuleClause> and rename variables in copy */
+ RuleCopy = clause_Copy(RuleClause);
+ clause_RenameVarsBiggerThan(RuleCopy, clause_MaxVar(RedClause));
+ TermS = term_FirstArgument(clause_GetLiteralAtom(RuleCopy, j));
+
+ /* Remove parent information of copied clause and mark it as temporary */
+ list_Delete(clause_ParentClauses(RuleCopy));
+ clause_SetParentClauses(RuleCopy, list_Nil());
+ list_Delete(clause_ParentLiterals(RuleCopy));
+ clause_SetParentLiterals(RuleCopy, list_Nil());
+ clause_SetTemporary(RuleCopy);
+
+ /* establish bindings */
+ cont_StartBinding();
+ if (!unify_MatchBindings(cont_LeftContext(), TermS, TermSInstance)) {
+#ifdef CHECK
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_CRwTautologyCheck: terms aren't matchable");
+ misc_FinishErrorReport();
+#endif
+ }
+
+ /* Apply bindings to equation s=t, where s > t. Here the strict version */
+ /* of cont_Apply... can be applied, because all variables in s and t */
+ /* are bound. */
+ cont_ApplyBindingsModuloMatching(cont_LeftContext(),
+ clause_GetLiteralAtom(RuleCopy, j),
+ TRUE);
+
+ /* Check whether E > (s=t)sigma. It suffices to check only positive */
+ /* equations. All other cases imply the condition. */
+ if (i >= clause_FirstSuccedentLitIndex(RedClause) &&
+ clause_LiteralIsEquality(clause_GetLiteral(RedClause, i)) &&
+ ord_LiteralCompare(clause_GetLiteralTerm(RedClause, i),
+ clause_LiteralIsOrientedEquality(clause_GetLiteral(RedClause, i)),
+ clause_GetLiteralTerm(RuleCopy, j), TRUE,
+ FALSE, Flags, Precedence) != ord_GREATER_THAN) {
+ cont_BackTrack();
+ clause_Delete(RuleCopy);
+ return FALSE;
+ }
+
+ /* if (subs_SubsumesBasic(RuleClause, RedClause, j, i)) { Potential improvement, not completely
+ cont_BackTrack(); developed ....
+ return TRUE;
+ } else */
+ {
+ int OldClauseCounter;
+ /* Apply bindings to the rest of <RuleCopy> */
+ last = clause_LastLitIndex(RuleCopy);
+ for (h = clause_FirstLitIndex(); h <= last; h++) {
+ if (h != j)
+ cont_ApplyBindingsModuloMatching(cont_LeftContext(),
+ clause_GetLiteralAtom(RuleCopy, h),
+ FALSE);
+ }
+
+ /* Backtrack bindings before reduction rules are invoked */
+ cont_BackTrack();
+
+ /* Create new flag store and save current settings. Must be improved **** */
+ /* Then turn off flags for printing and contextual rewriting. */
+ /* IMPORTANT: the DocProof flag mustn't be changed! */
+ BackupFlags = flag_CreateStore();
+ flag_TransferAllFlags(Flags, BackupFlags);
+#ifndef CRW_DEBUG
+ flag_ClearPrinting(Flags);
+#else
+ { /* HACK: turn on all printing flags for debugging */
+ FLAG_ID f;
+
+ for (f = (FLAG_ID) 0; f < flag_MAXFLAG; f++) {
+ if (flag_IsPrinting(f))
+ flag_SetFlagValue(Flags, f, flag_ON);
+ }
+ }
+#endif
+
+ /* ATTENTION: to apply CRw recursively, uncomment the following */
+ /* line and comment out the following two lines! */
+ /* flag_SetFlagValue(Flags, flag_RFCRW, flag_RFCRWON); */
+ flag_SetFlagValue(Flags, flag_RBCRW, flag_RBCRWOFF);
+ flag_SetFlagValue(Flags, flag_RFCRW, flag_RFCRWOFF);
+
+ /* Examine all literals of <RuleCopy> except <j> */
+ Rewrite = TRUE;
+ last = clause_LastLitIndex(RuleCopy);
+ OldClauseCounter = clause_Counter();
+
+ for (h = clause_FirstLitIndex(); Rewrite && h <= last; h++) {
+ if (h != j) {
+ aux = red_CRwLitTautologyCheck(Search, RedClause, i, RuleCopy, h,
+ TermSInstance, Mode);
+ if (aux == NULL)
+ Rewrite = FALSE;
+ else {
+ /* Store splitting data of <aux> in RuleCopy */
+ clause_UpdateSplitDataFromPartner(RuleCopy, aux);
+ /* Collect additonal parent information, if <DocProof> is turned on */
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+ clause_SetParentClauses(RuleCopy,
+ list_Nconc(clause_ParentClauses(aux),
+ clause_ParentClauses(RuleCopy)));
+ clause_SetParentLiterals(RuleCopy,
+ list_Nconc(clause_ParentLiterals(aux),
+ clause_ParentLiterals(RuleCopy)));
+ clause_SetParentClauses(aux, list_Nil());
+ clause_SetParentLiterals(aux, list_Nil());
+ }
+ clause_Delete(aux);
+ }
+ }
+ }
+ /* restore clause counter */
+ clause_SetCounter(OldClauseCounter);
+
+ /* reset flag store of proof search object and free backup store */
+ flag_TransferAllFlags(BackupFlags, Flags);
+ flag_DeleteStore(BackupFlags);
+ }
+
+ if (Rewrite)
+ *Result = RuleCopy;
+ else
+ /* cleanup */
+ clause_Delete(RuleCopy);
+
+ return Rewrite;
+}
+
+
+static void red_DocumentContextualRewriting(CLAUSE Clause, int i,
+ CLAUSE RuleClause, int ri,
+ LIST AdditionalPClauses,
+ LIST AdditionalPLits)
+/**************************************************************
+ INPUT: Two clauses and two literal indices (one per clause),
+ and two lists of additional parent clause numbers and
+ parent literals.
+ RETURNS: Nothing.
+ EFFECT: <Clause> is rewritten for the first time by
+ Contextual Rewriting. This function sets the parent
+ clause and parent literal information in <Clause>.
+ <Clause> gets a new clause number.
+ CAUTION: The lists are not copied!
+***************************************************************/
+{
+#ifdef CHECK
+ if (list_Length(AdditionalPClauses) != list_Length(AdditionalPLits)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_DocumentContextualRewriting: lists of parent ");
+ misc_ErrorReport("clauses\n and literals have different length.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+ clause_SetParentClauses(Clause, AdditionalPClauses);
+ clause_SetParentLiterals(Clause, AdditionalPLits);
+ /* Add the old number of <Clause> as parent clause, */
+ /* before it gets a new clause number. */
+ clause_AddParentClause(Clause, clause_Number(Clause));
+ clause_AddParentLiteral(Clause, i);
+ clause_AddParentClause(Clause, clause_Number(RuleClause));
+ clause_AddParentLiteral(Clause, ri);
+
+ clause_NewNumber(Clause);
+ clause_SetFromContextualRewriting(Clause);
+}
+
+
+static void red_DocumentFurtherCRw(CLAUSE Clause, int i, CLAUSE RuleClause,
+ int ri, LIST AdditionalPClauses,
+ LIST AdditionalPLits)
+/**************************************************************
+ INPUT: Two clauses, two literal indices (one per clause),
+ and two lists of additional parent clause numbers and
+ parent literal indices.
+ RETURNS: Nothing.
+ EFFECT: <Clause> is a clause, that was rewritten before by
+ Contextual Rewriting. This function adds the parent
+ clause and parent literal information from one more
+ rewriting step to <Clause>. The information is added
+ to the front of the respective lists.
+ CAUTION: The lists are not copied!
+***************************************************************/
+{
+ int PClauseNum;
+
+#ifdef CHECK
+ if (list_Length(AdditionalPClauses) != list_Length(AdditionalPLits)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_DocumentFurtherCRw: lists of parent ");
+ misc_ErrorReport("clauses\n and literals have different length.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ PClauseNum = (int)list_Second(clause_ParentClauses(Clause));
+
+ clause_SetParentClauses(Clause, list_Nconc(AdditionalPClauses,
+ clause_ParentClauses(Clause)));
+ clause_SetParentLiterals(Clause, list_Nconc(AdditionalPLits,
+ clause_ParentLiterals(Clause)));
+
+ clause_AddParentClause(Clause, PClauseNum);
+ clause_AddParentLiteral(Clause, i);
+ clause_AddParentClause(Clause, clause_Number(RuleClause));
+ clause_AddParentLiteral(Clause, ri);
+}
+
+
+static BOOL red_ContextualRewriting(PROOFSEARCH Search, CLAUSE RedClause,
+ NAT Mode, int Level, CLAUSE *Changed)
+/**************************************************************
+ INPUT: A proof search object, a clause to reduce, the
+ reduction mode which defines the clause set used for
+ reduction, a split level indicating the need of a copy
+ if <Clause> is reduced by a clause of higher split level
+ than <Level>, and a pointer to a clause used as return value.
+ RETURNS: TRUE, if contextual rewriting was possible, FALSE otherwise.
+ If rewriting was possible and the <DocProof> flag is true
+ or the split level of the rewrite rule is higher than
+ <Level>, a copy of <RedClause> that is rewritten wrt.
+ the indexed clauses is returned in <*Changed>.
+ Otherwise the clause is destructively rewritten and
+ returned.
+ CAUTION: If rewriting wasn't applied, the value of <*Changed>
+ isn't set explicitely in this function.
+***************************************************************/
+{
+ TERM RedAtom, RedTermS;
+ int B_Stack;
+ int ri, last;
+ BOOL Rewritten, Result, Document;
+ TERM TermS, PartnerEq;
+ LIST Gen, EqScan, LitScan;
+ CLAUSE Copy;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+ SHARED_INDEX ShIndex;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+#ifdef CHECK
+ if (!clause_IsClause(RedClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_ContextualRewriting: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ /* Select clause index */
+ if (red_WorkedOffMode(Mode))
+ ShIndex = prfs_WorkedOffSharingIndex(Search);
+ else
+ ShIndex = prfs_UsableSharingIndex(Search);
+
+ last = clause_LastSuccedentLitIndex(RedClause);
+ Document = flag_GetFlagValue(Flags, flag_DOCPROOF);
+
+ Result = FALSE;
+ Copy = RedClause;
+
+ /* Don't apply this rule on constraint literals! */
+ for (ri = clause_FirstAntecedentLitIndex(RedClause); ri <= last; ri++) {
+ if (!list_Empty(term_ArgumentList(clause_GetLiteralAtom(Copy, ri)))) {
+ Rewritten = TRUE;
+ while (Rewritten) {
+ Rewritten = FALSE;
+ RedAtom = clause_GetLiteralAtom(Copy, ri);
+
+ B_Stack = stack_Bottom();
+ /* push subterms on stack except variables */
+ sharing_PushListReverseOnStack(term_ArgumentList(RedAtom));
+
+ while (!stack_Empty(B_Stack)) {
+ RedTermS = (TERM)stack_PopResult();
+ Gen = st_GetGen(cont_LeftContext(), sharing_Index(ShIndex), RedTermS);
+
+ for ( ; !list_Empty(Gen) && !Rewritten; Gen = list_Pop(Gen)) {
+ TermS = list_Car(Gen);
+
+ /* A variable can't be greater than any other term, */
+ /* so don't consider any variables here. */
+ if (!term_IsVariable(TermS)) {
+ EqScan = term_SupertermList(TermS);
+
+ for ( ; !list_Empty(EqScan) && !Rewritten;
+ EqScan = list_Cdr(EqScan)) {
+ PartnerEq = list_Car(EqScan);
+ if (fol_IsEquality(PartnerEq) &&
+ (term_FirstArgument(PartnerEq) == TermS)) {
+ CLAUSE RuleClause, HelpClause;
+ LITERAL RuleLit;
+ int i;
+
+ for (LitScan = sharing_NAtomDataList(PartnerEq);
+ !list_Empty(LitScan) && !Rewritten;
+ LitScan = list_Cdr(LitScan)) {
+ RuleLit = list_Car(LitScan);
+ RuleClause = clause_LiteralOwningClause(RuleLit);
+ i = clause_LiteralGetIndex(RuleLit);
+ HelpClause = NULL;
+
+#ifdef CRW_DEBUG
+ if (clause_LiteralIsPositive(RuleLit) &&
+ clause_LiteralGetFlag(RuleLit,STRICTMAXIMAL) &&
+ clause_LiteralIsOrientedEquality(RuleLit) &&
+ red_LeftTermOfEquationIsStrictlyMaximalTerm(RuleClause,
+ RuleLit,
+ Flags,
+ Precedence)) {
+ printf("\n------\nFCRw: %s\n%d ", red_WorkedOffMode(Mode)
+ ? "WorkedOff" : "Usable", i);
+ clause_Print(RuleClause);
+ printf("\n%d ", ri);
+ clause_Print(RedClause);
+ }
+#endif
+
+ if (clause_LiteralIsPositive(RuleLit) &&
+ clause_LiteralGetFlag(RuleLit,STRICTMAXIMAL) &&
+ clause_LiteralIsOrientedEquality(RuleLit) &&
+ red_LeftTermOfEquationIsStrictlyMaximalTerm(RuleClause,
+ RuleLit,
+ Flags,
+ Precedence) &&
+ red_CRwTautologyCheck(Search, Copy, ri, RedTermS,
+ RuleClause, i, Mode,
+ &HelpClause)) {
+ TERM TermT;
+
+ if (RedClause == Copy &&
+ (Document ||
+ prfs_SplitLevelCondition(clause_SplitLevel(RuleClause),
+ clause_SplitLevel(RedClause),Level) ||
+ prfs_SplitLevelCondition(clause_SplitLevel(HelpClause),
+ clause_SplitLevel(RedClause),
+ Level))) {
+ Copy = clause_Copy(RedClause);
+ RedAtom = clause_GetLiteralAtom(Copy, ri);
+ }
+
+ if (!Result && flag_GetFlagValue(Flags, flag_PCRW)) {
+ /* Clause is rewitten for the first time and */
+ /* printing is turned on. */
+ fputs("\nFContRewriting: ", stdout);
+ clause_Print(Copy);
+ fputs(" ==>[ ", stdout);
+ }
+
+ if (Document) {
+ LIST PClauses, PLits;
+
+ /* Get additional parent information from */
+ /* <HelpClause> */
+ PClauses = PLits = list_Nil();
+ if (HelpClause != NULL) {
+ PClauses = clause_ParentClauses(HelpClause);
+ PLits = clause_ParentLiterals(HelpClause);
+ clause_SetParentClauses(HelpClause, list_Nil());
+ clause_SetParentLiterals(HelpClause, list_Nil());
+ } else
+ PClauses = PLits = list_Nil();
+
+ if (!Result)
+ red_DocumentContextualRewriting(Copy, ri,
+ RuleClause, i,
+ PClauses, PLits);
+ else
+ red_DocumentFurtherCRw(Copy, ri, RuleClause, i,
+ PClauses, PLits);
+ }
+ Result = TRUE;
+
+ cont_StartBinding();
+ unify_MatchBindings(cont_LeftContext(), TermS, RedTermS);
+ TermT = cont_ApplyBindingsModuloMatching(cont_LeftContext(),
+ term_Copy(term_SecondArgument(PartnerEq)),
+ TRUE);
+ cont_BackTrack();
+
+ term_ReplaceSubtermBy(RedAtom, RedTermS, TermT);
+ Rewritten = TRUE;
+ /* Set splitting data from parents */
+ clause_UpdateSplitDataFromPartner(Copy, RuleClause);
+ if (HelpClause != NULL) {
+ /* Store splitting data from intermediate clauses */
+ clause_UpdateSplitDataFromPartner(Copy, HelpClause);
+ clause_Delete(HelpClause);
+ }
+ term_Delete(TermT);
+ stack_SetBottom(B_Stack);
+
+ if (flag_GetFlagValue(Flags, flag_PCRW))
+ printf("%d.%d ",clause_Number(RuleClause), i);
+ clause_UpdateWeight(Copy, Flags);
+ }
+ }
+ }
+ }
+ }
+ }
+ list_Delete(Gen);
+ }
+ }
+ }
+ }
+ if (Result) {
+ clause_OrientAndReInit(Copy, Flags, Precedence);
+ if (flag_GetFlagValue(Flags, flag_PCRW)) {
+ fputs("] ", stdout);
+ clause_Print(Copy);
+ }
+ if (Copy != RedClause) {
+ clause_OrientAndReInit(RedClause, Flags, Precedence);
+ *Changed = Copy;
+ }
+ }
+
+#ifdef CHECK
+ if (Copy != RedClause)
+ clause_Check(Copy, Flags, Precedence);
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ return Result;
+}
+
+
+static LIST red_BackSubsumption(CLAUSE RedCl, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**********************************************************
+ INPUT: A pointer to a non-empty clause, an index of
+ clauses, a flag store and a precedence.
+ RETURNS: The list of clauses that are subsumed by the
+ clause RedCl.
+***********************************************************/
+{
+ TERM Atom,CandTerm;
+ CLAUSE SubsumedCl;
+ LITERAL CandLit;
+ LIST CandLits, Scan, SubsumedList;
+ int i, j, lc, fa, la, fs, l;
+
+#ifdef CHECK
+ if (!clause_IsClause(RedCl, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_BackSubsumption :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedCl, Flags, Precedence);
+#endif
+
+ /* Special case: clause is empty */
+ if (clause_IsEmptyClause(RedCl))
+ return list_Nil();
+
+ SubsumedList = list_Nil();
+
+ lc = clause_LastConstraintLitIndex(RedCl);
+ fa = clause_FirstAntecedentLitIndex(RedCl);
+ la = clause_LastAntecedentLitIndex(RedCl);
+ fs = clause_FirstSuccedentLitIndex(RedCl);
+ l = clause_LastLitIndex(RedCl);
+
+ /* Choose the literal with the greatest weight to start the search */
+ i = clause_FirstLitIndex();
+ for (j = i + 1; j <= l; j++) {
+ if (clause_LiteralWeight(clause_GetLiteral(RedCl, j)) >
+ clause_LiteralWeight(clause_GetLiteral(RedCl, i)))
+ i = j;
+ }
+
+ Atom = clause_GetLiteralAtom(RedCl, i);
+ CandTerm = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), Atom);
+
+ while (CandTerm) {
+ CandLits = sharing_NAtomDataList(CandTerm);
+
+ for (Scan = CandLits; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ CandLit = list_Car(Scan);
+ SubsumedCl = clause_LiteralOwningClause(CandLit);
+ j = clause_LiteralGetIndex(CandLit);
+
+ if (RedCl != SubsumedCl &&
+ /* Literals must be from same part of the clause */
+ ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) ||
+ (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) ||
+ (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) &&
+ !list_PointerMember(SubsumedList, SubsumedCl) &&
+ subs_SubsumesBasic(RedCl, SubsumedCl, i, j))
+ SubsumedList = list_Cons(SubsumedCl, SubsumedList);
+ }
+
+ CandTerm = st_NextCandidate();
+ }
+
+ if (fol_IsEquality(Atom) &&
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(RedCl, i))) {
+ Atom = term_Create(fol_Equality(),
+ list_Reverse(term_ArgumentList(Atom)));
+ CandTerm = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), Atom);
+
+ while (CandTerm) {
+ CandLits = sharing_NAtomDataList(CandTerm);
+
+ for (Scan = CandLits; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ CandLit = list_Car(Scan);
+ SubsumedCl = clause_LiteralOwningClause(list_Car(Scan));
+ /* if (!clause_GetFlag(SubsumedCl, BLOCKED)) { */
+ j = clause_LiteralGetIndex(list_Car(Scan));
+
+ if ((RedCl != SubsumedCl) &&
+ /* Literals must be from same part of the clause */
+ ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) ||
+ (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) ||
+ (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) &&
+ !list_PointerMember(SubsumedList, SubsumedCl) &&
+ subs_SubsumesBasic(RedCl, SubsumedCl, i, j))
+ SubsumedList = list_Cons(SubsumedCl, SubsumedList);
+ /* } */
+ }
+
+ CandTerm = st_NextCandidate();
+ }
+
+ list_Delete(term_ArgumentList(Atom));
+ term_Free(Atom);
+ }
+
+ if (flag_GetFlagValue(Flags, flag_PSUB)) {
+ for (Scan = SubsumedList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ SubsumedCl = list_Car(Scan);
+ fputs("\nBSubsumption: ", stdout);
+ clause_Print(SubsumedCl);
+ printf(" by %d ",clause_Number(RedCl));
+ }
+ }
+ return SubsumedList;
+}
+
+
+static LIST red_GetBackMRResLits(CLAUSE Clause, LITERAL ActLit, SHARED_INDEX ShIndex)
+/**************************************************************
+ INPUT: A clause, one of its literals and an Index.
+ RETURNS: A list of clauses with a complementary literal instance
+ that are subsumed if these literals are ignored.
+ the empty list if no such clause exists.
+ MEMORY: Allocates the needed listnodes.
+***************************************************************/
+{
+ CLAUSE PClause;
+ LITERAL PLit;
+ LIST LitScan, PClLits;
+ TERM CandTerm;
+ int i;
+
+ PClLits = list_Nil();
+ i = clause_LiteralGetIndex(ActLit);
+
+ CandTerm = st_ExistInstance(cont_LeftContext(),
+ sharing_Index(ShIndex),
+ clause_LiteralAtom(ActLit));
+
+ while (CandTerm) {
+
+ LitScan = sharing_NAtomDataList(CandTerm); /* CAUTION ! */
+
+ for ( ; !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) {
+
+ PLit = list_Car(LitScan);
+ PClause = clause_LiteralOwningClause(PLit);
+
+ if (PClause != Clause &&
+ clause_LiteralsAreComplementary(ActLit,PLit) &&
+ subs_SubsumesBasic(Clause,PClause,i,clause_LiteralGetIndex(PLit)))
+ PClLits = list_Cons(PLit, PClLits);
+ }
+
+ CandTerm = st_NextCandidate();
+ }
+ return PClLits;
+}
+
+
+static LIST red_BackMatchingReplacementResolution(CLAUSE RedClause, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence,
+ LIST* Result)
+/**************************************************************
+ INPUT: A clause, a shared index, a flag store, a
+ precedence, and a pointer to a result list.
+ RETURNS: The return value itself contains a list of clauses
+ from <ShIndex> that is reducible by <RedClause> via
+ clause reduction.
+ The return value stored in <*Result> contains the
+ result of this operation.
+ If the <DocProof> flag is true then the clauses in
+ <*Result> contain information about the reduction.
+***************************************************************/
+{
+ LIST Blocked;
+ CLAUSE Copy;
+ BOOL Document;
+
+#ifdef CHECK
+ if (!clause_IsClause(RedClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_BackMatchingReplacementResolution:");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ Blocked = list_Nil();
+ Document = flag_GetFlagValue(Flags, flag_DOCPROOF);
+
+ if (clause_Length(RedClause) == 1) {
+ LITERAL ActLit, PLit;
+ LIST LitList, Scan, Iter;
+ TERM CandTerm;
+ int RedClNum;
+
+ ActLit = clause_GetLiteral(RedClause, clause_FirstLitIndex());
+
+ if (!fol_IsEquality(clause_LiteralAtom(ActLit)) || /* Reduce with negative equations too */
+ clause_LiteralIsNegative(ActLit)) {
+ CLAUSE PClause;
+ LIST PIndL;
+
+ CandTerm = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), clause_LiteralAtom(ActLit));
+ RedClNum = clause_Number(RedClause);
+ LitList = list_Nil();
+
+ while (CandTerm) {
+ for (Iter = sharing_NAtomDataList(CandTerm); !list_Empty(Iter); Iter = list_Cdr(Iter))
+ if (clause_LiteralsAreComplementary(ActLit,list_Car(Iter)))
+ LitList = list_Cons(list_Car(Iter),LitList);
+ CandTerm = st_NextCandidate();
+ }
+
+ /* It is important to get all literals first,
+ because there may be several literals in the same clause which can be reduced by <ActLit> */
+
+ while (!list_Empty(LitList)) {
+ PLit = list_Car(LitList);
+ PIndL = list_List(PLit);
+ PClause = clause_LiteralOwningClause(PLit);
+ Blocked = list_Cons(PClause, Blocked);
+
+ if (flag_GetFlagValue(Flags, flag_PMRR)) {
+ fputs("\nBMatchingReplacementResolution: ", stdout);
+ clause_Print(PClause);
+ printf(" ==>[ %d.%d ] ",clause_Number(RedClause),clause_FirstLitIndex());
+ }
+
+ Iter = LitList;
+ for (Scan=list_Cdr(LitList);!list_Empty(Scan);Scan=list_Cdr(Scan)) /* Get brothers of PLit */
+ if (PClause == clause_LiteralOwningClause(list_Car(Scan))) {
+ list_Rplacd(Iter,list_Cdr(Scan));
+ list_Rplacd(Scan,PIndL);
+ PIndL = Scan;
+ Scan = Iter;
+ }
+ else
+ Iter = Scan;
+ Iter = LitList;
+ LitList = list_Cdr(LitList);
+ list_Free(Iter);
+ Copy = clause_Copy(PClause);
+ clause_RemoveFlag(Copy,WORKEDOFF);
+ clause_UpdateSplitDataFromPartner(Copy, RedClause);
+ for(Scan=PIndL;!list_Empty(Scan);Scan=list_Cdr(Scan)) /* Change lits to indexes */
+ list_Rplaca(Scan,(POINTER)clause_LiteralGetIndex(list_Car(Scan)));
+ clause_DeleteLiterals(Copy, PIndL, Flags, Precedence);
+
+ if (Document)
+ /* Lists are consumed */
+ red_DocumentMatchingReplacementResolution(Copy, PIndL, list_List((POINTER)RedClNum),
+ list_List((POINTER)clause_FirstLitIndex()));
+
+ else
+ list_Delete(PIndL);
+
+ if (flag_GetFlagValue(Flags, flag_PMRR))
+ clause_Print(Copy);
+ *Result = list_Cons(Copy, *Result);
+ }
+ }
+ return Blocked;
+ }
+ else {
+ CLAUSE PClause;
+ LITERAL ActLit, PLit;
+ LIST LitScan,LitList;
+ int i,length,RedClNum,PInd;
+
+ RedClNum = clause_Number(RedClause);
+ length = clause_Length(RedClause);
+
+ for (i = clause_FirstLitIndex(); i < length; i++) {
+ ActLit = clause_GetLiteral(RedClause, i);
+
+ if (!fol_IsEquality(clause_LiteralAtom(ActLit))) {
+ LitList = red_GetBackMRResLits(RedClause, ActLit, ShIndex);
+
+ for (LitScan = LitList;!list_Empty(LitScan);LitScan = list_Cdr(LitScan)) {
+ PLit = list_Car(LitScan);
+ PClause = clause_LiteralOwningClause(PLit);
+ PInd = clause_LiteralGetIndex(PLit);
+ Copy = clause_Copy(PClause);
+ if (list_PointerMember(Blocked,PClause)) {
+ if (!flag_GetFlagValue(Flags, flag_DOCPROOF))
+ clause_NewNumber(Copy);
+ }
+ else
+ Blocked = list_Cons(PClause, Blocked);
+ clause_RemoveFlag(Copy,WORKEDOFF);
+ clause_UpdateSplitDataFromPartner(Copy, RedClause);
+ clause_DeleteLiteral(Copy, PInd, Flags, Precedence);
+
+ if (Document)
+ red_DocumentMatchingReplacementResolution(Copy, list_List((POINTER)PInd),
+ list_List((POINTER)RedClNum),
+ list_List((POINTER)i));
+
+ if (flag_GetFlagValue(Flags, flag_PMRR)) {
+ fputs("\nBMatchingReplacementResolution: ", stdout);
+ clause_Print(PClause);
+ printf(" ==>[ %d.%d ] ",clause_Number(RedClause),i);
+ clause_Print(Copy);
+ }
+ *Result = list_Cons(Copy, *Result);
+ }
+ list_Delete(LitList);
+ }
+ }
+ return Blocked;
+ }
+}
+
+
+static void red_ApplyRewriting(CLAUSE RuleCl, int ri, CLAUSE PartnerClause,
+ int pli, TERM PartnerTermS, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause to use for rewriting, the index of a
+ positive equality literal where the first equality
+ argument is greater, a clause, the index of a
+ literal with subterm <PartnerTermS> that can be
+ rewritten, a flag store and a precedence.
+ RETURNS: Nothing.
+ EFFECT: The atom of literal pli in PartnerClause is
+ destructively changed !!!
+ The <DocProof> flag is considered.
+***************************************************************/
+{
+ LITERAL PartnerLit;
+ TERM ReplaceTermT, NewAtom;
+
+#ifdef CHECK
+ clause_Check(PartnerClause, Flags, Precedence);
+ clause_Check(RuleCl, Flags, Precedence);
+#endif
+
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ red_DocumentRewriting(PartnerClause, pli, RuleCl, ri);
+
+ if (flag_GetFlagValue(Flags, flag_PREW)) {
+ fputs("\nBRewriting: ", stdout);
+ clause_Print(PartnerClause);
+ printf(" ==>[ %d.%d ] ", clause_Number(RuleCl), ri);
+ }
+
+ PartnerLit = clause_GetLiteral(PartnerClause, pli);
+
+ ReplaceTermT =
+ cont_ApplyBindingsModuloMatchingReverse(cont_LeftContext(),
+ term_Copy(term_SecondArgument(clause_GetLiteralTerm(RuleCl, ri))));
+
+ NewAtom = clause_LiteralSignedAtom(PartnerLit);
+ term_ReplaceSubtermBy(NewAtom, PartnerTermS, ReplaceTermT);
+ term_Delete(ReplaceTermT);
+
+ clause_OrientAndReInit(PartnerClause, Flags, Precedence);
+ clause_UpdateSplitDataFromPartner(PartnerClause, RuleCl);
+
+ if (flag_GetFlagValue(Flags, flag_PREW))
+ clause_Print(PartnerClause);
+}
+
+
+static LIST red_LiteralRewriting(CLAUSE RedClause, LITERAL ActLit, int ri,
+ SHARED_INDEX ShIndex, FLAGSTORE Flags,
+ PRECEDENCE Precedence, LIST* Result)
+/**************************************************************
+ INPUT: A clause, a positive equality literal where the
+ first equality argument is greater, its index, an
+ index of clauses, a flag store, a precedence and a
+ pointer to a list of clauses that were rewritten.
+ RETURNS: The list of clauses from the index that can be
+ rewritten by <ActLit> and <RedClause>.
+ The rewritten clauses are stored in <*Result>.
+ EFFECT: The <DocProof> flag is considered.
+***************************************************************/
+{
+ TERM TermS, CandTerm;
+ LIST Blocked;
+
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(ActLit) || !clause_LiteralIsEquality(ActLit) ||
+ !clause_LiteralIsOrientedEquality(ActLit)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_LiteralRewriting: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ Blocked = list_Nil();
+ TermS = term_FirstArgument(clause_LiteralSignedAtom(ActLit)); /* Vars can't be greater ! */
+
+ CandTerm = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), TermS);
+
+ while (CandTerm) {
+
+ if (!term_IsVariable(CandTerm) &&
+ !symbol_IsPredicate(term_TopSymbol(CandTerm))) {
+ LIST LitList;
+
+ LitList = sharing_GetDataList(CandTerm, ShIndex);
+
+ for ( ; !list_Empty(LitList); LitList = list_Pop(LitList)){
+ LITERAL PartnerLit;
+ CLAUSE PartnerClause;
+ int pli;
+
+ PartnerLit = list_Car(LitList);
+ pli = clause_LiteralGetIndex(PartnerLit);
+ PartnerClause = clause_LiteralOwningClause(PartnerLit);
+
+ /* Partner literal must be from antecedent or succedent */
+ if (clause_Number(RedClause) != clause_Number(PartnerClause) &&
+ pli >= clause_FirstAntecedentLitIndex(PartnerClause) &&
+ !list_PointerMember(Blocked, PartnerClause) &&
+ subs_SubsumesBasic(RedClause, PartnerClause, ri, pli)) {
+ CLAUSE Copy;
+
+ Blocked = list_Cons(PartnerClause, Blocked);
+ Copy = clause_Copy(PartnerClause);
+ clause_RemoveFlag(Copy, WORKEDOFF);
+ red_ApplyRewriting(RedClause, ri, Copy, pli, CandTerm,
+ Flags, Precedence);
+ *Result = list_Cons(Copy, *Result);
+ }
+ }
+ }
+ CandTerm = st_NextCandidate();
+ }
+ return Blocked;
+}
+
+
+static LIST red_BackRewriting(CLAUSE RedClause, SHARED_INDEX ShIndex,
+ FLAGSTORE Flags, PRECEDENCE Precedence,
+ LIST* Result)
+/**************************************************************
+ INPUT: A clause, and Index, a flag store, a precedence and
+ a pointer to the list of rewritten clauses.
+ RETURNS: A list of clauses that can be rewritten with
+ <RedClause> and the result of this operation is
+ stored in <*Result>.
+ EFFECT: The <DocProof> flag is considered.
+***************************************************************/
+{
+ int i,length;
+ LITERAL ActLit;
+ LIST Blocked;
+
+#ifdef CHECK
+ if (!(clause_IsClause(RedClause, Flags, Precedence))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_BackRewriting :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ Blocked = list_Nil();
+ length = clause_Length(RedClause);
+
+ for (i=clause_FirstSuccedentLitIndex(RedClause); i < length; i++) {
+ ActLit = clause_GetLiteral(RedClause, i);
+ if (clause_LiteralIsOrientedEquality(ActLit)) {
+ Blocked = list_Nconc(red_LiteralRewriting(RedClause, ActLit, i,
+ ShIndex, Flags, Precedence,
+ Result),
+ Blocked);
+ }
+
+#ifdef CHECK
+ if (fol_IsEquality(clause_LiteralSignedAtom(ActLit))) {
+ ord_RESULT HelpRes;
+
+ HelpRes =
+ ord_Compare(term_FirstArgument(clause_LiteralSignedAtom(ActLit)),
+ term_SecondArgument(clause_LiteralSignedAtom(ActLit)),
+ Flags, Precedence);
+
+ if (ord_IsSmallerThan(HelpRes)){ /* For Debugging */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_BackRewriting:");
+ misc_ErrorReport("First Argument smaller than second in RedClause.\n");
+ misc_FinishErrorReport();
+ }
+ } /* end of if (fol_IsEquality). */
+#endif
+ } /* end of for 'all succedent literals'. */
+ Blocked = list_PointerDeleteDuplicates(Blocked);
+ return Blocked;
+}
+
+
+/**************************************************************/
+/* BACKWARD CONTEXTUAL REWRITING */
+/**************************************************************/
+
+static LIST red_BackCRwOnLiteral(PROOFSEARCH Search, CLAUSE RuleClause,
+ LITERAL Lit, int i, NAT Mode, LIST* Result)
+/**************************************************************
+ INPUT: A proof search object, a clause that is used to rewrite
+ other clauses, a positive literal from the clause,
+ that is a strictly maximal, oriented equation, the index
+ of the literal, a mode defining which clause index
+ is used to find rewritable clauses, and a pointer
+ to a list that is used as return value.
+ The left term of the equation has to be the strictly
+ maximal term in the clause, i.e. it is bigger than
+ any other term.
+ RETURNS: The list of clauses from the clause index that can be
+ rewritten by <Lit> and <RuleClause>.
+ The rewritten clauses are stored in <*Result>.
+ EFFECT: The <DocProof> flag is considered.
+***************************************************************/
+{
+ TERM TermS, CandTerm, ReplaceTermT;
+ LIST Inst, Blocked;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+ SHARED_INDEX ShIndex;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+ if (red_WorkedOffMode(Mode))
+ ShIndex = prfs_WorkedOffSharingIndex(Search);
+ else
+ ShIndex = prfs_UsableSharingIndex(Search);
+
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Lit) || !clause_LiteralIsEquality(Lit) ||
+ !clause_LiteralGetFlag(Lit, STRICTMAXIMAL) ||
+ !clause_LiteralIsOrientedEquality(Lit)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_BackCRwOnLiteral: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RuleClause, Flags, Precedence);
+#endif
+
+ Blocked = list_Nil();
+ TermS = term_FirstArgument(clause_LiteralSignedAtom(Lit));
+
+ /* Get all instances of <TermS> at once. This can't be done iteratively */
+ /* since other reduction rules are invoked within the following loop. */
+ Inst = st_GetInstance(cont_LeftContext(), sharing_Index(ShIndex), TermS);
+
+ for ( ; !list_Empty(Inst); Inst = list_Pop(Inst)) {
+ CandTerm = list_Car(Inst);
+
+ if (!term_IsVariable(CandTerm) &&
+ !symbol_IsPredicate(term_TopSymbol(CandTerm))) {
+ LIST LitList;
+
+ LitList = sharing_GetDataList(CandTerm, ShIndex);
+
+ for ( ; !list_Empty(LitList); LitList = list_Pop(LitList)){
+ LITERAL RedLit;
+ CLAUSE RedClause, HelpClause;
+ int ri;
+
+ RedLit = list_Car(LitList);
+ ri = clause_LiteralGetIndex(RedLit);
+ RedClause = clause_LiteralOwningClause(RedLit);
+ HelpClause = NULL;
+
+#ifdef CRW_DEBUG
+ if (clause_Number(RuleClause) != clause_Number(RedClause) &&
+ ri >= clause_FirstAntecedentLitIndex(RedClause) &&
+ !list_PointerMember(Blocked, RedClause)) {
+ printf("\n------\nBCRw: %s\n%d ", red_WorkedOffMode(Mode) ?
+ "WorkedOff" : "Usable", i);
+ clause_Print(RuleClause);
+ printf("\n%d ", ri);
+ clause_Print(RedClause);
+ }
+#endif
+
+ /* Partner literal must be from antecedent or succedent */
+ if (clause_Number(RuleClause) != clause_Number(RedClause) &&
+ ri >= clause_FirstAntecedentLitIndex(RedClause) &&
+ /* Check that clause wasn't already rewritten by this literal. */
+ /* Necessary because then the old version of the clause is still */
+ /* in the index, but the rewritten version in not in the index. */
+ !list_PointerMember(Blocked, RedClause) &&
+ red_CRwTautologyCheck(Search, RedClause, ri, CandTerm,
+ RuleClause, i, Mode, &HelpClause)) {
+ CLAUSE Copy;
+
+ /* The <PartnerClause> has to be copied because it's indexed. */
+ Blocked = list_Cons(RedClause, Blocked);
+ Copy = clause_Copy(RedClause);
+ clause_RemoveFlag(Copy, WORKEDOFF);
+
+ /* Establish bindings */
+ cont_StartBinding();
+ if (!unify_MatchBindings(cont_LeftContext(), TermS, CandTerm)) {
+#ifdef CHECK
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_BackCRwOnLiteral: terms aren't ");
+ misc_ErrorReport("matchable.");
+ misc_FinishErrorReport();
+#endif
+ }
+ /* The variable check in cont_ApplyBindings... is turned on here */
+ /* because all variables is s are bound, and s > t. So all */
+ /* variables in t are bound, too. */
+ ReplaceTermT =
+ cont_ApplyBindingsModuloMatching(cont_LeftContext(),
+ term_Copy(term_SecondArgument(clause_GetLiteralTerm(RuleClause, i))),
+ TRUE);
+ cont_BackTrack();
+
+ /* Modify copied clause */
+ term_ReplaceSubtermBy(clause_GetLiteralAtom(Copy, ri), CandTerm,
+ ReplaceTermT);
+ term_Delete(ReplaceTermT);
+
+ /* Proof documentation */
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+ LIST PClauses, PLits;
+
+ if (HelpClause != NULL) {
+ /* Get additional parent clauses and literals from the */
+ /* tautology check. */
+ PClauses = clause_ParentClauses(HelpClause);
+ PLits = clause_ParentLiterals(HelpClause);
+ clause_SetParentClauses(HelpClause, list_Nil());
+ clause_SetParentLiterals(HelpClause, list_Nil());
+ } else
+ PClauses = PLits = list_Nil();
+
+ red_DocumentContextualRewriting(Copy, ri, RuleClause, i,
+ PClauses, PLits);
+ }
+
+ /* Set splitting data according to all parents */
+ clause_UpdateSplitDataFromPartner(Copy, RuleClause);
+ if (HelpClause != NULL) {
+ clause_UpdateSplitDataFromPartner(Copy, HelpClause);
+ clause_Delete(HelpClause);
+ }
+
+ clause_OrientAndReInit(Copy, Flags, Precedence);
+
+ if (flag_GetFlagValue(Flags, flag_PCRW)) {
+ fputs("\nBContRewriting: ", stdout);
+ clause_Print(RedClause);
+ printf(" ==>[ %d.%d ] ", clause_Number(RuleClause), i);
+ clause_Print(Copy);
+ }
+
+ *Result = list_Cons(Copy, *Result);
+ }
+ }
+ }
+ }
+
+ return Blocked;
+}
+
+
+static LIST red_BackContextualRewriting(PROOFSEARCH Search, CLAUSE RuleClause,
+ NAT Mode, LIST* Result)
+/**************************************************************
+ INPUT: A proof search object, a clause that is used to rewrite
+ other clauses, a mode flag that indicates which clause
+ index is used to find rewritable clauses, and a pointer
+ to a list that is used as return value.
+ RETURNS: A list of clauses that can be reduced
+ with Contextual Rewriting with <RuleClause>.
+ The clauses resulting from the rewriting steps are
+ stored in <*Result>.
+ EFFECT: The <DocProof> flag is considered. Every rewritable clause
+ is copied before rewriting is applied! This has to be done,
+ because the rewritable clauses are indexed.
+***************************************************************/
+{
+ BOOL found;
+ int i, ls;
+ LITERAL Lit;
+ LIST Blocked;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+#ifdef CHECK
+ if (!clause_IsClause(RuleClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_BackContextualRewriting: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RuleClause, Flags, Precedence);
+#endif
+
+ Blocked = list_Nil();
+ ls = clause_LastSuccedentLitIndex(RuleClause);
+ found = FALSE;
+
+ for (i = clause_FirstSuccedentLitIndex(RuleClause); i <= ls && !found; i++) {
+ Lit = clause_GetLiteral(RuleClause, i);
+ if (clause_LiteralIsOrientedEquality(Lit) &&
+ clause_LiteralGetFlag(Lit, STRICTMAXIMAL) &&
+ red_LeftTermOfEquationIsStrictlyMaximalTerm(RuleClause, Lit, Flags,
+ Precedence)) {
+ Blocked = list_Nconc(red_BackCRwOnLiteral(Search, RuleClause, Lit, i,
+ Mode, Result),
+ Blocked);
+ /* Stop loop: there's only one strictly maximal term per clause */
+ found = TRUE;
+ }
+ }
+
+ Blocked = list_PointerDeleteDuplicates(Blocked);
+ return Blocked;
+}
+
+
+static void red_DocumentSortSimplification(CLAUSE Clause, LIST Indexes,
+ LIST Clauses)
+/*********************************************************
+ INPUT: A clause and the literal indices and clauses
+ involved in sort simplification.
+ RETURNS: Nothing.
+ MEMORY: Consumes the input lists.
+**********************************************************/
+{
+ LIST Scan,Declarations,Self;
+
+ Declarations = list_Nil();
+ Self = list_Nil();
+
+ list_Delete(clause_ParentClauses(Clause));
+ list_Delete(clause_ParentLiterals(Clause));
+
+ for(Scan=Indexes;!list_Empty(Scan);Scan=list_Cdr(Scan))
+ Self = list_Cons((POINTER)clause_Number(Clause),Self);
+
+ for(Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Declarations = list_Cons((POINTER)clause_FirstSuccedentLitIndex(list_Car(Scan)),Declarations);
+ list_Rplaca(Scan,(POINTER)clause_Number(list_Car(Scan)));
+ }
+
+ clause_SetParentLiterals(Clause, list_Nconc(Indexes,Declarations));
+ clause_SetParentClauses(Clause, list_Nconc(Self,Clauses));
+
+ clause_SetNumber(Clause, clause_IncreaseCounter());
+ clause_SetFromSortSimplification(Clause);
+}
+
+
+static BOOL red_SortSimplification(SORTTHEORY Theory, CLAUSE Clause, NAT Level,
+ BOOL Document, FLAGSTORE Flags,
+ PRECEDENCE Precedence, CLAUSE *Changed)
+/**********************************************************
+ INPUT: A sort theory, a clause, the last backtrack
+ level of the current proof search, a boolean
+ flag concerning proof documentation, a flag
+ store and a precedence.
+ RETURNS: TRUE iff sort simplification was possible.
+ If <Document> is true or the split level of the
+ used declaration clauses requires copying a
+ simplified copy of the clause is returned in
+ <*Changed>.
+ Otherwise the clause is destructively
+ simplified.
+***********************************************************/
+{
+ if (Theory != (SORTTHEORY)NULL) {
+ TERM Atom,Term;
+ SOJU SortPair;
+ SORT TermSort,LitSort;
+ LIST Indexes,NewClauses,Clauses,Scan;
+ int i,lc,j,OldSplitLevel;
+ CLAUSE Copy;
+ CONDITION Cond;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_SortSimplification :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(Clause, Flags, Precedence);
+#endif
+
+ lc = clause_LastConstraintLitIndex(Clause);
+ i = clause_FirstLitIndex();
+ j = 0;
+ OldSplitLevel = clause_SplitLevel(Clause);
+ Copy = Clause;
+ Indexes = list_Nil();
+ Clauses = list_Nil();
+
+ while (i <= lc) {
+
+ Atom = clause_LiteralAtom(clause_GetLiteral(Copy, i));
+ Term = term_FirstArgument(Atom);
+ SortPair = sort_ComputeSortNoResidues(Theory, Term, Copy, i,
+ Flags, Precedence);
+ TermSort = sort_PairSort(SortPair);
+ NewClauses = sort_ConditionClauses(sort_PairCondition(SortPair));
+ sort_ConditionPutClauses(sort_PairCondition(SortPair),list_Nil());
+ LitSort = sort_TheorySortOfSymbol(Theory,term_TopSymbol(Atom));
+
+ if ((Cond = sort_TheoryIsSubsortOfNoResidues(Theory, TermSort, LitSort)) != (CONDITION)NULL) {
+
+ if (j == 0 && flag_GetFlagValue(Flags, flag_PSSI)) {
+ fputs("\nSortSimplification: ", stdout);
+ clause_Print(Copy);
+ fputs(" ==>[ ", stdout);
+ }
+
+ NewClauses = list_Nconc(NewClauses,sort_ConditionClauses(Cond));
+ sort_ConditionPutClauses(Cond,list_Nil());
+ sort_ConditionDelete(Cond);
+
+ for (Scan = NewClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (Clause == Copy &&
+ (Document ||
+ prfs_SplitLevelCondition(clause_SplitLevel(list_Car(Scan)),OldSplitLevel,Level)))
+ Copy = clause_Copy(Clause);
+ clause_UpdateSplitDataFromPartner(Copy, list_Car(Scan));
+ if (flag_GetFlagValue(Flags, flag_PSSI))
+ printf("%d ",clause_Number(list_Car(Scan)));
+ }
+
+ if (Document)
+ Indexes = list_Cons((POINTER)(i+j), Indexes);
+
+ clause_DeleteLiteral(Copy, i, Flags, Precedence);
+ Clauses = list_Nconc(NewClauses,Clauses);
+ j++;
+ lc--;
+ }
+ else {
+ list_Delete(NewClauses);
+ i++;
+ }
+ sort_DeleteSortPair(SortPair);
+ sort_Delete(LitSort);
+ }
+
+#ifdef CHECK
+ clause_Check(Copy, Flags, Precedence);
+#endif
+
+ if (j > 0) {
+ if (Document)
+ red_DocumentSortSimplification(Copy,Indexes,Clauses);
+ else
+ list_Delete(Clauses);
+ clause_ReInit(Copy, Flags, Precedence);
+ if (flag_GetFlagValue(Flags, flag_PSSI)) {
+ fputs("] ", stdout);
+ clause_Print(Copy);
+ }
+ if (Copy != Clause)
+ *Changed = Copy;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void red_ExchangeClauses(CLAUSE *RedClause, CLAUSE *Copy, LIST *Result)
+/**********************************************************
+ INPUT: Two pointers to clauses and a pointer to a list.
+ RETURNS: Nothing.
+ EFFECT: If *Copy is NULL, nothing is done. Otherwise *RedClause
+ is added to the list, *Copy is assigned to *RedClause,
+ and NULL is assigned to *Copy.
+***********************************************************/
+{
+ if (*Copy) {
+ *Result = list_Cons(*RedClause,*Result);
+ *RedClause = *Copy;
+ *Copy = (CLAUSE)NULL;
+ }
+}
+
+
+
+static BOOL red_SimpleStaticReductions(CLAUSE *RedClause, FLAGSTORE Flags,
+ PRECEDENCE Precedence, LIST* Result)
+/**********************************************************
+ INPUT: A clause (by reference), a flag store and a
+ precedence.
+ RETURNS: TRUE if <*RedClause> is redundant.
+ If the <DocProof> flag is false and no copying is necessary
+ with respect to splitting, the clause is destructively changed,
+ otherwise (intermediate) copies are made and returned in <*Result>.
+ EFFECT: Used reductions are tautology deletion and
+ obvious reductions.
+***********************************************************/
+{
+ CLAUSE Copy;
+ BOOL DocProof;
+
+#ifdef CHECK
+ if (!clause_IsClause(*RedClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_SimpleStaticReductions :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(*RedClause, Flags, Precedence);
+#endif
+
+ Copy = (CLAUSE)NULL;
+ DocProof = flag_GetFlagValue(Flags, flag_DOCPROOF);
+
+ if (flag_GetFlagValue(Flags, flag_RTAUT) != flag_RTAUTOFF &&
+ red_Tautology(*RedClause, Flags, Precedence))
+ return TRUE;
+
+ if (flag_GetFlagValue(Flags, flag_ROBV)) {
+ red_ObviousReductions(*RedClause, DocProof, Flags, Precedence, &Copy);
+ red_ExchangeClauses(RedClause, &Copy, Result);
+ }
+
+ if (flag_GetFlagValue(Flags, flag_RCON)) {
+ red_Condensing(*RedClause, DocProof, Flags, Precedence, &Copy);
+ red_ExchangeClauses(RedClause, &Copy, Result);
+ }
+
+ return FALSE;
+}
+
+
+
+
+static BOOL red_StaticReductions(PROOFSEARCH Search, CLAUSE *Clause,
+ CLAUSE *Subsumer, LIST* Result, NAT Mode)
+/**********************************************************
+ INPUT: A proof search object, a clause (by reference) to be reduced,
+ a shared index of clauses and the mode of the reductions,
+ determining which sets (Usable, WorkedOff) in <Search>
+ are considered for reductions.
+ RETURNS: TRUE iff the clause is redundant.
+ If the <DocProof> flag is false and no copying is necessary
+ with respect to splitting, the clause is destructively changed,
+ otherwise (intermediate) copies are made and returned in <*Result>.
+ If <Clause> gets redundant with respect to forward subsumption,
+ the subsuming clause is returned in <*Subsumer>.
+ EFFECT: Used reductions are tautology deletion, obvious reductions,
+ forward subsumption, forward rewriting, forward contextual
+ rewriting, forward matching replacement resolution,
+ sort simplification, unit conflict and static soft typing.
+ Depending on <Mode>, then clauses are reduced with respect
+ to WorkedOff or Usable Clauses.
+***********************************************************/
+{
+ CLAUSE Copy;
+ BOOL Redundant;
+ SHARED_INDEX Index;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+#ifdef CHECK
+ if (!clause_IsClause(*Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_StaticReductions:");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(*Clause, Flags, Precedence);
+#endif
+
+ Index = (red_OnlyWorkedOffMode(Mode) ?
+ prfs_WorkedOffSharingIndex(Search) : prfs_UsableSharingIndex(Search));
+ Copy = (CLAUSE)NULL;
+ Redundant = red_SimpleStaticReductions(Clause, Flags, Precedence, Result);
+
+ if (Redundant)
+ return Redundant;
+
+ /* Assignment Equation Deletion */
+ if (flag_GetFlagValue(Flags, flag_RAED) != flag_RAEDOFF &&
+ red_AssignmentEquationDeletion(*Clause, Flags, Precedence, &Copy,
+ prfs_NonTrivClauseNumber(Search),
+ (flag_GetFlagValue(Flags, flag_RAED) == flag_RAEDPOTUNSOUND))) {
+ red_ExchangeClauses(Clause, &Copy, Result);
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ }
+
+ /* Subsumption */
+ if (flag_GetFlagValue(Flags, flag_RFSUB)) {
+ *Subsumer = red_ForwardSubsumption(*Clause, Index, Flags, Precedence);
+ if ((Redundant = (*Subsumer != (CLAUSE)NULL)))
+ return Redundant;
+ }
+
+ /* Forward Rewriting and Forward Contextual Rewriting */
+ if ((flag_GetFlagValue(Flags, flag_RFREW) &&
+ red_RewriteRedClause(*Clause, Index, Flags, Precedence,
+ &Copy, prfs_LastBacktrackLevel(Search))) ||
+ (flag_GetFlagValue(Flags, flag_RFCRW) &&
+ red_ContextualRewriting(Search, *Clause, Mode,
+ prfs_LastBacktrackLevel(Search), &Copy))) {
+ red_ExchangeClauses(Clause, &Copy, Result);
+ Redundant = red_SimpleStaticReductions(Clause, Flags, Precedence, Result);
+ if (Redundant)
+ return Redundant;
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ if (flag_GetFlagValue(Flags, flag_RFSUB)) {
+ *Subsumer = red_ForwardSubsumption(*Clause, Index, Flags, Precedence);
+ if ((Redundant = (*Subsumer != (CLAUSE)NULL)))
+ return Redundant;
+ }
+ }
+
+ /* Sort Simplification */
+ if (red_OnlyWorkedOffMode(Mode) && flag_GetFlagValue(Flags, flag_RSSI)) {
+ red_SortSimplification(prfs_DynamicSortTheory(Search), *Clause,
+ prfs_LastBacktrackLevel(Search),
+ flag_GetFlagValue(Flags, flag_DOCPROOF),
+ Flags, Precedence, &Copy);
+ red_ExchangeClauses(Clause, &Copy, Result);
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ }
+
+ /* Matching Replacement Resolution */
+ if (flag_GetFlagValue(Flags, flag_RFMRR)) {
+ red_MatchingReplacementResolution(*Clause, Index, Flags, Precedence,
+ &Copy, prfs_LastBacktrackLevel(Search));
+ red_ExchangeClauses(Clause, &Copy, Result);
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ }
+
+ /* Unit Conflict */
+ if (flag_GetFlagValue(Flags, flag_RUNC)) {
+ red_UnitConflict(*Clause, Index, Flags, Precedence,
+ &Copy, prfs_LastBacktrackLevel(Search));
+ red_ExchangeClauses(Clause, &Copy, Result);
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ }
+
+ /* Static Soft Typing */
+ if (red_OnlyWorkedOffMode(Mode) && flag_GetFlagValue(Flags, flag_RSST))
+ Redundant = red_ClauseDeletion(prfs_StaticSortTheory(Search),*Clause,
+ Flags, Precedence);
+
+#ifdef CHECK
+ clause_Check(*Clause, Flags, Precedence);
+#endif
+
+ return Redundant;
+}
+
+static BOOL red_SelectedStaticReductions(PROOFSEARCH Search, CLAUSE *Clause,
+ CLAUSE *Subsumer, LIST* Result,
+ NAT Mode)
+/**********************************************************
+ INPUT: A proof search object, a clause (by reference) to be reduced,
+ and the mode of the reductions, determining which sets
+ (Usable, WorkedOff) in <Search> are considered for reductions.
+ EFFECT: Used reductions are tautology deletion, obvious reductions,
+ forward subsumption, forward rewriting, forward matching
+ replacement resolution, sort simplification, unit conflict
+ and static soft typing.
+ Depending on <Mode>, the clauses are reduced with respect
+ to WorkedOff and/or Usable Clauses.
+ RETURNS: TRUE iff the clause is redundant.
+ If the <DocProof> flag is false and no copying is necessary
+ with respect to splitting, the clause is destructively changed,
+ otherwise (intermediate) copies are made and returned in <*Result>.
+ If <Clause> gets redundant with respect to forward subsumption,
+ the subsuming clause is returned in <*Subsumer>.
+***********************************************************/
+{
+ CLAUSE Copy;
+ BOOL Redundant ,Rewritten, Tried, ContextualRew, StandardRew;
+ SHARED_INDEX WoIndex,UsIndex;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+#ifdef CHECK
+ if (!clause_IsClause(*Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_SelectedStaticReductions:");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(*Clause, Flags, Precedence);
+#endif
+
+ WoIndex = (SHARED_INDEX)NULL;
+ UsIndex = (SHARED_INDEX)NULL;
+ if (red_WorkedOffMode(Mode))
+ WoIndex = prfs_WorkedOffSharingIndex(Search);
+ if (red_UsableMode(Mode))
+ UsIndex = prfs_UsableSharingIndex(Search);
+ Copy = (CLAUSE)NULL;
+ Redundant = red_SimpleStaticReductions(Clause, Flags, Precedence, Result);
+
+ if (Redundant)
+ return Redundant;
+
+ if (flag_GetFlagValue(Flags, flag_RAED) != flag_RAEDOFF &&
+ red_AssignmentEquationDeletion(*Clause, Flags, Precedence, &Copy,
+ prfs_NonTrivClauseNumber(Search),
+ (flag_GetFlagValue(Flags, flag_RAED)==flag_RAEDPOTUNSOUND))) {
+ red_ExchangeClauses(Clause, &Copy, Result);
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ }
+
+ if (flag_GetFlagValue(Flags, flag_RFSUB)) {
+ *Subsumer = (CLAUSE)NULL;
+ if (WoIndex != NULL) {
+ *Subsumer = red_ForwardSubsumption(*Clause, WoIndex, Flags, Precedence);
+ if (*Subsumer != (CLAUSE)NULL)
+ return TRUE;
+ }
+ if (UsIndex != NULL) {
+ *Subsumer = red_ForwardSubsumption(*Clause, UsIndex, Flags, Precedence);
+ if (*Subsumer != (CLAUSE)NULL)
+ return TRUE;
+ }
+ }
+
+ StandardRew = flag_GetFlagValue(Flags, flag_RFREW);
+ ContextualRew = flag_GetFlagValue(Flags, flag_RFCRW);
+
+ Rewritten = (StandardRew || ContextualRew);
+ Tried = FALSE;
+ while (Rewritten) {
+ Rewritten = FALSE;
+
+ if (WoIndex != NULL &&
+ ((StandardRew &&
+ red_RewriteRedClause(*Clause, WoIndex, Flags, Precedence, &Copy,
+ prfs_LastBacktrackLevel(Search))) ||
+ (ContextualRew &&
+ red_ContextualRewriting(Search, *Clause, red_WORKEDOFF,
+ prfs_LastBacktrackLevel(Search), &Copy)))) {
+ Rewritten = TRUE;
+ red_ExchangeClauses(Clause, &Copy, Result);
+ Redundant = red_SimpleStaticReductions(Clause, Flags,
+ Precedence, Result);
+ if (Redundant)
+ return Redundant;
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ if (flag_GetFlagValue(Flags, flag_RFSUB)) {
+ *Subsumer = (CLAUSE)NULL;
+ *Subsumer = red_ForwardSubsumption(*Clause, WoIndex,
+ Flags, Precedence);
+ if (*Subsumer != (CLAUSE)NULL)
+ return TRUE; /* Clause is redundant */
+ if (UsIndex != NULL) {
+ *Subsumer = red_ForwardSubsumption(*Clause, UsIndex,
+ Flags, Precedence);
+ if (*Subsumer != (CLAUSE)NULL)
+ return TRUE;
+ }
+ }
+ }
+
+ if (UsIndex != NULL &&
+ (!Tried || Rewritten) &&
+ ((StandardRew &&
+ red_RewriteRedClause(*Clause, UsIndex, Flags, Precedence,
+ &Copy, prfs_LastBacktrackLevel(Search))) ||
+ (ContextualRew &&
+ red_ContextualRewriting(Search, *Clause, red_USABLE,
+ prfs_LastBacktrackLevel(Search), &Copy)))) {
+ Rewritten = TRUE;
+ red_ExchangeClauses(Clause, &Copy, Result);
+ Redundant = red_SimpleStaticReductions(Clause, Flags,
+ Precedence, Result);
+ if (Redundant)
+ return Redundant;
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ if (flag_GetFlagValue(Flags, flag_RFSUB)) {
+ *Subsumer = (CLAUSE)NULL;
+ if (WoIndex != NULL)
+ *Subsumer = red_ForwardSubsumption(*Clause, WoIndex,
+ Flags, Precedence);
+ if (*Subsumer != (CLAUSE)NULL)
+ return TRUE;
+ *Subsumer = red_ForwardSubsumption(*Clause, UsIndex,
+ Flags, Precedence);
+ if (*Subsumer != (CLAUSE)NULL)
+ return TRUE;
+ }
+ }
+
+ Tried = TRUE;
+ } /* end of while(Rewritten) */
+
+
+ if (flag_GetFlagValue(Flags, flag_RSSI)) {
+ red_SortSimplification(prfs_DynamicSortTheory(Search), *Clause,
+ prfs_LastBacktrackLevel(Search),
+ flag_GetFlagValue(Flags, flag_DOCPROOF),
+ Flags, Precedence, &Copy);
+ red_ExchangeClauses(Clause, &Copy, Result);
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ }
+
+ if (flag_GetFlagValue(Flags, flag_RFMRR)) {
+ if (WoIndex)
+ red_MatchingReplacementResolution(*Clause, WoIndex, Flags, Precedence,
+ &Copy, prfs_LastBacktrackLevel(Search));
+ red_ExchangeClauses(Clause, &Copy, Result);
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ if (UsIndex)
+ red_MatchingReplacementResolution(*Clause, UsIndex, Flags, Precedence,
+ &Copy, prfs_LastBacktrackLevel(Search));
+ red_ExchangeClauses(Clause, &Copy, Result);
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ }
+
+ if (flag_GetFlagValue(Flags, flag_RUNC)) {
+ if (WoIndex)
+ red_UnitConflict(*Clause, WoIndex, Flags, Precedence,
+ &Copy, prfs_LastBacktrackLevel(Search));
+ red_ExchangeClauses(Clause, &Copy, Result);
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ if (UsIndex)
+ red_UnitConflict(*Clause, UsIndex, Flags, Precedence,
+ &Copy, prfs_LastBacktrackLevel(Search));
+ red_ExchangeClauses(Clause, &Copy, Result);
+ if (clause_IsEmptyClause(*Clause))
+ return FALSE;
+ }
+
+ if (flag_GetFlagValue(Flags, flag_RSST))
+ Redundant = red_ClauseDeletion(prfs_StaticSortTheory(Search),*Clause,
+ Flags, Precedence);
+
+#ifdef CHECK
+ clause_Check(*Clause, Flags, Precedence);
+#endif
+
+ return Redundant;
+}
+
+
+CLAUSE red_ReductionOnDerivedClause(PROOFSEARCH Search, CLAUSE Clause,
+ NAT Mode)
+/**************************************************************
+ INPUT: A proof search object, a derived clause and a mode
+ indicating which indexes should be used for reductions.
+ RETURNS: The non-redundant clause after reducing <Clause>,
+ NULL if <Clause> is redundant.
+ EFFECT: Clauses probably generated, but redundant are kept according
+ to the <DocProof> flag and the split level of involved clauses.
+ depending on <Mode>, then clauses are reduced
+ with respect to WorkedOff and/or Usable Clauses.
+***************************************************************/
+{
+ CLAUSE RedClause;
+ LIST Redundant;
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ Redundant = list_Nil();
+ RedClause = (CLAUSE)NULL;
+
+ if (red_StaticReductions(Search,&Clause,&RedClause,&Redundant,Mode)) {
+ /* Clause is redundant */
+ red_HandleRedundantDerivedClauses(Search, Redundant, Clause);
+ list_Delete(Redundant);
+ if (RedClause &&
+ prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause),
+ prfs_LastBacktrackLevel(Search))) {
+ split_KeepClauseAtLevel(Search,Clause,clause_SplitLevel(RedClause));
+ }
+ else
+ if (flag_GetFlagValue(prfs_Store(Search), flag_DOCPROOF))
+ prfs_InsertDocProofClause(Search,Clause);
+ else
+ clause_Delete(Clause);
+ Clause = (CLAUSE)NULL;
+ }
+ else {
+ red_HandleRedundantDerivedClauses(Search, Redundant, Clause);
+ list_Delete(Redundant);
+ }
+
+#ifdef CHECK
+ cont_CheckState();
+#endif
+
+ return Clause;
+}
+
+CLAUSE red_CompleteReductionOnDerivedClause(PROOFSEARCH Search, CLAUSE Clause,
+ NAT Mode)
+/**************************************************************
+ INPUT: A proof search object, a derived clause and a mode determining
+ which clauses to consider for reduction.
+ RETURNS: The non-redundant clause after reducing <Clause>,
+ NULL if <Clause> is redundant.
+ EFFECT: Clauses probably generated, but redundant are kept according
+ to the <DocProof> flag and the split level of involved clauses.
+ The clause is reduced with respect to all indexes determined
+ by <Mode>
+***************************************************************/
+{
+ CLAUSE RedClause;
+ LIST Redundant;
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ Redundant = list_Nil();
+ RedClause = (CLAUSE)NULL;
+
+ if (red_SelectedStaticReductions(Search,&Clause,&RedClause,&Redundant,Mode)) {
+ /* <Clause> is redundant */
+ red_HandleRedundantDerivedClauses(Search, Redundant, Clause);
+ list_Delete(Redundant);
+ if (RedClause &&
+ prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause),
+ prfs_LastBacktrackLevel(Search))) {
+ split_KeepClauseAtLevel(Search, Clause, clause_SplitLevel(RedClause));
+ }
+ else
+ if (flag_GetFlagValue(prfs_Store(Search), flag_DOCPROOF))
+ prfs_InsertDocProofClause(Search, Clause);
+ else
+ clause_Delete(Clause);
+ Clause = (CLAUSE)NULL;
+ }
+ else {
+ red_HandleRedundantDerivedClauses(Search, Redundant, Clause);
+ list_Delete(Redundant);
+ }
+
+#ifdef CHECK
+ cont_CheckState();
+#endif
+
+ return Clause;
+}
+
+
+LIST red_BackReduction(PROOFSEARCH Search, CLAUSE Clause, NAT Mode)
+/**************************************************************
+ INPUT: A proof search object, a clause and a mode flag.
+ RETURNS: A list of reduced clauses in usable and worked-off
+ (depending on <Mode>) in <Search> with respect to <Clause>.
+ The original clauses that become redundant are either deleted
+ or kept for proof documentation or splitting.
+ EFFECT: The original clauses that become redundant are either deleted
+ or kept for proof documentation or splitting.
+***************************************************************/
+{
+ LIST Result, Redundant;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ Result = list_Nil();
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ /* Subsumption */
+ if (flag_GetFlagValue(Flags, flag_RBSUB)) {
+ Redundant = list_Nil();
+ if (red_WorkedOffMode(Mode))
+ Redundant = red_BackSubsumption(Clause,
+ prfs_WorkedOffSharingIndex(Search),
+ Flags, Precedence);
+ if (red_UsableMode(Mode))
+ Redundant = list_Nconc(Redundant,
+ red_BackSubsumption(Clause,
+ prfs_UsableSharingIndex(Search),
+ Flags, Precedence));
+ red_HandleRedundantIndexedClauses(Search, Redundant, Clause);
+ list_Delete(Redundant);
+ }
+
+ /* Matching Replacement Resolution */
+ if (flag_GetFlagValue(Flags, flag_RBMRR)) {
+ Redundant = list_Nil();
+ if (red_WorkedOffMode(Mode))
+ Redundant = red_BackMatchingReplacementResolution(Clause,
+ prfs_WorkedOffSharingIndex(Search),
+ Flags, Precedence, &Result);
+ if (red_UsableMode(Mode))
+ Redundant = list_Nconc(Redundant,
+ red_BackMatchingReplacementResolution(Clause,
+ prfs_UsableSharingIndex(Search),
+ Flags, Precedence, &Result));
+ red_HandleRedundantIndexedClauses(Search, Redundant, Clause);
+ list_Delete(Redundant);
+ }
+
+ /* Standard Rewriting */
+ if (flag_GetFlagValue(Flags, flag_RBREW)) {
+ Redundant = list_Nil();
+ if (red_WorkedOffMode(Mode))
+ Redundant = red_BackRewriting(Clause,prfs_WorkedOffSharingIndex(Search),
+ Flags, Precedence, &Result);
+ if (red_UsableMode(Mode))
+ Redundant = list_Nconc(Redundant,
+ red_BackRewriting(Clause,
+ prfs_UsableSharingIndex(Search),
+ Flags, Precedence, &Result));
+
+ red_HandleRedundantIndexedClauses(Search, Redundant, Clause);
+ list_Delete(Redundant);
+ }
+
+ /* Contextual Rewriting */
+ if (flag_GetFlagValue(Flags, flag_RBCRW)) {
+ Redundant = list_Nil();
+ if (red_WorkedOffMode(Mode))
+ Redundant = red_BackContextualRewriting(Search, Clause, red_WORKEDOFF,
+ &Result);
+ if (red_UsableMode(Mode))
+ Redundant = list_Nconc(Redundant,
+ red_BackContextualRewriting(Search, Clause,
+ red_USABLE, &Result));
+
+ red_HandleRedundantIndexedClauses(Search, Redundant, Clause);
+ list_Delete(Redundant);
+ }
+
+#ifdef CHECK
+ cont_CheckState();
+#endif
+
+ return Result;
+}
+
+
+static __inline__ LIST red_MergeClauseListsByWeight(LIST L1, LIST L2)
+/**************************************************************
+ INPUT: Two lists of clauses, sorted by weight.
+ RETURNS:
+ EFFECT:
+***************************************************************/
+{
+ return list_NNumberMerge(L1, L2, (NAT (*)(POINTER))clause_Weight);
+}
+
+
+LIST red_CompleteReductionOnDerivedClauses(PROOFSEARCH Search,
+ LIST DerivedClauses, NAT Mode,
+ int Bound, NAT BoundMode,
+ int *BoundApplied)
+/**************************************************************
+ INPUT: A proof search object, a list of newly derived (unshared) clauses,
+ a mode determining which clause lists to consider for reduction,
+ a bound and a bound mode to cut off generated clauses.
+ RETURNS: A list of empty clauses that may be derived during the
+ reduction process.
+ <*BoundApplied> is set to the mode dependent value of the
+ smallest clause if a clause is deleted because of a bound.
+ EFFECT: The <DerivedClauses> are destructively reduced and reduced clauses
+ from the indexes are checked out and all finally reduced clauses
+ are checked into the indexes. Depending on <Mode> either the
+ WorkedOff, Usable or both indexes are considered.
+ The <DocProof> Flag is considered.
+***************************************************************/
+{
+ LIST EmptyClauses,NewClauses,Scan;
+ NAT ClauseBound;
+ CLAUSE Clause;
+ FLAGSTORE Flags;
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ EmptyClauses = list_Nil();
+ DerivedClauses = clause_ListSortWeighed(DerivedClauses);
+ ClauseBound = 0;
+ Flags = prfs_Store(Search);
+
+ while (!list_Empty(DerivedClauses)) {
+#ifdef WIN
+ clock_PingOneSecond();
+#endif
+ Clause = list_NCar(&DerivedClauses);
+ if (prfs_SplitStackEmpty(Search)) /* Otherwise splitting not compatible with bound deletion */
+ Clause = red_CompleteReductionOnDerivedClause(Search, Clause, Mode);
+
+ if (Clause != NULL && BoundMode != flag_BOUNDMODEUNLIMITED &&
+ Bound != flag_BOUNDSTARTUNLIMITED && !clause_IsFromInput(Clause) &&
+ !clause_IsFromSplitting(Clause)) {
+ switch (BoundMode) {
+ case flag_BOUNDMODERESTRICTEDBYWEIGHT:
+ ClauseBound = clause_Weight(Clause);
+ break;
+ case flag_BOUNDMODERESTRICTEDBYDEPTH:
+ ClauseBound = clause_ComputeTermDepth(Clause);
+ break;
+ default:
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n Error while applying bound restrictions:");
+ misc_UserErrorReport("\n You selected an unknown bound mode.\n");
+ misc_FinishUserErrorReport();
+ }
+ if (ClauseBound > Bound) {
+ if (flag_GetFlagValue(Flags, flag_PBDC)) {
+ fputs("\nDeleted by bound: ", stdout);
+ clause_Print(Clause);
+ }
+ clause_Delete(Clause);
+ if (*BoundApplied == -1 || ClauseBound < *BoundApplied)
+ *BoundApplied = ClauseBound;
+ Clause = (CLAUSE)NULL;
+ }
+ }
+
+ if (Clause != (CLAUSE)NULL && /* For clauses below bound, splitting is */
+ !prfs_SplitStackEmpty(Search)) /* compatible with bound deletion */
+ Clause = red_CompleteReductionOnDerivedClause(Search, Clause, Mode);
+
+ if (Clause) {
+ prfs_IncKeptClauses(Search);
+ if (flag_GetFlagValue(Flags, flag_PKEPT)) {
+ fputs("\nKept: ", stdout);
+ clause_Print(Clause);
+ }
+ if (clause_IsEmptyClause(Clause))
+ EmptyClauses = list_Cons(Clause,EmptyClauses);
+ else {
+ NewClauses = red_BackReduction(Search, Clause, Mode);
+ prfs_IncDerivedClauses(Search, list_Length(NewClauses));
+ if (flag_GetFlagValue(Flags, flag_PDER))
+ for (Scan=NewClauses; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ fputs("\nDerived: ", stdout);
+ clause_Print(list_Car(Scan));
+ }
+ NewClauses = split_ExtractEmptyClauses(NewClauses,&EmptyClauses);
+
+ prfs_InsertUsableClause(Search,Clause);
+ NewClauses = list_NumberSort(NewClauses, (NAT (*) (POINTER)) clause_Weight);
+ DerivedClauses = red_MergeClauseListsByWeight(DerivedClauses,NewClauses);
+ }
+ }
+ }
+
+#ifdef CHECK
+ cont_CheckState();
+#endif
+
+ return EmptyClauses;
+}
+
+
+
+static CLAUSE red_CDForwardSubsumer(CLAUSE RedCl, st_INDEX Index,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**********************************************************
+ INPUT: A pointer to a non-empty clause, an index of
+ clauses, a flag store and a precedence.
+ RETURNS: The first clause from the Approx Set which
+ subsumes 'RedCl'.
+***********************************************************/
+{
+ TERM Atom,AtomGen;
+ LIST LitScan;
+ int i,length;
+ CLAUSE CandCl;
+
+#ifdef CHECK
+ if (!clause_IsClause(RedCl, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_CDForwardSubsumer :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedCl, Flags, Precedence);
+#endif
+
+ length = clause_Length(RedCl);
+
+ for (i = 0; i < length; i++) {
+ Atom = clause_GetLiteralAtom(RedCl, i);
+ AtomGen = st_ExistGen(cont_LeftContext(), Index, Atom);
+
+ while (AtomGen) {
+ for (LitScan = term_SupertermList(AtomGen);
+ !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) {
+ CandCl = clause_LiteralOwningClause(list_Car(LitScan));
+
+ if (clause_GetLiteral(CandCl,clause_FirstLitIndex()) == (LITERAL)list_Car(LitScan) &&
+ subs_Subsumes(CandCl, RedCl, clause_FirstLitIndex(), i)) {
+ st_CancelExistRetrieval();
+ return CandCl;
+ }
+ }
+ AtomGen = st_NextCandidate();
+ }
+ }
+ return (CLAUSE)NULL;
+}
+
+
+static BOOL red_CDForwardSubsumption(CLAUSE RedClause, st_INDEX Index,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**********************************************************
+ INPUT: A clause, an index of clauses, a flag store and
+ a precedence.
+ RETURNS: The boolean value TRUE if the clause is subsumed
+ by an indexed clause, if so, the clause is deleted,
+ either really or locally.
+***********************************************************/
+{
+ BOOL IsSubsumed;
+ CLAUSE Subsumer;
+
+#ifdef CHECK
+ if (!clause_IsClause(RedClause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_CDForwardSubSumption :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+ IsSubsumed = FALSE;
+ Subsumer = red_CDForwardSubsumer(RedClause, Index, Flags, Precedence);
+
+ if (clause_Exists(Subsumer)) {
+ IsSubsumed = TRUE;
+
+ if (flag_GetFlagValue(Flags, flag_DOCSST) &&
+ flag_GetFlagValue(Flags, flag_PSUB)) {
+ fputs("\nFSubsumption:", stdout);
+ clause_Print(RedClause);
+ printf(" by %d ",clause_Number(Subsumer));
+ }
+ }
+ return IsSubsumed;
+}
+
+
+static void red_CDBackSubsumption(CLAUSE RedCl, FLAGSTORE Flags,
+ PRECEDENCE Precedence,
+ LIST* UsListPt, LIST* WOListPt,
+ st_INDEX Index)
+/**********************************************************
+ INPUT: A pointer to a non-empty clause, a flag store,
+ a precedence, and an index of clauses.
+ RETURNS: Nothing.
+***********************************************************/
+{
+ TERM Atom,AtomInst;
+ CLAUSE SubsumedCl;
+ LIST Scan, SubsumedList;
+
+#ifdef CHECK
+ if (!clause_IsClause(RedCl, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_CDBackupSubSumption :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedCl, Flags, Precedence);
+#endif
+
+ SubsumedList = list_Nil();
+
+ if (!clause_IsEmptyClause(RedCl)) {
+ Atom = clause_GetLiteralAtom(RedCl, clause_FirstLitIndex());
+ AtomInst = st_ExistInstance(cont_LeftContext(), Index, Atom);
+
+ while(AtomInst) {
+ for (Scan = term_SupertermList(AtomInst); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ SubsumedCl = clause_LiteralOwningClause(list_Car(Scan));
+ if ((RedCl != SubsumedCl) &&
+ subs_Subsumes(RedCl, SubsumedCl, clause_FirstLitIndex(),
+ clause_LiteralGetIndex(list_Car(Scan))) &&
+ !list_PointerMember(SubsumedList, SubsumedCl))
+ SubsumedList = list_Cons(SubsumedCl, SubsumedList);
+ }
+ AtomInst = st_NextCandidate();
+ }
+
+ for (Scan = SubsumedList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ SubsumedCl = list_Car(Scan);
+
+ if (flag_GetFlagValue(Flags, flag_DOCSST) && flag_GetFlagValue(Flags, flag_PSUB)) {
+ fputs("\nBSubsumption: ", stdout);
+ clause_Print(SubsumedCl);
+ printf(" by %d ",clause_Number(RedCl));
+ }
+
+
+ if (clause_GetFlag(SubsumedCl,WORKEDOFF)) {
+ *WOListPt = list_PointerDeleteOneElement(*WOListPt, SubsumedCl);
+ }else {
+ *UsListPt = list_PointerDeleteOneElement(*UsListPt, SubsumedCl);
+ }
+ clause_DeleteFlatFromIndex(SubsumedCl, Index);
+ }
+ list_Delete(SubsumedList);
+ }
+}
+
+
+static LIST red_CDDerivables(SORTTHEORY Theory, CLAUSE GivenClause,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A sort theory, a clause, a flag store and a
+ precedence.
+ RETURNS: A list of clauses derivable from <GivenClause> and
+ the declaration clauses in <Theory>.
+***************************************************************/
+{
+ LIST ListOfDerivedClauses;
+
+#ifdef CHECK
+ if (!(clause_IsClause(GivenClause, Flags, Precedence))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_CDDeriveables :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(GivenClause, Flags, Precedence);
+#endif
+
+ if (clause_HasTermSortConstraintLits(GivenClause))
+ ListOfDerivedClauses = inf_ForwardSortResolution(GivenClause,
+ sort_TheoryIndex(Theory),
+ Theory, TRUE,
+ Flags, Precedence);
+ else
+ ListOfDerivedClauses = inf_ForwardEmptySort(GivenClause,
+ sort_TheoryIndex(Theory),
+ Theory, TRUE,
+ Flags, Precedence);
+
+ return ListOfDerivedClauses;
+}
+
+
+static BOOL red_CDReduce(SORTTHEORY Theory, CLAUSE RedClause,
+ FLAGSTORE Flags, PRECEDENCE Precedence,
+ LIST *ApproxUsListPt, LIST *ApproxWOListPt,
+ st_INDEX Index)
+/**************************************************************
+ INPUT: A sort theory, an unshared clause, a flag store,
+ a precedence, their index and two pointers to the
+ sort reduction subproof usable and worked off list.
+ RETURNS: TRUE iff <RedClause> is redundant with respect to
+ clauses in the index or theory.
+ EFFECT: <RedClause> is destructively changed.
+ The <DocProof> flag is changed temporarily.
+***************************************************************/
+{
+ CLAUSE Copy;
+
+#ifdef CHECK
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ Copy = (CLAUSE)NULL; /* Only needed for interface */
+
+ red_ObviousReductions(RedClause, FALSE, Flags, Precedence, &Copy);
+ red_SortSimplification(Theory, RedClause, NAT_MAX, FALSE,
+ Flags, Precedence, &Copy);
+
+ if (clause_IsEmptyClause(RedClause))
+ return FALSE;
+
+ red_Condensing(RedClause, FALSE, Flags, Precedence, &Copy);
+
+ if (red_CDForwardSubsumption(RedClause, Index, Flags, Precedence))
+ return TRUE;
+ else { /* RedClause isn't subsumed! */
+ red_CDBackSubsumption(RedClause, Flags, Precedence,
+ ApproxUsListPt, ApproxWOListPt, Index);
+ clause_InsertFlatIntoIndex(RedClause, Index);
+ *ApproxUsListPt = list_Cons(RedClause, *ApproxUsListPt);
+ }
+
+#ifdef CHECK
+ clause_Check(RedClause, Flags, Precedence);
+ if (Copy != (CLAUSE)NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_CDReduce :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+
+#endif
+
+ return FALSE;
+}
+
+
+BOOL red_ClauseDeletion(SORTTHEORY Theory, CLAUSE RedClause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A sort theory, a clause (unshared), a flag store
+ and a precedence.
+ RETURNS: TRUE iff the sort constraint of the clause is
+ unsolvable with respect to the sort theory.
+***************************************************************/
+{
+ if (Theory != (SORTTHEORY)NULL) {
+ CLAUSE ConstraintClause, GivenClause;
+ LIST ApproxUsableList, ApproxWOList, EmptyClauses, ApproxDerivables, Scan;
+ int i,nc, Count, OldClauseCounter;
+ st_INDEX Index;
+
+#ifdef CHECK
+ if (!(clause_IsClause(RedClause, Flags, Precedence))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_ClauseDeletion :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+
+ if (clause_HasEmptyConstraint(RedClause) || !flag_GetFlagValue(Flags, flag_RSST))
+ return FALSE;
+
+ if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+ fputs("\n\nStatic Soft Typing tried on: ", stdout);
+ clause_Print(RedClause);
+ }
+
+ Index = st_IndexCreate();
+ Scan = list_Nil();
+ nc = clause_NumOfConsLits(RedClause);
+ OldClauseCounter = clause_Counter();
+
+ /* Make constraint clause, insert it into the Approx-usable-list: */
+
+ for (i = clause_FirstLitIndex(); i < nc; i++)
+ Scan = list_Cons(term_Copy(clause_LiteralAtom(
+ clause_GetLiteral(RedClause, i))), Scan);
+
+ Scan = list_NReverse(Scan);
+ ConstraintClause = clause_Create(Scan, list_Nil(), list_Nil(),
+ Flags, Precedence);
+ list_Delete(Scan);
+ clause_InitSplitData(ConstraintClause);
+ clause_AddParentClause(ConstraintClause, clause_Number(RedClause));
+ clause_AddParentLiteral(ConstraintClause, clause_FirstLitIndex());
+ clause_SetFromClauseDeletion(ConstraintClause);
+ clause_InsertFlatIntoIndex(ConstraintClause, Index);
+ ApproxUsableList = list_List(ConstraintClause);
+ ApproxWOList = list_Nil();
+
+ /* fputs("\nConstraint clause: ",stdout); clause_Print(ConstraintClause); */
+
+ /* Now the lists are initialized, the subproof is started: */
+
+ EmptyClauses = list_Nil();
+ Count = 0;
+
+ if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+ puts("\n*************** Static Soft Typing Subproof: ***************");
+ puts("The usable list:");
+ clause_ListPrint(ApproxUsableList);
+ puts("\nThe worked-off list:");
+ clause_ListPrint(ApproxWOList);
+ /* fputs("\nAll indexed clauses: ", stdout);
+ clause_PrintAllIndexedClauses(ShIndex); */
+ }
+ while (!list_Empty(ApproxUsableList) && list_Empty(EmptyClauses)) {
+ GivenClause = list_Car(ApproxUsableList);
+ clause_SetFlag(GivenClause,WORKEDOFF);
+
+ if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+ fputs("\n\tSubproof Given clause: ", stdout);
+ clause_Print(GivenClause); fflush(stdout);
+ }
+ ApproxWOList = list_Cons(GivenClause, ApproxWOList);
+ ApproxUsableList = list_PointerDeleteOneElement(ApproxUsableList,GivenClause);
+ ApproxDerivables = red_CDDerivables(Theory,GivenClause, Flags, Precedence);
+ ApproxDerivables = split_ExtractEmptyClauses(ApproxDerivables, &EmptyClauses);
+
+ if (!list_Empty(EmptyClauses)) { /* Exit while loop! */
+ if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+ fputs("\nStatic Soft Typing not successful: ", stdout);
+ clause_Print(list_Car(EmptyClauses));
+ }
+ clause_DeleteClauseList(ApproxDerivables);
+ ApproxDerivables = list_Nil();
+ }
+ else {
+ CLAUSE DerClause;
+ for (Scan = ApproxDerivables; !list_Empty(Scan) && list_Empty(EmptyClauses);
+ Scan = list_Cdr(Scan)) {
+ DerClause = (CLAUSE)list_Car(Scan);
+ if (red_CDReduce(Theory, DerClause, Flags, Precedence,
+ &ApproxUsableList, &ApproxWOList, Index))
+ clause_Delete(DerClause);
+ else{
+ Count++;
+ if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+ putchar('\n');
+ clause_Print(DerClause);
+ }
+ if (clause_IsEmptyClause(DerClause))
+ EmptyClauses = list_Cons(DerClause,EmptyClauses);
+ }
+ list_Rplaca(Scan,(CLAUSE)NULL);
+ }
+
+ if (!list_Empty(EmptyClauses)) {
+ if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+ fputs(" Static Soft Typing not successful!", stdout);
+ clause_Print(list_Car(EmptyClauses));
+ }
+ clause_DeleteClauseList(ApproxDerivables); /* There still may be clauses in the list */
+ ApproxDerivables = list_Nil();
+ }
+ else {
+ list_Delete(ApproxDerivables);
+ ApproxDerivables = list_Nil();
+ }
+ }
+ }
+
+ if (!list_Empty(EmptyClauses)) {
+ if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+ puts("\nStatic Soft Typing failed, constraint solvable.");
+ puts("************ Static Soft Typing Subproof finished. ************");
+ }
+ }
+ else
+ if (flag_GetFlagValue(Flags, flag_PSST)) {
+ fputs("\nStatic Soft Typing deleted: ", stdout);
+ clause_Print(RedClause);
+ }
+
+ /* Cleanup */
+ clause_DeleteClauseListFlatFromIndex(ApproxUsableList, Index);
+ clause_DeleteClauseListFlatFromIndex(ApproxWOList, Index);
+ st_IndexDelete(Index);
+ clause_SetCounter(OldClauseCounter);
+
+ if (!list_Empty(EmptyClauses)) {
+ clause_DeleteClauseList(EmptyClauses);
+ return FALSE;
+ }
+
+ return TRUE;
+
+#ifdef CHECK
+ clause_Check(RedClause, Flags, Precedence);
+#endif
+ }
+ return FALSE;
+}
+
+LIST red_SatUnit(PROOFSEARCH Search, LIST ClauseList)
+/*********************************************************
+ INPUT: A proof search object and a list of unshared clauses.
+ RETURNS: A possibly empty list of empty clauses.
+ EFFECT: Does a shallow saturation of the conclauses depending on the
+ flag_SATUNIT flag.
+ The <DocProof> flag is considered.
+**********************************************************/
+{
+ CLAUSE Given,Clause;
+ LIST Scan, Derivables, EmptyClauses, BackReduced;
+ NAT n, Derived;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+ Derived = flag_GetFlagValue(Flags, flag_CNFPROOFSTEPS);
+ EmptyClauses = list_Nil();
+
+ ClauseList = clause_ListSortWeighed(ClauseList);
+
+ while (!list_Empty(ClauseList) && list_Empty(EmptyClauses)) {
+ Given = (CLAUSE)list_NCar(&ClauseList);
+ Given = red_ReductionOnDerivedClause(Search, Given, red_USABLE);
+ if (Given) {
+ if (clause_IsEmptyClause(Given))
+ EmptyClauses = list_List(Given);
+ else {
+ BackReduced = red_BackReduction(Search, Given, red_USABLE);
+
+ if (Derived != 0) {
+ Derivables = inf_BoundedDepthUnitResolution(Given,
+ prfs_UsableSharingIndex(Search),
+ FALSE, Flags, Precedence);
+ n = list_Length(Derivables);
+ if (n > Derived)
+ Derived = 0;
+ else
+ Derived = Derived - n;
+ }
+ else
+ Derivables = list_Nil();
+
+ Derivables = list_Nconc(BackReduced,Derivables);
+ Derivables = split_ExtractEmptyClauses(Derivables, &EmptyClauses);
+
+ prfs_InsertUsableClause(Search, Given);
+
+ for(Scan = Derivables; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ clause_SetDepth(Clause,0);
+ }
+ ClauseList = list_Nconc(ClauseList,Derivables);
+ Derivables = list_Nil();
+ }
+ }
+ }
+ for(Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ prfs_InsertUsableClause(Search, list_Car(Scan));
+ list_Delete(ClauseList);
+ return EmptyClauses;
+}
+
+static CLAUSE red_SpecialInputReductions(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/*********************************************************
+ INPUT: A clause and a flag store.
+ RETURNS: The clause where the logical constants TRUE, FALSE
+ are removed.
+ EFFECT: The clause is destructively changed.
+**********************************************************/
+{
+ int i,end;
+ LIST Indexes;
+ TERM Atom;
+
+#ifdef CHECK
+ clause_Check(Clause, Flags, Precedence);
+#endif
+
+ Indexes = list_Nil();
+ end = clause_LastAntecedentLitIndex(Clause);
+
+ for (i = clause_FirstConstraintLitIndex(Clause); i <= end; i++) {
+ Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+ if (fol_IsTrue(Atom))
+ Indexes = list_Cons((POINTER)i,Indexes);
+ }
+
+ end = clause_LastSuccedentLitIndex(Clause);
+
+ for (i = clause_FirstSuccedentLitIndex(Clause); i <= end; i++) {
+ Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+ if (fol_IsFalse(Atom))
+ Indexes = list_Cons((POINTER)i,Indexes);
+ }
+
+ clause_DeleteLiterals(Clause,Indexes, Flags, Precedence);
+ list_Delete(Indexes);
+
+ return Clause;
+}
+
+
+LIST red_ReduceInput(PROOFSEARCH Search, LIST ClauseList)
+/*********************************************************
+ INPUT: A proof search object and a list of unshared clauses.
+ RETURNS: A list of empty clauses.
+ EFFECT: Interreduces the clause list and inserts the clauses into <Search>.
+ Keeps track of derived and kept clauses.
+ Time limits and the DocProof flag are considered.
+**********************************************************/
+{
+ CLAUSE Given;
+ LIST Scan, EmptyClauses, BackReduced;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+ EmptyClauses = list_Nil();
+ ClauseList = clause_ListSortWeighed(list_Copy(ClauseList));
+ ClauseList = split_ExtractEmptyClauses(ClauseList, &EmptyClauses);
+
+ while (!list_Empty(ClauseList) && list_Empty(EmptyClauses) &&
+ (flag_GetFlagValue(Flags,flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED ||
+ flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) {
+ Given = (CLAUSE)list_NCar(&ClauseList);
+#ifdef CHECK
+ if (!clause_IsClause(Given, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_ReduceInput :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+ Given = red_SpecialInputReductions(Given, Flags, Precedence);
+ Given = red_ReductionOnDerivedClause(Search, Given, red_USABLE);
+ if (Given) {
+ prfs_IncKeptClauses(Search);
+ if (clause_IsEmptyClause(Given))
+ EmptyClauses = list_List(Given);
+ else {
+ BackReduced = red_BackReduction(Search, Given, red_USABLE);
+ prfs_IncDerivedClauses(Search, list_Length(BackReduced));
+ BackReduced = split_ExtractEmptyClauses(BackReduced, &EmptyClauses);
+ prfs_InsertUsableClause(Search, Given);
+ BackReduced = clause_ListSortWeighed(BackReduced);
+ ClauseList = red_MergeClauseListsByWeight(ClauseList, BackReduced);
+ }
+ }
+ }
+ for(Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ prfs_InsertUsableClause(Search, list_Car(Scan));
+ list_Delete(ClauseList);
+ return EmptyClauses;
+}
+
+
+LIST red_SatInput(PROOFSEARCH Search)
+/*********************************************************
+ INPUT: A proof search object.
+ RETURNS: A list of derived empty clauses.
+ EFFECT: Does a saturation from the conjectures into the axioms/conjectures
+ Keeps track of derived and kept clauses. Keeps track of a possible
+ time limit.
+ Considers the Usable clauses in <Search> and a possible time limit.
+**********************************************************/
+{
+ CLAUSE Given;
+ LIST Scan, ClauseList, Derivables, EmptyClauses;
+ int n;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ EmptyClauses = list_Nil();
+ ClauseList = list_Nil();
+ Scan = prfs_UsableClauses(Search);
+ n = list_Length(Scan);
+
+ while(!list_Empty(Scan) &&
+ n > 0 &&
+ (flag_GetFlagValue(Flags,flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED ||
+ flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) {
+ Given = (CLAUSE)list_Car(Scan);
+ if (clause_GetFlag(Given,CONCLAUSE)) {
+ Derivables = inf_BoundedDepthUnitResolution(Given,
+ prfs_UsableSharingIndex(Search),
+ FALSE, Flags, Precedence);
+ n -= list_Length(Derivables);
+ ClauseList = list_Nconc(Derivables,ClauseList);
+ }
+ Scan = list_Cdr(Scan);
+ }
+
+ prfs_IncDerivedClauses(Search, list_Length(ClauseList));
+ EmptyClauses = red_ReduceInput(Search, ClauseList);
+ list_Delete(ClauseList);
+ ClauseList = list_Nil();
+ if (list_Empty(EmptyClauses)) {
+ Scan=prfs_UsableClauses(Search);
+ while (!list_Empty(Scan) &&
+ n > 0 &&
+ (flag_GetFlagValue(Flags,flag_TIMELIMIT)==flag_TIMELIMITUNLIMITED ||
+ flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) {
+ Given = (CLAUSE)list_Car(Scan);
+ if (clause_GetFlag(Given,CONCLAUSE) && clause_IsFromInput(Given)) {
+ Derivables = inf_BoundedDepthUnitResolution(Given,
+ prfs_UsableSharingIndex(Search),
+ TRUE, Flags, Precedence);
+ n -= list_Length(Derivables);
+ ClauseList = list_Nconc(Derivables,ClauseList);
+ }
+ Scan = list_Cdr(Scan);
+ }
+ prfs_IncDerivedClauses(Search, list_Length(ClauseList));
+ EmptyClauses = red_ReduceInput(Search, ClauseList);
+ list_Delete(ClauseList);
+ }
+ return EmptyClauses;
+}
+
+void red_CheckSplitSubsumptionCondition(PROOFSEARCH Search)
+/*********************************************************
+ INPUT: A proof search object.
+ EFFECT: For all deleted clauses in the split stack, it
+ is checked whether they are subsumed by some
+ existing clause. If they are not, a core is dumped.
+ Used for debugging.
+**********************************************************/
+{
+ LIST Scan1,Scan2;
+ CLAUSE Clause;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ for (Scan1=prfs_SplitStack(Search);!list_Empty(Scan1);Scan1=list_Cdr(Scan1))
+ for (Scan2=prfs_SplitDeletedClauses(list_Car(Scan1));!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) {
+ Clause = (CLAUSE)list_Car(Scan2);
+ if (!red_ForwardSubsumer(Clause, prfs_WorkedOffSharingIndex(Search),
+ Flags, Precedence) &&
+ !red_ForwardSubsumer(Clause, prfs_UsableSharingIndex(Search),
+ Flags, Precedence) &&
+ !red_ClauseDeletion(prfs_StaticSortTheory(Search),Clause,
+ Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_CheckSplitSubsumptionCondition: No clause found implying ");
+ clause_Print(Clause);
+ misc_ErrorReport("\n Current Split: ");
+ prfs_PrintSplit(list_Car(Scan1));
+ misc_FinishErrorReport();
+ }
+ }
+}
diff --git a/test/spass/rules-red.h b/test/spass/rules-red.h
new file mode 100644
index 0000000..2775ab2
--- /dev/null
+++ b/test/spass/rules-red.h
@@ -0,0 +1,111 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * REDUCTION RULES * */
+/* * * */
+/* * $Module: REDRULES * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _REDRULES_
+#define _REDRULES_
+
+#include "sort.h"
+#include "subsumption.h"
+#include "condensing.h"
+#include "search.h"
+#include "rules-split.h"
+#include "rules-inf.h"
+#include "doc-proof.h"
+#include "clock.h"
+#include "closure.h"
+
+/**************************************************************/
+/* Constants */
+/**************************************************************/
+
+extern const NAT red_USABLE;
+extern const NAT red_WORKEDOFF;
+extern const NAT red_ALL;
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+static __inline__ BOOL red_WorkedOffMode(NAT Mode)
+{
+ return (Mode == red_WORKEDOFF || Mode == red_ALL);
+}
+
+static __inline__ BOOL red_OnlyWorkedOffMode(NAT Mode)
+{
+ return (Mode == red_WORKEDOFF);
+}
+
+static __inline__ BOOL red_UsableMode(NAT Mode)
+{
+ return (Mode == red_USABLE || Mode == red_ALL);
+}
+
+static __inline__ BOOL red_AllMode(NAT Mode)
+{
+ return (Mode == red_ALL);
+}
+
+
+void red_Init(void);
+
+
+LIST red_CompleteReductionOnDerivedClauses(PROOFSEARCH, LIST, NAT, int, NAT, int*);
+CLAUSE red_ReductionOnDerivedClause(PROOFSEARCH, CLAUSE, NAT);
+CLAUSE red_CompleteReductionOnDerivedClause(PROOFSEARCH, CLAUSE, NAT);
+LIST red_BackReduction(PROOFSEARCH, CLAUSE, NAT);
+LIST red_SatUnit(PROOFSEARCH, LIST);
+LIST red_SatInput(PROOFSEARCH);
+LIST red_ReduceInput(PROOFSEARCH, LIST);
+BOOL red_ClauseDeletion(SORTTHEORY, CLAUSE, FLAGSTORE, PRECEDENCE);
+
+
+void red_CheckSplitSubsumptionCondition(PROOFSEARCH);
+
+
+#endif
diff --git a/test/spass/rules-sort.c b/test/spass/rules-sort.c
new file mode 100644
index 0000000..74f8c9f
--- /dev/null
+++ b/test/spass/rules-sort.c
@@ -0,0 +1,1763 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INFERENCE RULES FOR SORTS * */
+/* * * */
+/* * $Module: SORTRULES * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "rules-sort.h"
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+static LIST inf_GetForwardPartnerLits(LITERAL, st_INDEX);
+static SORT inf_GetSortFromLits(LIST, SORTTHEORY);
+
+
+static BOOL inf_SubsortPrecheck(CLAUSE Clause, LIST TLits, LITERAL Special,
+ st_INDEX Index, SORTTHEORY SortTheory)
+/**************************************************************
+ INPUT: A clause, a list of constraint literal indices in
+ that clause, a special literal, an index of clauses,
+ and the actual sort theory.
+ RETURNS: TRUE, if there exists any subsort of the <TLits> sort.
+***************************************************************/
+{
+ SORT tSort, unifierSort;
+ LIST unifiers;
+ BOOL result;
+
+ unifiers = inf_GetForwardPartnerLits(clause_GetLiteral(Clause,(int)list_Car(TLits)),
+ Index);
+ unifierSort = inf_GetSortFromLits(unifiers, SortTheory);
+ list_Delete(unifiers);
+
+ tSort = sort_TopSort();
+ for (; !list_Empty(TLits); TLits = list_Cdr(TLits)) {
+ TERM actAtom = clause_GetLiteralAtom(Clause, (int)list_Car(TLits));
+ tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)),
+ tSort);
+ }
+ tSort = list_PointerDeleteDuplicates(tSort);
+
+ if (Special == NULL)
+ result = sort_TheoryIsSubsortOf(SortTheory, unifierSort, tSort);
+ else {
+ SORT extraSort;
+ extraSort = sort_TheorySortOfSymbol(SortTheory, clause_LiteralPredicate(Special));
+ result = sort_TheoryIsSubsortOfExtra(SortTheory, extraSort, unifierSort, tSort);
+ sort_Delete(extraSort);
+ }
+
+ sort_Delete(tSort);
+ sort_Delete(unifierSort);
+
+ return result;
+}
+
+static LIST inf_GetSortResolutionPartnerLits(TERM Atom, st_INDEX Index)
+/**************************************************************
+ INPUT: A clause, and an Index of clauses.
+ RETURNS: A list of literals with which sortresolution is possible.
+ MEMORY: Allocates memory for the list.
+***************************************************************/
+{
+ LIST Result, TermList, LitScan;
+ LITERAL NextLit;
+ CLAUSE Clause;
+
+#ifdef CHECK
+ if (!term_IsAtom(Atom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GetSortResolutionPartnerLits: Variable as atom input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+ TermList = st_GetUnifier(cont_LeftContext(), Index, cont_RightContext(), Atom);
+
+ for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+
+ if (term_IsAtom(list_Car(TermList))) {
+
+ for (LitScan = sharing_NAtomDataList(list_Car(TermList));
+ !list_Empty(LitScan);
+ LitScan = list_Cdr(LitScan)){
+ NextLit = list_Car(LitScan);
+ Clause = clause_LiteralOwningClause(NextLit);
+
+ if (clause_LiteralIsPositive(NextLit) &&
+ clause_LiteralGetFlag(NextLit,STRICTMAXIMAL) &&
+ clause_GetFlag(Clause, WORKEDOFF) &&
+ clause_HasSolvedConstraint(Clause) &&
+ !list_PointerMember(Result, NextLit))
+ Result = list_Cons(NextLit, Result);
+ }
+ }
+ }
+
+ return Result;
+}
+
+
+static CLAUSE inf_BuildConstraintHyperResolvent(CLAUSE Clause, LIST Lits,
+ SUBST Subst, LIST Foundlits,
+ FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A <Clause> where the sort constraint is resolved,
+ a list <Lits> of constraint indices in <Clause> where
+ all corresponding constraints have the same term,
+ the overall substitution <Subst>,
+ a list <Foundlits> of literals of found partner clauses,
+ a flag store and a precedence.
+ RETURNS: A clause, the resolvent of a resolution step.
+***************************************************************/
+{
+ CLAUSE NewClause, ClauseCopy;
+ LIST Constraint, Antecedent, Succedent, ParentCls, ParentLits, Scan;
+ TERM Atom;
+ SYMBOL MaxVar,MaxCand;
+ int i,bound, depth;
+ BOOL IsFromEmptySort;
+ LIST Partners;
+
+ ParentCls = list_Nil();
+ ParentLits = list_Nil();
+ Constraint = list_Nil();
+ Antecedent = list_Nil();
+ Succedent = list_Nil();
+ Partners = list_Nil();
+ depth = clause_Depth(Clause);
+
+ for (Scan=Foundlits; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ depth = misc_Max(depth,
+ clause_Depth(clause_LiteralOwningClause(list_Car(Scan))));
+
+ ClauseCopy = clause_Copy(Clause);
+ Partners = list_Cons(ClauseCopy, Partners);
+ clause_SubstApply(Subst, ClauseCopy);
+
+ IsFromEmptySort = term_IsVariable(term_FirstArgument(
+ clause_GetLiteralAtom(Clause, (int)list_Car(Lits))));
+
+ bound = clause_LastConstraintLitIndex(ClauseCopy);
+
+ for (i = clause_FirstLitIndex(); i <= bound; i++)
+ if (!list_PointerMember(Lits, (POINTER)i)) {
+ Atom = term_Copy(clause_GetLiteralAtom(ClauseCopy, i));
+ Constraint = list_Cons(Atom, Constraint);
+ }
+ else {
+ ParentCls = list_Cons((POINTER)clause_Number(ClauseCopy), ParentCls);
+ ParentLits = list_Cons((POINTER)i, ParentLits);
+ }
+
+ bound = clause_LastAntecedentLitIndex(ClauseCopy);
+ for ( ; i <= bound; i++) {
+ Atom = term_Copy(clause_GetLiteralAtom(ClauseCopy, i));
+ Antecedent = list_Cons(Atom, Antecedent);
+ }
+ bound = clause_LastSuccedentLitIndex(ClauseCopy);
+ for (; i <= bound; i++) {
+ Atom = term_Copy(clause_GetLiteralAtom(ClauseCopy, i));
+ Succedent = list_Cons(Atom, Succedent);
+ }
+ bound = clause_LastConstraintLitIndex(Clause);
+ for (i = clause_FirstLitIndex(); i <= bound; i++) {
+ /* Hier sollen die gematchten Constraintliterale dazu fuehren, dass die */
+ /* c,a und s- literale der Partnerclauses in die Listen kommen... */
+
+ if (list_PointerMember(Lits, (POINTER)i)) {
+ CLAUSE PartnerCopy;
+ LITERAL PLit;
+ TERM PAtom;
+ SUBST NewSubst,RightSubst;
+ int j,lc,la,n,PLitInd;
+
+ Atom = clause_GetLiteralAtom(ClauseCopy, i);
+ NewClause = clause_CreateUnnormalized(Constraint, Antecedent, Succedent);
+
+ list_Delete(Constraint);
+ list_Delete(Antecedent);
+ list_Delete(Succedent);
+ Constraint = list_Nil();
+ Antecedent = list_Nil();
+ Succedent = list_Nil();
+
+ /* Find corresponding Foundlit: */
+ for (Scan = Foundlits;
+ term_TopSymbol(Atom) !=
+ term_TopSymbol(clause_LiteralAtom(list_Car(Scan)));
+ Scan = list_Cdr(Scan));
+ PLit = list_Car(Scan);
+ PLitInd = clause_LiteralGetIndex(PLit);
+ PartnerCopy = clause_Copy(clause_LiteralOwningClause(PLit));
+ Partners = list_Cons(PartnerCopy, Partners);
+ ParentCls = list_Cons((POINTER)clause_Number(PartnerCopy), ParentCls);
+ ParentLits = list_Cons((POINTER)PLitInd, ParentLits);
+ MaxVar = clause_SearchMaxVar(ClauseCopy);
+ MaxCand = clause_SearchMaxVar(NewClause);
+ MaxVar = ((MaxVar > MaxCand) ? MaxVar : MaxCand);
+ /* MaxVar is the maximal variable in the new clause or the ClauseCopy, */
+ /* the latter to guarantee the stability of variable names. */
+
+ clause_RenameVarsBiggerThan(PartnerCopy, MaxVar);
+ PLit = clause_GetLiteral(PartnerCopy, PLitInd);
+ PAtom = clause_LiteralAtom(PLit);
+
+ cont_Check();
+ if (!unify_UnifyNoOC(cont_LeftContext(), PAtom, cont_RightContext(), Atom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_BuildConstraintHyperResolvent: Unification failed.");
+ misc_FinishErrorReport();
+ }
+ subst_ExtractUnifier(cont_LeftContext(), &RightSubst, cont_RightContext(), &NewSubst);
+ cont_Reset();
+
+ clause_SubstApply(NewSubst, NewClause);
+ clause_SubstApply(NewSubst, ClauseCopy);
+ subst_Delete(NewSubst);
+
+ n = clause_Length(PartnerCopy);
+ lc = clause_LastConstraintLitIndex(PartnerCopy);
+ la = clause_LastAntecedentLitIndex(PartnerCopy);
+ for (j = clause_FirstLitIndex(); j < n; j++) {
+ if (j <= lc)
+ Constraint = list_Cons(subst_Apply(RightSubst,
+ term_Copy(clause_GetLiteralAtom(PartnerCopy, j))),
+ Constraint);
+ else if (j <= la)
+ Antecedent = list_Cons(subst_Apply(RightSubst,
+ term_Copy(clause_GetLiteralAtom(PartnerCopy, j))),
+ Antecedent);
+ else if (j != PLitInd)
+ Succedent = list_Cons(subst_Apply(RightSubst,
+ term_Copy(clause_GetLiteralAtom(PartnerCopy, j))),
+ Succedent);
+ }
+
+ subst_Delete(RightSubst);
+
+ n = clause_Length(NewClause);
+ lc = clause_LastConstraintLitIndex(NewClause);
+ la = clause_LastAntecedentLitIndex(NewClause);
+
+ for (j = clause_FirstLitIndex(); j < n; j++) {
+ if (j <= lc)
+ Constraint = list_Cons(term_Copy(clause_GetLiteralAtom(NewClause, j)),
+ Constraint);
+ else if (j <= la)
+ Antecedent = list_Cons(term_Copy(clause_GetLiteralAtom(NewClause, j)),
+ Antecedent);
+ else
+ Succedent = list_Cons(term_Copy(clause_GetLiteralAtom(NewClause, j)),
+ Succedent);
+ }
+ clause_Delete(NewClause);
+ clause_DecreaseCounter();
+ }
+ }
+ NewClause = clause_Create(Constraint, Antecedent, Succedent, Flags,Precedence);
+
+ list_Delete(Constraint);
+ list_Delete(Antecedent);
+ list_Delete(Succedent);
+
+ if (IsFromEmptySort)
+ clause_SetFromEmptySort(NewClause);
+ else
+ clause_SetFromSortResolution(NewClause);
+
+ clause_SetDepth(NewClause, depth + 1);
+
+ clause_SetSplitDataFromList(NewClause, Partners);
+ clause_DeleteClauseList(Partners);
+
+ clause_SetParentClauses(NewClause, list_NReverse(ParentCls));
+ clause_SetParentLiterals(NewClause, list_NReverse(ParentLits));
+
+ return NewClause;
+}
+
+
+static LIST inf_ConstraintHyperResolvents(CLAUSE Clause, LIST Lits,
+ SUBST Subst, LIST Restlits,
+ LIST Foundlits, st_INDEX Index,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A <Clause> where the sort constraint is resolved,
+ a list <Lits> of constraint indices in <Clause> where
+ all corresponding constraints have the same term,
+ the overall substitution <Subst>,
+ a list <Restlits> of constraint indeces for which
+ a partner clause is searched with respect to <Index>,
+ a list <Foundlits> of literals of already found partner clauses,
+ a flag store and a precedence.
+ RETURNS: The list of possible resolvents.
+***************************************************************/
+{
+ if (list_Empty(Restlits))
+ return list_List(inf_BuildConstraintHyperResolvent(Clause,Lits,Subst,
+ Foundlits, Flags,
+ Precedence));
+ else {
+ CLAUSE PartnerCopy;
+ LITERAL Lit, PLit;
+ LIST Result, NextLits;
+ TERM AtomCopy;
+ SUBST NewSubst, RightSubst, HelpSubst;
+ SYMBOL MaxVar, MaxCand;
+ int PLitInd;
+
+ Result = list_Nil();
+ Lit = clause_GetLiteral(Clause, (int) list_Car(Restlits));
+ AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit)));
+ NextLits = inf_GetSortResolutionPartnerLits(AtomCopy,Index);
+ MaxVar = clause_MaxVar(Clause);
+ MaxCand = clause_AtomMaxVar(AtomCopy);
+ MaxVar = (symbol_GreaterVariable(MaxVar, MaxCand) ? MaxVar : MaxCand);
+
+ for ( ; !list_Empty(NextLits); NextLits = list_Pop(NextLits)) {
+ PLit = list_Car(NextLits);
+ PLitInd = clause_LiteralGetIndex(PLit);
+ Foundlits = list_Cons(PLit, Foundlits);
+ PartnerCopy = clause_Copy(clause_LiteralOwningClause(PLit));
+
+ clause_RenameVarsBiggerThan(PartnerCopy, MaxVar);
+ PLit = clause_GetLiteral(PartnerCopy, PLitInd);
+
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), AtomCopy,
+ cont_RightContext(), clause_LiteralAtom(PLit));
+ subst_ExtractUnifier(cont_LeftContext(), &NewSubst, cont_RightContext(), &RightSubst);
+ cont_Reset();
+
+ subst_Delete(RightSubst);
+ HelpSubst = NewSubst;
+ NewSubst = subst_Compose(NewSubst, subst_Copy(Subst));
+
+ Result = list_Nconc(inf_ConstraintHyperResolvents(Clause, Lits, NewSubst,
+ list_Cdr(Restlits),
+ Foundlits, Index, Flags,
+ Precedence),
+ Result);
+ subst_Delete(NewSubst);
+ subst_Delete(HelpSubst);
+ clause_Delete(PartnerCopy);
+
+ Foundlits = list_Pop(Foundlits);
+ }
+ term_Delete(AtomCopy);
+
+ return Result;
+ }
+}
+
+
+LIST inf_BackwardSortResolution(CLAUSE GivenClause, st_INDEX Index,
+ SORTTHEORY SortTheory, BOOL Precheck,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause with a solved sort constraint, an index of clauses,
+ a sort theory, a boolean flag indicating whether the subsort
+ precheck can be applied, a flag store and a precedence.
+ RETURNS: A list of clauses inferred from the GivenClause by
+ SortResolution with the given clause.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST result;
+ int i, ls;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence) ||
+ !clause_HasSolvedConstraint(GivenClause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_BackwardSortResolution: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = list_Nil();
+ ls = clause_LastSuccedentLitIndex(GivenClause);
+
+ for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) {
+ LITERAL pLit;
+ TERM pAtom;
+
+ pLit = clause_GetLiteral(GivenClause, i);
+ pAtom = clause_LiteralAtom(pLit);
+
+ if (clause_LiteralGetFlag(pLit,STRICTMAXIMAL) &&
+ clause_LiteralIsSort(pLit)) {
+ LIST termList;
+ termList = st_GetUnifier(cont_LeftContext(),Index,cont_RightContext(),pAtom);
+
+ for ( ; !list_Empty(termList); termList = list_Pop(termList)){
+ if (term_IsAtom(list_Car(termList)) &&
+ !term_IsVariable(term_FirstArgument(list_Car(termList)))) {
+
+ LIST litScan;
+ litScan = sharing_NAtomDataList(list_Car(termList));
+ for ( ; !list_Empty(litScan); litScan = list_Cdr(litScan)) {
+ LITERAL gLit;
+ CLAUSE gClause;
+ gLit = list_Car(litScan);
+ gClause = clause_LiteralOwningClause(gLit);
+ if (clause_LiteralGetIndex(gLit) < clause_FirstAntecedentLitIndex(gClause) &&
+ clause_GetFlag(gClause,WORKEDOFF)) {
+ TERM gAtom;
+ int lc, gi, j;
+ LIST tLits, restLits;
+ gAtom = clause_LiteralAtom(gLit);
+ lc = clause_LastConstraintLitIndex(gClause);
+ gi = clause_LiteralGetIndex(gLit);
+ tLits = list_List((POINTER)gi);
+ restLits = list_Nil();
+ for (j = clause_FirstLitIndex(); j <= lc; j++) {
+ LITERAL tCand;
+ tCand = clause_GetLiteral(gClause, j);
+ if (j != gi &&
+ term_FirstArgument(clause_LiteralAtom(tCand))
+ == term_FirstArgument(gAtom)) {
+ tLits = list_Cons((POINTER)j, tLits);
+ restLits = list_Cons((POINTER)j, restLits);
+ }
+ }
+
+ if (!Precheck ||
+ inf_SubsortPrecheck(gClause,tLits,pLit,Index,SortTheory)) {
+ CLAUSE pClauseCopy;
+ SYMBOL minVar;
+ LIST foundLits;
+ SUBST leftSubst, rightSubst;
+ pClauseCopy = clause_Copy(GivenClause);
+ minVar = clause_MaxVar(gClause);
+ foundLits = list_List(pLit);
+
+ clause_RenameVarsBiggerThan(pClauseCopy, minVar);
+ pAtom = clause_GetLiteralAtom(pClauseCopy, i);
+ /* set, to unify correctly! */
+
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), gAtom, cont_RightContext(), pAtom);
+ subst_ExtractUnifier(cont_LeftContext(), &leftSubst,
+ cont_RightContext(), &rightSubst);
+ cont_Reset();
+
+ subst_Delete(rightSubst);
+
+ result =
+ list_Nconc(inf_ConstraintHyperResolvents(gClause, tLits,
+ leftSubst, restLits,
+ foundLits, Index,
+ Flags, Precedence),
+ result);
+
+ pAtom = clause_LiteralAtom(pLit);
+
+ subst_Delete(leftSubst);
+ list_Delete(foundLits);
+ clause_Delete(pClauseCopy);
+ } /* if Precheck */
+ list_Delete(tLits);
+ list_Delete(restLits);
+ }
+ }
+ }
+ }
+ }
+ }
+ return result;
+}
+
+
+LIST inf_ForwardSortResolution(CLAUSE GivenClause, st_INDEX Index,
+ SORTTHEORY SortTheory, BOOL Precheck,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause with an unsolved sort constraint, an index of clauses,
+ a sort theory, a boolean flag indicating whether the subsort
+ precheck can be applied, a flag store and a precedence.
+ RETURNS: A list of clauses inferred from the GivenClause by
+ SortResolution on the given clause.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result, TLits, RestLits;
+ int i, j, lc;
+ BOOL Hit;
+ TERM TAtom;
+
+#ifdef CHECK
+ if (!clause_IsClause(GivenClause, Flags, Precedence) ||
+ !clause_HasTermSortConstraintLits(GivenClause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_ForwardSortResolution: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+ lc = clause_LastConstraintLitIndex(GivenClause);
+ Hit = FALSE;
+
+ i = clause_FirstLitIndex();
+ while (i <= lc && !Hit) {
+ TAtom = clause_GetLiteralAtom(GivenClause, i);
+ if (!term_IsVariable(term_FirstArgument(TAtom)))
+ Hit = TRUE;
+ else
+ i++;
+ }
+
+ if (!Hit)
+ return list_Nil();
+
+ /* added because of compiler warnings */
+ TAtom = clause_GetLiteralAtom(GivenClause, i);
+
+ /* Search the other T_i from <GivenClause> */
+ TLits = list_List((POINTER)i);
+ for (j = i+1; j <= lc; j++) {
+ if (term_FirstArgument(clause_GetLiteralAtom(GivenClause, j))
+ == term_FirstArgument(TAtom))
+ TLits = list_Cons((POINTER)j, TLits);
+ }
+ RestLits = list_Copy(TLits);
+
+ if (!Precheck ||
+ inf_SubsortPrecheck(GivenClause, TLits, NULL, Index, SortTheory)) {
+
+ Result = inf_ConstraintHyperResolvents(GivenClause, TLits, subst_Nil(),
+ RestLits, list_Nil(), Index, Flags,
+ Precedence);
+
+ }
+ list_Delete(RestLits);
+ list_Delete(TLits);
+
+ return Result;
+}
+
+
+LIST inf_BackwardEmptySort(CLAUSE GivenClause, st_INDEX Index,
+ SORTTHEORY SortTheory, BOOL Precheck,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause with a solved sort constraint, an 'Index' of clauses,
+ a sort theory, a boolean flag indicating whether the subsort
+ precheck can be applied, a flag store and a precedence.
+ RETURNS: A list of clauses inferred from the GivenClause by
+ EmptySort with the given clause.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST result;
+ int i, ls;
+
+#ifdef CHECK
+ if (!(clause_IsClause(GivenClause, Flags, Precedence)) ||
+ !clause_HasSolvedConstraint(GivenClause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_BackwardEmptySort: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = list_Nil();
+
+ ls = clause_LastSuccedentLitIndex(GivenClause);
+
+ for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) {
+ LITERAL pLit = clause_GetLiteral(GivenClause, i);
+ TERM pAtom = clause_LiteralAtom(pLit);
+
+ if (clause_LiteralGetFlag(pLit,STRICTMAXIMAL) &&
+ clause_LiteralIsSort(pLit)) {
+ LIST unifiers = st_GetUnifier(cont_LeftContext(),Index,cont_RightContext(),pAtom);
+
+ for ( ; !list_Empty(unifiers); unifiers = list_Pop(unifiers)){
+ if (term_IsAtom(list_Car(unifiers)) &&
+ term_IsVariable(term_FirstArgument(list_Car(unifiers)))) {
+ LIST litScan = sharing_NAtomDataList(list_Car(unifiers));
+
+ for ( ; !list_Empty(litScan); litScan = list_Cdr(litScan)){
+ LITERAL gLit = list_Car(litScan);
+ CLAUSE gClause = clause_LiteralOwningClause(gLit);
+
+ if (clause_LiteralGetIndex(gLit) < clause_FirstAntecedentLitIndex(gClause) &&
+ clause_GetFlag(gClause,WORKEDOFF) &&
+ clause_HasOnlyVarsInConstraint(gClause, Flags, Precedence)) {
+ TERM gAtom = clause_LiteralAtom(gLit);
+ SYMBOL var = term_TopSymbol(term_FirstArgument(gAtom));
+ int lc = clause_LastConstraintLitIndex(gClause);
+ int gi = clause_LiteralGetIndex(gLit);
+ BOOL varOccursNoMore;
+ int j, bound;
+
+ varOccursNoMore = TRUE;
+ bound = clause_LastSuccedentLitIndex(gClause);
+
+ for (j = clause_FirstAntecedentLitIndex(gClause);
+ (j <= bound) && varOccursNoMore;
+ j++) {
+ if (term_ContainsSymbol(clause_GetLiteralAtom(gClause, j), var))
+ varOccursNoMore = FALSE;
+ }
+
+ if (varOccursNoMore) {
+ LIST tLits, restLits;
+
+ /* Search the other T_i from <gClause> */
+ tLits = list_List((POINTER)gi);
+ restLits = list_Nil();
+ for (j = clause_FirstLitIndex(); j <= lc; j++) {
+ LITERAL tCand = clause_GetLiteral(gClause, j);
+
+ if (j != gi &&
+ term_FirstArgument(clause_LiteralAtom(tCand))
+ == term_FirstArgument(gAtom)) {
+ tLits = list_Cons((POINTER)j, tLits);
+ restLits = list_Cons((POINTER)j, restLits);
+ }
+ }
+
+ if (!Precheck ||
+ inf_SubsortPrecheck(gClause,tLits,pLit,Index,SortTheory)) {
+ CLAUSE pCopy = clause_Copy(GivenClause);
+ SYMBOL minVar = clause_MaxVar(gClause);
+ LIST foundLits = list_List(pLit);
+ SUBST leftSubst, rightSubst;
+
+ clause_RenameVarsBiggerThan(pCopy, minVar);
+ pAtom = clause_GetLiteralAtom(pCopy, i);
+ /* set, to adress the renamed term! */
+
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), gAtom, cont_RightContext(), pAtom);
+ subst_ExtractUnifier(cont_LeftContext(), &leftSubst,
+ cont_RightContext(), &rightSubst);
+ cont_Reset();
+
+ subst_Delete(rightSubst);
+
+ result =
+ list_Nconc(inf_ConstraintHyperResolvents(gClause, tLits,
+ leftSubst,restLits,
+ foundLits, Index,
+ Flags, Precedence),
+ result);
+
+ list_Delete(foundLits);
+ subst_Delete(leftSubst);
+ clause_Delete(pCopy);
+
+ pAtom = clause_LiteralAtom(pLit);
+ /* reset to original clauses literal! */
+ } /* if Precheck */
+ list_Delete(tLits);
+ list_Delete(restLits);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return result;
+}
+
+
+LIST inf_ForwardEmptySort(CLAUSE GivenClause, st_INDEX Index,
+ SORTTHEORY SortTheory, BOOL Precheck, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, an index of clauses, a sort theory,
+ a boolean flag indicating whether the subsort
+ precheck can be applied, a flag store and a precedence.
+ The constraint of <GivenClause> is necessarily unsolved
+ RETURNS: A list of clauses inferred from the GivenClause by
+ EmptySort on the given clause.
+ MEMORY: A list of clauses is produced, where memory for the list
+ and the clauses is allocated.
+***************************************************************/
+{
+ LIST Result, TLits, RestLits;
+ int i, j, lc, ls;
+ BOOL Hit;
+ TERM TAtom;
+ SYMBOL Var;
+
+#ifdef CHECK
+ if (clause_HasTermSortConstraintLits(GivenClause) ||
+ clause_HasSolvedConstraint(GivenClause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_ForwardEmptySort: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+ lc = clause_LastConstraintLitIndex(GivenClause);
+ Hit = FALSE;
+
+ i = clause_FirstLitIndex();
+ while (i <= lc && !Hit) {
+ TAtom = clause_GetLiteralAtom(GivenClause, i);
+
+ if (term_IsVariable(term_FirstArgument(TAtom))) {
+ Var = term_TopSymbol(term_FirstArgument(TAtom));
+ ls = clause_LastSuccedentLitIndex(GivenClause);
+ Hit = TRUE;
+ /* Check if the variable occurs in antecedent or succedent literals */
+ for (j = clause_FirstAntecedentLitIndex(GivenClause);
+ j <= ls && Hit; j++) {
+ if (term_ContainsSymbol(clause_GetLiteralAtom(GivenClause,j), Var))
+ Hit = FALSE; /* Variable occurs in antecedent/constraint literal */
+ }
+ }
+ if (!Hit)
+ i++;
+ }
+
+ if (!Hit)
+ return list_Nil();
+
+ TAtom = clause_GetLiteralAtom(GivenClause, i);
+ Var = term_TopSymbol(term_FirstArgument(TAtom));
+
+ /* Search the other T_i(t) literals */
+ TLits = list_List((POINTER)i);
+ for (j = i+1; j <= lc; j++) {
+ TERM TCand;
+
+ TCand = clause_GetLiteralAtom(GivenClause, j);
+
+ if (symbol_Equal(term_TopSymbol(term_FirstArgument(TCand)), Var))
+ TLits = list_Cons((POINTER)j, TLits);
+ }
+ RestLits = list_Copy(TLits);
+
+ if (!Precheck ||
+ inf_SubsortPrecheck(GivenClause, TLits, NULL, Index, SortTheory)) {
+
+ Result = inf_ConstraintHyperResolvents(GivenClause, TLits, subst_Nil(),
+ RestLits, list_Nil(), Index, Flags,
+ Precedence);
+
+ }
+ list_Delete(RestLits);
+ list_Delete(TLits);
+
+ return Result;
+}
+
+static LIST inf_GetForwardPartnerLits(LITERAL Literal, st_INDEX Index)
+/**************************************************************
+ INPUT: A monadic literal, and an index of clauses.
+ RETURNS: A list of monadic succedent literals whose subterm
+ is unifiable with the (one) subterm of <Literal>.
+ The literals are strict maximal in their respective clauses,
+ the clauses are "WORKEDOFF" and either the subterm
+ is not a variable or the clause has an empty constraint.
+ MEMORY: Allocates memory for the list.
+***************************************************************/
+{
+ LIST result, unifiers, atomScan, litScan;
+
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Literal) || !clause_LiteralIsSort(Literal)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GetForwardPartnerLits: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = list_Nil();
+ /* Search unifiers for the literal's subterm */
+ unifiers = st_GetUnifier(cont_LeftContext(), Index, cont_RightContext(),
+ term_FirstArgument(clause_LiteralAtom(Literal)));
+
+ for ( ; !list_Empty(unifiers); unifiers = list_Pop(unifiers)) {
+
+ if (!term_IsAtom(list_Car(unifiers))) { /* Can happen if arg is variable */
+
+ for (atomScan = term_SupertermList(list_Car(unifiers));
+ !list_Empty(atomScan);
+ atomScan = list_Cdr(atomScan)) {
+ TERM atomCand;
+ atomCand = (TERM) list_Car(atomScan);
+ if (term_IsDeclaration(atomCand)) {
+ /* We are looking for an unary atom */
+
+ for (litScan = sharing_NAtomDataList(atomCand);
+ !list_Empty(litScan);
+ litScan = list_Cdr(litScan)) {
+ LITERAL nextLit;
+ CLAUSE nextClause;
+ nextLit = list_Car(litScan);
+ nextClause = clause_LiteralOwningClause(nextLit);
+
+ if (clause_LiteralIsPositive(nextLit) &&
+ clause_LiteralGetFlag(nextLit,STRICTMAXIMAL) &&
+ clause_GetFlag(nextClause, WORKEDOFF) &&
+ (!term_IsVariable(list_Car(unifiers)) ||
+ clause_HasEmptyConstraint(nextClause)) &&
+ clause_HasSolvedConstraint(nextClause)) {
+ /* Add the literal from the copied clause */
+ result = list_Cons(nextLit, result);
+ }
+ } /* litScan */
+ } /* if IsAtom */
+ } /* atomScan */
+ } /* ! variable */
+ } /* unifiers */
+ return result;
+}
+
+static BOOL inf_LiteralsHaveSameSubtermAndAreFromSameClause(LITERAL L1, LITERAL L2)
+/**************************************************************
+ INPUT: Two literals.
+ RETURNS: TRUE, if both literals have the same term and are
+ from the same clause, FALSE otherwise.
+ Since both literals are shared, pointer equality
+ is used to detect this.
+ This function is used by inf_GetBackwardPartnerLits().
+***************************************************************/
+{
+ return (term_FirstArgument(clause_LiteralAtom(L1))
+ == term_FirstArgument(clause_LiteralAtom(L2)) &&
+ clause_LiteralOwningClause(L1) == clause_LiteralOwningClause(L2));
+}
+
+static void inf_GetBackwardPartnerLits(LITERAL Literal, st_INDEX Index,
+ LIST* ConstraintLits, LIST* Unifiers,
+ BOOL IsFromEmptySort, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A literal, an index of clauses, two pointers to lists,
+ a boolean value, a flag store and a precedence.
+ RETURNS:
+ MEMORY: Allocates memory for the list.
+***************************************************************/
+{
+ LIST candidates, atomScan, litScan;
+ LITERAL nextLit;
+ CLAUSE nextClause;
+
+#ifdef CHECK
+ if (!clause_LiteralIsLiteral(Literal) || !clause_LiteralIsSort(Literal)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_GetBackwardPartnerLits: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ candidates = st_GetUnifier(cont_LeftContext(), Index, cont_RightContext(),
+ term_FirstArgument(clause_LiteralAtom(Literal)));
+
+ for ( ; !list_Empty(candidates); candidates = list_Pop(candidates)) {
+ if (!term_IsAtom(list_Car(candidates))) { /* May happen if arg is variable */
+ /* Consider variable unifiers only if called from BackwardEmptySort */
+ for (atomScan = term_SupertermList(list_Car(candidates));
+ !list_Empty(atomScan);
+ atomScan = list_Cdr(atomScan)) {
+ TERM atomCand;
+ atomCand = (TERM) list_Car(atomScan);
+ if (term_IsDeclaration(atomCand)) {
+ /* We are looking for unary atoms */
+
+ for (litScan = sharing_NAtomDataList(atomCand);
+ !list_Empty(litScan);
+ litScan = list_Cdr(litScan)) {
+ nextLit = list_Car(litScan);
+ nextClause = clause_LiteralOwningClause(nextLit);
+
+ if (clause_GetFlag(nextClause, WORKEDOFF)) {
+ if (clause_LiteralIsPositive(nextLit)) {
+ if (clause_LiteralGetFlag(nextLit,STRICTMAXIMAL) &&
+ (!term_IsVariable(list_Car(candidates)) ||
+ clause_HasEmptyConstraint(nextClause)) &&
+ clause_HasSolvedConstraint(nextClause) &&
+ !symbol_Equal(clause_LiteralPredicate(Literal),
+ clause_LiteralPredicate(nextLit))) {
+ /* Don't consider literals with same top symbol as given literal */
+ /* since the given clause must be part of any inference */
+ *Unifiers = list_Cons(nextLit, *Unifiers);
+ }
+ } else if (clause_LiteralGetIndex(nextLit) < clause_FirstAntecedentLitIndex(nextClause) &&
+ ((!term_IsVariable(list_Car(candidates)) && !IsFromEmptySort) ||
+ (term_IsVariable(list_Car(candidates)) && IsFromEmptySort &&
+ clause_HasOnlyVarsInConstraint(nextClause,Flags, Precedence)))) {
+ *ConstraintLits = list_Cons(nextLit, *ConstraintLits);
+ }
+ }
+ } /* litScan */
+ }
+ } /* atomScan */
+ }
+ } /* candidates */
+
+ /* We have to avoid constraint literals from the same clause with the same
+ term or variable, since those would create the same result clause. */
+ *ConstraintLits =
+ list_DeleteDuplicates(*ConstraintLits,
+ (BOOL (*)(POINTER,POINTER)) inf_LiteralsHaveSameSubtermAndAreFromSameClause);
+}
+
+static void inf_MakeClausesDisjoint(CLAUSE GClause, LIST Literals)
+/**************************************************************
+ INPUT: A clause and a non-empty list of literals.
+ EFFECT: All input clauses, those pointed to by the literals,
+ are variable disjointly renamed.
+***************************************************************/
+{
+ SYMBOL maxVar, maxCand;
+ CLAUSE lastClause;
+
+ maxVar = clause_MaxVar(GClause);
+ lastClause = clause_LiteralOwningClause(list_Car(Literals));
+ clause_RenameVarsBiggerThan(lastClause, maxVar);
+ Literals = list_Cdr(Literals);
+
+ for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) {
+ CLAUSE actClause;
+
+ clause_UpdateMaxVar(lastClause);
+ maxCand = clause_MaxVar(lastClause);
+ maxVar = (symbol_GreaterVariable(maxVar,maxCand)? maxVar : maxCand);
+
+ actClause = clause_LiteralOwningClause(list_Car(Literals));
+ clause_RenameVarsBiggerThan(actClause, maxVar);
+ }
+}
+
+static void inf_CopyUnifierClauses(LIST Literals)
+/**************************************************************
+ INPUT: A list of literals.
+ EFFECT: Replaces all literals by pointers to literals of copies
+ of the respective clauses.
+***************************************************************/
+{
+ for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) {
+ CLAUSE actClause;
+ int i;
+
+ actClause = clause_LiteralOwningClause(list_Car(Literals));
+ i = clause_LiteralGetIndex(list_Car(Literals));
+ actClause = clause_Copy(actClause);
+ list_Rplaca(Literals, clause_GetLiteral(actClause, i)); /* Set to literal from copy */
+ }
+}
+
+static void inf_DeleteUnifierClauses(LIST Literals)
+/**************************************************************
+ INPUT: A list of literals.
+ EFFECT: Deletes all clauses the literals point to.
+***************************************************************/
+{
+ for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) {
+ clause_Delete(clause_LiteralOwningClause(list_Car(Literals)));
+ list_Rplaca(Literals, NULL);
+ }
+}
+
+static SORT inf_GetSortFromLits(LIST Literals, SORTTHEORY SortTheory)
+/**************************************************************
+ INPUT: A list of literals and a sort theory.
+ RETURNS: The sort created from the literals' predicates.
+***************************************************************/
+{
+ SORT result = sort_TopSort();
+
+ for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) {
+ SORT newSort = sort_TheorySortOfSymbol(SortTheory,
+ clause_LiteralPredicate(list_Car(Literals)));
+
+ result = sort_Intersect(newSort, result);
+ }
+
+ list_PointerDeleteDuplicates(result);
+
+ return result;
+}
+
+static LIST inf_ApplyWeakening(CLAUSE Clause, LIST TLits, LIST Partners,
+ CONDITION Condition, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a list of constraint indices in <Clause>,
+ a list of maximal, monadic succedent literals,
+ a subsort condition, a flag store and a precedence.
+ RETURNS: A one-element list with a clause derived from the
+ clause and the partner clauses by the Weakening or
+ Empty Sort rule.
+ The flag store is needed to create the result clause.
+ MEMORY: Memory is allocated for the returned list and the clause.
+***************************************************************/
+{
+ LIST scan, parents;
+ LIST constraint, antecedent, succedent;
+ LIST parentClauses, parentLits; /* clause numbers and literal indices */
+ int i, bound, depth;
+ TERM tSubterm;
+ CLAUSE newClause;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence) || list_Empty(TLits) ||
+ list_Empty(Partners) || Condition == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_ApplyWeakening: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ constraint = antecedent = succedent = list_Nil();
+ parentClauses = parentLits = list_Nil();
+ parents = list_Nil(); /* Used to set split data */
+ depth = clause_Depth(Clause);
+ tSubterm = term_FirstArgument(clause_GetLiteralAtom(Clause, (int)list_Car(TLits)));
+
+ /* Now collect the literals of the new clause */
+ /* First consider the condition atoms */
+ for (scan=sort_ConditionConstraint(Condition); !list_Empty(scan); scan=list_Cdr(scan)) {
+ TERM termCopy;
+
+ termCopy = term_Copy(list_Car(scan));
+ term_ReplaceVariable(termCopy, sort_ConditionVar(Condition), tSubterm);
+ constraint = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), termCopy),
+ constraint);
+ term_Delete(termCopy); /* constraint contains a copy */
+ }
+ for (scan=sort_ConditionAntecedent(Condition); !list_Empty(scan); scan=list_Cdr(scan)) {
+ TERM termCopy;
+
+ termCopy = term_Copy(list_Car(scan));
+ term_ReplaceVariable(termCopy, sort_ConditionVar(Condition), tSubterm);
+ antecedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), termCopy),
+ antecedent);
+ term_Delete(termCopy); /* antecedent contains a copy */
+ }
+ for (scan=sort_ConditionSuccedent(Condition); !list_Empty(scan); scan=list_Cdr(scan)) {
+ TERM termCopy;
+
+ termCopy = term_Copy(list_Car(scan));
+ term_ReplaceVariable(termCopy, sort_ConditionVar(Condition), tSubterm);
+ succedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), termCopy),
+ succedent);
+ term_Delete(termCopy); /* succedent contains a copy */
+ }
+ /* update parents and depth from condition clauses */
+ for (scan=sort_ConditionClauses(Condition); !list_Empty(scan); scan=list_Cdr(scan)) {
+ CLAUSE condClause;
+
+ condClause = list_Car(scan);
+ parents = list_Cons(condClause, parents);
+ parentClauses = list_Cons((POINTER)clause_Number(condClause), parentClauses);
+ parentLits = list_Cons((POINTER)clause_FirstSuccedentLitIndex(condClause), parentLits);
+ depth = misc_Max(depth, clause_Depth(condClause));
+ }
+
+ /* Now we consider the partner clauses */
+ for (scan = Partners; !list_Empty(scan); scan = list_Cdr(scan)) {
+ LITERAL pLit;
+ CLAUSE pClause;
+ int pi;
+
+ pLit = list_Car(scan);
+ pClause = clause_LiteralOwningClause(pLit);
+ pi = clause_LiteralGetIndex(pLit);
+ bound = clause_LastConstraintLitIndex(pClause);
+ for (i = clause_FirstLitIndex(); i <= bound; i++) {
+ constraint = list_Cons(cont_CopyAndApplyBindings(cont_RightContext(),
+ clause_GetLiteralAtom(pClause,i)),
+ constraint);
+ }
+ bound = clause_LastAntecedentLitIndex(pClause);
+ for (i = clause_FirstAntecedentLitIndex(pClause); i <= bound; i++) {
+ antecedent = list_Cons(cont_CopyAndApplyBindings(cont_RightContext(),
+ clause_GetLiteralAtom(pClause,i)),
+ antecedent);
+ }
+ bound = clause_LastSuccedentLitIndex(pClause);
+ for (i = clause_FirstSuccedentLitIndex(pClause); i <= bound; i++) {
+ if (i != pi)
+ succedent = list_Cons(cont_CopyAndApplyBindings(cont_RightContext(),
+ clause_GetLiteralAtom(pClause,i)),
+ succedent);
+ }
+
+ parents = list_Cons(pClause, parents);
+
+ parentClauses = list_Cons((POINTER)clause_Number(pClause), parentClauses);
+ parentLits = list_Cons((POINTER) pi, parentLits);
+
+ depth = misc_Max(depth, clause_Depth(pClause));
+ }
+
+ /* Last but not least we consider the <Clause> itself */
+ bound = clause_LastConstraintLitIndex(Clause);
+ for (i = clause_FirstLitIndex(); i <= bound; i++) {
+ if (!list_PointerMember(TLits, (POINTER)i))
+ constraint = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(),
+ clause_GetLiteralAtom(Clause,i)),
+ constraint);
+ else {
+ parentClauses = list_Cons((POINTER)clause_Number(Clause), parentClauses);
+ parentLits = list_Cons((POINTER)i, parentLits);
+ }
+ }
+ bound = clause_LastAntecedentLitIndex(Clause);
+ for (i = clause_FirstAntecedentLitIndex(Clause); i <= bound; i++) {
+ antecedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(),
+ clause_GetLiteralAtom(Clause,i)),
+ antecedent);
+ }
+ bound = clause_LastSuccedentLitIndex(Clause);
+ for (i = clause_FirstSuccedentLitIndex(Clause); i <= bound; i++) {
+ succedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(),
+ clause_GetLiteralAtom(Clause,i)),
+ succedent);
+ }
+
+ parents = list_Cons(Clause, parents);
+
+ /* Now we've got all data we need */
+ newClause = clause_Create(constraint, antecedent, succedent, Flags,Precedence);
+
+ list_Delete(constraint);
+ list_Delete(antecedent);
+ list_Delete(succedent);
+
+ if (term_IsVariable(tSubterm))
+ clause_SetFromEmptySort(newClause);
+ else
+ clause_SetFromSortResolution(newClause);
+
+ clause_SetDepth(newClause, depth+1);
+ clause_SetFlag(newClause, DOCCLAUSE);
+
+ clause_SetSplitDataFromList(newClause, parents);
+ list_Delete(parents);
+
+ clause_SetParentClauses(newClause, parentClauses);
+ clause_SetParentLiterals(newClause, parentLits);
+
+ return list_List(newClause);
+}
+
+static LIST inf_InternWeakening(CLAUSE Clause, LIST TLits, LIST Unifiers,
+ LITERAL Special, LIST SojuList, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A <Clause> with unsolved sort constraint,
+ a list <TLits> of constraint indices in <Clause> where
+ all corresponding constraints have the same term,
+ a list <Unifiers> of monadic succedent literals whose
+ subterm is unifiable with the subterm of the <TLits>,
+ and a flag store.
+ If called from a backward rule the literal <Special>
+ will be the succedent literal from the respective
+ GivenClause, that must be part of every considered
+ SOJU sort. If called from a forward rule <Special> is NULL.
+ A list <SojuList> of sort pairs.
+ A flag store and a precedence.
+ RETURNS: The list of possible resolvents.
+ EFFECT: ATTENTION: <SojuList> is deleted.
+ MEMORY: Memory is allocated for the returned list and the clauses.
+***************************************************************/
+{
+ LIST result, myUnifiers;
+ TERM searchTerm;
+ int stack;
+
+ LIST scan;
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence) || list_Empty(TLits) ||
+ list_Empty(Unifiers)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_InternWeakening: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ putchar('\n'); clause_Print(Clause);
+ fputs("\nT_k = ", stdout);
+ for (scan = TLits; !list_Empty(scan); scan = list_Cdr(scan)) {
+ clause_LiteralPrint(clause_GetLiteral(Clause, (int)list_Car(scan)));
+ putchar(' ');
+ }
+ fputs("\nS_k =", stdout);
+ for (scan = Unifiers; !list_Empty(scan); scan = list_Cdr(scan)) {
+ putchar('\n');
+ clause_LiteralPrint(list_Car(scan));
+ fputs(" in ", stdout);
+ clause_Print(clause_LiteralOwningClause(list_Car(scan)));
+ }
+ putchar('\n');
+
+ if (list_Empty(SojuList))
+ return list_Nil();
+
+ /*return list_Nil();*/
+ /* Und Schluss */
+
+ result = list_Nil();
+
+ myUnifiers = list_Copy(Unifiers);
+ inf_CopyUnifierClauses(myUnifiers);
+ inf_MakeClausesDisjoint(Clause, myUnifiers);
+
+ searchTerm =
+ term_FirstArgument(clause_GetLiteralAtom(Clause, (int)list_Car(TLits)));
+
+ stack = stack_Bottom();
+
+ for ( ; !list_Empty(SojuList); SojuList = list_Pop(SojuList)) {
+ SOJU actSoju = list_Car(SojuList);
+
+ fputs("\nSOJU: ", stdout); sort_PairPrint(actSoju); fflush(stdout);
+
+ if (Special == NULL ||
+ sort_ContainsSymbol(sort_PairSort(actSoju),
+ clause_LiteralPredicate(Special))) {
+ LIST actSortSymbols, symbolScan, unifierScan, subset;
+
+ actSortSymbols = sort_GetSymbolsFromSort(sort_PairSort(actSoju));
+ subset = list_Nil();
+
+ symbolScan = actSortSymbols;
+ unifierScan = myUnifiers;
+
+ do {
+ while (!list_Empty(symbolScan) && !list_Empty(unifierScan)) {
+ LITERAL actLit = list_Car(unifierScan);
+
+ if (symbol_Equal(clause_LiteralPredicate(list_Car(unifierScan)),
+ (SYMBOL)list_Car(symbolScan))) {
+ cont_StartBinding();
+ if (unify_UnifyNoOC(cont_LeftContext(), searchTerm, cont_RightContext(),
+ term_FirstArgument(clause_LiteralAtom(actLit)))) {
+ /* Found corresponding literal for sort symbol */
+ stack_Push(symbolScan);
+ stack_Push(list_Cdr(unifierScan));
+ subset = list_Cons(actLit, subset);
+ /* Now search literals for the next sort symbol */
+ symbolScan = list_Cdr(symbolScan);
+
+ if (!list_Empty(symbolScan))
+ /* Start search for literal at the beginning of unifier list */
+ unifierScan = myUnifiers;
+ else
+ unifierScan = list_Cdr(unifierScan);
+ } else {
+ cont_BackTrack();
+ unifierScan = list_Cdr(unifierScan);
+ }
+ } else
+ unifierScan = list_Cdr(unifierScan);
+ }
+
+ if (list_Empty(symbolScan)) {
+ /*putchar('\n');
+ clause_LiteralListPrint(subset);*/
+ /* Found subset */
+ result = list_Nconc(inf_ApplyWeakening(Clause, TLits, subset,
+ sort_PairCondition(actSoju),
+ Flags, Precedence),
+ result);
+ }
+
+ while (!stack_Empty(stack) && list_Empty(stack_Top())) {
+ /* No more literals */
+ stack_NPop(2);
+ cont_BackTrack();
+ subset = list_Pop(subset);
+ }
+
+ if (!stack_Empty(stack)) {
+ /* Implies that stack_Top is a non-empty list */
+ unifierScan = stack_PopResult();
+ symbolScan = stack_PopResult();
+ cont_BackTrack();
+ subset = list_Pop(subset);
+ }
+ } while (!stack_Empty(stack) || !list_Empty(unifierScan));
+
+ list_Delete(actSortSymbols);
+ }
+ sort_PairDelete(actSoju);
+ } /* For all SOJUs */
+
+ inf_DeleteUnifierClauses(myUnifiers);
+ list_Delete(myUnifiers);
+
+ return result;
+}
+
+LIST inf_ForwardWeakening(CLAUSE GivenClause, st_INDEX Index,
+ SORTTHEORY SortTheory, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, an index of clauses, a sort theory, a flag store
+ and a precedence.
+ The sort constraint of the clause must contain a non-variable term
+ (this implies the sort constraint is unsolved).
+ RETURNS: A list of clauses derived from the GivenClause by
+ the Weakening rule.
+ MEMORY: Memory is allocated for the returned list and the clauses.
+***************************************************************/
+{
+ LIST result;
+ int i, lc;
+ BOOL hit;
+
+#ifdef CHECK
+ if (!clause_HasTermSortConstraintLits(GivenClause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_ForwardWeakening: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = list_Nil();
+ lc = clause_LastConstraintLitIndex(GivenClause);
+ hit = FALSE;
+
+ for (i = clause_FirstLitIndex(); i <= lc && !hit; i++) {
+
+ if (!term_IsVariable(term_FirstArgument(clause_GetLiteralAtom(GivenClause, i)))) {
+ /* Condition implies that constraint is unsolved */
+ LITERAL tLit;
+ LIST unifiers;
+ int j;
+
+ tLit = clause_GetLiteral(GivenClause, i);
+ hit = TRUE; /* Try only the first appropriate constraint literal */
+ unifiers = inf_GetForwardPartnerLits(tLit, Index);
+
+ if (!list_Empty(unifiers)) {
+ TERM tAtom;
+ LIST tLits, sojuList;
+ SORT tSort, unifierSort;
+
+ tAtom = clause_GetLiteralAtom(GivenClause, i);
+
+ /* Search the other T_k(t) in GivenClause */
+ tLits = list_Nil();
+ tSort = sort_TopSort();
+ for (j = lc; j > i; j--) {
+ TERM actAtom;
+ actAtom = clause_GetLiteralAtom(GivenClause, j);
+ if (term_FirstArgument(actAtom) == term_FirstArgument(tAtom)) {
+ tLits = list_Cons((POINTER)j, tLits);
+ tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)),
+ tSort);
+ }
+ }
+ tLits = list_Cons((POINTER)i, tLits);
+ tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(tAtom)),
+ tSort);
+ list_PointerDeleteDuplicates(tSort);
+ /* Necessary for Christoph's function */
+
+ unifierSort = inf_GetSortFromLits(unifiers, SortTheory);
+ sojuList = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort);
+ sort_Delete(unifierSort);
+ sort_Delete(tSort);
+
+ result =
+ list_Nconc(inf_InternWeakening(GivenClause, tLits, unifiers, NULL,
+ sojuList, Flags, Precedence),
+ result);
+
+ list_Delete(tLits);
+ list_Delete(unifiers);
+ }
+ }
+ }
+ return result;
+}
+
+LIST inf_BackwardWeakening(CLAUSE GivenClause, st_INDEX Index,
+ SORTTHEORY SortTheory, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause with solved sort constraint, an index of clauses,
+ a sort theory, a flag store and a precedence.
+ RETURNS: A list of clauses inferred from the GivenClause by
+ the Weakening rule.
+ MEMORY: Memory is allocated for the list and the clauses.
+***************************************************************/
+{
+ LIST result;
+ int i, ls;
+
+#ifdef CHECK
+ if (!clause_HasSolvedConstraint(GivenClause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_BackwardWeakening: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = list_Nil();
+ ls = clause_LastSuccedentLitIndex(GivenClause);
+
+ for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) {
+ LITERAL sLit;
+ TERM sAtom;
+
+ sLit = clause_GetLiteral(GivenClause, i);
+ sAtom = clause_LiteralAtom(sLit);
+ if (clause_LiteralGetFlag(sLit, STRICTMAXIMAL) &&
+ clause_LiteralIsSort(sLit) &&
+ (!term_IsVariable(term_FirstArgument(sAtom)) ||
+ clause_HasEmptyConstraint(GivenClause))) {
+ LIST unifiers, partners;
+ SORT unifierSort;
+
+ unifiers = partners = list_Nil();
+ inf_GetBackwardPartnerLits(sLit,Index,&partners,&unifiers,FALSE,Flags,
+ Precedence);
+ unifiers = list_Cons(sLit, unifiers);
+ /* <partners> holds monadic constraint literals */
+ /* <unifiers> holds monadic, maximal succedent literals */
+ unifierSort = inf_GetSortFromLits(unifiers, SortTheory);
+
+ for ( ; !list_Empty(partners); partners = list_Pop(partners)) {
+ LITERAL tLit;
+ CLAUSE tClause;
+ TERM tAtom;
+ int ti;
+ int lc;
+ int j;
+ LIST tLits, sojuList;
+ SORT tSort;
+
+ tLit = list_Car(partners);
+ tClause = clause_LiteralOwningClause(tLit);
+ tAtom = clause_LiteralAtom(tLit);
+ ti = clause_LiteralGetIndex(tLit);
+ lc = clause_LastConstraintLitIndex(tClause);
+
+ /* Search the other T_k(t) in GivenClause */
+ tLits = list_Nil();
+ tSort = sort_TopSort();
+ for (j = lc; j >= clause_FirstLitIndex(); j--) {
+ TERM actAtom;
+
+ actAtom = clause_GetLiteralAtom(tClause, j);
+ if (j != ti &&
+ term_FirstArgument(actAtom) == term_FirstArgument(tAtom)) {
+ tLits = list_Cons((POINTER)j, tLits);
+ tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)),
+ tSort);
+ }
+ }
+ tLits = list_Cons((POINTER)ti, tLits);
+ tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(tAtom)),
+ tSort);
+ list_PointerDeleteDuplicates(tSort);
+
+ sojuList = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort);
+ sort_Delete(tSort);
+
+ cont_StartBinding();
+ unify_UnifyNoOC(cont_LeftContext(), tAtom,
+ cont_RightContext(), sAtom);
+
+ result =
+ list_Nconc(inf_InternWeakening(tClause, tLits, unifiers, sLit,
+ sojuList, Flags, Precedence),
+ result);
+
+ cont_BackTrack();
+
+ list_Delete(tLits);
+ }
+ sort_Delete(unifierSort);
+ list_Delete(unifiers);
+ }
+ }
+
+ return result;
+}
+
+LIST inf_ForwardEmptySortPlusPlus(CLAUSE GivenClause, st_INDEX Index,
+ SORTTHEORY SortTheory, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, an 'Index' of clauses, a sort theory, a flag store
+ and a precedence.
+ The sort constraint of the clause must not contain a
+ non-variable term, but the sort constraint has to be unsolved.
+ RETURNS: A list of clauses derived from the GivenClause by
+ the Empty Sort rule.
+ MEMORY: Memory is allocated for the returned list and the clauses.
+***************************************************************/
+{
+ LIST result;
+ int i, lc;
+ BOOL hit;
+
+#ifdef CHECK
+ if (clause_HasTermSortConstraintLits(GivenClause) ||
+ clause_HasSolvedConstraint(GivenClause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_ForwardEmptySortPlusPlus: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = list_Nil();
+ lc = clause_LastConstraintLitIndex(GivenClause);
+ hit = FALSE;
+
+ for (i = clause_FirstLitIndex(); i <= lc && !hit; i++) {
+
+ if (term_IsVariable(term_FirstArgument(clause_GetLiteralAtom(GivenClause,i)))) {
+ LITERAL tLit;
+ TERM var;
+ int j, ls;
+ BOOL varOccursNoMore;
+
+ tLit = clause_GetLiteral(GivenClause, i);
+ var = term_FirstArgument(clause_LiteralAtom(tLit));
+ ls = clause_LastSuccedentLitIndex(GivenClause);
+ varOccursNoMore = TRUE;
+ /* Check if the variable occurs in antecedent or succedent literals */
+ for (j = clause_FirstAntecedentLitIndex(GivenClause);
+ (j <= ls) && varOccursNoMore; j++) {
+ if (term_ContainsSymbol(clause_GetLiteralAtom(GivenClause,j),
+ term_TopSymbol(var)))
+ varOccursNoMore = FALSE;
+ }
+
+ if (varOccursNoMore) {
+ /* Condition implies that constraint is unsolved */
+ LIST unifiers;
+
+ unifiers = inf_GetForwardPartnerLits(tLit, Index);
+ hit = TRUE; /* We found the first appropriate constraint literal */
+
+ if (!list_Empty(unifiers)) {
+ TERM tAtom = clause_LiteralAtom(tLit);
+ LIST tLits, sojuList;
+ SORT tSort, unifierSort;
+
+ /* Search the other T_k(t) in GivenClause */
+ tLits = list_Nil();
+ tSort = sort_TopSort();
+ for (j = lc; j > i; j--) {
+ TERM actAtom;
+
+ actAtom = clause_GetLiteralAtom(GivenClause, j);
+ if (term_FirstArgument(actAtom) == var) { /* tClause is shared */
+ tLits = list_Cons((POINTER)j, tLits);
+ tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory,
+ term_TopSymbol(actAtom)),
+ tSort);
+ }
+ }
+ tLits = list_Cons((POINTER)i, tLits);
+ tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory,
+ term_TopSymbol(tAtom)),
+ tSort);
+ list_PointerDeleteDuplicates(tSort);
+
+ unifierSort = inf_GetSortFromLits(unifiers, SortTheory);
+ sojuList = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort);
+
+ sort_Delete(unifierSort);
+ sort_Delete(tSort);
+
+ result =
+ list_Nconc(inf_InternWeakening(GivenClause, tLits, unifiers, NULL,
+ sojuList, Flags, Precedence),
+ result);
+
+ list_Delete(tLits);
+ list_Delete(unifiers);
+ }
+ }
+ }
+ }
+ return result;
+}
+
+LIST inf_BackwardEmptySortPlusPlus(CLAUSE GivenClause, st_INDEX Index,
+ SORTTHEORY SortTheory, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause with solved sort constraint, an index of clauses,
+ a sort theory, a flag store and a precedence.
+ RETURNS: A list of clauses inferred from the GivenClause by
+ the Empty Sort rule.
+ MEMORY: Memory is allocated for the list and the clauses.
+***************************************************************/
+{
+ LIST result;
+ int i, ls;
+
+#ifdef CHECK
+ if (!clause_HasSolvedConstraint(GivenClause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_BackwardEmptySortPlusPlus: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = list_Nil();
+ ls = clause_LastSuccedentLitIndex(GivenClause);
+
+ for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) {
+ LITERAL sLit;
+ TERM sAtom;
+
+ sLit = clause_GetLiteral(GivenClause, i);
+ sAtom = clause_LiteralAtom(sLit);
+ if (clause_LiteralGetFlag(sLit,STRICTMAXIMAL) &&
+ clause_LiteralIsSort(sLit) &&
+ (!term_IsVariable(term_FirstArgument(sAtom)) ||
+ clause_HasEmptyConstraint(GivenClause))) {
+ LIST unifiers, partners;
+ SORT unifierSort;
+
+ unifiers = partners = list_Nil();
+ inf_GetBackwardPartnerLits(sLit, Index, &partners, &unifiers, TRUE, Flags,
+ Precedence);
+ unifiers = list_Cons(sLit, unifiers);
+ /* <partners> holds monadic constraint literals */
+ /* <unifiers> holds monadic, maximal succedent literals */
+
+ unifierSort = inf_GetSortFromLits(unifiers, SortTheory);
+
+ for ( ; !list_Empty(partners); partners = list_Pop(partners)) {
+ LITERAL tLit;
+ CLAUSE tClause;
+ TERM tAtom;
+ int ti;
+ int li;
+ TERM var;
+ BOOL varOccursNoMore;
+ int j;
+
+ tLit = list_Car(partners);
+ tClause = clause_LiteralOwningClause(tLit);
+ tAtom = clause_LiteralAtom(tLit);
+ ti = clause_LiteralGetIndex(tLit);
+ li = clause_LastSuccedentLitIndex(tClause);
+ var = term_FirstArgument(tAtom);
+ varOccursNoMore = TRUE;
+ for (j = clause_FirstAntecedentLitIndex(tClause);
+ j <= li && varOccursNoMore;
+ j++) {
+ if (term_ContainsSymbol(clause_GetLiteralAtom(tClause,j),
+ term_TopSymbol(var)))
+ varOccursNoMore = FALSE;
+ }
+
+ if (varOccursNoMore) {
+ /* Condition implies that constraint is unsolved */
+ int lc;
+ LIST tLits, sojuList;
+ SORT tSort;
+
+ lc = clause_LastConstraintLitIndex(tClause);
+
+ /* Search the other T_k(t) in GivenClause */
+ tLits = list_Nil();
+ tSort = sort_TopSort();
+ for (j = lc; j >= clause_FirstLitIndex(); j--) {
+ TERM actAtom;
+
+ actAtom = clause_GetLiteralAtom(tClause, j);
+ if (j != ti &&
+ term_TopSymbol(term_FirstArgument(actAtom)) == term_TopSymbol(var)) {
+ tLits = list_Cons((POINTER)j, tLits);
+ tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)),
+ tSort);
+ }
+ }
+ tLits = list_Cons((POINTER)ti, tLits);
+ tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(tAtom)),
+ tSort);
+ list_PointerDeleteDuplicates(tSort);
+
+ sojuList = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort);
+ sort_Delete(tSort);
+
+ cont_StartBinding();
+ unify_UnifyNoOC(cont_LeftContext(), tAtom,
+ cont_RightContext(), sAtom);
+
+ result =
+ list_Nconc(inf_InternWeakening(tClause, tLits, unifiers, sLit,
+ sojuList, Flags, Precedence),
+ result);
+
+ cont_BackTrack();
+
+ list_Delete(tLits);
+ }
+ }
+ sort_Delete(unifierSort);
+ list_Delete(unifiers);
+ }
+ }
+
+ return result;
+}
diff --git a/test/spass/rules-sort.h b/test/spass/rules-sort.h
new file mode 100644
index 0000000..6b83c94
--- /dev/null
+++ b/test/spass/rules-sort.h
@@ -0,0 +1,79 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INFERENCE RULES FOR SORTS * */
+/* * * */
+/* * $Module: SORTRULES * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _SORTRULES_
+#define _SORTRULES_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "sort.h"
+#include "unify.h"
+#include "clause.h"
+#include "flags.h"
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+LIST inf_ForwardSortResolution(CLAUSE, st_INDEX, SORTTHEORY, BOOL, FLAGSTORE,
+ PRECEDENCE);
+LIST inf_BackwardSortResolution(CLAUSE, st_INDEX, SORTTHEORY, BOOL, FLAGSTORE,
+ PRECEDENCE);
+LIST inf_ForwardEmptySort(CLAUSE, st_INDEX, SORTTHEORY, BOOL, FLAGSTORE,
+ PRECEDENCE);
+LIST inf_BackwardEmptySort(CLAUSE, st_INDEX, SORTTHEORY, BOOL, FLAGSTORE,
+ PRECEDENCE);
+LIST inf_ForwardWeakening(CLAUSE, st_INDEX, SORTTHEORY, FLAGSTORE, PRECEDENCE);
+LIST inf_BackwardWeakening(CLAUSE, st_INDEX, SORTTHEORY, FLAGSTORE, PRECEDENCE);
+LIST inf_ForwardEmptySortPlusPlus(CLAUSE, st_INDEX, SORTTHEORY, FLAGSTORE,
+ PRECEDENCE);
+LIST inf_BackwardEmptySortPlusPlus(CLAUSE, st_INDEX, SORTTHEORY, FLAGSTORE,
+ PRECEDENCE);
+
+#endif
diff --git a/test/spass/rules-split.c b/test/spass/rules-split.c
new file mode 100644
index 0000000..7ee420a
--- /dev/null
+++ b/test/spass/rules-split.c
@@ -0,0 +1,460 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SPLITTING OF CLAUSES * */
+/* * * */
+/* * $Module: SPLIT * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 2000 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "rules-split.h"
+
+static LIST split_DeleteClausesDependingOnLevelFromList(PROOFSEARCH,LIST, int, LIST*);
+static LIST split_DeleteInvalidClausesFromList(PROOFSEARCH, int, LIST);
+static void split_DeleteInvalidClausesFromStack(PROOFSEARCH);
+static LIST split_RemoveUnnecessarySplits(PROOFSEARCH, CLAUSE);
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+
+LIST split_Backtrack(PROOFSEARCH PS, CLAUSE EmptyClause, CLAUSE* SplitClause)
+/**************************************************************
+ INPUT: A proofsearch object, an empty clause and a pointer to a clause
+ used as return value.
+ RETURNS: A list of clauses deleted in the backtracked split levels.
+ <*SplitClause> is set to the split clause for the right branch
+ of the splitting step, or NULL, if the tableau is finished.
+ EFFECT: Backtracks the top of the split stack wrt the empty clause's level
+***************************************************************/
+{
+ SPLIT ActBacktrackSplit;
+ LIST RecoverList, Scan;
+ int Backtracklevel;
+
+ ActBacktrackSplit = (SPLIT)NULL;
+ RecoverList = split_RemoveUnnecessarySplits(PS, EmptyClause);
+ Backtracklevel = clause_SplitLevel(EmptyClause);
+ *SplitClause = NULL;
+
+ /* Backtrack all split levels bigger than the level of the empty clause */
+ while (!prfs_SplitStackEmpty(PS) && (prfs_ValidLevel(PS) > Backtracklevel)) {
+ ActBacktrackSplit = prfs_SplitStackTop(PS);
+ prfs_SplitStackPop(PS);
+ if (prfs_SplitFatherClause(ActBacktrackSplit) != (CLAUSE)NULL) {
+ RecoverList = list_Cons(prfs_SplitFatherClause(ActBacktrackSplit),
+ RecoverList);
+ prfs_SplitSetFatherClause(ActBacktrackSplit, NULL);
+ }
+ RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit),
+ RecoverList);
+ clause_DeleteClauseList(prfs_SplitBlockedClauses(ActBacktrackSplit));
+ prfs_SplitFree(ActBacktrackSplit);
+ prfs_DecValidLevel(PS);
+ }
+
+ /* Backtrack further for all right branches on top of the stack */
+ while (!prfs_SplitStackEmpty(PS) &&
+ list_Empty(prfs_SplitBlockedClauses(prfs_SplitStackTop(PS)))) {
+ ActBacktrackSplit = prfs_SplitStackTop(PS);
+ prfs_SplitStackPop(PS);
+ if (prfs_SplitFatherClause(ActBacktrackSplit) != (CLAUSE)NULL)
+ RecoverList = list_Cons(prfs_SplitFatherClause(ActBacktrackSplit),
+ RecoverList);
+ RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit),
+ RecoverList);
+ prfs_SplitFree(ActBacktrackSplit);
+ prfs_DecValidLevel(PS);
+ }
+
+ if (!prfs_SplitStackEmpty(PS)) {
+ /* Enter the right branch of the splitting step */
+ int SplitMinus1;
+ LIST RightClauses;
+
+ SplitMinus1 = prfs_ValidLevel(PS) - 1;
+ ActBacktrackSplit = prfs_SplitStackTop(PS);
+
+ RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit),
+ RecoverList);
+ prfs_SplitSetDeletedClauses(ActBacktrackSplit, list_Nil());
+ RecoverList = split_DeleteInvalidClausesFromList(PS, SplitMinus1,
+ RecoverList);
+
+ RightClauses = prfs_SplitBlockedClauses(ActBacktrackSplit);
+ prfs_SplitSetBlockedClauses(ActBacktrackSplit, list_Nil());
+ for (Scan = RightClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (clause_Number(list_Car(Scan)) == 0) {
+ /* Found the right clause, the negation clauses have number -1. */
+#ifdef CHECK
+ if (*SplitClause != NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In split_Backtrack:");
+ misc_ErrorReport(" Found two blocked clauses ");
+ misc_ErrorReport("\n with clause number 0 (this marks the clause ");
+ misc_ErrorReport("\n for the right branch of the tableau).");
+ misc_FinishErrorReport();
+ }
+#endif
+ *SplitClause = list_Car(Scan);
+ }
+
+ clause_NewNumber((CLAUSE) list_Car(Scan));
+ clause_AddParentClause((CLAUSE) list_Car(Scan), clause_Number(EmptyClause));
+ clause_AddParentLiteral((CLAUSE) list_Car(Scan), 0); /* dummy literal */
+ }
+
+#ifdef CHECK
+ if (*SplitClause == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In split_Backtrack: Didn´t find a blocked clause");
+ misc_ErrorReport("\n with clause number 0. (this marks the clause ");
+ misc_ErrorReport("\n for the right branch of the tableau).");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ RecoverList = list_Nconc(RightClauses, RecoverList);
+
+ /* Then, delete clauses from current level (Hack) */
+ prfs_DecValidLevel(PS);
+ prfs_MoveInvalidClausesDocProof(PS);
+ split_DeleteInvalidClausesFromStack(PS);
+ prfs_IncValidLevel(PS);
+ } else {
+ /* Don't delete clauses from current level (split is top level) */
+ prfs_MoveInvalidClausesDocProof(PS);
+ for (Scan = RecoverList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ prfs_InsertDocProofClause(PS, list_Car(Scan));
+ list_Delete(RecoverList);
+ RecoverList = list_Nil();
+ }
+ prfs_SetLastBacktrackLevel(PS, prfs_ValidLevel(PS));
+
+ return RecoverList;
+}
+
+
+static LIST split_DeleteClausesDependingOnLevelFromList(PROOFSEARCH Search,
+ LIST ClauseList,
+ int Level, LIST* New)
+/**************************************************************
+ INPUT: A proof search object, a list of unshared clauses
+ and a split level.
+ EFFECT: Deletes all clauses depending on split level from
+ <ClauseList>.
+ All split stored deleted clauses from the level of
+ the deleted clauses from <ClauseList> are stored in
+ <*New>.
+ RETURNS: The updated list and the recover clauses in <*New>.
+***************************************************************/
+{
+ LIST Scan;
+ CLAUSE Clause;
+ SPLIT Reinsert;
+
+ for (Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Clause = list_Car(Scan);
+ if (clause_DependsOnSplitLevel(Clause, Level)) {
+ Reinsert = prfs_GetSplitOfLevel(clause_SplitLevel(Clause), Search);
+ if (prfs_SplitDeletedClauses(Reinsert) != list_Nil()) {
+ *New = list_Nconc(prfs_SplitDeletedClauses(Reinsert), *New);
+ prfs_SplitSetDeletedClauses(Reinsert, list_Nil());
+ }
+ prfs_InsertDocProofClause(Search,Clause);
+ list_Rplaca(Scan, NULL);
+ }
+ }
+ return list_PointerDeleteElement(ClauseList, NULL);
+}
+
+
+static LIST split_DeleteClausesDependingOnLevelFromSet(PROOFSEARCH PS,
+ LIST ClauseList,
+ int SplitLevel)
+/**************************************************************
+ INPUT: A PROOFSEARCH object, a list of shared clauses
+ and a split level.
+ RETURNS: A list of clauses that have to be recovered possibly.
+ EFFECT: Clauses from the clause list depending on <SplitLevel>
+ are moved to the doc proof index of <PS>.
+ All formerly redundant clauses that were reduced by a clause
+ of the same split level as a clause from the list depending
+ on <SplitLevel> are returned.
+***************************************************************/
+{
+ LIST scan, delList, recover;
+ CLAUSE clause;
+ SPLIT reinsert;
+
+ delList = recover = list_Nil();
+
+ for (scan = ClauseList; !list_Empty(scan); scan = list_Cdr(scan)){
+ clause = list_Car(scan);
+ if (clause_DependsOnSplitLevel(clause, SplitLevel)) {
+ reinsert = prfs_GetSplitOfLevel(clause_SplitLevel(clause), PS);
+ recover = list_Nconc(prfs_SplitDeletedClauses(reinsert), recover);
+ prfs_SplitSetDeletedClauses(reinsert, list_Nil());
+ delList = list_Cons(clause, delList);
+ }
+ }
+
+ /* WARNING: The following move operations change the worked off */
+ /* and usable sets of the proof search object destructively. */
+ /* So it's impossible to move those function calls into the */
+ /* loop above. */
+ for ( ; !list_Empty(delList); delList = list_Pop(delList)) {
+ clause = list_Car(delList);
+ if (clause_GetFlag(clause, WORKEDOFF))
+ prfs_MoveWorkedOffDocProof(PS, clause);
+ else
+ prfs_MoveUsableDocProof(PS, clause);
+ }
+ return recover;
+}
+
+
+
+static LIST split_DeleteInvalidClausesFromList(PROOFSEARCH Search, int Level,
+ LIST ClauseList)
+/**************************************************************
+ INPUT: A proof search object, a split level and a list of clauses.
+ RETURNS: The list where invalid clauses wrt 'Level' are deleted.
+ EFFECT: The invalid clauses are stored in the doc proof index
+ of the proof search object if necessary.
+***************************************************************/
+{
+ LIST Scan;
+ CLAUSE Clause;
+
+ /*printf("\nDiese Liste soll von ungueltigen (Level > %d) "
+ "befreit werden: \n",Level);fflush(stdout);
+ clause_ListPrint(ClauseList);*/
+
+ for (Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Clause = list_Car(Scan);
+ if (!prfs_IsClauseValid(Clause,Level)) {
+ prfs_InsertDocProofClause(Search,Clause);
+ list_Rplaca(Scan, NULL);
+ }
+ }
+ return list_PointerDeleteElement(ClauseList, NULL);
+}
+
+static void split_DeleteInvalidClausesFromStack(PROOFSEARCH Search)
+/**************************************************************
+ INPUT: A proof search object.
+ EFFECT: All clauses in the split stack of <Search> that have a higher
+ split level than the current <Search> split level are deleted.
+***************************************************************/
+{
+ LIST Scan1,Scan2,ClauseList;
+ int Level;
+ CLAUSE Clause;
+
+ Level = prfs_ValidLevel(Search);
+
+ for (Scan1=prfs_SplitStack(Search);!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+ ClauseList = prfs_SplitDeletedClauses(list_Car(Scan1));
+ for (Scan2 = ClauseList; !list_Empty(Scan2); Scan2 = list_Cdr(Scan2)) {
+ Clause = (CLAUSE)list_Car(Scan2);
+ if (!prfs_IsClauseValid(Clause,Level)) {
+ prfs_InsertDocProofClause(Search,Clause);
+ list_Rplaca(Scan2, NULL);
+ }
+ }
+ prfs_SplitSetDeletedClauses(list_Car(Scan1),list_PointerDeleteElement(ClauseList, NULL));
+ }
+}
+
+
+static LIST split_RemoveUnnecessarySplits(PROOFSEARCH PS, CLAUSE EmptyClause)
+/**************************************************************
+ INPUT: An empty clause and a proof search object
+ EFFECT: Removes all splits up to the last backtrack level
+ that were not necessary to derive the empty clause.
+ RETURNS: A list of recovered clauses.
+***************************************************************/
+{
+ LIST Scan;
+ LIST Recover, New;
+ LIST Deleted;
+ LIST ScanStack;
+
+ int SplitLevel;
+ int LastBacktrackLevel;
+ SPLIT Split,ScanSplit;
+
+ Scan = prfs_SplitStack(PS);
+ SplitLevel = prfs_ValidLevel(PS);
+ LastBacktrackLevel = prfs_LastBacktrackLevel(PS);
+ Recover = list_Nil();
+
+ while (SplitLevel > LastBacktrackLevel) {
+ if (prfs_SplitIsUnused(list_Car(Scan)) &&
+ !clause_DependsOnSplitLevel(EmptyClause, SplitLevel)) {
+ New = list_Nil();
+ Split = list_Car(Scan);
+
+ /*printf("\n\t Removed: %d",prfs_SplitSplitLevel(Split));*/
+
+ clause_DeleteClauseList(prfs_SplitBlockedClauses(Split));
+ prfs_SplitSetBlockedClauses(Split, list_Nil());
+
+ Recover = list_Nconc(prfs_SplitDeletedClauses(Split), Recover);
+ prfs_SplitSetDeletedClauses(Split, list_Nil());
+
+ if (prfs_SplitFatherClause(Split) != (CLAUSE)NULL) {
+ Recover = list_Cons(prfs_SplitFatherClause(Split),Recover);
+ prfs_SplitSetFatherClause(Split,NULL);
+ }
+ Recover = split_DeleteClausesDependingOnLevelFromList(PS, Recover, SplitLevel, &New);
+
+ ScanStack = prfs_SplitStack(PS);
+ while (!list_StackEmpty(ScanStack) &&
+ prfs_SplitSplitLevel((ScanSplit = (SPLIT)list_Car(ScanStack))) > LastBacktrackLevel) {
+ Deleted = prfs_SplitDeletedClauses(ScanSplit);
+ prfs_SplitSetDeletedClauses(ScanSplit, list_Nil()); /* IMPORTANT!, see next line */
+ Deleted = split_DeleteClausesDependingOnLevelFromList(PS, Deleted, SplitLevel, &New);
+ prfs_SplitSetDeletedClauses(ScanSplit, Deleted);
+ ScanStack = list_Cdr(ScanStack);
+ }
+
+ while (!list_Empty(New)) {
+ Deleted = list_Nil();
+ Recover = list_Nconc(split_DeleteClausesDependingOnLevelFromList(PS, New, SplitLevel, &Deleted),
+ Recover);
+ New = Deleted;
+ }
+ Recover = list_Nconc(Recover,
+ split_DeleteClausesDependingOnLevelFromSet(PS, prfs_UsableClauses(PS), SplitLevel));
+ Recover = list_Nconc(Recover,
+ split_DeleteClausesDependingOnLevelFromSet(PS, prfs_WorkedOffClauses(PS), SplitLevel));
+
+ prfs_SplitSetUsed(Split);
+ }
+
+ SplitLevel--;
+ Scan = list_Cdr(Scan);
+ }
+ return Recover;
+}
+
+
+void split_DeleteClauseAtLevel(PROOFSEARCH PS, CLAUSE Clause, int Level)
+/**************************************************************
+ INPUT: A clause, a level and a proofsearch object
+ RETURNS: Nothing.
+ EFFECT: <Clause> is deleted from the usable or worked off set
+ and made unshared.
+***************************************************************/
+{
+ if (clause_GetFlag(Clause,WORKEDOFF))
+ prfs_ExtractWorkedOff(PS, Clause);
+ else
+ prfs_ExtractUsable(PS, Clause);
+
+ split_KeepClauseAtLevel(PS, Clause, Level);
+}
+
+
+void split_KeepClauseAtLevel(PROOFSEARCH PS, CLAUSE Clause, int Level)
+/**************************************************************
+ INPUT: A clause and a level as int.
+ RETURNS: None.
+ MEMORY: A copy of clause is made and kept within the split stack.
+***************************************************************/
+{
+ SPLIT Split;
+
+ Split = prfs_GetSplitOfLevel(Level, PS);
+ prfs_SplitSetDeletedClauses(Split,list_Cons(Clause, prfs_SplitDeletedClauses(Split)));
+}
+
+
+LIST split_ExtractEmptyClauses(LIST Clauses, LIST* EmptyClauses)
+/**************************************************************
+ INPUT: A list of clauses and a pointer to a list of empty clauses.
+ RETURNS: <Clauses> without all empty clauses where the empty clauses
+ are moved to <EmptyClauses>
+ MEMORY: Destructive on <Clauses>.
+***************************************************************/
+{
+ LIST Scan;
+ CLAUSE Clause;
+
+ for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ if (clause_IsEmptyClause(Clause)) {
+ *EmptyClauses = list_Cons(Clause,*EmptyClauses);
+ list_Rplaca(Scan,NULL);
+ }
+ }
+ Clauses = list_PointerDeleteElement(Clauses,NULL);
+
+ return Clauses;
+}
+
+CLAUSE split_SmallestSplitLevelClause(LIST Clauses)
+/**************************************************************
+ INPUT: A non-empty list of clauses.
+ RETURNS: The clause with the smallest split level.
+***************************************************************/
+{
+ CLAUSE Result;
+
+ Result = (CLAUSE)list_Car(Clauses);
+ Clauses = list_Cdr(Clauses);
+
+ while (!list_Empty(Clauses)) {
+ if (clause_SplitLevel(Result) > clause_SplitLevel(list_Car(Clauses)))
+ Result = list_Car(Clauses);
+ Clauses = list_Cdr(Clauses);
+ }
+
+ return Result;
+}
diff --git a/test/spass/rules-split.h b/test/spass/rules-split.h
new file mode 100644
index 0000000..3423fa3
--- /dev/null
+++ b/test/spass/rules-split.h
@@ -0,0 +1,70 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SPLITTING OF CLAUSES * */
+/* * * */
+/* * $Module: SPLIT * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 2000 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _RULES_SPLIT_
+#define _RULES_SPLIT_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "clause.h"
+#include "search.h"
+
+
+/**************************************************************/
+/* Function Prototypes */
+/**************************************************************/
+
+LIST split_Backtrack(PROOFSEARCH, CLAUSE, CLAUSE*);
+void split_KeepClauseAtLevel(PROOFSEARCH, CLAUSE, int);
+void split_DeleteClauseAtLevel(PROOFSEARCH, CLAUSE, int);
+LIST split_ExtractEmptyClauses(LIST, LIST*);
+CLAUSE split_SmallestSplitLevelClause(LIST);
+
+
+#endif
diff --git a/test/spass/rules-ur.c b/test/spass/rules-ur.c
new file mode 100644
index 0000000..bd07651
--- /dev/null
+++ b/test/spass/rules-ur.c
@@ -0,0 +1,385 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * UR-RESOLUTION * */
+/* * * */
+/* * $Module: INFERENCE RULES * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "rules-ur.h"
+#include "list.h"
+
+
+static LIST inf_GetURPartnerLits(TERM Atom, LITERAL Lit,
+ BOOL Unit, SHARED_INDEX Index)
+/**************************************************************
+ INPUT: An atom, a literal, a boolean flag and a SHARED_INDEX.
+ RETURNS: A list of literals with sign complementary to <Lit>
+ that are unifiable with <Atom>. If <Unit> is true,
+ only literals from unit clauses are returned, if <Unit>
+ is false, only literals from non-unit clauses are
+ returned.
+ EFFECT: <Atom> is a copy of <Lit>'s atom where some substitution
+ was applied and equality literals might have been swapped.
+ <Lit> is just needed to check whether the unifiable
+ literals are complementary.
+***************************************************************/
+{
+ LIST Result, Unifiers, LitScan;
+ LITERAL PLit;
+ int length;
+
+ Result = list_Nil();
+ Unifiers = st_GetUnifier(cont_LeftContext(), sharing_Index(Index),
+ cont_RightContext(), Atom);
+ for ( ; !list_Empty(Unifiers); Unifiers = list_Pop(Unifiers)) {
+ if (!term_IsVariable(list_Car(Unifiers))) {
+ for (LitScan = sharing_NAtomDataList(list_Car(Unifiers));
+ !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) {
+ PLit = list_Car(LitScan);
+ length = clause_Length(clause_LiteralOwningClause(PLit));
+ if (clause_LiteralsAreComplementary(Lit, PLit) &&
+ ((Unit && length==1) || (!Unit && length!=1)))
+ /* The partner literals must have complementary sign and
+ if <Unit> == TRUE they must be from unit clauses,
+ if <Unit> == FALSE they must be from non-unit clauses. */
+ Result = list_Cons(PLit, Result);
+ }
+ }
+ }
+ return Result;
+}
+
+
+static CLAUSE inf_CreateURUnitResolvent(CLAUSE Clause, int i, SUBST Subst,
+ LIST FoundMap, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A non-unit clause, a literal index from the clause,
+ a substitution, a list of pairs (l1, l2) of literals,
+ where l1 is from the non-unit clause and l2 is from a
+ unit clause, a flag store and a precedence.
+ RETURNS: The resolvent of this UR resolution inference. The
+ clause consists of the literal at index <i> in <Clause>
+ after application of <Subst>.
+ EFFECT: The flag store and the precedence are needed to create
+ the new clause.
+***************************************************************/
+{
+ CLAUSE Result, PClause;
+ LITERAL Lit;
+ TERM Atom;
+ LIST Parents;
+ NAT depth;
+
+ /* Create atom for resolvent */
+ Atom = subst_Apply(Subst, term_Copy(clause_GetLiteralAtom(Clause, i)));
+ /* Create clause */
+ Parents = list_List(Atom);
+ if (i <= clause_LastConstraintLitIndex(Clause))
+ Result = clause_Create(Parents, list_Nil(), list_Nil(), Flags, Precedence);
+ else if (i <= clause_LastAntecedentLitIndex(Clause))
+ Result = clause_Create(list_Nil(), Parents, list_Nil(), Flags, Precedence);
+ else
+ Result = clause_Create(list_Nil(), list_Nil(), Parents, Flags, Precedence);
+ list_Delete(Parents);
+
+ /* Get parent clauses and literals, calculate depth of resolvent */
+ Parents = list_List(Clause);
+ depth = clause_Depth(Clause);
+ for ( ; !list_Empty(FoundMap); FoundMap = list_Cdr(FoundMap)) {
+ Lit = list_PairSecond(list_Car(FoundMap)); /* Literal from unit */
+ PClause = clause_LiteralOwningClause(Lit);
+ Parents = list_Cons(PClause, Parents);
+ depth = misc_Max(depth, clause_Depth(PClause));
+ clause_AddParentClause(Result, clause_Number(PClause));
+ clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit));
+
+ Lit = list_PairFirst(list_Car(FoundMap)); /* Is from <Clause> */
+ clause_AddParentClause(Result, clause_Number(Clause));
+ clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit));
+ }
+ clause_SetFromURResolution(Result);
+ clause_SetDepth(Result, depth+1);
+ clause_SetSplitDataFromList(Result, Parents);
+ list_Delete(Parents);
+
+ return Result;
+}
+
+
+static LIST inf_SearchURResolvents(CLAUSE Clause, int i, LIST FoundMap,
+ LIST RestLits, SUBST Subst,
+ SYMBOL GlobalMaxVar, SHARED_INDEX Index,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A non-unit clause, a literal index from <Clause>.
+ <FoundMap> is a list of pairs (l1,l2) of unifiable literals,
+ where l1 is from <Clause> and l2 is from a unit clause.
+ <RestLits> is a list of literals from <Clause> where
+ we haven't found unifiable literals from unit clauses
+ so far.
+ <Subst> is the overall substitution for <Clause>
+ (not for the unit-clauses!).
+ <GlobalMaxVar> is the maximal variable encountered so far.
+ <Index> is used to search unifiable literals.
+ The flag store and the precedence are needed to create
+ the new clauses.
+ RETURNS: A list of UR resolution resolvents.
+***************************************************************/
+{
+ if (list_Empty(RestLits)) {
+ /* Stop the recursion */
+ return list_List(inf_CreateURUnitResolvent(Clause, i, Subst, FoundMap,
+ Flags, Precedence));
+ } else {
+ LITERAL Lit, PLit;
+ SYMBOL NewMaxVar;
+ SUBST NewSubst, RightSubst;
+ TERM AtomCopy, PAtom;
+ LIST Result, Partners;
+ BOOL Swapped;
+
+ Result = list_Nil();
+ Swapped = FALSE;
+ /* Choose the unmatched literal with the most symbols */
+ RestLits = clause_MoveBestLiteralToFront(list_Copy(RestLits), Subst,
+ GlobalMaxVar,
+ clause_HyperLiteralIsBetter);
+ Lit = list_Car(RestLits);
+ RestLits = list_Pop(RestLits);
+ AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit)));
+
+ /* The following 'endless' loop runs twice for equality literals */
+ /* and only once for other literals. */
+ while (TRUE) {
+ Partners = inf_GetURPartnerLits(AtomCopy, Lit, TRUE, Index);
+ for ( ; !list_Empty(Partners); Partners = list_Pop(Partners)) {
+ PLit = list_Car(Partners);
+
+ /* Rename the atom */
+ PAtom = term_Copy(clause_LiteralAtom(PLit));
+ term_StartMaxRenaming(GlobalMaxVar);
+ term_Rename(PAtom);
+ /* Get the new global maximal variable */
+ NewMaxVar = term_MaxVar(PAtom);
+ if (symbol_GreaterVariable(GlobalMaxVar, NewMaxVar))
+ NewMaxVar = GlobalMaxVar;
+
+ /* Get the substitution */
+ cont_Check();
+ if (!unify_UnifyNoOC(cont_LeftContext(), AtomCopy,
+ cont_RightContext(), PAtom)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In inf_SearchURResolvents: Unification failed.");
+ misc_FinishErrorReport();
+ }
+ subst_ExtractUnifier(cont_LeftContext(), &NewSubst,
+ cont_RightContext(), &RightSubst);
+ cont_Reset();
+ subst_Delete(RightSubst); /* Forget substitution for unit clause */
+ term_Delete(PAtom); /* Was just needed to get the substitution */
+
+ /* Build the composition of the substitutions */
+ RightSubst = NewSubst;
+ NewSubst = subst_Compose(NewSubst, subst_Copy(Subst));
+ subst_Delete(RightSubst);
+
+ FoundMap = list_Cons(list_PairCreate(Lit, PLit), FoundMap);
+
+ Result = list_Nconc(inf_SearchURResolvents(Clause,i,FoundMap,RestLits,
+ NewSubst,NewMaxVar,Index,
+ Flags, Precedence),
+ Result);
+
+ list_PairFree(list_Car(FoundMap));
+ FoundMap = list_Pop(FoundMap);
+ subst_Delete(NewSubst);
+ }
+ /* loop control */
+ if (!fol_IsEquality(AtomCopy) || Swapped)
+ break;
+ else {
+ term_EqualitySwap(AtomCopy);
+ Swapped = TRUE;
+ }
+ }
+ /* cleanup */
+ term_Delete(AtomCopy);
+ list_Delete(RestLits);
+
+ return Result;
+ }
+}
+
+
+static LIST inf_NonUnitURResolution(CLAUSE Clause, int SpecialLitIndex,
+ LIST FoundMap, SUBST Subst,
+ SYMBOL GlobalMaxVar, SHARED_INDEX Index,
+ FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A non-unit clause, a literal index from <Clause>.
+ <FoundMap> is a list of pairs (l1,l2) of unifiable literals,
+ where l1 is from <Clause> and l2 is from a unit clause.
+ At this point the list has at most one element.
+ <Subst> is the substitution for <Clause>.
+ <GlobalMaxVar> is the maximal variable encountered so far.
+ <Index> is used to search unifiable literals.
+ The flag store and the precedence are needed to create
+ the new clauses.
+ RETURNS: The list of UR resolution resolvents.
+ EFFECT: If inf_URResolution was called with a unit clause,
+ <SpecialLitIndex> is the index of a literal from a non-unit
+ clause, that is unifiable with the unit clause's literal,
+ otherwise it is set to -1.
+***************************************************************/
+{
+ LIST Result, RestLits;
+ int i, last;
+
+ Result = list_Nil();
+ RestLits = clause_GetLiteralListExcept(Clause, SpecialLitIndex);
+ last = clause_LastLitIndex(Clause);
+ for (i = clause_FirstLitIndex(); i <= last; i++) {
+ /* <i> is the index of the literal that remains in the resolvent */
+ if (i != SpecialLitIndex) {
+ RestLits = list_PointerDeleteOneElement(RestLits,
+ clause_GetLiteral(Clause,i));
+
+ Result = list_Nconc(inf_SearchURResolvents(Clause, i, FoundMap, RestLits,
+ Subst, GlobalMaxVar, Index,
+ Flags, Precedence),
+ Result);
+
+ RestLits = list_Cons(clause_GetLiteral(Clause, i), RestLits);
+ }
+ }
+ list_Delete(RestLits);
+ return Result;
+}
+
+
+LIST inf_URResolution(CLAUSE Clause, SHARED_INDEX Index, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, a shared index, a flag store and a precedence.
+ RETURNS: The list of UR resolution resolvents.
+ EFFECT: The flag store and the precedence are needed to create
+ the resolvents.
+***************************************************************/
+{
+ LIST Result;
+
+ if (clause_Length(Clause) != 1) {
+ /* Clause isn't unit clause */
+ Result = inf_NonUnitURResolution(Clause, -1, list_Nil(), subst_Nil(),
+ clause_MaxVar(Clause), Index, Flags,
+ Precedence);
+ }
+ else {
+ /* Clause is unit clause, so search partner literals in non-unit clauses */
+ LITERAL Lit, PLit;
+ TERM Atom;
+ LIST Partners, FoundMap;
+ SYMBOL MaxVar, PMaxVar;
+ SUBST LeftSubst, RightSubst;
+ CLAUSE PClause;
+ int PLitInd;
+ BOOL Swapped;
+
+ Result = list_Nil();
+ Lit = clause_GetLiteral(Clause, clause_FirstLitIndex());
+ Atom = term_Copy(clause_LiteralAtom(Lit));
+ Swapped = FALSE;
+
+ /* The following 'endless' loop runs twice for equality literals */
+ /* and only once for other literals. */
+ while (TRUE) {
+ /* Get complementary literals from non-unit clauses */
+ Partners = inf_GetURPartnerLits(Atom, Lit, FALSE, Index);
+
+ for ( ; !list_Empty(Partners); Partners = list_Pop(Partners)) {
+ PLit = list_Car(Partners);
+ PLitInd = clause_LiteralGetIndex(PLit);
+ PClause = clause_LiteralOwningClause(PLit); /* non-unit clause */
+
+ PMaxVar = clause_MaxVar(PClause);
+ term_StartMaxRenaming(PMaxVar);
+ term_Rename(Atom); /* Rename atom from unit clause */
+ MaxVar = term_MaxVar(Atom);
+ if (symbol_GreaterVariable(PMaxVar, MaxVar))
+ MaxVar = PMaxVar;
+
+ /* Get the substitution */
+ cont_Check();
+ unify_UnifyNoOC(cont_LeftContext(), clause_LiteralAtom(PLit),
+ cont_RightContext(), Atom);
+ subst_ExtractUnifier(cont_LeftContext(), &LeftSubst,
+ cont_RightContext(), &RightSubst);
+ cont_Reset();
+ /* We don't need the substitution for the unit clause */
+ subst_Delete(RightSubst);
+
+ FoundMap = list_List(list_PairCreate(PLit, Lit));
+
+ Result = list_Nconc(inf_NonUnitURResolution(PClause, PLitInd, FoundMap,
+ LeftSubst, MaxVar, Index,
+ Flags, Precedence),
+ Result);
+
+ list_DeletePairList(FoundMap);
+ subst_Delete(LeftSubst);
+ }
+ /* loop control */
+ if (!fol_IsEquality(Atom) || Swapped)
+ break;
+ else {
+ term_EqualitySwap(Atom);
+ Swapped = TRUE;
+ }
+ } /* end of endless loop */
+ term_Delete(Atom);
+ }
+ return Result;
+}
diff --git a/test/spass/rules-ur.h b/test/spass/rules-ur.h
new file mode 100644
index 0000000..3bdc427
--- /dev/null
+++ b/test/spass/rules-ur.h
@@ -0,0 +1,55 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * UR-RESOLUTION * */
+/* * * */
+/* * $Module: INFERENCE RULES * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+#ifndef _UR_RESOLUTION_
+#define _UR_RESOLUTION_
+
+#include "clause.h"
+#include "sharing.h"
+#include "flags.h"
+
+LIST inf_URResolution(CLAUSE, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+
+#endif
diff --git a/test/spass/search.c b/test/spass/search.c
new file mode 100644
index 0000000..5833ada
--- /dev/null
+++ b/test/spass/search.c
@@ -0,0 +1,1271 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * REPRESENTATION OF PROOF SEARCH * */
+/* * * */
+/* * $Module: PROOF SEARCH * */
+/* * * */
+/* * Copyright (C) 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#include "search.h"
+#include "defs.h"
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+static SPLIT prfs_SplitCreate(PROOFSEARCH PS)
+/**************************************************************
+ INPUT: A proofsearch object
+ RETURNS: A new split object, which is initialized.
+ MEMORY: Allocates memory for the SPLIT_NODE.
+ EFFECT: Increases the split level of the proof search object.
+***************************************************************/
+{
+ SPLIT Result;
+
+ prfs_IncValidLevel(PS);
+
+ Result = (SPLIT)memory_Malloc(sizeof(SPLIT_NODE));
+ Result->splitlevel = prfs_ValidLevel(PS);
+ Result->used = FALSE;
+ Result->blockedClauses = list_Nil();
+ Result->deletedClauses = list_Nil();
+ Result->father = (CLAUSE) NULL;
+ return Result;
+}
+
+
+static void prfs_SplitDelete(SPLIT S)
+/**************************************************************
+ INPUT: A split
+ RETURNS: Nothing.
+ MEMORY: Deletes blocked and deleted clauses. Frees the split.
+***************************************************************/
+{
+ clause_DeleteClauseList(S->blockedClauses);
+ clause_DeleteClauseList(S->deletedClauses);
+ if (S->father != (CLAUSE)NULL)
+ clause_Delete(S->father);
+ prfs_SplitFree(S);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * DEBUGGING FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+BOOL prfs_Check(PROOFSEARCH Search)
+/**************************************************************
+ INPUT: A proof search object.
+ EFFECT: None.
+ RETURNS: TRUE if all invariants about <Search> are valid.
+***************************************************************/
+{
+ LIST Scan,Clauses;
+ SPLIT Split;
+ CLAUSE Clause;
+
+ for (Scan=prfs_UsableClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+ clause_GetFlag(Clause, WORKEDOFF) ||
+ !prfs_IsClauseValid(Clause, prfs_ValidLevel(Search)))
+ return FALSE;
+ }
+
+ for (Scan=prfs_WorkedOffClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+ !clause_GetFlag(Clause,WORKEDOFF) ||
+ !prfs_IsClauseValid(Clause, prfs_ValidLevel(Search)))
+ return FALSE;
+ }
+
+ for (Scan=prfs_SplitStack(Search); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ Split = (SPLIT)list_Car(Scan);
+ if (prfs_SplitIsUsed(Split)) {
+ if (!list_Empty(prfs_SplitBlockedClauses(Split)) ||
+ !list_Empty(prfs_SplitDeletedClauses(Split))) {
+ /*putchar('\n');prfs_PrintSplit(Split); putchar('\n');*/
+ return FALSE;
+ } else {
+ for (Clauses=prfs_UsableClauses(Search);!list_Empty(Clauses);Clauses=list_Cdr(Clauses))
+ if (clause_SplitLevel(list_Car(Clauses)) == prfs_SplitSplitLevel(Split)) {
+ /*puts("\n");prfs_PrintSplit(Split);
+ fputs("\n Clause must not exist: ",stdout);
+ clause_Print(list_Car(Clauses)); putchar('\n');*/
+ return FALSE;
+ }
+ for (Clauses=prfs_WorkedOffClauses(Search);!list_Empty(Clauses);Clauses=list_Cdr(Clauses))
+ if (clause_SplitLevel(list_Car(Clauses)) == prfs_SplitSplitLevel(Split)) {
+ /*puts("\n");prfs_PrintSplit(Split);
+ fputs("\n Clause must not exist: ",stdout);
+ clause_Print(list_Car(Clauses)); putchar('\n');*/
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ if (prfs_ValidLevel(Search) == 0) {
+ if (!prfs_SplitStackEmpty(Search))
+ return FALSE;
+ } else {
+ if (prfs_ValidLevel(Search) != prfs_SplitSplitLevel(prfs_SplitStackTop(Search)))
+ return FALSE;
+ }
+
+ if (prfs_ValidLevel(Search) < prfs_LastBacktrackLevel(Search))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * HIGH LEVEL FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+static void prfs_InsertInSortTheories(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ EFFECT: If the clause is a declaration clause it is inserted
+ into the dynamic and approximated dynamic sort theory.
+ RETURNS: Nothing.
+***************************************************************/
+{
+ if ((prfs_DynamicSortTheory(Search) != (SORTTHEORY)NULL ||
+ prfs_ApproximatedDynamicSortTheory(Search) != (SORTTHEORY)NULL) &&
+ clause_IsDeclarationClause(Clause)) {
+ int i,l;
+ LITERAL lit;
+ CLAUSE copy;
+ LIST approx;
+ l = clause_Length(Clause);
+ for (i = clause_FirstSuccedentLitIndex(Clause); i < l; i++) {
+ lit = clause_GetLiteral(Clause,i);
+ if (clause_LiteralIsMaximal(lit) &&
+ symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(lit)))) {
+ if (prfs_DynamicSortTheory(Search) != (SORTTHEORY)NULL) {
+ copy = clause_Copy(Clause);
+ list_Delete(clause_ParentClauses(copy));
+ clause_SetParentClauses(copy,list_Nil());
+ list_Delete(clause_ParentLiterals(copy));
+ clause_SetParentLiterals(copy,list_Nil());
+ clause_SetNumber(copy,clause_Number(Clause));
+ sort_TheoryInsertClause(prfs_DynamicSortTheory(Search),Clause,
+ copy,clause_GetLiteral(copy,i));
+ }
+ if (prfs_ApproximatedDynamicSortTheory(Search) != (SORTTHEORY)NULL) {
+ approx = sort_ApproxMaxDeclClauses(Clause, prfs_Store(Search),
+ prfs_Precedence(Search));
+ for ( ; !list_Empty(approx); approx = list_Pop(approx)) {
+ copy = (CLAUSE)list_Car(approx);
+ sort_TheoryInsertClause(prfs_ApproximatedDynamicSortTheory(Search),
+ Clause, copy,
+ clause_GetLiteral(copy,clause_FirstSuccedentLitIndex(copy)));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+static void prfs_DeleteFromSortTheories(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ EFFECT: If the clause is a declaration clause it is deleted
+ from the dynamic and approximated dynamic sort theory.
+***************************************************************/
+{
+ if (clause_IsDeclarationClause(Clause)) {
+ if (prfs_DynamicSortTheory(Search) != (SORTTHEORY)NULL)
+ sort_TheoryDeleteClause(prfs_DynamicSortTheory(Search), Clause);
+ if (prfs_ApproximatedDynamicSortTheory(Search) != (SORTTHEORY)NULL)
+ sort_TheoryDeleteClause(prfs_ApproximatedDynamicSortTheory(Search), Clause);
+ }
+}
+
+
+void prfs_DeleteDocProof(PROOFSEARCH Search)
+/**************************************************************
+ INPUT: A proof search object.
+ RETURNS: Nothing.
+ EFFECT: The docproof structures are deleted.
+***************************************************************/
+{
+ clause_DeleteSharedClauseList(prfs_DocProofClauses(Search),
+ prfs_DocProofSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+ if (prfs_DocProofSharingIndex(Search))
+ sharing_IndexDelete(prfs_DocProofSharingIndex(Search));
+ Search->dpindex = NULL;
+ Search->dplist = list_Nil();
+}
+
+
+static void prfs_InternalDelete(PROOFSEARCH Search)
+/**************************************************************
+ INPUT: A proof search object.
+ RETURNS: Nothing.
+ EFFECT: Most of the proofsearch object is deleted.
+ This function implements the common subset of
+ functionality of prfs_Clean and prfs_Delete.
+***************************************************************/
+{
+ LIST Scan;
+
+ clause_DeleteClauseList(prfs_EmptyClauses(Search));
+ list_DeleteWithElement(prfs_Definitions(Search),
+ (void (*)(POINTER)) def_Delete);
+ list_Delete(prfs_UsedEmptyClauses(Search));
+ sort_TheoryDelete(prfs_StaticSortTheory(Search));
+ sort_TheoryDelete(prfs_DynamicSortTheory(Search));
+ sort_TheoryDelete(prfs_ApproximatedDynamicSortTheory(Search));
+ clause_DeleteSharedClauseList(prfs_WorkedOffClauses(Search),
+ prfs_WorkedOffSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+ clause_DeleteSharedClauseList(prfs_UsableClauses(Search),
+ prfs_UsableSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+ clause_DeleteSharedClauseList(prfs_DocProofClauses(Search),
+ prfs_DocProofSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+ prfs_DeleteFinMonPreds(Search);
+ for (Scan=prfs_SplitStack(Search); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ prfs_SplitDelete(list_Car(Scan));
+ list_Delete(prfs_SplitStack(Search));
+}
+
+
+void prfs_Delete(PROOFSEARCH Search)
+/**************************************************************
+ INPUT: A proof search object.
+ RETURNS: Nothing.
+ EFFECT: The whole structure including all its substructures
+ is deleted.
+***************************************************************/
+{
+ prfs_InternalDelete(Search);
+
+ sharing_IndexDelete(prfs_WorkedOffSharingIndex(Search));
+ sharing_IndexDelete(prfs_UsableSharingIndex(Search));
+ if (prfs_DocProofSharingIndex(Search))
+ sharing_IndexDelete(prfs_DocProofSharingIndex(Search));
+ flag_DeleteStore(prfs_Store(Search));
+ symbol_DeletePrecedence(prfs_Precedence(Search));
+ memory_Free(Search,sizeof(PROOFSEARCH_NODE));
+}
+
+
+void prfs_Clean(PROOFSEARCH Search)
+/**************************************************************
+ INPUT: A proof search object.
+ RETURNS: Nothing.
+ EFFECT: All clauses are deleted. The structure is cleaned
+ and initialized.
+***************************************************************/
+{
+ prfs_InternalDelete(Search);
+
+ Search->emptyclauses = list_Nil();
+ Search->definitions = list_Nil();
+ Search->usedemptyclauses = list_Nil();
+ Search->wolist = list_Nil();
+ Search->uslist = list_Nil();
+ Search->finmonpreds = list_Nil();
+ Search->astatic = (SORTTHEORY)NULL;
+ Search->adynamic = (SORTTHEORY)NULL;
+ Search->dynamic = (SORTTHEORY)NULL;
+ Search->dplist = list_Nil();
+
+ Search->stack = list_StackBottom();
+ Search->validlevel = 0;
+ Search->lastbacktrack = 0;
+ Search->splitcounter = 0;
+ Search->keptclauses = 0;
+ Search->derivedclauses = 0;
+ Search->loops = 0;
+ Search->backtracked = 0;
+ Search->nontrivclausenumber = 0;
+
+ symbol_ClearPrecedence(prfs_Precedence(Search));
+}
+
+
+void prfs_SwapIndexes(PROOFSEARCH Search)
+/**************************************************************
+ INPUT: A proof search object.
+ RETURNS: Nothing.
+ EFFECT: The usable and worked-off indexes are exchanged.
+***************************************************************/
+{
+ LIST Scan;
+ SHARED_INDEX Help;
+
+ Help = prfs_WorkedOffSharingIndex(Search);
+ Scan = prfs_WorkedOffClauses(Search);
+ prfs_SetWorkedOffClauses(Search,prfs_UsableClauses(Search));
+ Search->woindex = prfs_UsableSharingIndex(Search);
+ prfs_SetUsableClauses(Search, Scan);
+ Search->usindex = Help;
+
+ for (Scan=prfs_UsableClauses(Search); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ clause_RemoveFlag(list_Car(Scan), WORKEDOFF);
+ for (Scan=prfs_WorkedOffClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ clause_SetFlag(list_Car(Scan), WORKEDOFF);
+}
+
+
+PROOFSEARCH prfs_Create(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: A new proof search object. The worked off and usable
+ indexes are created whilst the docproof index and the
+ sort theories are not created, since they are not
+ needed in general.
+***************************************************************/
+{
+ PROOFSEARCH Result;
+
+ Result = memory_Malloc(sizeof(PROOFSEARCH_NODE));
+
+ Result->emptyclauses = list_Nil();
+ Result->definitions = list_Nil();
+ Result->usedemptyclauses = list_Nil();
+ Result->woindex = sharing_IndexCreate();
+ Result->wolist = list_Nil();
+ Result->usindex = sharing_IndexCreate();
+ Result->uslist = list_Nil();
+ Result->finmonpreds = list_Nil();
+
+ Result->astatic = (SORTTHEORY)NULL;
+ Result->adynamic = (SORTTHEORY)NULL;
+ Result->dynamic = (SORTTHEORY)NULL;
+
+ Result->precedence = symbol_CreatePrecedence();
+
+ Result->store = flag_CreateStore();
+ flag_InitStoreByDefaults(Result->store);
+
+ Result->dpindex = (SHARED_INDEX)NULL;
+ Result->dplist = list_Nil();
+
+ Result->stack = list_StackBottom();
+ Result->validlevel = 0;
+ Result->lastbacktrack = 0;
+ Result->splitcounter = 0;
+ Result->keptclauses = 0;
+ Result->derivedclauses = 0;
+ Result->loops = 0;
+ Result->backtracked = 0;
+ Result->nontrivclausenumber = 0;
+
+ return Result;
+}
+
+
+void prfs_CopyIndices(PROOFSEARCH Search, PROOFSEARCH SearchCopy)
+/**************************************************************
+ INPUT: A proof search object and a clean proof search object.
+ RETURNS: Nothing.
+ EFFECT: Copies the indices from Search to SearchCopy.
+ CAUTION: Splitstack and theories are not copied!
+***************************************************************/
+{
+ LIST Scan;
+
+ /* If a DocProof index is required but not yet allocated in SearchCopy,
+ do it now */
+ if (prfs_DocProofSharingIndex(Search) != NULL &&
+ prfs_DocProofSharingIndex(SearchCopy) == NULL)
+ prfs_AddDocProofSharingIndex(SearchCopy);
+
+ /* Copy usable, worked-off and docproof index */
+ for (Scan = prfs_UsableClauses(Search); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ prfs_InsertUsableClause(SearchCopy, clause_Copy((CLAUSE) list_Car(Scan)));
+
+ for (Scan = prfs_WorkedOffClauses(Search); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ prfs_InsertWorkedOffClause(SearchCopy, clause_Copy((CLAUSE) list_Car(Scan)));
+
+ for (Scan = prfs_DocProofClauses(Search); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ prfs_InsertDocProofClause(SearchCopy, clause_Copy((CLAUSE) list_Car(Scan)));
+}
+
+
+void prfs_InsertWorkedOffClause(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ MEMORY: The clause is assumed to be unshared.
+ EFFECT: The clause is inserted into the worked off sharing index
+ and list of <Search>. The unshared literals are deleted.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsClause(Clause,prfs_Store(Search), prfs_Precedence(Search))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_InsertWorkedOffClause: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ clause_SetFlag(Clause,WORKEDOFF);
+ prfs_SetWorkedOffClauses(Search,list_Cons(Clause, prfs_WorkedOffClauses(Search)));
+ clause_InsertIntoSharing(Clause, prfs_WorkedOffSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+ prfs_InsertInSortTheories(Search, Clause);
+}
+
+
+void prfs_InsertUsableClause(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ MEMORY: The clause is assumed to be unshared.
+ EFFECT: The clause is inserted into the usable sharing index
+ and list of <Search> sorted with respect to their weight.
+ The unshared literals are deleted.
+***************************************************************/
+{
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+ clause_GetFlag(Clause, WORKEDOFF)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_InsertUsableClause: Illegal input.");
+ misc_FinishErrorReport();
+ }
+ /* The invariant that no two clauses have the same clause number cannot */
+ /* be guaranteed as long as e.g. several directly subsequent reductions */
+ /* are applied to a clause that eventually gets a greater split level. */
+#endif
+
+ prfs_SetUsableClauses(Search,clause_InsertWeighed(Clause,
+ prfs_UsableClauses(Search),
+ prfs_Store(Search),
+ prfs_Precedence(Search)));
+ clause_InsertIntoSharing(Clause, prfs_UsableSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+}
+
+
+void prfs_InsertDocProofClause(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ MEMORY: The clause is assumed to be unshared.
+ EFFECT: The clause is inserted into the proof documentation sharing index.
+ The unshared literals are deleted.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_InsertDocProofClause: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (prfs_DocProofSharingIndex(Search) == (SHARED_INDEX)NULL)
+ clause_Delete(Clause);
+ else {
+ prfs_SetDocProofClauses(Search,list_Cons(Clause, prfs_DocProofClauses(Search)));
+ clause_InsertIntoSharing(Clause, prfs_DocProofSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+ }
+}
+
+
+void prfs_MoveUsableWorkedOff(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ EFFECT: The clause is inserted into the worked off sharing index
+ and list and it is deleted from the usable index and list.
+ In particular, the WorkedOff flag is set and if <Clause> is a
+ declaration clause, it is inserted into the respective sort theories.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsClause(Clause,prfs_Store(Search), prfs_Precedence(Search)) ||
+ clause_GetFlag(Clause, WORKEDOFF)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_MoveUsableWorkedOff: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ prfs_SetUsableClauses(Search,list_PointerDeleteElement(prfs_UsableClauses(Search),Clause));
+ clause_SetFlag(Clause,WORKEDOFF);
+ clause_MoveSharedClause(Clause, prfs_UsableSharingIndex(Search),
+ prfs_WorkedOffSharingIndex(Search), prfs_Store(Search),
+ prfs_Precedence(Search));
+ prfs_SetWorkedOffClauses(Search,list_Cons(Clause, prfs_WorkedOffClauses(Search)));
+ prfs_InsertInSortTheories(Search, Clause);
+}
+
+
+void prfs_MoveWorkedOffDocProof(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ EFFECT: The clause is inserted into the doc proof sharing index
+ and list of <Search> and it is deleted from the worked off
+ index and list.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+ !clause_GetFlag(Clause, WORKEDOFF)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_MoveWorkedOffDocProof: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ prfs_DeleteFromSortTheories(Search, Clause);
+ prfs_SetWorkedOffClauses(Search,list_PointerDeleteElement(prfs_WorkedOffClauses(Search),Clause));
+ clause_RemoveFlag(Clause,WORKEDOFF);
+
+ if (prfs_DocProofSharingIndex(Search) == (SHARED_INDEX)NULL)
+ clause_DeleteFromSharing(Clause,prfs_WorkedOffSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+ else {
+ clause_MoveSharedClause(Clause, prfs_WorkedOffSharingIndex(Search),
+ prfs_DocProofSharingIndex(Search),prfs_Store(Search),
+ prfs_Precedence(Search));
+ prfs_SetDocProofClauses(Search,list_Cons(Clause, prfs_DocProofClauses(Search)));
+ }
+}
+
+
+void prfs_MoveUsableDocProof(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ EFFECT: The clause is inserted into the doc proof sharing index
+ and list of <Search> and it is deleted from the usable
+ index and list.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+ clause_GetFlag(Clause, WORKEDOFF)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_MoveUsableDocProof: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ prfs_SetUsableClauses(Search,list_PointerDeleteElement(prfs_UsableClauses(Search),Clause));
+
+ if (prfs_DocProofSharingIndex(Search) == (SHARED_INDEX)NULL)
+ clause_DeleteFromSharing(Clause, prfs_UsableSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+ else {
+ clause_MoveSharedClause(Clause, prfs_UsableSharingIndex(Search),
+ prfs_DocProofSharingIndex(Search),prfs_Store(Search),
+ prfs_Precedence(Search));
+ prfs_SetDocProofClauses(Search,list_Cons(Clause, prfs_DocProofClauses(Search)));
+ }
+}
+
+
+void prfs_MoveInvalidClausesDocProof(PROOFSEARCH Search)
+/**************************************************************
+ INPUT: A proof search object.
+ RETURNS: Nothing.
+ EFFECT: All clauses that have a split level higher than the
+ current split level of <Search> are moved to the
+ proof documentation index. If it does not exist, i.e.,
+ no proof documentation required, the clauses are
+ deleted.
+***************************************************************/
+{
+ LIST scan, invalid;
+ CLAUSE clause;
+
+ invalid = list_Nil();
+ for (scan = prfs_WorkedOffClauses(Search); !list_Empty(scan);
+ scan = list_Cdr(scan)) {
+ clause = (CLAUSE)list_Car(scan);
+ if (!prfs_IsClauseValid(clause, prfs_ValidLevel(Search)))
+ invalid = list_Cons(clause,invalid);
+ }
+ /* WARNING: The following move operation changes the worked off */
+ /* set of the proof search object destructively. */
+ /* So it's impossible to move those function calls into the */
+ /* loop above. */
+ for ( ; !list_Empty(invalid); invalid = list_Pop(invalid))
+ prfs_MoveWorkedOffDocProof(Search,list_Car(invalid));
+
+ invalid = list_Nil();
+ for (scan = prfs_UsableClauses(Search); !list_Empty(scan);
+ scan = list_Cdr(scan)) {
+ clause = (CLAUSE)list_Car(scan);
+ if (!prfs_IsClauseValid(clause, prfs_ValidLevel(Search)))
+ invalid = list_Cons(clause,invalid);
+ }
+ /* WARNING: The following move operation changes the usable */
+ /* set of the proof search object destructively. */
+ /* So it's impossible to move those function calls into the */
+ /* loop above. */
+ for ( ; !list_Empty(invalid); invalid = list_Pop(invalid))
+ prfs_MoveUsableDocProof(Search,list_Car(invalid));
+}
+
+
+void prfs_ExtractWorkedOff(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ EFFECT: The clause is removed from the worked off index and
+ list and returned as an unshared clause.
+ Sort theories are updated accordingly.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause) || !clause_GetFlag(Clause, WORKEDOFF)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_ExtractWorkedOff: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ prfs_DeleteFromSortTheories(Search, Clause);
+ clause_RemoveFlag(Clause,WORKEDOFF);
+ prfs_SetWorkedOffClauses(Search,list_PointerDeleteElement(prfs_WorkedOffClauses(Search),Clause));
+ clause_MakeUnshared(Clause,prfs_WorkedOffSharingIndex(Search));
+}
+
+
+void prfs_ExtractUsable(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ EFFECT: The clause is removed from the usable off index and
+ list and returned as an unshared clause.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause) || clause_GetFlag(Clause, WORKEDOFF)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_ExtractUsable: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ prfs_SetUsableClauses(Search,list_PointerDeleteElement(prfs_UsableClauses(Search),Clause));
+ clause_MakeUnshared(Clause,prfs_UsableSharingIndex(Search));
+}
+
+
+void prfs_ExtractDocProof(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ EFFECT: The clause is removed from the docproof off index and
+ list and returned as an unshared clause.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsUnorderedClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_ExtractDocProof: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ prfs_SetDocProofClauses(Search,list_PointerDeleteElement(prfs_DocProofClauses(Search),Clause));
+ clause_MakeUnshared(Clause,prfs_DocProofSharingIndex(Search));
+}
+
+
+void prfs_DeleteWorkedOff(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ EFFECT: The clause is deleted from the worked off index and list.
+ Sort theories are updated accordingly.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+ !clause_GetFlag(Clause, WORKEDOFF)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_DeleteWorkedOff: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ prfs_DeleteFromSortTheories(Search, Clause);
+ prfs_SetWorkedOffClauses(Search,list_PointerDeleteElement(prfs_WorkedOffClauses(Search),Clause));
+ clause_DeleteFromSharing(Clause, prfs_WorkedOffSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+}
+
+
+void prfs_DeleteUsable(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and a clause.
+ RETURNS: Nothing.
+ EFFECT: The clause is deleted from the usable index and list.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+ clause_GetFlag(Clause, WORKEDOFF)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_DeleteUsable: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ prfs_SetUsableClauses(Search,list_PointerDeleteElement(prfs_UsableClauses(Search),Clause));
+ clause_DeleteFromSharing(Clause,prfs_UsableSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+}
+
+
+void prfs_PrintSplit(SPLIT Split)
+/**************************************************************
+ INPUT: A split.
+ RETURNS: Nothing.
+ EFFECT: Prints the information kept in the split structure.
+***************************************************************/
+{
+ LIST Scan;
+
+ printf("\n Split: %d %ld", prfs_SplitSplitLevel(Split), (long)Split);
+ fputs("\n Father: ", stdout);
+ if (prfs_SplitFatherClause(Split) != (CLAUSE)NULL)
+ clause_Print(prfs_SplitFatherClause(Split));
+ else
+ fputs("No father, unnecessary split.", stdout);
+
+ fputs("\n Split is ", stdout);
+ if (prfs_SplitIsUnused(Split))
+ puts("unused.");
+ else
+ puts("used.");
+ fputs(" Blocked clauses:", stdout);
+ for (Scan=prfs_SplitBlockedClauses(Split);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ putchar('\n');
+ putchar(' ');
+ clause_Print(list_Car(Scan));
+ }
+ fputs("\n Deleted clauses:", stdout);
+ for (Scan=prfs_SplitDeletedClauses(Split);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ putchar('\n');
+ putchar(' ');
+ clause_Print(list_Car(Scan));
+ }
+}
+
+
+void prfs_PrintSplitStack(PROOFSEARCH PS)
+/**************************************************************
+ INPUT: A proof search object.
+ RETURNS: Nothing.
+ EFFECT: Prints almost all the information kept in the
+ split stack structure.
+***************************************************************/
+{
+ LIST Scan;
+
+ fputs("\n Splitstack:", stdout);
+
+ for (Scan = prfs_SplitStack(PS); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ prfs_PrintSplit(list_Car(Scan));
+ fputs("\n---------------------", stdout);
+ }
+}
+
+
+void prfs_Print(PROOFSEARCH Search)
+/**************************************************************
+ INPUT: A proof search object.
+ RETURNS: void.
+ EFFECT: The proof search object is printed to stdout.
+***************************************************************/
+{
+ LIST Scan;
+
+#ifdef CHECK
+ if (!prfs_Check(Search)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_Print: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ printf("\n\n Proofsearch: Current Level: %d Last Backtrack Level: %d Splits: %d Loops: %d Backtracked: %d",
+ prfs_ValidLevel(Search),prfs_LastBacktrackLevel(Search),prfs_SplitCounter(Search),
+ prfs_Loops(Search),prfs_BacktrackedClauses(Search));
+ if (prfs_NonTrivClauseNumber(Search)>0)
+ printf("\n Clause %d implies a non-trivial domain.", prfs_NonTrivClauseNumber(Search));
+ else
+ fputs("\n Potentially trivial domain.", stdout);
+ fputs("\n Empty Clauses:", stdout);
+ for (Scan=prfs_EmptyClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ fputs("\n ", stdout);
+ clause_Print(list_Car(Scan));
+ }
+ fputs("\n Definitions:", stdout);
+ for (Scan=prfs_Definitions(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ putchar('\n');
+ putchar(' ');
+ term_Print(list_Car(Scan));
+ }
+ fputs("\n Worked Off Clauses:", stdout);
+ for (Scan=prfs_WorkedOffClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ putchar('\n');
+ putchar(' ');
+ clause_Print(list_Car(Scan));
+ }
+ fputs("\n Usable Clauses:", stdout);
+ for (Scan=prfs_UsableClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ putchar('\n');
+ putchar(' ');
+ clause_Print(list_Car(Scan));
+ }
+ fputs("\n Finite predicates:", stdout);
+ for (Scan=prfs_GetFinMonPreds(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ fputs("\n ", stdout);
+ symbol_Print((SYMBOL)list_PairFirst(list_Car(Scan)));
+ fputs(": ", stdout);
+ term_TermListPrintPrefix(list_PairSecond(list_Car(Scan)));
+ }
+ prfs_PrintSplitStack(Search);
+ fputs("\n Static Sort Theory:", stdout);
+ sort_TheoryPrint(prfs_StaticSortTheory(Search));
+ fputs("\n Dynamic Sort Theory:", stdout);
+ sort_TheoryPrint(prfs_DynamicSortTheory(Search));
+ fputs("\n Approximated Dynamic Sort Theory:", stdout);
+ sort_TheoryPrint(prfs_ApproximatedDynamicSortTheory(Search));
+ putchar('\n');
+}
+
+
+CLAUSE prfs_DoSplitting(PROOFSEARCH PS, CLAUSE SplitClause, LIST Literals)
+/**************************************************************
+ INPUT: An proof search object, an unshared clause to be splitted
+ where 'Literals' is the list of literals to keep (in their
+ order in the SplitClause).
+ RETURNS: A pointer to the (stack-, not sharing-) inserted splitted clause.
+ MEMORY: The blocked parts and the actparts literals are created
+ unshared, memory for the two (more for HornSplits) new
+ clausenodes is allocated.
+ EFFECT: A new SPLIT object is created on the split stack of the proof
+ search object. The clause for the right branch will get clause
+ number 0 to make it distinguishable from the negation clauses,
+ which get clause number -1.
+ All newly created clauses are influenced by some flags of the
+ internal flag store of the proof search object.
+ For example the maximal literals are influenced by
+ the weight of function symbols, which is defined by the
+ flag "flag_FUNCWEIGHT".
+***************************************************************/
+{
+
+ SPLIT NewSplit;
+ CLAUSE NewClause, BlockedClause;
+ LITERAL NextLit,NewLit;
+ int i,j,lengthBlocked,lengthNew,lc,la,ls,nc,na,ns;
+
+#ifdef CHECK
+ if (list_Empty(Literals) ||
+ !clause_IsClause(SplitClause, prfs_Store(PS), prfs_Precedence(PS))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_DoSplitting: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ prfs_DecSplitCounter(PS);
+ NewSplit = prfs_SplitCreate(PS);
+
+ prfs_SplitSetFatherClause(NewSplit, SplitClause);
+
+ lengthNew = list_Length(Literals);
+ lengthBlocked = clause_Length(SplitClause) - lengthNew;
+
+ NewClause = clause_CreateBody(lengthNew); /* The left clause */
+ BlockedClause = clause_CreateBody(lengthBlocked); /* The right clause */
+ clause_DecreaseCounter(); /* reset internally increased counter! */
+ clause_SetNumber(BlockedClause, 0);
+ /* To detect forgotten setting at insertion! */
+
+ lc = clause_LastConstraintLitIndex(SplitClause);
+ la = clause_LastAntecedentLitIndex(SplitClause);
+ ls = clause_LastSuccedentLitIndex(SplitClause);
+
+ nc = na = ns = 0;
+
+ j = clause_FirstLitIndex();
+
+ for (i = clause_FirstLitIndex(); i <= ls; i++) {
+ NextLit = clause_GetLiteral(SplitClause, i);
+
+ NewLit = clause_LiteralCopy(NextLit);
+
+ if ((lengthNew > 0) && /* To avoid access of Nirvana. */
+ list_PointerMember(Literals, NextLit)) {
+ /* NewLit is literal for the NewClause. */
+
+ lengthNew--;
+ clause_SetLiteral(NewClause, j++, NewLit);
+ clause_LiteralSetOwningClause(NewLit, NewClause);
+ clause_AddParentClause(NewClause, clause_Number(SplitClause));
+ clause_AddParentLiteral(NewClause, i);
+ if (i <= lc)
+ nc++;
+ else if (i <= la)
+ na++;
+ else
+ ns++;
+
+ } else { /* NewLit is literal for the BlockedClause. */
+
+ clause_SetLiteral(BlockedClause, (i-j), NewLit);
+ clause_LiteralSetOwningClause(NewLit, BlockedClause);
+ clause_AddParentClause(BlockedClause, clause_Number(SplitClause));
+ clause_AddParentLiteral(BlockedClause, i);
+ }
+ } /* end of 'for all literals'. */
+
+ clause_SetNumOfConsLits(NewClause, nc);
+ clause_SetNumOfConsLits(BlockedClause,
+ (clause_NumOfConsLits(SplitClause) - nc));
+ clause_SetNumOfAnteLits(NewClause, na);
+ clause_SetNumOfAnteLits(BlockedClause,
+ (clause_NumOfAnteLits(SplitClause) - na));
+ clause_SetNumOfSuccLits(NewClause, ns);
+ clause_SetNumOfSuccLits(BlockedClause,
+ (clause_NumOfSuccLits(SplitClause) - ns));
+
+ clause_ReInit(BlockedClause, prfs_Store(PS), prfs_Precedence(PS));
+ clause_UpdateSplitDataFromNewSplitting(BlockedClause, SplitClause,
+ prfs_SplitSplitLevel(NewSplit));
+ clause_SetFromSplitting(BlockedClause);
+ clause_SetParentLiterals(BlockedClause,
+ list_NReverse(clause_ParentLiterals(BlockedClause)));
+
+ clause_SetDepth(BlockedClause, clause_Depth(SplitClause)+1);
+
+ prfs_SplitAddBlockedClause(NewSplit, BlockedClause);
+ prfs_SplitSetDeletedClauses(NewSplit, list_Nil());
+
+
+ prfs_SplitStackPush(PS, NewSplit);
+
+ clause_ReInit(NewClause, prfs_Store(PS), prfs_Precedence(PS));
+ clause_UpdateSplitDataFromNewSplitting(NewClause, SplitClause,
+ prfs_SplitSplitLevel(NewSplit));
+ clause_SetFromSplitting(NewClause);
+
+ clause_SetParentLiterals(NewClause,
+ list_NReverse(clause_ParentLiterals(NewClause)));
+
+ clause_SetDepth(NewClause, clause_Depth(SplitClause)+1);
+ clause_RemoveFlag(NewClause, WORKEDOFF);
+
+ if (clause_IsGround(NewClause)) {
+ /* Keep Clauses made from NewClause for refutation case! */
+ CLAUSE UnitClause;
+ LIST AtomList;
+
+ la = clause_LastAntecedentLitIndex(NewClause);
+ ls = clause_LastSuccedentLitIndex(NewClause);
+
+ Literals = clause_ParentLiterals(NewClause);
+
+ for (i = clause_FirstLitIndex(); i <= ls; i++) {
+
+ NextLit = clause_GetLiteral(NewClause, i);
+ AtomList = list_List(term_Copy(clause_LiteralAtom(NextLit)));
+
+ if (i <= la)
+ UnitClause = clause_Create(list_Nil(), list_Nil(), AtomList,
+ prfs_Store(PS), prfs_Precedence(PS));
+ else
+ UnitClause = clause_Create(list_Nil(), AtomList, list_Nil(),
+ prfs_Store(PS), prfs_Precedence(PS));
+
+ clause_SetNumber(UnitClause, -1);
+ /* To detect forgotten setting at reinsertion! */
+ clause_DecreaseCounter();
+ /* Reset internally increased counter! */
+
+ list_Delete(AtomList);
+
+ clause_SetFromSplitting(UnitClause);
+ clause_UpdateSplitDataFromNewSplitting(UnitClause, SplitClause,
+ prfs_SplitSplitLevel(NewSplit));
+ clause_AddParentClause(UnitClause, clause_Number(NewClause));
+ clause_AddParentLiteral(UnitClause, i);
+ clause_AddParentClause(UnitClause, clause_Number(SplitClause));
+ clause_AddParentLiteral(UnitClause, (int)list_Car(Literals));
+ Literals = list_Cdr(Literals);
+ prfs_SplitAddBlockedClause(NewSplit, UnitClause);
+ }
+ }
+ /* fputs("\n\nSPLITTING DONE!",stdout);
+ fputs("\nAus : ",stdout); clause_Print(SplitClause); fflush(stdout);
+ fputs("\nDer erste Teil: ",stdout); clause_Print(NewClause); fflush(stdout);
+ fputs("\nDer zweite Teil: ",stdout);
+ clause_Print(BlockedClause); fflush(stdout);
+ puts("\nDaher als BlockedClauses:");
+ clause_ListPrint(prfs_SplitBlockedClauses(NewSplit)); fflush(stdout);
+ */
+ return NewClause;
+}
+
+
+static LIST prfs_GetSplitLiterals(PROOFSEARCH PS, CLAUSE Clause)
+/**************************************************************
+ INPUT: A Clause and a proofsearch object
+ RETURNS: A list of literals building the bigger part of a
+ variable-disjunct literal partition if one exists,
+ an empty list, else.
+ MEMORY: Allocates memory for the literal list.
+***************************************************************/
+{
+ LITERAL NextLit;
+ int i, length, OldLength;
+ LIST LitList, VarOcc, NextOcc;
+ BOOL Change;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, prfs_Store(PS), prfs_Precedence(PS))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In prfs_GetSplitLiterals: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ LitList = list_Nil();
+
+ if (prfs_SplitCounter(PS) != 0) {
+
+ if (clause_HasSuccLits(Clause)) {
+ if (clause_HasGroundSuccLit(Clause)) {
+
+ NextLit = clause_GetGroundSuccLit(Clause);
+ LitList = list_Cons(NextLit, LitList);
+
+ for (i = clause_LastAntecedentLitIndex(Clause);i >= clause_FirstLitIndex();i--) {
+ NextLit = clause_GetLiteral(Clause, i);
+ if (term_IsGround(clause_LiteralAtom(NextLit)))
+ LitList = list_Cons(NextLit, LitList);
+ }
+ return LitList;
+ }
+
+ /* Clause has no ground succedent literals, but > 1 non-ground */
+ NextLit = clause_GetLiteral(Clause, clause_LastSuccedentLitIndex(Clause));
+ VarOcc = term_VariableSymbols(clause_LiteralAtom(NextLit));
+ LitList = list_List(NextLit);
+ length = clause_Length(Clause);
+ Change = TRUE;
+
+ while (Change) {
+ Change = FALSE;
+
+ for (i=clause_LastSuccedentLitIndex(Clause)-1; i>=clause_FirstLitIndex(); i--) {
+
+ NextLit = clause_GetLiteral(Clause, i);
+
+ if (!list_PointerMember(LitList, NextLit)) {
+ NextOcc = term_VariableSymbols(clause_LiteralAtom(NextLit));
+ if (list_HasIntersection(VarOcc, NextOcc)) {
+ OldLength = list_Length(VarOcc);
+ VarOcc = list_NPointerUnion(VarOcc, NextOcc);
+ LitList = list_Cons(NextLit, LitList);
+ if (OldLength != list_Length(VarOcc))
+ Change = TRUE;
+ }
+ else
+ list_Delete(NextOcc);
+ }
+ }
+ }
+ if (list_Length(LitList) == length) {
+ list_Delete(LitList);
+ LitList = list_Nil();
+ }
+ Change = TRUE; /* Check whether not all succedent literals are used */
+ for (i = clause_FirstSuccedentLitIndex(Clause); i < length && Change; i++)
+ if (!list_PointerMember(LitList,clause_GetLiteral(Clause, i)))
+ Change = FALSE;
+ if (Change) {
+ list_Delete(LitList);
+ LitList = list_Nil();
+ }
+ list_Delete(VarOcc);
+ }
+ }
+ return LitList;
+}
+
+
+CLAUSE prfs_PerformSplitting(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+ INPUT: A proof search object and an unshared clause.
+ EFFECT: If <Clause> can be split it is splitted, the first
+ part of the split is returned and the
+ splitted clause is kept in the split stack.
+ Otherwise <Clause> remains unchanged and NULL is returned.
+ RETURNS: NULL if <Clause> is not splittable, the first split part otherwise.
+***************************************************************/
+{
+ CLAUSE Result;
+
+ Result = (CLAUSE)NULL;
+
+ if (clause_HasSolvedConstraint(Clause)) {
+ LIST LitList;
+
+ LitList = prfs_GetSplitLiterals(Search, Clause);
+
+ if (!list_Empty(LitList)) {
+ Result = prfs_DoSplitting(Search, Clause, LitList);
+ list_Delete(LitList);
+ }
+ }
+
+ return Result;
+}
+
+
+void prfs_InstallFiniteMonadicPredicates(PROOFSEARCH Search, LIST Clauses,
+ LIST Predicates)
+/**************************************************************
+ INPUT: A proof search object a list of clauses and a list
+ of monadic predicates.
+ RETURNS: Nothing.
+ EFFECT: The argument terms for <Predicates> that occur in
+ positive unit clauses are extracted from <Clauses>
+ and installed in <Search> as an assoc list.
+***************************************************************/
+{
+ LIST Pair, Scan, Result;
+ CLAUSE Clause;
+ TERM Atom;
+
+ Result = list_Nil();
+
+ for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ if (clause_Length(Clause) == 1 &&
+ clause_NumOfSuccLits(Clause) == 1) {
+ Atom = clause_GetLiteralAtom(Clause,clause_FirstSuccedentLitIndex(Clause));
+ if (list_PointerMember(Predicates, (POINTER)term_TopSymbol(Atom))) {
+ Pair = list_AssocListPair(Result, (POINTER)term_TopSymbol(Atom));
+ if (Pair != list_PairNull())
+ list_PairRplacSecond(Pair, list_Cons(term_Copy(term_FirstArgument(Atom)),list_PairSecond(Pair)));
+ else
+ Result = list_AssocCons(Result, (POINTER)term_TopSymbol(Atom),
+ list_List(term_Copy(term_FirstArgument(Atom))));
+ }
+ }
+ }
+
+ prfs_DeleteFinMonPreds(Search);
+ prfs_SetFinMonPreds(Search, Result);
+}
+
+
+NAT prfs_GetNumberOfInstances(PROOFSEARCH Search, LITERAL Literal, BOOL Usables)
+/**************************************************************
+ INPUT: A proof search object, a literal, and a boolean flag.
+ RETURNS: The number of instances of the literal's atom.
+ EFFECT:
+***************************************************************/
+{
+ TERM Atom;
+ NAT NrOfInstances;
+ SHARED_INDEX WOIndex, UsIndex;
+
+ Atom = clause_LiteralAtom(Literal);
+ WOIndex = prfs_WorkedOffSharingIndex(Search);
+ UsIndex = prfs_UsableSharingIndex(Search);
+ NrOfInstances = sharing_GetNumberOfInstances(Atom, WOIndex);
+ if (Usables)
+ NrOfInstances += sharing_GetNumberOfInstances(Atom, UsIndex);
+
+ if (fol_IsEquality(Atom)) {
+ /* Exchange the subterms of the equation, and count the instances, too */
+ Atom = term_Create(fol_Equality(), list_Reverse(term_ArgumentList(Atom)));
+
+ NrOfInstances += sharing_GetNumberOfInstances(Atom, WOIndex);
+ if (Usables)
+ NrOfInstances += sharing_GetNumberOfInstances(Atom, UsIndex);
+
+ list_Delete(term_ArgumentList(Atom));
+ term_Free(Atom);
+
+ /* If equation is oriented, consider instances of the greater side, too */
+ Atom = clause_LiteralAtom(Literal);
+ if (clause_LiteralIsOrientedEquality(Literal)) {
+ NrOfInstances += sharing_GetNumberOfInstances(term_FirstArgument(Atom),
+ WOIndex);
+ if (Usables)
+ NrOfInstances += sharing_GetNumberOfInstances(term_FirstArgument(Atom),
+ UsIndex);
+ }
+ }
+
+ return NrOfInstances;
+}
diff --git a/test/spass/search.h b/test/spass/search.h
new file mode 100644
index 0000000..c34eb8a
--- /dev/null
+++ b/test/spass/search.h
@@ -0,0 +1,522 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * REPRESENTATION OF PROOF SEARCH * */
+/* * * */
+/* * $Module: PROOF SEARCH * */
+/* * * */
+/* * Copyright (C) 1997, 1998, 1999, 2000 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _PROOFSEARCH_
+#define _PROOFSEARCH_
+
+#include "clause.h"
+#include "sort.h"
+
+/**************************************************************/
+/* Data Structures and Constants */
+/**************************************************************/
+
+/* <blockedClauses>: list of (unshared) clauses containing the */
+/* "remainder" of the clause splitted at this */
+/* level and the negation of the first branch */
+/* if this branch created a ground clause. */
+/* The right clause has clause number 0, and */
+/* the negation clauses have number -1. */
+/* <deletedClauses>: list of (unshared) clauses made redundant */
+/* by a clause of this level. The split level */
+/* of these clauses may be above or below the */
+/* current level, but not equal to the current */
+/* level. */
+/* <father>: the unshared clause that was splitted. */
+typedef struct {
+ /* == 0 -> TOPLEVEL, 1,2,... */
+ int splitlevel;
+ BOOL used;
+ LIST blockedClauses, deletedClauses;
+ CLAUSE father;
+} *SPLIT, SPLIT_NODE;
+
+
+typedef struct PROOFSEARCH_HELP {
+ LIST definitions;
+ LIST emptyclauses;
+ LIST usedemptyclauses;
+ LIST finmonpreds;
+ SHARED_INDEX woindex;
+ LIST wolist;
+ SHARED_INDEX usindex;
+ LIST uslist;
+ SORTTHEORY astatic;
+ SORTTHEORY adynamic;
+ SORTTHEORY dynamic;
+ SHARED_INDEX dpindex;
+ LIST dplist;
+ PRECEDENCE precedence;
+ FLAGSTORE store;
+ LIST stack;
+ int validlevel;
+ int lastbacktrack;
+ int splitcounter;
+ int keptclauses;
+ int derivedclauses;
+ int loops;
+ int backtracked;
+ NAT nontrivclausenumber;
+} PROOFSEARCH_NODE,*PROOFSEARCH;
+
+/* There are two sets of clauses with their respective clause list: worked-off clauses */
+/* contained in <woindex>, <wolist> and usable clauses, contained in <usindex>,<uslist>. */
+/* The assoc list <finitepreds> is a list of pairs (<pred>.(<gterm1>,...,<gtermn>)) */
+/* where <pred> (monadic) has (at most) the extension <gterm1>,...,<gtermn> */
+/* Three sort theories: <astatic> is the static overall approximation, only available */
+/* in a non-equality setting, <adynamic> is the dynamic approximation only considering */
+/* maximal declarations, and <dynamic> is the (not approximated) dynamic sort theory of */
+/* all maximal declarations. Clauses that are no longer needed for the search, but for */
+/* proof documentation are stored in <dpindex>, <dplist>. If <dpindex> is NULL, then */
+/* this means that no proof documentation is required. */
+/* A search is also heavily influenced by the used <precedence> and flag values in */
+/* store. */
+/* The next components deal with splitting: the split stack, the current level */
+/* of splitting, the last backtrack level (for branch condensing) and the overall number */
+/* of splittings stored in <splitcounter>. */
+/* Finally some statistics is stored: the number of kept, derived clauses ... */
+/* and the clause number of some clause that implies a non-trivial domain . */
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+static __inline__ LIST prfs_EmptyClauses(PROOFSEARCH Prf)
+{
+ return Prf->emptyclauses;
+}
+
+static __inline__ void prfs_SetEmptyClauses(PROOFSEARCH Prf, LIST Clauses)
+{
+ Prf->emptyclauses = Clauses;
+}
+
+static __inline__ LIST prfs_Definitions(PROOFSEARCH Prf)
+{
+ return Prf->definitions;
+}
+
+static __inline__ void prfs_SetDefinitions(PROOFSEARCH Prf, LIST Definitions)
+{
+ Prf->definitions = Definitions;
+}
+
+static __inline__ LIST prfs_UsedEmptyClauses(PROOFSEARCH Prf)
+{
+ return Prf->usedemptyclauses;
+}
+
+static __inline__ void prfs_SetUsedEmptyClauses(PROOFSEARCH Prf, LIST Clauses)
+{
+ Prf->usedemptyclauses = Clauses;
+}
+
+
+static __inline__ LIST prfs_WorkedOffClauses(PROOFSEARCH Prf)
+{
+ return Prf->wolist;
+}
+
+static __inline__ void prfs_SetWorkedOffClauses(PROOFSEARCH Prf, LIST Clauses)
+{
+ Prf->wolist = Clauses;
+}
+
+static __inline__ SHARED_INDEX prfs_WorkedOffSharingIndex(PROOFSEARCH Prf)
+{
+ return Prf->woindex;
+}
+
+static __inline__ LIST prfs_UsableClauses(PROOFSEARCH Prf)
+{
+ return Prf->uslist;
+}
+
+static __inline__ void prfs_SetUsableClauses(PROOFSEARCH Prf, LIST Clauses)
+{
+ Prf->uslist = Clauses;
+}
+
+static __inline__ SHARED_INDEX prfs_UsableSharingIndex(PROOFSEARCH Prf)
+{
+ return Prf->usindex;
+}
+
+static __inline__ LIST prfs_DocProofClauses(PROOFSEARCH Prf)
+{
+ return Prf->dplist;
+}
+
+static __inline__ void prfs_SetDocProofClauses(PROOFSEARCH Prf, LIST Clauses)
+{
+ Prf->dplist = Clauses;
+}
+
+static __inline__ SHARED_INDEX prfs_DocProofSharingIndex(PROOFSEARCH Prf)
+{
+ return Prf->dpindex;
+}
+
+static __inline__ void prfs_AddDocProofSharingIndex(PROOFSEARCH Prf)
+{
+ Prf->dpindex = sharing_IndexCreate();
+}
+
+static __inline__ LIST prfs_GetFinMonPreds(PROOFSEARCH Prf)
+{
+ return Prf->finmonpreds;
+}
+
+static __inline__ void prfs_SetFinMonPreds(PROOFSEARCH Prf, LIST Preds)
+{
+ Prf->finmonpreds = Preds;
+}
+
+static __inline__ void prfs_DeleteFinMonPreds(PROOFSEARCH Prf)
+{
+ list_DeleteAssocListWithValues(Prf->finmonpreds,
+ (void (*)(POINTER)) term_DeleteTermList);
+ prfs_SetFinMonPreds(Prf, list_Nil());
+}
+
+static __inline__ SORTTHEORY prfs_StaticSortTheory(PROOFSEARCH Prf)
+{
+ return Prf->astatic;
+}
+
+static __inline__ void prfs_SetStaticSortTheory(PROOFSEARCH Prf, SORTTHEORY Theory)
+{
+ Prf->astatic = Theory;
+}
+
+static __inline__ SORTTHEORY prfs_DynamicSortTheory(PROOFSEARCH Prf)
+{
+ return Prf->dynamic;
+}
+
+static __inline__ void prfs_SetDynamicSortTheory(PROOFSEARCH Prf, SORTTHEORY Theory)
+{
+ Prf->dynamic = Theory;
+}
+
+static __inline__ SORTTHEORY prfs_ApproximatedDynamicSortTheory(PROOFSEARCH Prf)
+{
+ return Prf->adynamic;
+}
+
+static __inline__ void prfs_SetApproximatedDynamicSortTheory(PROOFSEARCH Prf, SORTTHEORY Theory)
+{
+ Prf->adynamic = Theory;
+}
+
+static __inline__ PRECEDENCE prfs_Precedence(PROOFSEARCH Prf)
+{
+ return Prf->precedence;
+}
+
+static __inline__ FLAGSTORE prfs_Store(PROOFSEARCH Prf)
+{
+ return Prf->store;
+}
+
+static __inline__ BOOL prfs_SplitLevelCondition(NAT OriginLevel, NAT RedundantLevel, NAT BacktrackLevel)
+{
+ return (OriginLevel > RedundantLevel || OriginLevel > BacktrackLevel);
+}
+
+static __inline__ BOOL prfs_IsClauseValid(CLAUSE C, int Level)
+{
+ return clause_SplitLevel(C) <= Level;
+}
+
+static __inline__ SPLIT prfs_GetSplitOfLevel(int L, PROOFSEARCH Prf)
+{
+ LIST Scan;
+ Scan = Prf->stack;
+ while (!list_Empty(Scan) &&
+ (((SPLIT)list_Car(Scan))->splitlevel != L))
+ Scan = list_Cdr(Scan);
+
+ return (SPLIT) list_Car(Scan);
+}
+
+static __inline__ LIST prfs_SplitStack(PROOFSEARCH Prf)
+{
+ return Prf->stack;
+}
+
+static __inline__ SPLIT prfs_SplitStackTop(PROOFSEARCH Prf)
+{
+ return (SPLIT) list_Car(Prf->stack);
+}
+
+static __inline__ void prfs_SplitStackPop(PROOFSEARCH Prf)
+{
+ Prf->stack = list_Pop(Prf->stack);
+}
+
+static __inline__ void prfs_SplitStackPush(PROOFSEARCH Prf, SPLIT S)
+{
+ Prf->stack = list_Cons(S, Prf->stack);
+}
+
+static __inline__ BOOL prfs_SplitStackEmpty(PROOFSEARCH Prf)
+{
+ return list_StackEmpty(prfs_SplitStack(Prf));
+}
+
+static __inline__ int prfs_TopLevel(void)
+{
+ return 0;
+}
+
+static __inline__ int prfs_ValidLevel(PROOFSEARCH Prf)
+{
+ return Prf->validlevel;
+}
+
+static __inline__ void prfs_SetValidLevel(PROOFSEARCH Prf, int Value)
+{
+ Prf->validlevel = Value;
+}
+
+static __inline__ void prfs_IncValidLevel(PROOFSEARCH Prf)
+{
+ (Prf->validlevel)++;
+}
+
+static __inline__ void prfs_DecValidLevel(PROOFSEARCH Prf)
+{
+ (Prf->validlevel)--;
+}
+
+static __inline__ int prfs_LastBacktrackLevel(PROOFSEARCH Prf)
+{
+ return Prf->lastbacktrack;
+}
+
+static __inline__ void prfs_SetLastBacktrackLevel(PROOFSEARCH Prf, int Value)
+{
+ Prf->lastbacktrack = Value;
+}
+
+static __inline__ int prfs_SplitCounter(PROOFSEARCH Prf)
+{
+ return Prf->splitcounter;
+}
+
+static __inline__ void prfs_SetSplitCounter(PROOFSEARCH Prf, int c)
+{
+ Prf->splitcounter = c;
+}
+
+static __inline__ void prfs_DecSplitCounter(PROOFSEARCH Prf)
+{
+ (Prf->splitcounter)--;
+}
+
+static __inline__ int prfs_KeptClauses(PROOFSEARCH Prf)
+{
+ return Prf->keptclauses;
+}
+
+static __inline__ void prfs_IncKeptClauses(PROOFSEARCH Prf)
+{
+ Prf->keptclauses++;
+}
+
+static __inline__ int prfs_DerivedClauses(PROOFSEARCH Prf)
+{
+ return Prf->derivedclauses;
+}
+
+static __inline__ void prfs_IncDerivedClauses(PROOFSEARCH Prf, int k)
+{
+ Prf->derivedclauses += k;
+}
+
+static __inline__ int prfs_Loops(PROOFSEARCH Prf)
+{
+ return Prf->loops;
+}
+
+static __inline__ void prfs_SetLoops(PROOFSEARCH Prf, int k)
+{
+ Prf->loops = k;
+}
+
+static __inline__ void prfs_DecLoops(PROOFSEARCH Prf)
+{
+ Prf->loops--;
+}
+
+static __inline__ int prfs_BacktrackedClauses(PROOFSEARCH Prf)
+{
+ return Prf->backtracked;
+}
+
+static __inline__ void prfs_SetBacktrackedClauses(PROOFSEARCH Prf, int k)
+{
+ Prf->backtracked = k;
+}
+
+static __inline__ void prfs_IncBacktrackedClauses(PROOFSEARCH Prf, int k)
+{
+ Prf->backtracked += k;
+}
+
+static __inline__ NAT prfs_NonTrivClauseNumber(PROOFSEARCH Prf)
+{
+ return Prf->nontrivclausenumber;
+}
+
+static __inline__ void prfs_SetNonTrivClauseNumber(PROOFSEARCH Prf, NAT Number)
+{
+ Prf->nontrivclausenumber = Number;
+}
+
+
+/**************************************************************/
+/* Functions for accessing SPLIT objects */
+/**************************************************************/
+
+static __inline__ void prfs_SplitFree(SPLIT Sp)
+{
+ memory_Free(Sp, sizeof(SPLIT_NODE));
+}
+
+static __inline__ LIST prfs_SplitBlockedClauses(SPLIT S)
+{
+ return S->blockedClauses;
+}
+
+static __inline__ void prfs_SplitAddBlockedClause(SPLIT S, CLAUSE C)
+{
+ S->blockedClauses = list_Cons(C,S->blockedClauses);
+}
+
+static __inline__ void prfs_SplitSetBlockedClauses(SPLIT S, LIST L)
+{
+ S->blockedClauses = L;
+}
+
+static __inline__ LIST prfs_SplitDeletedClauses(SPLIT S)
+{
+ return S->deletedClauses;
+}
+
+static __inline__ void prfs_SplitSetDeletedClauses(SPLIT S, LIST L)
+{
+ S->deletedClauses = L;
+}
+
+static __inline__ int prfs_SplitSplitLevel(SPLIT S)
+{
+ return S->splitlevel;
+}
+
+static __inline__ BOOL prfs_SplitIsUsed(SPLIT S)
+{
+ return S->used;
+}
+
+static __inline__ BOOL prfs_SplitIsUnused(SPLIT S)
+{
+ return !S->used;
+}
+
+static __inline__ void prfs_SplitSetUsed(SPLIT S)
+{
+ S->used = TRUE;
+}
+
+static __inline__ CLAUSE prfs_SplitFatherClause(SPLIT S)
+{
+ return S->father;
+}
+
+static __inline__ void prfs_SplitSetFatherClause(SPLIT S, CLAUSE C)
+{
+ S->father = C;
+}
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+PROOFSEARCH prfs_Create(void);
+BOOL prfs_Check(PROOFSEARCH);
+void prfs_CopyIndices(PROOFSEARCH, PROOFSEARCH);
+void prfs_Delete(PROOFSEARCH);
+void prfs_DeleteDocProof(PROOFSEARCH);
+void prfs_Clean(PROOFSEARCH);
+void prfs_Print(PROOFSEARCH);
+void prfs_PrintSplit(SPLIT);
+void prfs_PrintSplitStack(PROOFSEARCH);
+void prfs_InsertWorkedOffClause(PROOFSEARCH,CLAUSE);
+void prfs_InsertUsableClause(PROOFSEARCH,CLAUSE);
+void prfs_InsertDocProofClause(PROOFSEARCH,CLAUSE);
+void prfs_MoveUsableWorkedOff(PROOFSEARCH, CLAUSE);
+void prfs_MoveWorkedOffDocProof(PROOFSEARCH, CLAUSE);
+void prfs_MoveUsableDocProof(PROOFSEARCH, CLAUSE);
+void prfs_ExtractWorkedOff(PROOFSEARCH, CLAUSE);
+void prfs_DeleteWorkedOff(PROOFSEARCH, CLAUSE);
+void prfs_ExtractUsable(PROOFSEARCH, CLAUSE);
+void prfs_DeleteUsable(PROOFSEARCH, CLAUSE);
+void prfs_ExtractDocProof(PROOFSEARCH, CLAUSE);
+void prfs_MoveInvalidClausesDocProof(PROOFSEARCH);
+void prfs_SwapIndexes(PROOFSEARCH);
+
+void prfs_InstallFiniteMonadicPredicates(PROOFSEARCH, LIST, LIST);
+
+CLAUSE prfs_PerformSplitting(PROOFSEARCH, CLAUSE);
+CLAUSE prfs_DoSplitting(PROOFSEARCH, CLAUSE, LIST);
+NAT prfs_GetNumberOfInstances(PROOFSEARCH, LITERAL, BOOL);
+
+
+#endif
diff --git a/test/spass/sharing.c b/test/spass/sharing.c
new file mode 100644
index 0000000..47f8b50
--- /dev/null
+++ b/test/spass/sharing.c
@@ -0,0 +1,1143 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * STRUCTURE SHARING * */
+/* * * */
+/* * $Module: SHARING * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "sharing.h"
+
+/**************************************************************/
+/* Static Variables */
+/**************************************************************/
+
+#ifdef CHECK
+static BOOL sharing_DATABLOCKED;
+#endif
+
+static LIST sharing_DATALIST = (LIST) NULL;
+
+#define sharing_STACKSIZE 500
+static LIST sharing_STACK[sharing_STACKSIZE];
+static LIST* sharing_STACKPOINTER = sharing_STACK;
+
+/**************************************************************/
+/* Prototypes for static functions used only in this module */
+/**************************************************************/
+
+static BOOL sharing_IsNoMoreUsed(TERM);
+static LIST sharing_InternGetDataList(TERM);
+
+static TERM sharing_InsertIntoSharing(TERM, SHARED_INDEX);
+static void sharing_DeleteFromSharing(TERM, SHARED_INDEX);
+
+static void sharing_ResetTermStamp(TERM);
+
+static void sharing_PrintWithSuperterms(TERM);
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * PRIMITIVE SHARING FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+SHARED_INDEX sharing_IndexCreate(void)
+/**********************************************************
+ INPUT: None.
+ RETURNS: A shared index, consisting of an Index, a Consttable
+ and a Vartable.
+ EFFECTS: Initializes the shared Index for the sharing_Vartable and the
+ sharing_Consttable with NULL-Pointers and an empty st_index.
+**********************************************************/
+{
+ SHARED_INDEX Result;
+ int i;
+
+ Result = (SHARED_INDEX)memory_Malloc(sizeof(SHARED_INDEX_NODE));
+ sharing_SetIndex(Result, st_IndexCreate());
+
+ for (i=0; (i < symbol_MaxVars()); i++)
+ sharing_SetVartableEntry(Result, i, NULL);
+
+ for (i=0; (i < symbol_MaxConsts()); i++)
+ sharing_SetConsttableEntry(Result, i, NULL);
+
+ sharing_SetStampID(Result, term_GetStampID());
+ return Result;
+}
+
+
+void sharing_IndexDelete(SHARED_INDEX ShIndex)
+/**********************************************************
+ INPUT: A shared Index.
+ RETURNS: None.
+ EFFECTS: Deletes the Index and frees the memory for the
+ structure including the Const- and Vartable.
+**********************************************************/
+{
+ st_IndexDelete(sharing_Index(ShIndex));
+
+ memory_Free(ShIndex, sizeof(SHARED_INDEX_NODE));
+}
+
+
+void sharing_PushOnStack(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: None.
+ EFFECTS: Creates a Stack of Pointers to the
+ term and all of its subterms in their order in
+ the arglist (thus ordered by depth).
+ top of the stack is bottom term
+**********************************************************/
+{
+ LIST ArgList;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_PushOnStack: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ stack_Push(Term);
+
+ ArgList = term_ArgumentList(Term);
+
+ while (!list_Empty(ArgList)){
+ sharing_PushOnStack(list_Car(ArgList));
+ ArgList = list_Cdr(ArgList);
+ }
+}
+
+
+void sharing_PushReverseOnStack(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: None.
+ EFFECTS: Creates a Stack of Pointers to the
+ term and all of its subterms, except variables in their order in
+ the arglist (thus ordered by depth).
+ top of the stack is top term
+**********************************************************/
+{
+ LIST ArgList;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_PushReverseOnStack: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!term_IsVariable(Term)) {
+
+ ArgList = term_ArgumentList(Term);
+
+ while (!list_Empty(ArgList)){
+ sharing_PushReverseOnStack(list_Car(ArgList));
+ ArgList = list_Cdr(ArgList);
+ }
+
+ stack_Push(Term);
+ }
+}
+
+void sharing_PushReverseOnStackExcept(TERM Term, LIST DontTermList)
+/**********************************************************
+ INPUT: A term and an exception list.
+ RETURNS: None.
+ EFFECTS: Creates a Stack of Pointers to the
+ term and all of its subterms that are not contained
+ or below the terms in DontTermList in their order in
+ the arglist (thus ordered by depth).
+ top of the stack is top term
+**********************************************************/
+{
+ LIST ArgList;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_PushReverseOnStack: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!term_IsVariable(Term) && !term_ListContainsTerm(DontTermList, Term)) {
+ ArgList = term_ArgumentList(Term);
+
+ while (!list_Empty(ArgList)){
+ sharing_PushReverseOnStackExcept(list_Car(ArgList), DontTermList);
+ ArgList = list_Cdr(ArgList);
+ }
+
+ stack_Push(Term);
+ }
+}
+
+void sharing_PushOnStackNoStamps(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: None.
+ EFFECTS: Creates a Stack of Pointers to the
+ term and all of its subterms that are not stamped
+ or below stamped terms.
+ top of the stack is top term.
+**********************************************************/
+{
+ LIST ArgList;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_PushReverseOnStackNoStamps: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!term_IsVariable(Term) && !term_HasTermStamp(Term)) {
+
+ stack_Push(Term);
+
+ ArgList = term_ArgumentList(Term);
+
+ while (!list_Empty(ArgList)){
+ sharing_PushOnStackNoStamps(list_Car(ArgList));
+ ArgList = list_Cdr(ArgList);
+ }
+ }
+}
+
+
+void sharing_PushListOnStack(LIST TermList)
+/**********************************************************
+ INPUT: A list of terms.
+ RETURNS: None.
+ EFFECTS: Creates a Stack of Pointers to the
+ terms in <TermList> and all of subterms in their order in
+ the arglist (thus ordered by depth).
+**********************************************************/
+{
+ while (!list_Empty(TermList)) {
+ sharing_PushOnStack(list_Car(TermList));
+ TermList = list_Cdr(TermList);
+ }
+}
+
+
+void sharing_PushListReverseOnStack(LIST TermList)
+/**********************************************************
+ INPUT: A list of terms.
+ RETURNS: None.
+ EFFECTS: Puts all terms in Termlist and their superterms
+ in their order in the arglist (thus ordered by depth)
+ on the stack.
+ On top of the stack are subterms.
+**********************************************************/
+{
+ while (!list_Empty(TermList)) {
+ sharing_PushReverseOnStack(list_Car(TermList));
+ TermList = list_Cdr(TermList);
+ }
+}
+
+void sharing_PushListReverseOnStackExcept(LIST TermList, LIST DontPushList)
+/**********************************************************
+ INPUT: Two lists of terms.
+ RETURNS: None.
+ EFFECTS: Puts all terms in Termlist except those contained in
+ DontPushList and their superterms
+ in their order in the arglist (thus ordered by depth)
+ on the stack.
+ On top of the stack are subterms.
+**********************************************************/
+{
+ while (!list_Empty(TermList)) {
+ sharing_PushReverseOnStackExcept(list_Car(TermList), DontPushList);
+ TermList = list_Cdr(TermList);
+ }
+}
+
+void sharing_PushListOnStackNoStamps(LIST TermList)
+/**********************************************************
+ INPUT: A list of terms.
+ RETURNS: None.
+ EFFECTS: Puts all terms in Termlist on the stack.
+ On top of the stack are subterms.
+**********************************************************/
+{
+ while (!list_Empty(TermList)) {
+ sharing_PushOnStackNoStamps(list_Car(TermList));
+ TermList = list_Cdr(TermList);
+ }
+}
+
+
+static BOOL sharing_IsNoMoreUsed(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: TRUE, if the Term has no superterms,
+ FALSE, else.
+**********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_IsNoMoreUsed: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return (list_Empty(term_SupertermList(Term)));
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * FUNCTIONS FOR INSERTION AND DELETION * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * 1) FUNCTIONS FOR INSERTION * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+TERM sharing_Insert(POINTER Data, TERM Atom, SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A data element, it's unshared atom and a SharedIndex.
+ RETURNS: The shared term inserted into the SharedIndex.
+ CAUTION: The superterm slot of <Atom> is destructively used!
+ MEMORY: The term 'Atom' still exists, memory needed for
+ the shared version is allocated.
+**********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Atom) || (!sharing_IsNoMoreUsed(Atom))){
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_Insert: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Atom = sharing_InsertIntoSharing(Atom, SharedIndex);
+
+ term_RplacSupertermList(Atom, list_Cons(Data, term_SupertermList(Atom)));
+
+ return(Atom);
+}
+
+
+static TERM sharing_InsertIntoSharing(TERM Term, SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A term and a shared index.
+ RETURNS: A copy of 'Term' which is inserted into the Sharing
+ and the "SharedIndex".
+ MEMORY: The unshared version isn't freed, needed memory
+ is allocated.
+**********************************************************/
+{
+ int B_Stack;
+ TERM InsTerm;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_InsertIntoSharing: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ B_Stack = stack_Bottom();
+ sharing_PushOnStack(Term);
+ InsTerm = stack_Top(); /* not necessary initialization ... */
+
+ while (! stack_Empty(B_Stack)){
+ InsTerm = stack_PopResult();
+
+ if (term_IsVariable(InsTerm)){
+ if (!sharing_IsSharedVar(InsTerm, SharedIndex)) {
+
+ sharing_SetVartableEntry(SharedIndex, sharing_VariableIndex(InsTerm),
+ term_Create(term_TopSymbol(InsTerm),
+ list_Nil()));
+
+ st_EntryCreate(sharing_Index(SharedIndex),
+ sharing_VartableEntry(SharedIndex,
+ sharing_VariableIndex(InsTerm)),
+ sharing_VartableEntry(SharedIndex,
+ sharing_VariableIndex(InsTerm)),
+ cont_LeftContext());
+ }
+
+ /* The NULL-Pointer in the Vartable is replaced by a copy of the */
+ /* InsTerm, which is referenced by the InsTerms SharedTermCopy. */
+ /* A complex T still has to be insert. into its Args superlists. */
+ /* The unshared Term isn't yet in the 'SharedIndex' and thus is */
+ /* inserted, too. */
+
+
+ sharing_RememberSharedTermCopy(InsTerm,
+ sharing_VartableEntry(SharedIndex, sharing_VariableIndex(InsTerm)));
+
+ }else if (term_IsConstant(InsTerm)){
+ if (!sharing_IsSharedConst(InsTerm, SharedIndex)) {
+ sharing_SetConsttableEntry(SharedIndex, sharing_ConstantIndex(InsTerm),
+ term_Create(term_TopSymbol(InsTerm),
+ list_Nil()));
+
+ st_EntryCreate(sharing_Index(SharedIndex),
+ sharing_ConsttableEntry(SharedIndex, sharing_ConstantIndex(InsTerm)),
+ sharing_ConsttableEntry(SharedIndex, sharing_ConstantIndex(InsTerm)),
+ cont_LeftContext());
+ }
+
+ /* The NULL-Pointer in the Consttable is replaced by a copy of the */
+ /* InsTerm, which is referenced by the InsTerms SharedTermCopy. */
+ /* A complex T still has to be insert. into its Args superlists. */
+ /* The unshared Term isn't yet in the 'SharedIndex' and thus is */
+ /* inserted, too. */
+
+ sharing_RememberSharedTermCopy(InsTerm,
+ sharing_ConsttableEntry(SharedIndex, sharing_ConstantIndex(InsTerm)));
+
+ }else{ /* term_IsComplex(InsTerm) */
+ /* -> owns subterms which now have copies in Sharing. */
+
+ TERM SharedDuplicate;
+ LIST HelpList;
+ BOOL DuplCandHasSameArgs;
+
+ SharedDuplicate = (TERM)NULL;
+ HelpList =
+ term_SupertermList(sharing_SharedTermCopy(term_FirstArgument(InsTerm)));
+ if (list_Empty(HelpList)){
+ SharedDuplicate = term_Create(term_TopSymbol(InsTerm), list_Nil());
+ DuplCandHasSameArgs = FALSE;
+ }
+ else{
+ DuplCandHasSameArgs = FALSE;
+ while (!DuplCandHasSameArgs && !list_Empty(HelpList)){
+ SharedDuplicate = (TERM) list_First(HelpList);
+
+ if (term_TopSymbol(SharedDuplicate) == term_TopSymbol(InsTerm)){
+ LIST OrigHelpArgList, DuplHelpArgList;
+
+ OrigHelpArgList = term_ArgumentList(InsTerm);
+ DuplHelpArgList = term_ArgumentList(SharedDuplicate);
+ while (!list_Empty(OrigHelpArgList) &&
+ (DuplCandHasSameArgs =
+ (sharing_SharedTermCopy(list_First(OrigHelpArgList)) ==
+ list_First(DuplHelpArgList)))){
+ DuplHelpArgList = list_Cdr(DuplHelpArgList);
+ OrigHelpArgList = list_Cdr(OrigHelpArgList);
+ }
+ }
+ HelpList = list_Cdr(HelpList);
+ }
+ if (!DuplCandHasSameArgs)
+ SharedDuplicate = term_Create(term_TopSymbol(InsTerm), list_Nil());
+ } /* end of else fuer Behandlung von InsTerm mit shared FirstArg. */
+
+ if (!DuplCandHasSameArgs){
+ /* Falls neue Kopie gemacht wurde, wird diese hier "eingeshared": */
+
+ for (HelpList = term_ArgumentList(InsTerm); !list_Empty(HelpList);
+ HelpList = list_Cdr(HelpList)){
+ TERM SharedArg;
+
+ SharedArg = sharing_SharedTermCopy((TERM)list_First(HelpList));
+
+ term_RplacArgumentList(SharedDuplicate,
+ list_Cons(SharedArg,
+ term_ArgumentList(SharedDuplicate)));
+
+ term_RplacSupertermList(SharedArg,
+ list_Cons(SharedDuplicate,
+ term_SupertermList(SharedArg)));
+ }
+ term_RplacArgumentList(SharedDuplicate,
+ list_NReverse(term_ArgumentList(SharedDuplicate)));
+
+ /* Now a newly generated term can be inserted into the 'SharedIndex' ! */
+
+ st_EntryCreate(sharing_Index(SharedIndex),
+ SharedDuplicate,
+ SharedDuplicate,
+ cont_LeftContext());
+
+ }
+ sharing_RememberSharedTermCopy(InsTerm,
+ SharedDuplicate);
+ }
+ }
+
+ return(sharing_SharedTermCopy(InsTerm));
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * 2) FUNCTIONS FOR DELETION * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+void sharing_Delete(POINTER Data, TERM Atom, SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A data element, its atom and an index.
+ RETURNS: Nothing.
+ MEMORY: Destructive, deletes 'Atom' from Sharing and frees
+ memory that's no more needed.
+***********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Atom)){
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_Delete: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_RplacSupertermList(Atom,
+ list_PointerDeleteElement(term_SupertermList(Atom), Data));
+
+ if (sharing_IsNoMoreUsed(Atom))
+ sharing_DeleteFromSharing(Atom, SharedIndex);
+
+}
+
+
+static void sharing_DeleteFromSharing(TERM Term, SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A term and a SharedIndex
+ RETURNS: Nothing
+ MEMORY: 'Term' is removed from the Sharing, only correct
+ if 'Term' is unshared in sharing (real subterms
+ may be shared, off course).
+***********************************************************/
+{
+ BOOL IsIndexed;
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_DeleteFromSharing: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ IsIndexed = st_EntryDelete(sharing_Index(SharedIndex), Term, Term, cont_LeftContext());
+
+#ifdef CHECK
+ if (!IsIndexed) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_DeleteFromSharing: Input not indexed.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (term_IsComplex(Term)){
+ LIST Args;
+
+ Args = term_ArgumentList(Term);
+
+ while (!list_Empty(Args)){
+ TERM NextArg;
+ LIST Help;
+
+ /* This block frees the terms arglists memory. */
+ Help = Args;
+ NextArg = (TERM) list_First(Args);
+ Args = list_Cdr(Args);
+ list_Free(Help);
+
+ term_RplacSupertermList(NextArg,
+ list_PointerDeleteOneElement(term_SupertermList(NextArg), Term));
+ if (sharing_IsNoMoreUsed(NextArg))
+ sharing_DeleteFromSharing(NextArg, SharedIndex);
+ }
+
+ } else if (term_IsConstant(Term)) {
+ sharing_SetConsttableEntry(SharedIndex, sharing_ConstantIndex(Term), NULL);
+ } else {
+ sharing_SetVartableEntry(SharedIndex, sharing_VariableIndex(Term), NULL);
+ }
+ list_Delete(term_SupertermList(Term));
+ term_Free(Term);
+}
+
+
+/**************************************************************/
+/* Functions to access unshared data via the shared term. */
+/**************************************************************/
+
+LIST sharing_GetDataList(TERM Term, SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A shared term and the shared index it belongs to.
+ RETURNS: The list of data connected to all superterms of Term,
+ e.g. the list of all literals containing Term.
+ EFFECT: Allocates memory for the returned list.
+ CAUTION: Works recursive!
+**********************************************************/
+{
+ LIST Result = list_Nil();
+#ifdef CHECK
+ if (!term_IsTerm(Term) || (SharedIndex == NULL)){
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_GetDataList: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ /* What if the term doesn't belong to this shared index ?????? */
+
+#endif
+
+ if (term_StampOverflow(sharing_StampID(SharedIndex)))
+ sharing_ResetAllTermStamps(SharedIndex);
+
+ term_StartStamp();
+
+ Result = sharing_InternGetDataList(Term);
+
+ term_StopStamp();
+
+ return Result;
+}
+
+
+static LIST sharing_InternGetDataList(TERM Term)
+/**********************************************************
+ INPUT: A shared term.
+ RETURNS: The list of data connected to all superterms of Term
+ EFFECT: Allocates memory for the returned list.
+********************************************************/
+{
+ if (term_IsAtom(Term))
+ /* We are at top level of the superterm "tree", */
+ /* so the recursion stops here */
+ return list_Copy(term_AtomsLiterals(Term));
+ else{
+ LIST SuperList;
+ LIST DataList = list_Nil();
+
+ for (SuperList = term_SupertermList(Term); !list_Empty(SuperList);
+ SuperList = list_Cdr(SuperList)) {
+ TERM superterm = (TERM) list_Car(SuperList);
+ if (!term_AlreadyVisited(superterm)) {
+ DataList = list_Nconc(sharing_InternGetDataList(superterm), DataList);
+ term_SetTermStamp(superterm);
+ }
+ }
+ return DataList;
+ }
+}
+
+
+void sharing_StartDataIterator(TERM Term, SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A shared term and the shared index it belongs to.
+ RETURNS: Nothing.
+ EFFECT: Prepares the data iterator for Term.
+ After this call you can access single data items
+ for Term with function sharing_GetNextData.
+********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Term) || (SharedIndex == NULL)){
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_StartDataIterator: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ if (sharing_DATABLOCKED) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_StartDataIterator: Data iterator already used.\n");
+ misc_FinishErrorReport();
+ }
+ sharing_DATABLOCKED = TRUE;
+#endif
+
+ if (term_StampOverflow(sharing_StampID(SharedIndex)))
+ sharing_ResetAllTermStamps(SharedIndex);
+ term_StartStamp();
+
+ /* Init stack */
+ sharing_STACKPOINTER = sharing_STACK; /* Pop all items */
+ while (!term_IsAtom(Term)) {
+ /* Push superterm list on stack */
+ *(sharing_STACKPOINTER++) = term_SupertermList(Term);
+ Term = list_Car(term_SupertermList(Term));
+ }
+
+ sharing_DATALIST = term_AtomsLiterals(Term);
+}
+
+
+POINTER sharing_GetNextData(void)
+/**********************************************************
+ INPUT: None
+ RETURNS: A single data item connected to the term specified
+ in the previous call of sharing_StartDataIterator.
+ NULL is returned, if all data items were accessed before.
+ EFFECT: In contrast to function sharing_GetDataList
+ no memory is allocated.
+********************************************************/
+{
+ POINTER Result = NULL;
+ LIST superlist;
+
+#ifdef CHECK
+ if (!sharing_DATABLOCKED) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_GetNextData: Iterator wasn't started.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!list_Empty(sharing_DATALIST)) {
+ Result = list_Car(sharing_DATALIST);
+ sharing_DATALIST = list_Cdr(sharing_DATALIST);
+ } else {
+ superlist = NULL;
+ while ((sharing_STACKPOINTER > sharing_STACK) && /* stack not empty */
+ list_Empty(superlist)) {
+ /* change between backtracking and expansion */
+ do { /* Backtracking */
+ superlist = *(--sharing_STACKPOINTER); /* PopResult */
+ term_SetTermStamp(list_Car(superlist));
+ do
+ superlist = list_Cdr(superlist);
+ while (!list_Empty(superlist) &&
+ term_AlreadyVisited(list_Car(superlist)));
+ } while ((sharing_STACKPOINTER>sharing_STACK) && list_Empty(superlist));
+ while (!list_Empty(superlist) &&
+ !term_IsAtom(list_Car(superlist))) { /* Expansion */
+ *(sharing_STACKPOINTER++) = superlist;
+ superlist = term_SupertermList(list_Car(superlist));
+ /* Search next unvisited term */
+ while (!list_Empty(superlist) &&
+ term_AlreadyVisited(list_Car(superlist)))
+ superlist = list_Cdr(superlist);
+ }
+ }
+ if (!list_Empty(superlist)) {
+ *(sharing_STACKPOINTER++) = superlist;
+ sharing_DATALIST = term_AtomsLiterals(list_Car(superlist));
+ Result = list_Car(sharing_DATALIST);
+ sharing_DATALIST = list_Cdr(sharing_DATALIST);
+ }
+ } /* else */
+ return Result;
+}
+
+
+void sharing_StopDataIterator(void)
+/**********************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECT: The data iterator is stopped for the term you specified
+ in the corresponding call of sharing_StartDataIterator.
+********************************************************/
+{
+#ifdef CHECK
+ if (!sharing_DATABLOCKED) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_StopDataIterator: Iterator wasn't started.\n");
+ misc_FinishErrorReport();
+ }
+ sharing_DATABLOCKED = FALSE;
+#endif
+ sharing_DATALIST = list_Nil();
+ term_StopStamp();
+}
+
+
+LIST sharing_NAtomDataList(TERM Atom)
+/**********************************************************
+ INPUT: A shared term.
+ RETURNS: A List of data connected with 'Term' or superterms.
+ EFFECT: No memory Allocation
+ CAUTION: THE RETURNED LIST MUST NOT CHANGE
+**********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Atom) || !term_IsAtom(Atom)){
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_NAtomDataList: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return(term_AtomsLiterals(Atom));
+}
+
+
+LIST sharing_GetAllSuperTerms(SHARED_INDEX Index)
+/**********************************************************
+ INPUT: A shared Index.
+ RETURNS: A List of all Data in the shared Index.
+ EFFECT: The term stamp is used.
+**********************************************************/
+{
+ int i;
+ LIST Result = list_Nil();
+ TERM term;
+
+ if (term_StampOverflow(sharing_StampID(Index)))
+ sharing_ResetAllTermStamps(Index);
+ term_StartStamp();
+
+ for (i = 0; i < symbol_MaxVars(); i++) {
+ term = sharing_VartableEntry(Index,i);
+ if (term != NULL)
+ Result = list_Nconc(sharing_InternGetDataList(term), Result);
+ }
+
+ for (i = 0; i < symbol_MaxConsts(); i++) {
+ term = sharing_ConsttableEntry(Index,i);
+ if (term != NULL)
+ Result = list_Nconc(sharing_InternGetDataList(term), Result);
+ }
+
+ term_StopStamp();
+
+ return Result;
+}
+
+
+void sharing_ResetAllTermStamps(SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A shared index.
+ RETURNS: Nothing.
+ EFFECT: The stamps of all terms in the shared index are reset.
+**********************************************************/
+{
+ TERM term;
+ int i;
+
+ /* Reset stamp for all variables and their superterms */
+ for (i = 0; i < symbol_MaxVars(); i++) {
+ term = sharing_VartableEntry(SharedIndex, i);
+ if (term != NULL)
+ sharing_ResetTermStamp(term);
+ }
+
+ /* Reset stamp for all constants and their superterms */
+ for (i = 0; i < symbol_MaxConsts(); i++){
+ term = sharing_ConsttableEntry(SharedIndex, i);
+ if (term != NULL)
+ sharing_ResetTermStamp(term);
+ }
+}
+
+
+static void sharing_ResetTermStamp(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: Nothing.
+ EFFECT: The stamps of Term and all its superterms are reset.
+**********************************************************/
+{
+ LIST SuperList;
+ TERM SuperTerm;
+
+ if (!term_IsAtom(Term)) {
+ for (SuperList = term_SupertermList(Term); !list_Empty(SuperList);
+ SuperList = list_Cdr(SuperList)) {
+ SuperTerm = (TERM) list_Car(SuperList);
+ if (!term_StampAlreadyReset(SuperTerm)) {
+ sharing_ResetTermStamp(SuperTerm);
+ term_ResetTermStamp(SuperTerm);
+ }
+ }
+ }
+}
+
+
+NAT sharing_GetNumberOfOccurances(TERM Term)
+/**************************************************************
+ INPUT: A shared (!) term.
+ RETURNS: How many literals contain <Term>.
+ Note that literals containing <Term> <n> times are counted
+ <n> times.
+***************************************************************/
+{
+ if (term_IsAtom(Term))
+ /* Stop recursion */
+ return list_Length(term_AtomsLiterals(Term));
+ else {
+ LIST Scan;
+ NAT Result;
+
+ Result = 0;
+ for (Scan = term_SupertermList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ Result += sharing_GetNumberOfOccurances(list_Car(Scan));
+
+ return Result;
+ }
+}
+
+
+NAT sharing_GetNumberOfInstances(TERM Term, SHARED_INDEX Index)
+/**************************************************************
+ INPUT: A (!) shared term and a shared index. The term has to be
+ part of the index.
+ RETURNS: How many literals within the index contain an instance of <Term>.
+ Note that literals containing <n> instances of <Term>
+ are counted <n> times.
+***************************************************************/
+{
+ NAT Result;
+ TERM Instance;
+
+ Result = 0;
+ Instance = st_ExistInstance(cont_LeftContext(), sharing_Index(Index), Term);
+ while (Instance != NULL) {
+ Result += sharing_GetNumberOfOccurances(Instance);
+ Instance = st_NextCandidate();
+ }
+ return Result;
+}
+
+
+/**************************************************************/
+/* Output functions for the sharing structure. */
+/**************************************************************/
+
+void sharing_PrintVartable(SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A shared index.
+ RETURNS: Nothing.
+ EFFECT: Prints the Vartable entries to stdout
+**********************************************************/
+{
+ int i;
+
+ for (i = 0; i < symbol_MaxVars(); i++){
+ if (sharing_VartableEntry(SharedIndex, i) != NULL){
+ printf("\n X%d : ", i);
+
+ term_Print(sharing_VartableEntry(SharedIndex, i));
+ }
+ }
+}
+
+
+void sharing_PrintConsttable(SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A shared index.
+ RETURNS: Nothing.
+ EFFECT: Prints the Consttable entries to stdout
+**********************************************************/
+{
+ int i;
+
+ for (i = 0; i < symbol_MaxConsts(); i++){
+ if (sharing_ConsttableEntry(SharedIndex, i) != NULL){
+ printf("\n c%d : ", i);
+
+ term_Print(sharing_ConsttableEntry(SharedIndex, i));
+ }
+ }
+}
+
+
+void sharing_PrintSharingConstterms1(SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A shared index.
+ RETURNS: Nothing.
+ EFFECT: Prints all terms from the Consttable and their
+ direct superterms to stdout
+**********************************************************/
+{
+ TERM term;
+ int i;
+
+ for (i = 0; i < symbol_MaxConsts(); i++) {
+ term = sharing_ConsttableEntry(SharedIndex, i);
+ if (term != NULL){
+ printf("\n c%d : ", i);
+ term_Print(term);
+ puts(" has the direct superterms : ");
+ term_TermListPrint(term_SupertermList(term));
+ }
+ }
+}
+
+
+void sharing_PrintSharingVarterms1(SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A shared index.
+ RETURNS: Nothing.
+ EFFECT: Prints all terms from the Vartable and their
+ superterms to stdout
+**********************************************************/
+{
+ TERM term;
+ int i;
+
+ for (i = 0; i < symbol_MaxVars(); i++) {
+ term = sharing_VartableEntry(SharedIndex, i);
+ if (term != NULL){
+ printf("\n x%d : ", i);
+ term_Print(term);
+ puts(" has the direct superterms : ");
+ term_TermListPrint(term_SupertermList(term));
+ }
+ }
+}
+
+
+static void sharing_PrintWithSuperterms(TERM Term)
+/**********************************************************
+ INPUT: A Term
+ RETURNS: Nothing.
+ EFFECT: Prints all Superterms of 'Term' from the sharing
+ to stdout.
+**********************************************************/
+{
+
+ LIST HelpList;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sharing_PrintWithSuperterms: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (term_IsAtom(Term)) {
+ term_Print(Term);
+ putchar('\n');
+ }
+ else{
+ term_Print(Term);
+ HelpList = term_SupertermList(Term);
+ if (!list_Empty(HelpList)){
+ putchar('[');
+ term_TermListPrint(HelpList);
+ puts("]");
+ while (!list_Empty(HelpList)){
+ sharing_PrintWithSuperterms(list_Car(HelpList));
+ HelpList = list_Cdr(HelpList);
+ }
+ }
+ }
+}
+
+
+void sharing_PrintSharing(SHARED_INDEX SharedIndex)
+/**********************************************************
+ INPUT: A shared Index.
+ EFFECT: Prints the sharing to standard.out.
+**********************************************************/
+{
+ int i;
+
+ for (i = 0; i < symbol_MaxConsts(); i++){
+ if (sharing_ConsttableEntry(SharedIndex, i) != NULL){
+ sharing_PrintWithSuperterms(sharing_ConsttableEntry(SharedIndex, i));
+ puts("\n");
+ }
+ }
+ puts("------------------------");
+ for (i = 0; i < symbol_MaxVars(); i++){
+ if (sharing_VartableEntry(SharedIndex, i) != NULL){
+ sharing_PrintWithSuperterms(sharing_VartableEntry(SharedIndex, i));
+ puts("\n");
+ }
+ }
+}
+
+
+void sharing_PrintSameLevelTerms(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: Nothing.
+ EFFECT: Prints all terms, that share any of 'Term's args to
+ standard.out.
+**********************************************************/
+{
+ LIST HelpList;
+
+ HelpList = term_ArgumentList(Term);
+
+ while (!list_Empty(HelpList)){
+ if (!list_Empty(term_SupertermList(list_First(HelpList))))
+ term_TermListPrint(term_SupertermList(list_First(HelpList)));
+
+ HelpList = list_Cdr(HelpList);
+ }
+}
+
+void sharing_PrintStack(void)
+/**********************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECT: Prints the internal sharing stack for iterative
+ queries. Only for debugging purposes.
+**********************************************************/
+{
+ TERM term;
+ LIST* ptr = sharing_STACKPOINTER;
+
+ while (ptr > sharing_STACK) {
+ ptr--;
+ term = list_Car(*ptr);
+ term_Print(term);
+ putchar('\n');
+ }
+}
+
+
diff --git a/test/spass/sharing.h b/test/spass/sharing.h
new file mode 100644
index 0000000..d4f5d7e
--- /dev/null
+++ b/test/spass/sharing.h
@@ -0,0 +1,245 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * STRUCTURE SHARING * */
+/* * * */
+/* * $Module: SHARING * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _SHARING_
+#define _SHARING_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "term.h"
+#include "st.h"
+
+/**************************************************************/
+/* Data Structures and Constants */
+/**************************************************************/
+
+/* Symbol Tables; constants are just positive */
+/* integers and variables negative integers. */
+/* For constants and vars is a special symbol */
+/* table available, containing the sharing */
+/* info, i.e. a POINTER to the term structure, if */
+/* the symbol is already inserted in the sharing */
+/* structure, a NULL Pointer else. */
+
+typedef TERM VARTABLE[symbol__MAXVARIABLES];
+
+typedef TERM CONSTTABLE[symbol__MAXSIGNATURE];
+
+typedef struct {
+ st_INDEX index;
+ VARTABLE vartable;
+ CONSTTABLE consttable;
+ NAT stampId;
+} SHARED_INDEX_NODE, *SHARED_INDEX;
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+static __inline__ st_INDEX sharing_Index(SHARED_INDEX ShIndex)
+{
+ return ShIndex->index;
+}
+
+static __inline__ void sharing_SetIndex(SHARED_INDEX ShIndex, st_INDEX ST)
+{
+ ShIndex->index = ST;
+}
+
+static __inline__ const TERM* sharing_Vartable(SHARED_INDEX ShIndex)
+{
+ return ShIndex->vartable;
+}
+
+static __inline__ const TERM* sharing_Consttable(SHARED_INDEX ShIndex)
+{
+ return ShIndex->consttable;
+}
+
+static __inline__ NAT sharing_StampID(SHARED_INDEX ShIndex)
+{
+ return ShIndex->stampId;
+}
+
+static __inline__ void sharing_SetStampID(SHARED_INDEX ShIndex, NAT Stamp)
+{
+ ShIndex->stampId = Stamp;
+}
+
+static __inline__ TERM sharing_VartableEntry(SHARED_INDEX ShIndex, NAT Index)
+{
+ return ShIndex->vartable[Index];
+}
+
+static __inline__ void sharing_SetVartableEntry(SHARED_INDEX ShIndex,
+ NAT Index, TERM Term)
+{
+ ShIndex->vartable[Index] = Term;
+}
+
+static __inline__ TERM sharing_ConsttableEntry(SHARED_INDEX ShIndex,
+ NAT Index)
+{
+ return ShIndex->consttable[Index];
+}
+
+static __inline__ void sharing_SetConsttableEntry(SHARED_INDEX ShIndex,
+ NAT Index, TERM Term)
+{
+ ShIndex->consttable[Index] = Term;
+}
+
+static __inline__ TERM sharing_GetVarFromSymbol(SYMBOL S, SHARED_INDEX ShIndex)
+{
+ return sharing_VartableEntry(ShIndex, symbol_VarIndex(S));
+}
+
+static __inline__ int sharing_VariableIndex(TERM Term)
+{
+ return symbol_VarIndex(term_TopSymbol(Term));
+}
+
+static __inline__ int sharing_ConstantIndex(TERM Term)
+{
+ return symbol_Index(term_TopSymbol(Term));
+}
+
+static __inline__ BOOL sharing_IsSharedVar(TERM T, SHARED_INDEX ShIndex)
+/* RETURNS: True if there's already an entry for the variable T */
+/* in the Vartable of the shared index ShIndex. */
+{
+ return sharing_VartableEntry(ShIndex, sharing_VariableIndex(T)) != NULL;
+}
+
+static __inline__ BOOL sharing_IsSharedConst(TERM T, SHARED_INDEX ShIndex)
+/* True if there's already an entry for the constant T */
+/* in the Consttable of the shared index ShIndex. */
+{
+ return sharing_ConsttableEntry(ShIndex, sharing_ConstantIndex(T)) != NULL;
+}
+
+static __inline__ BOOL sharing_IsNotReallyShared(TERM Term)
+/* Der einzige Superterm ist der in dem ich loesche */
+{
+ return list_Length(term_SupertermList(Term)) <= 1;
+}
+
+static __inline__ void sharing_RememberSharedTermCopy(TERM Term, TERM Copy)
+/* The unshared term Term has now a link to its shared copy */
+{
+ term_RplacSuperterm(Term, Copy);
+}
+
+static __inline__ TERM sharing_SharedTermCopy(TERM Term)
+/* Return the shared copy of the unshared term Term */
+{
+ return term_Superterm(Term);
+}
+
+
+/**************************************************************/
+/* Functions for Creation and Deletion of a SHARED_INDEX */
+/**************************************************************/
+
+SHARED_INDEX sharing_IndexCreate(void);
+void sharing_IndexDelete(SHARED_INDEX);
+
+/**************************************************************/
+/* Functions on term insertion and deletion. */
+/**************************************************************/
+
+TERM sharing_Insert(POINTER, TERM, SHARED_INDEX);
+void sharing_Delete(POINTER, TERM, SHARED_INDEX);
+
+void sharing_PushOnStack(TERM);
+void sharing_PushReverseOnStack(TERM);
+void sharing_PushOnStackNoStamps(TERM);
+void sharing_PushListOnStack(LIST);
+void sharing_PushListReverseOnStack(LIST);
+void sharing_PushListReverseOnStackExcept(LIST, LIST);
+void sharing_PushListOnStackNoStamps(LIST);
+
+/**************************************************************/
+/* Functions to access unshared data by the shared terms. */
+/**************************************************************/
+
+LIST sharing_GetDataList(TERM, SHARED_INDEX);
+
+void sharing_StartDataIterator(TERM, SHARED_INDEX);
+POINTER sharing_GetNextData(void);
+void sharing_StopDataIterator(void);
+
+LIST sharing_NAtomDataList(TERM);
+LIST sharing_GetAllSuperTerms(SHARED_INDEX);
+
+void sharing_ResetAllTermStamps(SHARED_INDEX);
+
+NAT sharing_GetNumberOfOccurances(TERM);
+NAT sharing_GetNumberOfInstances(TERM, SHARED_INDEX);
+
+/**************************************************************/
+/* Output functions */
+/**************************************************************/
+
+void sharing_PrintVartable(SHARED_INDEX);
+void sharing_PrintConsttable(SHARED_INDEX);
+void sharing_PrintSharing(SHARED_INDEX);
+
+/**************************************************************/
+/* Debugging Functions */
+/**************************************************************/
+
+void sharing_PrintStack(void);
+void sharing_PrintSharingConstterms1(SHARED_INDEX);
+void sharing_PrintSharingVarterms1(SHARED_INDEX);
+void sharing_PrintSameLevelTerms(TERM);
+
+
+#endif
+
diff --git a/test/spass/small_problem.dfg b/test/spass/small_problem.dfg
new file mode 100644
index 0000000..f0b1a6d
--- /dev/null
+++ b/test/spass/small_problem.dfg
@@ -0,0 +1,154 @@
+%------------------------------------------------------------------------------
+% File : SET002+4 : TPTP v3.1.0. Released v2.2.0.
+% Domain : Set Theory (Naive)
+% Problem : Idempotency of union
+% Version : [Pas99] axioms.
+% English :
+
+% Refs : [Pas99] Pastre (1999), Email to G. Sutcliffe
+% Source : [Pas99]
+% Names :
+
+% Status : Theorem
+% Rating : 0.36 v3.1.0, 0.56 v2.7.0, 0.33 v2.6.0, 0.57 v2.5.0, 0.50 v2.4.0, 0.25 v2.3.0, 0.00 v2.2.1
+% Syntax : Number of formulae : 12 ( 2 unit)
+% Number of atoms : 30 ( 3 equality)
+% Maximal formula depth : 7 ( 5 average)
+% Number of connectives : 20 ( 2 ~ ; 2 |; 4 &)
+% ( 10 <=>; 2 =>; 0 <=)
+% ( 0 <~>; 0 ~|; 0 ~&)
+% Number of predicates : 4 ( 0 propositional; 2-2 arity)
+% Number of functors : 9 ( 1 constant; 0-2 arity)
+% Number of variables : 29 ( 0 singleton; 28 !; 1 ?)
+% Maximal term depth : 2 ( 1 average)
+
+% Comments :
+% : tptp2X -f dfg -t rm_equality:rstfp SET002+4.p
+%------------------------------------------------------------------------------
+
+begin_problem(TPTP_Problem).
+
+list_of_descriptions.
+name({*[ File : SET002+4 : TPTP v3.1.0. Released v2.2.0.],[ Names :]*}).
+author({*[ Source : [Pas99]]*}).
+status(unknown).
+description({*[ Refs : [Pas99] Pastre (1999), Email to G. Sutcliffe]*}).
+end_of_list.
+
+list_of_symbols.
+functions[(difference,2), (empty_set,0), (intersection,2), (power_set,1), (product,1), (singleton,1), (sum,1), (union,2), (unordered_pair,2)].
+predicates[(equal_set,2), (member,2), (subset,2)].
+end_of_list.
+
+list_of_formulae(axioms).
+
+formula(
+ forall([A,B],
+ equiv(
+ subset(A,B),
+ forall([X],
+ implies(
+ member(X,A),
+ member(X,B))))),
+subset ).
+
+formula(
+ forall([A,B],
+ equiv(
+ equal_set(A,B),
+ and(
+ subset(A,B),
+ subset(B,A)))),
+equal_set ).
+
+formula(
+ forall([X,A],
+ equiv(
+ member(X,power_set(A)),
+ subset(X,A))),
+power_set ).
+
+formula(
+ forall([X,A,B],
+ equiv(
+ member(X,intersection(A,B)),
+ and(
+ member(X,A),
+ member(X,B)))),
+intersection ).
+
+formula(
+ forall([X,A,B],
+ equiv(
+ member(X,union(A,B)),
+ or(
+ member(X,A),
+ member(X,B)))),
+union ).
+
+formula(
+ forall([X],
+ not(
+ member(X,empty_set))),
+empty_set ).
+
+formula(
+ forall([B,A,E],
+ equiv(
+ member(B,difference(E,A)),
+ and(
+ member(B,E),
+ not(
+ member(B,A))))),
+difference ).
+
+formula(
+ forall([X,A],
+ equiv(
+ member(X,singleton(A)),
+ equal(X,A))),
+singleton ).
+
+formula(
+ forall([X,A,B],
+ equiv(
+ member(X,unordered_pair(A,B)),
+ or(
+ equal(X,A),
+ equal(X,B)))),
+unordered_pair ).
+
+formula(
+ forall([X,A],
+ equiv(
+ member(X,sum(A)),
+ exists([Y],
+ and(
+ member(Y,A),
+ member(X,Y))))),
+sum ).
+
+formula(
+ forall([X,A],
+ equiv(
+ member(X,product(A)),
+ forall([Y],
+ implies(
+ member(Y,A),
+ member(X,Y))))),
+product ).
+
+end_of_list.
+
+%----NOTE WELL: conjecture has been negated
+list_of_formulae(conjectures).
+
+formula( %(conjecture)
+ forall([A],
+ equal_set(union(A,A),A)),
+thI14 ).
+
+end_of_list.
+
+end_problem.
+%------------------------------------------------------------------------------
diff --git a/test/spass/sort.c b/test/spass/sort.c
new file mode 100644
index 0000000..e109ef1
--- /dev/null
+++ b/test/spass/sort.c
@@ -0,0 +1,1974 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SORTED REASONING * */
+/* * * */
+/* * $Module: SORT * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "sort.h"
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * HIGH LEVEL FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+void sort_Delete(SORT Sort)
+/**************************************************************
+ INPUT: A sort.
+ RETURNS: Nothing.
+ MEMORY: The memory of the sort is freed.
+***************************************************************/
+{
+ list_Delete(Sort);
+}
+
+BOOL sort_Eq(SORT S1, SORT S2)
+/**************************************************************
+ INPUT: Two sorts.
+ RETURNS: TRUE iff the sorts <S1> and <S2> are the same base
+ sort intersection
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+ BOOL Found;
+
+#ifdef CHECK
+ if (!sort_IsSort(S1) || !sort_IsSort(S2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sort_Eq :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (list_Length(S1) != list_Length(S2))
+ return FALSE;
+
+ for (Scan1=S1; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) {
+ Found = FALSE;
+ for (Scan2=S2; !list_Empty(Scan2) && !Found; Scan2=list_Cdr(Scan2))
+ Found = sort_NodeEqual(list_Car(Scan1),list_Car(Scan2));
+ if (!Found)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+LIST sort_GetSymbolsFromSort(SORT Sort)
+/**************************************************************
+ INPUT: A sort.
+ RETURNS: The list of sort symbols..
+***************************************************************/
+{
+ LIST result = list_Nil();
+
+ for ( ; !list_Empty(Sort); Sort = list_Cdr(Sort))
+ result = list_Cons((POINTER)sort_NodeSymbol(list_Car(Sort)), result);
+
+ return result;
+}
+
+BOOL sort_ContainsSymbol(SORT Sort, SYMBOL Symbol)
+/**************************************************************
+ INPUT: A sort and a symbol.
+ RETURNS: TRUE, if the sort contains the symbol, FALSE otherwise.
+***************************************************************/
+{
+ for ( ; !list_Empty(Sort); Sort = list_Cdr(Sort))
+ if (symbol_Equal(sort_NodeSymbol(list_Car(Sort)), Symbol))
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL sort_IsSort(SORT Sort)
+/**************************************************************
+ INPUT: A sort.
+ RETURNS: TRUE, if the sort contains not more than one node.
+***************************************************************/
+{
+ LIST Scan1,Scan2;
+
+ for (Scan1=Sort ; !list_Empty(Scan1); Scan1 = list_Cdr(Scan1))
+ for (Scan2=list_Cdr(Scan1) ; !list_Empty(Scan2); Scan2 = list_Cdr(Scan2))
+ if (sort_NodeEqual(list_Car(Scan1),list_Car(Scan2)))
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL sort_TheorySortEqual(SORTTHEORY Theory, SORT Sort1, SORT Sort2)
+/**************************************************************
+ INPUT:
+ RETURNS:
+***************************************************************/
+{
+ LIST Scan;
+
+ if (list_Length(Sort1) != list_Length(Sort2))
+ return FALSE;
+
+ sort_TheoryIncrementMark(Theory);
+
+ for (Scan=Sort1; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ sort_PutNodeExtraTrue(Theory,list_Car(Scan));
+ for (Scan=Sort2; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (!sort_NodeExtraValue(Theory,list_Car(Scan)))
+ return FALSE;
+
+ return TRUE;
+}
+
+static BOOL sort_TheorySortMember(SORTTHEORY Theory, LIST List, SORT Sort)
+/**************************************************************
+ INPUT:
+ RETURNS:
+***************************************************************/
+{
+ while (!list_Empty(List)) {
+ if (sort_TheorySortEqual(Theory,list_Car(List),Sort))
+ return TRUE;
+ List = list_Cdr(List);
+ }
+ return FALSE;
+}
+
+
+void sort_DeleteSortPair(SOJU Pair)
+/**************************************************************
+ INPUT:
+ RETURNS: Nothing.
+***************************************************************/
+{
+ sort_DeleteOne(sort_PairSort(Pair));
+ sort_ConditionDelete(sort_PairCondition(Pair));
+ list_PairFree(Pair);
+}
+
+
+
+static void sort_ConditionPrint(CONDITION Cond)
+/**************************************************************
+ INPUT:
+ RETURNS: Nothing.
+***************************************************************/
+{
+ LIST Scan;
+
+ symbol_Print(sort_ConditionVar(Cond));
+ for (Scan=sort_ConditionConstraint(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ putchar(',');
+ term_PrintPrefix(list_Car(Scan));
+ }
+ for (Scan=sort_ConditionAntecedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ putchar(',');
+ term_PrintPrefix(list_Car(Scan));
+ }
+ for (Scan=sort_ConditionSuccedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ putchar(',');
+ term_PrintPrefix(list_Car(Scan));
+ }
+ for (Scan=sort_ConditionClauses(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ printf(",%d",clause_Number(list_Car(Scan)));
+ }
+}
+
+static void sort_LinkPrint(SLINK Link)
+/**************************************************************
+ INPUT:
+ RETURNS: Nothing.
+***************************************************************/
+{
+ LIST Scan;
+
+ fputs("Input: (", stdout);
+ for (Scan=sort_LinkInput(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ symbol_Print(sort_NodeSymbol(list_Car(Scan)));
+ if (!list_Empty(list_Cdr(Scan)))
+ putchar(',');
+ }
+ fputs(") Output: ", stdout);
+ symbol_Print(sort_NodeSymbol(sort_LinkOutput(Link)));
+ fputs(" C: (", stdout);
+ for (Scan=sort_LinkConstraint(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ term_PrintPrefix(list_Car(Scan));
+ if (!list_Empty(list_Cdr(Scan)))
+ putchar(',');
+ }
+ fputs(") A: (", stdout);
+ for (Scan=sort_LinkAntecedent(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ term_PrintPrefix(list_Car(Scan));
+ if (!list_Empty(list_Cdr(Scan)))
+ putchar(',');
+ }
+ fputs(") S: (", stdout);
+ for (Scan=sort_LinkSuccedent(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ term_PrintPrefix(list_Car(Scan));
+ if (!list_Empty(list_Cdr(Scan)))
+ putchar(',');
+ }
+ printf(") Clause: %d Card: %d Fire: %d Var: ", clause_Number(sort_LinkClause(Link)), sort_LinkCard(Link),
+ sort_LinkFire(Link));
+ symbol_Print(sort_LinkVar(Link));
+}
+
+
+
+void sort_PairPrint(SOJU Pair)
+/**************************************************************
+ INPUT:
+ RETURNS: Nothing.
+***************************************************************/
+{
+ sort_Print(sort_PairSort(Pair));
+ fputs(":[", stdout);
+ sort_ConditionPrint(sort_PairCondition(Pair));
+ putchar(']');
+}
+
+
+static NODE sort_NodeCreate(SYMBOL S)
+/**************************************************************
+ INPUT: A sort symbol.
+ RETURNS: A new initialized sort node for the symbol <S>.
+***************************************************************/
+{
+ NODE Result;
+
+ Result = (NODE)memory_Malloc(sizeof(NODE_NODE));
+
+ sort_PutNodeLinks(Result, list_Nil());
+ sort_PutNodeConditions(Result, list_Nil());
+ sort_PutNodeMark(Result, 0);
+ sort_PutNodeStart(Result, 0);
+ sort_PutNodeExtra(Result, 0);
+ sort_PutNodeSymbol(Result, S);
+
+ return Result;
+}
+
+BOOL sort_NodeIsTop(SORTTHEORY Theory, NODE Node)
+/**************************************************************
+ INPUT: A sort theory and a node.
+ RETURNS: TRUE if the Node is declared to be equivalent to the
+ top sort.
+***************************************************************/
+{
+ LIST Scan;
+ SLINK Link;
+
+ for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Link = (SLINK)list_Third(list_Car(Scan));
+ if (list_Empty(sort_LinkInput(Link)) && Node == sort_LinkOutput(Link))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static SLINK sort_TheoryLinkCreate(SORTTHEORY Theory, CLAUSE Origin,
+ CLAUSE Clause, LITERAL Lit)
+/**************************************************************
+ INPUT: A sort theory, a clause its origin and a subsort declaration
+ literal in the clause
+ RETURNS: A new link in <Theory> origin <Clause> and subsort declaration <Lit>
+***************************************************************/
+{
+ SLINK Result;
+ SYMBOL Output,Var,Max;
+ int i;
+ LIST Input, Antecedent, Succedent, Constraint;
+ TERM Term;
+
+ Result = (SLINK)memory_Malloc(sizeof(SLINK_NODE));
+
+ Output = term_TopSymbol(clause_LiteralSignedAtom(Lit));
+ Var = term_TopSymbol(term_FirstArgument(clause_LiteralSignedAtom(Lit)));
+ Input = Antecedent = Succedent = Constraint = list_Nil();
+ Max = clause_MaxVar(Clause);
+ term_StartMaxRenaming(Max);
+ Max = symbol_CreateStandardVariable();
+
+ for (i = clause_FirstConstraintLitIndex(Clause);
+ i <= clause_LastConstraintLitIndex(Clause); i++)
+ if (symbol_Equal(Var,term_TopSymbol(term_FirstArgument(clause_GetLiteralAtom(Clause,i)))))
+ Input = list_Cons(sort_TheoryNode(Theory,term_TopSymbol(clause_GetLiteralAtom(Clause,i))),
+ Input);
+ else {
+ Term = term_Copy(clause_GetLiteralTerm(Clause,i));
+ term_ExchangeVariable(Term,Var,Max);
+ Constraint = list_Cons(Term,Constraint);
+ }
+
+ for (i = clause_FirstAntecedentLitIndex(Clause);
+ i <= clause_LastAntecedentLitIndex(Clause); i++) {
+ Term = term_Copy(clause_GetLiteralTerm(Clause,i));
+ term_ExchangeVariable(Term,Var,Max);
+ Antecedent = list_Cons(Term,Antecedent);
+ }
+
+ for (i = clause_FirstSuccedentLitIndex(Clause);
+ i <= clause_LastSuccedentLitIndex(Clause); i++)
+ if (clause_GetLiteral(Clause,i) != Lit) {
+ Term = term_Copy(clause_GetLiteralTerm(Clause,i));
+ term_ExchangeVariable(Term,Var,Max);
+ Succedent = list_Cons(Term,Succedent);
+ }
+
+
+ sort_PutLinkInput(Result,Input);
+ sort_PutLinkOutput(Result,sort_TheoryNode(Theory,Output));
+ sort_PutLinkVar(Result,Max);
+ sort_PutLinkConstraint(Result,Constraint);
+ sort_PutLinkAntecedent(Result,Antecedent);
+ sort_PutLinkSuccedent(Result,Succedent);
+ sort_PutLinkCard(Result,list_Length(Input));
+ sort_LinkResetFire(Result);
+ sort_PutLinkClause(Result,Origin);
+
+ while (!list_Empty(Input)) {
+ sort_PutNodeLinks(list_Car(Input),list_Cons(Result,sort_NodeLinks(list_Car(Input))));
+ Input = list_Cdr(Input);
+ }
+
+ return Result;
+}
+
+
+void sort_Init(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: None.
+ SUMMARY: Initializes the sort Module.
+ EFFECTS: Initializes global variables, i.e. the BASESORT-Array.
+ CAUTION: MUST BE CALLED BEFORE ANY OTHER sort-FUNCTION.
+***************************************************************/
+{
+ return;
+}
+
+
+void sort_Print(SORT Sort)
+/**************************************************************
+ INPUT:
+ RETURNS: Nothing.
+***************************************************************/
+{
+ putchar('(');
+
+ while (!list_Empty(Sort)) {
+ symbol_Print(sort_NodeSymbol(list_Car(Sort)));
+ Sort = list_Cdr(Sort);
+ if (!list_Empty(Sort))
+ putchar(',');
+ }
+ putchar(')');
+}
+
+
+void sort_Free(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ SUMMARY: Frees the sort Module.
+***************************************************************/
+{
+ return;
+}
+
+SORTTHEORY sort_TheoryCreate(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: A new sort theory.
+ EFFECT: A new sort theory is created and initialized.
+***************************************************************/
+{
+ SORTTHEORY Result;
+ int i;
+ SIGNATURE Entry;
+ SYMBOL Symbol;
+
+ Result = (SORTTHEORY)memory_Malloc(sizeof(SORTTHEORY_NODE));
+
+ for (i = 1; i < symbol_ACTINDEX; i++) {
+ Result->basesorttable[i] = (NODE)NULL;
+ Entry = symbol_Signature(i);
+ if (Entry != NULL) {
+ Symbol = Entry->info;
+ if (symbol_IsPredicate(Symbol) && Entry->arity == 1)
+ Result->basesorttable[i] = sort_NodeCreate(Symbol);
+ }
+ }
+
+ Result->index = st_IndexCreate();
+ Result->suborigcls = list_Nil();
+ Result->termorigcls = list_Nil();
+ Result->mark = 0;
+
+ return Result;
+}
+
+void sort_TheoryPrint(SORTTHEORY Theory)
+/**************************************************************
+ INPUT: A sort theory
+ RETURNS: None.
+ EFFECT: Prints the sort theory to stdout.
+***************************************************************/
+{
+ LIST Scan;
+
+ if (Theory == (SORTTHEORY)NULL) {
+ fputs(" Empty Theory", stdout);
+ return;
+ }
+
+ fputs("\n Subsort Clauses:", stdout);
+ for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ fputs("\n\t\t Clause:", stdout);
+ clause_Print(list_Second(list_Car(Scan)));
+ fputs("\n\t\t Link: ", stdout);
+ sort_LinkPrint(list_Third(list_Car(Scan)));
+ }
+ fputs("\n Term Declaration Clauses:", stdout);
+ for (Scan=sort_TheoryTermorigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ fputs("\n\t\t Clause:", stdout);
+ clause_Print(list_Second(list_Car(Scan)));
+ }
+
+}
+
+void sort_TheoryDelete(SORTTHEORY Theory)
+/**************************************************************
+ INPUT: A sort theory
+ RETURNS: None.
+ EFFECT: The complete sort theory is deleted.
+***************************************************************/
+{
+ if (Theory != (SORTTHEORY)NULL) {
+ int i;
+ LIST Scan,Tuple;
+ TERM Term, Atom;
+
+ for (Scan=Theory->suborigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Tuple = (LIST)list_Car(Scan);
+ sort_LinkDelete(list_Third(Tuple));
+ clause_Delete(list_Second(Tuple));
+ list_Delete(Tuple);
+ }
+ list_Delete(Theory->suborigcls);
+ for (Scan=Theory->termorigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Tuple = (LIST)list_Car(Scan);
+ Term = (TERM)list_Third(Tuple);
+ Atom = (TERM)list_Car(term_SupertermList(Term));
+ st_EntryDelete(Theory->index,Term,Term,cont_LeftContext());
+ st_EntryDelete(Theory->index,Atom,Atom,cont_LeftContext());
+ list_Delete(term_SupertermList(Atom));
+ list_Delete(term_SupertermList(Term));
+ term_RplacSupertermList(Term, list_Nil());
+ term_RplacSupertermList(Atom, list_Nil());
+ clause_Delete(list_Second(Tuple));
+ list_Delete(Tuple);
+ }
+ list_Delete(Theory->termorigcls);
+ st_IndexDelete(Theory->index);
+
+ for (i=1;i<symbol_ACTINDEX;i++)
+ if (Theory->basesorttable[i] != (NODE)NULL)
+ sort_NodeDelete(Theory->basesorttable[i]);
+
+ memory_Free(Theory,sizeof(SORTTHEORY_NODE));
+ }
+}
+
+void sort_TheoryInsertClause(SORTTHEORY Theory, CLAUSE Origin, CLAUSE Clause, LITERAL L)
+/**************************************************************
+ INPUT: A sort theory, two clauses and a declaration of the second clause.
+ <Origin> is the original clause and <Clause> is a possibly approximated
+ copy of <Origin>.
+ RETURNS: None.
+ EFFECT: Inserts <Clause> with declaration <L> into the sort theory.
+***************************************************************/
+{
+ TERM Term, Atom;
+
+ Term = term_FirstArgument(clause_LiteralSignedAtom(L));
+
+ if (term_IsVariable(Term)) {
+ SLINK Link;
+ Link = sort_TheoryLinkCreate(Theory,Origin,Clause,L);
+ Theory->suborigcls = list_Cons(list_Cons(Origin,list_Cons(clause_Copy(Clause),list_List(Link))),
+ Theory->suborigcls);
+ }
+
+ /* Since currently Sort Resolution and Empty Sort require the subsort declaration clauses */
+ /* also subsort clauses are introduced into the sort theory index */
+
+ Atom = clause_LiteralSignedAtom(L);
+ term_RplacSupertermList(Atom, list_List(L));
+ term_RplacSupertermList(Term, list_List(Atom)); /* Must be empty before this operation */
+ st_EntryCreate(Theory->index,Term,Term,cont_LeftContext());
+ st_EntryCreate(Theory->index,Atom,Atom,cont_LeftContext());
+ Theory->termorigcls = list_Cons(list_Cons(Origin,list_Cons(Clause,list_List(Term))),
+ Theory->termorigcls);
+}
+
+void sort_TheoryDeleteClause(SORTTHEORY Theory, CLAUSE Origin)
+/**************************************************************
+ INPUT: A sort theory and a clause possibly inserted several times in the theory.
+ RETURNS: None.
+ EFFECT: <Origin> is deleted from the sort theory, but not deleted itself.
+***************************************************************/
+{
+ TERM Term,Atom;
+ LIST Scan,Tuple;
+
+ for (Scan=Theory->suborigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Tuple = list_Car(Scan);
+ if ((CLAUSE)list_First(Tuple) == Origin) {
+ list_Rplaca(Scan,NULL);
+ sort_LinkDelete(list_Third(Tuple));
+ clause_Delete(list_Second(Tuple));
+ list_Delete(Tuple);
+ }
+ }
+ Theory->suborigcls = list_PointerDeleteElement(Theory->suborigcls,NULL);
+ for (Scan=Theory->termorigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Tuple = list_Car(Scan);
+ if ((CLAUSE)list_First(Tuple) == Origin) {
+ list_Rplaca(Scan,NULL);
+ Term = (TERM)list_Third(Tuple);
+ Atom = (TERM)list_Car(term_SupertermList(Term));
+ st_EntryDelete(Theory->index,Term,Term,cont_LeftContext());
+ st_EntryDelete(Theory->index,Atom,Atom,cont_LeftContext());
+ list_Delete(term_SupertermList(Atom));
+ list_Delete(term_SupertermList(Term));
+ term_RplacSupertermList(Term, list_Nil());
+ term_RplacSupertermList(Atom, list_Nil());
+ clause_Delete(list_Second(Tuple));
+ list_Delete(Tuple);
+ }
+ }
+ Theory->termorigcls = list_PointerDeleteElement(Theory->termorigcls,NULL);
+}
+
+CONDITION sort_ConditionCreate(SYMBOL Var, LIST Constr, LIST Ante, LIST Succ, LIST Clauses)
+/**************************************************************
+ INPUT: A variable, a list of constraint literals, antecedent literals, succedent literals
+ and a list of clauses.
+ RETURNS: The condition created from these arguments.
+ MEMORY: It is assumed that all literals are unshared whereas the clauses are shared.
+***************************************************************/
+{
+ CONDITION Result;
+
+ Result = (CONDITION)memory_Malloc(sizeof(CONDITION_NODE));
+
+ sort_ConditionPutVar(Result, Var);
+ sort_ConditionPutConstraint(Result, Constr);
+ sort_ConditionPutAntecedent(Result, Ante);
+ sort_ConditionPutSuccedent(Result, Succ);
+ sort_ConditionPutClauses(Result, Clauses);
+
+ return Result;
+}
+
+CONDITION sort_ConditionNormalize(CONDITION Cond)
+/**************************************************************
+ INPUT: A condition.
+ RETURNS: The normalized condition, i.e., the variables for the various
+ literals are normalized starting with the minimal variable.
+ EFFECT: Destructive.
+***************************************************************/
+{
+ LIST Scan;
+ SYMBOL Old,New;
+
+ term_StartMinRenaming();
+ for (Scan=sort_ConditionConstraint(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ term_Rename(list_Car(Scan));
+ for (Scan=sort_ConditionAntecedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ term_Rename(list_Car(Scan));
+ for (Scan=sort_ConditionSuccedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ term_Rename(list_Car(Scan));
+ New = symbol_CreateStandardVariable();
+ Old = term_GetRenamedVarSymbol(sort_ConditionVar(Cond));
+ for (Scan=sort_ConditionConstraint(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ term_ExchangeVariable(list_Car(Scan),Old,New);
+ for (Scan=sort_ConditionAntecedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ term_ExchangeVariable(list_Car(Scan),Old,New);
+ for (Scan=sort_ConditionSuccedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ term_ExchangeVariable(list_Car(Scan),Old,New);
+
+ sort_ConditionPutVar(Cond,New);
+
+ return Cond;
+}
+
+CONDITION sort_ConditionCreateNoResidues(LIST Clauses)
+/**************************************************************
+ INPUT: A list of clauses.
+ RETURNS: The condition created just from the clauses.
+***************************************************************/
+{
+ CONDITION Result;
+
+ Result = (CONDITION)memory_Malloc(sizeof(CONDITION_NODE));
+
+ sort_ConditionPutVar(Result, symbol_FirstVariable());
+ sort_ConditionPutConstraint(Result, list_Nil());
+ sort_ConditionPutAntecedent(Result, list_Nil());
+ sort_ConditionPutSuccedent(Result, list_Nil());
+ sort_ConditionPutClauses(Result, Clauses);
+
+ return Result;
+}
+
+CONDITION sort_ExtendConditionByLink(CONDITION Cond, SLINK Link)
+/**************************************************************
+ INPUT: A condition and a link.
+ RETURNS: <Cond> extended by the clause, antecedent, constraint and succedent
+ literals of <Link>
+ EFFECT: <Cond> is destructively extended with <Link>.
+***************************************************************/
+{
+ LIST Lits,Antecedent,Succedent,Constraint;
+ SYMBOL Old,New;
+
+
+ term_StartMaxRenaming(sort_ConditionVar(Cond));
+ Constraint = term_CopyTermList(sort_LinkConstraint(Link));
+ Antecedent = term_CopyTermList(sort_LinkAntecedent(Link));
+ Succedent = term_CopyTermList(sort_LinkSuccedent(Link));
+ for (Lits=Constraint;!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ for (Lits=Antecedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ for (Lits=Succedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ Old = term_GetRenamedVarSymbol(sort_LinkVar(Link));
+ New = symbol_CreateStandardVariable();
+ for (Lits=Constraint;!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=Antecedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=Succedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ Old = sort_ConditionVar(Cond);
+ for (Lits=sort_ConditionConstraint(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=sort_ConditionAntecedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=sort_ConditionSuccedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ sort_ConditionPutConstraint(Cond,list_Nconc(sort_ConditionConstraint(Cond),Constraint));
+ sort_ConditionPutAntecedent(Cond,list_Nconc(sort_ConditionAntecedent(Cond),Antecedent));
+ sort_ConditionPutSuccedent(Cond,list_Nconc(sort_ConditionSuccedent(Cond),Succedent));
+ sort_ConditionPutClauses(Cond,list_Cons(sort_LinkClause(Link),sort_ConditionClauses(Cond)));
+ sort_ConditionPutVar(Cond,New);
+ sort_ConditionNormalize(Cond);
+
+ return Cond;
+
+}
+
+CONDITION sort_ExtendConditionByCondition(CONDITION Cond, CONDITION Update)
+/**************************************************************
+ INPUT: Two conditions.
+ RETURNS: <Cond> extended by the clauses, antecedent, constraint and succedent
+ literals of <Update>
+ EFFECT: <Cond> is destructively extended by <Update>.
+***************************************************************/
+{
+ LIST Lits,Antecedent,Succedent,Constraint;
+ SYMBOL Old,New;
+
+ term_StartMaxRenaming(sort_ConditionVar(Cond));
+ Constraint = term_CopyTermList(sort_ConditionConstraint(Update));
+ Antecedent = term_CopyTermList(sort_ConditionAntecedent(Update));
+ Succedent = term_CopyTermList(sort_ConditionSuccedent(Update));
+ for (Lits=Constraint;!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ for (Lits=Antecedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ for (Lits=Succedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ Old = term_GetRenamedVarSymbol(sort_ConditionVar(Update));
+ New = symbol_CreateStandardVariable();
+ for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ Old = sort_ConditionVar(Cond);
+ for (Lits=sort_ConditionConstraint(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=sort_ConditionAntecedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=sort_ConditionSuccedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ sort_ConditionPutConstraint(Cond,list_Nconc(sort_ConditionConstraint(Cond),Constraint));
+ sort_ConditionPutAntecedent(Cond,list_Nconc(sort_ConditionAntecedent(Cond),Antecedent));
+ sort_ConditionPutSuccedent(Cond,list_Nconc(sort_ConditionSuccedent(Cond),Succedent));
+ sort_ConditionPutClauses(Cond,list_Nconc(list_Copy(sort_ConditionClauses(Update)),
+ sort_ConditionClauses(Cond)));
+ sort_ConditionPutVar(Cond,New);
+ sort_ConditionNormalize(Cond);
+
+ return Cond;
+}
+
+LIST sort_ExtendConditions(LIST Conditions, SLINK Link)
+/**************************************************************
+ INPUT: A list of conditions and a link.
+ RETURNS: A new list of conditions augmented by the conditions in <Link>.
+***************************************************************/
+{
+ LIST Result,Scan,Antecedent,Succedent,Constraint;
+ CONDITION Cond;
+
+ Result = list_Nil();
+
+ for (Scan=Conditions;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Cond = (CONDITION)list_Car(Scan);
+ Constraint = term_CopyTermList(sort_ConditionConstraint(Cond));
+ Antecedent = term_CopyTermList(sort_ConditionAntecedent(Cond));
+ Succedent = term_CopyTermList(sort_ConditionSuccedent(Cond));
+ if (sort_LinkNoResidues(Link))
+ Result = list_Cons(sort_ConditionCreate(sort_ConditionVar(Cond),Constraint,Antecedent,
+ Succedent,list_Cons(sort_LinkClause(Link),
+ list_Copy(sort_ConditionClauses(Cond)))),
+ Result);
+ else {
+ SYMBOL New,Old;
+ LIST NewAntecedent,NewSuccedent,NewConstraint,Lits;
+ term_StartMaxRenaming(sort_ConditionVar(Cond));
+ NewConstraint = term_CopyTermList(sort_LinkConstraint(Link));
+ NewAntecedent = term_CopyTermList(sort_LinkAntecedent(Link));
+ NewSuccedent = term_CopyTermList(sort_LinkSuccedent(Link));
+ for (Lits=NewConstraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ for (Lits=NewAntecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ for (Lits=NewSuccedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ Old = term_GetRenamedVarSymbol(sort_LinkVar(Link));
+ New = symbol_CreateStandardVariable();
+ for (Lits=NewConstraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=NewAntecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=NewSuccedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ Old = sort_ConditionVar(Cond);
+ for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ Result = list_Cons(sort_ConditionNormalize(sort_ConditionCreate(New,list_Nconc(Constraint,NewConstraint),
+ list_Nconc(Antecedent,NewAntecedent),
+ list_Nconc(Succedent,NewSuccedent),
+ list_Cons(sort_LinkClause(Link),
+ list_Copy(sort_ConditionClauses(Cond))))),
+ Result);
+ }
+ }
+ return Result;
+}
+
+CONDITION sort_ConditionsUnion(LIST Conditions)
+/**************************************************************
+ INPUT: A list of conditions.
+ RETURNS: A new condition that is the union of all input conditions.
+***************************************************************/
+{
+ LIST Scan,Antecedent,Succedent,Constraint;
+ CONDITION Cond;
+ SYMBOL Act,New,Old;
+ LIST NewAntecedent,NewSuccedent,NewConstraint,NewClauses,Lits;
+
+ if (list_Empty(Conditions))
+ return sort_ConditionCreate(symbol_FirstVariable(),list_Nil(),list_Nil(),list_Nil(),
+ list_Nil());
+ else {
+ Cond = (CONDITION)list_Car(Conditions);
+ Conditions = list_Cdr(Conditions);
+ Act = sort_ConditionVar(Cond);
+ NewConstraint = term_CopyTermList(sort_ConditionConstraint(Cond));
+ NewAntecedent = term_CopyTermList(sort_ConditionAntecedent(Cond));
+ NewSuccedent = term_CopyTermList(sort_ConditionSuccedent(Cond));
+ NewClauses = list_Copy(sort_ConditionClauses(Cond));
+ }
+
+ for (Scan=Conditions;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Cond = (CONDITION)list_Car(Scan);
+ if (!sort_ConditionNoResidues(Cond)) {
+ Constraint = term_CopyTermList(sort_ConditionConstraint(Cond));
+ Antecedent = term_CopyTermList(sort_ConditionAntecedent(Cond));
+ Succedent = term_CopyTermList(sort_ConditionSuccedent(Cond));
+
+ term_StartMaxRenaming(Act);
+ for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_Rename(list_Car(Lits));
+ Old = term_GetRenamedVarSymbol(sort_ConditionVar(Cond));
+ New = symbol_CreateStandardVariable();
+ for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Old,New);
+ for (Lits=NewConstraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Act,New);
+ for (Lits=NewAntecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Act,New);
+ for (Lits=NewSuccedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+ term_ExchangeVariable(list_Car(Lits),Act,New);
+ Act = New;
+ NewConstraint = list_Nconc(Constraint,NewConstraint);
+ NewAntecedent = list_Nconc(Antecedent,NewAntecedent);
+ NewSuccedent = list_Nconc(Succedent,NewSuccedent);
+ }
+ NewClauses = list_Nconc(list_Copy(sort_ConditionClauses(Cond)),NewClauses);
+ }
+
+ return sort_ConditionNormalize(sort_ConditionCreate(Act,NewConstraint,NewAntecedent,NewSuccedent,NewClauses));
+}
+
+void sort_ConditionDelete(CONDITION C)
+/**************************************************************
+ INPUT: A condition.
+ RETURNS: Nothing.
+ MEMORY: The condition and all literals and lists are deleted.
+***************************************************************/
+{
+ if (C!= (CONDITION)NULL) {
+ term_DeleteTermList(sort_ConditionConstraint(C));
+ term_DeleteTermList(sort_ConditionAntecedent(C));
+ term_DeleteTermList(sort_ConditionSuccedent(C));
+ list_Delete(sort_ConditionClauses(C));
+
+ sort_ConditionFree(C);
+ }
+}
+
+
+CONDITION sort_ConditionCopy(CONDITION C)
+/**************************************************************
+ INPUT: A condition.
+ RETURNS: A copy of the condition.
+***************************************************************/
+{
+ return sort_ConditionCreate(sort_ConditionVar(C),
+ term_CopyTermList(sort_ConditionConstraint(C)),
+ term_CopyTermList(sort_ConditionAntecedent(C)),
+ term_CopyTermList(sort_ConditionSuccedent(C)),
+ list_Copy(sort_ConditionClauses(C)));
+}
+
+
+
+BOOL sort_IsBaseSortSymbol(SYMBOL Symbol)
+/*********************************************************
+ INPUT: A Symbol.
+ RETURNS: The boolean value TRUE, if 'Symbol' is a
+ basesortsymbol, FALSE else.
+*******************************************************/
+{
+#ifdef CHECK
+ if (!symbol_IsSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sort_IsBaseSymbol :");
+ misc_ErrorReport(" Illegal input. Input not a symbol.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return(symbol_IsPredicate(Symbol) && symbol_Arity(Symbol) == 1);
+}
+
+
+SORT sort_TheorySortOfSymbol(SORTTHEORY Theory, SYMBOL Symbol)
+/*********************************************************
+ INPUT: A sort theory and a base sort symbol.
+ RETURNS: The Basesort of 'Symbol'.
+*******************************************************/
+{
+#ifdef CHECK
+ if (!sort_IsBaseSortSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sort_TheorySortOfSymbol :");
+ misc_ErrorReport(" Illegal input. Input not a symbol.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return (list_List(sort_TheoryNode(Theory, Symbol)));
+}
+
+
+static void sort_EvalSubsortNoResidues(SORTTHEORY Theory, LIST Nodes)
+/*********************************************************
+ INPUT: A sort theory and a list of nodes from this theory.
+ RETURNS: None.
+ EFFECT: Starting from the nodes in <Nodes> the subsort
+ graph is exploited as long as links fire and
+ new nodes become true. Only links without residues
+ are considered.
+*******************************************************/
+{
+ NODE Node,Head;
+ LIST Scan,Help,Clauses;
+ SLINK Link;
+
+ while (!list_Empty(Nodes)) {
+ Node = (NODE)list_Car(Nodes);
+ Scan = Nodes;
+ Nodes = list_Cdr(Nodes);
+ list_Free(Scan);
+
+ for (Scan = sort_NodeLinks(Node);
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan)) {
+ Link = (SLINK)list_Car(Scan);
+ if (sort_LinkNoResidues(Link) && sort_LinkDecrementFire(Link) == 0) {
+ Head = sort_LinkOutput(Link);
+ if (!sort_NodeValue(Theory, Head)) {
+ Clauses = list_List(sort_LinkClause(Link));
+ for (Help=sort_LinkInput(Link);!list_Empty(Help);Help=list_Cdr(Help))
+ if (!list_Empty(sort_NodeConditions(list_Car(Help))))
+ Clauses =
+ list_Nconc(list_Copy(sort_ConditionClauses(
+ list_Car(sort_NodeConditions(list_Car(Help))))),Clauses);
+ sort_DeleteConditionList(sort_NodeConditions(Head));
+ sort_PutNodeConditions(Head,list_List(sort_ConditionCreateNoResidues(Clauses)));
+ sort_PutNodeTrue(Theory, Head);
+ Nodes = list_Cons(Head,Nodes);
+ }
+ }
+ }
+ }
+}
+
+
+static BOOL sort_TestSubsortSpecial(SORTTHEORY Theory, LIST Nodes, LIST Goal)
+/*********************************************************
+ INPUT: A sort theory and a list of nodes from this theory and
+ a list of goal nodes.
+ RETURNS: TRUE if we can walk from at least one node of <Nodes> over
+ a previously evaluated sort structure.
+*******************************************************/
+{
+ NODE Node,Head;
+ LIST Scan;
+ SLINK Link;
+
+ while (!list_Empty(Nodes)) {
+ Node = (NODE)list_NCar(&Nodes);
+ if (list_PointerMember(Goal,Node)) {
+ list_Delete(Nodes);
+ return TRUE;
+ }
+ for (Scan = sort_NodeLinks(Node);!list_Empty(Scan);Scan = list_Cdr(Scan)) {
+ Link = (SLINK)list_Car(Scan);
+ if (sort_LinkFire(Link) == 0) {
+ Head = sort_LinkOutput(Link);
+ Nodes = list_Cons(Head,Nodes);
+ }
+ }
+ }
+ return FALSE;
+}
+
+static void sort_EvalSubsortSpecial(SORTTHEORY Theory, LIST Nodes)
+/*********************************************************
+ INPUT: A sort theory and a list of nodes from this theory.
+ RETURNS: None.
+ EFFECT: Starting from the nodes in <Nodes> the subsort
+ graph is exploited as long as links fire and
+ new nodes become true. Only links without residues
+ are considered.
+*******************************************************/
+{
+ NODE Node,Head;
+ LIST Scan;
+ SLINK Link;
+
+ while (!list_Empty(Nodes)) {
+ Node = (NODE)list_NCar(&Nodes);
+ for (Scan = sort_NodeLinks(Node);!list_Empty(Scan);Scan = list_Cdr(Scan)) {
+ Link = (SLINK)list_Car(Scan);
+ if (sort_LinkDecrementFire(Link) == 0) {
+ Head = sort_LinkOutput(Link);
+ if (!sort_NodeValue(Theory, Head)) {
+ sort_PutNodeTrue(Theory, Head);
+ Nodes = list_Cons(Head,Nodes);
+ }
+ }
+ }
+ }
+}
+
+static void sort_EvalSubsort(SORTTHEORY Theory, LIST Nodes)
+/*********************************************************
+ INPUT: A sort theory and a list of nodes from this theory.
+ RETURNS: None.
+ EFFECT: Starting from the nodes in <Nodes> the subsort
+ graph is exploited as long as links fire and
+ new nodes become true.
+ Only ONE condition for each node becoming
+ valid is established.
+*******************************************************/
+{
+ NODE Node,Head;
+ LIST Scan,Help;
+ SLINK Link;
+ CONDITION Cond;
+
+ while (!list_Empty(Nodes)) {
+ Node = (NODE)list_Car(Nodes);
+ Scan = Nodes;
+ Nodes = list_Cdr(Nodes);
+ list_Free(Scan);
+
+ for (Scan = sort_NodeLinks(Node);
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan)) {
+ Link = (SLINK)list_Car(Scan);
+ if (sort_LinkDecrementFire(Link) == 0) {
+ Head = sort_LinkOutput(Link);
+ if (!sort_NodeValue(Theory, Head)) {
+ Cond = sort_ConditionCreate(symbol_FirstVariable(),list_Nil(),list_Nil(),list_Nil(),list_Nil());
+ for (Help=sort_LinkInput(Link);!list_Empty(Help);Help=list_Cdr(Help))
+ if (!list_Empty(sort_NodeConditions(list_Car(Help))))
+ Cond = sort_ExtendConditionByCondition(Cond,list_Car(sort_NodeConditions(list_Car(Help))));
+ sort_ExtendConditionByLink(Cond,Link);
+ sort_DeleteConditionList(sort_NodeConditions(Head));
+ sort_PutNodeConditions(Head,list_List(Cond));
+ sort_PutNodeTrue(Theory, Head);
+ Nodes = list_Cons(Head,Nodes);
+ }
+ }
+ }
+ }
+}
+
+
+CONDITION sort_TheoryIsSubsortOfNoResidues(SORTTHEORY Theory, SORT Sort1, SORT Sort2)
+/*********************************************************
+ INPUT: A sort theory and two sorts.
+ RETURNS: A condition if <Sort1> is a subsort of <Sort2> and NULL otherwise.
+*******************************************************/
+{
+ LIST Scan,Clauses;
+ SLINK Link;
+ NODE Node;
+ SORT Top;
+
+#ifdef CHECK
+ if (!sort_IsSort(Sort1) || !sort_IsSort(Sort2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sort_TheoryIsSubsortOfNoResidues :");
+ misc_ErrorReport(" Illegal sort input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ sort_TheoryIncrementMark(Theory);
+
+ /*fputs("\n Subsort Test: ", stdout);
+ sort_Print(Sort1);
+ putchar(' ');
+ sort_Print(Sort2);*/
+
+ for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Link = (SLINK)list_Third(list_Car(Scan));
+ sort_LinkResetFire(Link);
+ }
+
+ for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Node = (NODE)list_Car(Scan);
+ sort_DeleteConditionList(sort_NodeConditions(Node));
+ sort_PutNodeConditions(Node,list_List(sort_ConditionCreate(symbol_FirstVariable(),
+ list_Nil(),list_Nil(),list_Nil(),list_Nil())));
+ sort_PutNodeTrue(Theory, Node);
+ }
+
+ Top = sort_TopSort();
+ for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Link = (SLINK)list_Third(list_Car(Scan));
+ if (list_Empty(sort_LinkInput(Link)) && sort_LinkNoResidues(Link)) {
+ Node = sort_LinkOutput(Link);
+ Top = sort_AddBaseNode(Top,Node);
+ sort_DeleteConditionList(sort_NodeConditions(Node));
+ sort_PutNodeConditions(Node,list_List(sort_ConditionCreateNoResidues(list_List(sort_LinkClause(Link)))));
+ sort_PutNodeTrue(Theory,Node);
+ }
+ }
+
+ sort_EvalSubsortNoResidues(Theory,sort_Intersect(Top,sort_Copy(Sort1)));
+ Top = sort_TopSort();
+
+ Clauses = list_Nil();
+
+ for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Node = (NODE)list_Car(Scan);
+ if (!sort_NodeValue(Theory,Node)) {
+ /*puts(" FALSE");*/
+ list_Delete(Clauses);
+ return NULL;
+ }
+ else
+ if (!list_Empty(sort_NodeConditions(Node)))
+ Clauses = list_Nconc(list_Copy(sort_ConditionClauses(list_Car(sort_NodeConditions(Node)))),
+ Clauses);
+ }
+ /*printf(" TRUE %lu\n",(unsigned long)Clauses);*/
+ return sort_ConditionCreateNoResidues(Clauses);
+}
+
+BOOL sort_TheoryIsSubsortOf(SORTTHEORY Theory, SORT Sort1, SORT Sort2)
+/*********************************************************
+ INPUT: A sort theory and two sorts.
+ RETURNS: TRUE if <Sort1> is a subsort of <Sort2> and NULL otherwise.
+*******************************************************/
+{
+ LIST Scan;
+ SLINK Link;
+ NODE Node;
+
+ sort_TheoryIncrementMark(Theory);
+
+ /*fputs("\n Subsort Test: ", stdout);
+ sort_Print(Sort1);
+ putchar(' ');
+ sort_Print(Sort2);*/
+
+ for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Link = (SLINK)list_Third(list_Car(Scan));
+ sort_LinkResetFire(Link);
+ }
+
+ for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Node = (NODE)list_Car(Scan);
+ sort_PutNodeTrue(Theory, Node);
+ }
+
+ sort_EvalSubsortSpecial(Theory,sort_Copy(Sort1));
+
+ for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Node = (NODE)list_Car(Scan);
+ if (!sort_NodeValue(Theory,Node))
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+BOOL sort_TheoryIsSubsortOfExtra(SORTTHEORY Theory, SORT Extra, SORT Sort1, SORT Sort2)
+/*********************************************************
+ INPUT: A sort theory and three sorts.
+ RETURNS: TRUE if <Sort1> is a subsort of <Sort2> and <Extra> is
+ useful for that purpose
+*******************************************************/
+{
+ LIST Scan;
+ SLINK Link;
+ NODE Node;
+
+ sort_TheoryIncrementMark(Theory);
+
+ /*fputs("\n Subsort Test: ", stdout);
+ sort_Print(Sort1);
+ putchar(' ');
+ sort_Print(Sort2);*/
+
+ for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Link = (SLINK)list_Third(list_Car(Scan));
+ sort_LinkResetFire(Link);
+ }
+
+ for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Node = (NODE)list_Car(Scan);
+ sort_PutNodeTrue(Theory, Node);
+ }
+
+ sort_EvalSubsortSpecial(Theory,sort_Copy(Sort1));
+
+ for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Node = (NODE)list_Car(Scan);
+ if (!sort_NodeValue(Theory,Node))
+ return FALSE;
+ }
+
+ return sort_TestSubsortSpecial(Theory,sort_Copy(Extra),Sort2);
+
+}
+
+LIST sort_TheoryComputeAllSubsortHits(SORTTHEORY Theory, SORT Sort1, SORT Sort2)
+/*********************************************************
+ INPUT: A sort theory and two sorts.
+ RETURNS: All possible sorts that are subsets of <Sort1> that are subsorts
+ of <Sort2> together with all conditions.
+*******************************************************/
+{
+ LIST Scan,Result,Search,Scan2,Visited;
+ SLINK Link;
+ NODE Node;
+ SOJU Cand;
+ BOOL Valid,ValidStart;
+ NAT StartMark;
+
+ sort_TheoryIncrementMark(Theory);
+ StartMark = sort_TheoryMark(Theory);
+
+ /*fputs("\n Exhaustive Subsort Test: ", stdout);
+ sort_Print(Sort1);
+ putchar(' ');
+ sort_Print(Sort2);*/
+
+ for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Link = (SLINK)list_Third(list_Car(Scan));
+ sort_LinkResetFire(Link);
+ }
+
+ for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Node = (NODE)list_Car(Scan);
+ sort_DeleteConditionList(sort_NodeConditions(Node));
+ sort_PutNodeConditions(Node,list_List(sort_ConditionCreate(symbol_FirstVariable(),
+ list_Nil(),list_Nil(),list_Nil(),list_Nil())));
+ sort_PutNodeTrue(Theory, Node);
+ sort_PutNodeStartTrue(Theory,Node);
+ }
+
+ sort_EvalSubsort(Theory,sort_Copy(Sort1));
+
+ for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) {/* Subsort condition must hold */
+ Node = (NODE)list_Car(Scan);
+ if (!sort_NodeValue(Theory,Node))
+ return list_Nil();
+ }
+
+ Result = list_Nil();
+ Search = list_List(sort_PairCreate(sort_Copy(Sort2),sort_ConditionCreateNoResidues(list_Nil())));
+ Visited = list_Nil();
+ fputs("\n\n Starting Soju Search:", stdout);
+
+ while (!list_Empty(Search)) {
+ Cand = (SOJU)list_Car(Search);
+ Scan = Search;
+ Search = list_Cdr(Search);
+ list_Free(Scan);
+ putchar('\n');
+ sort_PairPrint(Cand);
+
+ if (!sort_TheorySortMember(Theory,Visited,sort_PairSort(Cand))) {
+ Visited = list_Cons(sort_Copy(sort_PairSort(Cand)),Visited);
+ ValidStart = TRUE;
+ Valid = TRUE;
+ for (Scan=sort_PairSort(Cand);!list_Empty(Scan) && (ValidStart || Valid);Scan=list_Cdr(Scan)) {
+ Node = (NODE)list_Car(Scan);
+ if (sort_NodeMark(Node) != StartMark) {
+ Valid = FALSE;
+ ValidStart = FALSE;
+ }
+ else
+ if (sort_NodeStart(Node) != StartMark)
+ ValidStart = FALSE;
+ }
+ if (Valid) {
+ if (ValidStart)
+ Result = list_Cons(sort_PairCopy(Cand),Result);
+
+ for (Scan=sort_PairSort(Cand);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Node = (NODE)list_Car(Scan);
+ for (Scan2=sort_TheorySuborigcls(Theory);!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) {
+ Link = (SLINK)list_Third(list_Car(Scan2));
+ if (sort_LinkOutput(Link) == Node && !list_Empty(sort_LinkInput(Link)))
+ Search = list_Cons(sort_PairCreate(list_PointerDeleteDuplicates(sort_Intersect(sort_DeleteBaseNode(sort_Copy(sort_PairSort(Cand)),Node),sort_Copy(sort_LinkInput(Link)))),
+ sort_ExtendConditionByLink(sort_ConditionCopy(sort_PairCondition(Cand)),Link)),
+ Search);
+ }
+ }
+ }
+ sort_PairDelete(Cand);
+ }
+ }
+ list_DeleteWithElement(Visited,(void (*)(POINTER)) sort_Delete);
+
+ return Result;
+}
+
+static SORT sort_VarSort(SORTTHEORY Theory, SYMBOL Var, CLAUSE Clause, int i)
+/*********************************************************
+ INPUT: A variable symbol, a clause and a literal index in the clause.
+ RETURNS: The sort of <Var> with respect to the sort constraint
+ literals (possibly in the antecedent)
+ in <Clause> except literal <i> that is not considered.
+ MEMORY: Both Sorts are destroyed.
+*******************************************************/
+{
+ SORT Result;
+ int j;
+ TERM Atom;
+
+ Result = sort_TopSort();
+
+ for (j=clause_FirstConstraintLitIndex(Clause);j<=clause_LastAntecedentLitIndex(Clause);j++)
+ if (j != i) {
+ Atom = clause_LiteralAtom(clause_GetLiteral(Clause,j));
+ if (symbol_IsBaseSort(term_TopSymbol(Atom)) &&
+ term_TopSymbol(term_FirstArgument(Atom)) == Var)
+ Result = sort_Intersect(Result,sort_TheorySortOfSymbol(Theory,term_TopSymbol(Atom)));
+ }
+
+ return Result;
+}
+
+
+static BOOL sort_MatchNoResidues(SORTTHEORY Theory, TERM Term1, TERM Term2, CLAUSE Clause, LIST* Clauses)
+/*********************************************************
+ INPUT: A sort theory, two terms, a clause and list of clauses
+ as an additional return parameter.
+ RETURNS: TRUE iff there exists a well-sorted matcher from <Term1> to <Term2>
+ The sorts of variables in <Term1> is determined by the sort constraint in <Clause>
+ The sorts of subterms of <Term2> are assumed to be already computed and stored.
+*******************************************************/
+{
+ int l;
+ SUBST subst,scan;
+ SORT varsort;
+ LIST NewClauses;
+ SOJU Pair;
+ CONDITION Cond;
+
+ l = clause_Length(Clause);
+ NewClauses = list_Nil();
+
+ cont_StartBinding();
+ unify_Match(cont_LeftContext(),Term1,Term2);
+ subst = subst_ExtractMatcher();
+ cont_BackTrack();
+
+ /*putchar('\n'); term_Print(Term1);fputs("->",stdout);
+ term_Print(Term2);putchar(':');subst_Print(subst);
+ putchar('\n');*/
+ for (scan=subst;!subst_Empty(scan);scan=subst_Next(scan)) {
+ varsort = sort_VarSort(Theory,subst_Dom(scan),Clause,l);
+ Pair = hash_Get(subst_Cod(scan));
+ if ((Cond = sort_TheoryIsSubsortOfNoResidues(Theory,sort_PairSort(Pair),varsort)) == NULL) {
+ sort_DeleteOne(varsort);
+ list_Delete(NewClauses);
+ subst_Free(subst);
+ return FALSE;
+ } else {
+ NewClauses = list_Nconc(NewClauses,
+ list_Copy(sort_ConditionClauses(sort_PairCondition(Pair))));
+ NewClauses = list_Nconc(NewClauses,sort_ConditionClauses(Cond));
+ sort_ConditionPutClauses(Cond,list_Nil());
+ sort_ConditionDelete(Cond);
+ }
+
+ sort_DeleteOne(varsort);
+ }
+
+ subst_Free(subst);
+ *Clauses = list_Nconc(NewClauses,*Clauses);
+ return TRUE;
+}
+
+
+static SOJU sort_ComputeSortInternNoResidues(SORTTHEORY Theory, TERM Term,
+ CLAUSE Clause, int i,
+ FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/*********************************************************
+ INPUT: A Term, a sort theory representing a set of
+ clauses, a clause wrt that variable sorts are
+ computed, where the literal <i> is discarded,
+ a flag store and a precedence.
+ The sorts of 'Term's args have to be known.
+ RETURNS: The sort of 'Term' wrt. the sort theory of the
+ clause set. Be careful, the Sort-entries of
+ 'Term' and its subterms are changed.
+*******************************************************/
+{
+ SORT Sort;
+ LIST HelpList, Scan, Clauses;
+ TERM QueryTerm;
+
+ Sort = sort_TopSort();
+ Clauses = list_Nil();
+
+ if (term_IsVariable(Term))
+ Sort = sort_VarSort(Theory,term_TopSymbol(Term),Clause,i);
+ else {
+ HelpList = st_GetGen(cont_LeftContext(), sort_TheoryIndex(Theory), Term);
+ for (Scan=HelpList;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ SYMBOL Top;
+ LITERAL ActLit;
+ TERM Atom;
+ CLAUSE ActClause;
+
+ QueryTerm = (TERM)list_First(Scan);
+
+ if (!term_IsVariable(QueryTerm)) { /* Currently also subort declarations are in the index ...*/
+ Atom = (TERM)list_First(term_SupertermList(QueryTerm));
+ Top = term_TopSymbol(Atom);
+ ActLit = (LITERAL)list_First(term_SupertermList(Atom));
+ ActClause = clause_LiteralOwningClause(ActLit);
+ if (clause_IsSortTheoryClause(ActClause, Flags, Precedence) &&
+ sort_MatchNoResidues(Theory,QueryTerm,Term, ActClause,&Clauses) &&
+ !sort_ContainsSymbol(Sort,Top)) {
+ Sort = sort_Intersect(Sort,sort_TheorySortOfSymbol(Theory,Top));
+ Clauses = list_Cons(ActClause,Clauses);
+ }
+ }
+ }
+ list_Delete(HelpList);
+ }
+ return (sort_PairCreate(Sort,sort_ConditionCreateNoResidues(Clauses)));
+}
+
+
+SOJU sort_ComputeSortNoResidues(SORTTHEORY Theory, TERM Term, CLAUSE Clause,
+ int i, FLAGSTORE Flags, PRECEDENCE Precedence)
+/*********************************************************
+ INPUT: A Term and an Index representing a set of
+ clauses, a clause to access
+ variable-sort-information where the literal <i>
+ is discarded, a flag store and a precedence.
+ RETURNS: The sort of 'Term' wrt. the sort theory of the
+ clause set and the clauses used for this
+ computation.
+ Be careful, the Sort-entries of
+ 'Term' and its subterms are changed, if they
+ already existed.
+*******************************************************/
+{
+ int SubtermStack;
+ SOJU SortPair;
+
+ SortPair = (SOJU)NULL;
+ SubtermStack = stack_Bottom();
+ sharing_PushOnStack(Term);
+
+
+ while (!stack_Empty(SubtermStack)){
+ Term = stack_PopResult();
+
+ if (!(SortPair = (SOJU)hash_Get(Term))) {
+ SortPair = sort_ComputeSortInternNoResidues(Theory,Term,Clause,i,
+ Flags, Precedence);
+ /*fputs("\n Computed:",stdout);term_Print(Term);
+ putchar(':');sort_PairPrint(SortPair);putchar('\n');*/
+ hash_Put(Term,SortPair);
+ }
+ }
+
+ SortPair = sort_PairCopy(SortPair);
+ hash_ResetWithValue((void (*)(POINTER)) sort_DeleteSortPair);
+
+ return(SortPair);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * Creating and Analyzing Sort Theories * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static BOOL sort_SortTheoryIsTrivial(SORTTHEORY Theory, LIST Clauses)
+/*********************************************************
+ INPUT: A sort theory and a list of clauses that generated the theory.
+ RETURNS: TRUE iff all considered base sorts are top.
+*******************************************************/
+{
+ LIST Sorts;
+ CLAUSE Clause;
+ int i,n;
+ CONDITION Cond;
+
+ Sorts = list_Nil();
+
+ /* fputs("\n\nAnalyzing Theory:", stdout); */
+
+ while (!list_Empty(Clauses)) {
+ Clause = (CLAUSE)list_Car(Clauses);
+ n = clause_Length(Clause);
+ Clauses = list_Cdr(Clauses);
+
+ /* fputs("\n\t", stdout);clause_Print(Clause); */
+
+ for (i=clause_FirstConstraintLitIndex(Clause); i<n; i++)
+ Sorts = list_Cons((POINTER)term_TopSymbol(clause_LiteralAtom(
+ clause_GetLiteral(Clause,i))), Sorts);
+
+ Sorts = list_PointerDeleteDuplicates(Sorts);
+ }
+
+ Clauses = Sorts;
+ while (!list_Empty(Clauses)) {
+ list_Rplaca(Clauses,sort_TheorySortOfSymbol(Theory,(SYMBOL)list_Car(Clauses)));
+ Clauses = list_Cdr(Clauses);
+ }
+
+ n = list_Length(Sorts);
+ i = 0;
+ Clauses = Sorts;
+
+ /* printf("\n\t There are %d different sorts.",n); */
+
+ while (!list_Empty(Clauses)) {
+ if ((Cond = sort_TheoryIsSubsortOfNoResidues(Theory,sort_TopSort(),list_Car(Clauses)))) {
+ sort_ConditionDelete(Cond);
+ i++;
+ }
+ sort_DeleteOne(list_Car(Clauses));
+ Clauses = list_Cdr(Clauses);
+ }
+
+ list_Delete(Sorts);
+
+ return (i == n); /* All sorts are trivial */
+}
+
+
+static LIST sort_ApproxPseudoLinear(LIST Constraint, TERM Head, SYMBOL Var)
+/**************************************************************
+ INPUT: A list of constraint literals, the head literal term
+ and a variable maximal for all variables.
+ RETURNS: The new list of constraint literals.
+ EFFECT: The succedent literal is made pseudo-linear.
+ The function is DESTRUCTIVE.
+***************************************************************/
+{
+ TERM Atom;
+ LIST RenVars,Scan1,Scan2,Lits;
+ SYMBOL OldVar, NewVar;
+
+ RenVars = term_RenamePseudoLinear(Head,Var);
+ Lits = list_Nil();
+
+ for (Scan1=RenVars;!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+ OldVar = (SYMBOL)list_PairFirst(list_Car(Scan1));
+ NewVar = (SYMBOL)list_PairSecond(list_Car(Scan1));
+ list_PairFree(list_Car(Scan1));
+ for (Scan2=Constraint;!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) {
+ Atom = (TERM)list_Car(Constraint);
+ if (symbol_Equal(term_TopSymbol(term_FirstArgument(Atom)),OldVar))
+ Lits = list_Cons(term_Create(term_TopSymbol(Atom),
+ list_List(term_Create(NewVar,list_Nil()))), Lits);
+ }
+ }
+ list_Delete(RenVars);
+
+ Lits = list_Nconc(Constraint,Lits);
+
+ return Lits;
+}
+
+
+static LIST sort_ApproxHornClauses(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause to make special horn clauses from, a flag
+ store and a precedence.
+ RETURNS: The list of clauses according to the rule
+ ClauseDeletion.
+ MEMORY: Allocates memory for the clauses and the list.
+***************************************************************/
+{
+ LIST Result, NewConstraint,NewSuccedent;
+ CLAUSE NewClause;
+ LITERAL LitK;
+ int i,length,j,lc,pli;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sort_ApproxHornClauses :");
+ misc_ErrorReport(" Illegal input. Input not a clause.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+
+ if (clause_HasOnlyVarsInConstraint(Clause, Flags, Precedence) &&
+ clause_HasSortInSuccedent(Clause, Flags, Precedence)) {
+ length = clause_Length(Clause);
+
+ for (i = clause_FirstSuccedentLitIndex(Clause); i < length; i++) {
+ LitK = clause_GetLiteral(Clause, i);
+
+ if (symbol_Arity(term_TopSymbol(clause_LiteralSignedAtom(LitK))) == 1) {
+ pli = i;
+ NewSuccedent = list_List(term_Copy(clause_LiteralSignedAtom(LitK)));
+ NewConstraint = list_Nil();
+ lc = clause_LastConstraintLitIndex(Clause);
+
+ for (j = clause_FirstLitIndex(); j <= lc; j++)
+ if (clause_LitsHaveCommonVar(LitK, clause_GetLiteral(Clause, j)))
+ NewConstraint = list_Cons(term_Copy(clause_LiteralAtom(
+ clause_GetLiteral(Clause, j))), NewConstraint);
+
+ if (!list_Empty(NewConstraint))
+ NewConstraint = sort_ApproxPseudoLinear(NewConstraint,
+ list_Car(NewSuccedent),
+ clause_MaxVar(Clause));
+
+ NewClause = clause_Create(NewConstraint, list_Nil(), NewSuccedent,
+ Flags, Precedence);
+ clause_SetSplitLevel(NewClause, 0);
+ clause_SetFlag(NewClause,WORKEDOFF);
+ clause_SetFromClauseDeletion(NewClause);
+ clause_SetParentClauses(NewClause, list_List((POINTER)clause_Number(Clause)));
+ clause_AddParentLiteral(NewClause, pli);
+
+ list_Delete(NewConstraint);
+ list_Delete(NewSuccedent);
+ Result = list_Cons(NewClause, Result);
+ }
+ }
+ }
+ return(Result);
+}
+
+LIST sort_ApproxMaxDeclClauses(CLAUSE Clause, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A declaration clause to make special horn clauses
+ from, a flag store and a precedence.
+ RETURNS: The list of Horn clauses that are pseudo-linear declaration
+ clauses generated from maximal declarations in <Clause>
+ MEMORY: Allocates memory for the clauses and the list.
+***************************************************************/
+{
+ LIST Result, NewConstraint,NewSuccedent;
+ CLAUSE NewClause;
+ LITERAL LitK;
+ int i,length,j,lc,pli;
+
+#ifdef CHECK
+ if (!clause_IsClause(Clause, Flags, Precedence) ||
+ !clause_IsDeclarationClause(Clause)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In sort_ApproxMaxDeclClauses :");
+ misc_ErrorReport(" Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Nil();
+ length = clause_Length(Clause);
+
+ for (i = clause_FirstSuccedentLitIndex(Clause); i < length; i++) {
+ LitK = clause_GetLiteral(Clause, i);
+
+ if (clause_LiteralIsMaximal(LitK) &&
+ symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(LitK)))) {
+ pli = i;
+ NewSuccedent = list_List(term_Copy(clause_LiteralSignedAtom(LitK)));
+ NewConstraint = list_Nil();
+ lc = clause_LastConstraintLitIndex(Clause);
+
+ for (j = clause_FirstLitIndex(); j <= lc; j++)
+ if (clause_LitsHaveCommonVar(LitK, clause_GetLiteral(Clause, j)))
+ NewConstraint = list_Cons(term_Copy(clause_LiteralAtom(clause_GetLiteral(Clause, j))),
+ NewConstraint);
+
+ if (!list_Empty(NewConstraint))
+ NewConstraint = sort_ApproxPseudoLinear(NewConstraint,
+ list_Car(NewSuccedent),
+ clause_MaxVar(Clause));
+
+ NewClause = clause_Create(NewConstraint, list_Nil(), NewSuccedent,
+ Flags, Precedence);
+ clause_SetSplitLevel(NewClause, 0);
+ clause_SetFlag(NewClause,WORKEDOFF);
+ clause_SetFromClauseDeletion(NewClause);
+ clause_SetParentClauses(NewClause, list_List(Clause)); /* The clause itself is added! */
+ clause_AddParentLiteral(NewClause, pli);
+
+ list_Delete(NewConstraint);
+ list_Delete(NewSuccedent);
+ Result = list_Cons(NewClause, Result);
+ }
+ }
+ return(Result);
+}
+
+
+static LIST sort_ApproxClauses(LIST Clauses, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A list of top level clauses, a flag store and a
+ precedence.
+ RETURNS: A list of approximated clauses from <Clauses> which must
+ be used for sort deletion.
+ EFFECT: None.
+***************************************************************/
+{
+ LIST Result,ApproxClauses;
+ CLAUSE ActClause;
+
+ Result = list_Nil();
+
+ while (!list_Empty(Clauses)) {
+ ActClause = (CLAUSE)list_Car(Clauses);
+ ApproxClauses = sort_ApproxHornClauses(ActClause, Flags, Precedence);
+ Result = list_Nconc(ApproxClauses,Result);
+ Clauses = list_Cdr(Clauses);
+ }
+
+ return Result;
+}
+
+LIST sort_EliminateSubsumedClauses(LIST Clauses)
+/*********************************************************
+ INPUT: A list of clauses.
+ RETURNS: <Clauses> without subsumed clauses.
+*******************************************************/
+{
+ LIST RedundantClauses,Iter,Scan;
+ BOOL Kept;
+
+ RedundantClauses = list_Nil();
+ for (Scan = Clauses; !list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Kept = TRUE;
+ for (Iter = Clauses;!list_Empty(Iter) && Kept; Iter = list_Cdr(Iter))
+ if (list_Car(Iter) != list_Car(Scan) &&
+ !list_PointerMember(RedundantClauses,list_Car(Iter)) &&
+ subs_Subsumes(list_Car(Iter),list_Car(Scan),subs_NoException(),subs_NoException())) {
+ Kept = FALSE;
+ RedundantClauses = list_Cons(list_Car(Scan),RedundantClauses);
+ }
+ }
+ Clauses = list_NPointerDifference(Clauses,RedundantClauses);
+ clause_DeleteClauseList(RedundantClauses);
+ return Clauses;
+}
+
+
+SORTTHEORY sort_ApproxStaticSortTheory(LIST Clauses, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/*********************************************************
+ INPUT: A list of clauses, a flag store and a
+ precedence.
+ RETURNS: NULL if the approximated sort theory is trivial,
+ the approximated sort theory otherwise.
+*******************************************************/
+{
+ LIST Scan,ApproxClauses;
+ CLAUSE Clause;
+ SORTTHEORY Result;
+
+ Result = sort_TheoryCreate();
+ ApproxClauses = sort_ApproxClauses(Clauses, Flags, Precedence);
+ ApproxClauses = sort_EliminateSubsumedClauses(ApproxClauses);
+
+ /*fputs("\n\n Approx Sort Theory:", stdout);
+ for (Scan = ApproxClauses; !list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ fputs("\n\t",stdout); clause_Print(list_Car(Scan));
+ }*/
+
+ for (Scan = ApproxClauses; !list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ sort_TheoryInsertClause(Result,Clause,Clause,
+ clause_GetLiteral(Clause,clause_FirstSuccedentLitIndex(Clause)));
+ }
+
+ if (sort_SortTheoryIsTrivial(Result,ApproxClauses)) {
+ sort_TheoryDelete(Result);
+ Result = (SORTTHEORY)NULL;
+ }
+
+
+ if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+ fputs("\n\n Approx Sort Theory:", stdout);
+ if (Result) {
+ puts("\n");
+ sort_TheoryPrint(Result);
+ }
+ else
+ fputs(" trivial.", stdout);
+ }
+ list_Delete(ApproxClauses);
+
+ return Result;
+}
+
+
+SORTTHEORY sort_ApproxDynamicSortTheory(LIST Clauses)
+/*********************************************************
+ INPUT: A list of clauses.
+ RETURNS: The approximated dynamic sort theory for <Clauses>
+ Only maximal declarations are considered.
+*******************************************************/
+{
+ return (SORTTHEORY)NULL;
+}
+
+STR sort_AnalyzeSortStructure(LIST Clauses, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/*********************************************************
+ INPUT: A list of clauses, a flag store and a
+ precedence.
+ RETURNS: SORTEQMANY if all positive equations are many
+ sorted.
+ SORTEQDEC if all positive equations are sort
+ decreasing.
+ SORTEQNONE otherwise.
+ For the check, the static sort theory is
+ considered.
+*******************************************************/
+{
+ SORTTHEORY Theory;
+ LIST Scan;
+ CLAUSE Clause,Copy;
+ int i,l;
+ TERM Atom,Left,Right;
+ SOJU SojuLeft,SojuRight;
+ CONDITION Cond;
+ BOOL ManySorted, Decreasing;
+
+ Theory = sort_TheoryCreate();
+ ManySorted = TRUE;
+ Decreasing = TRUE;
+
+ for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ /* Extract static sort theory */
+ Clause = (CLAUSE)list_Car(Scan);
+ if (clause_IsPotentialSortTheoryClause(Clause, Flags, Precedence)) {
+ Copy = clause_Copy(Clause);
+ symbol_AddProperty(term_TopSymbol(clause_GetLiteralTerm(Copy,
+ clause_FirstSuccedentLitIndex(Copy))),
+ DECLSORT);
+ list_Delete(clause_ParentClauses(Copy));
+ clause_SetParentClauses(Copy,list_Nil());
+ list_Delete(clause_ParentLiterals(Copy));
+ clause_SetParentLiterals(Copy,list_Nil());
+ clause_SetNumber(Copy,clause_Number(Clause));
+ clause_SetSortConstraint(Copy,FALSE, Flags, Precedence);
+ sort_TheoryInsertClause(Theory,Clause,Copy,
+ clause_GetLiteral(Copy,clause_FirstSuccedentLitIndex(Copy)));
+ }
+ }
+
+ /*putchar('\n');
+ sort_TheoryPrint(Theory);
+ putchar('\n');*/
+
+ for (Scan=Clauses;!list_Empty(Scan) && Decreasing;Scan=list_Cdr(Scan)) {
+ Clause = (CLAUSE)list_Car(Scan);
+ l = clause_Length(Clause);
+ for (i=clause_FirstSuccedentLitIndex(Clause);i<l && Decreasing;i++) {
+ Atom = clause_GetLiteralTerm(Clause,i);
+ if (fol_IsEquality(Atom)) {
+ Left = term_FirstArgument(Atom);
+ Right = term_SecondArgument(Atom);
+ SojuLeft = sort_ComputeSortNoResidues(Theory, Left, Clause, i,
+ Flags, Precedence);
+ SojuRight = sort_ComputeSortNoResidues(Theory, Right,Clause, i,
+ Flags, Precedence);
+ if (sort_IsTopSort(sort_PairSort(SojuRight)) || sort_IsTopSort(sort_PairSort(SojuLeft))) {
+ /*fputs("\nNon decreasing equation ",stdout); term_PrintPrefix(Atom);
+ fputs(" in clause: ",stdout);clause_Print(Clause);putchar('\n');*/
+ ManySorted = FALSE;
+ Decreasing = FALSE;
+ }
+ else {
+ if (!sort_Eq(sort_PairSort(SojuRight), sort_PairSort(SojuLeft))) {
+ ManySorted = FALSE;
+ Cond = sort_TheoryIsSubsortOfNoResidues(Theory, sort_PairSort(SojuRight),
+ sort_PairSort(SojuLeft));
+ if (Cond && !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i))) {
+ sort_ConditionDelete(Cond);
+ Cond = sort_TheoryIsSubsortOfNoResidues(Theory, sort_PairSort(SojuLeft),
+ sort_PairSort(SojuRight));
+ }
+ if (Cond)
+ sort_ConditionDelete(Cond);
+ else {
+ /*fputs("\nNon decreasing equation ",stdout); term_PrintPrefix(Atom);
+ fputs(" in clause: ",stdout);clause_Print(Clause);putchar('\n');*/
+ Decreasing = FALSE;
+ }
+ }
+ }
+ sort_PairDelete(SojuLeft);
+ sort_PairDelete(SojuRight);
+ }
+ }
+ }
+ sort_TheoryDelete(Theory);
+ if (ManySorted)
+ return SORTEQMANY;
+ if (Decreasing)
+ return SORTEQDECR;
+
+ return SORTEQNONE;
+}
+
diff --git a/test/spass/sort.h b/test/spass/sort.h
new file mode 100644
index 0000000..83bc547
--- /dev/null
+++ b/test/spass/sort.h
@@ -0,0 +1,598 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SORTED REASONING * */
+/* * * */
+/* * $Module: SORT * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _SORT_
+#define _SORT_
+
+#include "clause.h"
+#include "unify.h"
+#include "hash.h"
+#include "subsumption.h"
+
+
+/**************************************************************/
+/* Data Structures and Constants */
+/**************************************************************/
+
+/* Objects of type SORT are used to store the sort information */
+/* for terms. SORT is a list of NODE's */
+
+typedef LIST SORT;
+/* List of sort nodes */
+
+typedef LIST SOJU;
+/* Pair: First Component Sort, Second Component Condition */
+
+typedef enum {SORTEQNONE=1, SORTEQDECR=2, SORTEQMANY=3} STR;
+/* The overall result of an sort theory analysis with respect to equations */
+
+typedef struct CONDITION_HELP {
+ SYMBOL var;
+ LIST constraint;
+ LIST antecedent;
+ LIST succedent;
+ LIST clauses;
+} CONDITION_NODE,*CONDITION;
+
+/* This data structure collects the conditions from conditioned subsort clauses */
+/* The constraint, antecedent, succedent lists contain lists of atoms used to */
+/* derive the subsort relationship that come from clauses. */
+
+
+typedef struct NODE_HELP {
+ LIST links;
+ NAT mark;
+ NAT start;
+ NAT extra;
+ LIST conditions;
+ SYMBOL symbol;
+} NODE_NODE,*NODE;
+
+/* This is a node from the subsort graph with outgoing links the represented */
+/* sort symbol and a mark indicating whether the node is already visited,i.e, */
+/* it is TRUE. Whereas start indicates whether the node was put true right */
+/* from the beginning. Conditions contains a list of conditions needed to set */
+/* the node true. */
+
+typedef struct SLINK_HELP {
+ LIST input;
+ NODE output;
+ int card;
+ int fire;
+ LIST constraint;
+ LIST antecedent;
+ LIST succedent;
+ SYMBOL var;
+ CLAUSE clause;
+} SLINK_NODE,*SLINK;
+
+/* This is a link in the subsort graph, with a list of input nodes that have */
+/* to become true in order to fire the link and set the output node TRUE */
+/* constraint, antecedent, succedent literals are the extra literals of */
+/* <clause> and <var> is the subsort variable. It is always assumed that the */
+/* subsort variable is the maximal variable with respect to the constraint, */
+/* antecedent and succedent literals. */
+
+typedef struct SORTTHEORY_HELP {
+ st_INDEX index;
+ NODE basesorttable[symbol__MAXSIGNATURE];
+ LIST suborigcls;
+ LIST termorigcls;
+ NAT mark;
+} SORTTHEORY_NODE,*SORTTHEORY;
+
+/* The index contains the term declarations mapped to their possibly */
+/* approximated term declarations of inserted clauses. The subsort declarations*/
+/* are handled by a specific graph initiated over the base sorts. There is */
+/* one node in the graph for every base sort (basesorttable) and links */
+/* correspond to subsort declaration clauses */
+/* The mark is used in the subsort graph to detect already visited nodes. */
+/* The lists suborigcls and termorigcls map original clauses to sort theory */
+/* clauses to links/terms respectively. They contain triples of this kind */
+
+
+
+/**************************************************************/
+/* Extern */
+/**************************************************************/
+
+void sort_ConditionDelete(CONDITION);
+CONDITION sort_ConditionCopy(CONDITION);
+
+
+/**************************************************************/
+/* Macros */
+/**************************************************************/
+
+static __inline__ SORT sort_TopSort(void)
+{
+ return list_Nil();
+}
+
+static __inline__ BOOL sort_IsTopSort(SORT S)
+{
+ return list_Empty(S);
+}
+
+static __inline__ SORT sort_Copy(SORT S)
+{
+ return list_Copy(S);
+}
+
+static __inline__ void sort_DeleteOne(SORT S)
+{
+ list_Delete(S);
+}
+
+static __inline__ SORT sort_Intersect(SORT S1, SORT S2)
+{
+ return list_Nconc(S1, S2);
+}
+
+static __inline__ SORT sort_DeleteBaseNode(SORT S, NODE N)
+{
+ return list_PointerDeleteElement(S,N);
+}
+
+static __inline__ SORT sort_AddBaseNode(SORT S, NODE N)
+{
+ return list_Cons(N,S);
+}
+
+static __inline__ void sort_NodeFree(NODE N)
+{
+ memory_Free(N,sizeof(NODE_NODE));
+}
+
+static __inline__ BOOL sort_NodeEqual(NODE N1, NODE N2)
+{
+ return (N1 == N2);
+}
+
+static __inline__ void sort_DeleteConditionList(LIST List)
+{
+ list_DeleteWithElement(List, (void (*)(POINTER)) sort_ConditionDelete);
+}
+
+static __inline__ void sort_NodeDelete(NODE N)
+{
+ list_Delete(N->links);
+ N->links = list_Nil();
+ sort_DeleteConditionList(N->conditions);
+ N->conditions = list_Nil();
+ sort_NodeFree(N);
+}
+
+static __inline__ LIST sort_NodeLinks(NODE N)
+{
+ return N->links;
+}
+
+static __inline__ BOOL sort_NodeValue(SORTTHEORY S, NODE N)
+{
+ return (N->mark == S->mark);
+}
+
+static __inline__ BOOL sort_NodeExtraValue(SORTTHEORY S, NODE N)
+{
+ return (N->extra == S->mark);
+}
+
+static __inline__ BOOL sort_NodeStartValue(SORTTHEORY S, NODE N)
+{
+ return (N->start == S->mark);
+}
+
+static __inline__ NAT sort_NodeMark(NODE N)
+{
+ return N->mark;
+}
+
+static __inline__ NAT sort_NodeStart(NODE N)
+{
+ return N->start;
+}
+
+static __inline__ SYMBOL sort_NodeSymbol(NODE N)
+{
+ return N->symbol;
+}
+
+static __inline__ LIST sort_NodeConditions(NODE N)
+{
+ return N->conditions;
+}
+
+static __inline__ void sort_PutNodeMark(NODE N, NAT M)
+{
+ N->mark = M;
+}
+
+static __inline__ void sort_PutNodeExtra(NODE N, NAT M)
+{
+ N->extra = M;
+}
+
+static __inline__ void sort_PutNodeStart(NODE N, NAT S)
+{
+ N->start = S;
+}
+
+static __inline__ void sort_PutNodeSymbol(NODE N, SYMBOL S)
+{
+ N->symbol = S;
+}
+
+static __inline__ void sort_PutNodeLinks(NODE N, LIST C)
+{
+ N->links = C;
+}
+
+static __inline__ void sort_PutNodeConditions(NODE N, LIST C)
+{
+ N->conditions = C;
+}
+
+static __inline__ void sort_PutNodeTrue(SORTTHEORY S, NODE N)
+{
+ N->mark = S->mark;
+}
+
+static __inline__ void sort_PutNodeExtraTrue(SORTTHEORY S, NODE N)
+{
+ N->extra = S->mark;
+}
+
+static __inline__ void sort_PutNodeStartTrue(SORTTHEORY S, NODE N)
+{
+ N->start = S->mark;
+}
+
+static __inline__ LIST sort_LinkInput(SLINK S)
+{
+ return S->input;
+}
+
+static __inline__ NODE sort_LinkOutput(SLINK S)
+{
+ return S->output;
+}
+
+static __inline__ int sort_LinkFire(SLINK S)
+{
+ return S->fire;
+}
+
+static __inline__ int sort_LinkVar(SLINK S)
+{
+ return S->var;
+}
+
+static __inline__ LIST sort_LinkConstraint(SLINK S)
+{
+ return S->constraint;
+}
+
+static __inline__ LIST sort_LinkAntecedent(SLINK S)
+{
+ return S->antecedent;
+}
+
+static __inline__ LIST sort_LinkSuccedent(SLINK S)
+{
+ return S->succedent;
+}
+
+static __inline__ CLAUSE sort_LinkClause(SLINK S)
+{
+ return S->clause;
+}
+
+static __inline__ int sort_LinkCard(SLINK S)
+{
+ return S->card;
+}
+
+static __inline__ void sort_PutLinkInput(SLINK S, LIST T)
+{
+ S->input = T;
+}
+
+static __inline__ void sort_PutLinkVar(SLINK S, SYMBOL V)
+{
+ S->var = V;
+}
+
+static __inline__ void sort_PutLinkConstraint(SLINK S, LIST T)
+{
+ S->constraint = T;
+}
+
+static __inline__ void sort_PutLinkAntecedent(SLINK S, LIST T)
+{
+ S->antecedent = T;
+}
+
+static __inline__ void sort_PutLinkSuccedent(SLINK S, LIST T)
+{
+ S->succedent = T;
+}
+
+static __inline__ void sort_PutLinkOutput(SLINK S,NODE H)
+{
+ S->output = H;
+}
+
+static __inline__ void sort_PutLinkClause(SLINK S, CLAUSE C)
+{
+ S->clause = C;
+}
+
+static __inline__ void sort_PutLinkCard(SLINK S,int L)
+{
+ S->card = L;
+}
+
+static __inline__ void sort_LinkResetFire(SLINK S) {
+ S->fire = S->card;
+}
+
+static __inline__ int sort_LinkDecrementFire(SLINK S)
+{
+ --(S->fire);
+ return S->fire;
+}
+
+static __inline__ void sort_LinkFree(SLINK S)
+{
+ memory_Free(S,sizeof(SLINK_NODE));
+}
+
+static __inline__ void sort_LinkDelete(SLINK S)
+{
+ LIST Scan;
+ for (Scan=sort_LinkInput(S); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ sort_PutNodeLinks(list_Car(Scan),list_PointerDeleteElement(sort_NodeLinks(list_Car(Scan)),S));
+ list_Delete(sort_LinkInput(S));
+ term_DeleteTermList(sort_LinkConstraint(S));
+ term_DeleteTermList(sort_LinkAntecedent(S));
+ term_DeleteTermList(sort_LinkSuccedent(S));
+ sort_LinkFree(S);
+}
+
+static __inline__ SYMBOL sort_ConditionVar(CONDITION C)
+{
+ return C->var;
+}
+
+static __inline__ LIST sort_ConditionConstraint(CONDITION C)
+{
+ return C->constraint;
+}
+
+static __inline__ LIST sort_ConditionAntecedent(CONDITION C)
+{
+ return C->antecedent;
+}
+
+static __inline__ LIST sort_ConditionSuccedent(CONDITION C)
+{
+ return C->succedent;
+}
+
+static __inline__ LIST sort_ConditionClauses(CONDITION C)
+{
+ return C->clauses;
+}
+
+static __inline__ void sort_ConditionPutVar(CONDITION C, SYMBOL Var)
+{
+ C->var = Var;
+}
+
+static __inline__ void sort_ConditionPutConstraint(CONDITION C, LIST Constr)
+{
+ C->constraint = Constr;
+}
+
+static __inline__ void sort_ConditionPutAntecedent(CONDITION C, LIST Ante)
+{
+ C->antecedent = Ante;
+}
+
+static __inline__ void sort_ConditionPutSuccedent(CONDITION C, LIST Succ)
+{
+ C->succedent = Succ;
+}
+
+static __inline__ void sort_ConditionPutClauses(CONDITION C, LIST Clauses)
+{
+ C->clauses = Clauses;
+}
+
+static __inline__ void sort_ConditionFree(CONDITION C)
+{
+ memory_Free(C, sizeof(CONDITION_NODE));
+}
+
+static __inline__ BOOL sort_ConditionNoResidues(CONDITION C)
+{
+ return (list_Empty(sort_ConditionConstraint(C)) &&
+ list_Empty(sort_ConditionAntecedent(C)) &&
+ list_Empty(sort_ConditionSuccedent(C)));
+}
+
+
+
+static __inline__ BOOL sort_LinkNoResidues(SLINK S)
+{
+ return (list_Empty(sort_LinkConstraint(S)) &&
+ list_Empty(sort_LinkAntecedent(S)) &&
+ list_Empty(sort_LinkSuccedent(S)));
+}
+
+static __inline__ BOOL sort_HasEqualSort(SORT S1, SORT S2)
+{
+ return S1 == S2;
+}
+
+
+static __inline__ POINTER sort_PairSort(LIST Pair)
+{
+ return list_PairFirst(Pair);
+}
+
+static __inline__ POINTER sort_PairCondition(LIST Pair)
+{
+ return list_PairSecond(Pair);
+}
+
+static __inline__ LIST sort_PairCreate(SORT S , CONDITION Just)
+{
+ return list_PairCreate((POINTER)S, Just);
+}
+
+static __inline__ void sort_PairFree(LIST Pair)
+{
+ list_PairFree(Pair);
+}
+
+static __inline__ void sort_PairDelete(LIST Pair)
+{
+ sort_DeleteOne(sort_PairSort(Pair));
+ sort_ConditionDelete(sort_PairCondition(Pair));
+ list_PairFree(Pair);
+}
+
+static __inline__ LIST sort_PairCopy(LIST Pair)
+{
+ return sort_PairCreate(sort_Copy(sort_PairSort(Pair)),
+ sort_ConditionCopy(sort_PairCondition(Pair)));
+}
+
+static __inline__ NODE sort_TheoryNode(SORTTHEORY Theory, SYMBOL S)
+{
+ return Theory->basesorttable[symbol_Index(S)];
+}
+
+static __inline__ NAT sort_TheoryMark(SORTTHEORY Theory)
+{
+ return Theory->mark;
+}
+
+static __inline__ LIST sort_TheorySuborigcls(SORTTHEORY Theory)
+{
+ return Theory->suborigcls;
+}
+
+static __inline__ LIST sort_TheoryTermorigcls(SORTTHEORY Theory)
+{
+ return Theory->termorigcls;
+}
+
+static __inline__ void sort_TheoryIncrementMark(SORTTHEORY Theory)
+{
+ if (Theory->mark == NAT_MAX) {
+ int i;
+ NODE Node;
+ for (i = 0; i < symbol__MAXSIGNATURE; i++) {
+ Node = Theory->basesorttable[i];
+ Node->mark = 0;
+ Node->extra = 0;
+ Node->start = 0;
+ }
+ Theory->mark = 0;
+ }
+ ++(Theory->mark);
+}
+
+static __inline__ st_INDEX sort_TheoryIndex(SORTTHEORY Theory)
+{
+ return Theory->index;
+}
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void sort_Init(void);
+void sort_Free(void);
+
+void sort_Delete(SORT);
+BOOL sort_Eq(SORT, SORT);
+void sort_DeleteSortPair(SOJU);
+
+void sort_Print(SORT);
+void sort_PairPrint(SOJU);
+
+LIST sort_GetSymbolsFromSort(SORT);
+BOOL sort_ContainsSymbol(SORT, SYMBOL);
+BOOL sort_IsSort(SORT);
+
+
+SORTTHEORY sort_ApproxStaticSortTheory(LIST, FLAGSTORE, PRECEDENCE);
+SORTTHEORY sort_ApproxDynamicSortTheory(LIST);
+
+
+SORTTHEORY sort_TheoryCreate(void);
+void sort_TheoryDelete(SORTTHEORY);
+void sort_TheoryPrint(SORTTHEORY);
+void sort_TheoryInsertClause(SORTTHEORY, CLAUSE, CLAUSE, LITERAL);
+void sort_TheoryDeleteClause(SORTTHEORY, CLAUSE);
+SORT sort_TheorySortOfSymbol(SORTTHEORY, SYMBOL);
+BOOL sort_TheorySortEqual(SORTTHEORY,SORT,SORT);
+CONDITION sort_TheoryIsSubsortOfNoResidues(SORTTHEORY, SORT, SORT);
+BOOL sort_TheoryIsSubsortOf(SORTTHEORY, SORT, SORT);
+BOOL sort_TheoryIsSubsortOfExtra(SORTTHEORY , SORT , SORT , SORT);
+LIST sort_TheoryComputeAllSubsortHits(SORTTHEORY, SORT, SORT);
+SOJU sort_ComputeSortNoResidues(SORTTHEORY,TERM, CLAUSE, int, FLAGSTORE, PRECEDENCE);
+LIST sort_ApproxMaxDeclClauses(CLAUSE, FLAGSTORE, PRECEDENCE);
+STR sort_AnalyzeSortStructure(LIST, FLAGSTORE, PRECEDENCE);
+
+
+#endif
diff --git a/test/spass/st.c b/test/spass/st.c
new file mode 100644
index 0000000..5f591ef
--- /dev/null
+++ b/test/spass/st.c
@@ -0,0 +1,1691 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * ST INDEXING * */
+/* * * */
+/* * $Module: ST * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "st.h"
+
+
+/**************************************************************/
+/* Local Variables */
+/**************************************************************/
+
+static st_RETRIEVAL_TYPE st_CURRENT_RETRIEVAL;
+static st_WHERE_TYPE st_WHICH_CONTEXTS;
+static CONTEXT st_INDEX_CONTEXT;
+static st_MINMAX st_EXIST_MINMAX;
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+ST_STACK st_STACK;
+int st_STACKPOINTER;
+int st_STACKSAVE;
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CREATION OF INDEX * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+st_INDEX st_IndexCreate(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: A pointer to a new St-Index.
+ SUMMARY: Creates a new St-index.
+***************************************************************/
+{
+ st_INDEX StIndex;
+
+ StIndex = st_Get();
+ StIndex->subnodes = list_Nil();
+ StIndex->entries = list_Nil();
+ StIndex->subst = subst_Nil();
+ st_SetMax(StIndex, 0);
+ st_SetMin(StIndex, 0);
+
+ return StIndex;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CREATION OF INDEX NODES * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static st_INDEX st_NodeAddLeaf(SUBST Subst, st_MINMAX MinMax, POINTER Pointer)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ st_INDEX NewLeaf;
+
+ NewLeaf = st_Get();
+ NewLeaf->subnodes = list_Nil();
+ NewLeaf->entries = list_List(Pointer);
+ NewLeaf->subst = Subst;
+ st_SetMax(NewLeaf, MinMax);
+ st_SetMin(NewLeaf, MinMax);
+
+ return NewLeaf;
+}
+
+
+static void st_NodeAddInner(st_INDEX StIndex, SUBST SubstOld, SUBST SubstNew,
+ SUBST ComGen, st_MINMAX MinMax, POINTER Pointer)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ st_INDEX OldIndexNode;
+
+ OldIndexNode = st_Get();
+ OldIndexNode->subst = SubstOld;
+ OldIndexNode->entries = StIndex->entries;
+ OldIndexNode->subnodes = StIndex->subnodes;
+ st_SetMax(OldIndexNode, st_Max(StIndex));
+ st_SetMin(OldIndexNode, st_Min(StIndex));
+
+ subst_Delete(StIndex->subst);
+
+ StIndex->subst = ComGen;
+ StIndex->entries = list_Nil();
+ StIndex->subnodes = list_Cons(st_NodeAddLeaf(SubstNew, MinMax, Pointer),
+ list_List(OldIndexNode));
+
+ if (st_Max(StIndex) < MinMax)
+ st_SetMax(StIndex, MinMax);
+ else if (st_Min(StIndex) > MinMax)
+ st_SetMin(StIndex, MinMax);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * MERGING OF INDEX NODES * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static void st_NodeMergeWithSon(st_INDEX StIndex)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ st_INDEX SubNode;
+
+ SubNode = (st_INDEX)list_Car(StIndex->subnodes);
+
+ list_Delete(StIndex->subnodes);
+
+ StIndex->subst = subst_Merge(SubNode->subst, StIndex->subst);
+ StIndex->entries = SubNode->entries;
+ StIndex->subnodes = SubNode->subnodes;
+ st_SetMax(StIndex, st_Max(SubNode));
+ st_SetMin(StIndex, st_Min(SubNode));
+
+ subst_Delete(SubNode->subst);
+
+ st_Free(SubNode);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * VARIABLE HANDLING FOR TERMS AND SUBSTS. * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static void st_CloseUsedVariables(const CONTEXT Context, LIST NodeList)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ for (; list_Exist(NodeList); NodeList = list_Cdr(NodeList)) {
+ SUBST Subst;
+
+ for (Subst = ((st_INDEX)list_Car(NodeList))->subst;
+ subst_Exist(Subst);
+ Subst = subst_Next(Subst))
+ if (!cont_VarIsUsed(Context, subst_Dom(Subst)))
+ cont_CreateClosedBinding(Context, subst_Dom(Subst));
+
+ if (!st_IsLeaf((st_INDEX)list_Car(NodeList)))
+ st_CloseUsedVariables(Context, ((st_INDEX)list_Car(NodeList))->subnodes);
+ }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * HEURISTICS FOR INSERTION OF TERMS AND SUBSTS. * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static st_INDEX st_FirstVariant(const CONTEXT Context, LIST Subnodes, st_INDEX* BestNonVariant)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ st_INDEX EmptyVariant;
+
+ for (EmptyVariant = NULL, *BestNonVariant = NULL;
+ list_Exist(Subnodes);
+ Subnodes = list_Cdr(Subnodes)) {
+ st_INDEX CurrentNode;
+
+ CurrentNode = (st_INDEX)list_Car(Subnodes);
+
+ cont_StartBinding();
+
+ if (subst_Variation(Context, CurrentNode->subst)) {
+ if (subst_Exist(CurrentNode->subst)) {
+ subst_CloseVariables(Context, CurrentNode->subst);
+
+ return CurrentNode;
+ } else
+ EmptyVariant = CurrentNode;
+
+ } else if (*BestNonVariant == NULL)
+ if (subst_MatchTops(Context, CurrentNode->subst))
+ *BestNonVariant = CurrentNode;
+
+ cont_BackTrack();
+ }
+
+ return EmptyVariant;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INSERTION OF TERMS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void st_EntryCreate(st_INDEX StIndex, POINTER Pointer, TERM Term, const CONTEXT Context)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ st_INDEX Current;
+ st_INDEX BestNonVariant;
+ SYMBOL FirstDomain;
+ st_MINMAX MinMax;
+
+ cont_Check();
+
+ MinMax = term_ComputeSize(Term);
+
+ /* CREATE INITIAL BINDING AND INITIALIZE LOCAL VARIABLES */
+ FirstDomain = cont_NextIndexVariable(Context);
+ cont_CreateBinding(Context, FirstDomain, Context, Term);
+
+ Current = StIndex;
+
+ if (st_Max(Current) < MinMax)
+ st_SetMax(Current, MinMax);
+ else if (st_Min(Current) > MinMax)
+ st_SetMin(Current, MinMax);
+
+ /* FIND "LAST" VARIATION */
+ while (!st_IsLeaf(Current) &&
+ (Current = st_FirstVariant(Context, Current->subnodes, &BestNonVariant))) {
+ if (st_Max(Current) < MinMax)
+ st_SetMax(Current, MinMax);
+ else if (st_Min(Current) > MinMax)
+ st_SetMin(Current, MinMax);
+
+ StIndex = Current;
+ }
+
+ if (cont_BindingsSinceLastStart()==0 && Current && st_IsLeaf(Current)) {
+
+ /* INSERT ENTRY EQUAL MODULO RENAMING */
+ Current->entries = list_Cons(Pointer, Current->entries);
+
+ } else if (BestNonVariant) {
+
+ /* CREATE INNER NODE AND A NEW LEAF */
+ SUBST ComGen, SubstOld, SubstNew;
+
+ if (!st_IsLeaf(BestNonVariant))
+ st_CloseUsedVariables(Context, BestNonVariant->subnodes);
+
+ ComGen = subst_ComGen(Context, BestNonVariant->subst, &SubstOld, &SubstNew);
+
+ st_NodeAddInner(BestNonVariant,
+ SubstOld,
+ subst_CloseOpenVariables(SubstNew),
+ ComGen,
+ MinMax,
+ Pointer);
+
+ } else
+
+ /* ADD A SINGLE LEAF NODE TO FATHER */
+ StIndex->subnodes =
+ list_Cons(st_NodeAddLeaf(subst_CloseOpenVariables(subst_Nil()), MinMax,
+ Pointer),
+ StIndex->subnodes);
+
+ cont_Reset();
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * DELETION OF INDEX * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void st_IndexDelete(st_INDEX StIndex)
+/**************************************************************
+ INPUT: A pointer to an existing St-Index.
+ SUMMARY: Deletes the whole index structure.
+***************************************************************/
+{
+ if (StIndex == NULL)
+ return;
+ else if (st_IsLeaf(StIndex))
+ list_Delete(StIndex->entries);
+ else
+ /* Recursion */
+ list_DeleteWithElement(StIndex->subnodes, (void (*)(POINTER))st_IndexDelete);
+
+ subst_Delete(StIndex->subst);
+ st_Free(StIndex);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * DELETION OF ENTRY FOR TERMS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static st_INDEX st_EntryDeleteHelp(const CONTEXT Context, st_INDEX StIndex, POINTER Pointer,
+ BOOL* Found)
+/**************************************************************
+ INPUT: The root of an abstraction tree (StIndex), a
+ pointer to a specific entry of the tree and
+ a query term.
+ RETURNS: Nothing.
+ SUMMARY: Uses Term in order to find Pointer in the tree.
+ EFFECTS: Will delete nodes of StIndex.
+***************************************************************/
+{
+ if (st_IsLeaf(StIndex)) {
+
+ *Found = list_DeleteFromList(&(StIndex->entries), Pointer);
+
+ if (list_Exist(StIndex->entries))
+ return StIndex;
+ else {
+ subst_Delete(StIndex->subst);
+ st_Free(StIndex);
+
+ return NULL;
+ }
+
+ } else {
+
+ LIST Subnodes;
+
+ for (Subnodes = StIndex->subnodes;
+ list_Exist(Subnodes);
+ Subnodes = list_Cdr(Subnodes)) {
+ st_INDEX CurrentNode;
+
+ CurrentNode = (st_INDEX)list_Car(Subnodes);
+
+ cont_StartBinding();
+
+ if (subst_Variation(Context, CurrentNode->subst)) {
+ list_Rplaca(Subnodes, st_EntryDeleteHelp(Context,
+ CurrentNode,
+ Pointer,
+ Found));
+ if (*Found) {
+ if (list_DeleteFromList(&(StIndex->subnodes), NULL))
+ if (list_Empty(list_Cdr(StIndex->subnodes))) {
+ /* 'StIndex' has one subnode only. */
+ st_NodeMergeWithSon(StIndex);
+
+ return StIndex;
+ }
+
+ /* Assertion: 'StIndex' is an inner node. */
+
+ CurrentNode = (st_INDEX)list_Car(StIndex->subnodes);
+ st_SetMax(StIndex, st_Max(CurrentNode));
+ st_SetMin(StIndex, st_Min(CurrentNode));
+
+ for (Subnodes = list_Cdr(StIndex->subnodes);
+ list_Exist(Subnodes);
+ Subnodes = list_Cdr(Subnodes)) {
+ CurrentNode = (st_INDEX)list_Car(Subnodes);
+
+ if (st_Max(CurrentNode) > st_Max(StIndex))
+ st_SetMax(StIndex, st_Max(CurrentNode));
+
+ if (st_Min(CurrentNode) < st_Min(StIndex))
+ st_SetMin(StIndex, st_Min(CurrentNode));
+ }
+
+ return StIndex;
+ }
+ }
+
+ cont_BackTrack();
+ }
+
+ return StIndex;
+ }
+}
+
+
+BOOL st_EntryDelete(st_INDEX StIndex, POINTER Pointer, TERM Term, const CONTEXT Context)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ BOOL Found;
+ LIST Subnodes;
+ SYMBOL FirstDomain;
+
+ cont_Check();
+
+ FirstDomain = symbol_FirstIndexVariable();
+ cont_CreateBinding(Context, FirstDomain, Context, Term);
+
+ for (Found = FALSE, Subnodes = StIndex->subnodes;
+ list_Exist(Subnodes);
+ Subnodes = list_Cdr(Subnodes)) {
+ st_INDEX CurrentNode;
+
+ CurrentNode = (st_INDEX)list_Car(Subnodes);
+
+ cont_StartBinding();
+
+ if (subst_Variation(Context, CurrentNode->subst)) {
+ list_Rplaca(Subnodes, st_EntryDeleteHelp(Context, CurrentNode, Pointer, &Found));
+
+ if (Found) {
+ StIndex->subnodes = list_PointerDeleteElement(StIndex->subnodes, NULL);
+
+ if (list_Exist(StIndex->subnodes)) {
+ CurrentNode = (st_INDEX)list_Car(StIndex->subnodes);
+ st_SetMax(StIndex, st_Max(CurrentNode));
+ st_SetMin(StIndex, st_Min(CurrentNode));
+
+ for (Subnodes = list_Cdr(StIndex->subnodes);
+ list_Exist(Subnodes);
+ Subnodes = list_Cdr(Subnodes)) {
+ CurrentNode = (st_INDEX)list_Car(Subnodes);
+
+ if (st_Max(CurrentNode) > st_Max(StIndex))
+ st_SetMax(StIndex, st_Max(CurrentNode));
+
+ if (st_Min(CurrentNode) < st_Min(StIndex))
+ st_SetMin(StIndex, st_Min(CurrentNode));
+ }
+ } else {
+ st_SetMax(StIndex, 0);
+ st_SetMin(StIndex, 0);
+ }
+
+ break;
+ }
+ }
+
+ cont_BackTrack();
+ }
+
+ cont_Reset();
+
+ return Found;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * RETRIEVAL FOR TERMS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static LIST st_TraverseTreeUnifier(CONTEXT IndexContext, st_INDEX StIndex)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ int Save;
+ LIST Result, CurrentList;
+ st_INDEX CurrentNode;
+
+ /* PREPARE TRAVERSAL */
+ Save = stack_Bottom();
+
+ Result = list_Nil();
+ CurrentList = StIndex->subnodes;
+
+ cont_StartBinding();
+
+ for (;;) {
+
+ /* BACKTRACK A BIG STEP */
+ if (list_Empty(CurrentList)) {
+ cont_StopAndBackTrack();
+
+ if (stack_Empty(Save))
+ return Result;
+
+ CurrentList = stack_PopResult();
+ }
+
+ /* DESCENDING */
+ for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+ subst_Unify(IndexContext, CurrentNode->subst);
+ CurrentList = CurrentNode->subnodes,
+ CurrentNode = (st_INDEX)list_Car(CurrentList))
+ if (st_IsLeaf(CurrentNode)) {
+ Result = list_Append(CurrentNode->entries, Result);
+ break;
+ } else if (list_Exist(list_Cdr(CurrentList))) {
+ stack_Push(list_Cdr(CurrentList));
+ cont_StartBinding();
+ } else
+ cont_StopAndStartBinding();
+
+ /* BACKTRACK LEAF OR INNER NODE */
+ CurrentList = list_Cdr(CurrentList);
+ cont_BackTrackAndStart();
+ }
+}
+
+
+static LIST st_TraverseTreeGen(CONTEXT IndexContext, st_INDEX StIndex)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ int Save;
+ LIST Result, CurrentList;
+ st_INDEX CurrentNode;
+
+ /* PREPARE TRAVERSAL */
+ Save = stack_Bottom();
+
+ Result = list_Nil();
+ CurrentList = StIndex->subnodes;
+
+ cont_StartBinding();
+
+ for (;;) {
+
+ /* BACKTRACK A BIG STEP */
+ if (list_Empty(CurrentList)) {
+ cont_StopAndBackTrack();
+
+ if (stack_Empty(Save))
+ return Result;
+
+ CurrentList = stack_PopResult();
+ }
+
+ /* DESCENDING */
+ for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+ subst_Match(IndexContext, CurrentNode->subst);
+ CurrentList = CurrentNode->subnodes,
+ CurrentNode = (st_INDEX)list_Car(CurrentList))
+ if (st_IsLeaf(CurrentNode)) {
+ Result = list_Append(CurrentNode->entries, Result);
+ break;
+ } else if (list_Cdr(CurrentList)) {
+ stack_Push(list_Cdr(CurrentList));
+ cont_StartBinding();
+ } else
+ cont_StopAndStartBinding();
+
+ /* BACKTRACK LEAF OR INNER NODE */
+ CurrentList = list_Cdr(CurrentList);
+ cont_BackTrackAndStart();
+ }
+}
+
+
+static LIST st_TraverseTreeInstance(CONTEXT IndexContext, st_INDEX StIndex)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ int Save;
+ LIST Result, CurrentList;
+ st_INDEX CurrentNode;
+
+ /* PREPARE TRAVERSAL */
+ Save = stack_Bottom();
+
+ Result = list_Nil();
+ CurrentList = StIndex->subnodes;
+
+ cont_StartBinding();
+
+ for (;;) {
+
+ /* BACKTRACK A BIG STEP */
+ if (list_Empty(CurrentList)) {
+ cont_StopAndBackTrack();
+
+ if (stack_Empty(Save))
+ return Result;
+
+ CurrentList = stack_PopResult();
+ }
+
+ /* DESCENDING */
+ for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+ subst_MatchReverse(IndexContext, CurrentNode->subst);
+ CurrentList = CurrentNode->subnodes,
+ CurrentNode = (st_INDEX)list_Car(CurrentList))
+ if (st_IsLeaf(CurrentNode)) {
+ Result = list_Append(CurrentNode->entries, Result);
+ break;
+ } else if (list_Cdr(CurrentList)) {
+ stack_Push(list_Cdr(CurrentList));
+ cont_StartBinding();
+ } else
+ cont_StopAndStartBinding();
+
+ /* BACKTRACK LEAF OR INNER NODE */
+ CurrentList = list_Cdr(CurrentList);
+ cont_BackTrackAndStart();
+ }
+}
+
+
+static LIST st_TraverseTreeGenPreTest(CONTEXT IndexContext,
+ st_INDEX StIndex,
+ st_MINMAX MinMax)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ int Save;
+ LIST Result, CurrentList;
+ st_INDEX CurrentNode;
+
+ /* PREPARE TRAVERSAL */
+ Save = stack_Bottom();
+
+ Result = list_Nil();
+ CurrentList = StIndex->subnodes;
+
+ cont_StartBinding();
+
+ for (;;) {
+
+ /* BACKTRACK A BIG STEP */
+ if (list_Empty(CurrentList)) {
+ cont_StopAndBackTrack();
+
+ if (stack_Empty(Save))
+ return Result;
+
+ CurrentList = stack_PopResult();
+ }
+
+ /* DESCENDING */
+ for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+ (MinMax >= st_Min(CurrentNode)) &&
+ subst_Match(IndexContext, CurrentNode->subst);
+ CurrentList = CurrentNode->subnodes,
+ CurrentNode = (st_INDEX)list_Car(CurrentList))
+ if (st_IsLeaf(CurrentNode)) {
+ Result = list_Append(CurrentNode->entries, Result);
+ break;
+ } else if (list_Cdr(CurrentList)) {
+ stack_Push(list_Cdr(CurrentList));
+ cont_StartBinding();
+ } else
+ cont_StopAndStartBinding();
+
+ /* BACKTRACK LEAF OR INNER NODE */
+ CurrentList = list_Cdr(CurrentList);
+ cont_BackTrackAndStart();
+ }
+}
+
+
+static LIST st_TraverseTreeInstancePreTest(CONTEXT IndexContext, st_INDEX StIndex, st_MINMAX MinMax)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ int Save;
+ LIST Result, CurrentList;
+ st_INDEX CurrentNode;
+
+ /* PREPARE TRAVERSAL */
+ Save = stack_Bottom();
+
+ Result = list_Nil();
+ CurrentList = StIndex->subnodes;
+
+ cont_StartBinding();
+
+ for (;;) {
+
+ /* BACKTRACK A BIG STEP */
+ if (list_Empty(CurrentList)) {
+ cont_StopAndBackTrack();
+
+ if (stack_Empty(Save))
+ return Result;
+
+ CurrentList = stack_PopResult();
+ }
+
+ /* DESCENDING */
+ for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+ (MinMax <= st_Max(CurrentNode)) &&
+ subst_MatchReverse(IndexContext, CurrentNode->subst);
+ CurrentList = CurrentNode->subnodes,
+ CurrentNode = (st_INDEX)list_Car(CurrentList))
+ if (st_IsLeaf(CurrentNode)) {
+ Result = list_Append(CurrentNode->entries, Result);
+ break;
+ } else if (list_Cdr(CurrentList)) {
+ stack_Push(list_Cdr(CurrentList));
+ cont_StartBinding();
+ } else
+ cont_StopAndStartBinding();
+
+ /* BACKTRACK LEAF OR INNER NODE */
+ CurrentList = list_Cdr(CurrentList);
+ cont_BackTrackAndStart();
+ }
+}
+
+
+LIST st_GetUnifier(CONTEXT IndexContext, st_INDEX StIndex, CONTEXT TermContext, TERM Term)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST Result;
+ SYMBOL FirstDomain;
+
+ cont_Check();
+
+ FirstDomain = symbol_FirstIndexVariable();
+ cont_CreateBinding(IndexContext, FirstDomain, TermContext, Term);
+
+ Result = st_TraverseTreeUnifier(IndexContext, StIndex);
+
+ cont_Reset();
+
+ return Result;
+}
+
+
+LIST st_GetGen(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST Result;
+ SYMBOL FirstDomain;
+
+ cont_Check();
+
+ FirstDomain = symbol_FirstIndexVariable();
+ cont_CreateBinding(IndexContext, FirstDomain, cont_InstanceContext(), Term);
+
+ Result = st_TraverseTreeGen(IndexContext, StIndex);
+
+ cont_Reset();
+
+ return Result;
+}
+
+
+LIST st_GetGenPreTest(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST Result;
+ SYMBOL FirstDomain;
+
+ cont_Check();
+
+ FirstDomain = symbol_FirstIndexVariable();
+ cont_CreateBinding(IndexContext, FirstDomain, cont_InstanceContext(), Term);
+
+ Result = st_TraverseTreeGenPreTest(IndexContext, StIndex, term_ComputeSize(Term));
+
+ cont_Reset();
+
+ return Result;
+}
+
+
+LIST st_GetInstance(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST Result;
+ SYMBOL FirstDomain;
+
+ cont_Check();
+
+ FirstDomain = symbol_FirstIndexVariable();
+ cont_CreateBinding(IndexContext, FirstDomain, IndexContext, Term);
+
+ Result = st_TraverseTreeInstance(IndexContext, StIndex);
+
+ cont_Reset();
+
+ return Result;
+}
+
+
+LIST st_GetInstancePreTest(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST Result;
+ SYMBOL FirstDomain;
+
+ cont_Check();
+
+ FirstDomain = symbol_FirstIndexVariable();
+ cont_CreateBinding(IndexContext, FirstDomain, IndexContext, Term);
+
+ Result = st_TraverseTreeInstancePreTest(IndexContext, StIndex, term_ComputeSize(Term));
+
+ cont_Reset();
+
+ return Result;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INCREMENTAL RETRIEVAL * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static POINTER st_TraverseForExistUnifier(CONTEXT IndexContext)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST CurrentList;
+ st_INDEX CurrentNode;
+
+ /* Caution: In case an entry is found
+ the procedure returns immediately
+ without backtracking the current bindings. */
+
+ CurrentList = list_Nil();
+
+ for (;;) {
+
+ /* BACKTRACK A BIG STEP */
+ if (list_Empty(CurrentList)) {
+ cont_StopAndBackTrack();
+
+ if (st_StackEmpty(st_STACKSAVE))
+ return NULL;
+
+ CurrentList = st_StackPopResult();
+ }
+
+ /* DESCENDING */
+ for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+ subst_Unify(IndexContext, CurrentNode->subst);
+ CurrentList = CurrentNode->subnodes,
+ CurrentNode = (st_INDEX)list_Car(CurrentList)) {
+ if (list_Exist(list_Cdr(CurrentList))) {
+ st_StackPush(list_Cdr(CurrentList));
+ cont_StartBinding();
+ } else
+ cont_StopAndStartBinding();
+
+ if (st_IsLeaf(CurrentNode)) {
+ st_StackPush(list_Cdr(CurrentNode->entries));
+ return list_Car(CurrentNode->entries);
+ }
+ }
+
+ /* BACKTRACK LEAF OR INNER NODE */
+ CurrentList = list_Cdr(CurrentList);
+ cont_BackTrackAndStart();
+ }
+}
+
+
+static POINTER st_TraverseForExistGen(CONTEXT IndexContext)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST CurrentList;
+ st_INDEX CurrentNode;
+
+ /* Caution: In case an entry is found
+ the procedure returns immediately
+ without backtracking the current bindings. */
+
+ CurrentList = list_Nil();
+
+ for (;;) {
+
+ /* BACKTRACK A BIG STEP */
+ if (list_Empty(CurrentList)) {
+ cont_StopAndBackTrack();
+
+ if (st_StackEmpty(st_STACKSAVE))
+ return NULL;
+
+ CurrentList = st_StackPopResult();
+ }
+
+ /* DESCENDING */
+ for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+ subst_Match(IndexContext, CurrentNode->subst);
+ CurrentList = CurrentNode->subnodes,
+ CurrentNode = (st_INDEX)list_Car(CurrentList)) {
+ if (list_Exist(list_Cdr(CurrentList))) {
+ st_StackPush(list_Cdr(CurrentList));
+ cont_StartBinding();
+ } else
+ cont_StopAndStartBinding();
+
+ if (st_IsLeaf(CurrentNode)) {
+ st_StackPush(list_Cdr(CurrentNode->entries));
+ return list_Car(CurrentNode->entries);
+ }
+ }
+
+ /* BACKTRACK LEAF OR INNER NODE */
+ CurrentList = list_Cdr(CurrentList);
+ cont_BackTrackAndStart();
+ }
+}
+
+
+static POINTER st_TraverseForExistGenPreTest(CONTEXT IndexContext)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST CurrentList;
+ st_INDEX CurrentNode;
+
+ /* Caution: In case an entry is found
+ the procedure returns immediately
+ without backtracking the current bindings. */
+
+ CurrentList = list_Nil();
+
+ for (;;) {
+
+ /* BACKTRACK A BIG STEP */
+ if (list_Empty(CurrentList)) {
+ cont_StopAndBackTrack();
+
+ if (st_StackEmpty(st_STACKSAVE))
+ return NULL;
+
+ CurrentList = st_StackPopResult();
+ }
+
+ /* DESCENDING */
+ for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+ (st_EXIST_MINMAX >= st_Min(CurrentNode)) &&
+ subst_Match(IndexContext, CurrentNode->subst);
+ CurrentList = CurrentNode->subnodes,
+ CurrentNode = (st_INDEX)list_Car(CurrentList)) {
+ if (list_Exist(list_Cdr(CurrentList))) {
+ st_StackPush(list_Cdr(CurrentList));
+ cont_StartBinding();
+ } else
+ cont_StopAndStartBinding();
+
+ if (st_IsLeaf(CurrentNode)) {
+ st_StackPush(list_Cdr(CurrentNode->entries));
+ return list_Car(CurrentNode->entries);
+ }
+ }
+
+ /* BACKTRACK LEAF OR INNER NODE */
+ CurrentList = list_Cdr(CurrentList);
+ cont_BackTrackAndStart();
+ }
+}
+
+
+static POINTER st_TraverseForExistInstance(CONTEXT IndexContext)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST CurrentList;
+ st_INDEX CurrentNode;
+
+ /* Caution: In case an entry is found
+ the procedure returns immediately
+ without backtracking the current bindings. */
+
+ CurrentList = list_Nil();
+
+ for (;;) {
+
+ /* BACKTRACK A BIG STEP */
+ if (list_Empty(CurrentList)) {
+ cont_StopAndBackTrack();
+
+ if (st_StackEmpty(st_STACKSAVE))
+ return NULL;
+
+ CurrentList = st_StackPopResult();
+ }
+
+ /* DESCENDING */
+ for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+ subst_MatchReverse(IndexContext, CurrentNode->subst);
+ CurrentList = CurrentNode->subnodes,
+ CurrentNode = (st_INDEX)list_Car(CurrentList)) {
+ if (list_Exist(list_Cdr(CurrentList))) {
+ st_StackPush(list_Cdr(CurrentList));
+ cont_StartBinding();
+ } else
+ cont_StopAndStartBinding();
+
+ if (st_IsLeaf(CurrentNode)) {
+ st_StackPush(list_Cdr(CurrentNode->entries));
+ return list_Car(CurrentNode->entries);
+ }
+ }
+
+ /* BACKTRACK LEAF OR INNER NODE */
+ CurrentList = list_Cdr(CurrentList);
+ cont_BackTrackAndStart();
+ }
+}
+
+
+static POINTER st_TraverseForExistInstancePreTest(CONTEXT IndexContext)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST CurrentList;
+ st_INDEX CurrentNode;
+
+ /* Caution: In case an entry is found
+ the procedure returns immediately
+ without backtracking the current bindings. */
+
+ CurrentList = list_Nil();
+
+ for (;;) {
+
+ /* BACKTRACK A BIG STEP */
+ if (list_Empty(CurrentList)) {
+ cont_StopAndBackTrack();
+
+ if (st_StackEmpty(st_STACKSAVE))
+ return NULL;
+
+ CurrentList = st_StackPopResult();
+ }
+
+ /* DESCENDING */
+ for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+ (st_EXIST_MINMAX <= st_Max(CurrentNode)) &&
+ subst_MatchReverse(IndexContext, CurrentNode->subst);
+ CurrentList = CurrentNode->subnodes,
+ CurrentNode = (st_INDEX)list_Car(CurrentList)) {
+ if (list_Exist(list_Cdr(CurrentList))) {
+ st_StackPush(list_Cdr(CurrentList));
+ cont_StartBinding();
+ } else
+ cont_StopAndStartBinding();
+
+ if (st_IsLeaf(CurrentNode)) {
+ st_StackPush(list_Cdr(CurrentNode->entries));
+ return list_Car(CurrentNode->entries);
+ }
+ }
+
+ /* BACKTRACK LEAF OR INNER NODE */
+ CurrentList = list_Cdr(CurrentList);
+ cont_BackTrackAndStart();
+ }
+}
+
+
+void st_CancelExistRetrieval(void)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ if (st_CURRENT_RETRIEVAL != st_NOP) {
+
+#ifdef CHECK
+ cont_CheckState();
+#endif
+
+ st_StackSetBottom(st_STACKSAVE);
+
+ switch (st_WHICH_CONTEXTS) {
+
+ case st_STANDARD:
+ cont_Reset();
+ break;
+
+ case st_NOC:
+ break;
+
+ default:
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_CancelExistRetrieval: Unknown context type.\n");
+ misc_FinishErrorReport();
+ }
+
+ st_CURRENT_RETRIEVAL = st_NOP;
+ st_WHICH_CONTEXTS = st_NOC;
+ st_INDEX_CONTEXT = NULL;
+ st_EXIST_MINMAX = 0;
+ }
+}
+
+
+POINTER st_ExistUnifier(CONTEXT IndexContext, st_INDEX StIndex, CONTEXT TermContext, TERM Term)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ SYMBOL FirstDomain;
+ POINTER Result;
+
+#ifdef CHECK
+ if (!st_StackEmpty(st_STACKSAVE)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_ExistUnifier: ST-Stack not empty.\n");
+ misc_FinishErrorReport();
+ } else if (st_CURRENT_RETRIEVAL != st_NOP) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_ExistUnifier: %d Retrieval already in progress.\n",
+ st_CURRENT_RETRIEVAL);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ cont_Check();
+
+ if (st_Exist(StIndex)) {
+
+ st_CURRENT_RETRIEVAL = st_UNIFIER;
+ st_WHICH_CONTEXTS = st_STANDARD;
+ st_INDEX_CONTEXT = IndexContext;
+
+ st_STACKSAVE = st_StackBottom();
+
+ FirstDomain = symbol_FirstIndexVariable();
+ cont_CreateBinding(IndexContext, FirstDomain, TermContext, Term);
+
+ cont_StartBinding();
+ st_StackPush(StIndex->subnodes);
+ cont_StartBinding();
+
+ Result = st_TraverseForExistUnifier(IndexContext);
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ if (Result == NULL)
+ st_CancelExistRetrieval();
+
+ return Result;
+ } else
+ return NULL;
+}
+
+
+POINTER st_ExistGen(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ SYMBOL FirstDomain;
+ POINTER Result;
+
+#ifdef CHECK
+ if (!st_StackEmpty(st_STACKSAVE)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_ExistGen: ST-Stack not empty.\n");
+ misc_FinishErrorReport();
+ }
+ else
+ if (st_CURRENT_RETRIEVAL != st_NOP) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_ExistGen: %d Retrieval already in progress.\n",
+ st_CURRENT_RETRIEVAL);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ cont_Check();
+
+ if (st_Exist(StIndex)) {
+
+ st_CURRENT_RETRIEVAL = st_GEN;
+ st_WHICH_CONTEXTS = st_STANDARD;
+ st_INDEX_CONTEXT = IndexContext;
+
+ st_STACKSAVE = st_StackBottom();
+
+ FirstDomain = symbol_FirstIndexVariable();
+ cont_CreateBinding(IndexContext, FirstDomain, cont_InstanceContext(), Term);
+
+ cont_StartBinding();
+ st_StackPush(StIndex->subnodes);
+ cont_StartBinding();
+
+ Result = st_TraverseForExistGen(IndexContext);
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ if (Result == NULL)
+ st_CancelExistRetrieval();
+
+ return Result;
+ } else
+ return NULL;
+}
+
+
+POINTER st_ExistGenPreTest(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ SYMBOL FirstDomain;
+ POINTER Result;
+
+#ifdef CHECK
+ if (!st_StackEmpty(st_STACKSAVE)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_ExistGenPreTest: ST-Stack not empty.\n");
+ misc_FinishErrorReport();
+ }
+ else
+ if (st_CURRENT_RETRIEVAL != st_NOP) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_ExistGenPreTest: %d Retrieval already in progress.\n",
+ st_CURRENT_RETRIEVAL);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ cont_Check();
+
+ if (st_Exist(StIndex)) {
+
+ st_CURRENT_RETRIEVAL = st_GENPRETEST;
+ st_WHICH_CONTEXTS = st_STANDARD;
+ st_INDEX_CONTEXT = IndexContext;
+
+ st_STACKSAVE = st_StackBottom();
+
+
+ FirstDomain = symbol_FirstIndexVariable();
+ st_EXIST_MINMAX = term_ComputeSize(Term);
+ cont_CreateBinding(IndexContext, FirstDomain, IndexContext, Term);
+
+ cont_StartBinding();
+ st_StackPush(StIndex->subnodes);
+ cont_StartBinding();
+
+ Result = st_TraverseForExistGenPreTest(IndexContext);
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ if (Result == NULL)
+ st_CancelExistRetrieval();
+
+ return Result;
+ } else
+ return NULL;
+}
+
+
+POINTER st_ExistInstance(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ SYMBOL FirstDomain;
+ POINTER Result;
+
+#ifdef CHECK
+ if (!st_StackEmpty(st_STACKSAVE)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_ExistInstance: ST-Stack not empty.\n");
+ misc_FinishErrorReport();
+ }
+ else
+ if (st_CURRENT_RETRIEVAL != st_NOP) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_ExistInstance: %d Retrieval already in progress.\n",
+ st_CURRENT_RETRIEVAL);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ cont_Check();
+
+ if (st_Exist(StIndex)) {
+
+ st_CURRENT_RETRIEVAL = st_INSTANCE;
+ st_WHICH_CONTEXTS = st_STANDARD;
+ st_INDEX_CONTEXT = IndexContext;
+
+ st_STACKSAVE = st_StackBottom();
+
+ FirstDomain = symbol_FirstIndexVariable();
+ cont_CreateBinding(IndexContext, FirstDomain, IndexContext, Term);
+
+ cont_StartBinding();
+ st_StackPush(StIndex->subnodes);
+ cont_StartBinding();
+
+ Result = st_TraverseForExistInstance(IndexContext);
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ if (Result == NULL)
+ st_CancelExistRetrieval();
+
+ return Result;
+ } else
+ return NULL;
+}
+
+
+POINTER st_ExistInstancePreTest(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ SYMBOL FirstDomain;
+ POINTER Result;
+
+#ifdef CHECK
+ if (!st_StackEmpty(st_STACKSAVE)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_ExistInstancePreTest: ST-Stack not empty.\n");
+ misc_FinishErrorReport();
+ }
+ else
+ if (st_CURRENT_RETRIEVAL != st_NOP) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_ExistInstancePreTest: %d Retrieval already in progress.\n",
+ st_CURRENT_RETRIEVAL);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ cont_Check();
+
+ if (st_Exist(StIndex)) {
+
+ st_CURRENT_RETRIEVAL = st_INSTANCEPRETEST;
+ st_WHICH_CONTEXTS = st_STANDARD;
+ st_INDEX_CONTEXT = IndexContext;
+
+ st_STACKSAVE = st_StackBottom();
+
+ FirstDomain = symbol_FirstIndexVariable();
+ st_EXIST_MINMAX = term_ComputeSize(Term);
+ cont_CreateBinding(IndexContext, FirstDomain, IndexContext, Term);
+
+ cont_StartBinding();
+ st_StackPush(StIndex->subnodes);
+ cont_StartBinding();
+
+ Result = st_TraverseForExistInstancePreTest(IndexContext);
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ if (Result == NULL)
+ st_CancelExistRetrieval();
+
+ return Result;
+ } else
+ return NULL;
+}
+
+
+POINTER st_NextCandidate(void)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECTS:
+***************************************************************/
+{
+ LIST Result;
+
+#ifdef CHECK
+ if (st_StackEmpty(st_STACKSAVE)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_NextCandidate: ST-Stack empty.\n");
+ misc_FinishErrorReport();
+ }
+ else
+ if (st_CURRENT_RETRIEVAL == st_NOP) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_NextCandidate: No retrieval in progress.\n");
+ misc_FinishErrorReport();
+ }
+
+ cont_CheckState();
+#endif
+
+ Result = st_StackPopResult();
+
+ if (list_Exist(Result)) {
+ st_StackPush(list_Cdr(Result));
+#ifdef CHECK
+ cont_SaveState();
+#endif
+ return list_Car(Result);
+ } else {
+ POINTER NewResult;
+
+ NewResult = NULL;
+
+ if (st_WHICH_CONTEXTS == st_STANDARD)
+ switch (st_CURRENT_RETRIEVAL) {
+
+ case st_UNIFIER:
+ NewResult = st_TraverseForExistUnifier(st_INDEX_CONTEXT);
+ break;
+
+ case st_GEN:
+ NewResult = st_TraverseForExistGen(st_INDEX_CONTEXT);
+ break;
+
+ case st_GENPRETEST:
+ NewResult = st_TraverseForExistGenPreTest(st_INDEX_CONTEXT);
+ break;
+
+ case st_INSTANCE:
+ NewResult = st_TraverseForExistInstance(st_INDEX_CONTEXT);
+ break;
+
+ case st_INSTANCEPRETEST:
+ NewResult = st_TraverseForExistInstancePreTest(st_INDEX_CONTEXT);
+
+ default:
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_NextCandidate: Unknown retrieval type.\n");
+ misc_FinishErrorReport();
+ }
+ else {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_NextCandidate: Unknown context type.\n");
+ misc_FinishErrorReport();
+ }
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ if (NewResult == NULL)
+ st_CancelExistRetrieval();
+
+ return NewResult;
+ }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * OUTPUT * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static void st_PrintHelp(st_INDEX St, int Position, void (*Print)(POINTER))
+/**************************************************************
+ INPUT: A node of an St, an indention and a print
+ function for the entries.
+ SUMMARY: Prints an St starting at node St.
+***************************************************************/
+{
+ int i;
+
+ if (St == (st_INDEX)NULL)
+ return;
+
+ for (i = 0; i < Position; i++)
+ putchar(' ');
+ puts("|");
+
+ for (i = 0; i < Position; i++)
+ putchar(' ');
+ fputs("+-", stdout);
+
+ printf(" Max: %d, Min: %d, ", st_Max(St), st_Min(St));
+ subst_Print(St->subst);
+ putchar('\n');
+
+ if (st_IsLeaf(St)) {
+
+ LIST Scan;
+
+ for (i = 0; i < Position; i++)
+ putchar(' ');
+ fputs(" =>", stdout);
+
+ if (Print)
+ for (Scan = St->entries; Scan != NULL; Scan = list_Cdr(Scan)) {
+ putchar(' ');
+ Print(list_Car(Scan));
+ }
+ else
+ printf(" %d Entries", list_Length(St->entries));
+
+ putchar('\n');
+
+ } else {
+ LIST Scan;
+
+ for (Scan = St->subnodes; Scan != NULL; Scan = list_Cdr(Scan))
+ st_PrintHelp(list_Car(Scan), Position + 2, Print);
+ }
+}
+
+
+void st_Print(st_INDEX StIndex, void (*Print)(POINTER))
+/**************************************************************
+ INPUT: The root of an St.
+ SUMMARY: Prints a whole St.
+***************************************************************/
+{
+ LIST Scan;
+
+ if (st_Empty(StIndex)) {
+ puts("\n\nIndex empty.");
+ return;
+ }
+
+ fputs("\n\nroot: ", stdout);
+ printf(" Max: %d, Min: %d, ", st_Max(StIndex), st_Min(StIndex));
+ subst_Print(StIndex->subst);
+ putchar('\n');
+ if (st_IsLeaf(StIndex)) {
+ fputs(" =>", stdout);
+
+ if (Print)
+ for (Scan = StIndex->entries; Scan != NULL; Scan = list_Cdr(Scan)) {
+ putchar(' ');
+ Print(list_Car(Scan));
+ }
+ else
+ printf(" %d Entries", list_Length(StIndex->entries));
+
+ } else
+ for (Scan = StIndex->subnodes; Scan != NULL; Scan = list_Cdr(Scan))
+ st_PrintHelp(list_Car(Scan),2, Print);
+ puts("\n");
+}
diff --git a/test/spass/st.h b/test/spass/st.h
new file mode 100644
index 0000000..93f9fb6
--- /dev/null
+++ b/test/spass/st.h
@@ -0,0 +1,305 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * ST INDEXING * */
+/* * * */
+/* * $Module: ST * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _ST_
+#define _ST_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "foldfg.h"
+#include "term.h"
+#include "symbol.h"
+#include "list.h"
+
+#include "subst.h"
+#include "unify.h"
+
+/**************************************************************/
+/* Data Structures */
+/**************************************************************/
+
+typedef enum {st_NOP, st_UNIFIER, st_GEN,
+ st_GENPRETEST, st_INSTANCE, st_INSTANCEPRETEST
+} st_RETRIEVAL_TYPE;
+
+typedef enum {st_STANDARD, st_NOC} st_WHERE_TYPE;
+
+typedef unsigned short int st_MINMAX;
+
+
+/**************************************************************/
+/* Type st_INDEX and Inline Functions */
+/**************************************************************/
+
+typedef struct st {
+ SUBST subst;
+ LIST subnodes;
+ LIST entries;
+ st_MINMAX max, min;
+} st_INDEX_NODE, *st_INDEX;
+
+
+static __inline__ st_INDEX st_Get(void)
+{
+ return (st_INDEX) memory_Malloc(sizeof(st_INDEX_NODE));
+}
+
+static __inline__ void st_Free(st_INDEX ST)
+{
+ memory_Free(ST, sizeof(st_INDEX_NODE));
+}
+
+static __inline__ SUBST st_Subst(st_INDEX ST)
+{
+ return ST->subst;
+}
+
+static __inline__ LIST st_Entries(st_INDEX ST)
+{
+ return ST->entries;
+}
+
+static __inline__ LIST st_Subnodes(st_INDEX ST)
+{
+ return ST->subnodes;
+}
+
+static __inline__ st_MINMAX st_Max(st_INDEX ST)
+{
+ return ST->max;
+}
+
+static __inline__ void st_SetMax(st_INDEX ST, st_MINMAX Value)
+{
+ ST->max = Value;
+}
+
+static __inline__ st_MINMAX st_Min(st_INDEX ST)
+{
+ return ST->min;
+}
+
+static __inline__ void st_SetMin(st_INDEX ST, st_MINMAX Value)
+{
+ ST->min = Value;
+}
+
+static __inline__ BOOL st_IsLeaf(st_INDEX ST)
+{
+ return !list_Empty(st_Entries(ST));
+}
+
+static __inline__ BOOL st_IsInner(st_INDEX ST)
+{
+ return !list_Empty(st_Subnodes(ST));
+}
+
+static __inline__ BOOL st_Empty(st_INDEX ST)
+{
+ return (ST == NULL || (!st_IsLeaf(ST) && !st_IsInner(ST)));
+}
+
+static __inline__ BOOL st_Exist(st_INDEX ST)
+{
+ return (ST != NULL && (st_IsLeaf(ST) || st_IsInner(ST)));
+}
+
+static __inline__ void st_SetNode(st_INDEX Index, SUBST Subst,
+ LIST Subnodes, LIST Entries)
+{
+ Index->subst = Subst;
+ Index->subnodes = Subnodes;
+ Index->entries = Entries;
+}
+
+static __inline__ st_INDEX st_CreateNode(SUBST Subst, LIST Subnodes,
+ LIST Entries)
+{
+ st_INDEX index;
+
+ index = st_Get();
+ st_SetNode(index, Subst, Subnodes, Entries);
+
+ return index;
+}
+
+
+typedef enum {st_EMPTY = 1, st_FCT, st_CONST, st_VAR,
+ st_STAR, st_FIRST} NODETYPE;
+
+
+/**************************************************************/
+/* A special ST-Stack for sequential retrieval operations */
+/**************************************************************/
+
+#define st_STACKSIZE 1000
+
+typedef POINTER ST_STACK[st_STACKSIZE];
+
+extern ST_STACK st_STACK;
+extern int st_STACKPOINTER;
+extern int st_STACKSAVE;
+
+/* Stack operations */
+
+static __inline__ void st_StackInit(void)
+{
+ st_STACKPOINTER = 0;
+}
+
+static __inline__ void st_StackPush(POINTER Entry)
+{
+#ifdef CHECK
+ if (st_STACKPOINTER >= st_STACKSIZE) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In st_StackPush: ST-Stack Overflow!\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ st_STACK[st_STACKPOINTER++] = Entry;
+}
+
+static __inline__ void st_StackPop(void)
+{
+ --st_STACKPOINTER;
+}
+
+static __inline__ POINTER st_StackPopResult(void)
+{
+ return st_STACK[--st_STACKPOINTER];
+}
+
+static __inline__ void st_StackNPop(int N)
+{
+ st_STACKPOINTER -= N;
+}
+
+static __inline__ POINTER st_StackTop(void)
+{
+ return st_STACK[st_STACKPOINTER - 1];
+}
+
+static __inline__ POINTER st_StackNthTop(int N)
+{
+ return st_STACK[st_STACKPOINTER - (1 + N)];
+}
+
+static __inline__ void st_StackRplacTop(POINTER Entry)
+{
+ st_STACK[st_STACKPOINTER - 1] = Entry;
+}
+
+static __inline__ void st_StackRplacNthTop(int N, POINTER Entry)
+{
+ st_STACK[st_STACKPOINTER - (1 + N)] = Entry;
+}
+
+static __inline__ void st_StackRplacNth(int N, POINTER Entry)
+{
+ st_STACK[N] = Entry;
+}
+
+static __inline__ int st_StackBottom(void)
+{
+ return st_STACKPOINTER;
+}
+
+static __inline__ void st_StackSetBottom(int Pointer)
+{
+ st_STACKPOINTER = Pointer;
+}
+
+static __inline__ BOOL st_StackEmpty(int Pointer)
+{
+ return st_STACKPOINTER == Pointer;
+}
+
+
+/**************************************************************/
+/* Functions for Creation and Deletion of an st_INDEX */
+/**************************************************************/
+
+st_INDEX st_IndexCreate(void);
+void st_IndexDelete(st_INDEX);
+
+/**************************************************************/
+/* Add and Remove Entries to an st_INDEX */
+/**************************************************************/
+
+void st_EntryCreate(st_INDEX, POINTER, TERM, const CONTEXT);
+BOOL st_EntryDelete(st_INDEX, POINTER, TERM, const CONTEXT);
+
+/**************************************************************/
+/* Functions for Retrieval in the Index */
+/**************************************************************/
+
+LIST st_GetUnifier(CONTEXT, st_INDEX, CONTEXT, TERM);
+LIST st_GetGen(CONTEXT, st_INDEX, TERM);
+LIST st_GetGenPreTest(CONTEXT, st_INDEX, TERM);
+LIST st_GetInstance(CONTEXT, st_INDEX, TERM);
+LIST st_GetInstancePreTest(CONTEXT, st_INDEX, TERM);
+
+void st_CancelExistRetrieval(void);
+
+POINTER st_ExistUnifier(CONTEXT, st_INDEX, CONTEXT, TERM);
+POINTER st_ExistGen(CONTEXT, st_INDEX, TERM);
+POINTER st_ExistGenPreTest(CONTEXT, st_INDEX, TERM);
+POINTER st_ExistInstance(CONTEXT, st_INDEX, TERM);
+POINTER st_ExistInstancePreTest(CONTEXT, st_INDEX, TERM);
+
+POINTER st_NextCandidate(void);
+
+/**************************************************************/
+/* Function for Output */
+/**************************************************************/
+
+void st_Print(st_INDEX, void (*)(POINTER));
+
+#endif
diff --git a/test/spass/stack.c b/test/spass/stack.c
new file mode 100644
index 0000000..4d46314
--- /dev/null
+++ b/test/spass/stack.c
@@ -0,0 +1,55 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * GLOBAL SYSTEM STACK * */
+/* * * */
+/* * $Module: STACK * */
+/* * * */
+/* * Copyright (C) 1999, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "stack.h"
+
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+STACK stack_STACK;
+NAT stack_POINTER;
diff --git a/test/spass/stack.h b/test/spass/stack.h
new file mode 100644
index 0000000..4572b34
--- /dev/null
+++ b/test/spass/stack.h
@@ -0,0 +1,155 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * GLOBAL SYSTEM STACK * */
+/* * * */
+/* * $Module: STACK * */
+/* * * */
+/* * Copyright (C) 1996, 1998, 1999, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _STACK_
+#define _STACK_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "misc.h"
+
+/**************************************************************/
+/* More basic types and macros */
+/**************************************************************/
+
+
+#define stack_SIZE 10000
+
+typedef POINTER STACK[stack_SIZE];
+
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+extern STACK stack_STACK;
+extern NAT stack_POINTER;
+
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+static __inline__ void stack_Init(void)
+{
+ stack_POINTER = 0;
+}
+
+static __inline__ void stack_Push(POINTER Entry)
+{
+#ifdef CHECK
+ if (stack_POINTER >= stack_SIZE) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In stack_Push: Stack Overflow.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ stack_STACK[stack_POINTER++]= Entry;
+}
+
+static __inline__ int stack_Pop(void)
+{
+ return --stack_POINTER;
+}
+
+static __inline__ POINTER stack_PopResult(void)
+{
+ return stack_STACK[--stack_POINTER];
+}
+
+static __inline__ void stack_NPop(NAT N)
+{
+ stack_POINTER -= N;
+}
+
+static __inline__ POINTER stack_Top(void)
+{
+ return stack_STACK[stack_POINTER-1];
+}
+
+static __inline__ POINTER stack_NthTop(NAT N)
+{
+ return stack_STACK[stack_POINTER-(1+N)];
+}
+
+static __inline__ void stack_RplacTop(POINTER Entry)
+{
+ stack_STACK[stack_POINTER-1] = Entry;
+}
+
+static __inline__ void stack_RplacNthTop(NAT N, POINTER Entry)
+{
+ stack_STACK[stack_POINTER-(1+N)] = Entry;
+}
+
+static __inline__ void stack_RplacNth(NAT N, POINTER Entry)
+{
+ stack_STACK[N] = Entry;
+}
+
+static __inline__ NAT stack_Bottom(void)
+{
+ return stack_POINTER;
+}
+
+static __inline__ void stack_SetBottom(NAT Ptr)
+{
+ stack_POINTER = Ptr;
+}
+
+static __inline__ BOOL stack_Empty(NAT Ptr)
+{
+ return stack_POINTER == Ptr;
+}
+
+
+#endif
+
+
diff --git a/test/spass/strings.c b/test/spass/strings.c
new file mode 100644
index 0000000..bd0b2ed
--- /dev/null
+++ b/test/spass/strings.c
@@ -0,0 +1,325 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * STRING HANDLING * */
+/* * * */
+/* * $Module: STRINGS * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 35442 $ * */
+/* $State$ * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $ * */
+/* $Author: jeffc $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include <ctype.h>
+#include "stringsx.h"
+#include "list.h"
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+
+
+BOOL string_StringIsNumber(const char* String)
+/**************************************************************
+ INPUT: A string.
+ RETURNS: TRUE iff the string solely consists of number characters.
+***************************************************************/
+{
+ int i;
+
+ if (String == NULL || String[0] == '\0')
+ return FALSE;
+
+ i = 0;
+
+ while (String[i] != '\0')
+ if (String[i] >= '0' && String[i] <= '9')
+ i++;
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+
+char* string_StringCopy(const char* String)
+/**************************************************************
+ INPUT: A string.
+ RETURNS: A copy of the string.
+ EFFECT: The memory for the copy is allocated by the memory module.
+***************************************************************/
+{
+ char *copy;
+
+ copy = (char *) memory_Malloc(strlen(String)+1);
+ strcpy(copy, String);
+ return copy;
+}
+
+
+void string_StringFree(char* String)
+/**************************************************************
+ INPUT: A string.
+ RETURNS: Nothing.
+ EFFECT: Frees the memory used by the string.
+***************************************************************/
+{
+ memory_Free(String, strlen(String)+1);
+}
+
+
+char* string_IntToString(int Number)
+/**************************************************************
+ INPUT: An integer number.
+ RETURNS: The number as a string.
+ EFFECT: Memory is allocated for the string.
+***************************************************************/
+{
+ char* result;
+ NAT size = 1;
+
+ if (Number > 9) {
+ size = (NAT)log10((double) Number) + 1;
+ } else if (Number < 0) {
+ size = (NAT)log10((double) abs(Number)) + 2; /* including '-' */
+ }
+ size++; /* for '\0' */
+
+ result = (char *) memory_Malloc(sizeof(char) * size);
+ sprintf(result, "%d", Number);
+ return result;
+}
+
+
+BOOL string_StringToInt(const char* String, BOOL PrintError, int* Result)
+/**************************************************************
+ INPUT: A string that should represent a decimal number in the
+ format of the library function strtol, a boolean flag
+ concerning the printing of error messages and an pointer
+ to an integer that is used as a return value.
+ RETURNS: TRUE, if the string could be converted successfully, else FALSE.
+ EFFECT: This function converts the string a number of type 'int'.
+ If the string was converted successfully, the value of the
+ number is stored in <*Result> and the function returns TRUE.
+ If the number is too big (> INT_MAX), too small (< INT_MIN)
+ or the string couldn't be converted completely, <*Result> is
+ set to 0.
+ If <PrintError> is TRUE, additionally an error message is written
+ to stderr and the program exits.
+***************************************************************/
+{
+ long number;
+ char *end;
+
+ end = (char*)0x1; /* Has to be != NULL, so we take address 1 */
+ number = strtol(String, &end, 10);
+ /* Now <number> is LONG_MAX or LONG_MIN if the string represents a value */
+ /* out of range. The variable <end> is set to the first non-converted */
+ /* character, e.g. if the string can be converted completely, <end> points */
+ /* to the terminating '\0' character. */
+ if (number >= INT_MIN && number <= INT_MAX && *end == '\0') {
+ /* Number was converted successfully */
+ *Result = (int)number;
+ return TRUE;
+ } else {
+ /* Number is too large or buffer can't be converted completely */
+ *Result = 0;
+ if (PrintError) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\nString isn't a number or number to large: %s\n",
+ String);
+ misc_FinishUserErrorReport();
+ }
+ return FALSE;
+ }
+}
+
+
+char* string_Conc(const char* s1, const char* s2)
+/**************************************************************
+ INPUT: Two strings.
+ RETURNS: A new string s1.s2
+ EFFECTS: Memory is allocated for the new string.
+**************************************************************/
+{
+ char* dst;
+
+ dst = memory_Malloc(strlen(s1) + strlen(s2) + 1);
+ strcpy(dst, s1);
+ return strcat(dst,s2);
+}
+
+
+char* string_Nconc(char* s1, char* s2)
+/**************************************************************
+ INPUT: Two strings.
+ RETURNS: A new string s1.s2.
+ EFFECTS: s1,s2 are deleted, memory for the new string is
+ allocated.
+ CAUTION: Both strings must have been allocated by the memory module!
+**************************************************************/
+{
+ char* dst;
+
+ dst = memory_Malloc(strlen(s1) + strlen(s2) + 1);
+ strcpy(dst, s1);
+ dst = strcat(dst, s2);
+
+ string_StringFree(s1);
+ string_StringFree(s2);
+
+ return dst;
+}
+
+
+char* string_EmptyString(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The empty string.
+ EFFECT: Memory is allocated for the returned string.
+**************************************************************/
+{
+ char* s ;
+
+ s = memory_Malloc(1);
+ s[0] = '\0';
+ return s;
+}
+
+
+char* string_Prefix(const char* s, int i)
+/**************************************************************
+ INPUT: A string and a string length.
+ RETURNS: The prefix of <s> of length <i>.
+ EFFECT: Memory is allocated for the returned string.
+**************************************************************/
+{
+ char* dst;
+
+ dst = memory_Malloc(i + 1);
+ strncpy(dst, s, i);
+ dst[i] = '\0';
+ return dst;
+}
+
+
+char* string_Suffix(const char* s, int i)
+/**************************************************************
+ INPUT: A string and a string length.
+ RETURNS: The string that results from cutting the first
+ <i> characters from string <s>.
+ Returns the empty string if <i> >= length(s).
+ EFFECT: Memory is allocated for the returned string.
+**************************************************************/
+{
+ int l;
+ char *dst;
+
+ l = strlen(s);
+ if (i >= l)
+ return string_EmptyString();
+
+ dst = memory_Malloc(l - i + 1);
+ strcpy(dst, s+i);
+ return dst;
+}
+
+
+char** string_Tokens(char* String, int* ArraySize)
+/**************************************************************
+ INPUT: A string <String>.
+ RETURNS: The function returns an array of white space separated
+ substrings from <String>. <ArraySize> is set to the
+ actual size of the returned array.
+ The array size is the number of substrings + 2, since
+ the first entry is the program name and the last entry
+ is NULL.
+ This is done so to create an array similar to the
+ "argv" argument of the main() function.
+ EFFECT: This function breaks the string into several substrings
+ that don't contain any whitespace characters.
+ The argument string is modified temporarily within this
+ function, but it's restored at the end.
+***************************************************************/
+{
+ char *LastNonSpace, *Scan, Help, **Array;
+ LIST Substrings;
+ NAT i;
+
+#ifdef CHECK
+ if (String == NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In string_Tokens: String is NULL pointer.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Substrings = list_Nil();
+ Scan = String + strlen(String) - 1;
+ while (Scan >= String) {
+ while (Scan >= String && isspace((int)*Scan))
+ Scan--;
+
+ if (Scan >= String) {
+ LastNonSpace = Scan;
+
+ do {
+ Scan--;
+ } while (Scan >= String && !isspace((int)*Scan));
+
+ Help = *(LastNonSpace + 1);
+ *(LastNonSpace + 1) = '\0';
+ Substrings = list_Cons(string_StringCopy(Scan+1), Substrings);
+ *(LastNonSpace + 1) = Help;
+ }
+ }
+
+ *ArraySize = list_Length(Substrings) + 2;
+ Array = memory_Malloc(sizeof(char*) * *ArraySize);
+ Array[0] = string_StringCopy("SPASS");
+ for (i = 1; !list_Empty(Substrings); Substrings = list_Pop(Substrings), i++)
+ Array[i] = list_Car(Substrings);
+ Array[i] = NULL;
+ (*ArraySize)--;
+
+ return Array;
+}
diff --git a/test/spass/stringsx.h b/test/spass/stringsx.h
new file mode 100644
index 0000000..7209b4b
--- /dev/null
+++ b/test/spass/stringsx.h
@@ -0,0 +1,88 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * STRING HANDLING * */
+/* * * */
+/* * $Module: STRINGS * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 35442 $ * */
+/* $State$ * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $ * */
+/* $Author: jeffc $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _STRINGS_
+#define _STRINGS_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include <math.h>
+#include "memory.h"
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static __inline__ BOOL string_Equal(const char* S1, const char* S2)
+{
+ return strcmp(S1, S2) == 0;
+}
+
+
+BOOL string_StringIsNumber(const char*);
+char* string_StringCopy(const char*);
+void string_StringFree(char*);
+char* string_IntToString(int);
+BOOL string_StringToInt(const char*, BOOL, int*);
+char* string_Conc(const char*, const char*);
+char* string_Nconc(char*, char*);
+char* string_EmptyString(void);
+char* string_Prefix(const char*, int);
+char* string_Suffix(const char*, int);
+char** string_Tokens(char*, int*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/test/spass/subst.c b/test/spass/subst.c
new file mode 100644
index 0000000..a7d5ea3
--- /dev/null
+++ b/test/spass/subst.c
@@ -0,0 +1,647 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SUBSTITUTION * */
+/* * * */
+/* * $Module: SUBSTITUTION * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "subst.h"
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SUBSTITUTION CREATION AND DELETION * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+SUBST subst_Add(SYMBOL Symbol, TERM Codomain, SUBST Subst)
+{
+ SUBST Result;
+
+ Result = subst_Get();
+ Result->next = Subst;
+ Result->dom = Symbol;
+ Result->codomain = Codomain;
+
+ return Result;
+}
+
+
+void subst_Delete(SUBST Subst)
+{
+ SUBST Next;
+
+ while (subst_Exist(Subst)) {
+ Next = subst_Next(Subst);
+
+ if (subst_Cod(Subst))
+ term_Delete(subst_Cod(Subst));
+
+ subst_FreeOneNode(Subst);
+ Subst = Next;
+ }
+}
+
+void subst_Free(SUBST Subst)
+{
+ SUBST Next;
+
+ while (subst_Exist(Subst)) {
+ Next = subst_Next(Subst);
+ subst_FreeOneNode(Subst);
+ Subst = Next;
+ }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * FUNCTIONS ON SUBSTITUTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+TERM subst_Term(SYMBOL Symbol, SUBST Subst)
+{
+ for (; subst_Exist(Subst); Subst = subst_Next(Subst))
+ if (symbol_Equal(Symbol,subst_Dom(Subst)))
+ return subst_Cod(Subst);
+ return (TERM)NULL;
+}
+
+
+static TERM subst_ApplyIntern(SUBST Subst, TERM Term)
+{
+ TERM RplacTerm;
+ LIST Arglist;
+ SYMBOL Top;
+
+ Top = term_TopSymbol(Term);
+
+ if (symbol_IsVariable(Top) && (RplacTerm = subst_Term(Top,Subst))) {
+ Arglist = term_CopyTermList(term_ArgumentList(RplacTerm));
+ term_RplacTop(Term, term_TopSymbol(RplacTerm));
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term, Arglist);
+ } else {
+ for (Arglist = term_ArgumentList(Term);
+ !list_Empty(Arglist);
+ Arglist = list_Cdr(Arglist))
+ subst_ApplyIntern(Subst, list_Car(Arglist));
+ }
+
+ return Term;
+}
+
+TERM subst_Apply(SUBST Subst, TERM Term)
+{
+ if (subst_Empty(Subst))
+ return Term;
+
+ return subst_ApplyIntern(Subst, Term);
+}
+
+
+SUBST subst_Merge(SUBST Source, SUBST Drain)
+{
+ SUBST Scan;
+ BOOL Changed;
+
+ for (; subst_Exist(Source); Source = subst_Next(Source)) {
+
+ /* Apply current assignment of Source to all */
+ /* assignments of Drain. If the current ass. */
+ /* cannot be applied to any codomain in Drain */
+ /* the current assignment is added to Drain. */
+
+ Changed = FALSE;
+
+ for (Scan = Drain;
+ subst_Exist(Scan);
+ Scan = subst_Next(Scan))
+ if (term_SubstituteVariable(Source->dom,
+ Source->codomain,
+ &(Scan->codomain)))
+ Changed = TRUE;
+
+ if (!Changed)
+ Drain = subst_Add(Source->dom,
+ term_Copy(Source->codomain),
+ Drain);
+ }
+
+ return Drain;
+}
+
+SUBST subst_Compose(SUBST Outer, SUBST Inner)
+/**************************************************************
+ INPUT: Two substitutions.
+ RETURNS: The substitution corresponding to the composition of
+ <Outer> and <Inner>.
+ EFFECT: <Outer> is destructively applied to the codomain of <Inner>
+ <Inner> is destructively extended
+***************************************************************/
+{
+ SUBST Scan1,Scan2,New;
+
+ New = subst_Nil();
+
+ for (Scan1=Outer; subst_Exist(Scan1); Scan1 = subst_Next(Scan1)) {
+ for (Scan2 = Inner;subst_Exist(Scan2);Scan2 = subst_Next(Scan2))
+ term_SubstituteVariable(subst_Dom(Scan1),subst_Cod(Scan1),&(Scan2->codomain));
+ if (!subst_BindVar(subst_Dom(Scan1),Inner))
+ New = subst_Add(subst_Dom(Scan1), term_Copy(subst_Cod(Scan1)),New);
+ }
+ return subst_NUnion(Inner,New);
+}
+
+BOOL subst_BindVar(SYMBOL Var, SUBST Subst)
+/**************************************************************
+ INPUT: A variable symbol and a substitution.
+ RETURNS: TRUE iff <Var> is contained in the domain of <Subst>
+***************************************************************/
+{
+ SUBST Scan;
+
+ for (Scan=Subst; subst_Exist(Scan); Scan = subst_Next(Scan))
+ if (symbol_Equal(subst_Dom(Scan),Var))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+
+SUBST subst_Copy(SUBST Subst)
+{
+ SUBST Copy, Result;
+
+ for (Result = subst_Nil(),
+ Copy = subst_Nil();
+ subst_Exist(Subst);
+ Subst = subst_Next(Subst))
+ if (subst_Exist(Result)) {
+ subst_SetNext(Copy, subst_Add(subst_Dom(Subst),
+ term_Copy(subst_Cod(Subst)),
+ subst_Nil()));
+ Copy = subst_Next(Copy);
+ } else {
+ Result = subst_Add(subst_Dom(Subst),
+ term_Copy(subst_Cod(Subst)),
+ subst_Nil());
+ Copy = Result;
+ }
+
+ return Result;
+}
+
+
+BOOL subst_MatchTops(const CONTEXT Context, SUBST Subst)
+{
+ for ( ; subst_Exist(Subst); Subst = subst_Next(Subst))
+ if (cont_ContextBindingTerm(Context, subst_Dom(Subst)) &&
+ term_EqualTopSymbols(cont_ContextBindingTerm(Context, subst_Dom(Subst)),
+ subst_Cod(Subst)))
+ return TRUE;
+ return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * UNIFICATION TEST * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL subst_Unify(CONTEXT IndexContext, SUBST Subst)
+/*********************************************************
+ INPUT:
+ RETURNS:
+ CAUTION: 'Subst' IS ASSUMED TO BE NON-EMPTY.
+**********************************************************/
+{
+ while (subst_Exist(Subst)) {
+ if (!cont_VarIsBound(IndexContext, subst_Dom(Subst))) {
+ if (unify_OccurCheck(IndexContext, subst_Dom(Subst), IndexContext, subst_Cod(Subst)))
+ return FALSE;
+ else
+ cont_CreateBinding(IndexContext, subst_Dom(Subst), IndexContext, subst_Cod(Subst));
+ } else if (!unify_UnifyAllOC(IndexContext,
+ IndexContext,
+ subst_Cod(Subst),
+ cont_ContextBindingContext(IndexContext,
+ subst_Dom(Subst)),
+ cont_ContextBindingTerm(IndexContext,
+ subst_Dom(Subst))))
+ return FALSE;
+
+ Subst = subst_Next(Subst);
+ }
+
+ return TRUE;
+}
+
+BOOL subst_IsShallow(SUBST Subst) {
+/**********************************************************
+ INPUT: A unifier
+ RETURNS: TRUE, if the unifier is valid :
+ a variable or a ground term or a function with only
+ variables or ground terms as arguments.
+***********************************************************/
+ SUBST SubstScan;
+ for (SubstScan = Subst; SubstScan != subst_Nil();
+ SubstScan = subst_Next(SubstScan)) {
+ TERM Codomain = subst_Cod(SubstScan);
+ if ((!term_IsVariable(Codomain))
+ && (!term_IsGround(Codomain))) {
+ LIST Scan ;
+ for (Scan = term_ArgumentList(Codomain); Scan != list_Nil();
+ Scan = list_Cdr(Scan)) {
+ if ((!term_IsVariable(list_Car(Scan))
+ && (!term_IsGround(list_Car(Scan)))))
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * GENERALIZATION TEST * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL subst_Match(const CONTEXT Context, SUBST Subst)
+/*********************************************************
+ INPUT:
+ RETURNS:
+ CAUTION: 'Subst' IS ASSUMED TO BE NON-EMPTY.
+**********************************************************/
+{
+ while (subst_Exist(Subst)) {
+ if (!cont_VarIsBound(Context, subst_Dom(Subst)) ||
+ !unify_Match(Context,
+ subst_Cod(Subst),
+ cont_ContextBindingTerm(Context, subst_Dom(Subst))))
+ return FALSE;
+
+ Subst = subst_Next(Subst);
+ }
+
+ return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INSTANCE TEST * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL subst_MatchReverse(const CONTEXT IndexContext, SUBST Subst)
+/*********************************************************
+ INPUT:
+ RETURNS:
+ CAUTION: 'Subst' IS ASSUMED TO BE NON-EMPTY.
+**********************************************************/
+{
+ while (subst_Exist(Subst)) {
+
+ if (!cont_VarIsBound(IndexContext, subst_Dom(Subst))) {
+ if (symbol_IsIndexVariable(subst_Dom(Subst)))
+ cont_CreateBinding(IndexContext,
+ subst_Dom(Subst),
+ cont_InstanceContext(),
+ subst_Cod(Subst));
+ else
+ return FALSE;
+ }
+ else if (!unify_MatchReverse(IndexContext,
+ subst_Cod(Subst),
+ cont_ContextBindingContext(IndexContext, subst_Dom(Subst)),
+ cont_ContextBindingTerm(IndexContext, subst_Dom(Subst))))
+ return FALSE;
+
+ Subst = subst_Next(Subst);
+ }
+
+ return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * VARIATION TEST * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL subst_Variation(const CONTEXT Context, SUBST Subst)
+/*********************************************************
+ INPUT:
+ RETURNS:
+ CAUTION: 'Subst' IS ASSUMED TO BE NON-EMPTY.
+**********************************************************/
+{
+ while (subst_Exist(Subst)) {
+
+ if (!cont_VarIsBound(Context, subst_Dom(Subst)) ||
+ !unify_Variation(Context,
+ subst_Cod(Subst),
+ cont_ContextBindingTerm(Context, subst_Dom(Subst))))
+ return FALSE;
+
+ Subst = subst_Next(Subst);
+ }
+
+ return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * COMMON GENERALIZATIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+SUBST subst_ComGen(const CONTEXT Context, SUBST Subst, SUBST* SubstOld,
+ SUBST* SubstNew)
+/*********************************************************
+ INPUT:
+ RETURNS:
+ CAUTION: 'Subst' IS ASSUMED TO BE NON-EMPTY.
+**********************************************************/
+{
+ SUBST Result;
+
+ Result = *SubstOld = *SubstNew = NULL;
+
+ do {
+
+ if (!cont_VarIsBound(Context, subst_Dom(Subst)))
+ *SubstOld=subst_Add(subst_Dom(Subst), term_Copy(subst_Cod(Subst)), *SubstOld);
+
+ else if (term_Equal(cont_ContextBindingTerm(Context, subst_Dom(Subst)),
+ subst_Cod(Subst)))
+ Result = subst_Add(subst_Dom(Subst), term_Copy(subst_Cod(Subst)), Result);
+
+ else
+ if (!symbol_Equal(term_TopSymbol(cont_ContextBindingTerm(Context,
+ subst_Dom(Subst))),
+ term_TopSymbol(subst_Cod(Subst)))) {
+
+ *SubstOld=subst_Add(subst_Dom(Subst),
+ term_Copy(subst_Cod(Subst)),
+ *SubstOld);
+ *SubstNew=subst_Add(subst_Dom(Subst),
+ term_Copy(cont_ContextBindingTerm(Context,
+ subst_Dom(Subst))),
+ *SubstNew);
+
+ } else
+ Result = subst_Add(subst_Dom(Subst),
+ unify_ComGenLinear(Context,
+ SubstNew,
+ cont_ContextBindingTerm(Context,
+ subst_Dom(Subst)),
+ SubstOld,
+ subst_Cod(Subst)),
+ Result);
+
+ cont_CloseBinding(Context, subst_Dom(Subst));
+
+ Subst = subst_Next(Subst);
+ } while (subst_Exist(Subst));
+
+ return Result;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * CLOSE BINDINGS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void subst_CloseVariables(const CONTEXT Context, SUBST Subst)
+{
+ for (; subst_Exist(Subst); Subst = subst_Next(Subst))
+ cont_CloseBinding(Context, subst_Dom(Subst));
+}
+
+
+SUBST subst_CloseOpenVariables(SUBST Result)
+{
+ while (cont_LastBinding()) {
+ if (cont_LastIsBound())
+ Result = subst_Add(cont_LastBindingSymbol(),
+ term_Copy(cont_LastBindingTerm()),
+ Result);
+ cont_BackTrackLastBinding();
+ }
+
+ return Result;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * EXTRACT UNIFIER * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void subst_ExtractUnifier(const CONTEXT CL,
+ SUBST* LeftSubst,
+ const CONTEXT CR,
+ SUBST* RightSubst)
+/*********************************************************
+ INPUT: 'LeftSubst', 'RightSubst' for the unifier,
+ renaming the codomain variables starts at
+ 'MinimumCoVariable' excl., number of
+ renamings are ADDED to 'Bindings'.
+ RETURNS: Nothing.
+ SUMMARY: Extracts the unifier into two substitutions
+ with renamed variables in the codomain.
+ CAUTION: DOES NOT RESET THE BINDINGS, CREATES EVEN
+ MORE BINDINGS BECAUSE OF RENAMING.
+**********************************************************/
+{
+ CONTEXT Scan;
+
+ *LeftSubst = subst_Nil();
+ *RightSubst = subst_Nil();
+
+ Scan = cont_LastBinding();
+
+ while (Scan) {
+ if (cont_IsInContext(CL,
+ cont_BindingSymbol(Scan),
+ Scan))
+ *LeftSubst = subst_Add(cont_BindingSymbol(Scan),
+ cont_CopyAndApplyBindings(cont_BindingContext(Scan),
+ cont_BindingTerm(Scan)),
+ *LeftSubst);
+ else if (cont_IsInContext(CR,
+ cont_BindingSymbol(Scan),
+ Scan))
+ *RightSubst = subst_Add(cont_BindingSymbol(Scan),
+ cont_CopyAndApplyBindings(cont_BindingContext(Scan),
+ cont_BindingTerm(Scan)),
+ *RightSubst);
+
+ Scan = cont_BindingLink(Scan);
+ }
+}
+
+
+void subst_ExtractUnifierCom(const CONTEXT Context, SUBST* Subst)
+/*********************************************************
+ INPUT: 'LeftSubst', 'RightSubst' for the unifier,
+ renaming the codomain variables starts at
+ 'MinimumCoVariable' excl., number of
+ renamings are ADDED to 'Bindings'.
+ RETURNS: Nothing.
+ SUMMARY: Extracts the unifier into two substitutions
+ with renamed variables in the codomain.
+ CAUTION: DOES NOT RESET THE BINDINGS, CREATES EVEN
+ MORE BINDINGS BECAUSE OF RENAMING.
+**********************************************************/
+{
+ CONTEXT Scan;
+
+ *Subst = subst_Nil();
+
+ Scan = cont_LastBinding();
+
+ while (Scan) {
+ *Subst =
+ subst_Add(cont_BindingSymbol(Scan),
+ cont_CopyAndApplyBindingsCom(Context, cont_BindingTerm(Scan)),
+ *Subst);
+
+ Scan = cont_BindingLink(Scan);
+ }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * EXTRACT MATCHER * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+SUBST subst_ExtractMatcher(void)
+/*********************************************************
+ INPUT: None.
+ RETURNS: The matcher.
+ SUMMARY: Extracts the matcher without renaming.
+ CAUTION: DOES NOT RESET THE BINDINGS, DOES NOT COPY
+ THE CODOMAINS.
+**********************************************************/
+{
+ CONTEXT Scan;
+ SUBST Result;
+
+ for (Scan = cont_LastBinding(), Result = subst_Nil();
+ Scan;
+ Scan = cont_BindingLink(Scan))
+ Result = subst_Add(cont_BindingSymbol(Scan),
+ cont_BindingTerm(Scan),
+ Result);
+
+ return Result;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * OUTPUT * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void subst_Print(SUBST Subst)
+{
+ fputs("{ ", stdout);
+ for (; subst_Exist(Subst); Subst = subst_Next(Subst)) {
+ symbol_Print(subst_Dom(Subst));
+ if (subst_Cod(Subst)) {
+ fputs(" -> ", stdout);
+ term_PrintPrefix(subst_Cod(Subst));
+ }
+ if (subst_Next(Subst))
+ fputs("; ", stdout);
+ }
+ fputs(" }", stdout);
+}
+
diff --git a/test/spass/subst.h b/test/spass/subst.h
new file mode 100644
index 0000000..db26197
--- /dev/null
+++ b/test/spass/subst.h
@@ -0,0 +1,219 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SUBSTITUTION * */
+/* * * */
+/* * $Module: SUBSTITUTION * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _SUBST_
+#define _SUBST_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "term.h"
+#include "symbol.h"
+#include "list.h"
+
+/**************************************************************/
+/* Data Structures */
+/**************************************************************/
+
+typedef struct subst {
+ struct subst *next;
+ SYMBOL dom;
+ TERM codomain;
+} SUBST_NODE, *SUBST;
+
+
+static __inline__ SUBST subst_Get(void)
+{
+ return (SUBST) memory_Malloc(sizeof(SUBST_NODE));
+}
+
+static __inline__ void subst_FreeOneNode(SUBST SL)
+{
+ memory_Free(SL, sizeof(SUBST_NODE));
+}
+
+/**************************************************************/
+/* Include 'unify.h' after SUBST declaration. */
+/**************************************************************/
+
+#include "unify.h"
+
+/**************************************************************/
+/* Functions on Substitutions */
+/**************************************************************/
+
+static __inline__ SUBST subst_Nil(void)
+{
+ return (SUBST)NULL;
+}
+
+static __inline__ BOOL subst_Exist(SUBST S)
+{
+ return S != subst_Nil();
+}
+
+static __inline__ BOOL subst_Empty(SUBST S)
+{
+ return S == subst_Nil();
+}
+
+static __inline__ SUBST subst_Next(SUBST S)
+{
+ return S->next;
+}
+
+static __inline__ void subst_SetNext(SUBST S, SUBST N)
+{
+ S->next = N;
+}
+
+static __inline__ SYMBOL subst_Dom(SUBST S)
+{
+ return S->dom;
+}
+
+static __inline__ TERM subst_Cod(SUBST S)
+{
+ return S->codomain;
+}
+
+static __inline__ SUBST subst_NUnion(SUBST S1,SUBST S2)
+{
+ SUBST Result;
+
+ if (S1 == (SUBST)NULL)
+ return S2;
+
+ if (S2 == (SUBST)NULL)
+ return S1;
+
+ Result = S1;
+
+ for (; S1->next != (SUBST)NULL; S1 = S1->next);
+
+ S1->next = S2;
+
+ return Result;
+}
+
+
+/**************************************************************/
+/* Functions for Creation and Deletion */
+/**************************************************************/
+
+SUBST subst_Add(SYMBOL, TERM, SUBST);
+void subst_Delete(SUBST);
+void subst_Free(SUBST);
+
+/**************************************************************/
+/* Functions for Applying and Copying */
+/**************************************************************/
+
+TERM subst_Term(SYMBOL, SUBST);
+TERM subst_Apply(SUBST, TERM);
+SUBST subst_Merge(SUBST, SUBST);
+SUBST subst_Compose(SUBST, SUBST);
+SUBST subst_Copy(SUBST);
+BOOL subst_MatchTops(const CONTEXT, SUBST);
+BOOL subst_BindVar(SYMBOL,SUBST);
+
+/**************************************************************/
+/* Functions for Search of Unifiers */
+/**************************************************************/
+
+BOOL subst_Unify(CONTEXT, SUBST);
+BOOL subst_IsShallow(SUBST);
+
+/**************************************************************/
+/* Functions for Search of Generalizations */
+/**************************************************************/
+
+BOOL subst_Match(const CONTEXT, SUBST);
+
+/**************************************************************/
+/* Functions for Search of Instances */
+/**************************************************************/
+
+BOOL subst_MatchReverse(const CONTEXT, SUBST);
+
+/**************************************************************/
+/* Functions for Search of Variations */
+/**************************************************************/
+
+BOOL subst_Variation(const CONTEXT, SUBST);
+
+/**************************************************************/
+/* Functions for Computation of MSCGs */
+/**************************************************************/
+
+SUBST subst_ComGen(const CONTEXT, SUBST, SUBST*, SUBST*);
+
+/**************************************************************/
+/* Functions for Closing Bindings */
+/**************************************************************/
+
+void subst_CloseVariables(const CONTEXT, SUBST);
+SUBST subst_CloseOpenVariables(SUBST);
+
+/**************************************************************/
+/* Functions for Extracting Substitutions from Bindings */
+/**************************************************************/
+
+void subst_ExtractUnifier(const CONTEXT, SUBST*, const CONTEXT, SUBST*);
+void subst_ExtractUnifierCom(const CONTEXT, SUBST*);
+SUBST subst_ExtractMatcher(void);
+
+/**************************************************************/
+/* Functions for Debugging */
+/**************************************************************/
+
+void subst_Print(SUBST);
+
+#endif
+
+
diff --git a/test/spass/subsumption.c b/test/spass/subsumption.c
new file mode 100644
index 0000000..d312cbf
--- /dev/null
+++ b/test/spass/subsumption.c
@@ -0,0 +1,2041 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SUBSUMPTION * */
+/* * * */
+/* * $Module: SUBSUMPTION * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#include "subsumption.h"
+
+static NAT multvec_i[subs__MAXLITS];
+static NAT multvec_j[subs__MAXLITS];
+static NAT stamp;
+
+static BOOL subs_InternIdc(CLAUSE, int, CLAUSE);
+static BOOL subs_InternIdcEq(CLAUSE, int, CLAUSE);
+static BOOL subs_InternIdcEqExcept(CLAUSE, int, CLAUSE, int);
+static BOOL subs_InternIdcRes(CLAUSE, int, int, int);
+
+/* The following functions are currently unused */
+BOOL subs_IdcTestlits(CLAUSE, CLAUSE, LITPTR*);
+BOOL subs_Testlits(CLAUSE, CLAUSE);
+
+
+void subs_Init(void)
+{
+ int i;
+
+ stamp = 0;
+ for (i = 0; i < subs__MAXLITS; i++)
+ multvec_i[i] = multvec_j[i] = 0;
+}
+
+
+static BOOL subs_TestlitsEq(CLAUSE c1, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1 and c2.
+ RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ TERM t1,t2;
+ int i,j,n,k;
+ BOOL found;
+
+ n = clause_Length(c1);
+ k = clause_Length(c2);
+
+ for (i = 0; i < n; i++){
+ j = 0;
+ found = FALSE;
+ t1 = clause_GetLiteralTerm(c1,i);
+
+ do {
+ t2 = clause_GetLiteralTerm(c2,j);
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(), t1, t2))
+ found = TRUE;
+ else{
+ if (symbol_Equal(term_TopSymbol(t1),term_TopSymbol(t2)) &&
+ fol_IsEquality(fol_Atom(t1)) &&
+ fol_IsEquality(fol_Atom(t2)) &&
+ (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c1,i)) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,j)))) {
+ cont_BackTrackAndStart();
+ if (unify_Match(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(t1)),
+ term_SecondArgument(fol_Atom(t2))) &&
+ unify_Match(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(t1)),
+ term_FirstArgument(fol_Atom(t2))))
+ found = TRUE;
+ else
+ j++;
+ }
+ else
+ j++;
+ }
+ cont_BackTrack();
+
+ } while (!found && j < k);
+
+ if (!found)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static BOOL subs_STMultiIntern(int i, CLAUSE c1, CLAUSE c2)
+/**********************************************************
+ INPUT: Integers i,j and two clauses c1 and c2
+ i and j stand for the i-th and the j-th literal
+ in the clause c1 respectively c2.
+ RETURNS: FALSE if c1 does not multisubsume c2 and TRUE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ int n,j;
+ TERM lit1,lit2;
+
+ j = 0;
+ n = clause_Length(c2);
+ lit1 = clause_GetLiteralTerm(c1,i);
+
+ while (j < n) {
+ if (multvec_j[j] != stamp) {
+ lit2 = clause_GetLiteralTerm(c2,j);
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),lit1,lit2)) {
+ if (i == (clause_Length(c1)-1)) {
+ cont_BackTrack();
+ return TRUE;
+ }
+ multvec_j[j] = stamp;
+ if (subs_STMultiIntern(i+1, c1, c2)) {
+ cont_BackTrack();
+ return TRUE;
+ }
+ multvec_j[j] = 0;
+ }
+ cont_BackTrack();
+ if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+ fol_IsEquality(fol_Atom(lit1)) &&
+ fol_IsEquality(fol_Atom(lit2)) &&
+ (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c1,i)) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,j)))) {
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(lit1)),
+ term_SecondArgument(fol_Atom(lit2))) &&
+ unify_Match(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(lit1)),
+ term_FirstArgument(fol_Atom(lit2)))) {
+ if (i == (clause_Length(c1)-1)) {
+ cont_BackTrack();
+ return TRUE;
+ }
+ multvec_j[j] = stamp;
+ if (subs_STMultiIntern(i+1, c1, c2)) {
+ cont_BackTrack();
+ return TRUE;
+ }
+ multvec_j[j] = 0;
+ }
+ cont_BackTrack();
+ }
+ }
+ j++;
+ }
+ return FALSE;
+}
+
+
+BOOL subs_STMulti(CLAUSE c1, CLAUSE c2)
+{
+ BOOL Result;
+ int n;
+
+ n = clause_Length(c1);
+
+ /*printf("\n St-Multi: %d -> %d",clause_Number(c1),clause_Number(c2));*/
+
+ if (n > clause_Length(c2) ||
+ (n > 1 && !subs_TestlitsEq(c1,c2))) {
+ /*fputs(" Testlits failure ", stdout);*/
+ return(FALSE);
+ }
+
+ if (++stamp == NAT_MAX) {
+ int i;
+ stamp = 1;
+ for (i = 0; i < subs__MAXLITS; i++)
+ multvec_i[i] = multvec_j[i] = 0;
+ }
+ /*unify_SaveState();*/
+ Result = subs_STMultiIntern(0,c1,c2);
+ /*unify_CheckState();*/
+ return Result;
+}
+
+
+static BOOL subs_TestlitsEqExcept(CLAUSE C1, CLAUSE C2)
+{
+ TERM t1,t2;
+ int i,j,n,k;
+ BOOL found;
+
+ n = clause_Length(C1);
+ k = clause_Length(C2);
+
+ i = 0;
+ while (multvec_i[i] == stamp && i < n)
+ i++;
+
+ while (i < n) {
+ j = 0;
+ found = FALSE;
+ t1 = clause_GetLiteralTerm(C1,i);
+
+ do {
+ if (multvec_j[j] == stamp)
+ j++;
+ else {
+ t2 = clause_GetLiteralTerm(C2,j);
+ cont_StartBinding();
+ if (unify_MatchBindings(cont_LeftContext(), t1, t2))
+ found = TRUE;
+ else {
+ if (symbol_Equal(term_TopSymbol(t1),term_TopSymbol(t2)) &&
+ fol_IsEquality(fol_Atom(t1)) &&
+ fol_IsEquality(fol_Atom(t2)) &&
+ (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C1,i)) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C2,j)))) {
+ cont_BackTrackAndStart();
+ if (unify_MatchBindings(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(t1)),
+ term_SecondArgument(fol_Atom(t2))) &&
+ unify_MatchBindings(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(t1)),
+ term_FirstArgument(fol_Atom(t2))))
+ found = TRUE;
+ else
+ j++;
+ }
+ else
+ j++;
+ }
+ cont_BackTrack();
+ } /* else */
+ } while (!found && (j < k));
+
+ if (!found)
+ return FALSE;
+ do
+ i++;
+ while (multvec_i[i] == stamp && i < n);
+ } /* while i < n */
+
+
+ return TRUE;
+}
+
+
+static BOOL subs_STMultiExceptIntern(CLAUSE C1, CLAUSE C2)
+{
+ int n, i, j, k;
+ NAT occs, occsaux;
+ TERM lit1,lit2;
+
+ i = -1;
+ k = 0;
+ occs = 0;
+ j = 0;
+ n = clause_Length(C2);
+
+ while (k < clause_Length(C1)) {
+ /* Select Literal with maximal number of variable occurrences. */
+ if (multvec_i[k] != stamp) {
+ if (i < 0) {
+ i = k;
+ occs = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,i));
+ } else
+ if ((occsaux = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,k)))
+ > occs) {
+ i = k;
+ occs = occsaux;
+ }
+ }
+ k++;
+ }
+
+ if (i < 0)
+ return TRUE;
+
+ lit1 = clause_GetLiteralTerm(C1, i);
+ multvec_i[i] = stamp;
+
+ while (j < n) {
+ if (multvec_j[j] != stamp) {
+ lit2 = clause_GetLiteralTerm(C2, j);
+ cont_StartBinding();
+ if (unify_MatchBindings(cont_LeftContext(), lit1, lit2)) {
+ multvec_j[j] = stamp;
+ if (subs_STMultiExceptIntern(C1, C2)) {
+ cont_BackTrack();
+ return TRUE;
+ }
+ multvec_j[j] = 0;
+ }
+ cont_BackTrack();
+ if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+ fol_IsEquality(fol_Atom(lit1)) &&
+ fol_IsEquality(fol_Atom(lit2)) &&
+ (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C1,i)) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C2,j)))) {
+ cont_StartBinding();
+ if (unify_MatchBindings(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(lit1)),
+ term_SecondArgument(fol_Atom(lit2))) &&
+ unify_MatchBindings(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(lit1)),
+ term_FirstArgument(fol_Atom(lit2)))) {
+ multvec_j[j] = stamp;
+ if (subs_STMultiExceptIntern(C1, C2)) {
+ cont_BackTrack();
+ return TRUE;
+ }
+ multvec_j[j] = 0;
+ }
+ cont_BackTrack();
+ }
+ }
+ j++;
+ }
+ multvec_i[i] = 0;
+ return FALSE;
+}
+
+
+BOOL subs_STMultiExcept(CLAUSE C1, CLAUSE C2, int ExceptI, int ExceptJ)
+/**********************************************************
+ INPUT: Two clauses and for each clause a literal that is
+ already bound to each other. If the literal value is negative,
+ a general subsumption test is performed.
+ RETURNS: TRUE if the first clause subsumes the second one.
+ CAUTION: The weight of the clauses must be up to date!
+***********************************************************/
+{
+ BOOL Result;
+ int n;
+
+ n = clause_Length(C1);
+
+ if (n > clause_Length(C2) ||
+ (clause_Weight(C1)-clause_LiteralWeight(clause_GetLiteral(C1,ExceptI))) >
+ (clause_Weight(C2)-clause_LiteralWeight(clause_GetLiteral(C2,ExceptJ))))
+ return FALSE;
+
+ if (++stamp == NAT_MAX) {
+ int i;
+ stamp = 1;
+ for (i = 0; i < subs__MAXLITS; i++)
+ multvec_i[i] = multvec_j[i] = 0;
+ }
+ multvec_i[ExceptI] = stamp;
+ multvec_j[ExceptJ] = stamp;
+
+ if (n > 1 && !subs_TestlitsEqExcept(C1, C2))
+ return FALSE;
+
+ /*unify_SaveState();*/
+ Result = subs_STMultiExceptIntern(C1, C2);
+ /*unify_CheckState();*/
+ return Result;
+}
+
+
+static BOOL subs_PartnerTest(CLAUSE C1, int c1l, int c1r, CLAUSE C2, int c2l, int c2r)
+/**********************************************************
+ INPUT: Two clauses and for each clause a starting left index
+ and an exclusive right index.
+ RETURNS: TRUE if every literal inside the bounds of the first clause
+ can be matched against a literal inside the bounds of the
+ second clause.
+ CAUTION: None.
+***********************************************************/
+{
+ TERM t1,t2;
+ int j;
+ BOOL found;
+
+ if (c1l == c1r)
+ return TRUE;
+
+ while (multvec_i[c1l] == stamp && c1l < c1r)
+ c1l++;
+
+ if (c1l < c1r) {
+ if (c2l == c2r)
+ return FALSE;
+ else
+ do {
+ j = c2l;
+ found = FALSE;
+ t1 = clause_GetLiteralTerm(C1,c1l);
+
+ do {
+ if (multvec_j[j] == stamp)
+ j++;
+ else {
+ t2 = clause_GetLiteralTerm(C2,j);
+ cont_StartBinding();
+ if (unify_MatchBindings(cont_LeftContext(), t1, t2))
+ found = TRUE;
+ else {
+ if (symbol_Equal(term_TopSymbol(t1),term_TopSymbol(t2)) &&
+ fol_IsEquality(fol_Atom(t1)) &&
+ fol_IsEquality(fol_Atom(t2)) &&
+ (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C1,c1l)) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C2,j)))) {
+ cont_BackTrackAndStart();
+ if (unify_MatchBindings(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(t1)),
+ term_SecondArgument(fol_Atom(t2))) &&
+ unify_MatchBindings(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(t1)),
+ term_FirstArgument(fol_Atom(t2))))
+ found = TRUE;
+ else
+ j++;
+ }
+ else
+ j++;
+ }
+ cont_BackTrack();
+ } /* else */
+ } while (!found && (j < c2r));
+
+ if (!found)
+ return FALSE;
+ do
+ c1l++;
+ while (multvec_i[c1l] == stamp && c1l < c1r);
+ } while (c1l < c1r);
+ }
+ return TRUE;
+}
+
+
+static BOOL subs_SubsumesInternBasic(CLAUSE C1, int c1fa, int c1fs, int c1l,
+ CLAUSE C2, int c2fa, int c2fs, int c2l)
+{
+ int i, j, n, k;
+ NAT occs, occsaux;
+ TERM lit1,lit2;
+
+ i = -1;
+ k = clause_FirstLitIndex();
+ occs = 0;
+
+ while (k < c1l) { /* Select literal with maximal variable occurrences. */
+ if (multvec_i[k] != stamp) {
+ if (i < 0) {
+ i = k;
+ occs = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,i));
+ } else
+ if ((occsaux = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,k)))
+ > occs) {
+ i = k;
+ occs = occsaux;
+ }
+ }
+ k++;
+ }
+
+ if (i < 0)
+ return TRUE;
+
+ lit1 = clause_GetLiteralTerm(C1, i);
+ multvec_i[i] = stamp;
+
+ if (i < c1fa) { /* Only consider relevant partner literals */
+ j = clause_FirstLitIndex();
+ n = c2fa;
+ }
+ else if (i < c1fs) {
+ j = c2fa;
+ n = c2fs;
+ }
+ else {
+ j = c2fs;
+ n = c2l;
+ }
+
+ while (j < n) {
+ if (multvec_j[j] != stamp) {
+ lit2 = clause_GetLiteralTerm(C2, j);
+ cont_StartBinding();
+ if (unify_MatchBindings(cont_LeftContext(), lit1, lit2)) {
+ multvec_j[j] = stamp;
+ if (subs_SubsumesInternBasic(C1,c1fa,c1fs,c1l,C2,c2fa,c2fs,c2l)) {
+ cont_BackTrack();
+ return TRUE;
+ }
+ multvec_j[j] = 0;
+ }
+ cont_BackTrack();
+ if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+ fol_IsEquality(fol_Atom(lit1)) &&
+ fol_IsEquality(fol_Atom(lit2)) &&
+ (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C1,i)) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C2,j)))) {
+ cont_StartBinding();
+ if (unify_MatchBindings(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(lit1)),
+ term_SecondArgument(fol_Atom(lit2))) &&
+ unify_MatchBindings(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(lit1)),
+ term_FirstArgument(fol_Atom(lit2)))) {
+ multvec_j[j] = stamp;
+ if (subs_SubsumesInternBasic(C1,c1fa,c1fs,c1l,C2,c2fa,c2fs,c2l)) {
+ cont_BackTrack();
+ return TRUE;
+ }
+ multvec_j[j] = 0;
+ }
+ cont_BackTrack();
+ }
+ }
+ j++;
+ }
+ multvec_i[i] = 0;
+ return FALSE;
+}
+
+
+BOOL subs_SubsumesBasic(CLAUSE C1, CLAUSE C2, int ExceptI, int ExceptJ)
+/**********************************************************
+ INPUT: Two clauses and for each clause a literal that are
+ already bound to each other. If the literal value is negative,
+ a general subsumption test is performed.
+ RETURNS: TRUE if the first clause subsumes the second one with respect
+ to basic restrictions on the sort literals.
+ CAUTION: The weight of the clauses must be up to date!
+***********************************************************/
+{
+ BOOL Result;
+ int c1fa,c1fs,c1l,c2fa,c2fs,c2l,lw1,lw2;
+
+ c1fa = clause_FirstAntecedentLitIndex(C1);
+ c1fs = clause_FirstSuccedentLitIndex(C1);
+ c1l = clause_Length(C1);
+ c2fa = clause_FirstAntecedentLitIndex(C2);
+ c2fs = clause_FirstSuccedentLitIndex(C2);
+ c2l = clause_Length(C2);
+
+ lw1 = (ExceptI >= clause_FirstLitIndex() ?
+ clause_LiteralWeight(clause_GetLiteral(C1,ExceptI)) : 0);
+ lw2 = (ExceptJ >= clause_FirstLitIndex() ?
+ clause_LiteralWeight(clause_GetLiteral(C2,ExceptJ)) : 0);
+
+ if (c1l > c2l || /* Multiset restriction */
+ (clause_Weight(C1)-lw1) > (clause_Weight(C2)-lw2)) {
+ return FALSE;
+ }
+
+ if (++stamp == NAT_MAX) {
+ int i;
+ stamp = 1;
+ for (i = 0; i < subs__MAXLITS; i++)
+ multvec_i[i] = multvec_j[i] = 0;
+ }
+
+ if (ExceptI >= clause_FirstLitIndex())
+ multvec_i[ExceptI] = stamp;
+ if (ExceptJ >= clause_FirstLitIndex())
+ multvec_j[ExceptJ] = stamp;
+
+ if (c1l > 1 &&
+ (!subs_PartnerTest(C1,clause_FirstConstraintLitIndex(C1),c1fa,
+ C2,clause_FirstConstraintLitIndex(C2),c2fa) ||
+ !subs_PartnerTest(C1,c1fa,c1fs,C2,c2fa,c2fs) ||
+ !subs_PartnerTest(C1,c1fs,c1l,C2,c2fs,c2l)))
+ return FALSE;
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ Result = subs_SubsumesInternBasic(C1,c1fa,c1fs,c1l,C2,c2fa,c2fs,c2l);
+
+#ifdef CHECK
+ cont_CheckState();
+#endif
+
+ return Result;
+}
+
+
+static BOOL subs_SubsumesInternWithSignature(int i, CLAUSE c1, CLAUSE c2, BOOL Variants, LIST* Bindings)
+/**********************************************************
+ INPUT:
+ RETURNS:
+ CAUTION:
+***********************************************************/
+{
+ int n,j;
+ TERM lit1,lit2;
+ LIST NewBindings,Scan;
+
+ j = 0;
+ n = clause_Length(c2);
+ lit1 = clause_GetLiteralTerm(c1,i);
+ NewBindings = list_Nil();
+
+ while (j < n) {
+ if (multvec_j[j] != stamp) {
+ lit2 = clause_GetLiteralTerm(c2,j);
+ cont_StartBinding();
+ if (fol_SignatureMatch(lit1,lit2,&NewBindings,Variants)) {
+ if (i == (clause_Length(c1)-1)) {
+ *Bindings = list_Nconc(NewBindings,*Bindings);
+ return TRUE;
+ }
+ multvec_j[j] = stamp;
+ if (subs_SubsumesInternWithSignature(i+1, c1, c2,Variants,&NewBindings)) {
+ *Bindings = list_Nconc(NewBindings,*Bindings);
+ return TRUE;
+ }
+ multvec_j[j] = 0;
+ }
+ for (Scan=NewBindings;!list_Empty(Scan);Scan=list_Cdr(Scan)) { /* Backtrack bindings */
+ if (symbol_IsVariable((SYMBOL)list_Car(Scan)))
+ term_ClearBinding((SYMBOL)list_Car(Scan));
+ else
+ symbol_ContextClearValue((SYMBOL)list_Car(Scan));
+ }
+ list_Delete(NewBindings);
+ NewBindings = list_Nil();
+ if (symbol_Equal(term_TopSymbol(fol_Atom(lit1)),term_TopSymbol(fol_Atom(lit2))) &&
+ fol_IsEquality(fol_Atom(lit1))) {
+ if (fol_SignatureMatch(term_FirstArgument(fol_Atom(lit1)),
+ term_SecondArgument(fol_Atom(lit2)), &NewBindings, Variants) &&
+ fol_SignatureMatch(term_SecondArgument(fol_Atom(lit1)),
+ term_FirstArgument(fol_Atom(lit2)), &NewBindings, Variants)) {
+ if (i == (clause_Length(c1)-1)) {
+ *Bindings = list_Nconc(NewBindings,*Bindings);
+ return TRUE;
+ }
+ multvec_j[j] = stamp;
+ if (subs_SubsumesInternWithSignature(i+1, c1, c2,Variants,&NewBindings)) {
+ *Bindings = list_Nconc(NewBindings,*Bindings);
+ return TRUE;
+ }
+ multvec_j[j] = 0;
+ }
+ for (Scan=NewBindings;!list_Empty(Scan);Scan=list_Cdr(Scan)) { /* Backtrack bindings */
+ if (symbol_IsVariable((SYMBOL)list_Car(Scan)))
+ term_ClearBinding((SYMBOL)list_Car(Scan));
+ else
+ symbol_ContextClearValue((SYMBOL)list_Car(Scan));
+ }
+ list_Delete(NewBindings);
+ NewBindings = list_Nil();
+ }
+ }
+ j++;
+ }
+ return FALSE;
+}
+
+BOOL subs_SubsumesWithSignature(CLAUSE C1, CLAUSE C2, BOOL Variants, LIST *Bindings)
+/**********************************************************
+ INPUT: Two clauses .
+ RETURNS: TRUE if the first clause subsumes the second one where
+ we allow signature symbols to be matched as well.
+ If <Variants> is TRUE variables must be mapped to variables.
+ Returns the signature symbols that were bound.
+ EFFECT: Symbol context bindings are established.
+***********************************************************/
+{
+ BOOL Result;
+
+ if (clause_Length(C1) > clause_Length(C2) ||
+ clause_NumOfSuccLits(C1) > clause_NumOfSuccLits(C2) ||
+ (clause_NumOfAnteLits(C1) + clause_NumOfConsLits(C1)) >
+ (clause_NumOfAnteLits(C2) + clause_NumOfConsLits(C2))) { /* Multiset restriction */
+ return FALSE;
+ }
+
+ if (++stamp == NAT_MAX) {
+ int i;
+ stamp = 1;
+ for (i = 0; i < subs__MAXLITS; i++)
+ multvec_i[i] = multvec_j[i] = 0;
+ }
+
+ term_NewMark();
+ Result = subs_SubsumesInternWithSignature(clause_FirstLitIndex(),C1,C2,Variants, Bindings);
+ *Bindings = list_DeleteElementIf(*Bindings, (BOOL (*)(POINTER)) symbol_IsVariable);
+ return Result;
+}
+
+static BOOL subs_SubsumesIntern(CLAUSE C1, int c1fs, int c1l, CLAUSE C2, int c2fs, int c2l)
+{
+ int i, j, n, k;
+ NAT occs, occsaux;
+ TERM lit1,lit2;
+
+ i = -1;
+ k = clause_FirstLitIndex();
+ occs = 0;
+
+ while (k < c1l) { /* Select literal with maximal variable occurrences. */
+ if (multvec_i[k] != stamp) {
+ if (i < 0) {
+ i = k;
+ occs = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,i));
+ } else
+ if ((occsaux = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,k)))
+ > occs) {
+ i = k;
+ occs = occsaux;
+ }
+ }
+ k++;
+ }
+
+ if (i < 0)
+ return TRUE;
+
+ lit1 = clause_GetLiteralTerm(C1, i);
+ multvec_i[i] = stamp;
+
+ if (i < c1fs) { /* Only consider relevant partner literals */
+ j = clause_FirstLitIndex();
+ n = c2fs;
+ }
+ else {
+ j = c2fs;
+ n = c2l;
+ }
+
+ while (j < n) {
+ if (multvec_j[j] != stamp) {
+ lit2 = clause_GetLiteralTerm(C2, j);
+ cont_StartBinding();
+ if (unify_MatchBindings(cont_LeftContext(), lit1, lit2)) {
+ multvec_j[j] = stamp;
+ if (subs_SubsumesIntern(C1,c1fs,c1l,C2,c2fs,c2l)) {
+ cont_BackTrack();
+ return TRUE;
+ }
+ multvec_j[j] = 0;
+ }
+ cont_BackTrack();
+ if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+ fol_IsEquality(fol_Atom(lit1)) &&
+ fol_IsEquality(fol_Atom(lit2)) &&
+ (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C1,i)) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C2,j)))) {
+ cont_StartBinding();
+ if (unify_MatchBindings(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(lit1)),
+ term_SecondArgument(fol_Atom(lit2))) &&
+ unify_MatchBindings(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(lit1)),
+ term_FirstArgument(fol_Atom(lit2)))) {
+ multvec_j[j] = stamp;
+ if (subs_SubsumesIntern(C1,c1fs,c1l,C2,c2fs,c2l)) {
+ cont_BackTrack();
+ return TRUE;
+ }
+ multvec_j[j] = 0;
+ }
+ cont_BackTrack();
+ }
+ }
+ j++;
+ }
+ multvec_i[i] = 0;
+ return FALSE;
+}
+
+
+BOOL subs_Subsumes(CLAUSE C1, CLAUSE C2, int ExceptI, int ExceptJ)
+/**********************************************************
+ INPUT: Two clauses and for each clause a literal that is
+ already bound to each other. If the literal value is negative,
+ a general subsumption test is performed.
+ RETURNS: TRUE if the first clause subsumes the second one.
+ CAUTION: The weight of the clauses must be up to date!
+***********************************************************/
+{
+ BOOL Result;
+ int c1fs, c1l, c2fs, c2l, lw1, lw2;
+
+ c1fs = clause_FirstSuccedentLitIndex(C1);
+ c1l = clause_Length(C1);
+ c2fs = clause_FirstSuccedentLitIndex(C2);
+ c2l = clause_Length(C2);
+
+ lw1 = (ExceptI >= clause_FirstLitIndex() ?
+ clause_LiteralWeight(clause_GetLiteral(C1,ExceptI)) : 0);
+ lw2 = (ExceptJ >= clause_FirstLitIndex() ?
+ clause_LiteralWeight(clause_GetLiteral(C2,ExceptJ)) : 0);
+
+ if (c1l > c2l || /* Multiset restriction */
+ (clause_Weight(C1) - lw1) > (clause_Weight(C2) - lw2))
+ return FALSE;
+
+ if (++stamp == NAT_MAX) {
+ int i;
+ stamp = 1;
+ for (i = 0; i < subs__MAXLITS; i++)
+ multvec_i[i] = multvec_j[i] = 0;
+ }
+
+ if (ExceptI >= clause_FirstLitIndex())
+ multvec_i[ExceptI] = stamp;
+ if (ExceptJ >= clause_FirstLitIndex())
+ multvec_j[ExceptJ] = stamp;
+
+ if (c1l > 1 &&
+ (!subs_PartnerTest(C1,clause_FirstConstraintLitIndex(C1),c1fs,
+ C2,clause_FirstConstraintLitIndex(C2),c2fs) ||
+ !subs_PartnerTest(C1,c1fs,c1l,C2,c2fs,c2l)))
+ return FALSE;
+
+#ifdef CHECK
+ cont_SaveState();
+#endif
+
+ Result = subs_SubsumesIntern(C1,c1fs,c1l,C2,c2fs,c2l);
+
+#ifdef CHECK
+ cont_CheckState();
+#endif
+
+ return Result;
+}
+
+
+
+
+BOOL subs_ST(int i, int j, CLAUSE c1, CLAUSE c2)
+/**********************************************************
+ INPUT: Integers i,j and two clauses c1 and c2.
+ i and j stand for the i-th and the j-th literal
+ in the clause c1 respectively c2.
+ RETURNS: FALSE if c1 does not subsume c2 and TRUE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ cont_StartBinding();
+
+ while ((j < clause_Length(c2)) &&
+ !(unify_Match(cont_LeftContext(),
+ clause_GetLiteralTerm(c1,i),
+ clause_GetLiteralTerm(c2,j)))){
+ j++;
+ cont_BackTrackAndStart();
+ }
+
+ if (j >= clause_Length(c2)) {
+ cont_BackTrack();
+ return FALSE;
+ }
+
+ if ((i == (clause_Length(c1)-1)) || subs_ST(i+1, 0, c1, c2))
+ return TRUE;
+ else
+ cont_BackTrack();
+
+ if (++j == clause_Length(c2))
+ return FALSE;
+
+ return subs_ST(i, j, c1, c2);
+}
+
+
+BOOL subs_Testlits(CLAUSE c1, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1 and c2.
+ RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ TERM t1;
+ int i,j;
+ BOOL found;
+
+ for (i = 0; i < clause_Length(c1); i++){
+ j = 0;
+ found = FALSE;
+ t1 = clause_GetLiteralTerm(c1,i);
+
+ do {
+ cont_StartBinding();
+ if (!(found = unify_Match(cont_LeftContext(), t1, clause_GetLiteralTerm(c2,j))))
+ j++;
+ cont_BackTrack();
+
+ } while (!found && (j < clause_Length(c2)));
+
+ if (!found)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static LIST subs_GetVariables(TERM t)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: The list of non bound variables of the term.
+ CAUTION: None.
+***********************************************************/
+{
+ LIST scan,insert,symbols,end;
+
+ symbols = term_VariableSymbols(t);
+ insert = symbols;
+ end = list_Nil();
+
+ for (scan = symbols; !list_Empty(scan); scan = list_Cdr(scan)) {
+ if (!cont_VarIsBound(cont_LeftContext(), (SYMBOL)list_Car(scan))) {
+ end = insert;
+ list_Rplaca(insert, list_Car(scan));
+ insert = list_Cdr(insert);
+ }
+ }
+
+ if (!list_Empty(insert)) {
+ list_Delete(insert);
+ if (list_Empty(end))
+ symbols = list_Nil();
+ else
+ list_Rplacd(end,list_Nil());
+ }
+
+ return(symbols);
+}
+
+
+static BOOL subs_SubsumptionPossible(CLAUSE c1, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1 and c2.
+ RETURNS: TRUE if every literal in c1 can independently be
+ matched to a literal in c2.
+ CAUTION: None.
+***********************************************************/
+{
+ int i,j;
+
+ for (i = 0; i < clause_Length(c1); i++) {
+ for (j = 0; j < clause_Length(c2); j++) {
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),
+ clause_GetLiteralTerm(c1,i),
+ clause_GetLiteralTerm(c2,j)))
+ j = clause_Length(c2) + 1;
+ cont_BackTrack();
+ }
+ if (j == clause_Length(c2))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+BOOL subs_IdcTestlits(CLAUSE c1, CLAUSE c2, LITPTR* litptr)
+/**********************************************************
+ INPUT: Two clauses c1, c2 and a pointer to a litptr structure.
+ RETURNS: FALSE if c1 can not independently be matched
+ to c2 and TRUE otherwise.
+ CAUTION: A structure is build and litptr points to that structure.
+***********************************************************/
+{
+ LIST TermIndexlist,VarSymbList,TermSymbList;
+ int i;
+
+ if (subs_SubsumptionPossible(c1,c2)) {
+
+ TermIndexlist = list_Nil();
+ VarSymbList = list_Nil();
+ TermSymbList = list_Nil();
+
+ for (i = 0; i < clause_Length(c1); i++) {
+ VarSymbList = subs_GetVariables(clause_GetLiteralTerm(c1,i));
+
+ if (VarSymbList != list_Nil()){
+ TermIndexlist = list_Cons((POINTER)i, TermIndexlist);
+ TermSymbList = list_Cons(VarSymbList,TermSymbList);
+ }
+ }
+
+ *litptr = litptr_Create(TermIndexlist,TermSymbList);
+
+ list_Delete(TermSymbList);
+ list_Delete(TermIndexlist);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static BOOL subs_SubsumptionVecPossible(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1 and c2 and a vector pointer.
+ RETURNS: TRUE if all literals in c1 which indexes stand
+ in the vector with bottom pointer vec can
+ independently be matched to a literal in c2.
+ CAUTION: None.
+***********************************************************/
+{
+ int i,j;
+
+ for (i = vec; i < vec_ActMax(); i++) {
+ for (j = 0; j < clause_Length(c2); j++) {
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),
+ clause_GetLiteralTerm(c1, (int) vec_GetNth(i)),
+ clause_GetLiteralTerm(c2,j)))
+ j = clause_Length(c2) + 1;
+ cont_BackTrack();
+ }
+ if (j == clause_Length(c2))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static BOOL subs_SubsumptionVecPossibleEq(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1 and c2 and a vector pointer.
+ RETURNS: TRUE if all literals in c1 which indexes stand
+ in the vector with bottom pointer vec can
+ independently be matched to a literal in c2.
+ CAUTION: None.
+***********************************************************/
+{
+ int i,j,n;
+ TERM lit1,lit2;
+
+ n = clause_Length(c2);
+ for (i = vec; i < vec_ActMax(); i++) {
+ lit1 = clause_GetLiteralTerm(c1, (int) vec_GetNth(i));
+ for (j=0;j<n;j++) {
+ lit2 = clause_GetLiteralTerm(c2,j);
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),lit1,lit2)) {
+ j = n + 1;
+ cont_BackTrack();
+ }
+ else {
+ cont_BackTrack();
+ if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+ fol_IsEquality(fol_Atom(lit1)) &&
+ fol_IsEquality(fol_Atom(lit2)) &&
+ (clause_LiteralIsNotOrientedEquality(
+ clause_GetLiteral(c1, (int)vec_GetNth(i))) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,j)))) {
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(lit1)),
+ term_SecondArgument(fol_Atom(lit2))) &&
+ unify_Match(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(lit1)),
+ term_FirstArgument(fol_Atom(lit2))))
+ j = n+1;
+ cont_BackTrack();
+ }
+ }
+ }
+ if (j==n)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static BOOL subs_IdcVecTestlits(CLAUSE c1, int vec, CLAUSE c2, LITPTR* litptr)
+/**********************************************************
+ INPUT: Two clauses c1, c2, a pointer to a literal structure and
+ a vector pointer.
+ RETURNS: FALSE if the literals of c1 which are designated by
+ the elements of vec do not subsume c2 and TRUE otherwise.
+ CAUTION: A structure is build and litptr points to that structure.
+***********************************************************/
+{
+ LIST TermIndexlist,VarSymbList,TermSymbList;
+ int i;
+
+ if (subs_SubsumptionVecPossible(c1,vec,c2)) {
+
+ TermIndexlist = list_Nil();
+ VarSymbList = list_Nil();
+ TermSymbList = list_Nil();
+
+ for (i = vec; i < vec_ActMax(); i++) {
+ VarSymbList =
+ subs_GetVariables(clause_GetLiteralTerm(c1, (int) vec_GetNth(i)));
+
+ if (VarSymbList != list_Nil()){
+ TermIndexlist = list_Cons(vec_GetNth(i), TermIndexlist);
+ TermSymbList = list_Cons(VarSymbList,TermSymbList);
+ }
+ }
+
+ *litptr = litptr_Create(TermIndexlist,TermSymbList);
+
+ list_Delete(TermSymbList);
+ list_Delete(TermIndexlist);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static BOOL subs_IdcVecTestlitsEq(CLAUSE c1, int vec, CLAUSE c2,
+ LITPTR* litptr)
+/**********************************************************
+ INPUT: Two clauses c1, c2, a pointer to a literal structure and
+ a vector pointer.
+ RETURNS: FALSE if the literals of c1 which are designated by
+ the elements of vec do not subsume c2 and TRUE otherwise.
+ CAUTION: A structure is build and litptr points to that structure.
+***********************************************************/
+{
+ LIST TermIndexlist,VarSymbList,TermSymbList;
+ int i;
+
+ if (subs_SubsumptionVecPossibleEq(c1,vec,c2)) {
+
+ TermIndexlist = list_Nil();
+ VarSymbList = list_Nil();
+ TermSymbList = list_Nil();
+
+ for (i = vec; i < vec_ActMax(); i++){
+ VarSymbList =
+ subs_GetVariables(clause_GetLiteralTerm(c1, (int) vec_GetNth(i)));
+
+ if (VarSymbList != list_Nil()){
+ TermIndexlist = list_Cons(vec_GetNth(i), TermIndexlist);
+ TermSymbList = list_Cons(VarSymbList,TermSymbList);
+ }
+ }
+
+ *litptr = litptr_Create(TermIndexlist,TermSymbList);
+
+ list_Delete(TermSymbList);
+ list_Delete(TermIndexlist);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static void subs_CompVec(LITPTR litptr)
+/**********************************************************
+ INPUT: A LITPTR pointer.
+ RETURNS: None.
+ CAUTION: Indexes are pushed on the vector. These indexes build
+ a component with respect to the structure litptr and to the
+ actual bindings.
+***********************************************************/
+{
+ LIST complist, end, scan;
+ int lit,n,i,j;
+
+ n = litptr_Length(litptr);
+ complist = list_Nil();
+
+
+ if (n > 0){
+ for (j = 0; j < n; j++) {
+ if (!literal_GetUsed(litptr_Literal(litptr,j))) {
+ complist = list_Cons((POINTER)j,complist);
+ vec_Push((POINTER)literal_GetLitIndex(litptr_Literal(litptr,j)));
+ literal_PutUsed(litptr_Literal(litptr,j), TRUE);
+ j = n + 1;
+ }
+ }
+
+ if (j != n) {
+ end = complist;
+ for (scan = complist; !list_Empty(scan); scan = list_Cdr(scan)) {
+ lit = (int)list_Car(scan);
+ for (i = 0; i < n; i++) {
+ if (!literal_GetUsed(litptr_Literal(litptr,i)) &&
+ list_HasIntersection(literal_GetLitVarList(litptr_Literal(litptr,lit)),
+ literal_GetLitVarList(litptr_Literal(litptr,i)))) {
+ list_Rplacd(end,list_List((POINTER)i));
+ end = list_Cdr(end);
+ vec_Push((POINTER)literal_GetLitIndex(litptr_Literal(litptr,i)));
+ literal_PutUsed(litptr_Literal(litptr,i), TRUE);
+ }
+ }
+ }
+ list_Delete(complist);
+ }
+ }
+}
+
+
+static BOOL subs_StVec(int i, int j, CLAUSE c1, CLAUSE c2)
+/**********************************************************
+ INPUT: Integers i,j and two clauses c1 and c2.
+ i is a pointer to vector and represents a
+ literal in clause c1 and j stand for the j-th
+ literal in the clause c2.
+ RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ int a;
+
+ if (j >= clause_Length(c2))
+ return FALSE;
+
+ a = j;
+
+ cont_StartBinding();
+
+ while ((a < clause_Length(c2)) &&
+ !(unify_Match(cont_LeftContext(),
+ clause_GetLiteralTerm(c1, (int) vec_GetNth(i)),
+ clause_GetLiteralTerm(c2,a)))){
+ a++;
+ cont_BackTrackAndStart();
+ }
+
+ if (a >= clause_Length(c2)) {
+ cont_BackTrack();
+ return FALSE;
+ }
+
+ if ((i == (vec_ActMax()-1)) || subs_StVec(i+1, 0, c1, c2))
+ return TRUE;
+ else
+ cont_BackTrack();
+
+ return subs_StVec(i, a+1, c1, c2);
+}
+
+
+static int subs_SearchTop(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1, c2, a vector pointer vec.
+ RETURNS: The index of that literal in c1 which has the least positive
+ matching tests with the literals in c2.
+ CAUTION: None.
+***********************************************************/
+{
+ int index, i, j, zaehler;
+
+ index = (int)vec_GetNth(vec);
+
+ for (i = vec; i < vec_ActMax(); i++) {
+ zaehler = 0;
+ j = 0;
+ while (j < clause_Length(c2) && zaehler < 2) {
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),
+ clause_GetLiteralTerm(c1, (int) vec_GetNth(i)),
+ clause_GetLiteralTerm(c2,j))) {
+ zaehler++;
+ }
+ cont_BackTrack();
+ j++;
+ }
+
+ if (zaehler == 0 || zaehler == 1) {
+ index = (int)vec_GetNth(i);
+ return index;
+ }
+ }
+ return index;
+}
+
+
+static BOOL subs_TcVec(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1, c2, a vector pointer vec.
+ RETURNS: FALSE if the literals of c1 which are designated by
+ the elements of vec do not subsume c2 and TRUE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ int a,top_index;
+ a = 0;
+
+ top_index = subs_SearchTop(c1,vec,c2);
+
+ do {
+ cont_StartBinding();
+ while ((a < clause_Length(c2)) &&
+ !(unify_Match(cont_LeftContext(),
+ clause_GetLiteralTerm(c1,top_index),
+ clause_GetLiteralTerm(c2,a)))) {
+ a++;
+ cont_BackTrackAndStart();
+ }
+
+ if (a >= clause_Length(c2)){
+ cont_BackTrack();
+ return FALSE;
+ }
+
+ if ((vec - vec_ActMax()) == 1)
+ return TRUE;
+
+ if (subs_InternIdc(c1, vec, c2))
+ return TRUE;
+ else {
+ cont_BackTrack(); /* Dies ist der 'Hurra' Fall.*/
+ a++;
+ }
+
+ } while (a < clause_Length(c2));
+
+ return FALSE;
+}
+
+static BOOL subs_TcVecEq(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1, c2, a vector pointer vec.
+ RETURNS: FALSE if the literals of c1 which are designated by
+ the elements of vec do not subsume c2 and TRUE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ int a,top_index;
+ BOOL search;
+ TERM lit1,lit2;
+
+ a = 0;
+ top_index = subs_SearchTop(c1,vec,c2);
+ lit1 = clause_GetLiteralTerm(c1,top_index);
+
+ do {
+ search = TRUE;
+
+ while (a < clause_Length(c2) && search) {
+ lit2 = clause_GetLiteralTerm(c2,a);
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),lit1,lit2))
+ search = FALSE;
+ else {
+ if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+ fol_IsEquality(fol_Atom(lit1)) &&
+ fol_IsEquality(fol_Atom(lit2)) &&
+ (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c1,top_index)) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,a)))) {
+ cont_BackTrackAndStart();
+ if (unify_Match(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(lit1)),
+ term_SecondArgument(fol_Atom(lit2))) &&
+ unify_Match(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(lit1)),
+ term_FirstArgument(fol_Atom(lit2))))
+ search = FALSE;
+ }
+ if (search) {
+ a++;
+ cont_BackTrack();
+ }
+ }
+ }
+
+ if (a >= clause_Length(c2)) {
+ cont_BackTrack();
+ return FALSE;
+ }
+
+ if ((vec_ActMax() - vec) == 1)
+ return TRUE;
+
+ if (subs_InternIdcEq(c1, vec, c2))
+ return TRUE;
+ else {
+ cont_BackTrack();
+ a++;
+ }
+
+ } while (a < clause_Length(c2));
+
+ return FALSE;
+}
+
+
+static BOOL subs_InternIdc(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1, c2, a vector pointer vec.
+ RETURNS: FALSE if the literals of c1 which are designed by
+ the elements of vec do not subsume c2 and TRUE otherwise.
+ CAUTION:
+***********************************************************/
+{
+ int locvec;
+ LITPTR litptr;
+
+
+ if (!subs_IdcVecTestlits(c1,vec,c2,&litptr))
+ return FALSE;
+
+ locvec = vec_ActMax();
+
+ do {
+ subs_CompVec(litptr);
+ if (!vec_IsMax(locvec)) {
+ if (!subs_TcVec(c1,locvec,c2)) {
+ vec_SetMax(locvec);
+ litptr_Delete(litptr);
+ return FALSE;
+ }
+ else
+ vec_SetMax(locvec);
+ }
+ } while (!litptr_AllUsed(litptr));
+
+ litptr_Delete(litptr);
+
+ return TRUE;
+}
+
+
+static BOOL subs_InternIdcEq(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1, c2, a vector pointer vec.
+ RETURNS: FALSE if the literals of c1 which are designed by
+ the elements of vec do not subsume c2 and TRUE otherwise.
+ CAUTION:
+***********************************************************/
+{
+ int locvec;
+ LITPTR litptr;
+
+
+ if (!subs_IdcVecTestlitsEq(c1,vec,c2,&litptr))
+ return FALSE;
+
+ locvec = vec_ActMax();
+
+ do {
+ subs_CompVec(litptr);
+ if (!vec_IsMax(locvec)) {
+ if (!subs_TcVecEq(c1,locvec,c2)) {
+ vec_SetMax(locvec);
+ litptr_Delete(litptr);
+ return FALSE;
+ }
+ else
+ vec_SetMax(locvec);
+ }
+
+ } while (!litptr_AllUsed(litptr));
+
+ litptr_Delete(litptr);
+
+ return TRUE;
+}
+
+
+BOOL subs_Idc(CLAUSE c1, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1, c2.
+ RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+ CAUTION:
+***********************************************************/
+{
+ int i,vec;
+ BOOL Result;
+
+ vec = vec_ActMax();
+
+ for (i = 0; i < clause_Length(c1); i++)
+ vec_Push((POINTER) i);
+
+ Result = subs_InternIdc(c1,vec,c2);
+
+ vec_SetMax(vec);
+
+ cont_Reset();
+
+ return Result;
+}
+
+
+BOOL subs_IdcEq(CLAUSE c1, CLAUSE c2)
+/**********************************************************
+ INPUT: Two clauses c1, c2.
+ RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+ CAUTION:
+***********************************************************/
+{
+ int i,vec;
+ BOOL Result;
+
+ /*fputs("\n Idc on: ", stdout); clause_Print(c1);
+ putchar('\t'); clause_Print(c2); */
+ vec = vec_ActMax();
+
+ for (i = 0; i < clause_Length(c1); i++)
+ vec_Push((POINTER) i);
+
+ Result = subs_InternIdcEq(c1,vec,c2);
+
+ vec_SetMax(vec);
+
+ cont_Reset();
+
+ /*printf(" Result: %s ",(Result ? "TRUE" : "FALSE"));*/
+
+ return Result;
+}
+
+
+BOOL subs_IdcEqMatch(CLAUSE c1, CLAUSE c2, SUBST subst)
+/**********************************************************
+ INPUT: Two clauses c1, c2.
+ RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+ CAUTION:
+***********************************************************/
+{
+ int i,vec;
+ BOOL Result;
+
+ /* fputs("\n Idc on: ", stdout); clause_Print(c1);
+ putchar('\t'); clause_Print(c2); DBG */
+ vec = vec_ActMax();
+
+ for (i = 0; i < clause_Length(c1); i++)
+ vec_Push((POINTER) i);
+
+ i = 0; /* Doesn't matter, there is a general cont_Reset below */
+ unify_EstablishMatcher(cont_LeftContext(), subst);
+
+ Result = subs_InternIdcEq(c1,vec,c2);
+
+ vec_SetMax(vec);
+
+ cont_Reset();
+
+ /*fputs("\nsubs_Idc end: ",stdout); clause_Print(c1); clause_Print(c2); DBG */
+
+ return Result;
+}
+
+
+static BOOL subs_SubsumptionVecPossibleRes(CLAUSE c1, int vec,
+ int beg, int end)
+/**********************************************************
+ INPUT: Two clauses c1 and c2 and three vector pointer
+ vec,beg and end.
+ RETURNS: TRUE if all literals in c1 which indexes stand
+ in the vector with bottom pointer vec can
+ independently be matched to a literal in c2
+ which indexes stand in the vector between the
+ pointers beg and end (exclusive).
+ CAUTION: None.
+***********************************************************/
+{
+ int j,i;
+
+ for (i = vec; i < vec_ActMax(); i++) {
+ for (j = beg; j < end; j++){
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),
+ clause_GetLiteralTerm(c1, (int) vec_GetNth(i)),
+ clause_GetLiteralTerm(c1, (int) vec_GetNth(j))))
+ j = end+1;
+ cont_BackTrack();
+ }
+ if (j == end)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static BOOL subs_IdcVecTestlitsRes(CLAUSE c1, int vec,
+ int beg, int end, LITPTR* litptr)
+/**********************************************************
+ INPUT: A clause c1, a pointer to a literal structure and
+ three vector pointer vec, beg and end.
+ RETURNS: FALSE if the literals of c1 which are designated by
+ the elements of vec can not be matched independently
+ to literal in c2 which are designated by the elements
+ of the vector between the pointers beg and end (exclusive).
+ CAUTION: A structure is build and litptr points to that structure.
+***********************************************************/
+{
+ LIST TermIndexlist,VarSymbList,TermSymbList;
+ int i;
+
+ if (subs_SubsumptionVecPossibleRes(c1,vec,beg,end)) {
+
+ TermIndexlist = list_Nil();
+ VarSymbList = list_Nil();
+ TermSymbList = list_Nil();
+
+ for (i = vec; i < vec_ActMax(); i++) {
+ VarSymbList =
+ subs_GetVariables(clause_GetLiteralTerm(c1, (int) vec_GetNth(i)));
+
+ if (VarSymbList != list_Nil()) {
+ TermIndexlist = list_Cons(vec_GetNth(i), TermIndexlist);
+ TermSymbList = list_Cons(VarSymbList,TermSymbList);
+ }
+ }
+
+ *litptr = litptr_Create(TermIndexlist,TermSymbList);
+
+ list_Delete(TermSymbList);
+ list_Delete(TermIndexlist);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static int subs_SearchTopRes(CLAUSE c1, int vec, int beg, int end)
+/**********************************************************
+ INPUT: A clause c1, three vector pointers vec, beg and end.
+ RETURNS: The index of that literal in c1 which has the least positive
+ matching tests with the literals in c2 with respect to
+ vector and the vector pointers beg and end.
+ CAUTION: None.
+***********************************************************/
+{
+ int index,i,j,zaehler;
+
+ index = (int) vec_GetNth(vec);
+
+ for (i = vec; i < vec_ActMax(); i++) {
+ zaehler = 0;
+ j = beg;
+ while ((j < end) && (zaehler < 2)) {
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),
+ clause_GetLiteralTerm(c1, (int) vec_GetNth(i)),
+ clause_GetLiteralTerm(c1, (int) vec_GetNth(j)))) {
+ zaehler++;
+ }
+ cont_BackTrack();
+ j++;
+ }
+
+ if (zaehler == 0 || zaehler == 1) {
+ index = (int)vec_GetNth(i);
+ return index;
+ }
+ }
+ return index;
+}
+
+
+static BOOL subs_TcVecRes(CLAUSE c1, int vec, int beg, int end)
+/**********************************************************
+ INPUT: A clause c1, three vector pointers vec,beg and end.
+ RETURNS: FALSE if the literals of c1 which are designated by
+ the elements of vec do not subsume c2 with
+ respect to the vector and the vector pointers
+ beg and end and TRUE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ int a,top_index;
+
+ a = beg;
+
+ top_index = subs_SearchTopRes(c1,vec,beg,end);
+
+ do {
+ cont_StartBinding();
+ while ((a < end) &&
+ !unify_Match(cont_LeftContext(),
+ clause_GetLiteralTerm(c1,top_index),
+ clause_GetLiteralTerm(c1,(int)vec_GetNth(a)))) {
+ a++;
+ cont_BackTrackAndStart();
+ }
+
+ if (a >= end){
+ cont_BackTrack();
+ return FALSE;
+ }
+
+ if ((vec - vec_ActMax()) == 1)
+ return TRUE;
+
+ if (subs_InternIdcRes(c1, vec, beg, end))
+ return TRUE;
+ else {
+ cont_BackTrack();
+ a++;
+ }
+
+ } while (a < end);
+
+ return FALSE;
+}
+
+
+static BOOL subs_InternIdcRes(CLAUSE c1, int vec, int beg, int end)
+/**********************************************************
+ INPUT: A clause c1 and three vector pointers vec,beg and end.
+ RETURNS: FALSE if the literals of c1 which are designated by
+ the elements of vec do not subsume c2 with respect
+ to vector and the vector pointers beg and end
+ and TRUE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ int locvec;
+ LITPTR litptr;
+
+
+ if (!subs_IdcVecTestlitsRes(c1,vec,beg,end,&litptr))
+ return FALSE;
+
+ locvec = vec_ActMax();
+
+ do {
+ subs_CompVec(litptr);
+ if (!vec_IsMax(locvec)) {
+ if (!subs_TcVecRes(c1,locvec,beg,end)) {
+ vec_SetMax(locvec);
+ litptr_Delete(litptr);
+ return FALSE;
+ }
+ else
+ vec_SetMax(locvec);
+ }
+ } while (!litptr_AllUsed(litptr));
+
+ litptr_Delete(litptr);
+
+ return TRUE;
+}
+
+
+BOOL subs_IdcRes(CLAUSE c1, int beg, int end)
+/**********************************************************
+ INPUT: A clause c1 and two vector pointers beg and end.
+ RETURNS: FALSE if c1 do not subsume c2 with respect to
+ vector and the vector pointers beg and end
+ and TRUE otherwise.
+ CAUTION:
+***********************************************************/
+{
+ int i,vec;
+ BOOL Result;
+
+ vec = vec_ActMax();
+
+ for (i = 0; i < clause_Length(c1); i++)
+ vec_Push((POINTER) i);
+
+ Result = subs_InternIdcRes(c1, vec, beg, end);
+
+ vec_SetMax(vec);
+
+ cont_Reset();
+
+ return Result;
+}
+
+
+static BOOL subs_TcVecEqExcept(CLAUSE c1, int vec, CLAUSE c2, int i2)
+/**********************************************************
+ INPUT: Two clauses c1, c2, a vector pointer vec.
+ RETURNS: FALSE if the literals of c1 which are designated by
+ the elements of vec do not subsume c2 and TRUE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ int a,top_index;
+ BOOL search;
+ TERM lit1,lit2;
+
+ a = 0;
+ top_index = subs_SearchTop(c1,vec,c2);
+ lit1 = clause_GetLiteralTerm(c1,top_index);
+
+ do {
+ search = TRUE;
+
+ while (a < clause_Length(c2) && search) {
+ if (a != i2) {
+ lit2 = clause_GetLiteralTerm(c2,a);
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),lit1,lit2))
+ search = FALSE;
+ else {
+ if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+ fol_IsEquality(fol_Atom(lit1)) &&
+ fol_IsEquality(fol_Atom(lit2)) &&
+ (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c1,top_index)) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,a)))) {
+ cont_BackTrackAndStart();
+ if (unify_Match(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(lit1)),
+ term_SecondArgument(fol_Atom(lit2))) &&
+ unify_Match(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(lit1)),
+ term_FirstArgument(fol_Atom(lit2))))
+ search = FALSE;
+ }
+ if (search) {
+ a++;
+ cont_BackTrack();
+ }
+ }
+ }
+ else
+ a++;
+ }
+
+ if (a>=clause_Length(c2)) {
+ cont_BackTrack();
+ return FALSE;
+ }
+
+ if ((vec_ActMax() - vec) == 1)
+ return TRUE;
+
+ if (subs_InternIdcEqExcept(c1, vec, c2, i2))
+ return TRUE;
+ else {
+ cont_BackTrack();
+ a++;
+ }
+
+ } while (a < clause_Length(c2));
+
+ return FALSE;
+}
+
+
+static BOOL subs_SubsumptionVecPossibleEqExcept(CLAUSE c1, int vec,
+ CLAUSE c2, int i2)
+/**********************************************************
+ INPUT: Two clauses c1 and c2 and a vector pointer
+ and an accept literal index for c2.
+ RETURNS: TRUE if all literals in c1 which indexes stand
+ in the vector with bottom pointer vec can
+ independently be matched to a literal in c2.
+ CAUTION: None.
+***********************************************************/
+{
+ int i,j,n;
+ TERM lit1,lit2;
+
+ n = clause_Length(c2);
+ for (i = vec; i < vec_ActMax(); i++) {
+ lit1 = clause_GetLiteralTerm(c1, (int) vec_GetNth(i));
+ for (j = 0; j < n; j++) {
+ if (j != i2) {
+ lit2 = clause_GetLiteralTerm(c2,j);
+ cont_StartBinding();
+ if (unify_Match(cont_LeftContext(),lit1,lit2))
+ j = n + 1;
+ else {
+ if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+ fol_IsEquality(fol_Atom(lit1)) &&
+ fol_IsEquality(fol_Atom(lit2)) &&
+ (clause_LiteralIsNotOrientedEquality(
+ clause_GetLiteral(c1,(int)vec_GetNth(i))) ||
+ clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,j)))) {
+ cont_BackTrackAndStart();
+ if (unify_Match(cont_LeftContext(),
+ term_FirstArgument(fol_Atom(lit1)),
+ term_SecondArgument(fol_Atom(lit2))) &&
+ unify_Match(cont_LeftContext(),
+ term_SecondArgument(fol_Atom(lit1)),
+ term_FirstArgument(fol_Atom(lit2))))
+ j = n+1;
+ }
+ }
+ cont_BackTrack();
+ }
+ }
+ if (j==n)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static BOOL subs_IdcVecTestlitsEqExcept(CLAUSE c1, int vec,
+ CLAUSE c2, int i2, LITPTR* litptr)
+/**********************************************************
+ INPUT: Two clauses c1, c2, a pointer to a literal structure and
+ a vector pointer and a literal index i2 in c2
+ RETURNS: FALSE if the literals of c1 which are designated by
+ the elements of vec do not subsume c2 and TRUE otherwise.
+ CAUTION: A structure is build and litptr points to that structure.
+ ***********************************************************/
+{
+ LIST TermIndexlist,VarSymbList,TermSymbList;
+ int i;
+
+ if (subs_SubsumptionVecPossibleEqExcept(c1,vec,c2,i2)) {
+
+ TermIndexlist = list_Nil();
+ VarSymbList = list_Nil();
+ TermSymbList = list_Nil();
+
+ for (i = vec; i < vec_ActMax(); i++) {
+ VarSymbList =
+ subs_GetVariables(clause_GetLiteralTerm(c1, (int) vec_GetNth(i)));
+
+ if (VarSymbList != list_Nil()){
+ TermIndexlist = list_Cons(vec_GetNth(i), TermIndexlist);
+ TermSymbList = list_Cons(VarSymbList,TermSymbList);
+ }
+ }
+
+ *litptr = litptr_Create(TermIndexlist,TermSymbList);
+
+ list_Delete(TermSymbList);
+ list_Delete(TermIndexlist);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static BOOL subs_InternIdcEqExcept(CLAUSE c1, int vec, CLAUSE c2, int i2)
+/**********************************************************
+ INPUT: Two clauses c1, c2, a vector pointer vec and a literal
+ i2 in c2 which must not be considered
+ RETURNS: FALSE if the literals of c1 which are designed by
+ the elements of vec do not subsume c2/i2 and TRUE otherwise.
+ CAUTION:
+***********************************************************/
+{
+ int locvec;
+ LITPTR litptr;
+
+
+ if (!subs_IdcVecTestlitsEqExcept(c1,vec,c2,i2,&litptr))
+ return FALSE;
+
+ locvec = vec_ActMax();
+
+ do {
+ subs_CompVec(litptr);
+ if (!vec_IsMax(locvec)) {
+ if (!subs_TcVecEqExcept(c1,locvec,c2,i2)) {
+ vec_SetMax(locvec);
+ litptr_Delete(litptr);
+ return FALSE;
+ }
+ else
+ vec_SetMax(locvec);
+ }
+ } while (!litptr_AllUsed(litptr));
+
+ litptr_Delete(litptr);
+
+ return TRUE;
+}
+
+
+BOOL subs_IdcEqMatchExcept(CLAUSE c1, int i1, CLAUSE c2, int i2,
+ SUBST subst)
+/**********************************************************
+ INPUT: Two clauses c1, c2 with the indices of two literals
+ which need not to be considered and a matcher
+ RETURNS: TRUE if (<c1>/<i1>)<subst> subsumes (<c2>/<i2>)<subst>
+ CAUTION:
+***********************************************************/
+{
+ int i,vec;
+ BOOL Result;
+
+ /*fputs("\n IdcEQExcept on: \n\t", stdout);
+ subst_Print(subst); fputs("\n\t", stdout);
+ clause_Print(c1); printf(" \t\t%d \n\t",i1);
+ clause_Print(c2); printf(" \t\t%d \n\t",i2);*/
+
+ if (clause_Length(c1) == 1)
+ Result = TRUE;
+ else {
+ vec = vec_ActMax();
+
+ for (i = 0; i < clause_Length(c1); i++)
+ if (i != i1)
+ vec_Push((POINTER) i);
+
+ i = 0; /* Doesn't matter, there is a general cont_Reset below */
+ unify_EstablishMatcher(cont_LeftContext(), subst);
+
+ Result = subs_InternIdcEqExcept(c1,vec,c2,i2);
+
+ /* printf("Result : %d",Result); */
+
+ vec_SetMax(vec);
+
+ cont_Reset();
+ }
+
+ return Result;
+}
diff --git a/test/spass/subsumption.h b/test/spass/subsumption.h
new file mode 100644
index 0000000..3f5b8ab
--- /dev/null
+++ b/test/spass/subsumption.h
@@ -0,0 +1,87 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SUBSUMPTION * */
+/* * * */
+/* * $Module: SUBSUMPTION * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1999, 2000 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _SUBSUMPTION_
+#define _SUBSUMPTION_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "misc.h"
+#include "unify.h"
+#include "component.h"
+#include "vector.h"
+#include "clause.h"
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+#define subs__MAXLITS 100
+
+static __inline__ int subs_NoException(void)
+{
+ return -1;
+}
+
+void subs_Init(void);
+BOOL subs_ST(int, int, CLAUSE, CLAUSE);
+BOOL subs_STMulti(CLAUSE, CLAUSE);
+BOOL subs_STMultiExcept(CLAUSE, CLAUSE, int, int);
+BOOL subs_Subsumes(CLAUSE, CLAUSE, int, int);
+BOOL subs_SubsumesBasic(CLAUSE, CLAUSE, int, int);
+BOOL subs_SubsumesWithSignature(CLAUSE, CLAUSE, BOOL, LIST*);
+BOOL subs_Idc(CLAUSE, CLAUSE);
+BOOL subs_IdcRes(CLAUSE, int, int);
+BOOL subs_IdcEq(CLAUSE, CLAUSE);
+BOOL subs_IdcEqMatch(CLAUSE, CLAUSE, SUBST);
+BOOL subs_IdcEqMatchExcept(CLAUSE, int, CLAUSE, int, SUBST);
+
+#endif
+
diff --git a/test/spass/symbol.c b/test/spass/symbol.c
new file mode 100644
index 0000000..ab1b0b4
--- /dev/null
+++ b/test/spass/symbol.c
@@ -0,0 +1,1020 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SYMBOLS * */
+/* * * */
+/* * $Module: SYMBOL * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "symbol.h"
+
+SIGNATURE *symbol_SIGNATURE;
+
+SYMBOL symbol_STANDARDVARCOUNTER;
+SYMBOL symbol_INDEXVARCOUNTER;
+
+const int symbol_MASK = 3; /* 0000011 */
+const int symbol_TYPEMASK = 3; /* 0000011 */
+const int symbol_STATMASK = 4; /* 0000100 */
+const int symbol_TYPESTATMASK = 7; /* 0000111 */
+
+
+const int symbol_TYPEBITS = 2;
+const int symbol_STATBITS = 1;
+const int symbol_TYPESTATBITS = 3;
+
+const int symbol_SIGTYPES = 4;
+
+const char symbol_SKFNAME[]="skf";
+const char symbol_SKCNAME[]="skc";
+const char symbol_SKPNAME[]="SkP";
+const char symbol_SKANAME[]="SkC";
+const int symbol_SKLENGTH = 3;
+
+static BOOL symbol_HASSIGNATURE;
+static LIST symbol_FREEDSYMBOLS;
+
+int symbol_ACTINDEX;
+int symbol_ACTSKOLEMFINDEX;
+int symbol_ACTSKOLEMCINDEX;
+int symbol_ACTSKOLEMAINDEX;
+int symbol_ACTSKOLEMPINDEX;
+int symbol_ORDERING;
+char *symbol_VARSTRING;
+
+SYMBOL symbol_CONTEXT[symbol__MAXSIGNATURE];
+
+static unsigned long symbol_COUNT[symbol__MAXSIGNATURE];
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SYMBOL CREATION * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+int symbol_GetIncreasedOrderingCounter(void)
+{
+ return symbol_ORDERING++;
+}
+
+NAT symbol_MaxStringLength(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The maximal number of characters needed for a string in the signature.
+***************************************************************/
+{
+ int Index;
+ NAT Result,Length;
+ SIGNATURE Entry;
+
+ Result = 0;
+
+ for (Index=1; Index < symbol_ACTINDEX; Index++) {
+ Entry = symbol_Signature(Index);
+ if (Entry != NULL) {
+ Length = Entry->length;
+ if (Length > Result)
+ Result = Length;
+ }
+ }
+ return Result;
+}
+
+static SYMBOL symbol_SignatureCreate(char* String, int Type, int Arity,
+ int Status, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A pointer to a string, a type, the arity and the status
+ RETURNS: The symbol containing the passed parameters.
+ SUMMARY: Establishes a new symbol in the symbol table and returns the
+ internal representation (pointer and type).
+ CAUTION: The string is not copied!
+***************************************************************/
+{
+ SIGNATURE Entry;
+
+#ifdef CHECK
+ if (!symbol_SignatureExists()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_SignatureCreate:");
+ misc_ErrorReport(" Module was initialized with no signature.\n");
+ misc_FinishErrorReport();
+ }
+ if (Type < 0 || Type >= symbol_SIGTYPES) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_SignatureCreate: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if ((int)symbol_ACTINDEX >= symbol__MAXSIGNATURE &&
+ list_Empty(symbol_FREEDSYMBOLS)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In symbol_SignatureCreate: No more symbols available.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ if (strlen(String)>=symbol__SYMBOLMAXLEN) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In symbol_SignatureCreate: String too long.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ Entry = symbol_GetSignature();
+ Entry->weight = 1;
+ Entry->props = 0;
+ Entry->name = String;
+ Entry->length = strlen(String);
+ Entry->arity = Arity;
+ Entry->generatedBy = list_Nil();
+
+ if (list_Empty(symbol_FREEDSYMBOLS)) {
+ Entry->info = symbol_SignatureSymbol(symbol_ACTINDEX, Type, Status);
+ symbol_SetSignature(symbol_ACTINDEX++, Entry);
+ }
+ else {
+ int Index;
+
+ Index = (int)list_Car(symbol_FREEDSYMBOLS);
+ symbol_FREEDSYMBOLS = list_PointerDeleteElement(symbol_FREEDSYMBOLS,
+ (POINTER)Index);
+ Entry->info = symbol_SignatureSymbol(Index, Type, Status);
+ symbol_SetSignature(Index, Entry);
+ }
+
+ /* Define precedence of symbol */
+ symbol_SetIncreasedOrdering(Precedence, Entry->info);
+
+ return Entry->info;
+}
+
+
+SYMBOL symbol_CreateFunction(const char* String, int Arity, int Status,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A string defining a symbol name, an arity, the status the
+ created function symbol is supposed to have and a precedence
+ object.
+ RETURNS: A new symbol for a new function.
+ SUMMARY: Creates a new function symbol.
+ EFFECTS: Inserts the new function in the symbol table.
+ The precedence of the new symbol is set in <Precedence>.
+***************************************************************/
+{
+ if (Arity == 0)
+ return symbol_SignatureCreate(strcpy(memory_Malloc(symbol__SYMBOLMAXLEN),
+ String),
+ symbol_CONSTANT, Arity, Status, Precedence);
+ else
+ return symbol_SignatureCreate(strcpy(memory_Malloc(symbol__SYMBOLMAXLEN),
+ String),
+ symbol_FUNCTION, Arity, Status, Precedence);
+}
+
+SYMBOL symbol_CreateSkolemFunction(int Arity, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: The arity of a function to be created, and a precedence.
+ RETURNS: A new skolem symbol having the required arity.
+ SUMMARY: Creates a new function symbol.
+ EFFECTS: Inserts the new function in the symbol table.
+ The precedence of the new symbol is set in <Precedence>.
+***************************************************************/
+{
+ char newname[10];
+ SYMBOL Result;
+
+ Result = (SYMBOL)NULL;
+
+ while (Result == (SYMBOL)NULL) {
+ if (Arity == 0)
+ sprintf(newname,"%s%d",symbol_SKCNAME,symbol_ACTSKOLEMCINDEX++);
+ else
+ sprintf(newname,"%s%d",symbol_SKFNAME,symbol_ACTSKOLEMFINDEX++);
+ if (symbol_Lookup(newname) == 0)
+ Result = symbol_CreateFunction(newname, Arity, symbol_STATLEX, Precedence);
+ }
+
+ symbol_AddProperty(Result,SKOLEM);
+
+ return Result;
+}
+
+
+SYMBOL symbol_CreatePredicate(const char* String, int Arity, int Status,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A string, a symbol arity, the status the created predicate
+ is supposed to have, and a precedence object.
+ RETURNS: A new symbol for a new predicate.
+ SUMMARY: Creates a new predicate symbol.
+ EFFECTS: Inserts the new predicate symbol into the symbol table.
+ The precedence of the new symbol is set in <Precedence>.
+***************************************************************/
+{
+ return symbol_SignatureCreate(strcpy(memory_Malloc(symbol__SYMBOLMAXLEN),
+ String),
+ symbol_PREDICATE, Arity, Status, Precedence);
+}
+
+SYMBOL symbol_CreateSkolemPredicate(int Arity, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: The arity of a new Skolem predicate symbol and a precedence object.
+ RETURNS: A new symbol for a new predicate.
+ SUMMARY: Creates a new predicate symbol.
+ EFFECTS: Inserts the new predicate symbol into the symbol table.
+ The precedence of the new symbol is set in <Precedence>.
+***************************************************************/
+{
+ char newname[10];
+ SYMBOL Result;
+
+ Result = (SYMBOL)NULL;
+
+ while (Result == (SYMBOL)NULL) {
+ if (Arity==0)
+ sprintf(newname,"%s%d",symbol_SKANAME,symbol_ACTSKOLEMAINDEX++);
+ else
+ sprintf(newname,"%s%d",symbol_SKPNAME,symbol_ACTSKOLEMPINDEX++);
+ if (symbol_Lookup(newname) == 0)
+ Result = symbol_CreatePredicate(newname, Arity, symbol_STATLEX, Precedence);
+ }
+
+ return Result;
+}
+
+
+SYMBOL symbol_CreateJunctor(const char* String, int Arity, int Status,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A string, a symbol arity, the status the created junctor
+ is supposed to have, and a precedence object.
+ RETURNS: A new symbol for a new junctor.
+ SUMMARY: Creates a new junctor symbol.
+ EFFECTS: Inserts the new junctor symbol into the symbol table.
+ The precedence of the new symbol is set in <Precedence>.
+***************************************************************/
+{
+ return symbol_SignatureCreate(strcpy(memory_Malloc(symbol__SYMBOLMAXLEN),
+ String),
+ symbol_JUNCTOR, Arity, Status, Precedence);
+}
+
+
+BOOL symbol_IsSymbol(SYMBOL Symbol)
+/**************************************************************
+ INPUT: A symbol.
+ RETURNS: TRUE if the symbols is a variable or contained
+ in the symbol table.
+***************************************************************/
+{
+ return
+ (!symbol_SignatureExists() ||
+ ((!symbol_Equal(Symbol, symbol__NULL)) &&
+ ((symbol_IsVariable(Symbol) && Symbol<symbol_MaxVars()) ||
+ (symbol_IsSignature(Symbol) && symbol_Index(Symbol)<symbol_ACTINDEX))));
+}
+
+
+void symbol_Delete(SYMBOL Symbol)
+/**************************************************************
+ INPUT: A symbol.
+ RETURNS: Nothing.
+ SUMMARY: Deletes the symbol from the symbol table and frees its memory.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!symbol_SignatureExists()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_Delete: Module was initialized without signature.\n");
+ misc_FinishErrorReport();
+ }
+ if (!symbol_IsSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_Delete: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (!symbol_IsVariable(Symbol)) {
+ int Index;
+ SIGNATURE Entry;
+
+ Index = symbol_Index(Symbol);
+ symbol_FREEDSYMBOLS = list_Cons((POINTER)Index,symbol_FREEDSYMBOLS);
+ Entry = symbol_Signature(Index);
+ symbol_SetSignature(Index, NULL);
+ symbol_FreeSignature(Entry);
+ }
+}
+
+LIST symbol_GetAllSymbols(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: A list of all generated symbols.
+***************************************************************/
+{
+ LIST Result;
+
+ Result = list_Nil();
+
+ if (symbol_SignatureExists()) {
+ int Index;
+ SIGNATURE S;
+
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL) {
+ Result = list_Cons((POINTER)symbol_GetSigSymbol(Index), Result);
+ }
+ }
+ }
+ return Result;
+}
+
+
+LIST symbol_GetAllPredicates(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: A list of all predicate symbols.
+***************************************************************/
+{
+ LIST Result;
+
+ Result = list_Nil();
+
+ if (symbol_SignatureExists()) {
+ int Index;
+ SIGNATURE S;
+
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL && symbol_IsPredicate(symbol_GetSigSymbol(Index)))
+ Result = list_Cons((POINTER)symbol_GetSigSymbol(Index), Result);
+ }
+ }
+ return Result;
+}
+
+
+LIST symbol_GetAllFunctions(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: A list of all function symbols.
+***************************************************************/
+{
+ LIST Result;
+
+ Result = list_Nil();
+
+ if (symbol_SignatureExists()) {
+ int Index;
+ SIGNATURE S;
+
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL && symbol_IsFunction(symbol_GetSigSymbol(Index)))
+ Result = list_Cons((POINTER)symbol_GetSigSymbol(Index), Result);
+ }
+ }
+ return Result;
+}
+
+
+void symbol_FreeAllSymbols(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECTS: Frees all generated symbols
+***************************************************************/
+{
+ if (symbol_SignatureExists()) {
+ int Index;
+ SIGNATURE S;
+
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL)
+ symbol_FreeSignature(S);
+ }
+ memory_Free(symbol_SIGNATURE, sizeof(SIGNATURE[symbol__MAXSIGNATURE]));
+ }
+
+ memory_Free(symbol_VARSTRING, symbol__SYMBOLMAXLEN);
+ list_Delete(symbol_FREEDSYMBOLS);
+}
+
+
+void symbol_Init(BOOL Signature)
+/**************************************************************
+ INPUT: A flag indicating whether a signature is used or not.
+ RETURNS: None.
+ SUMMARY: Initializes the Symbol Module.
+ EFFECTS: Initializes global variables.
+ CAUTION: MUST BE CALLED BEFORE ANY OTHER Symbol-FUNCTION.
+***************************************************************/
+{
+ symbol_ResetSkolemIndex();
+ symbol_ContextClean();
+
+ if (Signature)
+ symbol_SIGNATURE = (SIGNATURE*)memory_Malloc(sizeof(SIGNATURE[symbol__MAXSIGNATURE]));
+
+ symbol_STANDARDVARCOUNTER = symbol_GetInitialStandardVarCounter();
+ symbol_INDEXVARCOUNTER = symbol_GetInitialIndexVarCounter();
+
+ symbol_ACTINDEX = 1;
+ symbol_ORDERING = 1;
+ symbol_VARSTRING = memory_Malloc(symbol__SYMBOLMAXLEN);
+
+ symbol_HASSIGNATURE = Signature;
+ symbol_FREEDSYMBOLS = list_Nil();
+}
+
+
+BOOL symbol_SignatureExists(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: TRUE, if a symbol signature was created, FALSE otherwise.
+***************************************************************/
+{
+ return symbol_HASSIGNATURE;
+}
+
+void symbol_ReinitGenericNameCounters(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECTS: Scans the symbol signature for generic names and if
+ there exists some, the corresponding counters are increased.
+***************************************************************/
+{
+ if (symbol_SignatureExists()) {
+ int Index,Num;
+ SYMBOL Info;
+ SIGNATURE Entry;
+ char *Name,*Subname;
+
+ for (Index=1; Index < symbol_ACTINDEX; Index++) {
+ Entry = symbol_Signature(Index);
+ if (Entry != NULL) {
+ Info = Entry->info;
+ Name = Entry->name;
+ if (strlen(Name)>symbol_SKLENGTH) {
+ Subname = Name + symbol_SKLENGTH;
+
+ switch (symbol_Type(Info)) {
+
+ case symbol_CONSTANT:
+ if (strncmp(Name,symbol_SKCNAME,symbol_SKLENGTH) == 0 &&
+ string_StringIsNumber(Subname)) {
+ Num = atoi(Subname);
+ if (Num >= symbol_ACTSKOLEMCINDEX)
+ symbol_ACTSKOLEMCINDEX = Num + 1;
+ }
+ break;
+ case symbol_FUNCTION:
+ if (strncmp(Name,symbol_SKFNAME,symbol_SKLENGTH) == 0 &&
+ string_StringIsNumber(Subname)) {
+ Num = atoi(Subname);
+ if (Num >= symbol_ACTSKOLEMFINDEX)
+ symbol_ACTSKOLEMFINDEX = Num + 1;
+ }
+ break;
+ case symbol_PREDICATE:
+ if (Entry->arity == 0) {
+ if (strncmp(Name,symbol_SKANAME,symbol_SKLENGTH) == 0 &&
+ string_StringIsNumber(Subname)) {
+ Num = atoi(Subname);
+ if (Num >= symbol_ACTSKOLEMAINDEX)
+ symbol_ACTSKOLEMAINDEX = Num + 1;
+ }
+ }
+ else {
+ if (strncmp(Name,symbol_SKPNAME,symbol_SKLENGTH) == 0 &&
+ string_StringIsNumber(Subname)) {
+ Num = atoi(Subname);
+ if (Num >= symbol_ACTSKOLEMPINDEX)
+ symbol_ACTSKOLEMPINDEX = Num + 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SYMBOL SEARCHING * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+SYMBOL symbol_Lookup(const char* String)
+/**********************************************************
+ INPUT: A pointer to a string.
+ RETURNS: If a symbol with name String exists in the signature, the symbol;
+ 0 otherwise
+********************************************************/
+{
+ if (symbol_SignatureExists()) {
+ int Index;
+ SIGNATURE S;
+
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL && string_Equal(String, S->name))
+ return S->info;
+ }
+ }
+
+ return 0;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SPECIALS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+void symbol_LowerSignature(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: Nothing.
+ EFFECT: Any predicate or function symbol in the signature that
+ starts with a capital letter is prefixed with "ss"
+***************************************************************/
+{
+ int Index;
+ SIGNATURE Entry;
+ SYMBOL Info;
+ char* String;
+
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ Entry = symbol_Signature(Index);
+ if (Entry != NULL) {
+ Info = Entry->info;
+
+ if (symbol_IsPredicate(Info) || symbol_IsFunction(Info)) {
+ String = Entry->name;
+ if ('A' <= String[0] && String[0] <= 'Z') {
+ char* New;
+ New = (char *)memory_Malloc(symbol__SYMBOLMAXLEN);
+ strcpy(&(New[2]),String);
+ New[0] = New[1] = 's'; /* prefix "ss" */
+
+ Entry->name = New;
+ memory_Free(String,symbol__SYMBOLMAXLEN);
+ }
+ }
+ }
+ }
+}
+
+void symbol_Dump(PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A precedence
+ RETURNS: Nothing.
+ EFFECT: Dumps all existing symbols to stdout.
+***************************************************************/
+{
+ if (symbol_SignatureExists()) {
+ int Index;
+ SIGNATURE S;
+ fputs("Dump:", stdout);
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL)
+ printf("\n\t %4d:%4d:%4d:%4d:%4d:%s:%d", Index, S->info, S->weight,
+ Precedence[Index], S->props, S->name, S->length);
+ }
+ }
+}
+
+
+LIST symbol_SortByPrecedence(LIST Symbols, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A list of symbols, and a precedence.
+ RETURNS: The same list where the elements are sorted with
+ respect to decreasing precedence.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ LIST Scan1,Scan2,Min;
+ POINTER Exchange;
+
+ /* We can't use list_Sort, since list_Sort expects an ordering
+ function that receives two arguments. Since symbol_PrecedenceGreater
+ requires three arguments, we have to define our own sorting function.
+ */
+
+ for (Scan1=Symbols; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) {
+ Min = Scan1;
+ for (Scan2 = list_Cdr(Scan1); !list_Empty(Scan2); Scan2 = list_Cdr(Scan2))
+ if (symbol_PrecedenceGreater(Precedence, (SYMBOL) list_Car(Scan2),
+ (SYMBOL) list_Car(Min))) {
+ Exchange = list_Car(Min);
+ list_Rplaca(Min, list_Car(Scan2));
+ list_Rplaca(Scan2, Exchange);
+ }
+ }
+
+ return Symbols;
+}
+
+void symbol_RearrangePrecedence(PRECEDENCE Precedence, LIST UserPrecedence)
+/**************************************************************
+ INPUT: A precedence and a list of symbols in the user
+ specified precedence, sorted in decreasing order.
+ RETURNS: Nothing.
+ EFFECT: Modifies the given precedence to comply with the
+ symbol precedence selected by the user.
+***************************************************************/
+{
+ LIST Scan1, Scan2, Precedences;
+
+ Precedences = list_Nil();
+
+ for (Scan1 = UserPrecedence; !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) {
+ Precedences = list_Cons((POINTER) symbol_Ordering(Precedence, (SYMBOL) list_Car(Scan1)),
+ Precedences);
+ }
+
+ Precedences = list_PointerSort(Precedences);
+
+ Scan1 = UserPrecedence;
+ Scan2 = Precedences;
+
+ while (Scan1 != list_Nil() && Scan2 != list_Nil()) {
+ symbol_SetOrdering(Precedence, (SYMBOL) list_Car(Scan1), (int) list_Car(Scan2));
+ Scan1 = list_Cdr(Scan1);
+ Scan2 = list_Cdr(Scan2);
+ }
+
+ list_Delete(Precedences);
+}
+
+/* unused */
+void symbol_PrintPrecedence(PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A precedence.
+ RETURNS: Nothing.
+ EFFECT: Prints the precedence to stdout.
+***************************************************************/
+{
+ if (symbol_SignatureExists()) {
+ LIST Symbols, Scan;
+ int Index;
+ SIGNATURE S;
+ Symbols = list_Nil();
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL &&
+ (symbol_IsPredicate(S->info) || symbol_IsFunction(S->info)))
+ Symbols = list_Cons((POINTER)S->info, Symbols);
+ }
+ Symbols = symbol_SortByPrecedence(Symbols, Precedence);
+
+ for (Scan = Symbols; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ S = symbol_Signature(symbol_Index((SYMBOL)list_Car(Scan)));
+ fputs(S->name, stdout);
+ if (!list_Empty(list_Cdr(Scan)))
+ fputs(" > ", stdout);
+ }
+ list_Delete(Symbols);
+ }
+}
+
+
+void symbol_FPrintPrecedence(FILE *File, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A file pointer and a precedence.
+ RETURNS: void
+ EFFECT: Prints the current precedence as a setting command
+ in DFG syntax to <File>.
+***************************************************************/
+{
+ if (symbol_SignatureExists()) {
+ LIST Symbols,Scan;
+ int Index;
+ SIGNATURE S;
+
+ Symbols = list_Nil();
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL &&
+ (symbol_IsPredicate(S->info) || symbol_IsFunction(S->info)))
+ Symbols = list_Cons((POINTER)S->info, Symbols);
+ }
+ Symbols = symbol_SortByPrecedence(Symbols, Precedence);
+ Index = 0;
+ fputs("set_precedence(", File);
+ for (Scan = Symbols; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ S = symbol_Signature(symbol_Index((SYMBOL)list_Car(Scan)));
+ fputs(S->name, File);
+ if (!list_Empty(list_Cdr(Scan)))
+ putc(',', File);
+ if (Index > 15) {
+ Index = 0;
+ fputs("\n\t", File);
+ }
+ else
+ Index++;
+ }
+ fputs(").", File);
+ list_Delete(Symbols);
+ }
+}
+
+void symbol_SetCount(SYMBOL Symbol, unsigned long Count)
+/**************************************************************
+ INPUT: A symbol, and a symbol count.
+ RETURNS: Nothing.
+ SUMMARY: Sets the symbol count for the symbol to Count.
+***************************************************************/
+{
+ symbol_COUNT[symbol_Index(Symbol)] = Count;
+}
+
+unsigned long symbol_GetCount(SYMBOL Symbol)
+/**************************************************************
+ INPUT: A symbol.
+ RETURNS: The number of occurences of the symbol in the clause
+ set.
+ SUMMARY: Gets the symbol count for the symbol.
+***************************************************************/
+{
+ return symbol_COUNT[symbol_Index(Symbol)];
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SYMBOL OUTPUT * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+void symbol_Print(SYMBOL Symbol)
+/**************************************************************
+ INPUT: A symbol.
+ RETURNS: Nothing.
+ SUMMARY: Prints a symbol to stdout.
+***************************************************************/
+{
+ symbol_FPrint(stdout, Symbol);
+}
+
+
+void symbol_FPrint(FILE* File, SYMBOL Symbol)
+/**************************************************************
+ INPUT: A file and a symbol.
+ RETURNS: None.
+ SUMMARY: Prints a symbol to the file.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!symbol_IsSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_FPrint: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (symbol_Equal(symbol_Null(),Symbol))
+ fputs("NULL", File);
+ else if (symbol_IsVariable(Symbol)) {
+ SYMBOL NormSymbol;
+
+ NormSymbol = symbol_NormVar(Symbol);
+
+ if (symbol_IsStandardVariable(Symbol)) {
+ if (Symbol <= 6)
+ /* U, V, W, X, Y, Z */
+ sprintf(symbol_VARSTRING,"%c", 'U' + NormSymbol - 1);
+ else
+ /* X1, X2, X3, ... */
+ sprintf(symbol_VARSTRING,"X%d", NormSymbol - 6);
+ }
+ else if (symbol_IsIndexVariable(Symbol))
+ /* I1, I2, I3, ... */
+ sprintf(symbol_VARSTRING,"I%d", NormSymbol);
+
+ fputs(symbol_VARSTRING, File);
+ }
+ else if (symbol_SignatureExists())
+ fputs(symbol_Name(Symbol), File);
+ else
+ fprintf(File, "%d", Symbol);
+}
+
+
+void symbol_FPrintOtter(FILE* File, SYMBOL Symbol)
+/**************************************************************
+ INPUT: A file and a symbol.
+ RETURNS: None.
+ SUMMARY: Prints a symbol in Otter format to stdout.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!symbol_IsSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_FPrintOtter: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (symbol_IsVariable(Symbol)) {
+ SYMBOL NormSymbol;
+
+ NormSymbol = symbol_NormVar(Symbol);
+
+ if (symbol_IsStandardVariable(Symbol)) {
+ if (Symbol <= 6)
+ /* u, v, w, x, y, z */
+ sprintf(symbol_VARSTRING,"%c", 116 + NormSymbol);
+ else
+ /* x1, x2, x3, ... */
+ sprintf(symbol_VARSTRING,"x%d", NormSymbol - 6);
+ }
+ else if (symbol_IsIndexVariable(Symbol))
+ /* I1, I2, I3, ... */
+ sprintf(symbol_VARSTRING,"I%d", NormSymbol);
+
+ fputs(symbol_VARSTRING, File);
+ }
+ else
+ if (symbol_SignatureExists()) {
+ if (symbol_IsConstant(Symbol))
+ fprintf(File, "c%s", symbol_Name(Symbol));
+ else
+ if (symbol_IsFunction(Symbol))
+ fprintf(File, "f%s", symbol_Name(Symbol));
+ else
+ if (symbol_IsPredicate(Symbol))
+ fprintf(File, "P%s", symbol_Name(Symbol));
+ else
+ fputs(symbol_Name(Symbol), File);
+ }
+ else
+ fprintf(File, "%d", Symbol);
+}
+
+
+void symbol_PrintLn(SYMBOL Symbol)
+/**************************************************************
+ INPUT: A symbol.
+ RETURNS: None.
+ SUMMARY: Prints a symbol and a newline to stdout.
+***************************************************************/
+{
+ symbol_Print(Symbol);
+ putchar('\n');
+
+}
+
+
+void symbol_PrintAll(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: None.
+ SUMMARY: Prints all symbols to stdout.
+***************************************************************/
+{
+ const int symbol_TABLEBLANKS = 2;
+ const int symbol_TABLETYPE = 6; /* breadth of the columns */
+ const int symbol_TABLEARITY = 7;
+ const int symbol_TABLESTAT = 6;
+ const int symbol_TABLEPROP = 8;
+ const int symbol_TABLESTRING = 36;
+
+ if (symbol_SignatureExists()) {
+ int Index;
+ SYMBOL Info;
+ SIGNATURE Entry;
+ unsigned int TypePos, ArityPos, StatPos, PropPos, StringPos, EndPos, ActPos;
+
+ TypePos = symbol_TABLEBLANKS;
+ ArityPos = TypePos + symbol_TABLETYPE + 1;
+ StatPos = ArityPos + symbol_TABLEARITY + 1;
+ PropPos = StatPos + symbol_TABLESTAT + 1;
+ StringPos = PropPos + symbol_TABLEPROP + 1;
+ EndPos = StringPos + symbol_TABLESTRING + 1;
+
+ fputs("\n\n", stdout);
+ misc_PrintChar(symbol_TABLEBLANKS, ' '); putchar('+');
+ misc_PrintChar(symbol_TABLETYPE, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLEARITY, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLESTAT, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLEPROP, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLESTRING, '-'); putchar('+'); putchar('\n');
+ misc_PrintChar(symbol_TABLEBLANKS, ' '); putchar('|');
+ ActPos = TypePos + 1 + fputs(" Type", stdout);
+ misc_PrintChar((ArityPos - ActPos), ' '); putchar('|');
+ ActPos = ArityPos + 1 + fputs(" Arity", stdout);
+ misc_PrintChar((StatPos - ActPos), ' '); putchar('|');
+ ActPos = StatPos + 1 + fputs(" Stat", stdout);
+ misc_PrintChar((PropPos - ActPos), ' '); putchar('|');
+ ActPos = PropPos + 1 + fputs(" Prop", stdout);
+ misc_PrintChar((StringPos - ActPos), ' '); putchar('|');
+ ActPos = StringPos + 1 + fputs(" String", stdout);
+ misc_PrintChar((EndPos - ActPos), ' '); putchar('|'); putchar('\n');
+ misc_PrintChar(symbol_TABLEBLANKS, ' '); putchar('+');
+ misc_PrintChar(symbol_TABLETYPE, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLEARITY, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLESTAT, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLEPROP, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLESTRING, '-'); putchar('+'); putchar('\n');
+
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ Entry = symbol_Signature(Index);
+ if (Entry != NULL) {
+ Info = Entry->info;
+
+ misc_PrintChar(symbol_TABLEBLANKS, ' '); putchar('|');
+ ActPos = TypePos + 1;
+
+ switch (symbol_Type(Info)) {
+ case symbol_CONSTANT:
+ ActPos += fputs(" Con", stdout); break;
+ case symbol_FUNCTION:
+ ActPos += fputs(" Fun", stdout); break;
+ case symbol_PREDICATE:
+ ActPos += fputs(" Pre", stdout); break;
+ case symbol_JUNCTOR:
+ ActPos += fputs(" Jun", stdout); break;
+ }
+ misc_PrintChar((ArityPos - ActPos), ' '); putchar('|');
+ ActPos = ArityPos + 1 + printf(" %3d", Entry->arity);
+ misc_PrintChar((StatPos - ActPos), ' '); putchar('|');
+ ActPos = StatPos + 1;
+ if (symbol_Type(Info) == symbol_FUNCTION) {
+ switch (symbol_Stat(Info)) {
+ case symbol_STATLEX:
+ ActPos += fputs(" Lex", stdout); break;
+ case symbol_STATMUL:
+ ActPos += fputs(" Mul", stdout); break;
+ }
+ }
+ misc_PrintChar((PropPos - ActPos), ' '); putchar('|');
+ ActPos = PropPos + 1 + printf(" %u", Entry->props);
+ misc_PrintChar((StringPos - ActPos), ' '); putchar('|');
+ ActPos = StringPos + 1 + printf(" %s", Entry->name);
+ misc_PrintChar((EndPos - ActPos), ' '); putchar('|'); putchar('\n');
+ }
+ }
+ misc_PrintChar(symbol_TABLEBLANKS, ' '); putchar('+');
+ misc_PrintChar(symbol_TABLETYPE, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLEARITY, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLESTAT, '-'); putchar('+');
+ misc_PrintChar(symbol_TABLEPROP, '-'); putchar('|');
+ misc_PrintChar(symbol_TABLESTRING, '-'); putchar('+'); putchar('\n');
+ }
+}
+
diff --git a/test/spass/symbol.h b/test/spass/symbol.h
new file mode 100644
index 0000000..a31f353
--- /dev/null
+++ b/test/spass/symbol.h
@@ -0,0 +1,786 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SYMBOLS * */
+/* * * */
+/* * $Module: SYMBOL * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 35442 $ * */
+/* $State$ * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $ * */
+/* $Author: jeffc $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _SYMBOL_
+#define _SYMBOL_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "list.h"
+#include "stringsx.h"
+
+/**************************************************************/
+/* Data Structures and Constants */
+/**************************************************************/
+
+/* Critical values: the maximum length of a symbol string and the */
+/* maximum number of different variables (in one term, clause) */
+/* CAUTION: symbol__MAXVARIABLES is the overall number of */
+/* variables + 1 to provide safe allocation of contexts */
+/* ... because the first var begins with 1 instead of 0. */
+
+#define symbol__SYMBOLMAXLEN 64
+
+#define symbol__NOOFSTANDARDVAR 2000
+#define symbol__NOOFINDEXVAR 1000
+
+#define symbol__MAXSTANDARDVAR symbol__NOOFSTANDARDVAR
+#define symbol__MAXINDEXVAR (symbol__NOOFSTANDARDVAR + symbol__NOOFINDEXVAR)
+
+#define symbol__NOOFVARIABLES (symbol__NOOFSTANDARDVAR + symbol__NOOFINDEXVAR)
+#define symbol__MAXVARIABLES (symbol__NOOFVARIABLES + 1)
+
+/* Symbol Types, Symbols are represented as integers. In case of */
+/* constants, functions, predicates, junctors, the two least */
+/* significant bits encode the type. Variables are just */
+/* positive integers, all other symbols negative integers */
+/* The third least significant bit encodes the status of */
+/* function symbols (lexicographic or multiset) */
+
+extern const int symbol_MASK;
+extern const int symbol_TYPEMASK;
+extern const int symbol_STATMASK;
+extern const int symbol_TYPESTATMASK;
+
+extern const int symbol_ARBITRARYARITY;
+
+extern const int symbol_TYPEBITS;
+extern const int symbol_STATBITS;
+extern const int symbol_TYPESTATBITS;
+
+extern const int symbol_SIGTYPES;
+
+#define symbol_CONSTANT 0
+#define symbol_FUNCTION 1
+#define symbol_PREDICATE 2
+#define symbol_JUNCTOR 3
+
+#define symbol_STATLEX 0
+#define symbol_STATMUL 1
+
+/* For constants, functions, predicates, junctors, is a special */
+/* symbol table available, containing the arity, status and the */
+/* print name. */
+
+typedef int SYMBOL;
+typedef int *PRECEDENCE;
+
+typedef struct signature {
+ char *name; /* The name of the symbol as a string */
+ NAT length; /* The length of the name. Needed for efficient printing */
+ int weight; /* The weight of the symbol for ordering purposes */
+ int arity; /* The arity of the symbol */
+ NAT props; /* Special Properties of the symbol, e.g. AC, Skolem,... */
+ SYMBOL info; /* 2 LSB denote Type and 3rd LSB denotes status */
+ LIST generatedBy;
+} SIGNATURE_NODE, *SIGNATURE;
+
+typedef enum {SKOLEM=1, CUMMUTATIVE=2, ASSOCIATIVE=4, ORDRIGHT=8, ORDMUL=16,
+ DECLSORT=32, DOMPRED=64, ISDEF=128, FREELY=256, GENERATED=512
+} SPROPERTY;
+
+
+#define symbol__MAXSIGNATURE 4000
+
+extern SIGNATURE *symbol_SIGNATURE;
+
+extern SYMBOL symbol_STANDARDVARCOUNTER;
+extern SYMBOL symbol_INDEXVARCOUNTER;
+
+extern int symbol_ACTINDEX;
+extern int symbol_ACTSKOLEMFINDEX;
+extern int symbol_ACTSKOLEMCINDEX;
+extern int symbol_ACTSKOLEMPINDEX;
+extern int symbol_ACTSKOLEMAINDEX;
+
+/* For matching of signature symbols */
+extern SYMBOL symbol_CONTEXT[symbol__MAXSIGNATURE];
+
+
+/**************************************************************/
+/* Specials */
+/**************************************************************/
+
+NAT symbol_MaxStringLength(void);
+
+void symbol_ReinitGenericNameCounters(void);
+
+int symbol_GetIncreasedOrderingCounter(void);
+
+void symbol_Delete(SYMBOL);
+BOOL symbol_IsSymbol(SYMBOL);
+void symbol_Dump(PRECEDENCE);
+
+LIST symbol_SortByPrecedence(LIST, PRECEDENCE);
+void symbol_RearrangePrecedence(PRECEDENCE, LIST);
+
+void symbol_LowerSignature(void);
+
+LIST symbol_GetAllSymbols(void);
+LIST symbol_GetAllPredicates(void);
+LIST symbol_GetAllFunctions(void);
+
+void symbol_SetCount(SYMBOL, unsigned long);
+unsigned long symbol_GetCount(SYMBOL);
+/**************************************************************/
+/* Symbol Comparisons */
+/**************************************************************/
+
+static __inline__ BOOL symbol_Equal(SYMBOL A, SYMBOL B)
+{
+ return A==B;
+}
+
+static __inline__ BOOL symbol_IsSignature(SYMBOL S)
+{
+ return S < 0;
+}
+
+static __inline__ void symbol_CheckNoVariable(SYMBOL S)
+{
+#ifdef CHECK
+ if (!symbol_IsSignature(S)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_CheckNoVariable: illegal input\n");
+ misc_FinishErrorReport();
+ }
+#endif
+}
+
+static __inline__ int symbol_Type(SYMBOL ActSymbol)
+{
+ symbol_CheckNoVariable(ActSymbol);
+ return (-ActSymbol) & symbol_TYPEMASK;
+}
+
+static __inline__ BOOL symbol_IsJunctor(SYMBOL S)
+{
+ return (symbol_IsSignature(S) && symbol_Type(S) == symbol_JUNCTOR);
+}
+
+static __inline__ BOOL symbol_IsFunction(SYMBOL S)
+{
+ return (symbol_IsSignature(S) &&
+ (symbol_Type(S) == symbol_FUNCTION ||
+ symbol_Type(S) == symbol_CONSTANT));
+}
+
+static __inline__ BOOL symbol_IsConstant(SYMBOL S)
+{
+ return (symbol_IsSignature(S) && symbol_Type(S) == symbol_CONSTANT);
+}
+
+static __inline__ BOOL symbol_IsPredicate(SYMBOL S)
+{
+ return (symbol_IsSignature(S) && symbol_Type(S) == symbol_PREDICATE);
+}
+
+static __inline__ BOOL symbol_IsVariable(SYMBOL S)
+{
+ return S > 0;
+}
+
+static __inline__ BOOL symbol_IsStandardVariable(SYMBOL S)
+{
+ return symbol_IsVariable(S) && (S <= symbol__MAXSTANDARDVAR);
+}
+
+static __inline__ BOOL symbol_IsIndexVariable(SYMBOL S)
+{
+ return (S > symbol__MAXSTANDARDVAR) && (S <= symbol__MAXINDEXVAR);
+}
+
+static __inline__ BOOL symbol_IsComplex(SYMBOL S)
+{
+ return (!symbol_IsVariable(S) && !symbol_IsConstant(S));
+}
+
+static __inline__ BOOL symbol_IsSuccessor(SYMBOL S, SYMBOL P)
+{
+ return S > P;
+}
+
+
+/**************************************************************/
+/* Symbol Manipulation */
+/**************************************************************/
+
+static __inline__ int symbol_GetInitialStandardVarCounter(void)
+{
+ return 0;
+}
+
+static __inline__ int symbol_GetInitialIndexVarCounter(void)
+{
+ return symbol__MAXSTANDARDVAR;
+}
+
+static __inline__ int symbol_FirstIndexVariable(void)
+{
+ return symbol__MAXSTANDARDVAR + 1;
+}
+
+static __inline__ int symbol_LastIndexVariable(void)
+{
+ return symbol_INDEXVARCOUNTER;
+}
+
+/* Special predefined symbols */
+
+#define symbol__NULL 0
+
+static __inline__ int symbol_MaxVars(void)
+{
+ return symbol__MAXVARIABLES;
+}
+
+static __inline__ int symbol_MaxConsts(void)
+{
+ return symbol__MAXSIGNATURE;
+}
+
+static __inline__ int symbol_MaxBaseSorts(void)
+{
+ return symbol__MAXSIGNATURE;
+}
+
+static __inline__ int symbol_TypeBits(void)
+{
+ return symbol_TYPEBITS;
+}
+
+static __inline__ int symbol_Null(void)
+{
+ return 0;
+}
+
+static __inline__ int symbol_ActIndex(void)
+{
+ return symbol_ACTINDEX;
+}
+
+static __inline__ void symbol_ResetSkolemIndex(void)
+{
+ symbol_ACTSKOLEMFINDEX = 0;
+ symbol_ACTSKOLEMCINDEX = 0;
+ symbol_ACTSKOLEMPINDEX = 0;
+ symbol_ACTSKOLEMAINDEX = 0;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * MEMORY MANAGEMENT * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+static __inline__ void symbol_FreeSignature(SIGNATURE Sig)
+/***************************************************************
+ INPUT: A signature datum.
+ RETURNS: void
+ EFFECTS: The datum is deleted and its memory freed.
+****************************************************************/
+{
+ memory_Free(Sig->name, symbol__SYMBOLMAXLEN);
+ list_Delete(Sig->generatedBy);
+ memory_Free(Sig, sizeof(SIGNATURE_NODE));
+}
+
+static __inline__ SIGNATURE symbol_GetSignature(void)
+{
+ return (SIGNATURE) memory_Malloc(sizeof(SIGNATURE_NODE));
+}
+
+
+/**************************************************************/
+/* Symbol Creation */
+/**************************************************************/
+
+static __inline__ SYMBOL symbol_CreateStandardVariable(void)
+/***************************************************************
+ INPUT: None
+ RETURNS: A new symbol for a new standard variable numbered according to
+ symbol_STANDARDVARCOUNTER
+ SUMMARY: Creates a new standard variable symbol.
+ EFFECTS: None
+****************************************************************/
+{
+#ifdef CHECK
+ if (symbol_STANDARDVARCOUNTER >= symbol__MAXSTANDARDVAR) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_CreateStandardVariable: Number of standard variables exceeded.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return (++symbol_STANDARDVARCOUNTER);
+}
+
+
+static __inline__ SYMBOL symbol_CreateIndexVariable(void)
+/***************************************************************
+ INPUT: None
+ RETURNS: A new symbol for a new index variable numbered according to
+ symbol_INDEXVARCOUNTER
+ SUMMARY: Creates a new index variable symbol.
+ EFFECTS: None
+****************************************************************/
+{
+#ifdef CHECK
+ if (symbol_INDEXVARCOUNTER >= symbol__MAXINDEXVAR) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_CreateIndexVariable: Number of index variables exceeded.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return (++symbol_INDEXVARCOUNTER);
+}
+
+
+static __inline__ SYMBOL symbol_NextIndexVariable(SYMBOL Variable)
+{
+#ifdef CHECK
+ if ((Variable != symbol_GetInitialIndexVarCounter() &&
+ !symbol_IsIndexVariable(Variable)) ||
+ Variable == symbol__MAXINDEXVAR) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_NextVariable: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return (Variable + 1);
+}
+
+
+static __inline__ void symbol_SetStandardVarCounter(SYMBOL Variable)
+{
+#ifdef CHECK
+ if (Variable != symbol_GetInitialStandardVarCounter() &&
+ !symbol_IsStandardVariable(Variable)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_SetStandardVarCounter: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+ else
+ if (Variable >= symbol__MAXSTANDARDVAR) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_SetStandardVarCounter: Number of standard variables exceeded.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ symbol_STANDARDVARCOUNTER = Variable;
+}
+
+static __inline__ SYMBOL symbol_FirstVariable(void)
+{
+ return 1;
+}
+
+static __inline__ BOOL symbol_GreaterVariable(SYMBOL Var1, SYMBOL Var2)
+{
+ return Var1 > Var2;
+}
+
+static __inline__ void symbol_ResetStandardVarCounter(void)
+{
+ symbol_STANDARDVARCOUNTER = symbol_GetInitialStandardVarCounter();
+}
+
+void symbol_Init(BOOL);
+BOOL symbol_SignatureExists(void);
+void symbol_FreeAllSymbols(void);
+SYMBOL symbol_CreateFunction(const char*, int, int, PRECEDENCE);
+SYMBOL symbol_CreateSkolemFunction(int, PRECEDENCE);
+SYMBOL symbol_CreateSkolemPredicate(int, PRECEDENCE);
+SYMBOL symbol_CreatePredicate(const char*, int, int, PRECEDENCE);
+SYMBOL symbol_CreateJunctor(const char*, int, int, PRECEDENCE);
+
+/**************************************************************/
+/* Symbol Access */
+/**************************************************************/
+
+SYMBOL symbol_Lookup(const char*);
+
+static __inline__ int symbol_VarIndex(SYMBOL ActSymbol)
+{
+ return ActSymbol;
+}
+
+static __inline__ int symbol_NormVar(SYMBOL ActSymbol)
+{
+ /* Normalization of variables s.t. the index of the variable
+ is normalized starting always with 1:
+ Standard variables are already normalized.
+ Index variables are decreased by the number of the
+ underlying standard variables. */
+ return (ActSymbol <= symbol__MAXSTANDARDVAR) ? ActSymbol : (ActSymbol - symbol__MAXSTANDARDVAR);
+}
+
+/* The name, index and arity macros are only defined for signature */
+/* elements not for variables. The type of the symbol is not checked */
+/* by the macros. */
+
+static __inline__ int symbol_Index(SYMBOL ActSymbol)
+{
+ symbol_CheckNoVariable(ActSymbol);
+ return (-ActSymbol) >> symbol_TYPESTATBITS;
+}
+
+static __inline__ void symbol_CheckIndexInRange(int Index)
+{
+#ifdef CHECK
+ if (Index < 0 || Index >= symbol__MAXSIGNATURE) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_CheckIndexInRange: Symbol index is out of range.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+}
+
+static __inline__ SYMBOL symbol_SignatureSymbol(int ActIndex, int Type, int Status)
+{
+ return -((ActIndex << symbol_TYPESTATBITS)
+ | (Status << symbol_TYPEBITS)
+ | Type);
+}
+
+static __inline__ SIGNATURE symbol_Signature(int Index)
+ /* Returns the signature of the symbol with <Index> or NULL */
+ /* if the symbol was deleted */
+{
+ symbol_CheckIndexInRange(Index);
+ return symbol_SIGNATURE[Index];
+}
+
+static __inline__ void symbol_SetSignature(int ActIndex, SIGNATURE Sig)
+{
+ symbol_CheckIndexInRange(ActIndex);
+ symbol_SIGNATURE[ActIndex] = Sig;
+}
+
+static __inline__ SYMBOL symbol_GetSigSymbol(int Index)
+{
+ return symbol_Signature(Index)->info;
+}
+
+static __inline__ int symbol_Stat(SYMBOL ActSymbol)
+{
+ symbol_CheckNoVariable(ActSymbol);
+ return ((-ActSymbol) & symbol_STATMASK) >> symbol_TYPEBITS;
+}
+
+static __inline__ SYMBOL symbol_ChangeType(SYMBOL S, int Type)
+/**************************************************************
+ INPUT: A symbol and a new type for that symbols.
+ RETURNS: A new symbol that is the old symbol with type changed to <Type>,
+ therefore the return value is different from <S>.
+ EFFECT: Uses the signature memory of the input symbol.
+ CAUTION: Usage only allowed by the parsing modules!!!
+***************************************************************/
+{
+ SIGNATURE Sig;
+ symbol_CheckNoVariable(S);
+ Sig = symbol_Signature(symbol_Index(S));
+ S = symbol_SignatureSymbol(symbol_Index(S), Type, symbol_Stat(S));
+ Sig->info = S;
+ return S;
+}
+
+static __inline__ int symbol_Arity(SYMBOL ActSymbol)
+{
+ return symbol_Signature(symbol_Index(ActSymbol))->arity;
+}
+
+static __inline__ NAT symbol_PositiveArity(SYMBOL ActSymbol)
+{
+ int arity = symbol_Arity(ActSymbol);
+ if (arity < 0)
+ return NAT_MAX;
+ else
+ return arity;
+}
+
+static __inline__ void symbol_SetArity(SYMBOL ActSymbol, int Arity)
+{
+ symbol_Signature(symbol_Index(ActSymbol))->arity = Arity;
+}
+
+static __inline__ int symbol_ArbitraryArity(void)
+{
+ return -1;
+}
+
+static __inline__ char* symbol_Name(SYMBOL ActSymbol)
+{
+ return symbol_Signature(symbol_Index(ActSymbol))->name;
+}
+
+static __inline__ NAT symbol_NameLength(SYMBOL ActSymbol)
+{
+ return symbol_Signature(symbol_Index(ActSymbol))->length;
+}
+
+static __inline__ int symbol_Info(SYMBOL ActSymbol)
+{
+ return symbol_Signature(symbol_Index(ActSymbol))->info;
+}
+
+static __inline__ int symbol_Weight(SYMBOL ActSymbol)
+{
+ return symbol_Signature(symbol_Index(ActSymbol))->weight;
+}
+
+static __inline__ int symbol_Ordering(PRECEDENCE P, SYMBOL ActSymbol)
+{
+ int Index;
+
+ Index = symbol_Index(ActSymbol);
+#ifdef CHECK
+ symbol_CheckIndexInRange(Index);
+ if (P[Index] < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In symbol_Ordering: Ordering of symbol %s is invalid\n",
+ symbol_Name(ActSymbol));
+ misc_FinishErrorReport();
+ }
+#endif
+ return P[Index];
+}
+
+static __inline__ void symbol_SetWeight(SYMBOL ActSymbol, int Weight)
+{
+ symbol_Signature(symbol_Index(ActSymbol))->weight = Weight;
+}
+
+static __inline__ void symbol_SetName(SYMBOL ActSymbol, char* Name)
+{
+ symbol_Signature(symbol_Index(ActSymbol))->name = Name;
+}
+
+static __inline__ LIST symbol_GeneratedBy(SYMBOL S)
+{
+ return symbol_Signature(symbol_Index(S))->generatedBy;
+}
+
+static __inline__ BOOL symbol_IsGeneratedBy(SYMBOL S1, SYMBOL S2)
+{
+ return list_PointerMember(symbol_GeneratedBy(S1), (POINTER)S2);
+}
+
+static __inline__ void symbol_SetGeneratedBy(SYMBOL S, LIST SymbolList)
+{
+ symbol_Signature(symbol_Index(S))->generatedBy = SymbolList;
+}
+
+static __inline__ void symbol_SetOrdering(PRECEDENCE P, SYMBOL ActSymbol,
+ int Ordering)
+{
+ int Index;
+
+ Index = symbol_Index(ActSymbol);
+ symbol_CheckIndexInRange(Index);
+ P[Index] = Ordering;
+}
+
+static __inline__ void symbol_SetIncreasedOrdering(PRECEDENCE P, SYMBOL S)
+{
+ symbol_SetOrdering(P, S, symbol_GetIncreasedOrderingCounter());
+}
+
+
+static __inline__ BOOL symbol_PrecedenceGreater(PRECEDENCE P, SYMBOL S1, SYMBOL S2)
+{
+ return symbol_Ordering(P, S1) < symbol_Ordering(P, S2);
+}
+
+static __inline__ BOOL symbol_HasProperty(SYMBOL ActSymbol, SPROPERTY Property)
+{
+ return (symbol_Signature(symbol_Index(ActSymbol))->props & Property);
+}
+
+static __inline__ void symbol_AddProperty(SYMBOL ActSymbol, SPROPERTY Property)
+{
+ SIGNATURE S = symbol_Signature(symbol_Index(ActSymbol));
+ S->props = S->props | Property;
+}
+
+static __inline__ void symbol_RemoveProperty(SYMBOL ActSymbol, SPROPERTY Property)
+{
+ SIGNATURE S = symbol_Signature(symbol_Index(ActSymbol));
+ if (S->props & Property)
+ S->props = S->props - Property;
+}
+
+static __inline__ BOOL symbol_IsBaseSort(SYMBOL Symbol)
+{
+ return (symbol_Arity(Symbol) == 1);
+}
+
+static __inline__ void symbol_ClearPrecedence(PRECEDENCE P)
+{
+ int i;
+ const int clear = -42; /* Some negative number */
+
+ for (i = 0; i < symbol__MAXSIGNATURE; i++)
+ P[i] = clear;
+}
+
+static __inline__ PRECEDENCE symbol_CreatePrecedence(void)
+{
+ PRECEDENCE P;
+
+ P = memory_Malloc(sizeof(int[symbol__MAXSIGNATURE]));
+ symbol_ClearPrecedence(P);
+ return P;
+}
+
+static __inline__ void symbol_DeletePrecedence(PRECEDENCE P)
+{
+ memory_Free(P, sizeof(int[symbol__MAXSIGNATURE]));
+}
+
+static __inline__ void symbol_TransferPrecedence(PRECEDENCE Source,
+ PRECEDENCE Target)
+ /* Copy settings from one precedence object to another */
+{
+ int i;
+
+ for (i = 0; i < symbol__MAXSIGNATURE; i++)
+ Target[i] = Source[i];
+}
+
+static __inline__ LIST symbol_DeleteSymbolFromList(LIST Symbols, SYMBOL S)
+ /* Deletes all occurrences of <S> from the list */
+{
+ return list_DeleteElement(Symbols, (POINTER) S,
+ (BOOL (*)(POINTER, POINTER)) symbol_Equal);
+}
+
+static __inline__ void symbol_DeleteSymbolList(LIST Symbols)
+ /* The list AND the symbols within are deleted */
+{
+ list_DeleteWithElement(Symbols, (void (*)(POINTER))symbol_Delete);
+}
+
+/**************************************************************/
+/* Symbol CONTEXT */
+/**************************************************************/
+
+static __inline__ BOOL symbol_ContextIsClean(void)
+{
+ int i;
+ for (i = 0; i < symbol__MAXSIGNATURE; i++)
+ if (symbol_CONTEXT[i] != (SYMBOL)0)
+ return FALSE;
+ return TRUE;
+}
+
+static __inline__ void symbol_ContextClean(void)
+{
+ int i;
+ for (i = 0; i < symbol__MAXSIGNATURE; i++)
+ symbol_CONTEXT[i] = (SYMBOL)0;
+}
+
+static __inline__ BOOL symbol_ContextIsMapped(SYMBOL Symbol)
+{
+ int i;
+ for (i = 0; i < symbol__MAXSIGNATURE; i++)
+ if (symbol_Equal(symbol_CONTEXT[i],Symbol))
+ return TRUE;
+ return FALSE;
+}
+
+static __inline__ SYMBOL symbol_ContextGetValue(SYMBOL Symbol)
+{
+ int Index;
+
+ Index = symbol_Index(Symbol);
+ symbol_CheckIndexInRange(Index);
+ return symbol_CONTEXT[Index];
+}
+
+static __inline__ void symbol_ContextSetValue(SYMBOL Symbol, SYMBOL Value)
+{
+ int Index;
+
+ Index = symbol_Index(Symbol);
+ symbol_CheckIndexInRange(Index);
+ symbol_CONTEXT[Index] = Value;
+}
+
+static __inline__ void symbol_ContextClearValue(SYMBOL Symbol)
+{
+ symbol_ContextSetValue(Symbol, (SYMBOL)0);
+}
+
+static __inline__ BOOL symbol_ContextIsBound(SYMBOL Symbol)
+{
+ return (symbol_ContextGetValue(Symbol) != (SYMBOL)0);
+}
+
+/**************************************************************/
+/* Symbol Output */
+/**************************************************************/
+
+void symbol_Print(SYMBOL);
+void symbol_PrintPrecedence(PRECEDENCE);
+void symbol_FPrintPrecedence(FILE*, PRECEDENCE);
+void symbol_FPrint(FILE*, SYMBOL);
+void symbol_FPrintOtter(FILE*, SYMBOL);
+void symbol_PrintLn(SYMBOL);
+void symbol_PrintAll(void);
+
+#endif
diff --git a/test/spass/table.c b/test/spass/table.c
new file mode 100644
index 0000000..639dbfd
--- /dev/null
+++ b/test/spass/table.c
@@ -0,0 +1,553 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SIGNATURE TABLE * */
+/* * * */
+/* * $Module: TABLE * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "table.h"
+
+
+/**************************************************************/
+/* Inline functions */
+/**************************************************************/
+
+static __inline__ int table_Index(SYMBOL symbol)
+{
+ if (symbol_IsVariable(symbol))
+ return -(int) symbol;
+ else
+ return symbol_Index(symbol);
+}
+
+
+static __inline__ TERM table_GetTerm(TERMARRAY ta)
+{
+ return ta->term;
+}
+
+
+static __inline__ TERMARRAY table_SetTerm(TERMARRAY ta, TERM term)
+{
+ ta->term = term;
+ return ta;
+}
+
+
+static __inline__ int table_GetStamp(TERMARRAY ta)
+{
+ return ta->stamp;
+}
+
+
+static __inline__ TERMARRAY table_SetStamp(TERMARRAY ta, int stamp)
+{
+ ta->stamp = stamp;
+ return ta;
+}
+
+
+static __inline__ TERMARRAY table_GetChild(TERMARRAY ta)
+{
+ return ta->child;
+}
+
+
+static __inline__ TERMARRAY table_SetChild(TERMARRAY ta, TERMARRAY child)
+{
+ ta->child = child;
+ return ta;
+}
+
+
+static __inline__ TERMARRAY table_GetTermarray(TABLE table)
+{
+ return table->ta;
+}
+
+
+static __inline__ TABLE table_SetTermarray(TABLE table, TERMARRAY ta)
+{
+ table->ta = ta;
+ return table;
+}
+
+
+static __inline__ TERMARRAY *table_GetPoss(TABLE table)
+{
+ return table->pos;
+}
+
+
+static __inline__ TERMARRAY table_GetPos(TABLE table, int index)
+{
+ return table_GetPoss(table)[index];
+}
+
+
+static __inline__ TABLE table_SetPoss(TABLE table, TERMARRAY *ref)
+{
+ table->pos = ref;
+ return table;
+}
+
+
+static __inline__ TABLE table_SetPos(TABLE table, int index, TERMARRAY ta)
+{
+ table_GetPoss(table)[index] = ta;
+ return table;
+}
+
+
+static __inline__ int *table_GetPosstamps(TABLE table)
+{
+ return table->posstamp;
+}
+
+
+static __inline__ int table_GetPosstamp(TABLE table, int index)
+{
+ return table_GetPosstamps(table)[index];
+}
+
+
+static __inline__ TABLE table_SetPosstamps(TABLE table, int *ref)
+{
+ table->posstamp = ref;
+ return table;
+}
+
+
+static __inline__ TABLE table_SetPosstamp(TABLE table, int index, int stamp)
+{
+ table_GetPosstamps(table)[index] = stamp;
+ return table;
+}
+
+
+static __inline__ int table_GetStampcounter(TABLE table)
+{
+ return table->stampcounter;
+}
+
+
+static __inline__ TABLE table_SetStampcounter(TABLE table, int stampcounter)
+{
+ table->stampcounter = stampcounter;
+ return table;
+}
+
+
+static __inline__ int table_GetOpbound(TABLE table)
+{
+ return table->opbound;
+}
+
+
+static __inline__ TABLE table_SetOpbound(TABLE table, int opbound)
+{
+ table->opbound = opbound;
+ return table;
+}
+
+
+static __inline__ int table_GetVarbound(TABLE table)
+{
+ return table->varbound;
+}
+
+
+static __inline__ TABLE table_SetVarbound(TABLE table, int varbound)
+{
+ table->varbound = varbound;
+ return table;
+}
+
+
+static __inline__ int table_GetTermbound(TABLE table)
+{
+ return table->termbound;
+}
+
+
+static __inline__ TABLE table_SetTermbound(TABLE table, int termbound)
+{
+ table->termbound = termbound;
+ return table;
+}
+
+
+static __inline__ BOOL table_LegalPosIndex(TABLE table, int index)
+{
+ return 0 <= index && index <= table_GetTermbound(table);
+}
+
+
+static __inline__ BOOL table_Stamped(TABLE table, TERMARRAY ta)
+{
+ return table_GetStamp(ta) == table_GetStampcounter(table);
+}
+
+
+static __inline__ TERMARRAY table_DelayedInit(TABLE table, TERMARRAY ta)
+/***************************************************************
+ INPUT: a table and a termarray
+ RETURNS: the (now stamped) termarray
+ EFFECT: partially initializes table by setting the
+ termarray's entry to the empty term
+***************************************************************/
+{
+ if (!table_Stamped(table, ta)) {
+ table_SetTerm(ta, term_Null());
+ table_SetStamp(ta, table_GetStampcounter(table));
+ }
+ return ta;
+}
+
+
+static __inline__ BOOL table_PosStamped(TABLE table, int index)
+{
+ return table_GetPosstamp(table, index) == table_GetStampcounter(table);
+}
+
+
+static __inline__ int table_DelayedPosInit(TABLE table, int index)
+/***************************************************************
+ INPUT: a table and a position index
+ RETURNS: the (now stamped) position index
+ EFFECT: partially initializes table by setting the indexed
+ position to the empty pointer, which means that the
+ term with this index is not stored in table
+***************************************************************/
+{
+ if (!table_PosStamped(table, index)) {
+ table_SetPos(table, index, (TERMARRAY) NULL);
+ table_SetPosstamp(table, index, table_GetStampcounter(table));
+ }
+ return index;
+}
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+TABLE table_Null(void)
+{
+ return (TABLE) NULL;
+}
+
+
+TABLE table_Create(int opbound, int varbound, int termbound)
+/***************************************************************
+ INPUT: bounds for the operator symbol, variable and term
+ indices of the terms to be stored in the signature
+ table (i. e. for every such term its top symbol index
+ has to be in [1, opbound] and the term numbers of its
+ arguments in [0, termbound] - or its variable index
+ in [1, varbound] if it is a variable)
+ RETURNS: a new (and empty) signature table
+***************************************************************/
+{
+ TABLE result;
+
+#ifdef CHECK
+ if (opbound < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_Create: negative opbound.");
+ misc_FinishErrorReport();
+ }
+ if (varbound < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_Create: negative varbound.");
+ misc_FinishErrorReport();
+ }
+ if (termbound < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_Create: negative termbound.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = (TABLE) memory_Malloc(sizeof(struct table));
+ table_SetTermarray(result, (TERMARRAY) memory_Calloc (
+ opbound + varbound + 1,
+ sizeof(struct termarray)
+ ) + varbound);
+ /* move pointer to the middle of the array to allow negative indices */
+ table_SetPoss(
+ result,
+ (TERMARRAY*) memory_Malloc((termbound + 1) * sizeof(TERMARRAY))
+ );
+ table_SetPosstamps(result, (int*) memory_Calloc(termbound + 1, sizeof(int)));
+ table_SetOpbound(result, opbound);
+ table_SetVarbound(result, varbound);
+ table_SetTermbound(result, termbound);
+ table_SetStampcounter(result, 1);
+ return result;
+}
+
+
+static void table_FreeTermarray(TERMARRAY ta, int size)
+/***************************************************************
+ INPUT: the termarray to free and its size
+ EFFECT: recursively frees the tree structure allocated for the
+ signature array
+***************************************************************/
+{
+ int i;
+
+ if (ta) {
+ for (i = 0; i < size; i++)
+ table_FreeTermarray(table_GetChild(ta + i), size);
+ memory_Free(ta, size * sizeof(struct termarray));
+ }
+}
+
+
+void table_Free(TABLE table)
+{
+ int i;
+
+ if (table != table_Null()) {
+ for (i = -table_GetVarbound(table); i <= table_GetOpbound(table); i++)
+ table_FreeTermarray(
+ table_GetChild(table_GetTermarray(table) + i),
+ table_GetTermbound(table) + 1
+ );
+ memory_Free(
+ table_GetTermarray(table) - table_GetVarbound(table),
+ (table_GetOpbound(table) + table_GetVarbound(table) + 1) * sizeof(struct
+ termarray)
+ );
+ memory_Free(
+ table_GetPoss(table),
+ (table_GetTermbound(table) + 1) * sizeof(TERMARRAY)
+ );
+ memory_Free(
+ table_GetPosstamps(table),
+ (table_GetTermbound(table) + 1) * sizeof(int)
+ );
+ memory_Free(table, sizeof(struct table));
+ }
+}
+
+
+TABLE table_Init(TABLE table, int opbound, int varbound, int termbound)
+/***************************************************************
+ INPUT: the table to recycle and bounds for the operator
+ symbol, variable and term indices of the terms to be
+ stored in the signature table (i. e. for every such
+ term its top symbol index has to be in [1, opbound]
+ and the term numbers of its arguments in
+ [0, termbound] - or its variable index in
+ [1, varbound] if it is a variable)
+ RETURNS: a cleaned up signature table
+ CAUTION: potentially frees the old table, therefore must be
+ called inside of an assignment like:
+ table = table_Init(table, ...)
+***************************************************************/
+{
+ int opmax, varmax, termmax, i;
+ TERMARRAY old;
+
+#ifdef CHECK
+ if (opbound < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_Init: negative opbound.");
+ misc_FinishErrorReport();
+ }
+ if (varbound < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_Init: negative varbound.");
+ misc_FinishErrorReport();
+ }
+ if (termbound < 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_Init: negative termbound.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ opmax = table_GetOpbound(table) > opbound ? table_GetOpbound(table) :
+ opbound;
+ varmax = table_GetVarbound(table) > varbound ? table_GetVarbound(table) :
+ varbound;
+ termmax = table_GetTermbound(table) > termbound ? table_GetTermbound(table) :
+ termbound;
+ table_SetStampcounter(table, table_GetStampcounter(table) + 1);
+
+ /* in case of stamp overflow or too small termarray nodes get a new table: */
+ if (table_GetStampcounter(table)<=0 || termbound>table_GetTermbound(table)) {
+ table_Free(table);
+ return table_Create(opmax, varmax, termmax);
+ }
+
+ /* if only the top layer of the tree is too small get a larger top layer: */
+ else if (opbound+varbound > table_GetOpbound(table)+table_GetVarbound(table)){
+ old = table_GetTermarray(table);
+ table_SetTermarray(table, (TERMARRAY) memory_Calloc(
+ opmax + varmax + 1,
+ sizeof(struct termarray)
+ ) + varmax);
+ for (i = -table_GetVarbound(table); i <= table_GetOpbound(table); i++)
+ table_SetChild(table_GetTermarray(table) + i, table_GetChild(old + i));
+ memory_Free(
+ old - table_GetVarbound(table),
+ (table_GetOpbound(table) + table_GetVarbound(table) + 1) * sizeof(struct
+ termarray)
+ );
+ table_SetOpbound(table, opmax);
+ table_SetVarbound(table, varmax);
+ return table;
+ }
+
+ else {
+
+ /* move pointer to termarray's new middle: */
+ table_SetTermarray(
+ table,
+ table_GetTermarray(table) + table_GetOpbound(table) - opbound
+ );
+
+ table_SetVarbound(
+ table,
+ table_GetOpbound(table) + table_GetVarbound(table) - opbound
+ );
+ table_SetOpbound(table, opbound);
+ return table;
+ }
+}
+
+
+TERM table_QueryAndEnter(TABLE table, PARTITION p, TERM term)
+/***************************************************************
+ RETURNS: a term with the same p-signature (sigtab_Index(top
+ symbol), [arg 1] , ..., [arg n] ) as term - or the
+ p p
+ empty term if no such term exists
+ EFFECT: term enters table in the latter case
+***************************************************************/
+{
+ TERMARRAY ta;
+ LIST terms;
+
+#ifdef CHECK
+ if (part_Size(p) - 1 > table_GetTermbound(table)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_QueryAndEnter: partition not suitable.");
+ misc_FinishErrorReport();
+ }
+ if (table_Index(term_TopSymbol(term)) > table_GetOpbound(table)) {
+ misc_StartErrorReport();
+ misc_ErrorReport
+ ("\n In table_QueryAndEnter: term's operation symbol out of bounds.");
+ misc_FinishErrorReport();
+ }
+ if (table_Index(term_TopSymbol(term)) < -table_GetVarbound(table)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_QueryAndEnter: variable out of bounds.");
+ misc_FinishErrorReport();
+ }
+ if (!table_LegalPosIndex(table, term_Size(term))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_QueryAndEnter: term out of bounds.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ ta = table_GetTermarray(table) + table_Index(term_TopSymbol(term));
+ for (terms = term_ArgumentList(term); !list_Empty(terms); terms =
+ list_Cdr(terms)) {
+ if (!table_GetChild(ta))
+ table_SetChild(ta, (TERMARRAY) memory_Calloc (
+ table_GetTermbound(table) + 1,
+ sizeof(struct termarray)
+ ));
+ ta = table_GetChild(ta) + part_Find(p, term_Size(list_Car(terms)));
+ }
+ table_DelayedInit(table, ta);
+ if (table_GetTerm(ta))
+ return table_GetTerm(ta);
+ else {
+ table_SetTerm(ta, term);
+ table_SetPos(table, table_DelayedPosInit(table, term_Size(term)), ta);
+ return term_Null();
+ }
+}
+
+
+TABLE table_Delete(TABLE table, TERM term)
+/***************************************************************
+ EFFECT: if term has entered table before, it is deleted
+***************************************************************/
+{
+ int no;
+
+#ifdef CHECK
+ if (!table_LegalPosIndex(table, term_Size(term))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_Delete: illegal table access.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ no = term_Size(term);
+ table_DelayedPosInit(table, no);
+ if (table_GetPos(table, no)) {
+
+#ifdef CHECK
+ if (!table_Stamped(table, table_GetPos(table, no))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In table_Delete: table corrupted.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ table_SetTerm(table_GetPos(table, no), term_Null());
+ table_SetPos(table, no, (TERMARRAY) NULL);
+ }
+ return table;
+}
+
diff --git a/test/spass/table.h b/test/spass/table.h
new file mode 100644
index 0000000..e0024a4
--- /dev/null
+++ b/test/spass/table.h
@@ -0,0 +1,101 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * SIGNATURE TABLE * */
+/* * * */
+/* * $Module: TABLE * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* module manages signature tables i. e. tables of terms (including the empty */
+/* term NULL) where the lookup key is the tuple of top symbol index and */
+/* arguments' equivalence classes with respect to a partition p, the */
+/* _p-signature_ (sigtab_Index(top symbol), [arg 1] , ..., [arg n] ) */
+/* p p */
+
+#ifndef _TABLE_
+#define _TABLE_
+
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "term.h"
+#include "partition.h"
+
+
+/**************************************************************/
+/* Basic types */
+/**************************************************************/
+
+typedef struct termarray {
+ TERM term;
+ int stamp;
+ struct termarray *child;
+} *TERMARRAY;
+
+typedef struct table {
+ TERMARRAY ta, *pos;
+ int *posstamp, stampcounter, opbound, varbound, termbound;
+}
+*TABLE;
+
+/* a signature table is an "array of terms allocated by need" (i. e. a tree */
+/* where the nodes of the same layer represent array entries with the same */
+/* dimension), an array of positions in this "array", stamps for the */
+/* positions, the stamp counter and bounds for the operator symbol, variable */
+/* and term indices of the terms to be stored in the signature table (i. e. */
+/* for every such term its top symbol index has to be in [1, opbound] and the */
+/* term numbers of its arguments in [0, termbound] - or its variable index in */
+/* [1, varbound] if it is a variable) */
+
+
+/**************************************************************/
+/* Prototypes */
+/**************************************************************/
+
+TABLE table_Null(void);
+TABLE table_Create(int, int, int);
+void table_Free(TABLE);
+TABLE table_Init(TABLE, int, int, int);
+TERM table_QueryAndEnter(TABLE, PARTITION, TERM);
+TABLE table_Delete(TABLE, TERM);
+
+
+#endif
+
diff --git a/test/spass/tableau.c b/test/spass/tableau.c
new file mode 100644
index 0000000..5b1ab8a
--- /dev/null
+++ b/test/spass/tableau.c
@@ -0,0 +1,880 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * TABLEAU PROOF TREES * */
+/* * * */
+/* * Copyright (C) 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+
+/* $RCSfile$ */
+
+#include "tableau.h"
+
+/* for graph output */
+extern BOOL pcheck_ClauseCg;
+extern GRAPHFORMAT pcheck_GraphFormat;
+
+TABPATH tab_PathCreate(int MaxLevel, TABLEAU Tab)
+/**************************************************************
+ INPUT: A tableau, its maximum expected depth
+ RETURNS: A path consisting of the root node of the tableau
+ which can have a max length of <MaxLevel>
+***************************************************************/
+{
+ TABPATH TabPath;
+
+ TabPath = (TABPATH)memory_Malloc(sizeof(TABPATH_NODE));
+ TabPath->Path = (TABLEAU*)memory_Malloc(sizeof(TABLEAU)*(MaxLevel+1));
+ TabPath->Path[0] = Tab;
+ TabPath->MaxLength = MaxLevel;
+ TabPath->Length = 0;
+
+ return TabPath;
+}
+
+void tab_PathDelete(TABPATH TabPath)
+/**************************************************************
+ INPUT: A tableau path.
+ RETURNS: Nothing.
+ EFFECTS: The path is deleted.
+***************************************************************/
+{
+ memory_Free(TabPath->Path, (TabPath->MaxLength+1)*sizeof(TABLEAU));
+ memory_Free(TabPath, sizeof(TABPATH_NODE));
+}
+
+
+BOOL tab_PathContainsClause(TABPATH Path, CLAUSE Clause)
+/**************************************************************
+ INPUT: A tableau path, a clause
+ RETURNS: TRUE iff the clause exists on its level (wrt. the
+ path) in the tableau
+***************************************************************/
+{
+ LIST Scan;
+
+ if (clause_SplitLevel(Clause) > tab_PathLength(Path))
+ return FALSE;
+
+ for (Scan = tab_Clauses(tab_PathNthNode(Path, clause_SplitLevel(Clause)));
+ !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (list_Car(Scan) == Clause)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static BOOL tab_PathContainsClauseSoft(TABPATH Path, CLAUSE Clause)
+/**************************************************************
+ INPUT: A tableau path, a clause
+ RETURNS: TRUE iff the clause is on one of the levels
+ in the tableau traversed by the path. Different
+ from tab_PathContainsClauseSoft, since it does
+ not expect the clause on its split level.
+***************************************************************/
+{
+ LIST Scan;
+ int Level;
+
+ if (clause_SplitLevel(Clause) > tab_PathLength(Path))
+ return FALSE;
+
+ for (Level = 0; Level <= tab_PathLength(Path); Level++) {
+ for (Scan = tab_Clauses(tab_PathNthNode(Path, Level));
+ !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (list_Car(Scan) == Clause)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* unused */
+/*static*/ BOOL tab_PathContainsClauseRobust(TABPATH P, CLAUSE C)
+/**************************************************************
+ INPUT: A tableau path, a clause
+ RETURNS: TRUE if clause can be find on the path (not
+ necessarily on its level)
+ EFFECTS: Prints a note if clause cannot be found on
+ its level. Intended for debugging.
+***************************************************************/
+{
+ if (tab_PathContainsClause(P,C))
+ return TRUE;
+
+ if (tab_PathContainsClauseSoft(P,C)) {
+ fputs("NOTE: Clause is found on path, but not indexed by level.\n", stderr);
+ clause_PParentsFPrint(stderr,C);
+ fflush(stderr);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void tab_AddSplitAtCursor(TABPATH Path, BOOL LeftSide)
+/**************************************************************
+ INPUT: A tableau path, a flag
+ RETURNS: Nothing.
+ EFFECTS: Extends the tableau containing the path <Path> to
+ the left if <LeftSide> is TRUE, to the right
+ otherwise
+***************************************************************/
+{
+ TABLEAU Tab, NewBranch;
+
+ Tab = tab_PathTop(Path);
+ NewBranch = tab_CreateNode();
+ if (LeftSide) {
+
+#ifdef CHECK
+ if (!tab_LeftBranchIsEmpty(Tab)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In tab_AddSplitAtCursor: Recreating existing");
+ misc_ErrorReport(" left branch in tableau.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ tab_SetLeftBranch(Tab,NewBranch);
+ } else {
+
+#ifdef CHECK
+ if (!tab_RightBranchIsEmpty(Tab)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In tab_AddSplitAtCursor: Recreating existing");
+ misc_ErrorReport(" right branch in tableau.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+ tab_SetRightBranch(Tab, NewBranch);
+ }
+ tab_PathPush(NewBranch, Path);
+}
+
+void tab_AddClauseOnItsLevel(CLAUSE C, TABPATH Path)
+/**************************************************************
+ INPUT: A clause, a tableau path
+ RETURNS: Nothing
+ EFFECTS: Adds the clause on its split level which
+ must belong to <Path>
+***************************************************************/
+{
+ int Level;
+
+ Level = clause_SplitLevel(C);
+ if (Level > tab_PathLength(Path)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\nError: Split level of some clause ");
+ misc_UserErrorReport("\nis higher than existing level.");
+ misc_UserErrorReport("\nThis may be a bug in the proof file.");
+ misc_FinishUserErrorReport();
+ }
+
+ tab_AddClause(C, tab_PathNthNode(Path, clause_SplitLevel(C)));
+}
+
+
+int tab_Depth(TABLEAU T)
+/**************************************************************
+ INPUT: A tableau
+ RETURNS: The depth of the tableau
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return 0;
+ if (tab_IsLeaf(T))
+ return 0;
+ else
+ return (misc_Max(tab_Depth(tab_RightBranch(T))+1, tab_Depth(tab_LeftBranch(T)))+1);
+}
+
+static BOOL tab_HasEmptyClause(TABLEAU T)
+/**************************************************************
+ INPUT: A tableau
+ RETURNS: TRUE iff an empty clause is among the clauses
+ on this level
+***************************************************************/
+{
+ LIST Scan;
+
+ for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (clause_IsEmptyClause(list_Car(Scan)))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+BOOL tab_IsClosed(TABLEAU T)
+/**************************************************************
+ INPUT: A Tableau
+ RETURNS: TRUE iff the tableau is closed. (NOTE: FALSE
+ if the tableau is empty)
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return FALSE;
+
+ if (tab_HasEmptyClause(T))
+ return TRUE;
+ /*
+ * now tableau can only be closed
+ * if there has been a split, and
+ * both subtableaus are closed
+ */
+
+ if (tab_RightBranchIsEmpty(T) || tab_LeftBranchIsEmpty(T)) {
+ printf("\nopen node label: %d", T->Label);
+ fflush(stdout);
+
+ return FALSE;
+ }
+ return tab_IsClosed(tab_RightBranch(T)) && tab_IsClosed(tab_LeftBranch(T));
+}
+
+static LIST tab_DeleteFlat(TABLEAU T)
+/**************************************************************
+ INPUT: A tableau
+ RETURNS: The list of its clauses on the first level of
+ the tableau
+ EFFECTS: Frees the root tableau node.
+***************************************************************/
+{
+ LIST Clauses;
+
+ Clauses = tab_Clauses(T);
+ memory_Free(T, sizeof(TABLEAU_NODE));
+
+ return Clauses;
+}
+
+
+static void tab_DeleteGen(TABLEAU T, LIST* Clauses, BOOL DeleteClauses)
+/**************************************************************
+ INPUT: A tableau, a list of clauses by reference, a flag
+ RETURNS: Nothing
+ EFFECTS: Depending on <DeleteClauses>, all clauses in the
+ tableau are added to <Clauses> or just deleted.
+ The memory for the tableau and its clause lists is
+ freed.
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return;
+
+ tab_DeleteGen(tab_RightBranch(T), Clauses, DeleteClauses);
+ tab_DeleteGen(tab_LeftBranch(T), Clauses, DeleteClauses);
+
+ list_Delete(tab_RightSplitClauses(T));
+ if (DeleteClauses)
+ list_Delete(tab_Clauses(T));
+ else
+ *Clauses = list_Nconc(tab_Clauses(T), *Clauses);
+
+ tab_DeleteFlat(T);
+
+}
+
+static void tab_DeleteCollectClauses(TABLEAU T, LIST* Clauses)
+/**************************************************************
+ INPUT: A tableau, a list of clauses by reference
+ RETURNS: Nothing
+ EFFECTS: Frees the memory of the tableau, but collects
+ its clauses
+***************************************************************/
+{
+ tab_DeleteGen(T, Clauses, FALSE);
+}
+
+void tab_Delete(TABLEAU T)
+/**************************************************************
+ INPUT: A tableau
+ RETURNS: Nothing
+ EFFECTS: Frees the memory of the tableau
+***************************************************************/
+{
+ LIST Redundant;
+
+ Redundant = list_Nil();
+ tab_DeleteGen(T, &Redundant, TRUE);
+}
+
+static void tab_SetSplitLevelsRec(TABLEAU T, int Level)
+/**************************************************************
+ INPUT: A tableau
+ RETURNS: Nothing
+ EFFECTS: The split levels of the clauses in the
+ tableau are set to the level of the
+ tableau level they are contained in.
+***************************************************************/
+{
+ LIST Scan;
+
+ if (tab_IsEmpty(T))
+ return;
+
+ for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ clause_SetSplitLevel(list_Car(Scan), Level);
+ if (Level >0) {
+ clause_ClearSplitField(list_Car(Scan));
+ clause_SetSplitFieldBit(list_Car(Scan), Level);
+ }
+ else
+ clause_SetSplitField(list_Car(Scan), (SPLITFIELD)NULL,0);
+ }
+
+ tab_SetSplitLevelsRec(tab_RightBranch(T), Level+1);
+ tab_SetSplitLevelsRec(tab_LeftBranch(T), Level+1);
+}
+
+void tab_SetSplitLevels(TABLEAU T)
+/**************************************************************
+ INPUT: A tableau
+ RETURNS: Nothing
+ EFFECTS: The split levels of the clauses in the
+ tableau are set to the level of the
+ tableau they belong to.
+***************************************************************/
+{
+ tab_SetSplitLevelsRec(T,0);
+}
+
+
+TABLEAU tab_PruneClosedBranches(TABLEAU T, LIST* Clauses)
+/**************************************************************
+ INPUT: A tableau, a list of clauses by reference.
+ RETURNS: The (destructively) reduced tableau: Descendants of
+ nodes that have an empty clause are deleted.
+ EFFECTS: The tableau is modified.
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return T;
+
+ /* if there is an empty clause on this level, delete subtrees */
+
+ if (tab_HasEmptyClause(T)) {
+
+ tab_DeleteCollectClauses(tab_RightBranch(T), Clauses);
+ tab_DeleteCollectClauses(tab_LeftBranch(T), Clauses);
+ tab_SetRightBranch(T, tab_EmptyTableau());
+ tab_SetLeftBranch(T, tab_EmptyTableau());
+ list_Delete(tab_RightSplitClauses(T));
+ tab_SetRightSplitClauses(T, list_Nil());
+ tab_SetSplitClause(T,clause_Null());
+ tab_SetLeftSplitClause(T, clause_Null());
+ }
+ /* else recursively prune subtrees */
+ else {
+ tab_SetRightBranch(T, tab_PruneClosedBranches(tab_RightBranch(T), Clauses));
+ tab_SetLeftBranch(T, tab_PruneClosedBranches(tab_LeftBranch(T), Clauses));
+ }
+
+ return T;
+}
+
+
+TABLEAU tab_RemoveIncompleteSplits(TABLEAU T, LIST* Clauses)
+/**************************************************************
+ INPUT: A Tableau, a list of clauses by reference
+ RETURNS: The reduced tableau: If a node has exactly one
+ successor (that is, the corresponding split was
+ not completed), delete the successor and move
+ its subtrees to <T>.
+ EFFECTS: The successor node is deleted, and its clauses added
+ to <Clauses>
+***************************************************************/
+{
+ LIST NewClauses;
+ TABLEAU Child;
+
+ if (tab_IsEmpty(T))
+ return T;
+
+ if (tab_IsLeaf(T))
+ return T;
+
+ if (!tab_IsEmpty(tab_RightBranch(T)) &&
+ !tab_IsEmpty(tab_LeftBranch(T))) {
+ tab_SetRightBranch(T, tab_RemoveIncompleteSplits(tab_RightBranch(T), Clauses));
+ tab_SetLeftBranch(T, tab_RemoveIncompleteSplits(tab_LeftBranch(T), Clauses));
+ return T;
+ }
+ if (tab_IsEmpty(tab_RightBranch(T)))
+ Child = tab_LeftBranch(T);
+ else
+ Child = tab_RightBranch(T);
+
+ Child = tab_RemoveIncompleteSplits(Child, Clauses);
+
+ tab_SetLeftBranch(T, tab_LeftBranch(Child));
+ tab_SetRightBranch(T, tab_RightBranch(Child));
+
+ /* copy split data */
+
+ tab_SetSplitClause(T, tab_SplitClause(Child));
+ tab_SetLeftSplitClause(T, tab_LeftSplitClause(Child));
+ tab_SetRightSplitClauses(T, tab_RightSplitClauses(Child));
+
+ /* delete ancestors of deleted clauses and remember */
+
+ NewClauses = tab_DeleteFlat(Child);
+ (*Clauses) = list_Nconc(NewClauses, *Clauses);
+
+ return T;
+}
+
+
+void tab_CheckEmpties(TABLEAU T)
+/**************************************************************
+ INPUT: A tableau
+ RETURNS: Nothing.
+ EFFECTS: Prints warnings if non-leaf nodes contain
+ empty clauses (which should not be the case
+ after pruning any more), of if leaf nodes
+ contain more than one empty clause
+***************************************************************/
+{
+ LIST Scan, Empties;
+ BOOL Printem;
+
+ if (tab_IsEmpty(T))
+ return;
+
+ /* get all empty clauses in this node */
+ Empties = list_Nil();
+ for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (clause_IsEmptyClause(list_Car(Scan)))
+ Empties = list_Cons(list_Car(Scan), Empties);
+ }
+ Printem = FALSE;
+ if (!list_Empty(Empties) && !tab_IsLeaf(T)) {
+ puts("\nNOTE: non-leaf node contains empty clauses.");
+ Printem = TRUE;
+ }
+
+ if (tab_IsLeaf(T) && list_Length(Empties) > 1) {
+ puts("\nNOTE: Leaf contains more than one empty clauses.");
+ Printem = TRUE;
+ }
+ if (Printem) {
+ puts("Clauses:");
+ clause_PParentsListPrint(tab_Clauses(T));
+ }
+ list_Delete(Empties);
+ tab_CheckEmpties(tab_LeftBranch(T));
+ tab_CheckEmpties(tab_RightBranch(T));
+}
+
+
+void tab_GetAllEmptyClauses(TABLEAU T, LIST* L)
+/**************************************************************
+ INPUT: A tableau, a list by reference
+ RETURNS: All empty clauses in the tableau prepended to <L>.
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return;
+
+ tab_GetAllEmptyClauses(tab_LeftBranch(T), L);
+ tab_GetAllEmptyClauses(tab_RightBranch(T), L);
+}
+
+
+void tab_GetEarliestEmptyClauses(TABLEAU T, LIST* L)
+/**************************************************************
+ INPUT : A tableau, a list of clauses by reference
+ RETURNS: Nothing.
+ EFFECTS: For each leaf node, adds empty clauses in
+ leaf nodes to <L>. If the leaf node contains only one
+ empty clause, it is added to <L> anyway.
+ If the leaf node contains more than one empty clause,
+ the earliest derived empty clause is added to <L>.
+***************************************************************/
+{
+ CLAUSE FirstEmpty;
+ LIST Scan;
+
+ if (tab_IsEmpty(T))
+ return;
+
+ if (tab_IsLeaf(T)) {
+ FirstEmpty = clause_Null();
+
+ for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (clause_IsEmptyClause(list_Car(Scan))) {
+ if (FirstEmpty == clause_Null())
+ FirstEmpty = list_Car(Scan);
+ else if (clause_Number(FirstEmpty) > clause_Number(list_Car(Scan)))
+ FirstEmpty = list_Car(Scan);
+ }
+ }
+
+ if (FirstEmpty != clause_Null())
+ (*L) = list_Cons(FirstEmpty, *L);
+ }
+ tab_GetEarliestEmptyClauses(tab_LeftBranch(T), L);
+ tab_GetEarliestEmptyClauses(tab_RightBranch(T), L);
+
+}
+
+void tab_ToClauseList(TABLEAU T, LIST* Proof)
+/**************************************************************
+ INPUT: A tableau <T>, a list of clauses
+ RETURNS: Nothing.
+ EFFECTS: All clauses in T are added to <Proof>
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return;
+
+ (*Proof) = list_Nconc(list_Copy(tab_Clauses(T)), *Proof);
+
+ tab_ToClauseList(tab_LeftBranch(T),Proof);
+ tab_ToClauseList(tab_RightBranch(T),Proof);
+}
+
+
+static void tab_ToSeqProofOrdered(TABLEAU T, LIST* Proof)
+/**************************************************************
+ INPUT: A tableau <T>, a list of clauses <Proof> representing a
+ proof by reference
+ RETURNS: The sequential proof corresponding to the tableau.
+***************************************************************/
+{
+ LIST Scan;
+ BOOL RightSplitRead, LeftSplitRead;
+
+ if (tab_IsEmpty(T))
+ return;
+
+ Scan = tab_Clauses(T);
+ RightSplitRead = LeftSplitRead = FALSE;
+
+ while (!list_Empty(Scan)) {
+ /* insert left and right splits and descendants controlled by clause number */
+
+ if (!RightSplitRead && !tab_RightBranchIsEmpty(T) &&
+ clause_Number(list_Car(Scan)) <
+ clause_Number(list_Car(tab_RightSplitClauses(T)))) {
+ tab_ToSeqProofOrdered(tab_RightBranch(T), Proof);
+ RightSplitRead = TRUE;
+ }
+ if (!LeftSplitRead && !tab_LeftBranchIsEmpty(T) &&
+ clause_Number(list_Car(Scan)) <
+ clause_Number(tab_LeftSplitClause(T))) {
+ tab_ToSeqProofOrdered(tab_LeftBranch(T), Proof);
+ LeftSplitRead = TRUE;
+ }
+ (*Proof) = list_Cons(list_Car(Scan), *Proof);
+ Scan = list_Cdr(Scan);
+ }
+ /* if a split clause with descendants has not been inserted yet,
+ it been generated after all other clauses */
+
+ if (!RightSplitRead)
+ tab_ToSeqProofOrdered(tab_RightBranch(T), Proof);
+ if (!LeftSplitRead)
+ tab_ToSeqProofOrdered(tab_LeftBranch(T), Proof);
+}
+
+
+/****************************************************************/
+/* SPECIALS FOR GRAPHS */
+/****************************************************************/
+
+static void tab_LabelNodesRec(TABLEAU T, int* Num)
+/**************************************************************
+ INPUT: A Tableau, a number by reference
+ RETURNS: Nothing.
+ EFFECTS: Labels the tableau nodes dflr, starting with <Num>
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return;
+ T->Label = *Num;
+ (*Num)++;
+ tab_LabelNodesRec(tab_LeftBranch(T), Num);
+ tab_LabelNodesRec(tab_RightBranch(T), Num);
+}
+
+
+void tab_LabelNodes(TABLEAU T)
+/**************************************************************
+ INPUT: A Tableau, a number by reference
+ RETURNS: Nothing.
+ EFFECTS: Labels the tableau nodes dflr, starting with 0
+***************************************************************/
+{
+ int Num;
+
+ Num = 0;
+ tab_LabelNodesRec(T, &Num);
+}
+
+
+static void tab_FPrintNodeLabel(FILE *File, TABLEAU T)
+/**************************************************************
+ INPUT: A file handle, a tableau
+ RETURNS: Nothing.
+ EFFECTS: Prints the root node information to <File>:
+ clauses, split information
+***************************************************************/
+{
+ LIST Scan;
+
+ /* start printing of node label string */
+
+ fprintf(File, "\"label: %d\\n", T->Label);
+
+ /* print left and right parts of split */
+ fputs("SplitClause : ", File);
+ clause_PParentsFPrint(File, tab_SplitClause(T));
+ fputs("\\nLeft Clause : ", File);
+ clause_PParentsFPrint(File, tab_LeftSplitClause(T));
+ fputs("\\nRightClauses: ", File);
+ if (list_Empty(tab_RightSplitClauses(T)))
+ fputs("[]\\n", File);
+ else {
+ clause_PParentsFPrint(File, list_Car(tab_RightSplitClauses(T)));
+ fputs("\\n", File);
+ for (Scan = list_Cdr(tab_RightSplitClauses(T)); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ fputs(" ", File);
+ clause_PParentsFPrint(File, list_Car(Scan));
+ fputs("\\n", File);
+ }
+ }
+ /* print clause at this level */
+ if (pcheck_ClauseCg) {
+ if (list_Empty(tab_Clauses(T)))
+ fputs("[]", File);
+ else {
+ for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)){
+ clause_PParentsFPrint(File, list_Car(Scan));
+ fputs("\\n", File);
+ }
+ }
+ }
+ putc('"', File); /* close string */
+}
+
+
+static void tab_FPrintEdgeCgFormat(FILE* File, int Source, int Target, BOOL Left)
+/**************************************************************
+ INPUT: A file handle, two node labels, a flag
+ RETURNS: Nothing.
+ EFFECTS: Prints the edge denoted by <Source> and <Target>
+ to <File>, with an edge label (0/1) according to <Left>.
+ The edge label is added since xvcg cannot handle
+ ordered edges.
+***************************************************************/
+{
+ fputs("\nedge: {", File);
+ fprintf(File, "\nsourcename: \"%d\"", Source);
+ fprintf(File, "\ntargetname: \"%d\"\n", Target);
+ fputs("\nlabel: \"", File);
+ if (Left)
+ putc('0', File);
+ else
+ putc('1', File);
+ fputs("\" }\n", File);
+}
+
+
+static void tab_FPrintEdgesCgFormat(FILE* File, TABLEAU T)
+/**************************************************************
+ INPUT: A file handle, a tableau
+ RETURNS: Nothing.
+ EFFECTS: Prints edge information of <T> in xvcg graph format
+ to <File>.
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return;
+
+ if (!tab_LeftBranchIsEmpty(T))
+ tab_FPrintEdgeCgFormat(File, T->Label, tab_LeftBranch(T)->Label, TRUE);
+ if (!tab_RightBranchIsEmpty(T))
+ tab_FPrintEdgeCgFormat(File, T->Label, tab_RightBranch(T)->Label, FALSE);
+
+ tab_FPrintEdgesCgFormat(File, tab_LeftBranch(T));
+ tab_FPrintEdgesCgFormat(File, tab_RightBranch(T));
+}
+
+
+static void tab_FPrintNodesCgFormat(FILE* File, TABLEAU T)
+/**************************************************************
+ INPUT: A file handle, a tableau
+ RETURNS: Nothing
+ EFFECTS: Prints egde information of <T> in xvcg graph format
+ to <File>.
+***************************************************************/
+{
+ if (tab_IsEmpty(T))
+ return;
+
+ fputs("\nnode: {\n\nlabel: ", File);
+ tab_FPrintNodeLabel(File, T);
+ putc('\n', File); /* end label section */
+
+ fprintf(File, "title: \"%d\"\n", T->Label);
+ fputs(" }\n", File);
+
+ /* recursion */
+ tab_FPrintNodesCgFormat(File, tab_LeftBranch(T));
+ tab_FPrintNodesCgFormat(File, tab_RightBranch(T));
+
+}
+
+static void tab_FPrintCgFormat(FILE* File, TABLEAU T)
+/**************************************************************
+ INPUT: A file handle, a tableau
+ RETURNS: Nothing.
+ EFFECTS: Prints tableau as a graph in xvcg format to <File>
+***************************************************************/
+{
+ fputs("graph: \n{\ndisplay_edge_labels: yes\n", File);
+
+ tab_FPrintNodesCgFormat(File, T);
+ tab_FPrintEdgesCgFormat(File, T);
+ fputs("}\n", File);
+}
+
+/* unused */
+/*static*/ void tab_PrintCgFormat(TABLEAU T)
+/**************************************************************
+ INPUT: A tableau.
+ RETURNS: Nothing.
+ EFFECTS: Print tableau in xvcg format to stdout
+***************************************************************/
+{
+ tab_FPrintCgFormat(stdout, T);
+}
+
+
+/**************************************************************/
+/* procedures for printing graph in da Vinci format */
+/**************************************************************/
+
+static void tab_FPrintDaVinciEdge(FILE* File, int L1, int L2)
+/**************************************************************
+ INPUT: A file handle, two numbers
+ RETURNS: Nothing
+ EFFECTS: Print an edge in daVinci format
+***************************************************************/
+{
+ fprintf(File, "l(\"%d->%d\"," ,L1,L2);
+ fputs("e(\"\",[],\n", File);
+ /* print child node as reference */
+ fprintf(File, "r(\"%d\")))\n", L2);
+}
+
+
+static void tab_FPrintDaVinciFormatRec(FILE* File, TABLEAU T)
+/**************************************************************
+ INPUT: A file handle, a tableau
+ RETURNS: Nothing
+ EFFECTS: Prints tableau to <File> in daVinci format
+***************************************************************/
+{
+ /* print node label */
+ fprintf(File, "l(\"%d\",", T->Label);
+ /* print node attributes */
+ fputs("n(\"\", [a(\"OBJECT\",", File);
+ tab_FPrintNodeLabel(File, T);
+ fputs(")],\n", File);
+
+ /* print egde list */
+ putc('[', File);
+ if (!tab_LeftBranchIsEmpty(T))
+ tab_FPrintDaVinciEdge(File, T->Label, tab_LeftBranch(T)->Label);
+
+ if (!tab_RightBranchIsEmpty(T)) {
+ if (!tab_LeftBranchIsEmpty(T))
+ putc(',', File);
+ tab_FPrintDaVinciEdge(File, T->Label, tab_RightBranch(T)->Label);
+ }
+ fputs("]))", File); /* this ends the node description */
+
+ if (!tab_LeftBranchIsEmpty(T)) {
+ putc(',', File);
+ tab_FPrintDaVinciFormatRec(File, tab_LeftBranch(T));
+ }
+ if (!tab_RightBranchIsEmpty(T)) {
+ putc(',', File);
+ tab_FPrintDaVinciFormatRec(File, tab_RightBranch(T));
+ }
+}
+
+
+static void tab_FPrintDaVinciFormat(FILE* File, TABLEAU T)
+/**************************************************************
+ INPUT: A file handle <File>, a tableau
+ RETURNS: Nothing
+ EFFECTS: Print tableau in daVinci format to <File>
+***************************************************************/
+{
+ fputs("[\n", File);
+ tab_FPrintDaVinciFormatRec(File,T);
+ fputs("]\n", File);
+}
+
+
+void tab_WriteTableau(TABLEAU T, const char* Filename, GRAPHFORMAT Format)
+/**************************************************************
+ INPUT: A tableau, a filename
+ RETURNS: Nothing.
+***************************************************************/
+{
+ FILE* File;
+
+ if (Format != DAVINCI && Format != XVCG) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\nError: unknown output format for tableau.\n");
+ misc_FinishUserErrorReport();
+ }
+
+ File = misc_OpenFile(Filename, "w");
+
+ if (Format == DAVINCI)
+ tab_FPrintDaVinciFormat(File, T);
+ else
+ if (Format == XVCG)
+ tab_FPrintCgFormat(File, T);
+
+ misc_CloseFile(File, Filename);
+}
diff --git a/test/spass/tableau.h b/test/spass/tableau.h
new file mode 100644
index 0000000..f04a826
--- /dev/null
+++ b/test/spass/tableau.h
@@ -0,0 +1,292 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * TABLEAUS * */
+/* * * */
+/* * $Module: TABLEAU * */
+/* * * */
+/* * Copyright (C) 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _TABLEAU_
+#define _TABLEAU_
+
+
+#include "list.h"
+#include "clause.h"
+
+typedef struct TABLEAU_HELP {
+ LIST Clauses; /* all clauses generated on the split level */
+ CLAUSE SplitClause; /* this levels split clause */
+
+ CLAUSE LeftSplitClause; /* first clause generated by split */
+ LIST RightSplitClauses; /* other clauses generated by split */
+
+ struct TABLEAU_HELP* LeftBranch; /* branch corresponding to first split clause */
+ struct TABLEAU_HELP* RightBranch; /* branch corresponding to other split clauses */
+
+ int Label;
+} TABLEAU_NODE, *TABLEAU;
+
+
+typedef struct {
+ TABLEAU *Path; /* An array of tableaux */
+ int Length;
+ int MaxLength;
+
+} TABPATH_NODE, *TABPATH;
+
+/* tableau output formats */
+typedef enum { DAVINCI, XVCG } GRAPHFORMAT;
+
+
+TABPATH tab_PathCreate(int, TABLEAU);
+void tab_PathDelete(TABPATH);
+BOOL tab_PathContainsClause(TABPATH, CLAUSE);
+void tab_AddClauseOnItsLevel(CLAUSE, TABPATH);
+void tab_AddSplitAtCursor(TABPATH, BOOL);
+BOOL tab_IsClosed(TABLEAU);
+TABLEAU tab_PruneClosedBranches(TABLEAU, LIST*);
+int tab_Depth(TABLEAU);
+void tab_SetSplitLevels(TABLEAU T);
+TABLEAU tab_RemoveIncompleteSplits(TABLEAU, LIST*);
+void tab_PathDelete(TABPATH);
+void tab_Delete(TABLEAU);
+void tab_ToClauseList(TABLEAU, LIST*);
+void tab_GetEarliestEmptyClauses(TABLEAU, LIST*);
+void tab_WriteTableau(TABLEAU, const char*, GRAPHFORMAT);
+void tab_CheckEmpties(TABLEAU);
+void tab_GetAllEmptyClauses(TABLEAU, LIST*);
+void tab_LabelNodes(TABLEAU);
+
+/* inline functions for tableau paths */
+
+static __inline__ int tab_PathLength(TABPATH TabPath)
+{
+ return TabPath->Length;
+}
+
+static __inline__ TABLEAU tab_PathNthNode(TABPATH TabPath, int n)
+{
+#ifdef CHECK
+ if (n > TabPath->MaxLength) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In tab_PathNthNode:");
+ misc_ErrorReport(" Path length is %d,", tab_PathLength(TabPath));
+ misc_ErrorReport("\nnode %d was requested.\n", n);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return TabPath->Path[n];
+}
+
+static __inline__ TABPATH tab_PathPush(TABLEAU Tab, TABPATH TabPath)
+{
+ TabPath->Length++;
+ TabPath->Path[TabPath->Length] = Tab;
+
+#ifdef CHECK
+ if (TabPath->Length > TabPath->MaxLength) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In tab_PathPush: Maximum path length %d exceeded\n",
+ TabPath->MaxLength);
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return TabPath;
+}
+
+static __inline__ TABLEAU tab_EmptyTableau(void)
+{
+ return (TABLEAU)NULL;
+}
+
+static __inline__ TABPATH tab_PathPop(TABPATH TabPath)
+{
+#ifdef CHECK
+ if (TabPath->Length <= 0) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In tab_PathPop: Popping from empty path.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ TabPath->Path[TabPath->Length--] = tab_EmptyTableau();
+
+ return TabPath;
+}
+
+static __inline__ BOOL tab_PathEmpty(TABPATH P)
+{
+ return (tab_PathLength(P) == 0);
+}
+
+static __inline__ TABLEAU tab_CreateNode(void)
+{
+ TABLEAU Node;
+
+ Node = (TABLEAU)memory_Malloc(sizeof(TABLEAU_NODE));
+ Node->RightBranch = (TABLEAU)NULL;
+ Node->LeftBranch = (TABLEAU)NULL;
+ Node->SplitClause = (CLAUSE)NULL;
+ Node->LeftSplitClause = (CLAUSE)NULL;
+ Node->RightSplitClauses = list_Nil();
+
+ Node->Clauses = list_Nil();
+
+#ifdef USE_LABEL
+ Node->Label = 0;
+#endif
+
+ return Node;
+}
+
+static __inline__ TABPATH tab_PathPrefix(int Level, TABPATH TabPath)
+{
+ TabPath->Length = Level;
+ return TabPath;
+}
+
+static __inline__ TABLEAU tab_PathTop(TABPATH Path)
+{
+ return tab_PathNthNode(Path, tab_PathLength(Path));
+}
+
+
+static __inline__ BOOL tab_IsEmpty(TABLEAU Tab)
+{
+ return (Tab == tab_EmptyTableau());
+}
+
+static __inline__ TABLEAU tab_RightBranch(TABLEAU Tab)
+{
+ return Tab->RightBranch;
+}
+
+static __inline__ TABLEAU tab_LeftBranch(TABLEAU Tab)
+{
+ return Tab->LeftBranch;
+}
+
+static __inline__ void tab_SetRightBranch(TABLEAU Tab, TABLEAU SubTab)
+{
+ Tab->RightBranch = SubTab;
+}
+
+static __inline__ void tab_SetLeftBranch(TABLEAU Tab, TABLEAU SubTab)
+{
+ Tab->LeftBranch = SubTab;
+}
+
+static __inline__ BOOL tab_RightBranchIsEmpty(TABLEAU Tab)
+{
+ return (Tab->RightBranch == tab_EmptyTableau());
+}
+
+static __inline__ BOOL tab_LeftBranchIsEmpty(TABLEAU Tab)
+{
+ return (Tab->LeftBranch == tab_EmptyTableau());
+}
+
+static __inline__ CLAUSE tab_SplitClause(TABLEAU Tab)
+{
+ return Tab->SplitClause;
+}
+
+static __inline__ void tab_SetSplitClause(TABLEAU Tab, CLAUSE C)
+{
+ Tab->SplitClause = C;
+}
+
+static __inline__ BOOL tab_HasSplit(TABLEAU T)
+{
+ return (tab_SplitClause(T) != clause_Null());
+}
+
+static __inline__ void tab_AddClause(CLAUSE C,TABLEAU T)
+{
+ T->Clauses = list_Cons(C,T->Clauses);
+}
+
+static __inline__ LIST tab_Clauses(TABLEAU T)
+{
+ return T->Clauses;
+}
+
+static __inline__ void tab_SetClauses(TABLEAU T, LIST Clauses)
+{
+ T->Clauses = Clauses;
+}
+
+static __inline__ CLAUSE tab_LeftSplitClause(TABLEAU T)
+{
+ return T->LeftSplitClause;
+}
+
+static __inline__ void tab_SetLeftSplitClause(TABLEAU T, CLAUSE C)
+{
+ T->LeftSplitClause = C;
+}
+
+
+static __inline__ LIST tab_RightSplitClauses(TABLEAU T)
+{
+ return T->RightSplitClauses;
+}
+
+
+static __inline__ void tab_SetRightSplitClauses(TABLEAU T, LIST L)
+{
+ T->RightSplitClauses = L;
+}
+
+static __inline__ void tab_AddRightSplitClause(TABLEAU T, CLAUSE C)
+{
+ T->RightSplitClauses = list_Cons(C, T->RightSplitClauses);
+}
+
+static __inline__ BOOL tab_IsLeaf(TABLEAU T)
+{
+ return (tab_RightBranchIsEmpty(T) && tab_LeftBranchIsEmpty(T));
+}
+
+#endif
diff --git a/test/spass/term.c b/test/spass/term.c
new file mode 100644
index 0000000..2bc38e4
--- /dev/null
+++ b/test/spass/term.c
@@ -0,0 +1,2551 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * TERMS * */
+/* * * */
+/* * $Module: TERM * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#include "term.h"
+
+/**************************************************************/
+/* Global variables */
+/**************************************************************/
+
+NAT term_MARK;
+POINTER term_BIND[symbol__MAXVARIABLES][2];
+#ifdef CHECK
+BOOL term_BINDPHASE;
+#endif
+
+NAT term_STAMP;
+BOOL term_STAMPBLOCKED;
+static BOOL term_STAMPOVERFLOW[term_MAXSTAMPUSERS];
+static NAT term_STAMPUSERS;
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * TERM CREATION FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+void term_Init(void)
+/**********************************************************
+ INPUT: None.
+ RETURNS: None.
+ CAUTION: The term module is initialized.
+***********************************************************/
+{
+ int i;
+
+ term_MARK = 1;
+
+ term_STAMP = 0;
+ term_STAMPBLOCKED = FALSE;
+ for (i = 0; i < term_MAXSTAMPUSERS; i++)
+ term_STAMPOVERFLOW[i] = FALSE;
+ term_STAMPUSERS = 0;
+#ifdef CHECK
+ term_BINDPHASE = FALSE;
+#endif
+}
+
+
+TERM term_Create(SYMBOL Symbol, LIST List)
+/**********************************************************
+ INPUT: A symbol and a list of arguments.
+ RETURNS: A term consisting of the top symbol 'Symbol' and
+ the arguments stored in 'List'.
+ CAUTION: None.
+********************************************************/
+{
+ TERM Result;
+
+#ifdef CHECK
+ if (!symbol_IsSymbol(Symbol) || !term_IsTermList(List)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_Create: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = (TERM)memory_Malloc(sizeof(TERM_NODE));
+ Result->symbol = Symbol;
+ Result->args = List;
+ Result->super.termlist = list_Nil();
+ Result->stamp = 0;
+ Result->size = 0;
+ return Result;
+}
+
+TERM term_CreateAddFather(SYMBOL Symbol, LIST List)
+/**********************************************************
+ INPUT: A symbol and a list of arguments.
+ RETURNS: A term consisting of the top symbol 'Symbol' and
+ the arguments stored in 'List'.
+ In contrast to term_Create the superterm members are set for the arguments.
+ CAUTION: None.
+********************************************************/
+{
+ TERM Result;
+ LIST l;
+ Result = term_Create(Symbol, List);
+ for (l=term_ArgumentList(Result); !list_Empty(l); l = list_Cdr(l))
+ term_RplacSuperterm((TERM) list_Car(l), Result);
+ return Result;
+}
+
+TERM term_CreateStandardVariable(void)
+/**********************************************************
+ RETURNS: Returns a term with a new variable as top symbol.
+***********************************************************/
+{
+ return term_Create(symbol_CreateStandardVariable(), list_Nil());
+}
+
+
+void term_Delete(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ SUMMARY: Deletes the term and frees the storage.
+ CAUTION: The arguments of Term are also deleted.
+********************************************************/
+{
+ if (term_IsComplex(Term)) {
+ LIST Scan;
+ for (Scan = term_ArgumentList(Term);
+ list_Exist(Scan);
+ Scan = list_Cdr(Scan))
+ term_Delete(list_Car(Scan));
+ list_Delete(term_ArgumentList(Term));
+ }
+ term_Free(Term);
+}
+
+
+void term_DeleteIterative(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ SUMMARY: Deletes the term and frees the storage.
+ CAUTION: The arguments of Term are also deleted.
+********************************************************/
+{
+ if (term_IsComplex(Term)) {
+ LIST Stack, Aux;
+ Stack = list_StackBottom();
+ do {
+ if (term_IsComplex(Term))
+ Stack = list_Push(term_ArgumentList(Term),Stack);
+ term_Free(Term);
+ while (!list_StackEmpty(Stack) && list_Empty(list_Top(Stack)))
+ Stack = list_Pop(Stack);
+ if (!list_StackEmpty(Stack)) {
+ Aux = list_Top(Stack);
+ Term = (TERM)list_Car(Aux);
+ list_RplacTop(Stack, list_Cdr(Aux));
+ list_Free(Aux);
+ }
+ } while (!list_StackEmpty(Stack));
+ }
+ else
+ term_Free(Term);
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * PRIMITIVE TERM FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+BOOL term_Equal(TERM Term1, TERM Term2)
+/*********************************************************
+ INPUT: Two terms.
+ RETURNS: The boolean value TRUE if the terms are equal.
+ CAUTION: EQUAL FUNCTION- OR PREDICATE SYMBOLS SHARE THE
+ SAME ARITY. THIS IS NOT VALID FOR JUNCTORS!
+**********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Term1) || !term_IsTerm(Term2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_Equal: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /* if (term_IsIndexVariable(Term1))
+ puts("\nterm_Equal: Left index variable.");
+ else if (term_IsIndexVariable(Term2))
+ puts("\nterm_Equal: Right index variable.");
+
+ fflush(stdout); */
+
+ if (Term1 == Term2) /* pointers are equal */
+ return TRUE;
+ else if (!term_EqualTopSymbols(Term1, Term2))
+ return FALSE;
+ else if (term_ArgumentList(Term1)) {
+ LIST Scan1, Scan2;
+ for (Scan1=term_ArgumentList(Term1), Scan2=term_ArgumentList(Term2);
+ list_Exist(Scan1) && list_Exist(Scan2);
+ Scan1=list_Cdr(Scan1), Scan2=list_Cdr(Scan2))
+ if (!term_Equal(list_Car(Scan1),list_Car(Scan2)))
+ return FALSE;
+ return (list_Empty(Scan1) ? list_Empty(Scan2) : FALSE);
+ } else
+ return TRUE;
+}
+
+
+BOOL term_EqualIterative(TERM Term1, TERM Term2)
+/*********************************************************
+ INPUT: Two terms.
+ RETURNS: The boolean value TRUE if the terms are equal.
+ CAUTION: Notice that there may be symbols with arbitrary arity
+*******************************************************/
+{
+ LIST Stack1,Stack2;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term1) || !term_IsTerm(Term2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_EqualIterative: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Stack1 = Stack2 = list_StackBottom();
+ do {
+ if (term_EqualTopSymbols(Term1,Term2) &&
+ term_IsComplex(Term1) && term_IsComplex(Term2)) {
+ Stack1 = list_Push(term_ArgumentList(Term1),Stack1);
+ Stack2 = list_Push(term_ArgumentList(Term2),Stack2);
+ }
+ if (!term_EqualTopSymbols(Term1,Term2) ||
+ term_IsComplex(Term1) != term_IsComplex(Term2)) {
+ Stack1 = list_StackFree(Stack1);
+ Stack2 = list_StackFree(Stack2);
+ return FALSE;
+ }
+ while (!list_StackEmpty(Stack1) && list_Empty(list_Top(Stack1)))
+ if (!list_StackEmpty(Stack2) && list_Empty(list_Top(Stack2))) {
+ Stack1 = list_Pop(Stack1);
+ Stack2 = list_Pop(Stack2);
+ }
+ else {
+ Stack1 = list_StackFree(Stack1);
+ Stack2 = list_StackFree(Stack2);
+ return FALSE;
+ }
+ if (!list_StackEmpty(Stack1)) {
+ if (!list_Empty(list_Top(Stack2))) {
+ Term1 = (TERM)list_Car(list_Top(Stack1));
+ list_RplacTop(Stack1, list_Cdr(list_Top(Stack1)));
+ Term2 = (TERM)list_Car(list_Top(Stack2));
+ list_RplacTop(Stack2, list_Cdr(list_Top(Stack2)));
+ }
+ else {
+ Stack1 = list_StackFree(Stack1);
+ Stack2 = list_StackFree(Stack2);
+ return FALSE;
+ }
+ }
+ } while (!list_StackEmpty(Stack1));
+ return TRUE;
+}
+
+
+BOOL term_VariableEqual(TERM Variable1, TERM Variable2)
+/*********************************************************
+ INPUT: Two Variables.
+ RETURNS: The boolean value TRUE, if the variables are
+ equal.
+**********************************************************/
+{
+ return term_EqualTopSymbols(Variable1, Variable2);
+}
+
+
+BOOL term_IsGround(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: A boolean value which is TRUE, if 'Term' is a
+ ground term, i.e. does not contain variables.
+********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_IsGround: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (term_IsComplex(Term)) {
+ LIST Stack;
+ Stack = list_StackBottom();
+ do {
+ if (term_IsComplex(Term))
+ Stack = list_Push(term_ArgumentList(Term),Stack);
+ else
+ if (term_IsVariable(Term)) {
+ Stack = list_StackFree(Stack);
+ return FALSE;
+ }
+ while (!list_StackEmpty(Stack) && list_Empty(list_Top(Stack)))
+ Stack = list_Pop(Stack);
+ if (!list_StackEmpty(Stack)) {
+ Term = (TERM)list_Car(list_Top(Stack));
+ list_RplacTop(Stack, list_Cdr(list_Top(Stack)));
+ }
+ } while (!list_StackEmpty(Stack));
+ return TRUE;
+ } else
+ return !term_IsVariable(Term);
+}
+
+
+BOOL term_IsTerm(TERM Term)
+/*********************************************************
+ INPUT: A term.
+ RETURNS: TRUE, if 'Term' is not NULL
+ and has a symbol as its top symbol.
+**********************************************************/
+{
+ return (Term != (TERM)NULL && symbol_IsSymbol(term_TopSymbol(Term)));
+}
+
+
+BOOL term_IsTermList(LIST TermList)
+/*********************************************************
+ INPUT: A term.
+ RETURNS: TRUE iff <TermList> is a list of terms.
+*******************************************************/
+{
+ for ( ; !list_Empty(TermList); TermList=list_Cdr(TermList))
+ if (!(term_IsTerm((TERM)list_Car(TermList))))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+BOOL term_AllArgsAreVar(TERM Term)
+/*********************************************************
+ INPUT: A term.
+ RETURNS: The boolean value TRUE, if all arguments of the
+ term are variables.
+*******************************************************/
+{
+ LIST Scan;
+ for (Scan = term_ArgumentList(Term);
+ !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (!term_IsVariable(list_Car(Scan)))
+ return FALSE;
+ return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * LOW LEVEL FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+TERM term_Copy(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: A copy of 'Term' where the stamp field is copied, too.
+ SUMMARY: Copies "Term" and returns a pointer to the copy.
+*********************************************************/
+{
+ TERM Result;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_Copy: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (term_IsComplex(Term)) {
+ LIST Scan, ArgumentList;
+ for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term));
+ list_Exist(Scan);
+ Scan = list_Cdr(Scan))
+ list_Rplaca(Scan, term_Copy(list_Car(Scan)));
+ Result = term_Create(term_TopSymbol(Term), ArgumentList);
+ } else
+ Result = term_Create(term_TopSymbol(Term), list_Nil());
+
+ Result->stamp = Term->stamp;
+ Result->size = Term->size;
+
+ return Result;
+}
+
+
+TERM term_CopyIterative(TERM Term)
+/**********************************************************
+ INPUT: A term.
+ RETURNS: A copy of <Term>.
+ SUMMARY: Copies <Term> and returns a pointer to the copy.
+*********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_CopyIterative: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (term_IsComplex(Term)) {
+ LIST TopStack, ArgumentStack, ActStack;
+ TopStack = list_Push((POINTER)term_TopSymbol(Term),
+ list_StackBottom());
+ ArgumentStack = list_Push(list_Copy(term_ArgumentList(Term)),
+ list_StackBottom());
+ ActStack = list_Push(list_Top(ArgumentStack),
+ list_StackBottom());
+
+ while (!list_StackEmpty(TopStack)) {
+ if (list_Empty(list_Top(ActStack))) {
+ Term = term_Create((SYMBOL)list_Top(TopStack),
+ (LIST)list_Top(ArgumentStack));
+ TopStack = list_Pop(TopStack);
+ ArgumentStack = list_Pop(ArgumentStack);
+ ActStack = list_Pop(ActStack);
+ if (!list_StackEmpty(TopStack)) {
+ list_Rplaca(list_Top(ActStack), Term);
+ list_RplacTop(ActStack, list_Cdr(list_Top(ActStack)));
+ }
+ }
+ else {
+ Term = (TERM)list_Car(list_Top(ActStack));
+ if (term_IsComplex(Term)) {
+ TopStack = list_Push((POINTER)term_TopSymbol(Term), TopStack);
+ ArgumentStack = list_Push(list_Copy(term_ArgumentList(Term)),
+ ArgumentStack);
+ ActStack = list_Push(list_Top(ArgumentStack), ActStack);
+ }
+ else {
+ list_Rplaca(list_Top(ActStack),
+ term_Create(term_TopSymbol(Term), list_Nil()));
+ list_RplacTop(ActStack, list_Cdr(list_Top(ActStack)));
+ }
+ }
+ }
+ return Term;
+ }
+ else
+ return term_Create(term_TopSymbol(Term), list_Nil());
+}
+
+
+TERM term_CopyWithEmptyArgListNode(TERM Term, LIST ArgListNode,
+ LIST* ListNodeCopyPt)
+/**********************************************************
+ INPUT: A term and a pointer to an argument list node of
+ this term.
+ RETURNS: A copy of 'Term' with a NULL as list_Car(ListNodeCopy).
+ SUMMARY: Copies "Term" and returns a pointer to the copy.
+*********************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_CopyWithEmptyArgListNode: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (term_IsComplex(Term)) {
+ LIST Scan, ArgumentList, HelpScan;
+ TERM Result;
+
+ HelpScan = term_ArgumentList(Term);
+ ArgumentList = list_Copy(HelpScan);
+
+ for (Scan = ArgumentList;
+ list_Exist(Scan);
+ Scan = list_Cdr(Scan),HelpScan = list_Cdr(HelpScan))
+ if (HelpScan != ArgListNode)
+ list_Rplaca(Scan,
+ term_CopyWithEmptyArgListNode(list_Car(Scan),
+ ArgListNode,
+ ListNodeCopyPt));
+ else{
+ list_Rplaca(Scan, (TERM)NULL);
+ *ListNodeCopyPt = Scan;
+ }
+
+ Result = (TERM)memory_Malloc(sizeof(TERM_NODE));
+ Result->symbol = term_TopSymbol(Term);
+ Result->args = ArgumentList;
+ Result->super.termlist = list_Nil();
+
+ return Result;
+
+ } else
+ return term_Create(term_TopSymbol(Term), list_Nil());
+}
+
+
+void term_PrintWithEmptyArgListNode(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: none.
+ SUMMARY: Prints any term to stdout, especially terms with empty
+ argument list nodes.
+ CAUTION: Uses the other term_Output functions.
+*************************************************************/
+{
+ if (Term == (TERM)NULL)
+ fputs("(NULL)", stdout);
+
+ else if (term_IsComplex(Term)) {
+ putchar('(');
+ symbol_Print(term_TopSymbol(Term));
+ putchar(' ');
+ list_Apply((void (*)(POINTER)) term_PrintWithEmptyArgListNode,
+ term_ArgumentList(Term));
+ putchar(')');
+
+ } else if (term_IsVariable(Term)) {
+
+ symbol_Print(term_TopSymbol(Term));
+
+ } else {
+
+ /* term_IsConstant(Term) */
+ putchar('(');
+ symbol_Print(term_TopSymbol(Term));
+ putchar(')');
+ }
+}
+
+
+BOOL term_ReplaceSubtermBy(TERM Atom, TERM TermS, TERM TermT)
+/**************************************************************
+ INPUT: Three terms.
+ RETURNS: None.
+ EFFECT: Replaces all occurrences of TermS in Atom by TermT.
+ Top level is NOT considered!
+*************************************************************/
+{
+ LIST ArgListNode;
+ BOOL Replaced;
+ int B_Stack;
+
+#ifdef CHECK
+ if (!term_IsTerm(Atom) || !term_IsTerm(TermS) ||
+ !term_IsTerm(TermT) || term_Equal(Atom, TermS)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_ReplaceSubtermBy: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /*fputs("\nWe look for: ",stdout);term_Print(TermS);
+ fputs("\nin: ",stdout);term_Print(Atom);
+ */
+
+ Replaced = FALSE;
+ TermS = term_Copy(TermS);
+
+ if (!term_Equal(Atom, TermS) && !list_Empty(term_ArgumentList(Atom))) {
+
+ B_Stack = stack_Bottom();
+ stack_Push(term_ArgumentList(Atom));
+
+ while (!stack_Empty(B_Stack)) {
+ ArgListNode = stack_Top();
+ Atom = (TERM)list_Car(ArgListNode);
+ stack_RplacTop(list_Cdr(ArgListNode));
+
+ if (term_Equal(Atom, TermS)) {
+ Replaced = TRUE;
+ list_Rplaca(ArgListNode, term_Copy(TermT));
+ term_Delete(Atom);
+ }
+ else
+ if (term_IsComplex(Atom))
+ stack_Push(term_ArgumentList(Atom));
+
+ while (!stack_Empty(B_Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ }
+ }
+ term_Delete(TermS);
+ return Replaced;
+}
+
+
+void term_ReplaceVariable(TERM Term, SYMBOL Symbol, TERM Repl)
+/**************************************************************
+ INPUT: A term, a variable symbol and a replacement term.
+ RETURNS: void
+ EFFECT: All variables with <Symbol> in <Term> are replaced
+ with copies of <Repl>
+ CAUTION: Destructive
+***************************************************************/
+{
+ LIST Scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !term_IsTerm(Repl) || !symbol_IsVariable(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_ReplaceVariable: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (symbol_Equal(term_TopSymbol(Term), Symbol)) {
+ term_RplacTop(Term,term_TopSymbol(Repl));
+ term_RplacArgumentList(Term,term_CopyTermList(term_ArgumentList(Repl)));
+ }
+ else
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ term_ReplaceVariable(list_Car(Scan),Symbol,Repl);
+}
+
+void term_ExchangeVariable(TERM Term, SYMBOL Old, SYMBOL New)
+/**************************************************************
+ INPUT: A term, and two variable symbols.
+ RETURNS: void
+ EFFECT: All variables <Old> in <Term> are replaced with <New>
+ CAUTION: Destructive
+***************************************************************/
+{
+ LIST Scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !symbol_IsVariable(Old) || !symbol_IsVariable(New)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_ExchangeVariable: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (symbol_Equal(term_TopSymbol(Term), Old))
+ term_RplacTop(Term,New);
+ else
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ term_ExchangeVariable(list_Car(Scan),Old,New);
+}
+
+
+BOOL term_SubstituteVariable(SYMBOL Symbol, TERM Repl, TERM* Term)
+/******************************************************
+ INPUT: A Symbol which has to be found in the Term,
+ a term which is the replacement for the
+ 'Symbol', and a term in which the substitu-
+ tions take place.
+ RETURNS: A boolean value which is TRUE, if any sub-
+ stitutions were made.
+ SUMMARY: term_Substitute works recursively and repl.
+ every occurence of 'Symbol' in 'Term' by
+ 'Repl'.
+ CAUTION: FUNCTION IS DESTRUCTIVE ON 'Term'. REPLACE-
+ MENT IS COPIED EACH TIME A SUB. TAKES PLACE
+*******************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(*Term) || !term_IsTerm(Repl) || !symbol_IsSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_SubstituteVariable: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (symbol_Equal(term_TopSymbol(*Term), Symbol)) {
+
+ TERM New;
+ New = term_Copy(Repl);
+ (*Term)->symbol = Repl->symbol;
+ (*Term)->args = term_ArgumentList(New);
+
+ /* Free Top-Node of New, as the symbol has been written */
+ /* into the node pointed to by `Term'. */
+ memory_Free(New, sizeof(TERM_NODE));
+ return TRUE;
+
+ } else {
+
+ BOOL Result;
+ LIST List;
+
+ Result = FALSE;
+ for (List = term_ArgumentList(*Term);
+ list_Exist(List); List = list_Cdr(List))
+ if (term_SubstituteVariable(Symbol, Repl, (TERM*) &(List->car)))
+ Result = TRUE;
+ return Result;
+ }
+}
+
+
+static int term_CompareByConstants(TERM Left, TERM Right)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: 1 if left term < right term
+ 0 if left term = right term
+ -1 if left term > right term
+ EFFECT: The terms are compared by their multisets of
+ constants. The frequency of elements in the
+ multisets is a multiset itself. The frequencies
+ are sorted and the resulting sorted multisets
+ compared.
+***************************************************************/
+{
+ LIST lconsts, rconsts;
+ int result;
+
+ /* Get multiset of constants. */
+
+ lconsts = term_ListOfConstants(Left);
+ rconsts = term_ListOfConstants(Right);
+
+ result = list_CompareMultisetsByElementDistribution(lconsts, rconsts);
+
+ list_Delete(lconsts);
+ list_Delete(rconsts);
+
+ return result;
+}
+
+static int term_CompareByFunctions(TERM Left, TERM Right)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: 1 if left term < right term
+ 0 if left term = right term
+ -1 if left term > right term
+ EFFECT: The terms are compared by their multisets of
+ functions. The frequency of elements in the
+ multisets is a multiset itself. The frequencies
+ are sorted and the resulting sorted multisets
+ compared.
+***************************************************************/
+{
+ LIST lfuns, rfuns;
+ int result;
+
+ /* Get multiset of functions. */
+
+ lfuns = term_ListOfFunctions(Left);
+ rfuns = term_ListOfFunctions(Right);
+
+ result = list_CompareMultisetsByElementDistribution(lfuns, rfuns);
+
+ list_Delete(lfuns);
+ list_Delete(rfuns);
+
+ return result;
+}
+
+static int term_CompareByVariables(TERM Left, TERM Right)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: 1 if left term < right term
+ 0 if left term = right term
+ -1 if left term > right term
+ EFFECT: The terms are compared by their multisets of
+ variables. The frequency of elements in the
+ multisets is a multiset itself. The frequencies
+ are sorted and the resulting sorted multisets
+ compared.
+***************************************************************/
+{
+ LIST lvars, rvars;
+ int result;
+
+ /* Get multiset of variables. */
+
+ lvars = term_ListOfVariables(Left);
+ rvars = term_ListOfVariables(Right);
+
+ result = list_CompareMultisetsByElementDistribution(lvars, rvars);
+
+ list_Delete(lvars);
+ list_Delete(rvars);
+
+ return result;
+}
+
+LIST term_ListOfConstants(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: A list of constants.
+ EFFECT: Creates a list of constants used in a term. If no
+ constants are used in a term, it returns an empty
+ list.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_ListOfConstants: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (symbol_IsConstant(term_TopSymbol(Term)))
+ return list_List((POINTER) term_TopSymbol(Term));
+ else {
+ LIST result;
+ LIST scan;
+
+ result = list_Nil();
+ for (scan = term_ArgumentList(Term);
+ !list_Empty(scan);
+ scan = list_Cdr(scan)) {
+ /* Append to the smaller list for efficiency.
+ A subterm's list of constants will usually
+ be smaller than the intermediate result.
+ */
+ result = list_Nconc(term_ListOfConstants((TERM) list_Car(scan)), result);
+ }
+
+ return result;
+ }
+}
+
+LIST term_ListOfFunctions(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: A list of functions.
+ EFFECT: Creates a list of functions used in a term. If no
+ functions are used in a term, it returns an empty
+ list.
+***************************************************************/
+{
+ LIST result;
+ LIST scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_ListOfFunctions: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = list_Nil();
+
+ /* If the term starts with a function, add the function symbol
+ to the result.
+ */
+ if (symbol_IsFunction(term_TopSymbol(Term))) {
+ result = list_Nconc(result, list_List((POINTER) term_TopSymbol(Term)));
+ }
+
+ /* A function can utilize other functions, so
+ traverse the argument list for further
+ functions.
+ */
+ for (scan = term_ArgumentList(Term);
+ !list_Empty(scan);
+ scan = list_Cdr(scan)) {
+ /* Append to the smaller list for efficiency.
+ A subterm's list of functions will usually
+ be smaller than the intermediate result.
+ */
+ result = list_Nconc(term_ListOfFunctions((TERM) list_Car(scan)), result);
+ }
+
+ return result;
+}
+
+void term_CountSymbols(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: None.
+ EFFECT: Counts the non-variable symbols in the term, and
+ increases their counts accordingly.
+***************************************************************/
+{
+ LIST scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_CountSymbols: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ /* If the term starts with a function, increase the count for
+ the function symbol.
+ */
+ if (symbol_IsFunction(term_TopSymbol(Term))) {
+ SYMBOL S;
+
+ S = term_TopSymbol(Term);
+ symbol_SetCount(S, symbol_GetCount(S) + 1);
+ }
+
+ /* A function can utilize other functions, so
+ traverse the argument list for further
+ function symbols.
+ */
+ for (scan = term_ArgumentList(Term);
+ !list_Empty(scan);
+ scan = list_Cdr(scan)) {
+ term_CountSymbols((TERM) list_Car(scan));
+ }
+}
+
+static int term_CompareByArity(TERM Left, TERM Right)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: 1 if left term < right term
+ 0 if left term = right term
+ -1 if left term > right term
+ EFFECT: Terms are compared top down, left to right with
+ respect to the arity of their signature symbols,
+ where variables in addition are defined to be smaller
+ than constants.
+***************************************************************/
+{
+ NAT lval, rval;
+ SYMBOL lsymb, rsymb;
+ LIST largs, rargs;
+ int result;
+
+ result = 0;
+
+ /* Compare top symbols first */
+ lsymb = term_TopSymbol(Left);
+ rsymb = term_TopSymbol(Right);
+
+ if (symbol_IsVariable(lsymb)) {
+ if (symbol_IsVariable(rsymb))
+ return 0;
+ else
+ return 1;
+ }
+ else
+ if (symbol_IsVariable(rsymb))
+ return -1;
+
+ lval = symbol_Arity(lsymb);
+ rval = symbol_Arity(rsymb);
+
+ if (lval > rval)
+ return -1;
+
+ if (lval < rval)
+ return 1;
+
+ /* If top symbol arities are equal, compare subterms left to right */
+ largs = term_ArgumentList(Left);
+ rargs = term_ArgumentList(Right);
+
+ while(!list_Empty(largs)) {
+ result = term_CompareByArity(list_Car(largs), list_Car(rargs));
+ if (result != 0)
+ break;
+
+ largs = list_Cdr(largs);
+ rargs = list_Cdr(rargs);
+ }
+
+ return result;
+}
+
+int term_CompareBySymbolOccurences(TERM Left, TERM Right)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: 1 if left term < right term
+ 0 if left term = right term
+ -1 if left term > right term
+ EFFECT: Terms are compared top down, left to right with
+ respect to the frequency of their symbols.
+***************************************************************/
+{
+ unsigned long lval, rval;
+ SYMBOL lsymb, rsymb;
+ LIST largs, rargs;
+ int result;
+
+ result = 0;
+
+ /* Compare top symbols first */
+ lsymb = term_TopSymbol(Left);
+ rsymb = term_TopSymbol(Right);
+
+ if (symbol_IsFunction(lsymb)) {
+ if (symbol_IsFunction(rsymb)) {
+
+ lval = symbol_GetCount(lsymb);
+ rval = symbol_GetCount(rsymb);
+
+ if (lval > rval)
+ return -1;
+
+ if (lval < rval)
+ return 1;
+
+ /* If top symbol arities are equal, compare subterms left to right */
+ largs = term_ArgumentList(Left);
+ rargs = term_ArgumentList(Right);
+
+ while(!list_Empty(largs)) {
+ result = term_CompareBySymbolOccurences(list_Car(largs),
+ list_Car(rargs));
+ if (result != 0)
+ break;
+
+ largs = list_Cdr(largs);
+ rargs = list_Cdr(rargs);
+ }
+ }
+ else {
+ return -1;
+ }
+ }
+ else {
+ if (symbol_IsFunction(rsymb)) {
+ return 1;
+ }
+ }
+
+ return result;
+}
+
+int term_CompareAbstract(TERM Left, TERM Right)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: 1 if left term < right term
+ 0 if left term = right term
+ -1 if left term > right term
+ EFFECT: Compares two terms using an internal array of term
+ comparison functions. As soon as a term is found to
+ compare greater than the other, the result of the
+ comparison is returned. If all term comparison
+ functions yield an "equal", then 0 is returned.
+***************************************************************/
+{
+ int result;
+ int i;
+ int functions;
+
+ typedef int (*TERM_COMPARE_FUNCTION) (TERM, TERM);
+
+ static const TERM_COMPARE_FUNCTION term_compare_functions [] = {
+ term_CompareByArity,
+ term_CompareBySymbolOccurences,
+ term_CompareByConstants,
+ term_CompareByVariables,
+ term_CompareByFunctions
+ };
+
+#ifdef CHECK
+ if (!(term_IsTerm(Left) && term_IsTerm(Right))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_CompareAbstract: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ result = 0;
+ functions = sizeof(term_compare_functions)/sizeof(TERM_COMPARE_FUNCTION);
+
+ for (i = 0; i < functions; i++) {
+ result = term_compare_functions[i](Left, Right);
+
+ if ( result != 0) {
+ return result;
+ }
+ }
+
+ return result;
+}
+
+BOOL term_CompareAbstractLEQ(TERM Left, TERM Right)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: TRUE if left term <= right term, FALSE otherwise.
+ EFFECT: Terms are compared top down, left to right with
+ respect to the arity of their signature symbols,
+ where variables in addition are defined to be smaller
+ than constants.
+***************************************************************/
+{
+ return (term_CompareAbstract(Left, Right) >= 0);
+}
+
+
+NAT term_ComputeSize(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: The number of symbols in the term.
+ EFFECT: None
+***************************************************************/
+{
+ NAT Weight;
+ LIST Scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_ComputeSize: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Weight = 1;
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ Weight += term_ComputeSize((TERM)list_Car(Scan));
+ return Weight;
+}
+
+NAT term_RootDistance(TERM Term)
+/**************************************************************
+ INPUT: A term with establised father links.
+ RETURNS: The distance from <Term> to its root father term.
+ EFFECT: None
+***************************************************************/
+{
+ NAT Distance;
+
+ Distance = 0;
+
+ while (term_Superterm(Term) != (TERM)NULL) {
+ Distance++;
+ Term = term_Superterm(Term);
+ }
+
+ return Distance;
+}
+
+BOOL term_RootDistanceSmaller(TERM Term1, TERM Term2)
+/**************************************************************
+ INPUT: Two terms with establised father links.
+ RETURNS: TRUE iff root distance of <Term1> is smaller than
+ root distance of <Term2>
+ EFFECT: None
+***************************************************************/
+{
+ return (term_RootDistance(Term1)<term_RootDistance(Term2));
+}
+
+void term_InstallSize(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: None
+ EFFECT: Sets for every subterm the size.
+***************************************************************/
+{
+ NAT Weight;
+ LIST Scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_InstallSize: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Weight = 1;
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ term_InstallSize((TERM)list_Car(Scan));
+ Weight += term_Size((TERM)list_Car(Scan));
+ };
+ term_SetSize(Term, Weight);
+}
+
+NAT term_Depth(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: The depth of the term.
+ EFFECT: None
+***************************************************************/
+{
+ NAT Depth,Help;
+ LIST Scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_Depth: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Depth = 0;
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ Help = term_Depth(list_Car(Scan));
+ if (Help > Depth)
+ Depth = Help;
+ }
+ return (Depth+1);
+}
+
+BOOL term_ContainsSymbol(TERM Term, SYMBOL Symbol)
+/**************************************************************
+ INPUT: A term and a symbol.
+ RETURNS: TRUE, if the symbol occurs somewhere in the term,
+ FALSE otherwise.
+***************************************************************/
+{
+ int Stack;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !symbol_IsSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_ContainsSymbol: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Stack = stack_Bottom();
+
+ do {
+ if (term_TopSymbol(Term) == Symbol) {
+ stack_SetBottom(Stack); /* Clean up the stack */
+ return TRUE;
+ }
+ else
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+
+ if (!stack_Empty(Stack)) {
+ Term = list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return FALSE;
+}
+
+TERM term_FindSubterm(TERM Term, SYMBOL Symbol)
+/**************************************************************
+ INPUT: A term and a symbol.
+ RETURNS: If the symbol occurs in the Term the subterm is returned.
+ NULL otherwise.
+***************************************************************/
+{
+ int stack;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !symbol_IsSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_FindSubterm: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ stack = stack_Bottom();
+
+ do {
+ if (term_TopSymbol(Term) == Symbol) {
+ stack_SetBottom(stack); /* Clean up the stack */
+ return Term;
+ } else if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+
+ while (!stack_Empty(stack) && list_Empty(stack_Top()))
+ stack_Pop();
+
+ if (!stack_Empty(stack)) {
+ Term = list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(stack));
+
+ return NULL;
+}
+
+static int term_SharingList(TERM Term, LIST List)
+/**************************************************************
+ INPUT: A term and a list cell.
+ RETURNS: The number of times <List> occurs in <Term>
+ EFFECT: None
+***************************************************************/
+{
+ LIST Scan;
+ int n;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_SharingList: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ n = 0;
+
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ if (Scan == List)
+ n++;
+ n += term_SharingList(list_Car(Scan), List);
+ }
+
+ return n;
+}
+
+
+static int term_SharingTerm(TERM Term, TERM CompareTerm)
+/**************************************************************
+ INPUT: A term and a compare term
+ RETURNS: The number of occurrences of <CompareTerm> in <Term>
+ EFFECT: None
+***************************************************************/
+{
+ LIST Scan;
+ int n;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_SharingTerm: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ n = 0;
+
+ if (Term == CompareTerm)
+ n = 1;
+
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ n += term_SharingTerm(list_Car(Scan),CompareTerm);
+
+ return n;
+}
+
+
+BOOL term_Sharing(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: TRUE iff the term shares list cells or subterms.
+ EFFECT: None
+***************************************************************/
+{
+ LIST Scan;
+ int stack;
+ TERM ActTerm;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_Sharing: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ stack = stack_Bottom();
+ stack_Push(Term);
+
+ while (!stack_Empty(stack)) {
+ ActTerm = (TERM)stack_Top();
+ stack_Pop();
+
+ if (term_SharingTerm(Term,ActTerm)>1)
+ return TRUE;
+
+ if (term_IsComplex(Term)) {
+ for (Scan = term_ArgumentList(ActTerm);
+ !list_Empty(Scan);
+ Scan=list_Cdr(Scan))
+ if (term_SharingList(Term, Scan) > 1)
+ return TRUE;
+ else
+ stack_Push(list_Car(Scan));
+ }
+ }
+
+ return FALSE;
+}
+
+
+void term_AddFatherLinks(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: void.
+ EFFECT: The super term links of Term are cleared and then all
+ its subterms are set.
+***************************************************************/
+{
+ LIST Scan;
+ TERM ActTerm;
+
+ term_RplacSuperterm(Term,(TERM)NULL);
+
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ ActTerm = (TERM)list_Car(Scan);
+ term_AddFatherLinks(ActTerm);
+ term_RplacSuperterm(ActTerm,Term);
+ }
+
+}
+
+BOOL term_FatherLinksEstablished(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: TRUE iff all father links in Term are established.
+ EFFECT: None.
+***************************************************************/
+{
+ LIST Scan;
+
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (Term != term_Superterm(list_Car(Scan)) || !term_FatherLinksEstablished(list_Car(Scan)))
+ return FALSE;
+
+ return TRUE;
+}
+
+TERM term_TopLevelTerm(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: The top level father of the term.
+ EFFECT: The father links have to be established!
+***************************************************************/
+{
+ while (term_Superterm(Term))
+ Term = term_Superterm(Term);
+ return Term;
+}
+
+
+BOOL term_HasPointerSubterm(TERM Term, TERM Subterm)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: TRUE, if <Term> has <Subterm> as a subterm.
+ CAUTION: Only term pointers are compared, term_Equal isn't used.
+***************************************************************/
+{
+ if (Term == Subterm)
+ return TRUE;
+ else {
+ LIST scan = term_ArgumentList(Term);
+
+ while (!list_Empty(scan)) {
+ if (term_HasPointerSubterm((TERM) list_Car(scan), Subterm))
+ return TRUE;
+ scan = list_Cdr(scan);
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL term_HasSubterm(TERM Term, TERM Subterm)
+/**************************************************************
+ INPUT: Two terms.
+ RETURNS: TRUE, if <Term> has <Subterm> as a subterm.
+ CAUTION: term_Equal is used.
+***************************************************************/
+{
+ if (term_Equal(Term,Subterm))
+ return TRUE;
+ else {
+ LIST Scan;
+ Scan = term_ArgumentList(Term);
+
+ while (!list_Empty(Scan)) {
+ if (term_HasSubterm((TERM) list_Car(Scan), Subterm))
+ return TRUE;
+ Scan = list_Cdr(Scan);
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL term_HasProperSuperterm(TERM Term, TERM Super)
+/**********************************************************
+ INPUT : Two terms.
+ RETURNS : TRUE iff Super can be reached from Term by following
+ the superterm member of the TERM structure.
+ CAUTION : not reflexive
+**********************************************************/
+{
+ if (Term == Super)
+ return FALSE;
+ while (Term != (TERM) NULL) {
+ if (Term == Super) /* Pointer equality ! */
+ return TRUE;
+ else
+ Term = term_Superterm(Term);
+ }
+ return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * TERM OUTPUT FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+void term_Print(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: none.
+ SUMMARY: Prints the term to stdout.
+ CAUTION: Uses the other term output functions.
+***************************************************************/
+{
+ if (term_IsComplex(Term)) {
+ putchar('(');
+ symbol_Print(term_TopSymbol(Term));
+ putchar(' ');
+ term_TermListPrint(term_ArgumentList(Term));
+ putchar(')');
+
+ } else if (term_IsVariable(Term)) {
+
+ symbol_Print(term_TopSymbol(Term));
+
+ } else {
+
+ /* term_IsConstant(Term) */
+ putchar('(');
+ symbol_Print(term_TopSymbol(Term));
+ putchar(')');
+ }
+}
+
+static void term_PrettyPrintIntern(TERM Term, int Depth)
+/**************************************************************
+ INPUT: A term and a depth parameter for indentation.
+ RETURNS: none.
+ SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+ int i;
+ LIST scan;
+
+
+ for (i=0; i < Depth; i++)
+ fputs(" ", stdout);
+ if (symbol_IsJunctor(term_TopSymbol(Term))) {
+ if (term_IsComplex(Term)) {
+ symbol_Print(term_TopSymbol(Term));
+ putchar('(');
+ fputs("\n", stdout);
+ for (scan=term_ArgumentList(Term); !list_Empty(scan); scan= list_Cdr(scan)) {
+ term_PrettyPrintIntern((TERM) list_Car(scan), Depth+1);
+ if (!list_Empty(list_Cdr(scan)))
+ fputs(",\n", stdout);
+ }
+ putchar(')');
+ }
+ else {
+ if (term_IsVariable(Term)) {
+ symbol_Print(term_TopSymbol(Term));
+ }
+ else {
+ putchar('(');
+ symbol_Print(term_TopSymbol(Term));
+ putchar(')');
+ }
+ }
+ }
+ else {
+ term_PrintPrefix(Term);
+ }
+}
+
+void term_PrettyPrint(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: none.
+ SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+ term_PrettyPrintIntern(Term, 0);
+}
+
+
+void term_FPrint(FILE* File,TERM Term)
+/**************************************************************
+ INPUT: A file and a term.
+ RETURNS: none.
+ SUMMARY: Prints the term to the file.
+ CAUTION: Uses the other term output functions.
+***************************************************************/
+{
+ if (term_IsComplex(Term)) {
+ putc('(', File);
+ symbol_FPrint(File,term_TopSymbol(Term));
+ putc(' ', File);
+ term_TermListFPrint(File,term_ArgumentList(Term));
+ putc(')', File);
+
+ } else if (term_IsVariable(Term)) {
+
+ symbol_FPrint(File,term_TopSymbol(Term));
+
+ } else {
+
+ /* term_IsConstant(Term) */
+ putc('(', File);
+ symbol_FPrint(File,term_TopSymbol(Term));
+ putc(')', File);
+ }
+}
+
+
+void term_TermListPrint(LIST List)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: None.
+***************************************************************/
+{
+ for (; !list_Empty(List); List=list_Cdr(List)) {
+ term_Print(list_Car(List)); fflush(stdout);
+ if (!list_Empty(list_Cdr(List)))
+ putchar(' ');
+ }
+}
+
+
+void term_TermListFPrint(FILE* File, LIST List)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: None.
+***************************************************************/
+{
+ for (; !list_Empty(List); List=list_Cdr(List)) {
+ term_FPrint(File,list_Car(List));
+ if (!list_Empty(list_Cdr(List)))
+ putc(' ', File);
+ }
+}
+
+
+void term_PrintPrefix(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: none.
+ SUMMARY: Prints the term in prefix notation to stdout.
+ CAUTION: Uses the other term output functions.
+***************************************************************/
+{
+ if (term_IsComplex(Term)) {
+ symbol_Print(term_TopSymbol(Term));
+ putchar('(');
+ term_TermListPrintPrefix(term_ArgumentList(Term));
+ putchar(')');
+
+ } else
+ symbol_Print(term_TopSymbol(Term));
+}
+
+
+void term_FPrintPrefix(FILE* File, TERM Term)
+/**************************************************************
+ INPUT: A file and a term.
+ RETURNS: none.
+ SUMMARY: Prints the term in prefix notation to the file.
+ CAUTION: Uses the other term output functions.
+***************************************************************/
+{
+ if (term_IsComplex(Term)) {
+ symbol_FPrint(File,term_TopSymbol(Term));
+ putc('(', File);
+ term_TermListFPrintPrefix(File,term_ArgumentList(Term));
+ putc(')', File);
+
+ } else
+ symbol_FPrint(File,term_TopSymbol(Term));
+}
+
+
+void term_TermListPrintPrefix(LIST List)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: None.
+***************************************************************/
+{
+ for (; !list_Empty(List); List=list_Cdr(List)) {
+ term_PrintPrefix(list_Car(List));
+ if (!list_Empty(list_Cdr(List)))
+ putchar(',');
+ }
+}
+
+
+void term_TermListFPrintPrefix(FILE* File, LIST List)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: None.
+***************************************************************/
+{
+ for (; !list_Empty(List); List=list_Cdr(List)) {
+ term_FPrintPrefix(File,list_Car(List));
+ if (!list_Empty(list_Cdr(List)))
+ putc(',', File);
+ }
+}
+
+
+
+void term_FPrintOtterPrefix(FILE* File, TERM Term)
+/**************************************************************
+ INPUT: A file and a term.
+ RETURNS: none.
+ SUMMARY: Prints the term in prefix notation to the file.
+ CAUTION: Uses the other term_Output functions.
+***************************************************************/
+{
+ if (term_IsComplex(Term)) {
+ symbol_FPrintOtter(File, term_TopSymbol(Term));
+ putc('(', File);
+ term_TermListFPrintOtterPrefix(File, term_ArgumentList(Term));
+ putc(')', File);
+ } else
+ symbol_FPrintOtter(File, term_TopSymbol(Term));
+}
+
+
+void term_TermListFPrintOtterPrefix(FILE* File, LIST List)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: None.
+***************************************************************/
+{
+ for (; !list_Empty(List); List=list_Cdr(List)) {
+ term_FPrintOtterPrefix(File,list_Car(List));
+ if (!list_Empty(list_Cdr(List)))
+ putc(',', File);
+ }
+}
+
+
+void term_FPrintPosition(FILE* File, TERM TopTerm, TERM Subterm)
+/**************************************************************
+ INPUT: An output file and two terms where <Subterm> is a subterm
+ of <TopTerm>.
+ RETURNS: Nothing.
+ SUMMARY: The position of <Subterm> relative to <TopTerm> is
+ printed to the output file. A simple top-down search
+ is done, so the superterm pointers are not needed.
+ Note that we compare terms with respect to pointers!
+ If <Subterm> isn't a subterm of <TopTerm> at all,
+ this causes an error message followed by a core dump.
+***************************************************************/
+{
+ NAT pos;
+ LIST Scan;
+
+ if (TopTerm == Subterm)
+ return;
+
+ for (Scan = term_ArgumentList(TopTerm), pos = 1; !list_Empty(Scan);
+ Scan = list_Cdr(Scan), pos++) {
+ if (term_HasPointerSubterm(list_Car(Scan), Subterm)) {
+ fprintf(File, "%u", pos);
+ if (Subterm != list_Car(Scan)) {
+ putc('.', File);
+ term_FPrintPosition(File, list_Car(Scan), Subterm);
+ }
+ return;
+ }
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_FPrintPosition: Term isn't subterm of the other one.");
+ misc_FinishErrorReport();
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * HIGH LEVEL FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+NAT term_Bytes(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: The number of bytes occupied by the term.
+ EFFECT: None
+***************************************************************/
+{
+ NAT Bytes;
+ LIST Scan;
+
+ Bytes = sizeof(TERM_NODE) + list_Bytes(term_ArgumentList(Term));
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ Bytes += term_Bytes((TERM)list_Car(Scan));
+ return Bytes;
+}
+
+
+LIST term_ListOfVariables(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: The list of variables occurring in the term.
+ Note that there may be many terms with same variable symbol.
+***************************************************************/
+{
+ LIST Stack, Variables;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_ListOfVariables: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Variables = list_Nil();
+ Stack = list_StackBottom();
+ do {
+ if (term_IsComplex(Term))
+ Stack = list_Push(term_ArgumentList(Term),Stack);
+ else
+ if (term_IsVariable(Term))
+ Variables = list_Cons(Term, Variables);
+ while (!list_StackEmpty(Stack) && list_Empty(list_Top(Stack)))
+ Stack = list_Pop(Stack);
+ if (!list_StackEmpty(Stack)) {
+ Term = (TERM)list_Car(list_Top(Stack));
+ list_RplacTop(Stack, list_Cdr(list_Top(Stack)));
+ }
+ } while (!list_StackEmpty(Stack));
+ return Variables;
+}
+
+
+void term_MarkVariables(TERM Term, NAT Mark)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Nothing.
+ EFFECT: All variables from <Term> are marked with <Mark>.
+ CAUTION: The term module must be in a binding phase (started with
+ term_StartBinding)!
+***************************************************************/
+{
+ int Stack;
+
+#ifdef CHECK
+ if (!term_InBindingPhase()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_MarkVariables:");
+ misc_ErrorReport(" Called while not in binding phase.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Stack = stack_Bottom();
+ do {
+ if (term_IsComplex(Term)) {
+ stack_Push(term_ArgumentList(Term));
+ }
+ else if (term_IsVariable(Term))
+ term_CreateBinding(term_TopSymbol(Term), Mark);
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Term = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+}
+
+
+LIST term_VariableSymbols(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: The list of variable symbols occurring in the term.
+***************************************************************/
+{
+ LIST Variables;
+ int Stack;
+ SYMBOL Top;
+ NAT ActMark;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || term_InBindingPhase()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_VariableSymbols: Illegal input or context.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+
+ Variables = list_Nil();
+ Stack = stack_Bottom();
+ ActMark = term_ActMark();
+ do {
+ if (term_IsComplex(Term)) {
+ stack_Push(term_ArgumentList(Term));
+ }
+ else {
+ Top = term_TopSymbol(Term);
+ if (symbol_IsVariable(Top) && !term_VarIsMarked(Top, ActMark)) {
+ Variables = list_Cons((POINTER)Top, Variables);
+ term_CreateBinding(Top, ActMark);
+ }
+ }
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Term = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ term_StopBinding();
+
+ return Variables;
+}
+
+
+NAT term_NumberOfVarOccs(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: The list of variable symbols occurring in the term.
+***************************************************************/
+{
+ NAT Result;
+ int Stack;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_NumberOfVarOccs: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = 0;
+ Stack = stack_Bottom();
+ do {
+ if (term_IsComplex(Term)) {
+ stack_Push(term_ArgumentList(Term));
+ }
+ else {
+ if (symbol_IsVariable(term_TopSymbol(Term)))
+ Result++;
+ }
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Term = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return Result;
+}
+
+NAT term_NumberOfSymbolOccurrences(TERM Term, SYMBOL Symbol)
+/**************************************************************
+ INPUT: A term and a symbol.
+ RETURNS: The number of occurrences of <Symbol> in <Term>
+***************************************************************/
+{
+ NAT Result;
+ LIST Scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !symbol_IsSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_NumberOfSymbolOccurrences: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = 0;
+
+ if (symbol_Equal(term_TopSymbol(Term),Symbol))
+ Result++;
+
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ Result += term_NumberOfSymbolOccurrences(list_Car(Scan), Symbol);
+
+ return Result;
+}
+
+
+BOOL term_ContainsFunctions(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: TRUE iff the term contains a function symbol
+***************************************************************/
+{
+ int Stack;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_ContainsFunctions: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Stack = stack_Bottom();
+ do {
+ if (term_IsComplex(Term)) {
+ if (symbol_IsFunction(term_TopSymbol(Term)) && !symbol_IsConstant(term_TopSymbol(Term))) {
+ stack_SetBottom(Stack);
+ return TRUE;
+ }
+ stack_Push(term_ArgumentList(Term));
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Term = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return FALSE;
+}
+
+BOOL term_ContainsVariable(TERM Term, SYMBOL Var)
+/**************************************************************
+ INPUT: A term and a variable symbol.
+ RETURNS: TRUE iff the term contains the variable symbol
+***************************************************************/
+{
+ int Stack;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !symbol_IsSymbol(Var)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_ContainsVariable: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Stack = stack_Bottom();
+ do {
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+ else
+ if (symbol_Equal(term_TopSymbol(Term),Var)) {
+ stack_SetBottom(Stack);
+ return TRUE;
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Term = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return FALSE;
+}
+
+SYMBOL term_MaxVar(TERM Term)
+/*********************************************************
+ INPUT: A term.
+ RETURNS: The maximal variable in <Term>, NULL otherwise
+********************************************************/
+{
+ LIST Scan;
+ int Stack;
+ SYMBOL Result;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_MaxVar: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = (SYMBOL)NULL;
+ Stack = stack_Bottom();
+
+ if (term_IsStandardVariable(Term)) {
+ if (term_TopSymbol(Term)>Result)
+ Result = term_TopSymbol(Term);
+ }
+ else
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+
+ while (!stack_Empty(Stack)) {
+ Scan = stack_Top();
+ Term = (TERM)list_Car(Scan);
+ stack_RplacTop(list_Cdr(Scan));
+
+ if (term_IsStandardVariable(Term)) {
+ if (term_TopSymbol(Term)>Result)
+ Result = term_TopSymbol(Term);
+ }
+ else
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ }
+
+ return Result;
+}
+
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * Renaming * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void term_StartMinRenaming(void)
+/**************************************************************
+ INPUT: None
+ EFFECT: Initializes the term and symbol modules for min co var renaming
+***************************************************************/
+{
+ symbol_ResetStandardVarCounter();
+ term_NewMark();
+}
+
+
+void term_StartMaxRenaming(SYMBOL MaxVar)
+/**************************************************************
+ INPUT: A variable symbol.
+ EFFECT: Initializes the term and symbol modules for renaming above <MaxVar>
+***************************************************************/
+{
+ symbol_SetStandardVarCounter(MaxVar);
+ term_NewMark();
+}
+
+
+TERM term_Rename(TERM Term)
+/**************************************************************
+ INPUT: A Term.
+ RETURNS: The destructively renamed term.
+ EFFECT: All co variables are destructively renamed in <TERM>
+***************************************************************/
+{
+ int Stack;
+ SYMBOL Top;
+ NAT ActMark;
+ TERM ActTerm;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || term_InBindingPhase()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_Rename: Illegal input or context.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+
+ Stack = stack_Bottom();
+ ActMark = term_OldMark();
+ ActTerm = Term;
+ do {
+ if (term_IsComplex(ActTerm)) {
+ stack_Push(term_ArgumentList(ActTerm));
+ }
+ else {
+ Top = term_TopSymbol(ActTerm);
+ if (symbol_IsVariable(Top)) {
+ if (!term_VarIsMarked(Top, ActMark))
+ term_CreateValueBinding(Top, ActMark, (POINTER)symbol_CreateStandardVariable());
+ term_RplacTop(ActTerm,(SYMBOL)term_BindingValue(Top));
+ }
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ ActTerm = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ term_StopBinding();
+
+ return Term;
+}
+
+SYMBOL term_GetRenamedVarSymbol(SYMBOL Var)
+/**************************************************************
+ INPUT: A variable symbol.
+ RETURNS: The renamed variable for symbol for <var> with respect
+ to the current renaming. If it does not exist, <var>
+ itself is returned.
+ EFFECT: None.
+***************************************************************/
+{
+ NAT ActMark;
+
+#ifdef CHECK
+ if (!symbol_IsStandardVariable(Var)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_GetRenamedVarSymbol: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ ActMark = term_OldMark();
+
+ if (term_VarIsMarked(Var, ActMark))
+ return (SYMBOL)term_BindingValue(Var);
+
+ return Var;
+}
+
+
+static LIST term_MakePseudoLinear(TERM Term, NAT Depth, NAT Mark)
+/**************************************************************
+ INPUT: A Term and a variable and the current depth.
+ RETURNS: A list of pairs (<oldvar>,<newvar>)
+ EFFECT: The term is destructively made pseudo_linear.
+***************************************************************/
+{
+ LIST Result,Scan;
+ SYMBOL Top;
+
+ Result = list_Nil();
+
+ if (term_IsComplex(Term))
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ Result = list_Nconc(term_MakePseudoLinear(list_Car(Scan),Depth+1,Mark),
+ Result);
+ else {
+ Top = term_TopSymbol(Term);
+ if (symbol_IsVariable(Top)) {
+ if (term_VarIsMarked(Top, Mark)) {
+ if (Depth != (NAT)term_BindingValue(Top))
+ term_RplacTop(Term,symbol_CreateStandardVariable());
+ Result = list_Cons(list_PairCreate((POINTER)Top,
+ (POINTER)term_TopSymbol(Term)),
+ Result);
+ }
+ else {
+ term_CreateValueBinding(Top, Mark, (POINTER)Depth);
+ }
+ }
+ }
+
+ return Result;
+}
+
+
+LIST term_RenamePseudoLinear(TERM Term, SYMBOL Var)
+/**************************************************************
+ INPUT: A Term and a variable.
+ RETURNS: A list of pairs (<oldvar>,<newvar>)
+ EFFECT: The term is destructively renamed.
+***************************************************************/
+{
+ NAT Mark;
+ LIST Result;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !symbol_IsVariable(Var) || term_InBindingPhase()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_RenamePseudoLinear: Illegal input or context.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+ symbol_SetStandardVarCounter(Var);
+
+ term_NewMark();
+ Mark = term_ActMark();
+ Result = term_MakePseudoLinear(Term,0,Mark);
+
+ term_StopBinding();
+
+ return Result;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * STAMP FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+NAT term_GetStampID(void)
+/**************************************************************
+ INPUT: None
+ RETURNS: An identifier that must be used for some stamp functions
+ EFFECT: Each module using the term stamp has to request an
+ identifier that is needed for function term_StampOverflow
+ The purpose of this identifier is to synchronize
+ different modules in case of an overflow of the variable
+ term_STAMP.
+***************************************************************/
+{
+ if (term_STAMPUSERS >= term_MAXSTAMPUSERS) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n In term_GetStampID: no more free stamp IDs.");
+ misc_UserErrorReport("\n You have to increase the constant term_MAXSTAMPUSERS.");
+ misc_FinishUserErrorReport();
+ }
+
+ return term_STAMPUSERS++;
+}
+
+
+BOOL term_StampOverflow(NAT ID)
+/**************************************************************
+ INPUT: The identifier of the calling module as returned by
+ the function term_GetStampID.
+ RETURNS: True if an overflow of the variable term_STAMP occurred
+ for the module with the identifier ID.
+ CAUTION: If an overflow occurred for a module you can test that
+ only once!!! After the first test the overflow flag
+ is cleared for that module.
+***************************************************************/
+{
+ BOOL Result = FALSE;
+ NAT i;
+
+#ifdef CHECK
+ if (ID >= term_MAXSTAMPUSERS) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_StampOverflow: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (term_STAMP == NAT_MAX) {
+ term_STAMP = 0;
+ /* set overflow flag for all other modules */
+ for (i = 0; i < term_MAXSTAMPUSERS; i++)
+ term_STAMPOVERFLOW[i] = TRUE;
+ term_STAMPOVERFLOW[ID] = FALSE;
+ Result = TRUE;
+ } else if (term_STAMPOVERFLOW[ID]) {
+ term_STAMPOVERFLOW[ID] = FALSE;
+ Result = TRUE;
+ }
+ return Result;
+}
+
+void term_SetTermSubtermStamp(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: void.
+ EFFECT: Sets the current stamp to <Term> and its subterms.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_SetTermSubtermStamp: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_SetTermStamp(Term);
+ list_Apply((void (*)(POINTER)) term_SetTermSubtermStamp,
+ term_ArgumentList(Term));
+}
+
+LIST term_ListOfAtoms(TERM Term, SYMBOL Predicate)
+/**************************************************************
+ INPUT: A term and a predicate symbol.
+ RETURNS: A list of pointers to all atoms in Term with
+ predicate symbol <Predicate>.
+***************************************************************/
+{
+ if (symbol_Equal(term_TopSymbol(Term), Predicate))
+ return list_List(Term);
+ else {
+ LIST Result, List;
+
+ Result = list_Nil();
+ for (List = term_ArgumentList(Term); !list_Empty(List); List = list_Cdr(List))
+ Result = list_Nconc(Result, term_ListOfAtoms(list_Car(List), Predicate));
+ return Result;
+ }
+}
+
+/* Currently only in CHECK mode */
+#ifdef CHECK
+
+void term_StartStamp(void)
+/**************************************************************
+ INPUT: None
+ RETURNS: Nothing
+ EFFECT: The stamp is prepared for a new term traversal.
+***************************************************************/
+{
+ if (term_STAMPBLOCKED) {
+ /* Error: the Stamp is already used */
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_StartStamp: Illegal context, term stamp is already used.");
+ misc_FinishErrorReport();
+ }
+ else {
+ term_STAMP++;
+ term_STAMPBLOCKED = TRUE;
+ }
+}
+
+#endif
+
+LIST term_FindAllAtoms(TERM Term, SYMBOL Predicate)
+/**********************************************************************
+ INPUT: A term Term and a symbol Predicate.
+ RETURN: A list of all atoms of Term with Symbol as top symbol.
+***********************************************************************/
+{
+ int stack;
+ LIST Result;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !symbol_IsPredicate(Predicate)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In term_FindAllPredicates: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ stack = stack_Bottom();
+ Result = list_Nil();
+
+ do {
+ if (term_TopSymbol(Term) == Predicate) {
+ Result = list_Cons(Term, Result);
+ } else if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+
+ while (!stack_Empty(stack) && list_Empty(stack_Top()))
+ stack_Pop();
+
+ if (!stack_Empty(stack)) {
+ Term = list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(stack));
+
+ return Result;
+}
+
+BOOL term_CheckTermIntern(TERM Term, BOOL Links)
+/**************************************************************************
+ INPUT: A term and a boolean.
+ RETURN: True iff 1) the arity of each top symbol is equal to the number
+ of arguments of symbol's term.
+ and 2) either all father links are set correctly iff Links is TRUE
+ or none is set iff Links is FALSE.
+ COMMENT: Intern function of term_CheckTerm.
+***************************************************************************/
+{
+ LIST Scan;
+ SYMBOL Top;
+
+ if (!term_IsTerm(Term))
+ return FALSE;
+
+ Top = term_TopSymbol(Term);
+ if (symbol_IsSignature(Top) &&
+ symbol_Arity(Top) != -1 &&
+ symbol_Arity(Top) != (int)list_Length(term_ArgumentList(Term)))
+ return FALSE;
+
+ if (symbol_IsVariable(Top) && !list_Empty(term_ArgumentList(Term)))
+ return FALSE;
+
+ if (Links) {
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (term_Superterm(list_Car(Scan)) != Term ||
+ !term_CheckTermIntern(list_Car(Scan), Links))
+ return FALSE;
+ }
+ }
+ else {
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (term_Superterm(list_Car(Scan)) != term_Null() ||
+ !term_CheckTermIntern(list_Car(Scan), Links))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+BOOL term_CheckTerm(TERM Term)
+/********************************************************************************
+ INPUT : A term Term.
+ RETURN: TRUE iff eihter all or no father links are set AND
+ the length of any argument list matches the arity of the respective symbol
+*********************************************************************************/
+{
+ if (term_IsComplex(Term) &&
+ term_Superterm(term_FirstArgument(Term)) != term_Null())
+ /* check father links as well */
+ return term_CheckTermIntern(Term, TRUE);
+ else
+ return term_CheckTermIntern(Term, FALSE);
+}
diff --git a/test/spass/term.h b/test/spass/term.h
new file mode 100644
index 0000000..3acb237
--- /dev/null
+++ b/test/spass/term.h
@@ -0,0 +1,612 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * TERMS * */
+/* * * */
+/* * $Module: TERM * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _TERM_
+#define _TERM_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "symbol.h"
+#include "stack.h"
+
+/**************************************************************/
+/* Structures */
+/**************************************************************/
+
+/* In CHECK mode you can block the stamp for all terms,
+ so no other function can use the macro term_IncStamp(),
+ which must be used for initialization at the beginning
+ of a new traversal */
+
+typedef struct term {
+ SYMBOL symbol;
+ union {
+ LIST termlist;
+ struct term* term;
+ } super;
+ LIST args;
+ NAT stamp;
+ NAT size;
+} *TERM, TERM_NODE;
+
+
+/* Data Structures and Macros for Marking of variables, used in */
+/* all functions extracting variables from terms. */
+
+extern NAT term_MARK;
+extern POINTER term_BIND[symbol__MAXVARIABLES][2];
+
+#ifdef CHECK
+extern BOOL term_BINDPHASE;
+static __inline__ void term_StartBinding(void) { term_BINDPHASE=TRUE; }
+static __inline__ void term_StopBinding(void) { term_BINDPHASE=FALSE; }
+static __inline__ BOOL term_InBindingPhase(void) { return term_BINDPHASE; }
+#else
+static __inline__ void term_StartBinding(void) { }
+static __inline__ void term_StopBinding(void) { }
+#endif
+
+static __inline__ NAT term_NullMark(void)
+{
+ return 0;
+}
+
+
+static __inline__ NAT term_BindingMark(SYMBOL Var)
+{
+ return (NAT) term_BIND[symbol_VarIndex(Var)][0];
+}
+
+
+static __inline__ void term_SetBindingMark(SYMBOL Var, NAT Mark)
+{
+ term_BIND[symbol_VarIndex(Var)][0] = (POINTER) Mark;
+}
+
+
+static __inline__ POINTER term_BindingValue(SYMBOL Var)
+{
+ return term_BIND[symbol_VarIndex(Var)][1];
+}
+
+
+static __inline__ void term_SetBindingValue(SYMBOL Var, POINTER Value)
+{
+ term_BIND[symbol_VarIndex(Var)][1] = Value;
+}
+
+static __inline__ void term_CreateBinding(SYMBOL Var, NAT Mark)
+{
+ term_SetBindingMark(Var, Mark);
+}
+
+static __inline__ void term_ClearBinding(SYMBOL Var)
+{
+ term_SetBindingMark(Var, term_NullMark());
+}
+
+static __inline__ void term_CreateValueBinding(SYMBOL Var, NAT Mark, POINTER Value)
+{
+ term_SetBindingMark(Var, Mark);
+ term_SetBindingValue(Var, Value);
+}
+
+
+static __inline__ BOOL term_VarIsMarked(SYMBOL Var, NAT Mark)
+{
+ return term_BindingMark(Var) >= Mark;
+}
+
+
+static __inline__ NAT term_ActMark(void)
+{
+ NAT MarkVar;
+ if (term_MARK == NAT_MAX) {
+ int i;
+ for (i = 0; i < symbol_MaxVars(); i++)
+ term_BIND[i][0] = (POINTER) term_NullMark();
+ term_MARK = 1;
+ }
+ MarkVar = term_MARK++;
+ return MarkVar;
+}
+
+
+static __inline__ void term_NewMark(void)
+{
+ if (term_MARK == NAT_MAX) {
+ int i;
+ for (i = 0; i < symbol_MaxVars(); i++)
+ term_BIND[i][0] = (POINTER) term_NullMark();
+ term_MARK = 1;
+ }
+ term_MARK++;
+}
+
+
+static __inline__ NAT term_OldMark(void)
+{
+ return term_MARK - 1;
+}
+
+
+/**************************************************************/
+/* Macros */
+/**************************************************************/
+
+static __inline__ TERM term_Null(void)
+{
+ return (TERM)NULL;
+}
+
+static __inline__ SYMBOL term_TopSymbol(TERM T)
+{
+ return T->symbol;
+}
+
+
+static __inline__ void term_RplacTop(TERM T, SYMBOL S)
+{
+ T->symbol = S;
+}
+
+
+static __inline__ LIST term_SupertermList(TERM T)
+{
+ return T->super.termlist;
+}
+
+
+static __inline__ void term_RplacSupertermList(TERM T, LIST L)
+{
+ T->super.termlist = L;
+}
+
+
+static __inline__ LIST term_AtomsLiterals(TERM T)
+{
+ return T->super.termlist;
+}
+
+
+static __inline__ TERM term_Superterm(TERM T)
+{
+ return T->super.term;
+}
+
+
+static __inline__ void term_RplacSuperterm(TERM T1, TERM T2)
+{
+ T1->super.term = T2;
+}
+
+
+static __inline__ BOOL term_IsVariable(TERM T)
+{
+ return symbol_IsVariable(term_TopSymbol(T));
+}
+
+
+static __inline__ BOOL term_IsStandardVariable(TERM T)
+{
+ return symbol_IsStandardVariable(term_TopSymbol(T));
+}
+
+
+static __inline__ BOOL term_IsIndexVariable(TERM T)
+{
+ return symbol_IsIndexVariable(term_TopSymbol(T));
+}
+
+
+static __inline__ LIST term_ArgumentList(TERM T)
+{
+ return T->args;
+}
+
+
+static __inline__ void term_RplacArgumentList(TERM T, LIST A)
+{
+ T->args = A;
+}
+
+
+static __inline__ BOOL term_IsComplex(TERM T)
+{
+ return term_ArgumentList(T) != NULL;
+}
+
+
+static __inline__ BOOL term_IsConstant(TERM T)
+{
+ return !term_IsComplex(T) && !term_IsVariable(T);
+}
+
+
+static __inline__ BOOL term_IsAtom(TERM T)
+{
+ return symbol_IsPredicate(term_TopSymbol(T));
+}
+
+static __inline__ BOOL term_IsDeclaration(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: TRUE, if the term is a monadic atom, FALSE otherwise.
+***************************************************************/
+{
+ return (term_IsAtom(Term) && symbol_IsBaseSort(term_TopSymbol(Term)));
+}
+
+
+static __inline__ TERM term_FirstArgument(TERM T)
+{
+ return (TERM) list_First(T->args);
+}
+
+
+static __inline__ void term_RplacFirstArgument(TERM T1, TERM T2)
+{
+ list_Rplaca(T1->args, T2);
+}
+
+
+static __inline__ TERM term_SecondArgument(TERM T)
+{
+ return (TERM) list_Second(T->args);
+}
+
+
+static __inline__ void term_RplacSecondArgument(TERM T1, TERM T2)
+{
+ list_RplacSecond(T1->args, T2);
+}
+
+
+static __inline__ void term_Free(TERM T)
+{
+ memory_Free((char*) T, sizeof(TERM_NODE));
+}
+
+
+static __inline__ BOOL term_EqualTopSymbols(TERM T, TERM S)
+{
+ return symbol_Equal(term_TopSymbol(T), term_TopSymbol(S));
+}
+
+
+static __inline__ void term_EqualitySwap(TERM T)
+{
+ TERM Aux;
+ Aux = term_FirstArgument(T);
+ list_Rplaca(term_ArgumentList(T), (POINTER) term_SecondArgument(T));
+ list_Rplaca(list_Cdr(term_ArgumentList(T)), (POINTER) Aux);
+}
+
+
+/**************************************************************/
+/* Macros and Variables for the term's stamp */
+/**************************************************************/
+
+/* Maximum number of modules that use the term module's stamp */
+#define term_MAXSTAMPUSERS 20
+
+extern NAT term_STAMP;
+extern BOOL term_STAMPBLOCKED;
+
+static __inline__ NAT term_Stamp(void)
+{
+ return term_STAMP;
+}
+
+static __inline__ BOOL term_StampBlocked(void)
+{
+ return term_STAMPBLOCKED;
+}
+
+
+#ifdef CHECK
+
+/* In CHECK mode 'term_StartStamp' is a real function defined in */
+/* 'term.c'. */
+
+static __inline__ void term_StopStamp(void)
+{
+ term_STAMPBLOCKED = FALSE;
+}
+
+#else
+
+/* Attention: */
+/* You should check for Overflow before calling this function !!!!! */
+/* Use "term_StampOverflow" to do this. */
+/* If an overflow occurred, you have to reset the stamp of all terms */
+/* you're using. */
+static __inline__ void term_StartStamp(void)
+{
+ term_STAMP++;
+}
+
+static __inline__ void term_StopStamp(void)
+{ }
+
+#endif
+
+
+static __inline__ NAT term_TermStamp(TERM T)
+{
+ return T->stamp;
+}
+
+static __inline__ void term_SetTermStamp(TERM T)
+{
+ T->stamp = term_STAMP;
+}
+
+static __inline__ NAT term_Size(TERM T)
+{
+ return T->size;
+}
+
+static __inline__ void term_SetSize(TERM T, NAT s)
+{
+ T->size = s;
+}
+
+static __inline__ BOOL term_AlreadyVisited(TERM T)
+{
+ return T->stamp == term_STAMP;
+}
+
+static __inline__ BOOL term_HasTermStamp(TERM T)
+{
+ return T->stamp == term_STAMP;
+}
+
+static __inline__ void term_ResetTermStamp(TERM T)
+{
+ T->stamp = 0;
+}
+
+static __inline__ BOOL term_StampAlreadyReset(TERM T)
+{
+ return T->stamp == 0;
+}
+
+
+/**************************************************************/
+/* Functions on Term Creation And Deletion */
+/**************************************************************/
+
+void term_Init(void);
+
+TERM term_Create(SYMBOL, LIST);
+TERM term_CreateAddFather(SYMBOL, LIST);
+TERM term_CreateStandardVariable(void);
+void term_Delete(TERM);
+void term_DeleteIterative(TERM);
+
+/**************************************************************/
+/* Term Comparisons */
+/**************************************************************/
+
+BOOL term_Equal(TERM, TERM);
+BOOL term_EqualIterative(TERM, TERM); /* Unused */
+BOOL term_VariableEqual(TERM, TERM);
+BOOL term_IsGround(TERM);
+BOOL term_IsTerm(TERM);
+BOOL term_IsTermList(LIST);
+BOOL term_AllArgsAreVar(TERM);
+int term_CompareBySymbolOccurences(TERM, TERM);
+int term_CompareAbstract(TERM, TERM);
+BOOL term_CompareAbstractLEQ(TERM, TERM);
+
+
+/**************************************************************/
+/* Low Level Term Functions */
+/**************************************************************/
+
+TERM term_Copy(TERM);
+TERM term_CopyIterative(TERM); /* Unused */
+TERM term_CopyWithEmptyArgListNode(TERM, LIST, LIST*);
+void term_PrintWithEmptyArgListNode(TERM);
+BOOL term_ReplaceSubtermBy(TERM, TERM, TERM);
+void term_ReplaceVariable(TERM, SYMBOL, TERM);
+void term_ExchangeVariable(TERM, SYMBOL, SYMBOL);
+BOOL term_SubstituteVariable(SYMBOL, TERM, TERM*);
+NAT term_ComputeSize(TERM);
+void term_InstallSize(TERM);
+NAT term_Depth(TERM);
+BOOL term_ContainsSymbol(TERM, SYMBOL);
+BOOL term_Sharing(TERM);
+void term_AddFatherLinks(TERM);
+BOOL term_FatherLinksEstablished(TERM);
+TERM term_TopLevelTerm(TERM);
+BOOL term_HasPointerSubterm(TERM, TERM);
+BOOL term_HasSubterm(TERM, TERM);
+BOOL term_HasProperSuperterm(TERM, TERM);
+TERM term_FindSubterm(TERM, SYMBOL);
+LIST term_FindAllAtoms(TERM, SYMBOL);
+BOOL term_CheckTerm(TERM);
+NAT term_RootDistance(TERM);
+BOOL term_RootDistanceSmaller(TERM,TERM);
+
+static __inline__ LIST term_CopyTermList(LIST List)
+/**************************************************************
+ INPUT: A list of TERMs.
+ RETURNS: A deep copy of the list, i.e. the terms are copied, too.
+***************************************************************/
+{
+ return list_CopyWithElement(List, (POINTER (*)(POINTER))term_Copy);
+}
+
+static __inline__ void term_CopyTermsInList(LIST List)
+/**************************************************************
+ INPUT: A list of TERMs.
+ EFFECT: Replaces every term in the list with its copy.
+***************************************************************/
+{
+ list_NMapCar(List, (POINTER (*)(POINTER)) term_Copy);
+}
+
+static __inline__ void term_DeleteTermList(LIST List)
+/**************************************************************
+ INPUT: A list of TERMs.
+ RETURNS: Nothing.
+ EFFECT: The list is freed together with its elements.
+***************************************************************/
+{
+ list_DeleteWithElement(List, (void (*)(POINTER))term_Delete);
+}
+
+static __inline__ BOOL term_ListContainsTerm(LIST List, TERM Term)
+/**************************************************************
+ INPUT: A list of TERMs.
+ RETURNS: TRUE, if <List> contains <Term>, FALSE otherwise.
+ Terms are compared with respect to the term_Equal function.
+***************************************************************/
+{
+ return list_Member(List, Term, (BOOL (*)(POINTER,POINTER))term_Equal);
+}
+
+static __inline__ LIST term_DeleteDuplicatesFromList(LIST List)
+/**************************************************************
+ INPUT: A list of TERMs.
+ RETURNS: The list where duplicate terms are removed.
+ EFFECT: Terms are compared with respect to the term_Equal function.
+ The duplicate terms are not deleted.
+***************************************************************/
+{
+ return list_DeleteDuplicates(List, (BOOL (*)(POINTER, POINTER))term_Equal);
+}
+
+
+static __inline__ LIST term_DestroyDuplicatesInList(LIST Terms)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: The list where all duplicate terms are removed.
+ EFFECTS: The terms are compared with respect to the term_Equal function.
+ The duplicate terms are deleted, too.
+***************************************************************/
+{
+ return list_DeleteDuplicatesFree(Terms, (BOOL (*)(POINTER,POINTER))term_Equal,
+ (void (*)(POINTER))term_Delete);
+}
+
+
+
+/**************************************************************/
+/* Term Input and Output Functions */
+/**************************************************************/
+
+void term_Print(TERM);
+void term_PrettyPrint(TERM);
+void term_FPrint(FILE*, TERM);
+void term_TermListPrint(LIST);
+void term_TermListFPrint(FILE*, LIST);
+
+
+void term_PrintPrefix(TERM);
+void term_FPrintPrefix(FILE*, TERM);
+void term_TermListPrintPrefix(LIST);
+void term_TermListFPrintPrefix(FILE*, LIST);
+
+void term_FPrintOtterPrefix(FILE*, TERM);
+void term_TermListFPrintOtterPrefix(FILE*, LIST);
+
+void term_FPrintPosition(FILE*,TERM,TERM);
+
+static __inline__ void term_PrintPosition(TERM TopTerm, TERM Subterm)
+{
+ term_FPrintPosition(stdout, TopTerm, Subterm);
+}
+
+/**************************************************************/
+/* High Level Term Functions */
+/**************************************************************/
+
+void term_ToCoVariables(TERM);
+NAT term_Bytes(TERM);
+
+void term_MarkVariables(TERM, NAT);
+void term_CountSymbols(TERM);
+LIST term_ListOfVariables(TERM);
+LIST term_VariableSymbols(TERM);
+LIST term_ListOfAtoms(TERM,SYMBOL);
+LIST term_ListOfConstants(TERM);
+LIST term_ListOfFunctions(TERM);
+NAT term_NumberOfVarOccs(TERM);
+NAT term_NumberOfSymbolOccurrences(TERM, SYMBOL);
+BOOL term_ContainsFunctions(TERM);
+BOOL term_ContainsVariable(TERM,SYMBOL);
+SYMBOL term_MaxVar(TERM);
+
+void term_StartMinRenaming(void);
+void term_StartMaxRenaming(SYMBOL);
+TERM term_Rename(TERM);
+SYMBOL term_GetRenamedVarSymbol(SYMBOL);
+
+LIST term_RenamePseudoLinear(TERM, SYMBOL);
+
+/**************************************************************/
+/* Stamp Functions */
+/**************************************************************/
+
+/* Currently only in CHECK mode */
+#ifdef CHECK
+void term_StartStamp(void);
+#endif
+
+void term_SetTermSubtermStamp(TERM T);
+
+NAT term_GetStampID(void);
+BOOL term_StampOverflow(NAT);
+
+
+#endif
diff --git a/test/spass/terminator.c b/test/spass/terminator.c
new file mode 100644
index 0000000..7335204
--- /dev/null
+++ b/test/spass/terminator.c
@@ -0,0 +1,319 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * TERMINATOR * */
+/* * * */
+/* * $Module: REDRULES * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "terminator.h"
+#include "list.h"
+
+
+static LIST red_GetTerminatorPartnerLits(TERM Atom, LITERAL Lit,
+ BOOL UnitsOnly, LIST IndexList)
+/**************************************************************
+ INPUT: An atom, a literal, a boolean flag and a list of SHARED_INDEXes.
+ RETURNS: A list of literals with sign complementary to <Lit>
+ that are unifiable with <Atom>. The literals are searched
+ in all SHARED_INDEXes from <IndexList>. Additionally,
+ if <Unitsonly> is true, only literals from unit clauses
+ are returned.
+ EFFECT: <Atom> is a copy of <Lit> where some substitution
+ was applied and equality literals might have been swapped.
+ <Lit> is just needed to check whether the unifiable
+ literals are complementary.
+***************************************************************/
+{
+ LIST Result, Unifiers, LitScan;
+ LITERAL NextLit;
+
+ Result = list_Nil();
+ for ( ; !list_Empty(IndexList); IndexList = list_Cdr(IndexList)) {
+ Unifiers = st_GetUnifier(cont_LeftContext(),
+ sharing_Index(list_Car(IndexList)),
+ cont_RightContext(), Atom);
+ for ( ; !list_Empty(Unifiers); Unifiers = list_Pop(Unifiers)) {
+ if (!term_IsVariable(list_Car(Unifiers))) {
+ for (LitScan = sharing_NAtomDataList(list_Car(Unifiers));
+ !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) {
+ NextLit = list_Car(LitScan);
+ if (clause_LiteralsAreComplementary(Lit, NextLit) &&
+ (!UnitsOnly || clause_Length(clause_LiteralOwningClause(NextLit))==1))
+ /* The partner literals must have complementary sign and
+ if <UnitsOnly> == TRUE they must be from unit clauses. */
+ Result = list_Cons(NextLit, Result);
+ }
+ }
+ }
+ }
+ return Result;
+}
+
+
+static CLAUSE red_CreateTerminatorEmptyClause(LIST FoundMap, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A list of pairs (l1, l2), where l1 and l2 are unifiable
+ literals with complementary sign and a flag store.
+ More accurately, a substitution s exists,
+ such that l1 s = l2 s for all pairs (l1,l2) in
+ <FoundMap>.
+ For all literals l from the involved clauses
+ there exists one pair (l1,l2) in <FoundMap>
+ with l1=l or l2=l.
+ The flags store and the precedence are needed to create
+ the new clause.
+ RETURNS: A newly created empty clause, where the data
+ (parents,...) is set according to <FoundMap>.
+***************************************************************/
+{
+ CLAUSE Result, PClause;
+ LITERAL Lit;
+ LIST Parents;
+ NAT depth;
+
+ Result = clause_Create(list_Nil(), list_Nil(), list_Nil(), Flags, Precedence);
+ Parents = list_Nil();
+ depth = 0;
+ for (; !list_Empty(FoundMap); FoundMap = list_Cdr(FoundMap)) {
+ Lit = list_PairSecond(list_Car(FoundMap));
+ PClause = clause_LiteralOwningClause(Lit);
+ Parents = list_Cons(PClause, Parents);
+ depth = misc_Max(depth, clause_Depth(PClause));
+ clause_AddParentClause(Result, clause_Number(PClause));
+ clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit));
+
+ Lit = list_PairFirst(list_Car(FoundMap));
+ PClause = clause_LiteralOwningClause(Lit);
+ Parents = list_Cons(PClause, Parents);
+ depth = misc_Max(depth, clause_Depth(PClause));
+ clause_AddParentClause(Result, clause_Number(PClause));
+ clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit));
+ }
+ clause_SetFromTerminator(Result);
+ clause_SetDepth(Result, depth+1);
+ clause_SetSplitDataFromList(Result, Parents);
+ list_Delete(Parents);
+ return Result;
+}
+
+
+static BOOL red_TerminatorLitIsBetter(LITERAL L1, NAT S1, LITERAL L2, NAT S2)
+/**************************************************************
+ INPUT: Two literals and its sizes wrt. some substitution.
+ RETURNS: TRUE, if <L1> is 'better' than <L2>, FALSE otherwise.
+ EFFECT: 1. Positive literals are 'better' than negative literals
+ 2. If both literals have the same sign, the bigger literal
+ is better.
+ This is an heuristic that has shown to be useful in practice.
+ This function is used as parameter for the function
+ clause_MoveBestLiteralToFront.
+***************************************************************/
+{
+ if ((clause_LiteralIsNegative(L2) && clause_LiteralIsPositive(L1)) ||
+ /* The following conditions do the same as this condition: */
+ /* (!clause_LiteralsAreComplementary(L1, L2) && S1 > S2) */
+ (clause_LiteralIsPositive(L1) && S1 > S2) ||
+ (clause_LiteralIsNegative(L2) && S1 > S2))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+static CLAUSE red_SearchTerminator(NAT n, LIST RestLits, LIST FoundMap,
+ SUBST Subst, SYMBOL GlobalMaxVar,
+ LIST IndexList, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A natural number, a list of literals, a list of pairs,
+ a substitution, the maximum variable occurring in all
+ involved clauses, a list of SHARED_INDEXes, a flag store
+ and a precedence.
+ RETURNS: An empty clause, if a terminator situation was found,
+ NULL otherwise.
+ EFFECT: This recursive function implements the search for
+ a terminator situation with at most <n> non-unit clauses.
+ <RestLits> is the lists of literals actually missing
+ a complementary partner literal.
+ <FoundMap> is a list of pairs (l1,l2), where l1 and l2
+ are complementary, unifiable literals.
+ <Subst> is the common substitution of all those pairs.
+ <GlobalMaxVar> is the maximum variable from all
+ involved clauses.
+ To enable the search all involved clauses are made
+ variable-disjoint.
+ At the moment the function stops, if ANY terminator
+ situation occurred. This might not be desirable
+ if splitting is enabled, since there might be other
+ terminator situations resulting in an empty clause
+ of lower split level.
+ The flag store and the precedence are needed to create
+ the new clause.
+***************************************************************/
+{
+ if (list_Empty(RestLits)) {
+ /* We found a terminator situation, so stop the recursion */
+ return red_CreateTerminatorEmptyClause(FoundMap, Flags, Precedence);
+ } else {
+ CLAUSE Result, PClauseCopy;
+ LITERAL Lit, PLit;
+ SYMBOL NewMaxVar;
+ SUBST NewSubst, RightSubst;
+ TERM AtomCopy;
+ LIST ClashList, ToDoList;
+ BOOL Swapped;
+ NAT Limit;
+ int PLitInd;
+
+ Swapped = FALSE;
+ Result = clause_Null();
+ clause_MoveBestLiteralToFront(RestLits, Subst, GlobalMaxVar,
+ red_TerminatorLitIsBetter);
+ Lit = list_Car(RestLits);
+ RestLits = list_Cdr(RestLits);
+ AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit)));
+
+ /* The following 'endless' loop runs twice for equality literals */
+ /* and only once for other literals. */
+ while (TRUE) {
+ ClashList = red_GetTerminatorPartnerLits(AtomCopy, Lit, n==0, IndexList);
+ for (; !list_Empty(ClashList) && Result==NULL;
+ ClashList = list_Pop(ClashList)) {
+ PLit = list_Car(ClashList);
+ PLitInd = clause_LiteralGetIndex(PLit);
+ PClauseCopy = clause_Copy(clause_LiteralOwningClause(PLit));
+ Limit = clause_Length(PClauseCopy) == 1 ? n : n-1;
+
+ clause_RenameVarsBiggerThan(PClauseCopy, GlobalMaxVar);
+
+ PLit = clause_GetLiteral(PClauseCopy, PLitInd);
+ FoundMap = list_Cons(list_PairCreate(Lit, PLit), FoundMap);
+ ToDoList = clause_GetLiteralListExcept(PClauseCopy, PLitInd);
+ ToDoList = list_Nconc(ToDoList, list_Copy(RestLits));
+
+ NewMaxVar = clause_SearchMaxVar(PClauseCopy);
+ if (symbol_GreaterVariable(GlobalMaxVar, NewMaxVar))
+ NewMaxVar = GlobalMaxVar;
+
+ cont_Check();
+ if (!unify_UnifyNoOC(cont_LeftContext(), AtomCopy,
+ cont_RightContext(), clause_LiteralAtom(PLit))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In red_SearchTerminator: Unification failed.");
+ misc_FinishErrorReport();
+ }
+ subst_ExtractUnifier(cont_LeftContext(), &NewSubst,
+ cont_RightContext(), &RightSubst);
+ cont_Reset();
+
+ /* The domains of both substitutions are disjoint */
+ /* so we do just a simple union operation. */
+ NewSubst = subst_NUnion(NewSubst, RightSubst);
+ RightSubst = NewSubst;
+ NewSubst = subst_Compose(NewSubst, subst_Copy(Subst));
+ subst_Delete(RightSubst);
+
+ Result = red_SearchTerminator(Limit, ToDoList, FoundMap, NewSubst,
+ NewMaxVar, IndexList, Flags, Precedence);
+
+ clause_Delete(PClauseCopy);
+ subst_Delete(NewSubst);
+ list_Delete(ToDoList);
+ list_PairFree(list_Car(FoundMap));
+ FoundMap = list_Pop(FoundMap);
+ }
+ /* loop control */
+ if (!fol_IsEquality(AtomCopy) || Swapped || Result!=NULL)
+ break;
+ else {
+ list_Delete(ClashList);
+ term_EqualitySwap(AtomCopy);
+ Swapped = TRUE;
+ }
+ }
+ /* cleanup */
+ term_Delete(AtomCopy);
+ /* <ClashList> may be non-empty since the loop stops */
+ /* if a terminator was found. */
+ list_Delete(ClashList);
+
+ return Result;
+ }
+}
+
+
+CLAUSE red_Terminator(CLAUSE RedClause, NAT n, SHARED_INDEX WoIndex,
+ SHARED_INDEX UsIndex, FLAGSTORE Flags,
+ PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A clause, two shared indexes, a number <n>
+ restricting the number of non-unit clauses in
+ a possible terminator situation, a flag store
+ and a precedence.
+ RETURNS: An empty clause if a terminator with at most <n>
+ non-unit clauses is found, NULL otherwise.
+ EFFECT: See also description of red_SearchTerminator.
+***************************************************************/
+{
+ LIST Rest, IndexList;
+ CLAUSE Result;
+
+ if (clause_Length(RedClause) > 1) /* non-unit clause */
+ n--;
+
+ /* Pass the indexes as a list to sub-functions */
+ IndexList = list_Cons(WoIndex, list_List(UsIndex));
+ Rest = clause_GetLiteralList(RedClause);
+ Result = red_SearchTerminator(n, Rest, list_Nil(), subst_Nil(),
+ clause_MaxVar(RedClause), IndexList, Flags,
+ Precedence);
+
+ /* cleanup */
+ list_Delete(IndexList);
+ list_Delete(Rest);
+
+ return Result;
+}
diff --git a/test/spass/terminator.h b/test/spass/terminator.h
new file mode 100644
index 0000000..8ddf32d
--- /dev/null
+++ b/test/spass/terminator.h
@@ -0,0 +1,58 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * TERMINATOR * */
+/* * * */
+/* * $Module: REDRULES * */
+/* * * */
+/* * Copyright (C) 1999, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+#ifndef _TERMINATOR_
+#define _TERMINATOR_
+
+
+#include "misc.h"
+#include "symbol.h"
+#include "clause.h"
+#include "sharing.h"
+#include "flags.h"
+
+CLAUSE red_Terminator(CLAUSE,NAT,SHARED_INDEX,SHARED_INDEX,FLAGSTORE,PRECEDENCE);
+
+#endif
diff --git a/test/spass/top.c b/test/spass/top.c
new file mode 100644
index 0000000..073add9
--- /dev/null
+++ b/test/spass/top.c
@@ -0,0 +1,1648 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * TOP MODULE OF SPASS * */
+/* * * */
+/* * $Module: TOP * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 35442 $ * */
+/* $State$ * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $ * */
+/* $Author: jeffc $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/*** MAIN LOOP *************************************************/
+
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "dfg.h"
+#include "defs.h"
+#include "ia.h"
+#include "rules-inf.h"
+#include "rules-sort.h"
+#include "rules-split.h"
+#include "terminator.h"
+#include "rules-red.h"
+#include "analyze.h"
+#include "clock.h"
+#include "stringsx.h"
+#include "options.h"
+#include "context.h"
+#include "cnf.h"
+#include "search.h"
+#include "hasharray.h"
+#include "closure.h"
+#include <errno.h>
+#include <stdlib.h>
+
+
+/**************************************************************/
+/* Types and Variables */
+/**************************************************************/
+
+static const char *top_InputFile;
+
+static OPTID top_RemoveFileOptId;
+
+typedef enum {top_PROOF, top_COMPLETION, top_RESOURCE} top_SEARCHRESULT;
+
+
+/**************************************************************/
+/* Catch Signals Section */
+/**************************************************************/
+
+#if (defined(SPASS_SIGNALS))
+#include <signal.h>
+
+static PROOFSEARCH *top_PROOFSEARCH;
+
+static void top_SigHandler(int Signal)
+/**************************************************************
+ INPUT:
+ RETURNS:
+ EFFECT:
+***************************************************************/
+{
+ if (Signal == SIGSEGV || Signal == SIGBUS) {
+ puts("\n\n\tSPASS is going to crash. This is probably caused by a");
+ puts("\tbug in SPASS. Please send a copy of the input file(s) together");
+ puts("\twith the used options to weidenb@mpi-sb.mpg.de, and someone will");
+ puts("\ttry to fix the problem.\n");
+ abort();
+ }
+
+ if (Signal == SIGINT || Signal == SIGTERM) {
+ clock_StopPassedTime(clock_OVERALL);
+ printf("\nSPASS %s ", misc_VERSION);
+ puts("\nSPASS beiseite: Ran out of time. SPASS was killed.");
+ printf("Problem: %s ",
+ (top_InputFile != (char*)NULL ? top_InputFile : "Read from stdin."));
+ printf("\nSPASS derived %d clauses, backtracked %d clauses "
+ "and kept %d clauses.",
+ (*top_PROOFSEARCH == (PROOFSEARCH)NULL ? 0 : prfs_DerivedClauses(*top_PROOFSEARCH)),
+ (*top_PROOFSEARCH == (PROOFSEARCH)NULL ? 0 : prfs_BacktrackedClauses(*top_PROOFSEARCH)),
+ (*top_PROOFSEARCH == (PROOFSEARCH)NULL ? 0 : prfs_KeptClauses(*top_PROOFSEARCH)));
+ printf("\nSPASS allocated %lu KBytes.", memory_DemandedBytes()/1024);
+ fputs("\nSPASS spent\t", stdout);
+ clock_PrintTime(clock_OVERALL);
+ fputs(" on the problem.\n\t\t", stdout);
+ clock_PrintTime(clock_INPUT);
+ fputs(" for the input.\n\t\t", stdout);
+ clock_PrintTime(clock_CNF);
+ fputs(" for the FLOTTER CNF translation.\n\t\t", stdout);
+ clock_PrintTime(clock_INFERENCE);
+ fputs(" for inferences.\n\t\t", stdout);
+ clock_PrintTime(clock_BACKTRACK);
+ fputs(" for the backtracking.\n\t\t", stdout);
+ clock_PrintTime(clock_REDUCTION);
+ puts(" for the reduction.");
+ }
+
+ if (opts_IsSet(top_RemoveFileOptId))
+ remove(top_InputFile);
+
+ exit(EXIT_FAILURE);
+}
+
+#endif
+
+
+/**************************************************************/
+/* Clause Selection Functions */
+/**************************************************************/
+
+static CLAUSE top_SelectClauseDepth(LIST List, FLAGSTORE Flags)
+/**************************************************************
+ INPUT: A list of clauses and a flag store.
+ RETURNS: A clause selected from the list.
+ EFFECT: This function selects a clause from the list according
+ to the following criteria:
+ 1. minimal depth
+ 2. minimal weight
+ 3a. maximal number of variable occurrences, if the flag
+ 'PrefVar' is TRUE
+ 3b. minimal number of variable occurrences, if 'PrefVar'
+ is FALSE
+***************************************************************/
+{
+ CLAUSE Result;
+ NAT Vars,NewVars,Weight,Depth,NewDepth;
+
+ Result = (CLAUSE)list_Car(List);
+ Depth = clause_Depth(Result);
+ Weight = clause_Weight(Result);
+ Vars = clause_NumberOfVarOccs(Result);
+ List = list_Cdr(List);
+
+ while (!list_Empty(List)) {
+ NewDepth = clause_Depth(list_Car(List));
+ if (NewDepth <= Depth) {
+ if (NewDepth < Depth || clause_Weight(list_Car(List)) < Weight) {
+ Depth = NewDepth;
+ Result = (CLAUSE)list_Car(List);
+ Weight = clause_Weight(Result);
+ Vars = clause_NumberOfVarOccs(list_Car(List));
+ }
+ else
+ if (clause_Weight(list_Car(List)) == Weight) {
+ NewVars = clause_NumberOfVarOccs(list_Car(List));
+ if (flag_GetFlagValue(Flags, flag_PREFVAR)) {
+ if (Vars < NewVars) {
+ Depth = NewDepth;
+ Result = (CLAUSE)list_Car(List);
+ Weight = clause_Weight(Result);
+ Vars = NewVars;
+ }
+ }
+ else
+ if (Vars > NewVars) {
+ Depth = NewDepth;
+ Result = (CLAUSE)list_Car(List);
+ Weight = clause_Weight(Result);
+ Vars = NewVars;
+ }
+ }
+ }
+ List = list_Cdr(List);
+ }
+
+ return Result;
+}
+
+
+static CLAUSE top_SelectMinimalWeightClause(LIST List, FLAGSTORE Flags)
+/**************************************************************
+ INPUT: A list of clauses and a flag store.
+ RETURNS: A clause selected from the list.
+ EFFECT: This function selects a clause with minimal weight.
+ If more than one clause has minimal weight and the flag
+ 'PrefVar' is TRUE, a clause with maximal number of variable
+ occurrences is selected. If 'PrefVar' is FALSE, a clause with
+ minimal number of variable occurrences is selected.
+ If two clauses are equal with respect to the two criteria
+ the clause with the smaller list position is selected.
+ CAUTION: THE LIST HAS TO BY SORTED BY WEIGHT IN ASCENDING ORDER!
+***************************************************************/
+{
+ CLAUSE Result;
+ NAT Vars, NewVars, Weight;
+
+#ifdef CHECK
+ /* Check invariant: List has to be sorted by weight (ascending) */
+ LIST Scan;
+ Weight = clause_Weight(list_Car(List));
+ for (Scan = list_Cdr(List); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ NAT NewWeight;
+ NewWeight = clause_Weight(list_Car(Scan));
+ if (NewWeight < Weight) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In top_SelectMinimalConWeightClause: clause list ");
+ misc_ErrorReport("isn't sorted by weight");
+ misc_FinishErrorReport();
+ }
+ Weight = NewWeight;
+ }
+#endif
+
+ Result = (CLAUSE)list_Car(List);
+ Weight = clause_Weight(Result);
+ Vars = clause_NumberOfVarOccs(Result);
+ List = list_Cdr(List);
+
+ while (!list_Empty(List)) {
+ if (clause_Weight(list_Car(List)) == Weight) {
+ NewVars = clause_NumberOfVarOccs(list_Car(List));
+ if (flag_GetFlagValue(Flags, flag_PREFVAR)) {
+ if (Vars < NewVars) {
+ Result = (CLAUSE)list_Car(List);
+ Weight = clause_Weight(Result);
+ Vars = NewVars;
+ }
+ }
+ else
+ if (Vars > NewVars) {
+ Result = (CLAUSE)list_Car(List);
+ Weight = clause_Weight(Result);
+ Vars = NewVars;
+ }
+ }
+ else
+ return Result;
+ List = list_Cdr(List);
+ }
+ return Result;
+}
+
+
+static CLAUSE top_SelectMinimalConWeightClause(LIST List, FLAGSTORE Flags)
+/**************************************************************
+ INPUT: A non-empty list of clauses and a flag store.
+ RETURNS: A clause selected from the list.
+ EFFECT: This function selects a clause from the list in a
+ similar way as the function top_SelectMinimalWeightClause.
+ The only difference is that conjecture clauses are
+ preferred over axiom clauses, because their weight
+ is divided by a factor given by the flag 'PrefCon'.
+***************************************************************/
+{
+ CLAUSE Result;
+ NAT NewWeight,Weight, NewVars, Vars, Factor;
+
+ Result = (CLAUSE)list_Car(List);
+ Factor = flag_GetFlagValue(Flags, flag_PREFCON);
+ Weight = clause_Weight(Result);
+ if (clause_GetFlag(Result, CONCLAUSE))
+ Weight = Weight / Factor;
+ Vars = clause_NumberOfVarOccs(list_Car(List));
+ List = list_Cdr(List);
+
+ while (!list_Empty(List)) {
+ NewWeight = clause_Weight(list_Car(List));
+ if (clause_GetFlag(list_Car(List),CONCLAUSE))
+ NewWeight = NewWeight / Factor;
+ if (NewWeight < Weight) {
+ Weight = NewWeight;
+ Result = list_Car(List);
+ Vars = clause_NumberOfVarOccs(list_Car(List));
+ }
+ else {
+ if (NewWeight == Weight) {
+ NewVars = clause_NumberOfVarOccs(list_Car(List));
+ if (flag_GetFlagValue(Flags, flag_PREFVAR)) {
+ if (Vars < NewVars) {
+ Result = (CLAUSE)list_Car(List);
+ Weight = NewWeight;
+ Vars = NewVars;
+ }
+ }
+ else
+ if (Vars > NewVars) {
+ Result = (CLAUSE)list_Car(List);
+ Weight = NewWeight;
+ Vars = NewVars;
+ }
+ }
+ }
+
+ List = list_Cdr(List);
+ }
+ return Result;
+}
+
+
+/*static CLAUSE top_SelectClauseDepth(LIST List)*/
+/**************************************************************
+ INPUT: A list of clauses.
+ RETURNS: A clause selected from the list.
+ EFFECT:
+***************************************************************/
+/*{
+ CLAUSE Result;
+ int Min, Depth;
+
+ Result = (CLAUSE)list_Car(List);
+ Depth = clause_Depth(Result);
+ Min = Depth * clause_Weight(Result);
+ List = list_Cdr(List);
+
+ if (Depth == 0)
+ return Result;
+
+ while (!list_Empty(List)) {
+ Depth = clause_Depth(list_Car(List));
+ if (Min > Depth * clause_Weight(list_Car(List))) {
+ Result = list_Car(List);
+ if (Depth == 0)
+ return Result;
+ Min = clause_Depth(Result) * clause_Weight(Result);
+ }
+ List = list_Cdr(List);
+ }
+
+ return Result;
+}*/
+
+
+static LIST top_GetLiteralsForSplitting(CLAUSE Clause)
+/**************************************************************
+ INPUT: A clause.
+ RETURNS: A list of succedent literal indices where every single
+ literal doesn't share any variables with other literals.
+ If the clause is horn, an empty list is returned.
+***************************************************************/
+{
+ LIST* Variables; /* An array, mapping literal index to list of variables */
+ int i, j;
+ BOOL Stop;
+ LIST Failed, Result;
+
+ Result = list_Nil();
+
+ /* Special case: horn clause */
+ if (clause_IsHornClause(Clause))
+ return Result;
+
+ /* Special case: clause is ground, so return all succedent literals */
+ if (clause_IsGround(Clause)) {
+ for (i = clause_LastSuccedentLitIndex(Clause);
+ i >= clause_FirstSuccedentLitIndex(Clause); i--)
+ Result = list_Cons((POINTER)i, Result);
+ return Result;
+ }
+
+ Variables = memory_Malloc(sizeof(LIST) * clause_Length(Clause));
+ /* Initialize the array */
+ for (i = clause_FirstLitIndex(); i <= clause_LastLitIndex(Clause); i++)
+ Variables[i] = term_VariableSymbols(clause_GetLiteralAtom(Clause, i));
+
+ /* <Failed> is the set of literals that share variables with other literals */
+ Failed = list_Nil();
+ for (i = clause_LastSuccedentLitIndex(Clause);
+ i >= clause_FirstSuccedentLitIndex(Clause); i--) {
+ if (list_Empty(Variables[i]))
+ Result = list_Cons((POINTER)i, Result);
+ else if (!list_PointerMember(Failed, (POINTER)i)) {
+ /* We don't know yet whether the literal shares variables */
+ Stop = FALSE;
+ for (j = clause_FirstLitIndex();
+ j <= clause_LastLitIndex(Clause) && !Stop; j++) {
+ if (i != j && list_HasIntersection(Variables[i], Variables[j])) {
+ Stop = TRUE; /* Literal isn´t candidate for "optimal" splitting */
+ Failed = list_Cons((POINTER)i, Failed);
+ Failed = list_Cons((POINTER)j, Failed);
+ }
+ }
+ if (!Stop)
+ Result = list_Cons((POINTER)i, Result);
+ }
+ }
+
+ /* Cleanup */
+ for (i = clause_FirstLitIndex(); i <= clause_LastLitIndex(Clause); i++)
+ list_Delete(Variables[i]);
+ memory_Free(Variables, sizeof(LIST) * clause_Length(Clause));
+ list_Delete(Failed);
+ return Result;
+}
+
+
+static int top_GetOptimalSplitLiteralIndex(PROOFSEARCH Search, CLAUSE Clause,
+ BOOL Usables)
+/**************************************************************
+ INPUT: A proofsearch object, a clause and a boolean flag.
+ RETURNS: The index of the positive literal from <Clause>
+ with the greatest number of instances (maybe 0) within
+ the WorkedOff/Usable sets of the proof search object.
+ The literal mustn't share any variables with other literals.
+ If the clause doesn't have a suitable literal, a negative
+ number is returned.
+ EFFECT: If <Usables> is FALSE, only the number of instances
+ within the WorkedOff set is considered, otherwise
+ the number of instances within both clause sets is considered.
+***************************************************************/
+{
+ LIST SplitLits;
+ LITERAL Literal;
+ NAT Count, MaxInstances;
+ int Result;
+
+ MaxInstances = -1;
+ SplitLits = top_GetLiteralsForSplitting(Clause);
+ Result = -1;
+
+ for ( ; !list_Empty(SplitLits); SplitLits = list_Pop(SplitLits)) {
+ Literal = clause_GetLiteral(Clause, (int)list_Car(SplitLits));
+ /* Count the number of instances */
+ Count = prfs_GetNumberOfInstances(Search, Literal, Usables);
+ if (Count > MaxInstances) {
+ Result = (int)list_Car(SplitLits);
+ MaxInstances = Count;
+ }
+ }
+ return Result;
+}
+
+
+/* EK: hier lassen oder nach search.c oder nach rules-split.c? */
+static CLAUSE top_GetPowerfulSplitClause(PROOFSEARCH Search, BOOL Usables,
+ int* LitIndex)
+/**************************************************************
+ INPUT: A proofsearch object, a boolean flag and a pointer to a literal
+ index which is used as return value.
+ RETURNS: A clause from the usable set that was selected as given clause.
+ Iff no suitable clause was found NULL is returned and <*LitIndex>
+ is set to -1.
+ Iff a suitable clause was found, this clause is returned and
+ <*LitIndex> is set to the index of the "optimal" literal.
+ EFFECT: This function selects a clause from the "usable" set and
+ a literal that are "optimal" for the application of the splitting
+ rule with respect to the following criteria:
+ 1) the literal must occur in the succedent of the non-horn clause,
+ 2) the literal mustn't share any variables with other literals,
+ 3) the clause must have a solved constraint,
+ 4) the atom must have the maximum number of instances
+ a) within the set of "workedoff" clauses, iff <Usables>=FALSE
+ b) within the set of "usable" and "workedoff" clauses,
+ iff "Usables"=TRUE
+ 5) the atom must have at least one instance in another clause.
+***************************************************************/
+{
+ LIST Scan, SplitLits;
+ NAT MaxNrOfInstances, NrOfInstances;
+ CLAUSE Clause, OptimalClause;
+ TERM Atom;
+ SHARED_INDEX WOIndex, UsIndex;
+
+ OptimalClause = NULL;
+ *LitIndex = -1;
+ MaxNrOfInstances = 0;
+ WOIndex = prfs_WorkedOffSharingIndex(Search);
+ UsIndex = prfs_UsableSharingIndex(Search);
+
+ /* Prepare the term stamp */
+ if (term_StampOverflow(sharing_StampID(WOIndex)))
+ sharing_ResetAllTermStamps(WOIndex);
+ if (Usables && term_StampOverflow(sharing_StampID(UsIndex)))
+ sharing_ResetAllTermStamps(UsIndex);
+ term_StartStamp();
+
+ for (Scan = prfs_UsableClauses(Search); !list_Empty(Scan);
+ Scan = list_Cdr(Scan)) {
+ Clause = list_Car(Scan);
+ if (clause_HasSolvedConstraint(Clause) && !clause_IsHornClause(Clause)) {
+ /* Get a list of splittable literal indices */
+ SplitLits = top_GetLiteralsForSplitting(Clause);
+ for ( ; !list_Empty(SplitLits); SplitLits = list_Pop(SplitLits)) {
+ LITERAL Literal;
+
+ Literal = clause_GetLiteral(Clause, (int)list_Car(SplitLits));
+ Atom = clause_LiteralAtom(Literal);
+ if (!term_AlreadyVisited(Atom)) {
+ /* Don't visit atom more than once */
+ term_SetTermStamp(Atom);
+ /* Count the number of instances */
+ NrOfInstances = prfs_GetNumberOfInstances(Search, Literal, Usables);
+ if (NrOfInstances > MaxNrOfInstances || OptimalClause == NULL ||
+ (NrOfInstances == MaxNrOfInstances &&
+ /* Prefer shorter clauses for splitting! */
+ clause_Length(Clause) < clause_Length(OptimalClause))) {
+ OptimalClause = Clause;
+ MaxNrOfInstances = NrOfInstances;
+ *LitIndex = (int)list_Car(SplitLits);
+ }
+ }
+ }
+ }
+ }
+ term_StopStamp();
+
+ /* The splittable literal must have at least one instance to be useful */
+ /* reducing other clauses. If <Usables> is TRUE, the literal must even */
+ /* have two instances, since the literal of the given clause is in the */
+ /* usable index, too. */
+ if (MaxNrOfInstances == 0 || (Usables && MaxNrOfInstances == 1)) {
+ *LitIndex = -1;
+ OptimalClause = NULL;
+ }
+
+ return OptimalClause;
+}
+
+
+static LIST top_FullReductionSelectGivenComputeDerivables(PROOFSEARCH Search,
+ CLAUSE *SplitClause,
+ int *Counter)
+/**************************************************************
+ INPUT: A proof search object, a pointer to a clause resulting from a
+ previous splitting step, and a pointer to an integer counter.
+ RETURNS: A list of derived clauses.
+ EFFECT: In this function a clause is selected from the set of
+ "usable" clauses. After a clause was selected as "given clause",
+ inferences between the given clause and the "worked off" clauses
+ are made. The selection works as follows:
+ 1) If <*SplitClause> is not NULL, the split clause
+ is selected as "given clause". <*SplitClause> should result
+ from splitting
+ 2) If <*SplitClause> is NULL, we try to find a clause that is
+ "optimal" for splitting. This is done by selecting a literal
+ <L> in a clause, such that <L> is variable-disjoint from
+ the rest of the clause, and the atom of <L> has the maximum
+ number of instances within the set of "usable" and "workoff"
+ clauses.
+ 3) If the previous steps failed, a clause is selected by weight
+ or by depth, depending on the parameters "WDRatio", "PrefVar"
+ and "PrefCon". Then splitting is tried on the selected clause.
+ If the clause is a non-horn clause, we try to find a positive
+ literal <L> and a set of negative literals <N>, such that <N>
+ and <L> are variable disjoint from the rest of the clause.
+***************************************************************/
+{
+ CLAUSE GivenClause, TerminatorClause;
+ LIST Derivables, SplitLits;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+ int LitIndex;
+
+ GivenClause = NULL;
+ Derivables = list_Nil();
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ /* 1) If the last given clause was split or if backtracking was applied, */
+ /* then choose the clause resulting from the splitting step as */
+ /* given clause. */
+ /* ATTENTION: Since the <SplitClause> might have been reduced since */
+ /* the time the variable was set, we have to check whether */
+ /* <SplitClause> is still element of the set of usable clauses. */
+ if (*SplitClause != NULL &&
+ list_PointerMember(prfs_UsableClauses(Search), *SplitClause))
+ GivenClause = *SplitClause;
+
+ *SplitClause = NULL;
+
+ if (GivenClause == NULL) {
+ if (prfs_SplitCounter(Search) != 0)
+ /* 2) Try to find an "optimal" splitting clause, that doesn't share */
+ /* variables with any other literal. */
+ GivenClause = top_GetPowerfulSplitClause(Search, FALSE, &LitIndex);
+
+ if (GivenClause != NULL) {
+ /* Found "optimal" split clause, so apply splitting */
+ SplitLits = list_List(clause_GetLiteral(GivenClause, LitIndex));
+ *SplitClause = prfs_DoSplitting(Search, GivenClause, SplitLits);
+ list_Delete(SplitLits);
+ } else {
+ /* 3) Splitting wasn't applied, so use the other strategies */
+ if ((*Counter) % flag_GetFlagValue(Flags, flag_WDRATIO) == 0)
+ GivenClause = top_SelectClauseDepth(prfs_UsableClauses(Search), Flags);
+ else {
+ if (flag_GetFlagValue(Flags, flag_PREFCON) != flag_PREFCONUNCHANGED)
+ GivenClause = top_SelectMinimalConWeightClause(prfs_UsableClauses(Search),
+ Flags);
+ else
+ GivenClause = top_SelectMinimalWeightClause(prfs_UsableClauses(Search),
+ Flags);
+ }
+ (*Counter)++; /* EK: hier lassen, oder eine Klammerebene nach aussen? */
+ }
+ }
+
+ if (*SplitClause == NULL && prfs_SplitCounter(Search) != 0) {
+ /* Try to find the "optimal" literal for splitting the clause. */
+ /* This makes sense for a clause that is the right part of a */
+ /* splitting step. */
+ LitIndex = top_GetOptimalSplitLiteralIndex(Search, GivenClause, FALSE);
+ if (LitIndex >= 0) {
+ SplitLits = list_List(clause_GetLiteral(GivenClause, LitIndex));
+ *SplitClause = prfs_DoSplitting(Search, GivenClause, SplitLits);
+ list_Delete(SplitLits);
+ } else {
+ /* Optimal splitting wasn't possible, so try the old-style splitting. */
+ /* Here a split is done if a positive literal doesn't share variables */
+ /* with another POSITIVE literal. */
+ *SplitClause = prfs_PerformSplitting(Search, GivenClause);
+ }
+ }
+
+ prfs_ExtractUsable(Search, GivenClause);
+
+ if (flag_GetFlagValue(Flags, flag_PGIVEN)) {
+ fputs("\n\tGiven clause: ", stdout);
+ clause_Print(GivenClause);
+ fflush(stdout);
+ }
+
+ if (*SplitClause != NULL)
+ Derivables = list_List(*SplitClause);
+ else {
+ /* No splitting was applied */
+ if (flag_GetFlagValue(Flags, flag_RTER) != flag_RTEROFF) {
+ clock_StartCounter(clock_REDUCTION);
+ TerminatorClause = red_Terminator(GivenClause,
+ flag_GetFlagValue(Flags, flag_RTER),
+ prfs_WorkedOffSharingIndex(Search),
+ prfs_UsableSharingIndex(Search), Flags,
+ Precedence);
+ clock_StopAddPassedTime(clock_REDUCTION);
+
+ if (TerminatorClause != NULL) {
+ /* An empty clause was derived by the "terminator" rule */
+ Derivables = list_List(TerminatorClause);
+ prfs_InsertUsableClause(Search, GivenClause);
+ }
+ }
+ if (list_Empty(Derivables)) {
+ /* No splitting was applied, no empty clause was found by terminator */
+ clause_SelectLiteral(GivenClause, Flags);
+ /*clause_SetSpecialFlags(GivenClause,ana_SortDecreasing());*/
+ prfs_InsertWorkedOffClause(Search, GivenClause);
+ clock_StartCounter(clock_INFERENCE);
+ Derivables = inf_DerivableClauses(Search, GivenClause);
+ clock_StopAddPassedTime(clock_INFERENCE);
+ }
+ }
+
+ prfs_IncDerivedClauses(Search, list_Length(Derivables));
+
+ return Derivables;
+}
+
+
+static LIST top_LazyReductionSelectGivenComputeDerivables(PROOFSEARCH Search,
+ CLAUSE *SplitClause,
+ int *Counter)
+/**************************************************************
+ INPUT: A proof search object, a pointer to a clause resulting from a
+ previous splitting step, and a pointer to an integer counter.
+ RETURNS: A list of derived clauses.
+ EFFECT: In this function a clause is selected from the set of
+ "usable" clauses. After a clause was selected as "given clause",
+ inferences between the given clause and the "worked off" clauses
+ are made. Take a look at the description of the function
+ top_FullReduction... for more details.
+ This function is more complicated than the other function,
+ since clauses in the set of usable clauses may be reducible.
+ Because of this fact, the selection of the given clause
+ has to be done in a loop. After picking a "candidate" clause
+ the clause is inter-reduced with the "worked off" set.
+ If the candidate still exists after the reduction it is
+ selected as given clause, else another usable clause is picked
+ as candidate.
+***************************************************************/
+{
+ CLAUSE GivenClause, TerminatorClause;
+ LIST Derivables;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+ int LitIndex;
+
+ GivenClause = (CLAUSE)NULL;
+ TerminatorClause = (CLAUSE)NULL;
+ Derivables = list_Nil();
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+
+ while (GivenClause == (CLAUSE)NULL &&
+ !list_Empty(prfs_UsableClauses(Search))) {
+ /* The selected clause may be redundant */
+
+ if (*SplitClause != NULL &&
+ list_PointerMember(prfs_UsableClauses(Search), *SplitClause))
+ GivenClause = *SplitClause;
+
+ *SplitClause = NULL;
+
+ /* Try selecting a clause that is optimal for splitting */
+ if (GivenClause == NULL) {
+ if (prfs_SplitCounter(Search) != 0) {
+ GivenClause = top_GetPowerfulSplitClause(Search, FALSE, &LitIndex);
+ /* The value of <LitIndex> isn't used here. */
+ }
+
+ if (GivenClause == NULL) {
+ /* No optimal clause for splitting found */
+ if ((*Counter) % flag_GetFlagValue(Flags, flag_WDRATIO) == 0)
+ GivenClause = top_SelectClauseDepth(prfs_UsableClauses(Search), Flags);
+ else {
+ if (flag_GetFlagValue(Flags, flag_PREFCON) != flag_PREFCONUNCHANGED)
+ GivenClause = top_SelectMinimalConWeightClause(prfs_UsableClauses(Search),
+ Flags);
+ else
+ GivenClause = top_SelectMinimalWeightClause(prfs_UsableClauses(Search),
+ Flags);
+ }
+ (*Counter)++;
+ }
+ }
+ prfs_ExtractUsable(Search, GivenClause);
+
+ /* Reduce the selected clause */
+ clock_StartCounter(clock_REDUCTION);
+ GivenClause = red_CompleteReductionOnDerivedClause(Search, GivenClause,
+ red_WORKEDOFF);
+ clock_StopAddPassedTime(clock_REDUCTION);
+ }
+
+ if (GivenClause == (CLAUSE)NULL)
+ /* Set of usable clauses is empty */
+ return list_Nil();
+
+
+ if (clause_IsEmptyClause(GivenClause)) {
+ Derivables = list_List(GivenClause);
+ return Derivables;
+ }
+ else {
+ /* Reduce Workedoff clauses with selected clause */
+ clock_StartCounter(clock_REDUCTION);
+ Derivables = red_BackReduction(Search, GivenClause, red_WORKEDOFF);
+ clock_StopAddPassedTime(clock_REDUCTION);
+ }
+
+ /* Print selected clause */
+ if (flag_GetFlagValue(Flags, flag_PGIVEN)) {
+ fputs("\n\tGiven clause: ", stdout);
+ clause_Print(GivenClause);
+ fflush(stdout);
+ }
+
+ /* Try splitting */
+ if (prfs_SplitCounter(Search) != 0) {
+ /* First try "optimal" splitting on the selected clause */
+ LitIndex = top_GetOptimalSplitLiteralIndex(Search, GivenClause, FALSE);
+
+ if (LitIndex >= 0) {
+ LIST SplitLits;
+
+ SplitLits = list_List(clause_GetLiteral(GivenClause, LitIndex));
+ *SplitClause = prfs_DoSplitting(Search, GivenClause, SplitLits);
+ list_Delete(SplitLits);
+ } else {
+ /* Try the old splitting that allows negative literals */
+ /* sharing variables with the selected positive literal. */
+ *SplitClause = prfs_PerformSplitting(Search, GivenClause);
+ }
+ }
+
+ if (*SplitClause != NULL) {
+ Derivables = list_Cons(*SplitClause, Derivables);
+ } else {
+ /* Try terminator reduction only for a clause that wasn't splitted. */
+ if (flag_GetFlagValue(Flags, flag_RTER) != flag_RTEROFF) {
+ TerminatorClause = red_Terminator(GivenClause,
+ flag_GetFlagValue(Flags, flag_RTER),
+ prfs_WorkedOffSharingIndex(Search),
+ prfs_UsableSharingIndex(Search),
+ Flags, Precedence);
+ if (TerminatorClause != NULL) {
+ Derivables = list_Cons(TerminatorClause, Derivables);
+ prfs_InsertUsableClause(Search, GivenClause);
+ }
+ }
+ if (TerminatorClause == (CLAUSE)NULL) {
+ clause_SelectLiteral(GivenClause, Flags);
+ /* clause_SetSpecialFlags(GivenClause,ana_SortDecreasing());*/
+ prfs_InsertWorkedOffClause(Search, GivenClause);
+ clock_StartCounter(clock_INFERENCE);
+ Derivables = list_Nconc(Derivables,
+ inf_DerivableClauses(Search, GivenClause));
+ clock_StopAddPassedTime(clock_INFERENCE);
+ }
+ }
+
+ prfs_IncDerivedClauses(Search, list_Length(Derivables));
+
+ return Derivables;
+}
+
+
+static PROOFSEARCH top_ProofSearch(PROOFSEARCH Search, LIST ProblemClauses,
+ FLAGSTORE InputFlags, LIST UserPrecedence, int *BoundApplied)
+/**************************************************************
+ INPUT: A proof search object, a list of clauses, a flag store
+ containing the flags from the command line and from
+ the input file, a list containing the precedence as
+ specified by the user, and a pointer to an integer.
+ RETURNS: The same proof search object
+ EFFECTS:
+***************************************************************/
+{
+ LIST Scan,EmptyClauses,Derivables;
+ LIST UsedEmptyClauses;
+ CLAUSE SplitClause,HighestLevelEmptyClause;
+ FLAGSTORE Flags;
+ PRECEDENCE Precedence;
+ int Counter, ActBound, BoundMode, BoundLoops;
+
+ HighestLevelEmptyClause = (CLAUSE)NULL;
+ UsedEmptyClauses = list_Nil();
+ EmptyClauses = list_Nil();
+ Derivables = list_Nil();
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+ Counter = 1;
+
+ clock_InitCounter(clock_REDUCTION);
+ clock_InitCounter(clock_BACKTRACK);
+ clock_InitCounter(clock_INFERENCE);
+
+ /* Important ! Recomputes Weight ! */
+ ana_AnalyzeProblem(Search, ProblemClauses);
+ if (flag_GetFlagValue(Flags, flag_AUTO)) {
+ prfs_InstallFiniteMonadicPredicates(Search, ProblemClauses, ana_FinMonPredList());
+ ana_AutoConfiguration(ProblemClauses, Flags, Precedence);
+ /* File and input flags have higher precedence */
+ flag_TransferSetFlags(InputFlags, Flags);
+ }
+
+ /* Rearrange automatically determined precedence according to user's specification. */
+ symbol_RearrangePrecedence(Precedence, UserPrecedence);
+
+ for (Scan = ProblemClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ clause_OrientAndReInit(list_Car(Scan), Flags, Precedence);
+
+ /* Must be called after ana_AnalyzeProblem and Reorientation */
+ ana_AnalyzeSortStructure(ProblemClauses, Flags, Precedence);
+
+ if (flag_GetFlagValue(Flags, flag_AUTO)) {
+ ana_ExploitSortAnalysis(Flags);
+ /* File and input flags have higher precedence */
+ flag_TransferSetFlags(InputFlags, Flags);
+ }
+ prfs_SetSplitCounter(Search, flag_GetFlagValue(Flags, flag_SPLITS));
+
+ ActBound = flag_GetFlagValue(Flags, flag_BOUNDSTART);
+ BoundMode = flag_GetFlagValue(Flags, flag_BOUNDMODE);
+ BoundLoops = flag_GetFlagValue(Flags, flag_BOUNDLOOPS);
+ *BoundApplied = -1;
+
+ if (flag_GetFlagValue(Flags, flag_PPROBLEM)) {
+ puts("");
+ puts("--------------------------SPASS-START-----------------------------");
+ puts("Input Problem:");
+ clause_ListPrint(ProblemClauses);
+ ana_Print(Flags, Precedence);
+ }
+
+ if (flag_GetFlagValue(Flags, flag_SORTS) != flag_SORTSOFF) {
+ BOOL Strong;
+ Strong = (flag_GetFlagValue(Flags, flag_SORTS) == flag_SORTSMONADICALL);
+ for (Scan = ProblemClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ clause_SetSortConstraint((CLAUSE)list_Car(Scan),Strong,Flags, Precedence);
+ }
+
+ if (flag_GetFlagValue(Flags, flag_RINPUT)) {
+ clock_StartCounter(clock_REDUCTION);
+ EmptyClauses = red_ReduceInput(Search, ProblemClauses);
+ clock_StopAddPassedTime(clock_REDUCTION);
+ if (list_Empty(EmptyClauses) && flag_GetFlagValue(Flags, flag_SATINPUT))
+ EmptyClauses = red_SatInput(Search);
+ }
+ else {
+ for (Scan=ProblemClauses; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ prfs_InsertUsableClause(Search, list_Car(Scan));
+ }
+ Derivables = list_Nil();
+
+ if (ana_SortRestrictions() ||
+ (ana_UnsolvedSortRestrictions() &&
+ flag_GetFlagValue(Flags,flag_SORTS) == flag_SORTSMONADICALL)) {
+ if (flag_GetFlagValue(Flags, flag_RSST))
+ prfs_SetStaticSortTheory(Search,sort_ApproxStaticSortTheory(prfs_UsableClauses(Search),Flags,Precedence));
+ prfs_SetDynamicSortTheory(Search,sort_TheoryCreate());
+ }
+
+ /* Fix literal order in clauses in the usable set.
+ Since they are shared, we have to extract them from
+ the sharing before fixing them. Afterwards, we have to
+ insert them in the sharing again.
+ */
+ for (Scan = prfs_UsableClauses(Search);
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan)) {
+ CLAUSE clause;
+ clause = list_Car(Scan);
+ clause_MakeUnshared(clause,prfs_UsableSharingIndex(Search));
+ clause_FixLiteralOrder(clause, Flags, Precedence);
+ clause_InsertIntoSharing(clause, prfs_UsableSharingIndex(Search),
+ prfs_Store(Search), prfs_Precedence(Search));
+ }
+
+ /* Calculate the frequency counts for the symbols in the usable set. */
+ for (Scan = prfs_UsableClauses(Search);
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan)) {
+ CLAUSE clause;
+ clause = list_Car(Scan);
+
+ clause_CountSymbols(clause);
+ }
+
+ /* Sort usable set. */
+ prfs_SetUsableClauses(Search,
+ list_Sort(prfs_UsableClauses(Search),
+ (BOOL (*) (void *, void *)) clause_CompareAbstractLEQ));
+
+ if (flag_GetFlagValue(Flags, flag_SOS)) {
+ Derivables = list_Copy(prfs_UsableClauses(Search));
+ for (Scan=Derivables;!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (!clause_GetFlag(list_Car(Scan), CONCLAUSE))
+ prfs_MoveUsableWorkedOff(Search,list_Car(Scan));
+ list_Delete(Derivables);
+ }
+
+ if (flag_GetFlagValue(Flags, flag_PPROBLEM)) {
+ puts("\nProcessed Problem:");
+ puts("\nWorked Off Clauses:");
+ clause_ListPrint(prfs_WorkedOffClauses(Search));
+ puts("\nUsable Clauses:");
+ clause_ListPrint(prfs_UsableClauses(Search));
+ }
+
+ while ((list_Empty(EmptyClauses) || !prfs_SplitStackEmpty(Search)) &&
+ prfs_Loops(Search) != 0 &&
+ ((*BoundApplied != -1) || !list_Empty(prfs_UsableClauses(Search))) &&
+ (flag_GetFlagValue(Flags,flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED ||
+ flag_GetFlagValue(Flags,flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) {
+
+ Derivables = list_Nil();
+ SplitClause = (CLAUSE)NULL;
+ *BoundApplied = -1;
+
+ while ((list_Empty(EmptyClauses) || !prfs_SplitStackEmpty(Search)) &&
+ prfs_Loops(Search) != 0 &&
+ (!list_Empty(prfs_UsableClauses(Search)) || !list_Empty(EmptyClauses)) &&
+ (flag_GetFlagValue(Flags,flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED ||
+ flag_GetFlagValue(Flags,flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) {
+
+ if (!list_Empty(EmptyClauses)) {
+ /* Backtracking */
+ clock_StartCounter(clock_BACKTRACK);
+ Derivables = split_Backtrack(Search, HighestLevelEmptyClause,
+ &SplitClause);
+ clock_StopAddPassedTime(clock_BACKTRACK);
+ prfs_IncBacktrackedClauses(Search, list_Length(Derivables));
+
+ if (prfs_SplitStackEmpty(Search))
+ Derivables = list_Nconc(EmptyClauses, Derivables);
+ else {
+ for ( ; !list_Empty(EmptyClauses); EmptyClauses = list_Pop(EmptyClauses))
+ if (list_Car(EmptyClauses) != HighestLevelEmptyClause)
+ clause_Delete(list_Car(EmptyClauses));
+ prfs_InsertDocProofClause(Search, HighestLevelEmptyClause);
+ /* Keep HighestLevelEmptyClause for finding the terms required */
+ /* for the proof. */
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ UsedEmptyClauses = list_Cons(HighestLevelEmptyClause, UsedEmptyClauses);
+ if (flag_GetFlagValue(Flags, flag_DOCSPLIT))
+ printf("\n\t Split Backtracking level %d:",prfs_ValidLevel(Search));
+ }
+ EmptyClauses = list_Nil();
+ HighestLevelEmptyClause = (CLAUSE)NULL;
+ }
+ else { /* no empty clause found */
+
+#ifdef CHECK
+ if (!prfs_Check(Search)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In top_ProofSearch: Illegal state of search in SPASS.\n");
+ misc_FinishErrorReport();
+ }
+ if (!ana_Equations())
+ red_CheckSplitSubsumptionCondition(Search);
+#endif
+
+ if (flag_GetFlagValue(Flags, flag_FULLRED))
+ Derivables = top_FullReductionSelectGivenComputeDerivables(Search, &SplitClause, &Counter);
+ else
+ Derivables = top_LazyReductionSelectGivenComputeDerivables(Search, &SplitClause, &Counter);
+ }
+
+ /* Print the derived clauses, if required */
+ if (flag_GetFlagValue(Flags, flag_PDER))
+ for (Scan=Derivables; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ fputs("\nDerived: ", stdout);
+ clause_Print(list_Car(Scan));
+ }
+
+ /* Partition the derived clauses into empty and non-empty clauses */
+ Derivables = split_ExtractEmptyClauses(Derivables, &EmptyClauses);
+
+ /* Apply reduction rules */
+ clock_StartCounter(clock_REDUCTION);
+ if (flag_GetFlagValue(Flags, flag_FULLRED)) {
+ EmptyClauses =
+ list_Nconc(EmptyClauses,
+ red_CompleteReductionOnDerivedClauses(Search, Derivables,
+ red_ALL, ActBound,
+ BoundMode,
+ BoundApplied));
+ } else {
+ EmptyClauses =
+ list_Nconc(EmptyClauses,
+ red_CompleteReductionOnDerivedClauses(Search, Derivables,
+ red_WORKEDOFF,
+ ActBound, BoundMode,
+ BoundApplied));
+ }
+ clock_StopAddPassedTime(clock_REDUCTION);
+
+
+ if (!list_Empty(EmptyClauses)) {
+ HighestLevelEmptyClause = split_SmallestSplitLevelClause(EmptyClauses);
+ if (flag_GetFlagValue(Flags, flag_PEMPTYCLAUSE)) {
+ fputs("\nEmptyClause: ", stdout);
+ clause_Print(HighestLevelEmptyClause);
+ }
+ }
+ prfs_DecLoops(Search);
+ }
+
+ if (ActBound != flag_BOUNDSTARTUNLIMITED &&
+ BoundMode != flag_BOUNDMODEUNLIMITED) {
+ BoundLoops--;
+ if (BoundLoops == flag_BOUNDLOOPSMIN)
+ ActBound = flag_BOUNDSTARTUNLIMITED;
+ else
+ ActBound = *BoundApplied;
+ if (*BoundApplied != -1) {
+ prfs_SwapIndexes(Search);
+ if (flag_GetFlagValue(Flags,flag_PBINC))
+ printf("\n\n\t ---- New Clause %s Bound: %2d ----\n",
+ (BoundMode==flag_BOUNDMODERESTRICTEDBYDEPTH) ? "Term Depth" : "Weight",ActBound);
+ }
+ }
+ }
+ prfs_SetEmptyClauses(Search, EmptyClauses);
+ prfs_SetUsedEmptyClauses(Search, UsedEmptyClauses);
+
+ return Search;
+}
+
+
+static void top_Flotter(int argc, const char* argv[], LIST InputClauses)
+/**************************************************************
+ INPUT:
+ RETURNS: Nothing.
+ EFFECT:
+***************************************************************/
+{
+ FILE *Output;
+ char *description;
+ const char *creator = "\n\tCNF generated by FLOTTER " misc_VERSION " *}";
+ int size;
+ int creator_size;
+
+ if (argc < opts_Indicator()+2)
+ Output = stdout;
+ else
+ Output = misc_OpenFile(argv[opts_Indicator()+1],"w");
+
+ creator_size = (int)strlen(creator);
+ size = (int)strlen(dfg_ProblemDescription()) + creator_size;
+ description = (char*)memory_Malloc(sizeof(char)*size);
+ strncpy(description,dfg_ProblemDescription(),size-creator_size-3);
+ strcpy(description+size-creator_size-3, creator);
+
+
+ clause_FPrintCnfDFGProblem(Output, dfg_ProblemName(), dfg_ProblemAuthor(),
+ dfg_ProblemStatusString(), description, InputClauses);
+
+ fputs("\nFLOTTER needed\t", stdout);
+ clock_PrintTime(clock_INPUT);
+ puts(" for the input.");
+ fputs("\t\t", stdout);
+ clock_PrintTime(clock_CNF);
+ fputs(" for the CNF translation.", stdout);
+
+
+ if (Output != stdout)
+ misc_CloseFile(Output,argv[opts_Indicator()+1]);
+ memory_Free(description, sizeof(char)*size);
+}
+
+static BOOL top_CalledFlotter(const char* Call)
+{
+ int length;
+ length = strlen(Call);
+ return string_Equal((Call + (length > 7 ? length - 7 : 0)), "FLOTTER");
+}
+
+
+
+/**************************************************************/
+/* Main Function */
+/**************************************************************/
+
+int main(int argc, const char* argv[])
+{
+ LIST InputClauses,Scan,Axioms,Conjectures, Sorts, QueryClauses,
+ LabelClauses, QueryPair, ProblemClauses, Labellist, Sortlabellist,
+ Symblist, UserPrecedence;
+ PROOFSEARCH Search, FlotterSearch;
+ /* <InputFlags> are the flags from the problem file and the command line. */
+ FLAGSTORE InputFlags, Flags;
+ /* <InputPrecedence> is the precedence after reading the problem file. */
+ PRECEDENCE InputPrecedence, Precedence;
+ FILE* InputStream;
+ HASH TermLabelToClauselist, ClauseToTermLabellist;
+ top_SEARCHRESULT Result;
+
+ Search = (PROOFSEARCH)NULL;
+
+#if (defined(SPASS_SIGNALS))
+ top_PROOFSEARCH = &Search;
+ signal(SIGINT, top_SigHandler);
+ signal(SIGTERM, top_SigHandler);
+ signal(SIGSEGV, top_SigHandler);
+ signal(SIGBUS, top_SigHandler);
+#endif
+
+ clock_Init();
+ clock_StartCounter(clock_OVERALL);
+ memory_Init(memory__UNLIMITED);
+ atexit(memory_FreeAllMem);
+ symbol_Init(TRUE);
+ stack_Init();
+ hash_Init();
+ sort_Init();
+ term_Init();
+
+ InputPrecedence = symbol_CreatePrecedence();
+ fol_Init(TRUE, InputPrecedence);
+ cont_Init();
+ unify_Init();
+ flag_Init();
+ subs_Init();
+ clause_Init();
+ red_Init();
+ ren_Init();
+ dp_Init();
+ opts_Init();
+ ana_Init();
+ cc_Init();
+
+ /* Build proof search object to store definitions in */
+ Search = prfs_Create();
+ InputFlags = flag_CreateStore();
+
+ /* declare all options */
+ opts_DeclareSPASSFlagsAsOptions();
+ top_RemoveFileOptId = opts_Declare("rf", opts_NOARGTYPE);
+
+ if (!opts_Read(argc, argv))
+ return EXIT_FAILURE;
+
+ /* Check whether flag_STDIN is set in the command line */
+ flag_InitStoreByDefaults(InputFlags);
+ opts_SetFlags(InputFlags);
+
+ if (argc < opts_Indicator()+1 && !flag_GetFlagValue(InputFlags,flag_STDIN)) {
+ /* No input file, no stdin input */
+ printf("\n\t %s %s",argv[0],misc_VERSION);
+ if (top_CalledFlotter(argv[0]) ||
+ flag_GetFlagValue(InputFlags, flag_FLOTTER))
+ puts("\n\t Usage: FLOTTER [options] [<input-file>] [<output-file>]\n");
+ else
+ puts("\n\t Usage: SPASS [options] [<input-file>] \n");
+ puts("Possible options:\n");
+ opts_PrintSPASSNames();
+ return EXIT_FAILURE;
+ }
+ FlotterSearch = NULL;
+
+ Axioms = Conjectures = Sorts = Labellist = Sortlabellist = UserPrecedence = list_Nil();
+
+ if (flag_GetFlagValue(InputFlags, flag_STDIN)) {
+ top_InputFile = (char*)NULL;
+ InputStream = stdin;
+ } else {
+ top_InputFile = argv[opts_Indicator()];
+ InputStream = misc_OpenFile(top_InputFile, "r");
+ }
+
+ clock_StartCounter(clock_INPUT);
+ flag_CleanStore(InputFlags); /* Mark all flags as unset */
+
+ /* Now add flags from file to InputFlags and set precedence */
+ InputClauses = dfg_DFGParser(InputStream, InputFlags, InputPrecedence, &Axioms,
+ &Conjectures, &Sorts, &UserPrecedence);
+
+ /* Add/overwrite with command line flags */
+ opts_SetFlags(InputFlags);
+ Flags = prfs_Store(Search);
+ Precedence = prfs_Precedence(Search);
+ /* The Flags were initialized with the default flag values. */
+ /* This values are now overwritten by command line flags and flags */
+ /* from the input file. */
+ flag_TransferSetFlags(InputFlags, Flags);
+ /* From now on the input flags are not changed! */
+
+ /* Transfer input precedence to search object */
+ symbol_TransferPrecedence(InputPrecedence, Precedence);
+
+
+ /* Complain about missing input clauses/formulae when in */
+ /* non-interactive mode */
+ if (!flag_GetFlagValue(Flags, flag_INTERACTIVE) && list_Empty(Axioms) &&
+ list_Empty(Conjectures) && list_Empty(InputClauses)) {
+ misc_StartUserErrorReport();
+ misc_UserErrorReport("\n No formulae and clauses found in input file!\n");
+ misc_FinishUserErrorReport();
+ }
+
+ cnf_Init(Flags); /* Depends on Strong Skolemization Flag */
+
+ /* DocProof is required for interactive mode */
+ if (flag_GetFlagValue(Flags, flag_INTERACTIVE)) {
+ flag_SetFlagValue(Flags, flag_DOCPROOF, flag_DOCPROOFON);
+ }
+
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ prfs_AddDocProofSharingIndex(Search);
+
+ /* Create necessary hasharrays */
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+ TermLabelToClauselist = hsh_Create();
+ ClauseToTermLabellist = hsh_Create();
+ }
+ else {
+ TermLabelToClauselist = NULL;
+ ClauseToTermLabellist = NULL;
+ }
+
+ /* Build conjecture formula and negate it: Conjectures are taken disjunctively!!*/
+ for (Scan = Conjectures; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ list_Rplacd(list_Car(Scan), (LIST)term_Create(fol_Not(),
+ list_List(list_PairSecond(list_Car(Scan)))));
+
+ clock_StopPassedTime(clock_INPUT);
+
+ if (top_InputFile) {
+ misc_CloseFile(InputStream,top_InputFile);
+ if (opts_IsSet(top_RemoveFileOptId))
+ remove(top_InputFile);
+ }
+
+ clock_StartCounter(clock_CNF);
+
+ if (list_Empty(InputClauses)) {
+ NAT Termcount;
+
+ Termcount = 0;
+
+ /* Create labels for formulae without them */
+ for (Scan = Axioms; !list_Empty(Scan); Scan = list_Cdr(Scan), Termcount++) {
+ if (list_PairFirst(list_Car(Scan)) == NULL) {
+ char L[100];
+ char* Label;
+ sprintf(L, "axiom%d", Termcount);
+ Label = string_StringCopy(L);
+ list_Rplaca(list_Car(Scan), Label);
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF) &&
+ flag_GetFlagValue(Flags, flag_PLABELS)) {
+ printf("\nAdded label %s for axiom \n", Label);
+ fol_PrettyPrintDFG((TERM) list_PairSecond(list_Car(Scan)));
+ }
+ }
+ }
+ Termcount = 0;
+ for (Scan = Sorts; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ char L[100];
+ char* Label;
+ sprintf(L, "declaration%d", Termcount);
+ Label = string_StringCopy(L);
+ list_Rplaca(list_Car(Scan), Label);
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF) &&
+ flag_GetFlagValue(Flags, flag_PLABELS)) {
+ printf("\nAdded label %s for declaration \n", Label);
+ fol_PrettyPrintDFG((TERM) list_PairSecond(list_Car(Scan)));
+ }
+ Sortlabellist = list_Cons(Label, Sortlabellist);
+ }
+ Axioms = list_Nconc(Axioms, Sorts);
+
+
+ if (flag_GetFlagValue(Flags, flag_APPLYDEFS) != flag_APPLYDEFSOFF) {
+ def_ExtractDefsFromTermlist(Search, Axioms, Conjectures);
+ Conjectures = def_ApplyDefinitionToTermList(prfs_Definitions(Search),
+ Conjectures, Flags,
+ Precedence);
+ }
+
+ /* We must keep the list of symbols because they can't be freed in cnf_Flotter */
+ Symblist = list_Nil();
+
+ /* Axioms is list of pairs, conjectures is list of terms */
+ /* A ProofSearch object is only returned and the symbols kept in Symblist
+ if flag_INTERACTIVE is set */
+ FlotterSearch = cnf_Flotter(Axioms,Conjectures,&InputClauses, &Labellist,
+ TermLabelToClauselist, ClauseToTermLabellist,
+ Flags, Precedence, &Symblist);
+
+ InputClauses = clause_ListSortWeighed(InputClauses);
+ clause_SetCounter(1);
+ for (Scan = InputClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ clause_NewNumber(list_Car(Scan));
+ }
+ }
+ else {
+ dfg_DeleteFormulaPairList(Axioms);
+ dfg_DeleteFormulaPairList(Sorts);
+ dfg_DeleteFormulaPairList(Conjectures);
+ if (flag_GetFlagValue(Flags, flag_APPLYDEFS) != flag_APPLYDEFSOFF) {
+ /* Extract list of definitions */
+ def_ExtractDefsFromClauselist(Search, InputClauses);
+ def_FlattenDefinitionsDestructive(Search);
+ for (Scan=prfs_Definitions(Search); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ InputClauses = def_ApplyDefToClauselist(Search, (DEF) list_Car(Scan),
+ InputClauses, TRUE);
+ }
+ }
+
+ clock_StopPassedTime(clock_CNF);
+
+ if (top_CalledFlotter(argv[0]) || flag_GetFlagValue(Flags, flag_FLOTTER)) {
+ top_Flotter(argc,argv,InputClauses);
+ flag_SetFlagValue(Flags, flag_TIMELIMIT, 0); /* Exit No Output */
+ flag_SetFlagValue(Flags, flag_INTERACTIVE, flag_INTERACTIVEOFF);
+ flag_SetFlagValue(Flags, flag_PPROBLEM, flag_PPROBLEMOFF);
+ }
+
+ memory_Restrict(flag_GetFlagValue(Flags, flag_MEMORY));
+
+ do {
+ LIST deflist;
+ int BoundApplied;
+ ProblemClauses = list_Nil();
+ LabelClauses = list_Nil();
+ Result = top_RESOURCE;
+
+ if (flag_GetFlagValue(Flags, flag_INTERACTIVE)) {
+ QueryPair = ia_GetNextRequest(InputStream, Flags);
+ /* A pair (<formula,labellist>) */
+ /* Get list of clauses derivable from formulae with labels in labellist */
+ if (list_Empty(QueryPair)) {
+ break;
+ }
+ for (Scan=list_PairSecond(QueryPair);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ LIST l;
+ l = hsh_GetWithCompareFunc(TermLabelToClauselist, list_Car(Scan),
+ (BOOL (*)(POINTER, POINTER)) cnf_LabelEqual,
+ (unsigned long (*)(POINTER)) hsh_StringHashKey);
+
+ l = list_PointerDeleteDuplicates(list_Copy(l));
+ LabelClauses = list_Nconc(l, LabelClauses);
+ }
+ /* Get list of clauses derivable from sorts */
+ for (Scan=Sortlabellist; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ LIST l;
+ l = hsh_GetWithCompareFunc(TermLabelToClauselist, list_Car(Scan),
+ (BOOL (*)(POINTER, POINTER)) cnf_LabelEqual,
+ (unsigned long (*)(POINTER)) hsh_StringHashKey);
+
+ l = list_PointerDeleteDuplicates(list_Copy(l));
+ LabelClauses = list_Nconc(l, LabelClauses);
+ }
+
+ /* For labelclauses copies are introduced */
+ /* So an update to the clause to term mapping is necessary */
+ for (Scan=LabelClauses; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ CLAUSE C;
+ LIST l;
+ C = (CLAUSE) list_Car(Scan);
+ l = list_Copy(hsh_Get(ClauseToTermLabellist, C));
+ l = cnf_DeleteDuplicateLabelsFromList(l);
+ list_Rplaca(Scan, clause_Copy(C));
+ hsh_PutList(ClauseToTermLabellist, list_Car(Scan), l);
+ }
+ QueryClauses = cnf_QueryFlotter(FlotterSearch, list_PairFirst(QueryPair),
+ &Symblist);
+ ProblemClauses = list_Nconc(QueryClauses, LabelClauses);
+
+ for (Scan=list_PairSecond(QueryPair); !list_Empty(Scan); Scan= list_Cdr(Scan))
+ string_StringFree(list_Car(Scan)); /* Free the label strings */
+ list_Delete(list_PairSecond(QueryPair));
+ list_PairFree(QueryPair);
+ clock_InitCounter(clock_OVERALL);
+ clock_StartCounter(clock_OVERALL);
+ }
+ else {
+ ProblemClauses = InputClauses;
+ InputClauses = list_Nil();
+ }
+
+
+ prfs_SetSplitCounter(Search,flag_GetFlagValue(Flags, flag_SPLITS));
+ prfs_SetLoops(Search,flag_GetFlagValue(Flags, flag_LOOPS));
+ prfs_SetBacktrackedClauses(Search, 0);
+ BoundApplied = -1;
+ Search = top_ProofSearch(Search, ProblemClauses, InputFlags, UserPrecedence, &BoundApplied);
+
+ if ((flag_GetFlagValue(Flags, flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED ||
+ flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL)) &&
+ prfs_Loops(Search) != 0 &&
+ (BoundApplied == -1 || !list_Empty(prfs_EmptyClauses(Search)))) {
+ if (list_Empty(prfs_EmptyClauses(Search)))
+ Result = top_COMPLETION;
+ else
+ Result = top_PROOF;
+ }
+
+ if (flag_GetFlagValue(Flags, flag_TIMELIMIT) != 0) {
+ /* Stop SPASS immediately */
+ printf("\nSPASS %s ", misc_VERSION);
+ fputs("\nSPASS beiseite: ", stdout);
+ switch (Result) {
+ case top_RESOURCE:
+ if (prfs_Loops(Search) != 0)
+ fputs("Ran out of time.", stdout);
+ else
+ fputs("Maximal number of loops exceeded.", stdout);
+ break;
+ case top_PROOF:
+ fputs("Proof found.", stdout);
+ break;
+ default: /* Completion */
+ fputs("Completion found.", stdout);
+ }
+ printf("\nProblem: %s ",
+ (top_InputFile != (char*)NULL ? top_InputFile : "Read from stdin."));
+ if (flag_GetFlagValue(Flags, flag_PSTATISTIC)) {
+ clock_StopPassedTime(clock_OVERALL);
+ printf("\nSPASS derived %d clauses,", prfs_DerivedClauses(Search));
+ printf(" backtracked %d clauses", prfs_BacktrackedClauses(Search));
+ printf(" and kept %d clauses.", prfs_KeptClauses(Search));
+ printf("\nSPASS allocated %lu KBytes.", memory_DemandedBytes()/1024);
+ fputs("\nSPASS spent\t", stdout);
+ clock_PrintTime(clock_OVERALL);
+ fputs(" on the problem.\n\t\t", stdout);
+ clock_PrintTime(clock_INPUT);
+ fputs(" for the input.\n\t\t", stdout);
+ clock_PrintTime(clock_CNF);
+ fputs(" for the FLOTTER CNF translation.\n\t\t", stdout);
+ clock_PrintTime(clock_INFERENCE);
+ fputs(" for inferences.\n\t\t", stdout);
+ clock_PrintTime(clock_BACKTRACK);
+ fputs(" for the backtracking.\n\t\t", stdout);
+ clock_PrintTime(clock_REDUCTION);
+ puts(" for the reduction.");
+ }
+ if (Result != top_PROOF &&
+ flag_GetFlagValue(Flags, flag_FPMODEL) != flag_FPMODELOFF) {
+ FILE *Output;
+ char name[100];
+ const char * creator = "{*SPASS " misc_VERSION " *}";
+ BOOL PrintPotProductive;
+
+ strcpy(name, (top_InputFile != (char*)NULL ? top_InputFile : "SPASS"));
+ if (Result == top_COMPLETION)
+ strcat(name, ".model");
+ else
+ strcat(name, ".clauses");
+ Output = misc_OpenFile(name,"w");
+ PrintPotProductive = (flag_GetFlagValue(Flags, flag_FPMODEL) ==
+ flag_FPMODELPOTENTIALLYPRODUCTIVECLAUSES);
+ if (Result == top_COMPLETION)
+ clause_FPrintCnfFormulasDFGProblem(Output, PrintPotProductive,
+ "{*Completion_by_SPASS*}",
+ creator, "satisfiable",
+ dfg_ProblemDescription(),
+ prfs_WorkedOffClauses(Search),
+ list_Nil(), Flags, Precedence);
+ else
+ clause_FPrintCnfFormulasDFGProblem(Output, PrintPotProductive,
+ "{*Clauses_generated_by_SPASS*}",
+ creator, "unknown",
+ dfg_ProblemDescription(),
+ prfs_WorkedOffClauses(Search),
+ prfs_UsableClauses(Search), Flags,
+ Precedence);
+ misc_CloseFile(Output, name);
+ if (Result == top_COMPLETION)
+ printf("\nCompletion printed to: %s\n", name);
+ else
+ printf("\nClauses printed to: %s\n", name);
+ }
+
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF) && Result != top_RESOURCE) {
+ if (Result == top_COMPLETION) {
+ puts("\n\n The saturated set of worked-off clauses is :");
+ clause_ListPrint(prfs_WorkedOffClauses(Search));
+ }
+ else {
+ LIST UsedClauses, UsedTerms;
+ if (!top_InputFile)
+ top_InputFile = "SPASS";
+ UsedClauses = dp_PrintProof(Search, prfs_EmptyClauses(Search),
+ top_InputFile);
+ /* Find terms required for proof */
+ UsedTerms = list_Nil();
+
+ for (Scan = UsedClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (clause_IsFromInput((CLAUSE) list_Car(Scan))) {
+ LIST L;
+ L = hsh_Get(ClauseToTermLabellist, list_Car(Scan));
+ L = list_Copy(L);
+ L = cnf_DeleteDuplicateLabelsFromList(L);
+ UsedTerms = list_Nconc(UsedTerms, L);
+ }
+ list_Delete(UsedClauses);
+ UsedTerms = cnf_DeleteDuplicateLabelsFromList(UsedTerms);
+ fputs("\nFormulae used in the proof :", stdout);
+ for (Scan = UsedTerms; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (!(strncmp((char*) list_Car(Scan), "_SORT_", 6) == 0))
+ printf(" %s", (char*) list_Car(Scan));
+ putchar('\n');
+ list_Delete(UsedTerms);
+ }
+ }
+ }
+
+ /* Delete mapping for the clause copies of the labelclauses */
+ for (Scan = LabelClauses; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ hsh_DelItem(ClauseToTermLabellist, list_Car(Scan));
+
+ list_Delete(ProblemClauses);
+
+ fflush(stdout);
+
+ /* Keep definitions */
+ deflist = prfs_Definitions(Search);
+ prfs_SetDefinitions(Search, list_Nil());
+ prfs_Clean(Search);
+ prfs_SetDefinitions(Search, deflist);
+
+ symbol_TransferPrecedence(InputPrecedence, Precedence);
+ if (flag_GetFlagValue(Flags, flag_PPROBLEM))
+ fputs("\n--------------------------SPASS-STOP------------------------------", stdout);
+ } while (flag_GetFlagValue(Flags, flag_INTERACTIVE) &&
+ (flag_GetFlagValue(Flags, flag_TIMELIMIT) != 0));
+
+ for (Scan = InputClauses; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ clause_OrientAndReInit(list_Car(Scan), Flags, Precedence);
+
+ /* Cleanup Flotter data structures */
+ if (flag_GetFlagValue(Flags, flag_INTERACTIVE)) {
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+ list_Delete(Symblist);
+ else
+ symbol_DeleteSymbolList(Symblist);
+ /* symbol_ResetSkolemIndex(); */
+ if (FlotterSearch != NULL)
+ prfs_Delete(FlotterSearch);
+ }
+ if (flag_GetFlagValue(Flags, flag_PFLAGS)) {
+ putchar('\n');
+ flag_Print(Flags);
+ }
+ if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+ hsh_Delete(TermLabelToClauselist);
+ hsh_Delete(ClauseToTermLabellist);
+ }
+ for (Scan = Labellist; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ string_StringFree(list_Car(Scan));
+ list_Delete(Labellist);
+ list_Delete(Sortlabellist);
+ list_Delete(UserPrecedence);
+
+ cnf_Free(Flags);
+
+ prfs_Delete(Search);
+ clause_DeleteClauseList(InputClauses);
+ flag_DeleteStore(InputFlags);
+ symbol_DeletePrecedence(InputPrecedence);
+
+ cc_Free();
+ ana_Free();
+ sort_Free();
+ unify_Free();
+ cont_Free();
+ fol_Free();
+ symbol_FreeAllSymbols();
+ dfg_Free();
+ opts_Free();
+#ifdef CHECK
+ memory_Print();
+ memory_PrintLeaks();
+#endif
+ putchar('\n');
+ return 0;
+}
diff --git a/test/spass/unify.c b/test/spass/unify.c
new file mode 100644
index 0000000..14cc7a6
--- /dev/null
+++ b/test/spass/unify.c
@@ -0,0 +1,857 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * STANDARD UNIFICATION * */
+/* * * */
+/* * $Module: UNIFY * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "unify.h"
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INITIALIZATION * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void unify_Init(void)
+/**********************************************************
+ INPUT: None.
+ RETURNS: None.
+ EFFECT: Initializes the unify module.
+********************************************************/
+{
+
+}
+
+void unify_Free(void)
+/**********************************************************
+ INPUT: None.
+ RETURNS: None.
+ EFFECT: Frees internal structures of the unify module.
+********************************************************/
+{
+
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * MISC FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * OCCUR CHECK * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_OccurCheckCom(SYMBOL Top, CONTEXT Context, TERM Term)
+/**********************************************************
+ INPUT: A variable symbol, a context, and a term.
+ RETURNS: TRUE if there is a occur check failure with respect
+ to the variable symbol <Top> and <Term>.
+ The search is started in <Term>
+***********************************************************/
+{
+ int Bottom;
+ LIST Args;
+
+ Bottom = stack_Bottom();
+
+ for (;;) {
+
+ if (term_IsVariable(Term)) {
+ if (symbol_Equal(Top, term_TopSymbol(Term))) {
+ stack_SetBottom(Bottom);
+ return TRUE;
+ } else if (cont_VarIsBound(Context, term_TopSymbol(Term))) {
+ Term = cont_ContextBindingTerm(Context, term_TopSymbol(Term));
+ continue;
+ }
+
+ } else if (term_IsComplex(Term)) {
+
+ Args = term_ArgumentList(Term);
+ if (!list_Empty(list_Cdr(Args)))
+ stack_Push(list_Cdr(Args));
+
+ Term = list_Car(Args);
+ continue;
+ }
+
+ if (stack_Empty(Bottom))
+ return FALSE;
+ else {
+ Args = (LIST)stack_PopResult();
+ Term = list_Car(Args);
+ if (!list_Empty(list_Cdr(Args)))
+ stack_Push(list_Cdr(Args));
+ }
+ }
+}
+
+
+BOOL unify_OccurCheck(CONTEXT CTop, SYMBOL Top, CONTEXT CTerm, TERM Term)
+/**********************************************************
+ INPUT: A context, a variable symbol, a context, and a term.
+ RETURNS: TRUE if there is a occur check failure with respect
+ to the variable symbol <Top> and <Term>.
+ The search is started in <Term>
+***********************************************************/
+{
+ int Bottom;
+ LIST Args;
+ SYMBOL TermTop;
+
+ Bottom = stack_Bottom();
+
+ for (;;) {
+
+ if (term_IsVariable(Term)) {
+
+ TermTop = term_TopSymbol(Term);
+
+ if ((CTop == CTerm) && (symbol_Equal(Top, TermTop))) {
+ stack_SetBottom(Bottom);
+ return TRUE;
+ } else if (cont_VarIsBound(CTerm, TermTop)) {
+ Term = cont_ContextBindingTerm(CTerm, TermTop);
+ CTerm = cont_ContextBindingContext(CTerm, TermTop);
+ continue;
+ }
+ } else if (term_IsComplex(Term)) {
+
+ Args = term_ArgumentList(Term);
+ if (!list_Empty(list_Cdr(Args))) {
+ stack_Push(CTerm);
+ stack_Push(list_Cdr(Args));
+ }
+ Term = list_Car(Args);
+ continue;
+
+ }
+
+ if (stack_Empty(Bottom))
+ return FALSE;
+ else {
+ Args = (LIST)stack_PopResult();
+ Term = list_Car(Args);
+ CTerm = (CONTEXT)stack_Top();
+ if (list_Empty(list_Cdr(Args)))
+ stack_Pop();
+ else
+ stack_Push(list_Cdr(Args));
+ }
+ }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * UNIFICATION * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_Unify(CONTEXT CtL, TERM TermL, CONTEXT CtR, TERM TermR)
+/**********************************************************
+ INPUT: Two terms which may contain the same variable symbols.
+ Equal variable symbols are interpreted different in
+ <TermL> and <TermR>, respectively.
+ RETURNS: TRUE, if <TermL> and <TermR> are unifiable, FALSE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ CONTEXT CHelp;
+ LIST ArgsL, ArgsR;
+ int Bottom;
+ BOOL Bound;
+
+ Bound = FALSE;
+ Bottom = stack_Bottom();
+
+ for (;;) {
+
+ while (term_IsVariable(TermL) &&
+ cont_VarIsBound(CtL, term_TopSymbol(TermL))) {
+ CHelp = cont_ContextBindingContext(CtL, term_TopSymbol(TermL));
+ TermL = cont_ContextBindingTerm(CtL, term_TopSymbol(TermL));
+ CtL = CHelp;
+ }
+
+ while (term_IsVariable(TermR) &&
+ cont_VarIsBound(CtR, term_TopSymbol(TermR))) {
+ CHelp = cont_ContextBindingContext(CtR, term_TopSymbol(TermR));
+ TermR = cont_ContextBindingTerm(CtR, term_TopSymbol(TermR));
+ CtR = CHelp;
+ }
+
+ /* Caution: Bindings from variable to variable are made with priority
+ from the right context into the left context. */
+
+ if (term_IsVariable(TermL)) {
+ if (term_IsVariable(TermR)) {
+ if (!(CtL == CtR && term_EqualTopSymbols(TermL, TermR)))
+ Bound = cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+ } else if (Bound && unify_OccurCheck(CtL, term_TopSymbol(TermL), CtR, TermR)) {
+ stack_SetBottom(Bottom);
+ return FALSE;
+ } else
+ Bound = cont_CreateBinding(CtL, term_TopSymbol(TermL), CtR, TermR);
+
+ } else if (term_IsVariable(TermR)) {
+ if (Bound && unify_OccurCheck(CtR, term_TopSymbol(TermR), CtL, TermL)) {
+ stack_SetBottom(Bottom);
+ return FALSE;
+ } else
+ Bound = cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+
+ } else if (term_EqualTopSymbols(TermL, TermR)) {
+ if (term_IsComplex(TermL) && TermL != TermR) {
+ ArgsL = term_ArgumentList(TermL);
+ ArgsR = term_ArgumentList(TermR);
+ if (!list_Empty(list_Cdr(ArgsL))) {
+ stack_Push(CtL);
+ stack_Push(CtR);
+ stack_Push(list_Cdr(ArgsL));
+ stack_Push(list_Cdr(ArgsR));
+ }
+ TermL = list_Car(ArgsL);
+ TermR = list_Car(ArgsR);
+ continue;
+ }
+ } else {
+ stack_SetBottom(Bottom);
+ return FALSE;
+ }
+
+ if (stack_Empty(Bottom))
+ return TRUE;
+ else {
+ ArgsR = stack_PopResult();
+ ArgsL = stack_PopResult();
+ TermR = list_Car(ArgsR);
+ TermL = list_Car(ArgsL);
+ CtR = (CONTEXT)stack_Top();
+ CtL = (CONTEXT)stack_NthTop(1);
+ if (list_Empty(list_Cdr(ArgsL)))
+ stack_NPop(2);
+ else {
+ stack_Push(list_Cdr(ArgsL));
+ stack_Push(list_Cdr(ArgsR));
+ }
+ }
+ }
+}
+
+BOOL unify_UnifyCom(CONTEXT Context, TERM TermL, TERM TermR)
+/**********************************************************
+ INPUT: Two terms which may contain the same variable symbols.
+ Equal variable symbols are interpreted equally in
+ <TermL> and <TermR>, respectively.
+ RETURNS: TRUE, if <TermL> and <TermR> are unifiable, FALSE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ LIST ArgsL, ArgsR;
+ int Bottom;
+
+ Bottom = stack_Bottom();
+
+ for (;;) {
+
+ while (term_IsVariable(TermL) &&
+ cont_VarIsBound(Context, term_TopSymbol(TermL)))
+ TermL = cont_ContextBindingTerm(Context, term_TopSymbol(TermL));
+
+ while (term_IsVariable(TermR) &&
+ cont_VarIsBound(Context, term_TopSymbol(TermR)))
+ TermR = cont_ContextBindingTerm(Context, term_TopSymbol(TermR));
+
+ if (term_EqualTopSymbols(TermL, TermR)) {
+ if (term_IsComplex(TermL) && TermL != TermR) {
+ ArgsL = term_ArgumentList(TermL);
+ ArgsR = term_ArgumentList(TermR);
+ if (!list_Empty(list_Cdr(ArgsL))) {
+ stack_Push(list_Cdr(ArgsL));
+ stack_Push(list_Cdr(ArgsR));
+ }
+ TermL = list_Car(ArgsL);
+ TermR = list_Car(ArgsR);
+ continue;
+ }
+ } else if (term_IsVariable(TermL)) {
+ if (term_IsVariable(TermR))
+ cont_CreateBinding(Context, term_TopSymbol(TermL), Context, TermR);
+ else if (unify_OccurCheckCom(term_TopSymbol(TermL), Context, TermR)) {
+ stack_SetBottom(Bottom);
+ return FALSE;
+ } else
+ cont_CreateBinding(Context, term_TopSymbol(TermL), Context, TermR);
+
+ } else if (term_IsVariable(TermR)) {
+ if (unify_OccurCheckCom(term_TopSymbol(TermR), Context, TermL)) {
+ stack_SetBottom(Bottom);
+ return FALSE;
+ } else
+ cont_CreateBinding(Context, term_TopSymbol(TermR), Context, TermL);
+
+ } else {
+ stack_SetBottom(Bottom);
+ return FALSE;
+ }
+
+ if (stack_Empty(Bottom))
+ return TRUE;
+ else {
+ ArgsR = stack_PopResult();
+ ArgsL = stack_PopResult();
+ TermR = list_Car(ArgsR);
+ TermL = list_Car(ArgsL);
+ if (!list_Empty(list_Cdr(ArgsL))) {
+ stack_Push(list_Cdr(ArgsL));
+ stack_Push(list_Cdr(ArgsR));
+ }
+ }
+ }
+}
+
+
+
+BOOL unify_UnifyNoOC(CONTEXT CtL, TERM TermL, CONTEXT CtR, TERM TermR)
+/**********************************************************
+ INPUT: Two terms which may contain the same variable symbols.
+ Equal variable symbols are interpreted different in
+ <TermL> and <TermR>, respectively.
+ RETURNS: TRUE, if <TermL> and <TermR> are unifiable, FALSE otherwise.
+ CAUTION: None.
+***********************************************************/
+{
+ CONTEXT CHelp;
+ LIST ArgsL, ArgsR;
+ int Bottom;
+
+ Bottom = stack_Bottom();
+
+ for (;;) {
+
+ while (term_IsVariable(TermL) &&
+ cont_VarIsBound(CtL, term_TopSymbol(TermL))) {
+ CHelp = cont_ContextBindingContext(CtL, term_TopSymbol(TermL));
+ TermL = cont_ContextBindingTerm(CtL, term_TopSymbol(TermL));
+ CtL = CHelp;
+ }
+
+ while (term_IsVariable(TermR) &&
+ cont_VarIsBound(CtR, term_TopSymbol(TermR))) {
+ CHelp = cont_ContextBindingContext(CtR, term_TopSymbol(TermR));
+ TermR = cont_ContextBindingTerm(CtR, term_TopSymbol(TermR));
+ CtR = CHelp;
+ }
+
+ /* Caution: Bindings from variable to variable are made with priority
+ from the right context into the left context. */
+
+ if (term_IsVariable(TermL)) {
+ if (term_IsVariable(TermR)) {
+ if (!(CtL == CtR && term_EqualTopSymbols(TermL, TermR)))
+ cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+ } else
+ cont_CreateBinding(CtL, term_TopSymbol(TermL), CtR, TermR);
+
+ } else if (term_IsVariable(TermR))
+ cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+
+ else if (term_EqualTopSymbols(TermL, TermR)) {
+ if (term_IsComplex(TermL) && TermL != TermR) {
+ ArgsL = term_ArgumentList(TermL);
+ ArgsR = term_ArgumentList(TermR);
+ if (!list_Empty(list_Cdr(ArgsL))) {
+ stack_Push(CtL);
+ stack_Push(CtR);
+ stack_Push(list_Cdr(ArgsL));
+ stack_Push(list_Cdr(ArgsR));
+ }
+ TermL = list_Car(ArgsL);
+ TermR = list_Car(ArgsR);
+ continue;
+ }
+ } else {
+ stack_SetBottom(Bottom);
+ return FALSE;
+ }
+
+ if (stack_Empty(Bottom))
+ return TRUE;
+ else {
+ ArgsR = stack_PopResult();
+ ArgsL = stack_PopResult();
+ TermR = list_Car(ArgsR);
+ TermL = list_Car(ArgsL);
+ CtR = (CONTEXT) stack_Top();
+ CtL = (CONTEXT) stack_NthTop(1);
+ if (list_Empty(list_Cdr(ArgsL)))
+ stack_NPop(2);
+ else {
+ stack_Push(list_Cdr(ArgsL));
+ stack_Push(list_Cdr(ArgsR));
+ }
+ }
+ }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * UNIFICATION WITH FULL OCCUR CHECK (recursive) * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_UnifyAllOC(CONTEXT IndexContext, CONTEXT CtL, TERM TermL, CONTEXT CtR, TERM TermR)
+{
+ while (term_IsVariable(TermL)) {
+ SYMBOL TermTop;
+
+ TermTop = term_TopSymbol(TermL);
+
+ if (cont_VarIsBound(CtL, TermTop)) {
+ CONTEXT CHelp;
+
+ CHelp = cont_ContextBindingContext(CtL, TermTop);
+ TermL = cont_ContextBindingTerm(CtL, TermTop);
+ CtL = CHelp;
+ } else
+ break;
+ }
+
+ while (term_IsVariable(TermR)) {
+ SYMBOL TermTop;
+
+ TermTop = term_TopSymbol(TermR);
+
+ if (cont_VarIsBound(CtR, TermTop)) {
+ CONTEXT CHelp;
+
+ CHelp = cont_ContextBindingContext(CtR, TermTop);
+ TermR = cont_ContextBindingTerm(CtR, TermTop);
+ CtR = CHelp;
+ } else
+ break;
+ }
+
+ if (term_IsVariable(TermL)) {
+
+ if (term_IsVariable(TermR)) {
+ if ((CtL != CtR || !term_EqualTopSymbols(TermL, TermR))) {
+ if (term_IsIndexVariable(TermL))
+ cont_CreateBinding(CtL, term_TopSymbol(TermL), CtR, TermR);
+ else
+ if (term_IsIndexVariable(TermR) || (CtR == IndexContext))
+ cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+ else
+ cont_CreateBinding(CtL, term_TopSymbol(TermL), CtR, TermR);
+ }
+ return TRUE;
+ }
+ else
+ if (unify_OccurCheck(CtL, term_TopSymbol(TermL), CtR, TermR))
+ return FALSE;
+ else {
+ cont_CreateBinding(CtL, term_TopSymbol(TermL), CtR, TermR);
+ return TRUE;
+ }
+ }
+ else
+ if (term_IsVariable(TermR)) {
+ if (unify_OccurCheck(CtR, term_TopSymbol(TermR), CtL, TermL))
+ return FALSE;
+ else {
+ cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+ return TRUE;
+ }
+ }
+ else
+ if (term_EqualTopSymbols(TermL, TermR)) {
+ if (term_IsComplex(TermL)) {
+ LIST ArgL, ArgR;
+ for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+ !list_Empty(ArgL);
+ ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+ if (!unify_UnifyAllOC(IndexContext, CtL, list_Car(ArgL), CtR, list_Car(ArgR)))
+ return FALSE;
+ }
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * GENERALIZATION TEST * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_Match(CONTEXT Context, TERM TermL, TERM TermR)
+{
+ if (term_IsVariable(TermL)) {
+ if (cont_VarIsBound(Context, term_TopSymbol(TermL)))
+ return term_Equal(cont_ContextBindingTerm(Context, term_TopSymbol(TermL)), TermR);
+ else {
+ cont_CreateBinding(Context, term_TopSymbol(TermL), cont_InstanceContext(), TermR);
+ return TRUE;
+ }
+ } else if (term_EqualTopSymbols(TermL, TermR)) {
+ if (term_IsComplex(TermL)) {
+ LIST ArgL;
+ LIST ArgR;
+ for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+ !list_Empty(ArgL);
+ ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+ if (!unify_Match(Context, list_Car(ArgL), list_Car(ArgR)))
+ return FALSE;
+ }
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+BOOL unify_MatchFlexible(CONTEXT Context, TERM TermL, TERM TermR)
+/**************************************************************
+ INPUT: Two terms where symbols with flexible arity are allowed.
+ RETURNS: TRUE if <TermL> matches <TermR>.
+***************************************************************/
+{
+ if (term_IsVariable(TermL)) {
+ if (cont_VarIsBound(Context, term_TopSymbol(TermL)))
+ return term_Equal(cont_ContextBindingTerm(Context, term_TopSymbol(TermL)), TermR);
+ else {
+ cont_CreateBinding(Context, term_TopSymbol(TermL), cont_InstanceContext(), TermR);
+ return TRUE;
+ }
+ } else
+ if (term_EqualTopSymbols(TermL, TermR)
+ && list_Length(term_ArgumentList(TermL)) == list_Length(term_ArgumentList(TermR))) {
+ if (term_IsComplex(TermL)) {
+ LIST ArgL;
+ LIST ArgR;
+ for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+ !list_Empty(ArgL);
+ ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+ if (!unify_MatchFlexible(Context, list_Car(ArgL), list_Car(ArgR)))
+ return FALSE;
+ }
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+void unify_EstablishMatcher(CONTEXT Context, SUBST Subst)
+{
+ while (subst_Exist(Subst)) {
+ /* Index to query */
+ cont_CreateBinding(Context, subst_Dom(Subst), cont_InstanceContext(), subst_Cod(Subst));
+ Subst = subst_Next(Subst);
+ }
+}
+
+
+BOOL unify_MatchBindingsHelp(const CONTEXT IndexContext, TERM TermL, CONTEXT CtR, TERM TermR)
+{
+ while (term_IsVariable(TermR)) {
+ SYMBOL TermTop;
+
+ TermTop = term_TopSymbol(TermR);
+
+ if (symbol_IsIndexVariable(TermTop))
+ CtR = IndexContext;
+ else if (CtR == cont_InstanceContext())
+ break;
+
+ if (cont_VarIsBound(CtR, TermTop)) {
+ CONTEXT CHelp;
+
+ CHelp = cont_ContextBindingContext(CtR, TermTop);
+ TermR = cont_ContextBindingTerm(CtR, TermTop);
+ CtR = CHelp;
+ } else
+ break;
+ }
+
+ if (term_IsVariable(TermL)) {
+ /* Assertion: Variables of 'TermL' are bound in the index context only. */
+
+ if (cont_VarIsBound(IndexContext, term_TopSymbol(TermL)))
+ return
+ cont_TermEqualModuloBindings(IndexContext,
+ cont_ContextBindingContext(IndexContext,
+ term_TopSymbol(TermL)),
+ cont_ContextBindingTerm(IndexContext,
+ term_TopSymbol(TermL)),
+ CtR,
+ TermR);
+ else {
+ cont_CreateBinding(IndexContext, term_TopSymbol(TermL), CtR, TermR);
+ return TRUE;
+ }
+ } else if (term_EqualTopSymbols(TermL, TermR)) {
+ if (term_IsComplex(TermL)) {
+ LIST ArgL;
+ LIST ArgR;
+
+ for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+ !list_Empty(ArgL);
+ ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+ if (!unify_MatchBindingsHelp(IndexContext, list_Car(ArgL), CtR, list_Car(ArgR)))
+ return FALSE;
+ }
+
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+BOOL unify_MatchBindings(const CONTEXT IndexContext, TERM TermL, TERM TermR)
+{
+ return unify_MatchBindingsHelp(IndexContext, TermL, cont_InstanceContext(), TermR);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * INSTANCE TEST * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_MatchReverse(const CONTEXT IndexContext, TERM TermL, CONTEXT CtR,
+ TERM TermR)
+/*********************************************************
+ INPUT: 'TermL' is in IndexContext and the codomain of a subst.,
+ 'CtR' is the context of 'TermR' which is the codomain of a subst.
+ obtained by a variable binding, 'Bindings' is
+ the number of established bindings.
+ RETURNS: TRUE, if 'TermL' is an instance of 'TermR';
+ FALSE, otherwise.
+**********************************************************/
+{
+ while (term_IsVariable(TermR)) {
+ SYMBOL TermTop;
+
+ TermTop = term_TopSymbol(TermR);
+
+ if (symbol_IsIndexVariable(TermTop))
+ CtR = IndexContext;
+ else if (CtR == cont_InstanceContext())
+ break;
+
+ if (cont_VarIsBound(CtR, TermTop)) {
+ CONTEXT CHelp;
+
+ CHelp = cont_ContextBindingContext(CtR, TermTop);
+ TermR = cont_ContextBindingTerm(CtR, TermTop);
+ CtR = CHelp;
+ } else
+ break;
+ }
+
+ if (term_IsVariable(TermL)) {
+ if ((CtR == cont_InstanceContext()) && term_EqualTopSymbols(TermL, TermR))
+ /* 'TermL' and 'TermR' are exactly the same variables (via bindings),
+ therefore do not bind them, just return positive. */
+ return TRUE;
+
+ else if (term_IsIndexVariable(TermL)) {
+ cont_CreateBinding(IndexContext, term_TopSymbol(TermL), CtR, TermR);
+ return TRUE;
+
+ } else if (term_IsVariable(TermR) &&
+ (term_IsIndexVariable(TermR) || (CtR == IndexContext))) {
+ cont_CreateBinding(IndexContext, term_TopSymbol(TermR), cont_InstanceContext(), TermL);
+ return TRUE;
+
+ } else
+ return FALSE;
+
+ } else if (term_IsVariable(TermR)) {
+ if (term_IsIndexVariable(TermR) || (CtR == IndexContext)) {
+ cont_CreateBinding(IndexContext, term_TopSymbol(TermR), cont_InstanceContext(), TermL);
+ return TRUE;
+ } else
+ return FALSE;
+
+ } else if (term_EqualTopSymbols(TermL, TermR)) {
+
+ if (term_IsComplex(TermL)) {
+ LIST ArgL, ArgR;
+ for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+ !list_Empty(ArgL);
+ ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+ if (!unify_MatchReverse(IndexContext,
+ list_Car(ArgL),
+ CtR,
+ list_Car(ArgR)))
+ return FALSE;
+ }
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * VARIATION TEST * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_Variation(const CONTEXT Context, TERM TermL, TERM TermR)
+{
+ if (term_IsVariable(TermL)) {
+ if (term_EqualTopSymbols(TermL, TermR))
+ /* TermL and TermR are in different contexts
+ but both are term variables which do not need to be variated.
+ Index variables cannot occur in TermR
+ which is the term to be inserted. */
+ return TRUE;
+ else if (term_IsIndexVariable(TermL)) {
+ if (cont_VarIsBound(Context, term_TopSymbol(TermL)))
+ return term_Equal(cont_ContextBindingTerm(Context, term_TopSymbol(TermL)), TermR);
+ else {
+ /* Index to query */
+ cont_CreateBinding(Context, term_TopSymbol(TermL), Context, TermR);
+ return TRUE;
+ }
+ }
+ else
+ return FALSE;
+
+ } else if (term_EqualTopSymbols(TermL, TermR)) {
+ if (term_IsComplex(TermL)) {
+ LIST ArgL;
+ LIST ArgR;
+ for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+ !list_Empty(ArgL);
+ ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+ if (!unify_Variation(Context, list_Car(ArgL), list_Car(ArgR)))
+ return FALSE;
+ }
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * COMMON GENERALIZATIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+TERM unify_ComGenLinear(const CONTEXT IndexContext,
+ SUBST* SubstL, TERM TermL, SUBST* SubstR, TERM TermR)
+{
+ if (term_IsIndexVariable(TermR)) {
+ *SubstL = subst_Add(term_TopSymbol(TermR), term_Copy(TermL), *SubstL);
+
+ return term_Copy(TermR);
+
+ } else if (term_EqualTopSymbols(TermL, TermR)) {
+
+ LIST ArgList, ArgL, ArgR;
+
+ ArgList = list_Nil();
+ for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+ !list_Empty(ArgL);
+ ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+ ArgList = list_Nconc(ArgList,
+ list_List(unify_ComGenLinear(IndexContext,
+ SubstL,
+ list_Car(ArgL),
+ SubstR,
+ list_Car(ArgR))));
+ return term_Create(term_TopSymbol(TermL), ArgList);
+
+ } else {
+
+ SYMBOL Symbol;
+
+ Symbol = cont_NextIndexVariable(IndexContext);
+
+ *SubstL = subst_Add(Symbol, term_Copy(TermL), *SubstL);
+ *SubstR = subst_Add(Symbol, term_Copy(TermR), *SubstR);
+
+ return term_Create(Symbol, list_Nil());
+ }
+}
+
diff --git a/test/spass/unify.h b/test/spass/unify.h
new file mode 100644
index 0000000..92c9398
--- /dev/null
+++ b/test/spass/unify.h
@@ -0,0 +1,119 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * STANDARD UNIFICATION * */
+/* * * */
+/* * $Module: UNIFY * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _UNIFY_
+#define _UNIFY_
+
+/**************************************************************/
+/* Includes */
+/**************************************************************/
+
+#include "term.h"
+#include "symbol.h"
+#include "list.h"
+#include "context.h"
+#include "subst.h"
+
+/**************************************************************/
+/* Functions for Initialization and Controlling */
+/**************************************************************/
+
+void unify_Init(void);
+void unify_Free(void);
+
+/**************************************************************/
+/* Functions for Misc */
+/**************************************************************/
+
+/**************************************************************/
+/* Functions for Occur Check */
+/**************************************************************/
+
+BOOL unify_OccurCheckCom(SYMBOL, CONTEXT, TERM);
+BOOL unify_OccurCheck(CONTEXT, SYMBOL, CONTEXT, TERM);
+
+/**************************************************************/
+/* Functions for Unification */
+/**************************************************************/
+
+BOOL unify_Unify(CONTEXT, TERM, CONTEXT, TERM);
+BOOL unify_UnifyCom(CONTEXT, TERM, TERM);
+BOOL unify_UnifyNoOC(CONTEXT, TERM, CONTEXT, TERM);
+BOOL unify_UnifyAllOC(CONTEXT, CONTEXT, TERM, CONTEXT, TERM);
+
+/**************************************************************/
+/* Functions for Generalization Test */
+/**************************************************************/
+
+BOOL unify_Match(CONTEXT, TERM, TERM);
+BOOL unify_MatchFlexible(CONTEXT, TERM, TERM);
+void unify_EstablishMatcher(CONTEXT, SUBST);
+BOOL unify_MatchBindings(const CONTEXT, TERM, TERM);
+
+/**************************************************************/
+/* Functions for Instance Test */
+/**************************************************************/
+
+BOOL unify_MatchReverse(const CONTEXT, TERM, CONTEXT, TERM);
+
+/**************************************************************/
+/* Functions for Variation Test */
+/**************************************************************/
+
+BOOL unify_Variation(const CONTEXT, TERM, TERM);
+
+/**************************************************************/
+/* Functions for Computing MSCGs */
+/**************************************************************/
+
+TERM unify_ComGenLinear(const CONTEXT, SUBST*, TERM, SUBST*, TERM);
+
+/**************************************************************/
+/* Functions for Debugging */
+/**************************************************************/
+
+#endif
diff --git a/test/spass/vector.c b/test/spass/vector.c
new file mode 100644
index 0000000..bd16424
--- /dev/null
+++ b/test/spass/vector.c
@@ -0,0 +1,120 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * GLOBAL SYSTEM VECTOR * */
+/* * * */
+/* * $Module: VECTOR * */
+/* * * */
+/* * Copyright (C) 1996, 2000, 2001 MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "vector.h"
+
+/**************************************************************/
+/* Global Variables */
+/**************************************************************/
+
+VECTOR vec_VECTOR;
+int vec_MAX;
+
+
+/**************************************************************/
+/* Functions */
+/**************************************************************/
+
+void vec_Swap(int i, int j)
+/**********************************************************
+ INPUT: Two integers i and j which designate the i-th and
+ the j-th cell of the vector.
+ RETURNS: None.
+ CAUTION: The values in the i-th and the j-th cell in the
+ vector are interchanged.
+********************************************************/
+{
+ POINTER help;
+
+ help = vec_GetNth(i);
+ vec_PutNth(i, vec_GetNth(j));
+ vec_PutNth(j, help);
+
+}
+
+
+void vec_PrintSel(int beg, int end, void (*ElementPrint)(POINTER))
+/**********************************************************
+ INPUT: An int for the start position, an int for
+ the end position and a print function for
+ elements.
+ RETURNS: None.
+ EFFECT: Writes the vector from beg to end to stdout.
+ CAUTION: None.
+********************************************************/
+{
+ int i;
+
+ if (vec_ActMax() > 0) {
+ for (i = beg; i < end; i++){
+ printf("Entry %d:\t",i);
+ ElementPrint(vec_GetNth(i));
+ putchar('\n');
+ }
+ } else
+ puts("Vector is empty");
+}
+
+
+void vec_PrintAll(void (*ElementPrint)(POINTER))
+/**********************************************************
+ INPUT: A print function for the elements of the vector.
+ RETURNS: None.
+ EFFECT: Writes the vector to stdout.
+ CAUTION: None.
+********************************************************/
+{
+ int i;
+
+ if (vec_ActMax() > 0) {
+ for (i = 0; i < vec_ActMax(); i++) {
+ printf("Entry %d:\t", i);
+ ElementPrint(vec_GetNth(i));
+ putchar('\n');
+ }
+ } else
+ puts("Vector is empty");
+}
diff --git a/test/spass/vector.h b/test/spass/vector.h
new file mode 100644
index 0000000..2204804
--- /dev/null
+++ b/test/spass/vector.h
@@ -0,0 +1,188 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * GLOBAL SYSTEM VECTOR * */
+/* * * */
+/* * $Module: VECTOR * */
+/* * * */
+/* * Copyright (C) 1996, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * 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 * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _VECTOR_
+#define _VECTOR_
+
+#include "misc.h"
+
+
+/**************************************************************/
+/* Type and Variable Definitions */
+/**************************************************************/
+
+#define vec_SIZE 10000
+
+typedef POINTER VECTOR[vec_SIZE];
+
+extern VECTOR vec_VECTOR;
+extern int vec_MAX;
+
+/**************************************************************/
+/* Inline Functions */
+/**************************************************************/
+
+/* Stack operations */
+
+static __inline__ void vec_Init(void)
+{
+ vec_MAX = 0;
+}
+
+static __inline__ void vec_Push(POINTER Value)
+{
+#ifdef CHECK
+ if (vec_MAX >= vec_SIZE) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In vec_Push: Vector Overflow.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ vec_VECTOR[vec_MAX++] = Value;
+}
+
+
+static __inline__ POINTER vec_GetNth(NAT Index)
+{
+#ifdef CHECK
+ if (Index >= vec_SIZE || Index >= vec_MAX) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In vec_GetNth: Illegal vector access.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return vec_VECTOR[Index];
+}
+
+
+static __inline__ void vec_PutNth(NAT Index, POINTER Value)
+{
+#ifdef CHECK
+ if (Index >= vec_SIZE || Index >= vec_MAX) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In vec_PutNth: Illegal vector access.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ vec_VECTOR[Index] = Value;
+}
+
+
+static __inline__ void vec_Pop(void)
+{
+ --vec_MAX;
+}
+
+static __inline__ POINTER vec_PopResult(void)
+{
+ return vec_VECTOR[--vec_MAX];
+}
+
+static __inline__ void vec_PopToN(int N)
+{
+ vec_VECTOR[N] = vec_VECTOR[--vec_MAX];
+}
+
+static __inline__ void vec_NPop(int N)
+{
+ vec_MAX -= N;
+}
+
+static __inline__ POINTER vec_Top(void)
+{
+ return vec_VECTOR[vec_MAX-1];
+}
+
+static __inline__ POINTER vec_NthTop(int N)
+{
+ return vec_VECTOR[vec_MAX-(1+N)];
+}
+
+
+static __inline__ void vec_RplacTop(POINTER Value)
+{
+ vec_VECTOR[vec_MAX-1] = Value;
+}
+
+static __inline__ void vec_RplacNthTop(int N, POINTER Value)
+{
+ vec_VECTOR[vec_MAX-(1+N)] = Value;
+}
+
+static __inline__ int vec_ActMax(void)
+{
+ return vec_MAX;
+}
+
+static __inline__ void vec_SetMax(int Index)
+{
+ vec_MAX = Index;
+}
+
+static __inline__ BOOL vec_IsMax(int Index)
+{
+ return vec_MAX == Index;
+}
+
+static __inline__ BOOL vec_IsEmpty(void)
+{
+ return vec_MAX == 0;
+}
+
+/**************************************************************/
+/* Prototypes */
+/**************************************************************/
+
+void vec_Swap(int, int);
+void vec_PrintSel(int, int, void(*)(POINTER));
+void vec_PrintAll(void(*)(POINTER));
+
+#endif