summaryrefslogtreecommitdiff
path: root/test/spass/foldfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/spass/foldfg.c')
-rw-r--r--test/spass/foldfg.c2444
1 files changed, 2444 insertions, 0 deletions
diff --git a/test/spass/foldfg.c b/test/spass/foldfg.c
new file mode 100644
index 0000000..549b92e
--- /dev/null
+++ b/test/spass/foldfg.c
@@ -0,0 +1,2444 @@
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * FIRST ORDER LOGIC SYMBOLS * */
+/* * * */
+/* * $Module: FOL DFG * */
+/* * * */
+/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
+/* * MPI fuer Informatik * */
+/* * * */
+/* * This program is free software; you can redistribute * */
+/* * it and/or modify it under the terms of the GNU * */
+/* * General Public License as published by the Free * */
+/* * Software Foundation; either version 2 of the License, * */
+/* * or (at your option) any later version. * */
+/* * * */
+/* * This program is distributed in the hope that it will * */
+/* * be useful, but WITHOUT ANY WARRANTY; without even * */
+/* * the implied warranty of MERCHANTABILITY or FITNESS * */
+/* * FOR A PARTICULAR PURPOSE. See the GNU General Public * */
+/* * License for more details. * */
+/* * * */
+/* * You should have received a copy of the GNU General * */
+/* * Public License along with this program; if not, write * */
+/* * to the Free Software Foundation, Inc., 59 Temple * */
+/* * Place, Suite 330, Boston, MA 02111-1307 USA * */
+/* * * */
+/* * * */
+/* $Revision: 21527 $ * */
+/* $State$ * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */
+/* $Author: duraid $ * */
+/* * * */
+/* * Contact: * */
+/* * Christoph Weidenbach * */
+/* * MPI fuer Informatik * */
+/* * Stuhlsatzenhausweg 85 * */
+/* * 66123 Saarbruecken * */
+/* * Email: weidenb@mpi-sb.mpg.de * */
+/* * Germany * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#include "foldfg.h"
+#include "flags.h"
+
+
+SYMBOL fol_ALL;
+SYMBOL fol_EXIST;
+SYMBOL fol_AND;
+SYMBOL fol_OR;
+SYMBOL fol_NOT;
+SYMBOL fol_IMPLIES;
+SYMBOL fol_IMPLIED;
+SYMBOL fol_EQUIV;
+SYMBOL fol_VARLIST;
+SYMBOL fol_EQUALITY;
+SYMBOL fol_TRUE;
+SYMBOL fol_FALSE;
+
+LIST fol_SYMBOLS;
+
+/**************************************************************/
+/* ********************************************************** */
+/* * * */
+/* * FUNCTIONS * */
+/* * * */
+/* ********************************************************** */
+/**************************************************************/
+
+void fol_Init(BOOL All, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A boolean value determining whether only 'equality' or
+ all fol symbols are created, and a precedence.
+ RETURNS: Nothing.
+ SUMMARY: Initializes the Fol Module.
+ EFFECTS: If <All> then all fol-symbols are created,
+ only 'equality' otherwise.
+ The precedence of the first order logic symbols is set
+ in <Precedence>.
+ CAUTION: MUST BE CALLED BEFORE ANY OTHER fol-FUNCTION.
+***************************************************************/
+{
+ if (All) {
+
+ fol_ALL = symbol_CreateJunctor("forall", 2, symbol_STATLEX, Precedence);
+ fol_EXIST = symbol_CreateJunctor("exists", 2, symbol_STATLEX, Precedence);
+ fol_AND = symbol_CreateJunctor("and", symbol_ArbitraryArity(),
+ symbol_STATLEX, Precedence);
+ fol_OR = symbol_CreateJunctor("or", symbol_ArbitraryArity(),
+ symbol_STATLEX, Precedence);
+ fol_NOT = symbol_CreateJunctor("not", 1, symbol_STATLEX, Precedence);
+ fol_IMPLIES = symbol_CreateJunctor("implies", 2, symbol_STATLEX, Precedence);
+ fol_IMPLIED = symbol_CreateJunctor("implied", 2, symbol_STATLEX, Precedence);
+ fol_EQUIV = symbol_CreateJunctor("equiv", 2, symbol_STATLEX, Precedence);
+ fol_VARLIST = symbol_CreateJunctor("", symbol_ArbitraryArity(),
+ symbol_STATLEX, Precedence);
+ fol_EQUALITY = symbol_CreatePredicate("equal", 2, symbol_STATLEX, Precedence);
+ fol_TRUE = symbol_CreatePredicate("true", 0, symbol_STATLEX, Precedence);
+ fol_FALSE = symbol_CreatePredicate("false", 0, symbol_STATLEX, Precedence);
+
+ fol_SYMBOLS =
+ list_Cons((POINTER)fol_ALL, list_Cons((POINTER)fol_EXIST,
+ list_Cons((POINTER)fol_AND, list_Cons((POINTER)fol_OR,
+ list_Cons((POINTER)fol_NOT,
+ list_Cons((POINTER)fol_IMPLIES, list_Cons((POINTER)fol_IMPLIED,
+ list_Cons((POINTER)fol_EQUIV, list_Cons((POINTER)fol_VARLIST,
+ list_Cons((POINTER)fol_EQUALITY, list_Cons((POINTER)fol_TRUE,
+ list_List((POINTER)fol_FALSE))))))))))));
+ }
+ else {
+ fol_EQUALITY = symbol_CreatePredicate("equal", 2, symbol_STATLEX, Precedence);
+ fol_NOT = symbol_CreateJunctor("not", 1, symbol_STATLEX, Precedence);
+ fol_SYMBOLS = list_Cons((POINTER)fol_NOT, list_List((POINTER)fol_EQUALITY));
+ }
+}
+
+
+SYMBOL fol_IsStringPredefined(const char* String)
+/**************************************************************
+ INPUT: A string.
+ RETURNS: The symbol iff String is a predefined fol string,
+ symbol NULL otherwise
+***************************************************************/
+{
+ LIST Scan;
+ for (Scan=fol_SYMBOLS; !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (string_Equal(String, symbol_Name((SYMBOL)list_Car(Scan))))
+ return (SYMBOL)list_Car(Scan);
+ return symbol_Null();
+}
+
+
+TERM fol_CreateQuantifier(SYMBOL Quantifier, LIST VarList, LIST Arguments)
+/**************************************************************
+ INPUT: A symbol (which MUST be a fol quantifier),
+ a list of variables that will be bound, and
+ a list of arguments.
+ RETURNS: A quantified term.
+***************************************************************/
+{
+#ifdef CHECK
+ if (!fol_IsQuantifier(Quantifier)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_CreateQuantifier: Symbol isn't FOL quantifier.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ return term_Create(Quantifier, list_Cons(term_Create(fol_Varlist(), VarList),
+ Arguments));
+}
+
+
+TERM fol_CreateQuantifierAddFather(SYMBOL Quantifier, LIST VarList, LIST Arguments)
+/**************************************************************
+ INPUT: A symbol (which MUST be a fol quantifier),
+ a list of variables that will be bound, and
+ a list of arguments.
+ In contrast to fol_CreateQuantifier the superterm members
+ are set for the arguments.
+ RETURNS: A quantified term.
+***************************************************************/
+{
+ return term_CreateAddFather(Quantifier,
+ list_Cons(term_CreateAddFather(fol_Varlist(),
+ VarList),
+ Arguments));
+}
+
+
+TERM fol_ComplementaryTerm(TERM Term)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: The (copied) complementary (in sign) formula of <Term>
+***************************************************************/
+{
+ if (symbol_Equal(term_TopSymbol(Term), fol_Not()))
+ return term_Copy((TERM)list_First(term_ArgumentList(Term)));
+ else
+ return term_Create(fol_Not(), list_List(term_Copy(Term)));
+}
+
+
+LIST fol_GetNonFOLPredicates(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: The list of all predicate symbols except the predefined
+ FOL symbols.
+***************************************************************/
+{
+ LIST Result;
+
+ Result = symbol_GetAllPredicates();
+ Result = list_DeleteElementIf(Result, (BOOL (*)(POINTER))fol_IsPredefinedPred);
+ return Result;
+}
+
+
+LIST fol_GetAssignments(TERM Term)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: All assignemnts that occur inside the formula, i.e.,
+ equations of the form "x=t" where "x" does not
+ occur in "t".
+***************************************************************/
+{
+ if (term_IsAtom(Term)) {
+ if (fol_IsAssignment(Term))
+ return list_List(Term);
+ }
+ else
+ if (term_IsComplex(Term)) {
+ LIST Scan,Result;
+ Result = list_Nil();
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ Result = list_Nconc(fol_GetAssignments(list_Car(Scan)),Result);
+ return Result;
+ }
+
+ return list_Nil();
+
+}
+
+static void fol_NormalizeVarsIntern(TERM Formula)
+/**************************************************************
+ INPUT: A sentence.
+ RETURNS: void.
+ EFFECT: The quantifier variables of the formula are
+ normalized, i.e., no two different quantifiers
+ bind the same variable.
+ CAUTION: Desctructive.
+***************************************************************/
+{
+ SYMBOL Top;
+ LIST Scan1;
+
+#ifdef CHECK
+ if (!term_IsTerm(Formula)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_NormalizeVarsIntern: Formula is corrupted.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Top = term_TopSymbol(Formula);
+
+ if (term_IsComplex(Formula)) {
+ if (fol_IsQuantifier(Top)) {
+ SYMBOL Var;
+ LIST OldVars,Scan2;
+ OldVars = list_Nil();
+ for (Scan1=fol_QuantifierVariables(Formula);!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+ Var = term_TopSymbol(list_Car(Scan1));
+ OldVars = list_Nconc(OldVars,list_List((POINTER)term_BindingValue(Var)));
+ term_CreateValueBinding(Var, term_OldMark(), (POINTER)symbol_CreateStandardVariable());
+ }
+ fol_NormalizeVarsIntern(term_SecondArgument(Formula));
+ for (Scan1=fol_QuantifierVariables(Formula),Scan2=OldVars;
+ !list_Empty(Scan1);
+ Scan1=list_Cdr(Scan1),Scan2=list_Cdr(Scan2)) {
+ Var = term_TopSymbol(list_Car(Scan1));
+ term_RplacTop(list_Car(Scan1),(SYMBOL)term_BindingValue(Var));
+ term_CreateValueBinding(Var, term_OldMark(), list_Car(Scan2));
+ }
+ list_Delete(OldVars);
+ }
+ else
+ for (Scan1=term_ArgumentList(Formula);!list_Empty(Scan1);Scan1=list_Cdr(Scan1))
+ fol_NormalizeVarsIntern(list_Car(Scan1));
+ }
+ else
+ if (symbol_IsVariable(Top))
+ term_RplacTop(Formula,(SYMBOL)term_BindingValue(Top));
+
+ return;
+}
+
+
+void fol_NormalizeVars(TERM Formula)
+/**************************************************************
+ INPUT: A sentence.
+ RETURNS: void.
+ EFFECT: The quantifier variables of the formula are
+ normalized, i.e., no two different quantifiers
+ bind the same variable.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ symbol_ResetStandardVarCounter();
+ term_NewMark();
+ fol_NormalizeVarsIntern(Formula);
+}
+
+
+void fol_NormalizeVarsStartingAt(TERM Formula, SYMBOL S)
+/**************************************************************
+ INPUT: A sentence.
+ RETURNS: void.
+ EFFECT: The quantifier variables of the formula are
+ normalized, i.e., no two different quantifiers
+ bind the same variable.
+ CAUTION: Destructive.
+***************************************************************/
+{
+ SYMBOL old = symbol_STANDARDVARCOUNTER;
+ symbol_SetStandardVarCounter(S);
+ term_NewMark();
+ fol_NormalizeVarsIntern(Formula);
+ symbol_SetStandardVarCounter(old);
+}
+
+
+void fol_RemoveImplied(TERM Formula)
+/*********************************************************
+ INPUT: A formula.
+ RETURNS: void.
+ EFFECT: All occurrences of "implied" are replaced by "implies"
+ CAUTION: Destructive.
+*******************************************************/
+{
+ if (!fol_IsLiteral(Formula)) {
+ if (fol_IsQuantifier(term_TopSymbol(Formula)))
+ fol_RemoveImplied(term_SecondArgument(Formula));
+ else {
+ LIST Scan;
+ if (symbol_Equal(term_TopSymbol(Formula),fol_Implied())) {
+ term_RplacTop(Formula,fol_Implies());
+ term_RplacArgumentList(Formula,list_NReverse(term_ArgumentList(Formula)));
+ }
+ for (Scan=term_ArgumentList(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ fol_RemoveImplied(list_Car(Scan));
+ }
+ }
+}
+
+
+BOOL fol_VarOccursFreely(TERM Var,TERM Term)
+/**************************************************************
+ INPUT: A variable and a term.
+ RETURNS: TRUE iff <Var> occurs freely in <Term>
+***************************************************************/
+{
+ LIST Scan;
+ int Stack;
+ SYMBOL Top;
+ BOOL Hit;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !term_IsVariable(Var)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_VarOccursFreely: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Stack = stack_Bottom();
+
+ do {
+ Top = term_TopSymbol(Term);
+ if (term_IsComplex(Term)) {
+ if (fol_IsQuantifier(Top)) {
+ Hit = TRUE;
+ for (Scan=fol_QuantifierVariables(Term);!list_Empty(Scan)&&Hit;Scan=list_Cdr(Scan))
+ if (symbol_Equal(term_TopSymbol(list_Car(Scan)),term_TopSymbol(Var)))
+ Hit = FALSE;
+ if (Hit)
+ stack_Push(list_Cdr(term_ArgumentList(Term)));
+ }
+ else
+ stack_Push(term_ArgumentList(Term));
+ }
+ else {
+ if (symbol_IsVariable(Top) && symbol_Equal(Top,term_TopSymbol(Var))) {
+ stack_SetBottom(Stack);
+ return TRUE;
+ }
+ }
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Term = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return FALSE;
+}
+
+
+LIST fol_FreeVariables(TERM Term)
+/**************************************************************
+ INPUT: A term where we assume that no variable is bound by more than
+ one quantifier in <Term> !!!!!
+ RETURNS: The list of variables occurring in the term. Variables are
+ not (!) copied.
+ Note that there may be many terms with same variable symbol.
+ All Variable terms are newly created.
+***************************************************************/
+{
+ LIST Variables,Scan;
+ int Stack;
+ SYMBOL Top;
+ NAT BoundMark,FreeMark;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || term_InBindingPhase()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_FreeVariables: Illegal input or context.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+
+ Variables = list_Nil();
+ Stack = stack_Bottom();
+ BoundMark = term_ActMark();
+ FreeMark = term_ActMark();
+
+ do {
+ Top = term_TopSymbol(Term);
+ if (term_IsComplex(Term)) {
+ if (fol_IsQuantifier(Top)) {
+ for (Scan=fol_QuantifierVariables(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (!term_VarIsMarked(term_TopSymbol(list_Car(Scan)), FreeMark))
+ term_CreateBinding(term_TopSymbol(list_Car(Scan)), BoundMark);
+ stack_Push(term_ArgumentList(Term)); /* Mark has to be removed ! */
+ stack_Push(list_Cdr(term_ArgumentList(Term)));
+ }
+ else
+ if (symbol_Equal(Top,fol_Varlist())) {
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (!term_VarIsMarked(term_TopSymbol(list_Car(Scan)), FreeMark))
+ term_CreateBinding(term_TopSymbol(list_Car(Scan)), 0); /* Mark has to be removed ! */
+ stack_RplacTop(list_Cdr(stack_Top())); /* Second Argument is Quantifier Arg */
+ }
+ else
+ stack_Push(term_ArgumentList(Term));
+ }
+ else {
+ if (symbol_IsVariable(Top) && !term_VarIsMarked(Top, FreeMark)
+ && !term_VarIsMarked(Top, BoundMark)) {
+ Variables = list_Cons(Term, Variables);
+ term_CreateBinding(Top, FreeMark);
+ }
+ }
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Term = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ term_StopBinding();
+
+ return Variables;
+}
+
+LIST fol_BoundVariables(TERM Term)
+/**************************************************************
+ INPUT: A term
+ RETURNS: The list of bound variables occurring in the term.
+***************************************************************/
+{
+ int stack;
+ LIST result;
+
+ stack = stack_Bottom();
+ result = list_Nil();
+
+ do {
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ result = list_Nconc(result, list_Copy(fol_QuantifierVariables(Term)));
+ stack_Push(list_Cdr(term_ArgumentList(Term)));
+ }
+ else
+ if (term_IsComplex(Term))
+ stack_Push(term_ArgumentList(Term));
+
+ while (!stack_Empty(stack) && list_Empty(stack_Top()))
+ stack_Pop();
+
+ if (!stack_Empty(stack)) {
+ Term = list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(stack));
+ result = term_DeleteDuplicatesFromList(result);
+ return result;
+}
+
+
+void fol_Free(void)
+/**************************************************************
+ INPUT: None.
+ RETURNS: void.
+ EFFECT: The memory used by the fol modul is freed.
+***************************************************************/
+{
+ list_Delete(fol_SYMBOLS);
+}
+
+
+BOOL fol_FormulaIsClause(TERM Formula)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: TRUE, if <Formula> is a clause, FALSE otherwise.
+***************************************************************/
+{
+ LIST LitList;
+
+ if (term_TopSymbol(Formula) == fol_ALL)
+ Formula = term_SecondArgument(Formula);
+
+ if (term_TopSymbol(Formula) != fol_OR)
+ return FALSE;
+
+ LitList = term_ArgumentList(Formula);
+
+ while (!list_Empty(LitList)) {
+ if (!fol_IsLiteral(list_Car(LitList)))
+ return FALSE;
+ LitList = list_Cdr(LitList);
+ }
+
+ return TRUE;
+}
+
+
+void fol_FPrintOtterOptions(FILE* File, BOOL Equality,
+ FLAG_TDFG2OTTEROPTIONSTYPE Options)
+/**************************************************************
+ INPUT: A file, a boolean flag and an Flag determining printed options.
+ RETURNS: Nothing.
+ SUMMARY: Prints Otter Options to <File>.
+ If <Equality> then appropriate paramodulation options
+ are possibly added.
+***************************************************************/
+{
+ switch (Options) {
+ case flag_TDFG2OTTEROPTIONSPROOFCHECK:
+ fputs("\nset(process_input).", File);
+ fputs("\nset(binary_res).", File);
+ fputs("\nset(factor).", File);
+ /*fputs("\nassign(pick_given_ratio, 4).", File);*/
+ fputs("\nclear(print_kept).", File);
+ fputs("\nassign(max_seconds, 20).", File);
+ if (Equality) {
+ fputs("\nclear(print_new_demod).", File);
+ fputs("\nclear(print_back_demod).", File);
+ fputs("\nclear(print_back_sub).", File);
+ /*fputs("\nset(knuth_bendix).", File);*/
+ fputs("\nset(para_from).", File);
+ fputs("\nset(para_into).", File);
+ fputs("\nset(para_from_vars).", File);
+ fputs("\nset(back_demod).", File);
+ } /* No break: add auto */
+ case flag_TDFG2OTTEROPTIONSAUTO:
+ fputs("\nset(auto).", File);
+ break;
+ case flag_TDFG2OTTEROPTIONSAUTO2:
+ fputs("\nset(auto2).", File);
+ break;
+ case flag_TDFG2OTTEROPTIONSOFF:
+ /* print nothing */
+ break;
+ default:
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_FPrintOtterOptions: Illegal parameter value %d.",
+ Options);
+ misc_FinishErrorReport();
+ }
+
+ fputs("\n\n",File);
+}
+
+static void fol_FPrintOtterFormula(FILE* File, TERM Formula)
+/**************************************************************
+ INPUT: A file and a formula.
+ RETURNS: Nothing.
+ SUMMARY: Prints the formula in Otter format to <File>.
+***************************************************************/
+{
+ SYMBOL Top;
+
+ Top = term_TopSymbol(Formula);
+
+ if (symbol_IsPredicate(Top)) {
+ if (symbol_Equal(Top, fol_Equality())) {
+ term_FPrintOtterPrefix(File,term_FirstArgument(Formula));
+ fputs(" = ", File);
+ term_FPrintOtterPrefix(File,term_SecondArgument(Formula));
+ }
+ else
+ term_FPrintOtterPrefix(File,Formula);
+ }
+ else {
+ if (fol_IsQuantifier(Top)) {
+ LIST Scan;
+ for (Scan=fol_QuantifierVariables(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ if (symbol_Equal(Top,fol_All()))
+ fputs("all ", File);
+ else
+ fputs("exists ", File);
+ term_FPrintOtterPrefix(File, list_Car(Scan));
+ fputs(" (", File);
+ }
+ fol_FPrintOtterFormula(File, term_SecondArgument(Formula));
+ for (Scan=fol_QuantifierVariables(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ fputs(")", File);
+ }
+ else
+ if (symbol_Equal(Top,fol_Not())) {
+ fputs("- (", File);
+ fol_FPrintOtterFormula(File, term_FirstArgument(Formula));
+ fputs(")", File);
+ }
+ else
+ if (symbol_Equal(Top, fol_And()) || symbol_Equal(Top, fol_Or()) ||
+ symbol_Equal(Top, fol_Equiv()) || symbol_Equal(Top, fol_Implies()) ) {
+ LIST Scan;
+ fputs("(", File);
+ for (Scan=term_ArgumentList(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ if (fol_IsLiteral(list_Car(Scan)))
+ fol_FPrintOtterFormula(File, list_Car(Scan));
+ else {
+ fputs("(", File);
+ fol_FPrintOtterFormula(File, list_Car(Scan));
+ fputs(")", File);
+ }
+ if (!list_Empty(list_Cdr(Scan))) {
+ if (symbol_Equal(Top, fol_And()))
+ fputs(" & ", File);
+ if (symbol_Equal(Top, fol_Or()))
+ fputs(" | ", File);
+ if (symbol_Equal(Top, fol_Equiv()))
+ fputs(" <-> ", File);
+ if (symbol_Equal(Top, fol_Implies()))
+ fputs(" -> ", File);
+ }
+ }
+ fputs(")", File);
+ }
+ }
+}
+
+void fol_FPrintOtter(FILE* File, LIST Formulae, FLAG_TDFG2OTTEROPTIONSTYPE Option)
+/**************************************************************
+ INPUT: A file, a list of pairs (label.formula) and an option flag.
+ RETURNS: Nothing.
+ SUMMARY: Prints a the respective formulae in Otter format to <File>.
+***************************************************************/
+{
+ LIST Scan;
+ BOOL Equality;
+ TERM Formula;
+
+ Equality = FALSE;
+
+ for (Scan=Formulae;!list_Empty(Scan) && !Equality; Scan=list_Cdr(Scan)) {
+ Formula = (TERM)list_PairSecond(list_Car(Scan));
+ Equality = term_ContainsSymbol(Formula, fol_Equality());
+ }
+
+ fol_FPrintOtterOptions(File, Equality, Option);
+
+ if (!list_Empty(Formulae)) {
+ fputs("formula_list(usable).\n", File);
+ if (Equality)
+ fputs("all x (x=x).\n", File);
+ for (Scan=Formulae;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ if (list_PairFirst(list_Car(Scan)) != NULL)
+ fprintf(File,"\n%% %s \n",(char *)list_PairFirst(list_Car(Scan)));
+ fol_FPrintOtterFormula(File,list_PairSecond(list_Car(Scan)));
+ fputs(".\n\n", File);
+ }
+ fputs("end_of_list.\n\n", File);
+ }
+}
+
+
+void fol_FPrintDFGSignature(FILE* File)
+/**************************************************************
+ INPUT: A file stream.
+ RETURNS: Nothing.
+ SUMMARY: Prints all signature symbols in DFG format to the
+ file stream.
+***************************************************************/
+
+{
+ NAT i;
+ SYMBOL symbol;
+ LIST functions, predicates;
+
+ functions = symbol_GetAllFunctions();
+ predicates = fol_GetNonFOLPredicates();
+
+ /* First print the function symbols */
+ if (!list_Empty(functions)) {
+ fputs(" functions[", File);
+ i = 0;
+ do {
+ symbol = (SYMBOL) list_Top(functions);
+ fprintf(File, "(%s, %d)", symbol_Name(symbol), symbol_Arity(symbol));
+ functions = list_Pop(functions);
+ if (!list_Empty(functions))
+ fputs(", ", File);
+ if (i < 15)
+ i++;
+ else {
+ i = 0;
+ fputs("\n\t", File);
+ }
+
+ } while (!list_Empty(functions));
+ fputs("].\n", File);
+ }
+
+ /* Now print the predicate symbols */
+ if (!list_Empty(predicates)) {
+ i = 0;
+ fputs(" predicates[", File);
+ do {
+ symbol = (SYMBOL) list_Top(predicates);
+ fprintf(File, "(%s, %d)", symbol_Name(symbol), symbol_Arity(symbol));
+ predicates = list_Pop(predicates);
+ if (!list_Empty(predicates))
+ fputs(", ", File);
+ if (i < 15)
+ i++;
+ else {
+ i = 0;
+ fputs("\n\t", File);
+ }
+ } while (!list_Empty(predicates));
+ fputs("].\n", File);
+ }
+ list_Delete(predicates);
+ list_Delete(functions);
+}
+
+
+static void fol_TermListFPrintDFG(FILE* File, LIST List)
+/**************************************************************
+ INPUT: A list of terms.
+ RETURNS: Nothing.
+***************************************************************/
+{
+ for (; !list_Empty(List); List=list_Cdr(List)) {
+ fol_FPrintDFG(File,list_Car(List));
+ if (!list_Empty(list_Cdr(List)))
+ putc(',', File);
+ }
+}
+
+
+void fol_FPrintDFG(FILE* File, TERM Term)
+/**************************************************************
+ INPUT: A file and a term.
+ RETURNS: none.
+ SUMMARY: Prints the term in prefix notation to the file.
+ CAUTION: Uses the other fol_Output functions.
+***************************************************************/
+{
+ if (term_IsComplex(Term)) {
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ symbol_FPrint(File,term_TopSymbol(Term));
+ fputs("([", File);
+ fol_TermListFPrintDFG(File,fol_QuantifierVariables(Term));
+ fputs("],", File);
+ fol_FPrintDFG(File, term_SecondArgument(Term));
+ putc(')', File);
+ }
+ else {
+ symbol_FPrint(File,term_TopSymbol(Term));
+ putc('(', File);
+ fol_TermListFPrintDFG(File,term_ArgumentList(Term));
+ putc(')', File);
+ }
+ }
+ else
+ symbol_FPrint(File,term_TopSymbol(Term));
+}
+
+void fol_PrintDFG(TERM Term)
+{
+ fol_FPrintDFG(stdout,Term);
+}
+
+
+void fol_PrintPrecedence(PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A precedence.
+ RETURNS: void
+ EFFECT: Prints the current precedence to stdout,
+ fol symbols are excluded.
+***************************************************************/
+{
+ if (symbol_SignatureExists()) {
+ LIST Symbols, Scan;
+ SYMBOL Symbol;
+ int Index;
+ SIGNATURE S;
+
+ Symbols = list_Nil();
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL) {
+ Symbol = S->info;
+ if ((symbol_IsPredicate(Symbol) || symbol_IsFunction(Symbol)) &&
+ !fol_IsPredefinedPred(Symbol))
+ Symbols = list_Cons((POINTER)Symbol, Symbols);
+ }
+ }
+ Symbols = symbol_SortByPrecedence(Symbols, Precedence);
+ for (Scan = Symbols; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ S = symbol_Signature(symbol_Index((SYMBOL)list_Car(Scan)));
+ fputs(S->name, stdout);
+ if (!list_Empty(list_Cdr(Scan)))
+ fputs(" > ", stdout);
+ }
+ list_Delete(Symbols);
+ }
+}
+
+void fol_FPrintPrecedence(FILE *File, PRECEDENCE Precedence)
+/**************************************************************
+ INPUT: A file to print to, and a precedence.
+ RETURNS: Nothing.
+ EFFECT: Prints the current precedence as a setting
+ command in DFG syntax to <File>.
+ fol symbols are excluded.
+***************************************************************/
+{
+ if (symbol_SignatureExists()) {
+ LIST Symbols, Scan;
+ SYMBOL Symbol;
+ int Index;
+ SIGNATURE S;
+
+ Symbols = list_Nil();
+ for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+ S = symbol_Signature(Index);
+ if (S != NULL) {
+ Symbol = S->info;
+ if ((symbol_IsPredicate(Symbol) || symbol_IsFunction(Symbol)) &&
+ !fol_IsPredefinedPred(Symbol))
+ Symbols = list_Cons((POINTER)Symbol, Symbols);
+ }
+ }
+ Symbols = symbol_SortByPrecedence(Symbols, Precedence);
+ Index = 0;
+ fputs("set_precedence(", File);
+ for (Scan = Symbols; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ S = symbol_Signature(symbol_Index((SYMBOL)list_Car(Scan)));
+ putc('(', File);
+ fputs(S->name, File);
+ putc(',', File);
+ fprintf(File, "%d", S->weight);
+ putc(',', File);
+ putc((symbol_HasProperty((SYMBOL)list_Car(Scan),ORDRIGHT) ? 'r' :
+ (symbol_HasProperty((SYMBOL)list_Car(Scan),ORDMUL) ? 'm' : 'l')),
+ File);
+ putc(')', File);
+ if (!list_Empty(list_Cdr(Scan)))
+ putc(',', File);
+
+ if (Index > 15) {
+ Index = 0;
+ fputs("\n\t", File);
+ }
+ else
+ Index++;
+ }
+ fputs(").", File);
+ list_Delete(Symbols);
+ }
+}
+
+
+static void fol_FPrintFormulaList(FILE* File, LIST Formulas, const char* Name)
+/**************************************************************
+ INPUT: A file, a list of formulas, a name.
+ EFFECTS: Print a list formulas in DFG format, with given list name.
+ **************************************************************/
+{
+ LIST scan;
+
+ fputs("list_of_formulae(", File);
+ fputs(Name, File);
+ fputs(").\n", File);
+ for (scan = Formulas; !list_Empty(scan); scan= list_Cdr(scan)) {
+ fputs("\tformula(", File);
+ fol_FPrintDFG(File, list_Car(scan));
+ fputs(").\n", File);
+ }
+ fputs("end_of_list.\n\n", File);
+}
+
+
+void fol_FPrintDFGProblem(FILE* File, const char* Name, const char* Author,
+ const char* Status, const char* Description,
+ LIST Axioms, LIST Conjectures)
+/**************************************************************
+ INPUT: A file, two lists of formulas, ??? EK
+ EFFECTS: Prints a complete DFG file containing these lists.
+**************************************************************/
+{
+ fputs("begin_problem(Unknown).\n\n", File);
+
+ fputs("list_of_descriptions.\n", File);
+ fprintf(File,"name(%s).\n",Name);
+ fprintf(File,"author(%s).\n",Author);
+ fprintf(File,"status(%s).\n",Status);
+ fprintf(File,"description(%s).\n",Description);
+ fputs("end_of_list.\n\n", File);
+
+ fputs("list_of_symbols.\n", File);
+ fol_FPrintDFGSignature(File);
+ fputs("end_of_list.\n\n", File);
+
+ fol_FPrintFormulaList(File, Axioms, "axioms");
+ fol_FPrintFormulaList(File, Conjectures, "conjectures");
+
+ fputs("end_problem.\n", File);
+}
+
+
+BOOL fol_AssocEquation(TERM Term, SYMBOL *Result)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: TRUE if the term is an equation defining associativity
+ for some function symbol.
+ EFFECT: If the <Term> is an assoc equation, then <*Result> is
+ assigned the assoc symbol.
+***************************************************************/
+{
+
+ if (fol_IsEquality(Term)) {
+ SYMBOL Top;
+ TERM Left,Right;
+ Left = term_FirstArgument(Term);
+ Right= term_SecondArgument(Term);
+ Top = term_TopSymbol(Left);
+ if (symbol_IsFunction(Top) && symbol_Arity(Top) == 2 &&
+ symbol_Equal(Top,term_TopSymbol(Right))) {
+ SYMBOL v1,v2,v3;
+ if (term_IsVariable(term_FirstArgument(Left)))
+ v1 = term_TopSymbol(term_FirstArgument(Left));
+ else
+ if (term_IsVariable(term_FirstArgument(Right))) {
+ Term = Right;
+ Right = Left;
+ Left = Term;
+ v1 = term_TopSymbol(term_FirstArgument(Left));
+ }
+ else
+ return FALSE;
+ if (symbol_Equal(term_TopSymbol(term_SecondArgument(Left)),Top) &&
+ symbol_IsVariable((v2=term_TopSymbol(term_FirstArgument(term_SecondArgument(Left)))))&&
+ symbol_IsVariable((v3=term_TopSymbol(term_SecondArgument(term_SecondArgument(Left)))))&&
+ symbol_Equal(term_TopSymbol(term_FirstArgument(Right)),Top) &&
+ symbol_Equal(v1,term_TopSymbol(term_FirstArgument(term_FirstArgument(Right)))) &&
+ symbol_Equal(v2,term_TopSymbol(term_SecondArgument(term_FirstArgument(Right)))) &&
+ symbol_Equal(v3,term_TopSymbol(term_SecondArgument(Right)))) {
+ *Result = Top;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+BOOL fol_DistributiveEquation(TERM Term, SYMBOL* Addition,
+ SYMBOL* Multiplication)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: TRUE if the term is an equation defining distributivity
+ for two function symbols, FALSE otherwise.
+ EFFECT: If the function returns TRUE, < Addition> and
+ <Multiplication> return the respective symbols.
+***************************************************************/
+{
+ TERM left, right, help, v1, v2, v3;
+
+ if (!fol_IsEquality(Term))
+ return FALSE;
+
+ left = term_FirstArgument(Term);
+ right = term_SecondArgument(Term);
+
+ if (term_EqualTopSymbols(left, right) ||
+ !symbol_IsFunction(term_TopSymbol(left)) ||
+ !symbol_IsFunction(term_TopSymbol(right)) ||
+ symbol_Arity(term_TopSymbol(left)) != 2 ||
+ symbol_Arity(term_TopSymbol(right)) != 2)
+ return FALSE;
+
+ if (term_IsVariable(term_FirstArgument(left)))
+ v1 = term_FirstArgument(left);
+ else if (term_IsVariable(term_FirstArgument(right))) {
+ help = right; /* Exchange left and right terms */
+ right = left;
+ left = help;
+ v1 = term_FirstArgument(left);
+ } else
+ return FALSE;
+
+ if (!term_EqualTopSymbols(left, term_FirstArgument(right)) ||
+ !term_EqualTopSymbols(left, term_SecondArgument(right)) ||
+ !term_EqualTopSymbols(term_SecondArgument(left), right))
+ return FALSE;
+
+ v2 = term_FirstArgument(term_SecondArgument(left));
+ v3 = term_SecondArgument(term_SecondArgument(left));
+
+ if (term_IsVariable(v2) && term_IsVariable(v3) &&
+ term_EqualTopSymbols(term_FirstArgument(term_FirstArgument(right)), v1) &&
+ term_EqualTopSymbols(term_SecondArgument(term_FirstArgument(right)), v2) &&
+ term_EqualTopSymbols(term_FirstArgument(term_SecondArgument(right)), v1) &&
+ term_EqualTopSymbols(term_SecondArgument(term_SecondArgument(right)), v3)) {
+ *Addition = term_TopSymbol(right);
+ *Multiplication = term_TopSymbol(left);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static LIST fol_InstancesIntern(TERM Formula, TERM ToMatch, NAT Symbols)
+/**************************************************************
+ INPUT: A formula in which all instances of <ToMatch> are searched.
+ The number of symbols of <ToMatch>.
+ RETURNS: The list of found instances.
+ CAUTION: Bound variables must be different, for otherwise the
+ used matching produces wrong results!!
+***************************************************************/
+{
+ NAT HitSymbols;
+ LIST Result;
+ int Stack;
+
+ Stack = stack_Bottom();
+ Result = list_Nil();
+
+ do {
+ HitSymbols = term_Size(Formula); /* First check number of symbols of current formula */
+
+ if (HitSymbols >= Symbols && (Formula != ToMatch)) {
+ cont_StartBinding();
+ if (unify_MatchFlexible(cont_LeftContext(), ToMatch, Formula))
+ Result = list_Cons(Formula, Result);
+ else
+ if (!symbol_IsPredicate(term_TopSymbol(Formula))) {
+ if (fol_IsQuantifier(term_TopSymbol(Formula)))
+ stack_Push(list_Cdr(term_ArgumentList(Formula)));
+ else
+ stack_Push(term_ArgumentList(Formula));
+ }
+ cont_BackTrack();
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Formula = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return Result;
+}
+
+
+LIST fol_Instances(TERM Formula, TERM ToMatch)
+/**************************************************************
+ INPUT: A formula in which all instances of <ToMatch> are searched.
+ RETURNS: The list of found occurrences matched by <ToMatch>.
+ The formula <ToMatch> is not included!
+***************************************************************/
+{
+ NAT Symbols;
+
+ Symbols = term_ComputeSize(ToMatch); /* We use the number of symbols as a filter */
+ term_InstallSize(Formula);
+
+ return fol_InstancesIntern(Formula, ToMatch, Symbols);
+}
+
+
+static LIST fol_GeneralizationsIntern(TERM Formula, TERM MatchedBy, NAT Symbols)
+/**************************************************************
+ INPUT: A formula in which all instances of <ToMatch> are searched.
+ The number of symbols of <ToMatch>.
+ RETURNS: The list of found instances.
+ CAUTION: Bound variables must be different, for otherwise the
+ used matching produces wrong results!!
+***************************************************************/
+{
+ NAT HitSymbols;
+ LIST Result;
+ int Stack;
+
+ Stack = stack_Bottom();
+ Result = list_Nil();
+
+ do {
+ if (Formula != MatchedBy) {
+ HitSymbols = term_Size(Formula); /* First check number of symbols of current formula */
+ if (HitSymbols <= Symbols) {
+ cont_StartBinding();
+ if (unify_MatchFlexible(cont_LeftContext(), Formula, MatchedBy))
+ Result = list_Cons(Formula, Result);
+ else
+ if (!symbol_IsPredicate(term_TopSymbol(Formula))) {
+ if (fol_IsQuantifier(term_TopSymbol(Formula)))
+ stack_Push(list_Cdr(term_ArgumentList(Formula)));
+ else
+ stack_Push(term_ArgumentList(Formula));
+ }
+ cont_BackTrack();
+ }
+ else
+ if (!symbol_IsPredicate(term_TopSymbol(Formula))) {
+ if (fol_IsQuantifier(term_TopSymbol(Formula)))
+ stack_Push(list_Cdr(term_ArgumentList(Formula)));
+ else
+ stack_Push(term_ArgumentList(Formula));
+ }
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+ stack_Pop();
+ if (!stack_Empty(Stack)) {
+ Formula = (TERM)list_Car(stack_Top());
+ stack_RplacTop(list_Cdr(stack_Top()));
+ }
+ } while (!stack_Empty(Stack));
+
+ return Result;
+}
+
+
+LIST fol_Generalizations(TERM Formula, TERM MatchedBy)
+/**************************************************************
+ INPUT: A formula in which all first-order generalizations of <MatchedBy> are searched.
+ RETURNS: The list of found occurrences that are more general than <MatchedBy>.
+ The formula <MatchedBy> is not included!
+***************************************************************/
+{
+ NAT Symbols;
+
+ Symbols = term_ComputeSize(MatchedBy); /* We use the number of symbols as a filter */
+ term_InstallSize(Formula);
+
+ return fol_GeneralizationsIntern(Formula, MatchedBy, Symbols);
+}
+
+
+TERM fol_MostGeneralFormula(LIST Formulas)
+/**************************************************************
+ INPUT: A list of formulas.
+ RETURNS: A most general formula out of the list, i.e., if
+ some formula is returned, there is no formula in the
+ list that is more general than that formula.
+***************************************************************/
+{
+ TERM Result, Candidate;
+ LIST Scan;
+
+#ifdef CHECK
+ if (list_Empty(Formulas)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_MostGeneralFormula: Called with empty list.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Result = list_Car(Formulas);
+
+ for (Scan=list_Cdr(Formulas);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+ Candidate = (TERM)list_Car(Scan);
+ cont_StartBinding();
+ if (unify_MatchFlexible(cont_LeftContext(), Candidate, Result))
+ Result = Candidate;
+ cont_BackTrack();
+ }
+
+ return Result;
+}
+
+
+void fol_ReplaceVariable(TERM Term, SYMBOL Symbol, TERM Repl)
+/**************************************************************
+ INPUT: A term, a variable symbol and a replacement term.
+ RETURNS: void
+ EFFECT: All free variables with <Symbol> in <Term> are replaced with copies of <Repl>
+ CAUTION: Destructive
+***************************************************************/
+{
+ LIST Scan;
+
+#ifdef CHECK
+ if (!(term_IsTerm(Term) && term_IsTerm(Repl) && symbol_IsVariable(Symbol))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_ReplaceVariable: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ for (Scan=term_ArgumentList(term_FirstArgument(Term)); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (symbol_Equal(term_TopSymbol(list_Car(Scan)), Symbol)) /* var is bound */
+ return;
+ fol_ReplaceVariable(term_SecondArgument(Term), Symbol, Repl);
+ }
+
+ if (symbol_Equal(term_TopSymbol(Term), Symbol)) {
+ term_RplacTop(Term,term_TopSymbol(Repl));
+ term_RplacArgumentList(Term,term_CopyTermList(term_ArgumentList(Repl)));
+ }
+ else
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ fol_ReplaceVariable(list_Car(Scan),Symbol,Repl);
+}
+
+
+static void fol_PrettyPrintInternDFG(TERM Term, int Depth)
+/**************************************************************
+ INPUT: A term and a depth parameter for indentation.
+ RETURNS: none.
+ SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+ int i;
+ LIST scan;
+ SYMBOL Top;
+
+ Top = term_TopSymbol(Term);
+ if (!symbol_Equal(Top,fol_Varlist())) {
+ for (i = 0; i < Depth; i++)
+ fputs(" ", stdout);
+ if (fol_IsLiteral(Term))
+ term_PrintPrefix(Term);
+ else {
+ if (symbol_IsJunctor(Top)) {
+ if (term_IsComplex(Term)) {
+ symbol_Print(Top);
+ putchar('(');
+ if (!fol_IsQuantifier(Top))
+ putchar('\n');
+ for (scan=term_ArgumentList(Term); !list_Empty(scan); scan= list_Cdr(scan)) {
+ fol_PrettyPrintInternDFG((TERM) list_Car(scan), Depth+1);
+ if (!list_Empty(list_Cdr(scan)))
+ fputs(",\n", stdout);
+ }
+ putchar(')');
+ }
+ else {
+ if (term_IsVariable(Term)) {
+ symbol_Print(Top);
+ }
+ else {
+ putchar('(');
+ symbol_Print(Top);
+ putchar(')');
+ }
+ }
+ }
+ else {
+ term_PrintPrefix(Term);
+ }
+ }
+ }
+ else {
+ putchar('[');
+ term_TermListPrintPrefix(term_ArgumentList(Term));
+ putchar(']');
+ }
+}
+
+
+void fol_PrettyPrintDFG(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: none.
+ SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+ fol_PrettyPrintInternDFG(Term, 0);
+}
+
+
+TERM fol_CheckFatherLinksIntern(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: A subterm whose superterm pointer is not set correctly,
+ else NULL.
+ SUMMARY: Checks if all superterm links except of those from quantifier
+ variables are set correctly.
+***************************************************************/
+{
+ LIST l;
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return fol_CheckFatherLinksIntern(term_SecondArgument(Term));
+ if (term_IsComplex(Term)) {
+ for (l=term_ArgumentList(Term); !list_Empty(l); l=list_Cdr(l)) {
+ TERM result;
+ if (term_Superterm((TERM) list_Car(l)) != Term)
+ return (TERM) list_Car(l);
+ result = fol_CheckFatherLinksIntern((TERM) list_Car(l));
+ if (result != NULL)
+ return result;
+ }
+ }
+ return NULL;
+}
+
+
+void fol_CheckFatherLinks(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: none.
+ SUMMARY: Checks if all superterm links except of those from
+ quantifier variables are set correctly.
+***************************************************************/
+{
+ TERM Result;
+
+ Result = fol_CheckFatherLinksIntern(Term);
+#ifdef CHECK
+ if (Result != NULL || term_Superterm(Term) != NULL) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_CheckFatherLinks:");
+ misc_ErrorReport(" Found a term where the father links");
+ misc_ErrorReport(" are not correctly set.");
+ misc_FinishErrorReport();
+ }
+#endif
+}
+
+
+static void fol_PrettyPrintIntern(TERM Term, int Depth)
+/**************************************************************
+ INPUT: A term and a depth parameter for indentation.
+ RETURNS: none.
+ SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+ int i;
+ LIST scan;
+
+ for (i = 0; i < Depth; i++)
+ fputs(" ", stdout);
+ if (symbol_IsJunctor(term_TopSymbol(Term))) {
+ if (term_IsComplex(Term)) {
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ symbol_Print(term_TopSymbol(Term));
+ fputs("([", stdout);
+ for (scan=fol_QuantifierVariables(Term); !list_Empty(scan); scan=list_Cdr(scan)) {
+ symbol_Print(term_TopSymbol((TERM) list_Car(scan)));
+ if (!list_Empty(list_Cdr(scan)))
+ putchar(',');
+ }
+ fputs("],\n", stdout);
+ fol_PrettyPrintIntern(term_SecondArgument(Term), Depth+1);
+ }
+ else {
+ symbol_Print(term_TopSymbol(Term));
+ fputs("(\n", stdout);
+ for (scan=term_ArgumentList(Term); !list_Empty(scan); scan= list_Cdr(scan)) {
+ fol_PrettyPrintIntern((TERM) list_Car(scan), Depth+1);
+ if (!list_Empty(list_Cdr(scan)))
+ fputs(",\n", stdout);
+ }
+ putchar(')');
+ }
+ }
+ else {
+ if (term_IsVariable(Term)) {
+ symbol_Print(term_TopSymbol(Term));
+ }
+ else {
+ putchar('(');
+ symbol_Print(term_TopSymbol(Term));
+ putchar(')');
+ }
+ }
+ }
+ else {
+ term_PrintPrefix(Term);
+ }
+}
+
+
+void fol_PrettyPrint(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: none.
+ SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+ fol_PrettyPrintIntern(Term, 0);
+}
+
+
+LIST fol_GetSubstEquations(TERM Term)
+/**************************************************************
+ INPUT: A Term.
+ RETURNS: The list of all equations of the form x=t or t=x in <Term>
+ where x is a variable and t is a term not containing x.
+***************************************************************/
+{
+ LIST Result;
+ LIST Scan;
+
+ Result = list_Nil();
+
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return fol_GetSubstEquations(term_SecondArgument(Term));
+ if (fol_IsEquality(Term)) {
+ if (term_IsVariable(term_SecondArgument(Term))) {
+ if (!term_ContainsSymbol(term_FirstArgument(Term), term_TopSymbol(term_SecondArgument(Term))))
+ Result = list_Cons(Term, Result);
+ }
+ else {
+ if (term_IsVariable(term_FirstArgument(Term)))
+ if (!term_ContainsSymbol(term_SecondArgument(Term), term_TopSymbol(term_FirstArgument(Term))))
+ Result = list_Cons(Term, Result);
+ }
+ }
+ if (symbol_IsPredicate(term_TopSymbol(Term)))
+ return Result;
+ else
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ Result = list_Nconc(Result, fol_GetSubstEquations(list_Car(Scan)));
+
+ return Result;
+}
+
+
+TERM fol_GetBindingQuantifier(TERM Term, SYMBOL Symbol)
+/**************************************************************
+ INPUT: A symbol and a term containing the symbol.
+ RETURNS: The Quantifier binding the symbol.
+***************************************************************/
+{
+ LIST Scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !symbol_IsSymbol(Symbol)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_GetBindingQuantifier: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ for ( Scan = fol_QuantifierVariables(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (symbol_Equal(Symbol, term_TopSymbol(list_Car(Scan)))) {
+ return Term;
+ }
+ }
+
+ return fol_GetBindingQuantifier(term_Superterm(Term), Symbol);
+}
+
+
+int fol_TermPolarity(TERM SubTerm, TERM Term)
+/**************************************************************
+ INPUT: Two terms, SubTerm subterm of Term.
+ It is assumed that the superterm links in <Term>
+ are established.
+ RETURNS: The polarity of SubTerm in Term.
+***************************************************************/
+{
+ TERM SuperTerm;
+
+#ifdef CHECK
+ if (!term_IsTerm(SubTerm) || !term_IsTerm(Term) || !term_FatherLinksEstablished(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_TermPolarity: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ if (SubTerm == Term)
+ return 1;
+
+ SuperTerm = term_Superterm(SubTerm);
+
+ if (SuperTerm) {
+ SYMBOL Top;
+ Top = term_TopSymbol(SuperTerm);
+
+ if (symbol_Equal(Top,fol_AND) || symbol_Equal(Top,fol_OR) || fol_IsQuantifier(Top))
+ return fol_TermPolarity(SuperTerm, Term);
+
+ if (symbol_Equal(Top,fol_NOT))
+ return (-fol_TermPolarity(SuperTerm, Term));
+
+ if (symbol_Equal(Top,fol_EQUIV))
+ return 0;
+
+ if (symbol_Equal(Top, fol_IMPLIES)) {
+ if (SubTerm == term_FirstArgument(SuperTerm))
+ return (-fol_TermPolarity(SuperTerm, Term));
+ else
+ return fol_TermPolarity(SuperTerm, Term);
+ }
+ if (symbol_Equal(Top, fol_IMPLIED)) {
+ if (SubTerm == term_SecondArgument(SuperTerm))
+ return (-fol_TermPolarity(SuperTerm, Term));
+ else
+ return fol_TermPolarity(SuperTerm, Term);
+ }
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_TermPolarity: Unknown first-order operator.\n");
+ misc_FinishErrorReport();
+ }
+
+ return 1;
+}
+
+
+static int fol_PolarCheckCount(TERM Nowterm, TERM SuperTerm, int Nowpolar)
+/**************************************************************
+ INPUT: Two terms, Nowterm and its superterm, and the polarity of
+ Nowterm.
+ RETURNS: The polarity of SuperTerm according to Nowterm.
+ COMMENT: Helpfunction for fol_PolarCheck.
+***************************************************************/
+{
+ SYMBOL Top;
+ Top = term_TopSymbol(SuperTerm);
+
+ if (Nowterm == SuperTerm)
+ return Nowpolar;
+
+ if (symbol_Equal(Top, fol_OR) || symbol_Equal(Top, fol_AND) || fol_IsQuantifier(Top) ||
+ (symbol_Equal(Top, fol_IMPLIES) && Nowterm == term_SecondArgument(SuperTerm)) ||
+ (symbol_Equal(Top, fol_IMPLIED) && Nowterm == term_FirstArgument(SuperTerm)))
+ return Nowpolar;
+
+ if (symbol_Equal(term_TopSymbol(SuperTerm), fol_EQUIV))
+ return 0;
+
+ return -Nowpolar;
+}
+
+
+static BOOL fol_PolarCheckAllquantor(TERM Subterm, TERM Term, int SubtermPolar)
+/**************************************************************
+ INPUT: Two terms, Subterm subterm of Term, and polarity of Subterm.
+ RETURNS: TRUE iff Subterm occurs in Term disjunctively.
+ COMMENT: Help function for fol_PolarCheck. Dual case to Exist quantor.
+***************************************************************/
+{
+ TERM SuperTerm;
+ SYMBOL Top;
+ int SubPolar;
+
+ if (Subterm == Term)
+ return TRUE;
+
+ SuperTerm = term_Superterm(Subterm);
+
+ if (SuperTerm == Term) /* Ugly, but it does not make sense to introduce a further function */
+ return TRUE;
+
+ Top = term_TopSymbol(SuperTerm);
+ SubPolar = fol_PolarCheckCount(Subterm, SuperTerm, SubtermPolar);
+
+ /* To be clarified: can the below condition generalized to universal quantifiers? */
+
+ if (symbol_Equal(Top,fol_NOT) ||
+ (symbol_Equal(Top, fol_OR) && SubPolar == 1) ||
+ (symbol_Equal(Top, fol_AND) && SubPolar == -1) ||
+ (symbol_Equal(Top,fol_IMPLIES) && SubPolar == 1) ||
+ (symbol_Equal(Top,fol_IMPLIED) && SubPolar == 1))
+ return fol_PolarCheckAllquantor(SuperTerm, Term, SubPolar);
+
+ return FALSE;
+}
+
+
+static BOOL fol_PolarCheckExquantor(TERM Subterm, TERM Term, int SubtermPolar)
+/**************************************************************
+ INPUT: Two terms, Subterm subterm of Term, and polarity of Subterm.
+ RETURNS: TRUE iff Subterm occurs in Term conjunctively.
+ COMMENT: Help function for fol_PolarCheck. Dual case to Allquantor.
+***************************************************************/
+{
+ TERM SuperTerm;
+ SYMBOL Top;
+ int SubPolar;
+
+ if (Subterm == Term)
+ return TRUE;
+
+ SuperTerm = term_Superterm(Subterm);
+
+ if (SuperTerm == Term) /* Ugly, but it does not make sense to introduce a further function */
+ return TRUE;
+
+ Top = term_TopSymbol(SuperTerm);
+ SubPolar = fol_PolarCheckCount(Subterm, SuperTerm, SubtermPolar);
+
+ /* To be clarified: can the below condition generalized to existential quantifiers? */
+
+ if (symbol_Equal(Top,fol_NOT) ||
+ (symbol_Equal(Top, fol_OR) && SubPolar == -1) ||
+ (symbol_Equal(Top, fol_AND) && SubPolar == 1) ||
+ (symbol_Equal(Top,fol_IMPLIES) && SubPolar == -1) ||
+ (symbol_Equal(Top,fol_IMPLIED) && SubPolar == -1))
+ return fol_PolarCheckExquantor(SuperTerm, Term, SubPolar);
+
+ return FALSE;
+}
+
+BOOL fol_PolarCheck(TERM Subterm, TERM Term)
+/**************************************************************
+ INPUT: Two terms, <Subterm> is of the form x=t, where x or t variable.
+ <Subterm> is a subterm of <Term> and the top symbol of
+ <Term> must be the binding quantifier of x or t.
+ RETURNS: BOOL if check is ok.
+***************************************************************/
+{
+ int SubtermPolar;
+ SYMBOL Top;
+
+ SubtermPolar = fol_TermPolarity(Subterm, Term);
+ Top = term_TopSymbol(Term);
+
+ if (SubtermPolar == -1 && symbol_Equal(Top, fol_ALL))
+ return fol_PolarCheckAllquantor(Subterm, Term, SubtermPolar);
+
+ if (SubtermPolar == 1 && symbol_Equal(Top, fol_EXIST))
+ return fol_PolarCheckExquantor(Subterm, Term, SubtermPolar);
+
+ return FALSE;
+}
+
+
+void fol_PopQuantifier(TERM Term)
+/**************************************************************
+ INPUT: A term whose top symbol is a quantifier.
+ RETURNS: Nothing.
+ EFFECT: Removes the quantifier.
+ If supertermlinks were set, they are updated.
+***************************************************************/
+{
+ TERM SubTerm;
+ LIST Scan;
+
+#ifdef CHECK
+ if (!fol_IsQuantifier(term_TopSymbol(Term))) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_PopQuantifier: Top symbol of term isn't a quantifier.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_Delete(term_FirstArgument(Term));
+ SubTerm = term_SecondArgument(Term);
+ list_Delete(term_ArgumentList(Term));
+ term_RplacTop(Term,term_TopSymbol(SubTerm));
+ term_RplacArgumentList(Term,term_ArgumentList(SubTerm));
+ for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (term_Superterm(list_Car(Scan)))
+ term_RplacSuperterm(list_Car(Scan),Term);
+ term_Free(SubTerm);
+}
+
+
+void fol_DeleteQuantifierVariable(TERM Quant,SYMBOL Var)
+/****************************************************************
+ INPUT: A term starting with a quantifier and a variable symbol.
+ RETURNS: Nothing.
+ EFFECT: The variable is deleted from the list of variables
+ bound by the quantor of <Quant>
+*****************************************************************/
+{
+ LIST Scan;
+
+ for (Scan=fol_QuantifierVariables(Quant);!list_Empty(Scan);Scan=list_Cdr(Scan))
+ if (symbol_Equal(term_TopSymbol(list_Car(Scan)), Var)) {
+ term_Delete((TERM)list_Car(Scan));
+ list_Rplaca(Scan, (POINTER)NULL);
+ }
+ term_RplacArgumentList(term_FirstArgument(Quant),
+ list_PointerDeleteElement(fol_QuantifierVariables(Quant),(POINTER)NULL));
+ if (list_Empty(fol_QuantifierVariables(Quant)))
+ fol_PopQuantifier(Quant);
+}
+
+
+
+void fol_SetTrue(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Nothing.
+ EFFECT: Replaces Term destructively by fol_True().
+***************************************************************/
+{
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term, list_Nil());
+ term_RplacTop(Term, fol_True());
+}
+
+void fol_SetFalse(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: Nothing.
+ EFFECT: Replaces Term destructively by fol_False().
+***************************************************************/
+{
+ term_DeleteTermList(term_ArgumentList(Term));
+ term_RplacArgumentList(Term, list_Nil());
+ term_RplacTop(Term, fol_False());
+}
+
+
+static void fol_ReplaceByArgCon(TERM Term)
+/**************************************************************
+ INPUT: A term of the form f(...)=f(...), where f is a function.
+ RETURNS: True.
+ EFFECT: Substitutes Term by <and(t1=s1, t2=s2, ..., tn=sn)>,
+ where ti and si are the arguments of both f's in Term.
+***************************************************************/
+{
+ LIST Scan, Bscan, List, Hlist;
+ TERM Func1, Func2, NewTerm;
+
+ Func1 = term_FirstArgument(Term);
+ Func2 = term_SecondArgument(Term);
+ List = term_ArgumentList(Term);
+ Scan = list_Nil();
+ term_RplacArgumentList(Term, list_Nil());
+ term_RplacTop(Term, fol_And());
+
+ for (Scan = term_ArgumentList(Func1),Bscan = term_ArgumentList(Func2);
+ !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ Hlist = list_Nil();
+ Hlist = list_Cons(list_Car(Bscan), Hlist);
+ Hlist = list_Cons(list_Car(Scan), Hlist);
+ NewTerm = term_Create(fol_Equality(), Hlist);
+ term_RplacArgumentList(Term, list_Cons(NewTerm, term_ArgumentList(Term)));
+ Bscan = list_Cdr(Bscan);
+ }
+
+ list_Delete(term_ArgumentList(Func1));
+ list_Delete(term_ArgumentList(Func2));
+ term_RplacArgumentList(Func1, list_Nil());
+ term_RplacArgumentList(Func2, list_Nil());
+ term_Delete(Func1);
+ term_Delete(Func2);
+ list_Delete(List);
+}
+
+
+BOOL fol_PropagateFreeness(TERM Term)
+/**************************************************************
+ INPUT: A term and a list of functions.
+ RETURNS: True iff a subterm of the form f(...)=f(...) occurs in the term,
+ where f has property FREELY and GENERATED.
+ EFFECT: Substitutes all occurences of f=f by <and(t1=s1,...tn=sn)>,where
+ ti and si are the arguments of each f in f=f.
+***************************************************************/
+{
+ BOOL Free;
+ LIST Scan;
+ TERM Argum1, Argum2;
+
+ Free = FALSE;
+
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return fol_PropagateFreeness(term_SecondArgument(Term));
+
+ if (!term_IsAtom(Term)) {
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (fol_PropagateFreeness(list_Car(Scan)))
+ Free = TRUE;
+ }
+ else
+ if (fol_IsEquality(Term)) {
+ Argum1 = term_FirstArgument(Term);
+ Argum2 = term_SecondArgument(Term);
+ if (symbol_Equal(term_TopSymbol(Argum1), term_TopSymbol(Argum2)) &&
+ symbol_HasProperty(term_TopSymbol(Argum1), FREELY) &&
+ symbol_HasProperty(term_TopSymbol(Argum1), GENERATED)) {
+ fol_ReplaceByArgCon(Term);
+ return TRUE;
+ }
+ }
+
+ return Free;
+}
+
+
+static BOOL fol_PropagateWitnessIntern(TERM Equation, SYMBOL Variable)
+/**************************************************************
+ INPUT: A Term which is an equation where <Variable> is one
+ of the equation's arguments that does not occur in the
+ other argument. Father links must exist.
+ RETURNS: True in case of witness propagation.
+ EFFECT: Checks whether subterm the equation is part of
+ is of the form described in fol_PropagateWitness and
+ substitutes in case of a hit.
+***************************************************************/
+{
+ TERM SuperTerm, BindQuantor, Predicat;
+ SYMBOL SuperTop;
+
+ SuperTerm = term_Superterm(Equation);
+
+ if (SuperTerm == term_Null())
+ return FALSE;
+
+ SuperTop = term_TopSymbol(SuperTerm);
+ BindQuantor = term_Superterm(SuperTerm);
+
+ if (BindQuantor == term_Null())
+ return FALSE;
+
+ if (!fol_IsQuantifier(term_TopSymbol(BindQuantor)) ||
+ list_Length(term_ArgumentList(SuperTerm)) != 2)
+ return FALSE;
+
+ if (Equation == term_SecondArgument(SuperTerm))
+ Predicat = term_FirstArgument(SuperTerm);
+ else
+ Predicat = term_SecondArgument(SuperTerm);
+
+ if (symbol_Equal(term_TopSymbol(BindQuantor), fol_All()) &&
+ symbol_Equal(SuperTop, fol_Or()) &&
+ symbol_Equal(term_TopSymbol(Predicat), fol_Not()) &&
+ symbol_HasProperty(term_TopSymbol(term_FirstArgument(Predicat)), FREELY) &&
+ symbol_HasProperty(term_TopSymbol(term_FirstArgument(Predicat)), GENERATED) &&
+ symbol_Equal(term_TopSymbol(term_FirstArgument(term_FirstArgument(Predicat))), Variable)) {
+ fol_SetFalse(BindQuantor);
+ return TRUE;
+ }
+ if (!symbol_HasProperty(term_TopSymbol(Predicat), FREELY) ||
+ !symbol_HasProperty(term_TopSymbol(Predicat), GENERATED) ||
+ !symbol_Equal(Variable, term_TopSymbol(term_FirstArgument(Predicat))))
+ return FALSE;
+
+ if (symbol_Equal(term_TopSymbol(BindQuantor), fol_All())) {
+ if (symbol_Equal(SuperTop, fol_Implies()) &&
+ term_SecondArgument(SuperTerm) == Equation) {
+ fol_SetFalse(BindQuantor);
+ return TRUE;
+ }
+ if (symbol_Equal(SuperTop, fol_Implied()) &&
+ term_FirstArgument(SuperTerm) == Equation) {
+ fol_SetFalse(BindQuantor);
+ return TRUE;
+ }
+ }
+ else /* Exquantor */
+ if (symbol_Equal(SuperTop, fol_And())) {
+ fol_SetTrue(BindQuantor);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+BOOL fol_PropagateWitness(TERM Term)
+/**************************************************************
+ INPUT: A Term.
+ RETURNS: True in case of witness propagation.
+ EFFECT: Substitutes any subterm of Term of the form
+ forall([x],implies(P(x),x=t))
+ forall([x],implied(x=t,P(x)))
+ forall([x],or(notP(x),x=t)) by FALSE and
+ exists([x],and(P(x),x=t)) by TRUE, where
+ P has property FREELY and GENERATED, x doesn't occur in t.
+***************************************************************/
+{
+ BOOL Hit;
+ LIST Scan;
+
+ Hit = FALSE;
+
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return fol_PropagateWitness(term_SecondArgument(Term));
+ if (fol_IsEquality(Term)) {
+ if (term_IsVariable(term_SecondArgument(Term))) {
+ if (!term_ContainsSymbol(term_FirstArgument(Term), term_TopSymbol(term_SecondArgument(Term))))
+ Hit = fol_PropagateWitnessIntern(Term,term_TopSymbol(term_SecondArgument(Term)));
+ }
+ else {
+ if (term_IsVariable(term_FirstArgument(Term)))
+ if (!term_ContainsSymbol(term_SecondArgument(Term), term_TopSymbol(term_FirstArgument(Term))))
+ Hit = fol_PropagateWitnessIntern(Term,term_TopSymbol(term_FirstArgument(Term)));
+ }
+ }
+ if (symbol_IsPredicate(term_TopSymbol(Term)))
+ return FALSE;
+
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (fol_PropagateWitness(list_Car(Scan)))
+ Hit = TRUE;
+
+ return Hit;
+}
+
+BOOL fol_PropagateTautologies(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: True iff function replaced a subterm.
+ EFFECT: Replaces all occurences of t=t, or(A,not(A)) by TRUE
+ and and(A,not(A)) by FALSE.
+***************************************************************/
+{
+ BOOL Hit;
+ LIST Scan, Bscan, ArgumentList;
+ SYMBOL Top;
+
+ Top = term_TopSymbol(Term);
+ Hit = FALSE;
+ ArgumentList = term_ArgumentList(Term);
+
+ if (fol_IsQuantifier(Top))
+ return fol_PropagateTautologies(term_SecondArgument(Term));
+
+ if (fol_IsEquality(Term)) {
+ if (term_Equal(term_FirstArgument(Term), term_SecondArgument(Term))) {
+ fol_SetTrue(Term);
+ return TRUE;
+ }
+ }
+
+ if (symbol_Equal(Top, fol_Or()) || symbol_Equal(Top, fol_And())) {
+ for (Scan = ArgumentList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (symbol_Equal(term_TopSymbol(list_Car(Scan)), fol_Not())) {
+ for (Bscan = ArgumentList; !list_Empty(Bscan); Bscan = list_Cdr(Bscan)) {
+ if (list_Car(Scan) != list_Car(Bscan) &&
+ fol_AlphaEqual(term_FirstArgument(list_Car(Scan)), list_Car(Bscan))) {
+ if (symbol_Equal(Top, fol_Or()))
+ fol_SetTrue(Term);
+ else
+ fol_SetFalse(Term);
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ if (!term_IsAtom(Term))
+ for (Scan = ArgumentList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (fol_PropagateTautologies(list_Car(Scan)))
+ Hit = TRUE;
+ }
+
+ return Hit;
+}
+
+
+static BOOL fol_AlphaEqualIntern(TERM Term1, TERM Term2, NAT Mark)
+/**************************************************************
+ INPUT: Two terms which represent formulae and a binding mark.
+ RETURNS: True iff Term2 is equal to Term1 with respect to the
+ renaming of bound variables.
+***************************************************************/
+{
+ LIST Scan, Bscan;
+ SYMBOL Top1, Top2;
+
+ Top1 = term_TopSymbol(Term1);
+ Top2 = term_TopSymbol(Term2);
+
+ if (symbol_IsVariable(Top1) && symbol_IsVariable(Top2)) {
+ if (term_VarIsMarked(Top2, Mark))
+ return symbol_Equal(Top1, (SYMBOL)term_BindingValue(Top2));
+ else
+ return symbol_Equal(Top1, Top2);
+ }
+
+ if (!symbol_Equal(Top1, Top2))
+ return FALSE;
+
+ if (fol_IsQuantifier(Top1)) {
+ if (list_Length(fol_QuantifierVariables(Term1)) != list_Length(fol_QuantifierVariables(Term2)))
+ return FALSE;
+ for (Scan = fol_QuantifierVariables(Term1), Bscan = fol_QuantifierVariables(Term2);
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan), Bscan = list_Cdr(Bscan))
+ term_CreateValueBinding(term_TopSymbol(list_Car(Bscan)), Mark,
+ (POINTER)term_TopSymbol(list_Car(Scan)));
+
+ if (!fol_AlphaEqualIntern(term_SecondArgument(Term1), term_SecondArgument(Term2), Mark))
+ return FALSE;
+ for (Scan = fol_QuantifierVariables(Term1), Bscan = fol_QuantifierVariables(Term2);
+ !list_Empty(Scan);
+ Scan = list_Cdr(Scan), Bscan = list_Cdr(Bscan))
+ term_SetBindingMark(term_TopSymbol(list_Car(Bscan)), term_NullMark());
+ }
+ else {
+ if (list_Length(term_ArgumentList(Term1)) != list_Length(term_ArgumentList(Term2)))
+ return FALSE;
+
+ for (Scan = term_ArgumentList(Term1), Bscan = term_ArgumentList(Term2);
+ !list_Empty(Scan); Scan = list_Cdr(Scan), Bscan = list_Cdr(Bscan))
+ if (!fol_AlphaEqualIntern(list_Car(Scan), list_Car(Bscan), Mark))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+BOOL fol_AlphaEqual(TERM Term1, TERM Term2)
+/**************************************************************
+ INPUT: Two terms of the form Qx(<rest>). All variables that occur in
+ Term1 and Term2 must be bound by only one quantifier!
+ RETURNS: TRUE iff Term2 is bound renaming of Term1.
+***************************************************************/
+{
+ BOOL Hit;
+
+#ifdef CHECK
+ if (Term1 == term_Null() || Term2 == term_Null()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_AlphaEqual: Corrupted term as parameter.\n");
+ misc_FinishErrorReport();
+ }
+ if (fol_VarBoundTwice(Term1) || fol_VarBoundTwice(Term2)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_AlphaEqual: Variables are bound more than once.\n");
+ misc_FinishErrorReport();
+ }
+ if (term_InBindingPhase()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_AlphaEqual: Term context is in binding phase.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+
+ Hit = fol_AlphaEqualIntern(Term1, Term2, term_ActMark());
+
+ term_StopBinding();
+
+ return Hit;
+}
+
+
+static BOOL fol_VarBoundTwiceIntern(TERM Term, NAT Mark)
+/**************************************************************
+ INPUT: A term, possibly a NULL Term and a valid binding mark.
+ RETURNS: TRUE iff a variable in <Term> is bound by more than one quantifier.
+***************************************************************/
+{
+ LIST Scan;
+
+ if (Term == term_Null())
+ return FALSE;
+
+ if (term_IsAtom(Term))
+ return FALSE;
+
+ if (!fol_IsQuantifier(term_TopSymbol(Term))) {
+ for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ if (fol_VarBoundTwiceIntern(list_Car(Scan), Mark))
+ return TRUE;
+ }
+ else {
+ for (Scan = fol_QuantifierVariables(Term); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+ if (!term_VarIsMarked(term_TopSymbol(list_Car(Scan)), Mark))
+ term_SetBindingMark(term_TopSymbol(list_Car(Scan)), Mark);
+ else
+ return TRUE;
+ }
+ if (fol_VarBoundTwiceIntern(term_SecondArgument(Term), Mark))
+ return TRUE;
+ for (Scan = fol_QuantifierVariables(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+ term_SetBindingMark(term_TopSymbol(list_Car(Scan)), term_NullMark());
+ }
+ return FALSE;
+}
+
+
+BOOL fol_VarBoundTwice(TERM Term)
+/**************************************************************
+ INPUT: A term.
+ RETURNS: TRUE iff a variable in term is bound by more than one quantifier.
+***************************************************************/
+{
+ BOOL Hit;
+
+#ifdef CHECK
+ if (term_InBindingPhase()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n\n Context in fol_VarBoundTwice: term in binding phase\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+
+ Hit = fol_VarBoundTwiceIntern(Term, (NAT)term_ActMark());
+
+ term_StopBinding();
+
+ return Hit;
+}
+
+
+NAT fol_Depth(TERM Term)
+/**************************************************************
+ INPUT: A formula.
+ RETURNS: The depth of the formula up to predicate level.
+***************************************************************/
+{
+ NAT Depth,Help;
+ LIST Scan;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_Depth: Illegal input.\n");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Depth = 0;
+
+ if (symbol_IsPredicate(term_TopSymbol(Term)))
+ return 1;
+
+ if (fol_IsQuantifier(term_TopSymbol(Term)))
+ return (fol_Depth(term_SecondArgument(Term)) + 1);
+
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ Help = fol_Depth(list_Car(Scan));
+ if (Help > Depth)
+ Depth = Help;
+ }
+
+ return (Depth+1);
+}
+
+
+static void fol_ApplyContextToTermIntern(CONTEXT Context, TERM Term)
+/********************************************************************
+ INPUT: A context (Context) and a term (Term).
+ RETURN: void.
+ EFFECT: Term is destructively changed modulo Context.
+*********************************************************************/
+{
+ LIST Scan;
+
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ fol_ApplyContextToTermIntern(Context, term_SecondArgument(Term));
+ }
+ else if (symbol_IsVariable(term_TopSymbol(Term))) {
+ if (cont_VarIsBound(Context, term_TopSymbol(Term)))
+ Term = cont_ApplyBindingsModuloMatching(Context, Term, TRUE);
+ }
+ else {
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ fol_ApplyContextToTermIntern(Context, list_Car(Scan));
+ }
+}
+
+
+static BOOL fol_CheckApplyContextToTerm(CONTEXT Context, TERM Term)
+/*************************************************************
+ INPUT: A Context and a term.
+ RETURN: TRUE iff Context can be applied to Term.
+ COMMENT: Intern funktion of fol_ApplyContextToTerm.
+**************************************************************/
+{
+ LIST Scan;
+ BOOL Apply;
+
+ Apply = TRUE;
+
+ if (fol_IsQuantifier(term_TopSymbol(Term))) {
+ for (Scan=fol_QuantifierVariables(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (cont_VarIsBound(Context, term_TopSymbol(list_Car(Scan))))
+ return FALSE;
+ for (Scan=term_ArgumentList(term_SecondArgument(Term)); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+ if (!fol_CheckApplyContextToTerm(Context, list_Car(Scan)))
+ Apply = FALSE;
+ }
+ }
+ else {
+ for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+ if (!fol_CheckApplyContextToTerm(Context, list_Car(Scan)))
+ Apply = FALSE;
+ }
+ return Apply;
+}
+
+
+BOOL fol_ApplyContextToTerm(CONTEXT Context, TERM Term)
+/***************************************************************
+ INPUT: A context (Context) and a term (Term).
+ RETURN: TRUE iff context could be applied on Term.
+ EFFECT: Term is destructively changed modulo Context iff possible.
+****************************************************************/
+{
+ if (fol_CheckApplyContextToTerm(Context, Term)) {
+ fol_ApplyContextToTermIntern(Context, Term);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+BOOL fol_SignatureMatchFormula(TERM Formula, TERM Instance, BOOL Variant)
+/********************************************************************
+ INPUT : Two formulas and a flag.
+ It is assumed that the symbol context is clean.
+ RETURN: TRUE iff <Formula> can be matched to <Instance> by matching
+ variables as well as signature symbols. If <Variant> is TRUE
+ variables must be matched to variables.
+ EFFECT: The symbol matches are stored in the symbol context.
+*********************************************************************/
+{
+ int Stack;
+ SYMBOL FormulaTop, InstanceTop;
+ NAT ActMark;
+ TERM ActFormula, ActInstance;
+
+#ifdef CHECK
+ if (!term_IsTerm(Formula) || term_InBindingPhase() ||
+ !term_IsTerm(Instance) || !symbol_ContextIsClean()) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_SignatureMatchFormula: Illegal input or context.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ term_StartBinding();
+
+ Stack = stack_Bottom();
+ term_NewMark();
+ ActMark = term_OldMark();
+ ActFormula = Formula;
+ ActInstance = Instance;
+
+ do {
+ FormulaTop = term_TopSymbol(ActFormula);
+ InstanceTop = term_TopSymbol(ActInstance);
+
+ if (!symbol_IsVariable(FormulaTop)) {
+ if (!symbol_ContextIsBound(FormulaTop)) {
+ if (!symbol_IsJunctor(FormulaTop) && !symbol_IsJunctor(InstanceTop) &&
+ !fol_IsPredefinedPred(FormulaTop) && !fol_IsPredefinedPred(InstanceTop))
+ symbol_ContextSetValue(FormulaTop, InstanceTop); /* Symbols are ALWAYS bound !*/
+ else {
+ if (!symbol_Equal(FormulaTop, InstanceTop)) {
+ term_StopBinding();
+ return FALSE;
+ }
+ }
+ }
+ else {
+ if (symbol_ContextIsBound(FormulaTop) &&
+ !symbol_Equal(symbol_ContextGetValue(FormulaTop),InstanceTop)) {
+ term_StopBinding();
+ return FALSE;
+ }
+ }
+ }
+
+ if (list_Length(term_ArgumentList(ActFormula)) != list_Length(term_ArgumentList(ActInstance))) {
+ term_StopBinding();
+ return FALSE;
+ }
+
+ if (term_IsComplex(ActFormula)) {
+ stack_Push(term_ArgumentList(ActInstance));
+ stack_Push(term_ArgumentList(ActFormula));
+ }
+ else {
+ if (symbol_IsVariable(FormulaTop)) {
+ if (!term_VarIsMarked(FormulaTop, ActMark)) {
+ if (!Variant || symbol_IsVariable(InstanceTop))
+ term_CreateValueBinding(FormulaTop, ActMark, (POINTER)InstanceTop);
+ else {
+ term_StopBinding();
+ return FALSE;
+ }
+ }
+ else {
+ if (!symbol_Equal((SYMBOL)term_BindingValue(FormulaTop), InstanceTop)) {
+ term_StopBinding();
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top())) {
+ stack_Pop();
+ stack_Pop();
+ }
+ if (!stack_Empty(Stack)) {
+ ActFormula = (TERM)list_Car(stack_Top());
+ ActInstance = (TERM)list_Car(stack_NthTop(1));
+ stack_RplacTop(list_Cdr(stack_Top()));
+ stack_RplacNthTop(1,list_Cdr(stack_NthTop(1)));
+ }
+ } while (!stack_Empty(Stack));
+
+ term_StopBinding();
+
+ return TRUE;
+}
+
+
+BOOL fol_SignatureMatch(TERM Term, TERM Instance, LIST* Bindings, BOOL Variant)
+/*****************************************************************
+ INPUT : Two formulas, a binding list and a boolean flag.
+ RETURN: TRUE iff <Term> can be matched to <Instance> by matching
+ variables as well as signature symbols. If <Variant> is TRUE
+ variables must be matched to variables. Signature symbol
+ matchings have to be injective.
+ EFFECT: The symbol matches are stored in the symbol context.
+******************************************************************/
+{
+ int Stack;
+ SYMBOL TermTop, InstanceTop;
+ NAT ActMark;
+ TERM ActTerm, ActInstance;
+
+#ifdef CHECK
+ if (!term_IsTerm(Term) || !term_IsTerm(Instance)) {
+ misc_StartErrorReport();
+ misc_ErrorReport("\n In fol_SignatureMatch: Illegal input.");
+ misc_FinishErrorReport();
+ }
+#endif
+
+ Stack = stack_Bottom();
+ ActMark = term_OldMark();
+ ActTerm = Term;
+ ActInstance = Instance;
+
+ do {
+ TermTop = term_TopSymbol(ActTerm);
+ InstanceTop = term_TopSymbol(ActInstance);
+
+ if (!symbol_IsVariable(TermTop)) {
+ if (!symbol_ContextIsBound(TermTop)) {
+ if (!symbol_IsJunctor(TermTop) && !symbol_IsJunctor(InstanceTop) &&
+ !fol_IsPredefinedPred(TermTop) && !fol_IsPredefinedPred(InstanceTop) &&
+ !symbol_ContextIsMapped(InstanceTop)) {
+ symbol_ContextSetValue(TermTop, InstanceTop); /* Symbols are ALWAYS bound !*/
+ *Bindings = list_Cons((POINTER)TermTop,*Bindings);
+ }
+ else {
+ if (!symbol_Equal(TermTop, InstanceTop)) {
+ return FALSE;
+ }
+ }
+ }
+ else {
+ if (symbol_ContextIsBound(TermTop) &&
+ !symbol_Equal(symbol_ContextGetValue(TermTop),InstanceTop)) {
+ return FALSE;
+ }
+ }
+ }
+
+ if (list_Length(term_ArgumentList(ActTerm)) != list_Length(term_ArgumentList(ActInstance))) {
+ return FALSE;
+ }
+
+ if (term_IsComplex(ActTerm)) {
+ stack_Push(term_ArgumentList(ActInstance));
+ stack_Push(term_ArgumentList(ActTerm));
+ }
+ else {
+ if (symbol_IsVariable(TermTop)) {
+ if (!term_VarIsMarked(TermTop, ActMark)) {
+ if (!Variant || symbol_IsVariable(InstanceTop)) {
+ term_CreateValueBinding(TermTop, ActMark, (POINTER)InstanceTop);
+ *Bindings = list_Cons((POINTER)TermTop,*Bindings);
+ }
+ else
+ return FALSE;
+ }
+ else {
+ if (!symbol_Equal((SYMBOL)term_BindingValue(TermTop), InstanceTop)) {
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ while (!stack_Empty(Stack) && list_Empty(stack_Top())) {
+ stack_Pop();
+ stack_Pop();
+ }
+ if (!stack_Empty(Stack)) {
+ ActTerm = (TERM)list_Car(stack_Top());
+ ActInstance = (TERM)list_Car(stack_NthTop(1));
+ stack_RplacTop(list_Cdr(stack_Top()));
+ stack_RplacNthTop(1,list_Cdr(stack_NthTop(1)));
+ }
+ } while (!stack_Empty(Stack));
+
+ return TRUE;
+}
+
+
+BOOL fol_CheckFormula(TERM Formula)
+/*******************************************************************
+ INPUT : A term Formula.
+ RETURN: TRUE iff no free variables occure in Formula
+ and father links are properly set
+ and argument list lengths match arities
+********************************************************************/
+{
+ LIST FreeVars;
+
+ FreeVars = fol_FreeVariables(Formula);
+
+ if (!list_Empty(FreeVars)) {
+ list_Delete(FreeVars);
+ return FALSE;
+ }
+
+ return term_CheckTerm(Formula);
+}