From 6c196ec8a41d6ed506c133c8b33dba9684f9a7a6 Mon Sep 17 00:00:00 2001 From: xleroy Date: Wed, 3 Mar 2010 12:34:43 +0000 Subject: Updated raytracer test. Added SPASS test. git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1271 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- test/spass/.depend | 130 ++ test/spass/AUTHORS | 23 + test/spass/COPYING | 340 +++ test/spass/LICENSE.TXT | 1 + test/spass/Makefile | 34 + test/spass/Makefile.bak | 13 + test/spass/README | 96 + test/spass/VERSIONHISTORY | 135 ++ test/spass/analyze.c | 774 +++++++ test/spass/analyze.h | 121 + test/spass/approx.h | 61 + test/spass/clause.c | 5008 ++++++++++++++++++++++++++++++++++++++++ test/spass/clause.h | 1589 +++++++++++++ test/spass/clock.c | 215 ++ test/spass/clock.h | 78 + test/spass/closure.c | 441 ++++ test/spass/closure.h | 67 + test/spass/cnf.c | 4787 ++++++++++++++++++++++++++++++++++++++ test/spass/cnf.h | 120 + test/spass/component.c | 266 +++ test/spass/component.h | 151 ++ test/spass/condensing.c | 100 + test/spass/condensing.h | 64 + test/spass/context.c | 636 ++++++ test/spass/context.h | 1049 +++++++++ test/spass/defs.c | 1359 +++++++++++ test/spass/defs.h | 205 ++ test/spass/dfg.h | 86 + test/spass/dfgparser.c | 3728 ++++++++++++++++++++++++++++++ test/spass/dfgparser.h | 184 ++ test/spass/dfgscanner.c | 5174 ++++++++++++++++++++++++++++++++++++++++++ test/spass/doc-proof.c | 247 ++ test/spass/doc-proof.h | 91 + test/spass/flags.c | 810 +++++++ test/spass/flags.h | 1117 +++++++++ test/spass/foldfg.c | 2444 ++++++++++++++++++++ test/spass/foldfg.h | 303 +++ test/spass/graph.c | 318 +++ test/spass/graph.h | 148 ++ test/spass/hash.c | 115 + test/spass/hash.h | 107 + test/spass/hasharray.c | 138 ++ test/spass/hasharray.h | 246 ++ test/spass/ia.h | 58 + test/spass/iaparser.c | 1773 +++++++++++++++ test/spass/iaparser.h | 87 + test/spass/iascanner.c | 1991 ++++++++++++++++ test/spass/kbo.c | 593 +++++ test/spass/kbo.h | 67 + test/spass/list.c | 1660 ++++++++++++++ test/spass/list.h | 433 ++++ test/spass/memory.c | 1595 +++++++++++++ test/spass/memory.h | 478 ++++ test/spass/misc.c | 147 ++ test/spass/misc.h | 161 ++ test/spass/options.c | 1889 +++++++++++++++ test/spass/options.h | 127 ++ test/spass/order.c | 516 +++++ test/spass/order.h | 147 ++ test/spass/partition.c | 287 +++ test/spass/partition.h | 127 ++ test/spass/problem.dfg | 718 ++++++ test/spass/proofcheck.c | 1391 ++++++++++++ test/spass/proofcheck.h | 82 + test/spass/ras.h | 298 +++ test/spass/renaming.c | 1508 ++++++++++++ test/spass/renaming.h | 168 ++ test/spass/resolution.c | 178 ++ test/spass/resolution.h | 73 + test/spass/rpos.c | 521 +++++ test/spass/rpos.h | 82 + test/spass/rules-inf.c | 4281 ++++++++++++++++++++++++++++++++++ test/spass/rules-inf.h | 165 ++ test/spass/rules-red.c | 4508 ++++++++++++++++++++++++++++++++++++ test/spass/rules-red.h | 111 + test/spass/rules-sort.c | 1763 ++++++++++++++ test/spass/rules-sort.h | 79 + test/spass/rules-split.c | 460 ++++ test/spass/rules-split.h | 70 + test/spass/rules-ur.c | 385 ++++ test/spass/rules-ur.h | 55 + test/spass/search.c | 1271 +++++++++++ test/spass/search.h | 522 +++++ test/spass/sharing.c | 1143 ++++++++++ test/spass/sharing.h | 245 ++ test/spass/small_problem.dfg | 154 ++ test/spass/sort.c | 1974 ++++++++++++++++ test/spass/sort.h | 598 +++++ test/spass/st.c | 1691 ++++++++++++++ test/spass/st.h | 305 +++ test/spass/stack.c | 55 + test/spass/stack.h | 155 ++ test/spass/strings.c | 325 +++ test/spass/stringsx.h | 88 + test/spass/subst.c | 647 ++++++ test/spass/subst.h | 219 ++ test/spass/subsumption.c | 2041 +++++++++++++++++ test/spass/subsumption.h | 87 + test/spass/symbol.c | 1020 +++++++++ test/spass/symbol.h | 786 +++++++ test/spass/table.c | 553 +++++ test/spass/table.h | 101 + test/spass/tableau.c | 880 +++++++ test/spass/tableau.h | 292 +++ test/spass/term.c | 2551 +++++++++++++++++++++ test/spass/term.h | 612 +++++ test/spass/terminator.c | 319 +++ test/spass/terminator.h | 58 + test/spass/top.c | 1648 ++++++++++++++ test/spass/unify.c | 857 +++++++ test/spass/unify.h | 119 + test/spass/vector.c | 120 + test/spass/vector.h | 188 ++ 113 files changed, 83775 insertions(+) create mode 100644 test/spass/.depend create mode 100644 test/spass/AUTHORS create mode 100644 test/spass/COPYING create mode 100644 test/spass/LICENSE.TXT create mode 100644 test/spass/Makefile create mode 100644 test/spass/Makefile.bak create mode 100644 test/spass/README create mode 100644 test/spass/VERSIONHISTORY create mode 100644 test/spass/analyze.c create mode 100644 test/spass/analyze.h create mode 100644 test/spass/approx.h create mode 100644 test/spass/clause.c create mode 100644 test/spass/clause.h create mode 100644 test/spass/clock.c create mode 100644 test/spass/clock.h create mode 100644 test/spass/closure.c create mode 100644 test/spass/closure.h create mode 100644 test/spass/cnf.c create mode 100644 test/spass/cnf.h create mode 100644 test/spass/component.c create mode 100644 test/spass/component.h create mode 100644 test/spass/condensing.c create mode 100644 test/spass/condensing.h create mode 100644 test/spass/context.c create mode 100644 test/spass/context.h create mode 100644 test/spass/defs.c create mode 100644 test/spass/defs.h create mode 100644 test/spass/dfg.h create mode 100644 test/spass/dfgparser.c create mode 100644 test/spass/dfgparser.h create mode 100644 test/spass/dfgscanner.c create mode 100644 test/spass/doc-proof.c create mode 100644 test/spass/doc-proof.h create mode 100644 test/spass/flags.c create mode 100644 test/spass/flags.h create mode 100644 test/spass/foldfg.c create mode 100644 test/spass/foldfg.h create mode 100644 test/spass/graph.c create mode 100644 test/spass/graph.h create mode 100644 test/spass/hash.c create mode 100644 test/spass/hash.h create mode 100644 test/spass/hasharray.c create mode 100644 test/spass/hasharray.h create mode 100644 test/spass/ia.h create mode 100644 test/spass/iaparser.c create mode 100644 test/spass/iaparser.h create mode 100644 test/spass/iascanner.c create mode 100644 test/spass/kbo.c create mode 100644 test/spass/kbo.h create mode 100644 test/spass/list.c create mode 100644 test/spass/list.h create mode 100644 test/spass/memory.c create mode 100644 test/spass/memory.h create mode 100644 test/spass/misc.c create mode 100644 test/spass/misc.h create mode 100644 test/spass/options.c create mode 100644 test/spass/options.h create mode 100644 test/spass/order.c create mode 100644 test/spass/order.h create mode 100644 test/spass/partition.c create mode 100644 test/spass/partition.h create mode 100644 test/spass/problem.dfg create mode 100644 test/spass/proofcheck.c create mode 100644 test/spass/proofcheck.h create mode 100644 test/spass/ras.h create mode 100644 test/spass/renaming.c create mode 100644 test/spass/renaming.h create mode 100644 test/spass/resolution.c create mode 100644 test/spass/resolution.h create mode 100644 test/spass/rpos.c create mode 100644 test/spass/rpos.h create mode 100644 test/spass/rules-inf.c create mode 100644 test/spass/rules-inf.h create mode 100644 test/spass/rules-red.c create mode 100644 test/spass/rules-red.h create mode 100644 test/spass/rules-sort.c create mode 100644 test/spass/rules-sort.h create mode 100644 test/spass/rules-split.c create mode 100644 test/spass/rules-split.h create mode 100644 test/spass/rules-ur.c create mode 100644 test/spass/rules-ur.h create mode 100644 test/spass/search.c create mode 100644 test/spass/search.h create mode 100644 test/spass/sharing.c create mode 100644 test/spass/sharing.h create mode 100644 test/spass/small_problem.dfg create mode 100644 test/spass/sort.c create mode 100644 test/spass/sort.h create mode 100644 test/spass/st.c create mode 100644 test/spass/st.h create mode 100644 test/spass/stack.c create mode 100644 test/spass/stack.h create mode 100644 test/spass/strings.c create mode 100644 test/spass/stringsx.h create mode 100644 test/spass/subst.c create mode 100644 test/spass/subst.h create mode 100644 test/spass/subsumption.c create mode 100644 test/spass/subsumption.h create mode 100644 test/spass/symbol.c create mode 100644 test/spass/symbol.h create mode 100644 test/spass/table.c create mode 100644 test/spass/table.h create mode 100644 test/spass/tableau.c create mode 100644 test/spass/tableau.h create mode 100644 test/spass/term.c create mode 100644 test/spass/term.h create mode 100644 test/spass/terminator.c create mode 100644 test/spass/terminator.h create mode 100644 test/spass/top.c create mode 100644 test/spass/unify.c create mode 100644 test/spass/unify.h create mode 100644 test/spass/vector.c create mode 100644 test/spass/vector.h (limited to 'test/spass') 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 +Uwe Brahm +Thomas Hillenbrand +Dalibor Topic + + +Former: +======= + +Bijan Afshordel +Christof Brinker +Christian Cohrs +Thorsten Engel +Bernd Gaede +Peter Graf +Georg Jung +Christoph Meyer +Georg Rock +Christian Theobalt + 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. + + + Copyright (C) 19yy + + 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. + + , 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 + +#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. + 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 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 < belongs to component */ + 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 */ + 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. */ + /* 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 belongs to component */ + 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 with index i and + in the interval [Start:End] are prepended to . + 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 . + 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 . +***************************************************************/ +{ + 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 . +***************************************************************/ +{ + 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 . +***************************************************************/ +{ + 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 . +***************************************************************/ +{ + 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 in +**********************************************************/ +{ + 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 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 . +***************************************************************/ +{ + 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 . +***************************************************************/ +{ + 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 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 in + are replaced by copies if . + 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 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 of size +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 + 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 . + 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 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 . + 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 . + 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 with + indices between (and including) and + with literals from the + 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) + and 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 . 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 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 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 from and inserts it into + . +***************************************************************/ +{ + 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 '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 is deleted from . + 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 is deleted from . + 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 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 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 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();isplitfield_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 . +***************************************************************/ +{ + 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 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 dependent + on . +***************************************************************/ +{ + 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 . +***************************************************************/ +{ + 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 . +***************************************************************/ +{ + 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 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 is true then all axiom clauses in are + written to . Otherwise all conjecture clauses in + are written to . +***************************************************************/ +{ + 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 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 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 + is TRUE, the parents of 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 . +***************************************************************/ +{ + 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 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 and 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 . 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 to */ +{ + 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 is initialized. + RETURNS: None. + MEMORY: None. +**********************************************************/ +{ + clock_Akku[ClockCounter] = 0; +} + + +void clock_StartCounter(CLOCK_CLOCKS ClockCounter) +/********************************************************* + INPUT: A clock counter. + EFFECT: The clock counter 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 +#include + +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; + } + } + /* 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 and that is assumed to be associative. + RETURNS: If the top symbol of is the is flattened + as long as it contains further direct subterms starting with + 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 and that is assumed to be associative, + and a predicate term which is a subterm of term + RETURNS: If the top symbol of is the is flattened + as long as it contains further direct subterms starting with + 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 . +***************************************************************/ +{ + 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 . +***************************************************************/ +{ + /* 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 . +***************************************************************/ +{ + 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 of , a subterm of , + a list of existence quantified variables , + a list of free variables and a precedence. + is of the form + exists[...](t1 and t2 and ... and Proved and ..) + RETURNS: A new term, where is removed from the arguments + of . + EFFECT: The precedence of new Skolem functions is set in +*******************************************************************/ +{ + 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 . +*********************************************************/ +{ + 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 and further improvements. + 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 , a list of variables, a list + of variable symbols and a precedence. + RETURNS: The list of new Skolem functions. + EFFECT: The term is destructively changed. All variable symbols + in which appear in are replaced by skolem functions + with respect to which contains the universally quantified + variables. + New Skolem functions are created and their precedence is set + in . +***************************************************************/ +{ + 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 . +***************************************************************/ +{ + 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 */ + 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 . +***************************************************************/ +{ + 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, must be a subterm of . + Superterm of 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 . + All free variables in are bound by a universal quantifier + (with polarity 1). + RETURN: The destructively changed . + EFFECT: Removes all quantifiers not binding a variable in + from 's path. + Moves all universal quantifiers binding free variable + in up. + is transformed into the form + forall([X1,...,Xn],or (equiv(,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 . +**************************************************************/ +{ + 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; + } + } + + /* 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 + +/**************************************************************/ +/* 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: is destructively changed with respect to + established bindings in the context. + If is true, all variables in + 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: 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 with respect to + the bindings in +********************************************************/ +{ + 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 with respect to + the bindings in +********************************************************/ +{ + 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 occurs in with respect to + the bindings in , 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, and which must be subformula + of ,an int which is the polarity of in its + superterm and a list of 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 */ + /* 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 and a list of pairs (Label.Formula), + the maximal number of expansions, a flag store and a + precedence. + RETURNS: The possibly destructively changed list . + 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 +#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 +#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 /* 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 /* 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 /* 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