/**************************************************************/ /* ********************************************************** */ /* * * */ /* * INFERENCE RULES * */ /* * * */ /* * $Module: INFRULES * */ /* * * */ /* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */ /* * MPI fuer Informatik * */ /* * * */ /* * This program is free software; you can redistribute * */ /* * it and/or modify it under the terms of the GNU * */ /* * General Public License as published by the Free * */ /* * Software Foundation; either version 2 of the License, * */ /* * or (at your option) any later version. * */ /* * * */ /* * This program is distributed in the hope that it will * */ /* * be useful, but WITHOUT ANY WARRANTY; without even * */ /* * the implied warranty of MERCHANTABILITY or FITNESS * */ /* * FOR A PARTICULAR PURPOSE. See the GNU General Public * */ /* * License for more details. * */ /* * * */ /* * You should have received a copy of the GNU General * */ /* * Public License along with this program; if not, write * */ /* * to the Free Software Foundation, Inc., 59 Temple * */ /* * Place, Suite 330, Boston, MA 02111-1307 USA * */ /* * * */ /* * * */ /* $Revision: 21527 $ * */ /* $State$ * */ /* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */ /* $Author: duraid $ * */ /* * * */ /* * Contact: * */ /* * Christoph Weidenbach * */ /* * MPI fuer Informatik * */ /* * Stuhlsatzenhausweg 85 * */ /* * 66123 Saarbruecken * */ /* * Email: weidenb@mpi-sb.mpg.de * */ /* * Germany * */ /* * * */ /* ********************************************************** */ /**************************************************************/ /* $RCSfile$ */ /**************************************************************/ /* Includes */ /**************************************************************/ #include "rules-inf.h" /**************************************************************/ /* Some auxiliary functions for testing postconditions */ /**************************************************************/ static BOOL inf_LitMax(CLAUSE Clause, int i, int j, SUBST Subst, BOOL Strict, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause, the index of a maximal literal, another literal index, a substitution, a boolean flag, a flag store and a precedence. RETURNS: If =FALSE the function returns TRUE iff the literal at index is still maximal in the instantiated clause. If =TRUE the function returns TRUE iff the literal is STRICTLY maximal in the instantiated clause. The literal at index j is omitted at literal comparison. However, setting j to a negative number ensures that all literals are compared with the literal at index . CAUTION: DON'T call this function with a clause with selected literals! ***************************************************************/ { TERM Max, LitTerm; LITERAL Lit; ord_RESULT Compare; int k, l; #ifdef CHECK if (!clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)) || (Strict && !clause_LiteralGetFlag(clause_GetLiteral(Clause, i), STRICTMAXIMAL))) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_LitMax: Literal %d isn't %smaximal.", i, Strict ? "strictly " : ""); misc_FinishErrorReport(); } if (i < clause_FirstAntecedentLitIndex(Clause) || i > clause_LastSuccedentLitIndex(Clause)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_LitMax: Literal index %d is out of range.", i); misc_FinishErrorReport(); } /* If literal is selected, there's no need to check for maximality, */ /* if isn't selected, but there're other literals selected, */ /* inferences with literal are forbidden. */ if (clause_GetFlag(Clause, CLAUSESELECT)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_LitMax: There're selected literals.", i); misc_FinishErrorReport(); } #endif Lit = clause_GetLiteral(Clause, i); /* Check necessary condition */ if (!clause_LiteralIsMaximal(Lit) || (Strict && !clause_LiteralGetFlag(Lit, STRICTMAXIMAL))) return FALSE; /* Only antecedent and succedent literals are compared, so if there's */ /* only one such literal, it's maximal. */ /* If the substitution is empty, the necessary condition tested above */ /* is sufficient, too. */ if ((clause_NumOfAnteLits(Clause) + clause_NumOfSuccLits(Clause) == 1) || subst_Empty(Subst)) return TRUE; l = clause_LastSuccedentLitIndex(Clause); Max = subst_Apply(Subst,term_Copy(clause_GetLiteralTerm(Clause,i))); for (k = clause_FirstAntecedentLitIndex(Clause); k <= l; k++) if (k != i && k != j && clause_LiteralIsMaximal(clause_GetLiteral(Clause, k))) { /* Only compare with maximal literals, since for every non-maximal */ /* literal, there's at least one maximal literal, that is bigger. */ LitTerm = subst_Apply(Subst,term_Copy(clause_GetLiteralTerm(Clause,k))); Compare = ord_LiteralCompare(Max, clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)), LitTerm, clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,k)), TRUE, Flags, Precedence); if (Compare == ord_SmallerThan() || (Strict && Compare == ord_Equal())) { term_Delete(Max); term_Delete(LitTerm); return FALSE; } term_Delete(LitTerm); } term_Delete(Max); return TRUE; } static BOOL inf_LiteralsMax(CLAUSE Clause, int i, SUBST Subst, CLAUSE PartnerClause, int j, SUBST PartnerSubst, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: The parents of a resolution inference, the respective literal indices and substitutions, a flag store and a precedence. RETURNS: TRUE iff the positive/negative literals are still strictly maximal/maximal in the instantiated clause. If a negative literal is selected, no comparison is made. ***************************************************************/ { #ifdef CHECK if ((clause_GetFlag(Clause, CLAUSESELECT) && !clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT)) || (clause_GetFlag(PartnerClause, CLAUSESELECT) && !clause_LiteralGetFlag(clause_GetLiteral(PartnerClause,j),LITSELECT))) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_LiteralsMax: Another literal is selected."); misc_FinishErrorReport(); } #endif if (!clause_GetFlag(Clause, CLAUSESELECT) && !inf_LitMax(Clause,i,-1,Subst, i>clause_LastAntecedentLitIndex(Clause),Flags, Precedence)) return FALSE; if (!clause_GetFlag(PartnerClause, CLAUSESELECT) && !inf_LitMax(PartnerClause,j,-1,PartnerSubst, j>clause_LastAntecedentLitIndex(PartnerClause), Flags, Precedence)) return FALSE; return TRUE; } static BOOL inf_LitMaxWith2Subst(CLAUSE Clause, int i, int j, SUBST Subst2, SUBST Subst1, BOOL Strict, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause, the index of a maximal literal, another literal index, two substitutions, a boolean flag, a flag store and a precedence. RETURNS: In contrast to the function inf_LitMax this function compares the literals with respect to the composition of the two substitutions Subst2 ° Subst1. If =FALSE the function returns TRUE iff the literal at index is still maximal in the instantiated clause. If =TRUE the function returns TRUE iff the literal is STRICTLY maximal in the instantiated clause. The literal at index j is omitted at literal comparison. However, setting j to a negative number ensures that all literals are compared with the literal at index . CAUTION: DON'T call this function with a clause with selected literals! ***************************************************************/ { TERM Max, LitTerm; LITERAL Lit; ord_RESULT Compare; int k, l; #ifdef CHECK if (!clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)) || (Strict && !clause_LiteralGetFlag(clause_GetLiteral(Clause, i), STRICTMAXIMAL))) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_LitMaxWith2Subst: Literal %d isn't %smaximal.", i, Strict ? "strictly " : ""); misc_FinishErrorReport(); } if (i < clause_FirstAntecedentLitIndex(Clause) || i > clause_LastSuccedentLitIndex(Clause)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_LitMaxWith2Subst: Literal index %d is out of range.", i); misc_FinishErrorReport(); } /* If literal is selected, there's no need to check for maximality, */ /* if isn't selected, but there're other literals selected, */ /* inferences with literal are forbidden. */ if (clause_GetFlag(Clause, CLAUSESELECT)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_LitMaxWith2Subst: There're selected literals.", i); misc_FinishErrorReport(); } #endif Lit = clause_GetLiteral(Clause, i); /* Check necessary condition */ if (!clause_LiteralIsMaximal(Lit) || (Strict && !clause_LiteralGetFlag(Lit, STRICTMAXIMAL))) return FALSE; /* Only antecedent and succedent literals are compared, so if there's */ /* only one such literal, it's maximal. */ /* If both substitutions are empty, the necessary condition tested above */ /* is sufficient, too. */ if ((clause_NumOfAnteLits(Clause) + clause_NumOfSuccLits(Clause) == 1) || (subst_Empty(Subst1) && subst_Empty(Subst2))) return TRUE; l = clause_LastSuccedentLitIndex(Clause); Max = subst_Apply(Subst1, term_Copy(clause_GetLiteralTerm(Clause,i))); Max = subst_Apply(Subst2, Max); for (k = clause_FirstAntecedentLitIndex(Clause); k <= l; k++) if (k != i && k != j && clause_LiteralIsMaximal(clause_GetLiteral(Clause, k))) { /* Only compare with maximal literals, since for every non-maximal */ /* literal, there's at least one maximal literal, that is bigger. */ LitTerm = subst_Apply(Subst1,term_Copy(clause_GetLiteralTerm(Clause,k))); LitTerm = subst_Apply(Subst2, LitTerm); Compare = ord_LiteralCompare(Max, clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)), LitTerm, clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,k)), TRUE, Flags, Precedence); if (Compare == ord_SmallerThan() || (Strict && Compare == ord_Equal())) { term_Delete(Max); term_Delete(LitTerm); return FALSE; } term_Delete(LitTerm); } term_Delete(Max); return TRUE; } static BOOL inf_LiteralsMaxWith2Subst(CLAUSE Clause, int i, CLAUSE PartnerClause, int j, SUBST Subst2, SUBST Subst1, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: The parents of a resolution inference, the respective literal indices and substitutions, a flag store and a precedence. RETURNS: In contrast to the function inf_LiteralsMax the composition Subst2 ° Subst1 is applied to both clauses. The function returns TRUE iff the positive/negative literals are still strictly maximal/maximal in the instantiated clause. If a negative literal is selected, no comparison is made. ***************************************************************/ { #ifdef CHECK if ((clause_GetFlag(Clause, CLAUSESELECT) && !clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT)) || (clause_GetFlag(PartnerClause, CLAUSESELECT) && !clause_LiteralGetFlag(clause_GetLiteral(PartnerClause,j),LITSELECT))) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_LiteralsMaxWith2Subst: Another literal is selected."); misc_FinishErrorReport(); } #endif if (!clause_GetFlag(Clause, CLAUSESELECT) && !inf_LitMaxWith2Subst(Clause, i, -1, Subst2, Subst1, i>clause_LastAntecedentLitIndex(Clause), Flags, Precedence)) return FALSE; if (!clause_GetFlag(PartnerClause, CLAUSESELECT) && !inf_LitMaxWith2Subst(PartnerClause, j, -1, Subst2, Subst1, j>clause_LastAntecedentLitIndex(PartnerClause), Flags, Precedence)) return FALSE; return TRUE; } /**************************************************************/ /* Inference rules */ /**************************************************************/ LIST inf_EqualityResolution(CLAUSE GivenClause, BOOL Ordered, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause and a flag determining whether ordering constraints apply. For =TRUE the function makes Equality Resolution inferences, for =FALSE Reflexivity Resolution inferences are made. A flag store. A precedence. RETURNS: A list of clauses inferred from the GivenClause by Equality/Reflexivity Resolution. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result; LITERAL ActLit; int i, last; #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_EqualityResolution: Illegal input."); misc_FinishErrorReport(); } #endif if (clause_HasEmptyAntecedent(GivenClause) || !clause_HasSolvedConstraint(GivenClause)) { return list_Nil(); } Result = list_Nil(); last = clause_LastAntecedentLitIndex(GivenClause); for (i = clause_FirstAntecedentLitIndex(GivenClause); i <= last; i++) { ActLit = clause_GetLiteral(GivenClause, i); if (clause_LiteralIsEquality(ActLit) && (clause_LiteralGetFlag(ActLit,LITSELECT) || (!clause_GetFlag(GivenClause,CLAUSESELECT) && (!Ordered || clause_LiteralIsMaximal(ActLit))))) { TERM Atom; Atom = clause_GetLiteralAtom(GivenClause, i); cont_Check(); if (unify_UnifyCom(cont_LeftContext(), term_FirstArgument(Atom), term_SecondArgument(Atom))) { SUBST mgu; CLAUSE NewClause; int j, k, bound; subst_ExtractUnifierCom(cont_LeftContext(), &mgu); /* Check postcondition */ if (clause_LiteralGetFlag(ActLit,LITSELECT) || !Ordered || inf_LitMax(GivenClause, i, -1, mgu, FALSE, Flags, Precedence)) { NewClause = clause_CreateBody(clause_Length(GivenClause) - 1); clause_SetNumOfConsLits(NewClause, clause_NumOfConsLits(GivenClause)); clause_SetNumOfAnteLits(NewClause, (clause_NumOfAnteLits(GivenClause) - 1)); clause_SetNumOfSuccLits(NewClause, clause_NumOfSuccLits(GivenClause)); bound = clause_LastLitIndex(GivenClause); /* j iterates over the given clause, k iterates over the new one */ for (j = k = clause_FirstLitIndex(); j <= bound; j++) { if (j != i) { clause_SetLiteral(NewClause, k, clause_LiteralCreate(subst_Apply(mgu, term_Copy(clause_GetLiteralTerm(GivenClause,j))),NewClause)); k++; } } clause_SetDataFromFather(NewClause, GivenClause, i, Flags, Precedence); clause_SetFromEqualityResolution(NewClause); Result = list_Cons(NewClause, Result); } subst_Delete(mgu); } cont_Reset(); } /* end of if 'ActLit is maximal'. */ } /*end of for 'all literals'. */ return(Result); } static CLAUSE inf_ApplyEqualityFactoring(CLAUSE Clause, TERM Left, TERM Right, int i, int j, SUBST Subst, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause, two terms, two indices in the clause, a substitution, a flag store and a precedence. RETURNS: A new clause, where = is added as antecedent atom, the th literal is deleted, the th kept and is applied to a copy of . ***************************************************************/ { CLAUSE NewClause; TERM Atom; int k,c,a,s; NewClause = clause_CreateBody(clause_Length(Clause)); c = clause_LastConstraintLitIndex(Clause); clause_SetNumOfConsLits(NewClause, clause_NumOfConsLits(Clause)); a = clause_LastAntecedentLitIndex(Clause); clause_SetNumOfAnteLits(NewClause, clause_NumOfAnteLits(Clause) + 1); s = clause_LastSuccedentLitIndex(Clause); clause_SetNumOfSuccLits(NewClause, clause_NumOfSuccLits(Clause) - 1); for (k = clause_FirstLitIndex(); k <= c; k++) { clause_SetLiteral(NewClause, k, clause_LiteralCreate(subst_Apply(Subst, term_Copy(clause_GetLiteralTerm(Clause, k))),NewClause)); } for ( ; k <= a; k++) { clause_SetLiteral(NewClause, k, clause_LiteralCreate(subst_Apply(Subst, term_Copy(clause_GetLiteralTerm(Clause, k))),NewClause)); } Atom = term_Create(fol_Equality(), list_Cons(term_Copy(Left),list_List(term_Copy(Right)))); clause_SetLiteral(NewClause, k, clause_LiteralCreate( term_Create(fol_Not(), list_List(subst_Apply(Subst,Atom))), NewClause)); a = 1; /* Shift */ for ( ; k <= s; k++) { if (k == i) a = 0; else { clause_SetLiteral(NewClause, (k + a), clause_LiteralCreate(subst_Apply(Subst, term_Copy(clause_GetLiteralTerm(Clause, k))),NewClause)); } } clause_AddParentClause(NewClause, clause_Number(Clause)); clause_AddParentLiteral(NewClause, j); clause_SetDataFromFather(NewClause, Clause, i, Flags, Precedence); clause_SetFromEqualityFactoring(NewClause); return NewClause; } static BOOL inf_EqualityFactoringApplicable(CLAUSE Clause, int i, TERM Left, TERM Right, SUBST Subst, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause , the index of a maximal equality literal in , and are the left and right side of the literal, where is not greater than wrt the ordering, a unifier , a flag store and a precedence. RETURNS: TRUE iff the literal at index is strictly maximal in the instantiated clause and is not greater than or equal to after application of the substitution. Otherwise, the function returns FALSE. ***************************************************************/ { ord_RESULT Help; /* Literal oriented? */ if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause, i))) { TERM NLeft, NRight; NLeft = subst_Apply(Subst, term_Copy(Left)); NRight = subst_Apply(Subst, term_Copy(Right)); if ((Help = ord_Compare(NLeft,NRight,Flags, Precedence)) == ord_SmallerThan() || Help == ord_Equal()) { term_Delete(NLeft); term_Delete(NRight); return FALSE; } term_Delete(NLeft); term_Delete(NRight); } /* Literal maximal? */ return inf_LitMax(Clause, i, -1, Subst, FALSE, Flags, Precedence); } LIST inf_EqualityFactoring(CLAUSE GivenClause, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause, a flag store and a precedence. RETURNS: A list of clauses derivable from 'GivenClause' by EF. ***************************************************************/ { LIST Result; LITERAL ActLit; int i, j, last; SUBST mgu; #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_EqualityFactoring: Illegal input."); misc_FinishErrorReport(); } #endif if (clause_HasEmptySuccedent(GivenClause) || clause_GetFlag(GivenClause, CLAUSESELECT) || !clause_HasSolvedConstraint(GivenClause)) { return list_Nil(); } Result = list_Nil(); last = clause_LastSuccedentLitIndex(GivenClause); for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= last; i++) { ActLit = clause_GetLiteral(GivenClause, i); if (clause_LiteralIsMaximal(ActLit) && clause_LiteralIsEquality(ActLit)) { TERM Atom, Left, Right; LITERAL PartnerLit; Atom = clause_LiteralAtom(ActLit); Left = term_FirstArgument(Atom); Right = term_SecondArgument(Atom); for (j = clause_FirstSuccedentLitIndex(GivenClause); j <= last; j++) { PartnerLit = clause_GetLiteral(GivenClause, j); if (i != j && clause_LiteralIsEquality(PartnerLit)) { /* i==j can be excluded since this inference would either generate */ /* a copy of the given clause (if one side of the equality is */ /* unified with itself), or generate a tautology (if different */ /* sides of the equality are unified). */ TERM PartnerAtom, PartnerLeft, PartnerRight; PartnerAtom = clause_LiteralAtom(PartnerLit); PartnerLeft = term_FirstArgument(PartnerAtom); PartnerRight = term_SecondArgument(PartnerAtom); /* try and */ cont_Check(); if (unify_UnifyCom(cont_LeftContext(), Left, PartnerLeft)) { subst_ExtractUnifierCom(cont_LeftContext(), &mgu); if (inf_EqualityFactoringApplicable(GivenClause, i, Left, Right, mgu, Flags, Precedence)) Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Right, PartnerRight,i,j, mgu,Flags, Precedence), Result); subst_Delete(mgu); } cont_Reset(); /* try and */ cont_Check(); if (unify_UnifyCom(cont_LeftContext(), Left, PartnerRight)) { subst_ExtractUnifierCom(cont_LeftContext(), &mgu); if (inf_EqualityFactoringApplicable(GivenClause, i, Left, Right, mgu, Flags, Precedence)) Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Right, PartnerLeft,i,j, mgu,Flags, Precedence), Result); subst_Delete(mgu); } cont_Reset(); if (!clause_LiteralIsOrientedEquality(ActLit)) { /* try and */ cont_Check(); if (unify_UnifyCom(cont_LeftContext(), Right, PartnerLeft)) { subst_ExtractUnifierCom(cont_LeftContext(), &mgu); if (inf_EqualityFactoringApplicable(GivenClause, i, Right, Left, mgu, Flags, Precedence)) Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Left, PartnerRight,i,j, mgu,Flags, Precedence), Result); subst_Delete(mgu); } cont_Reset(); /* try and */ cont_Check(); if (unify_UnifyCom(cont_LeftContext(), Right, PartnerRight)) { subst_ExtractUnifierCom(cont_LeftContext(), &mgu); if (inf_EqualityFactoringApplicable(GivenClause, i, Right, Left, mgu, Flags, Precedence)) Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Left, PartnerLeft,i,j, mgu,Flags, Precedence), Result); subst_Delete(mgu); } cont_Reset(); } } } } } return Result; } /* START of block with new term replacement */ static BOOL inf_NAllTermsRplac(TERM Term, TERM TestTerm, TERM RplacTerm, SUBST Subst) /************************************************************** INPUT: Three terms, a substitution and an integer. All occurrences of in are replaced by . The substitution is applied to . RETURNS: TRUE, if TestTerm was replaced by RplacTerm, FALSE otherwise. EFFECT: is destructively changed! ***************************************************************/ { LIST ArgListNode; BOOL Replaced; int Bottom; Replaced = FALSE; /* check if whole term must be replaced */ if (term_Equal(Term, TestTerm)) { term_RplacTop(Term,term_TopSymbol(RplacTerm)); ArgListNode = term_ArgumentList(Term); term_RplacArgumentList(Term, term_CopyTermList(term_ArgumentList(RplacTerm))); term_DeleteTermList(ArgListNode); return TRUE; } if (term_IsVariable(Term)) subst_Apply(Subst, Term); /* if not, scan whole term. */ if (!list_Empty(term_ArgumentList(Term))) { Bottom = stack_Bottom(); stack_Push(term_ArgumentList(Term)); while (!stack_Empty(Bottom)) { ArgListNode = stack_Top(); Term = (TERM)list_Car(ArgListNode); stack_RplacTop(list_Cdr(ArgListNode)); if (term_Equal(Term, TestTerm)) { Replaced = TRUE; list_Rplaca(ArgListNode, term_Copy(RplacTerm)); term_Delete(Term); } else { if (term_IsComplex(Term)) stack_Push(term_ArgumentList(Term)); else if (term_IsVariable(Term)) subst_Apply(Subst,Term); } /* remove empty lists (corresponding to scanned terms) */ while (!stack_Empty(Bottom) && list_Empty(stack_Top())) stack_Pop(); } } return Replaced; } static TERM inf_AllTermsRplac(TERM Term, TERM TestTerm, TERM RplacTerm, SUBST Subst) /************************************************************** INPUT: Three terms, a substitution. All occurrences of in A COPY of are replaced by . The substitution is applied to the copy of . If no occurrence is found, NULL is returned. This function is not destructive like NAllTermRplac. RETURNS: TRUE, if TestTerm was replaced by RplacTerm, FALSE otherwise. ***************************************************************/ { TERM ActTerm = term_Copy(Term); if (!inf_NAllTermsRplac(ActTerm,TestTerm, RplacTerm, Subst )) { term_Delete(ActTerm); ActTerm = NULL; } return(ActTerm); } static TERM inf_AllTermsSideRplacs(TERM Term, TERM TestTerm, TERM RplacTerm, SUBST Subst, BOOL Right) /************************************************************** INPUT: Three terms, a substitution and a boolean flag. is typically an equality term. RETURNS: If occurs in the right (Right=TRUE) or left side (Right=FALSE) of : A copy of the term where all occurrences of in the ENTIRE are replaced by and the substitution is applied to all other subterms. If does not occur in the right/left side of , NULL is returned. In non-equality terms, The 'sides' correspond to the first and second argument of the term. ***************************************************************/ { TERM ActTerm = term_Copy(Term); TERM ReplSide, OtherSide; /* ReplSide is the side in which terms are replaced */ if (Right) { ReplSide = term_SecondArgument(ActTerm); OtherSide = term_FirstArgument(ActTerm); } else { ReplSide = term_FirstArgument(ActTerm); OtherSide = term_SecondArgument(ActTerm); } if (inf_NAllTermsRplac(ReplSide, TestTerm, RplacTerm, Subst)) /* If occurs in also replace it in . */ inf_NAllTermsRplac(OtherSide, TestTerm, RplacTerm, Subst); else { term_Delete(ActTerm); ActTerm = NULL; } return ActTerm; } static TERM inf_AllTermsRightRplac(TERM Term, TERM TestTerm, TERM RplacTerm, SUBST Subst) /************************************************************** INPUT: Three terms, a substitution. is typically an equality term. RETURNS: See inf_AllTermSideRplac with argument 'Right' set to TRUE **************************************************************/ { return(inf_AllTermsSideRplacs(Term, TestTerm, RplacTerm, Subst, TRUE)); } static TERM inf_AllTermsLeftRplac(TERM Term, TERM TestTerm, TERM RplacTerm, SUBST Subst) /************************************************************** INPUT: Three terms, a substitution. is typically an equality term. RETURNS: See inf_AllTermSideRplac with argument 'Right' set to FALSE. ***************************************************************/ { return(inf_AllTermsSideRplacs(Term, TestTerm, RplacTerm, Subst, FALSE)); } /* END of block with new term replacement */ static CLAUSE inf_ApplyGenSuperposition(CLAUSE Clause, int ci, SUBST Subst, CLAUSE PartnerClause, int pci, SUBST PartnerSubst, TERM SupAtom, BOOL Right, BOOL OrdPara, BOOL MaxPara, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: Two clauses where a generalized superposition inference can be applied using the positive equality literal from with subst using the literal from with subst where SupAtom is a derivable atom. Returns NULL if SupAtom is NULL. Right is TRUE if the inference is a superposition right inference Right is FALSE if the inference is a superposition left inference, where the inference is selected by MaxPara and OrdPara: (see also inf_GenSuperpositionLeft) OrdPara=TRUE, MaxPara=TRUE -> Superposition (Left or Right) OrdPara=TRUE, MaxPara=FALSE -> ordered Paramodulation OrdPara=FALSE, MaxPara=FALSE -> simple Paramodulation OrdPara=FALSE, MaxPara=TRUE -> not defined A flag store. A precedence. RETURNS: The new clause. MEMORY: Memory for the new clause is allocated. ***************************************************************/ { CLAUSE NewClause; int j,lc,la,ls,pls,pla,plc,help; #ifdef CHECK if (!OrdPara && MaxPara) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_ApplyGenSuperposition : Illegal inference"); misc_ErrorReport("\n rule selection, OrdPara=FALSE and MaxPara=TRUE."); misc_FinishErrorReport(); } if (SupAtom == NULL) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_ApplyGenSuperposition: Atom is NULL."); misc_FinishErrorReport(); return clause_Null(); } #endif pls = clause_LastSuccedentLitIndex(PartnerClause); pla = clause_LastAntecedentLitIndex(PartnerClause); plc = clause_LastConstraintLitIndex(PartnerClause); ls = clause_LastSuccedentLitIndex(Clause); la = clause_LastAntecedentLitIndex(Clause); lc = clause_LastConstraintLitIndex(Clause); NewClause = clause_CreateBody(clause_Length(Clause) - 1 + clause_Length(PartnerClause)); clause_SetNumOfConsLits(NewClause, (clause_NumOfConsLits(Clause) + clause_NumOfConsLits(PartnerClause))); clause_SetNumOfAnteLits(NewClause, (clause_NumOfAnteLits(Clause) + clause_NumOfAnteLits(PartnerClause))); clause_SetNumOfSuccLits(NewClause, ((clause_NumOfSuccLits(Clause) -1)+ clause_NumOfSuccLits(PartnerClause))); /* First set the literals from the Clause : */ for (j = clause_FirstLitIndex(); j <= lc; j++) { clause_SetLiteral(NewClause, j, clause_LiteralCreate(subst_Apply(Subst, term_Copy( clause_GetLiteralTerm(Clause, j))),NewClause)); } /* help = number of literals to leave empty */ help = clause_NumOfConsLits(PartnerClause); for ( ; j <= la; j++) { clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(subst_Apply(Subst, term_Copy( clause_GetLiteralTerm(Clause, j))),NewClause)); } /* help = number of literals to leave empty */ help += clause_NumOfAnteLits(PartnerClause); for ( ; j <= ls; j++) { if (j != ci) { /* The literal used in the inference isn't copied */ clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(subst_Apply(Subst, term_Copy(clause_GetLiteralTerm(Clause, j))),NewClause)); } else { /*the index has to be decreased to avoid an empty literal! */ help--; } } /* Now we consider the PartnerClause : */ /* help = number of already set constraint (Clause) literals */ help = clause_NumOfConsLits(Clause); for (j = clause_FirstLitIndex(); j <= plc; j++) { clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(subst_Apply(PartnerSubst, term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause)); } /* help = number of already set constraint and antecedent Given-literals */ help += clause_NumOfAnteLits(Clause); for ( ; j <= pla; j++) { if (j != pci) { clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(subst_Apply(PartnerSubst, term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause)); } else { /* The PartnerLit is modified appropriately! */ clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate( term_Create(fol_Not(),list_List(SupAtom)), NewClause)); } } /* help = number of already set Given-literals */ help = clause_Length(Clause) - 1; for ( ; j <= pls; j++) { if (j != pci) { /* The PartnerLit isn't copied! */ clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(subst_Apply(PartnerSubst, term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause)); } else { /* The PartnerLit is modified appropriately! */ clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(SupAtom, NewClause)); } } /* * Set inference type. Note that, in the case of (ordered) paramodulation, * we do not distinguish which side was paramodulated into, as compared * to the case of superposition. */ if (OrdPara && MaxPara) { if (Right) clause_SetFromSuperpositionRight(NewClause); else clause_SetFromSuperpositionLeft(NewClause); } else if (OrdPara && !MaxPara) clause_SetFromOrderedParamodulation(NewClause); else clause_SetFromParamodulation(NewClause); clause_SetDataFromParents(NewClause, PartnerClause, pci, Clause, ci, Flags, Precedence); return NewClause; } /* START of block with new superposition right rule */ static LIST inf_GenLitSPRight(CLAUSE Clause, TERM Left, TERM Right, int i, SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause (unshared) with a positive equality literal at position where and are the arguments of just that literal and is not greater wrt. the ordering than , two boolean flags for controlling inference preconditions (see inf_GenSuperpositionRight), a flag store and a precedence. RETURNS: A list of clauses derivable with the literals owning clause by general superposition right wrt. the Index. (see inf_GenSuperpositionRight for selection of inference rule by OrdPara/MaxPara) MEMORY: The list of clauses is extended, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result, Terms; Result = list_Nil(); Terms = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Left); for ( ; !list_Empty(Terms); Terms = list_Pop(Terms)) { LIST Lits; TERM Term; Term = (TERM)list_First(Terms); if (!term_IsVariable(Term) && !symbol_IsPredicate(term_TopSymbol(Term))) { Lits = sharing_GetDataList(Term, ShIndex); for ( ; !list_Empty(Lits); Lits = list_Pop(Lits)) { LITERAL PartnerLit; TERM PartnerAtom; CLAUSE PartnerClause; int pli; PartnerLit = (LITERAL)list_Car(Lits); PartnerAtom = clause_LiteralAtom(PartnerLit); pli = clause_LiteralGetIndex(PartnerLit); PartnerClause = clause_LiteralOwningClause(PartnerLit); if (!clause_GetFlag(PartnerClause,CLAUSESELECT) && (!MaxPara || clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) && !clause_GetFlag(PartnerClause,NOPARAINTO) && clause_LiteralIsPositive(PartnerLit) && clause_HasSolvedConstraint(PartnerClause)) { SUBST Subst, PartnerSubst; TERM NewLeft,NewRight; SYMBOL PartnerMaxVar; TERM SupAtom; SupAtom = (TERM)NULL; PartnerMaxVar = clause_MaxVar(PartnerClause); NewLeft = Left; clause_RenameVarsBiggerThan(Clause, PartnerMaxVar); cont_Check(); unify_UnifyNoOC(cont_LeftContext(), Left, cont_RightContext(), Term); subst_ExtractUnifier(cont_LeftContext(), &Subst, cont_RightContext(), &PartnerSubst); cont_Reset(); if (!MaxPara || inf_LiteralsMax(Clause, i, Subst, PartnerClause, pli, PartnerSubst, Flags, Precedence)) { NewRight = subst_Apply(Subst, term_Copy(Right)); if (OrdPara && !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i))) NewLeft = subst_Apply(Subst, term_Copy(Left)); if (!OrdPara || NewLeft == Left || /* TRUE, if oriented */ ord_Compare(NewLeft,NewRight, Flags, Precedence) != ord_SmallerThan()) { if (!MaxPara || clause_LiteralIsPredicate(PartnerLit)) { SupAtom = inf_AllTermsRplac(PartnerAtom, Term, NewRight, PartnerSubst); } else { /* Superposition and is equality */ if (clause_LiteralIsOrientedEquality(PartnerLit)) SupAtom = inf_AllTermsLeftRplac(PartnerAtom, Term, NewRight, PartnerSubst); else { TERM NewPartnerLeft,NewPartnerRight; NewPartnerLeft = subst_Apply(PartnerSubst, term_Copy(term_FirstArgument(PartnerAtom))); NewPartnerRight = subst_Apply(PartnerSubst, term_Copy(term_SecondArgument(PartnerAtom))); switch (ord_Compare(NewPartnerLeft,NewPartnerRight, Flags, Precedence)) { case ord_SMALLER_THAN: SupAtom = inf_AllTermsRightRplac(PartnerAtom,Term, NewRight,PartnerSubst); break; case ord_GREATER_THAN: SupAtom = inf_AllTermsLeftRplac(PartnerAtom,Term, NewRight,PartnerSubst); break; default: SupAtom = inf_AllTermsRplac(PartnerAtom,Term, NewRight,PartnerSubst); } term_Delete(NewPartnerLeft); term_Delete(NewPartnerRight); } } if (SupAtom != NULL) Result = list_Cons(inf_ApplyGenSuperposition(Clause, i, Subst, PartnerClause, pli, PartnerSubst, SupAtom, TRUE, OrdPara, MaxPara, Flags, Precedence), Result); } if (NewLeft != Left) term_Delete(NewLeft); term_Delete(NewRight); } subst_Delete(Subst); subst_Delete(PartnerSubst); } } } } return Result; } static LIST inf_GenSPRightEqToGiven(CLAUSE Clause, int i, BOOL Left, SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara, BOOL Unit, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: An unshared clause, the index of a succedent literal that is an equality literal and a boolean value which argument to use: If Left==TRUE then the left argument is used otherwise the right argument. Three boolean flags for controlling inference preconditions (see inf_GenSuperpositionRight). A flag store. A precedence. RETURNS: A list of clauses derivable from general superposition right on the GivenCopy wrt. the Index. (see inf_GenSuperpositionRight for selection of inference rule by OrdPara/MaxPara) MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result, TermList, Parents; int Bottom; LITERAL Lit; TERM Atom, Term, PartnerTerm, PartnerEq; Result = list_Nil(); Lit = clause_GetLiteral(Clause,i); Atom = clause_LiteralAtom(Lit); #ifdef CHECK if (!fol_IsEquality(Atom) || (MaxPara && clause_LiteralIsOrientedEquality(Lit) && !Left) || (MaxPara && !clause_LiteralGetFlag(Lit, STRICTMAXIMAL))) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSPRightEqToGiven: Illegal input."); misc_FinishErrorReport(); } #endif Bottom = stack_Bottom(); if (Left) /* Top Level considered in inf_LitSPRight */ sharing_PushListOnStack(term_ArgumentList(term_FirstArgument(Atom))); else sharing_PushListOnStack(term_ArgumentList(term_SecondArgument(Atom))); while (!stack_Empty(Bottom)) { Term = (TERM)stack_PopResult(); if (!term_IsVariable(Term)) { /* Superposition into variables is not necessary */ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Term); for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) { PartnerTerm = (TERM)list_Car(TermList); for (Parents = term_SupertermList(PartnerTerm); !list_Empty(Parents); Parents = list_Cdr(Parents)) { PartnerEq = (TERM)list_Car(Parents); if (fol_IsEquality(PartnerEq)) { CLAUSE PartnerClause; LITERAL PartnerLit; LIST Scl; int j; for (Scl = sharing_NAtomDataList(PartnerEq); !list_Empty(Scl); Scl = list_Cdr(Scl)) { PartnerLit = (LITERAL)list_Car(Scl); j = clause_LiteralGetIndex(PartnerLit); PartnerClause = clause_LiteralOwningClause(PartnerLit); if (!clause_GetFlag(PartnerClause,CLAUSESELECT) && (!MaxPara || clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) && (!OrdPara || PartnerTerm==term_FirstArgument(PartnerEq) || !clause_LiteralIsOrientedEquality(PartnerLit)) && clause_LiteralIsPositive(PartnerLit) && clause_Number(PartnerClause) != clause_Number(Clause) && (!Unit || clause_Length(PartnerClause) == 1) && clause_HasSolvedConstraint(PartnerClause)) { /* We exclude the same clause since that inference will be */ /* made by the "forward" function inf_GenLitSPRight. */ SYMBOL MaxVar; SUBST Subst, PartnerSubst; MaxVar = clause_MaxVar(PartnerClause); clause_RenameVarsBiggerThan(Clause, MaxVar); cont_Check(); unify_UnifyNoOC(cont_LeftContext(), Term, cont_RightContext(), PartnerTerm); subst_ExtractUnifier(cont_LeftContext(), &Subst, cont_RightContext(), &PartnerSubst); cont_Reset(); if (!MaxPara || inf_LiteralsMax(Clause, i, Subst, PartnerClause, j, PartnerSubst, Flags, Precedence)) { TERM PartnerLeft,PartnerRight; BOOL Check, PartnerCheck; PartnerLeft = PartnerRight = NULL; PartnerCheck = Check = TRUE; if (OrdPara && !clause_LiteralIsOrientedEquality(PartnerLit)) { /* Check post condition for partner literal */ if (PartnerTerm == term_FirstArgument(PartnerEq)) PartnerRight = term_SecondArgument(PartnerEq); else PartnerRight = term_FirstArgument(PartnerEq); PartnerLeft = subst_Apply(PartnerSubst, term_Copy(PartnerTerm)); PartnerRight = subst_Apply(PartnerSubst, term_Copy(PartnerRight)); PartnerCheck = (ord_Compare(PartnerLeft, PartnerRight, Flags, Precedence) != ord_SmallerThan()); } if (PartnerCheck && MaxPara && !clause_LiteralIsOrientedEquality(Lit)) { /* Check post condition for literal in given clause */ TERM NewLeft, NewRight; if (Left) { NewLeft = term_FirstArgument(Atom); NewRight = term_SecondArgument(Atom); } else { NewLeft = term_SecondArgument(Atom); NewRight = term_FirstArgument(Atom); } NewLeft = subst_Apply(Subst, term_Copy(NewLeft)); NewRight = subst_Apply(Subst, term_Copy(NewRight)); Check = (ord_Compare(NewLeft, NewRight, Flags, Precedence) != ord_SmallerThan()); term_Delete(NewLeft); term_Delete(NewRight); } if (Check && PartnerCheck) { /* Make inference only if both tests were successful */ TERM SupAtom; SupAtom = NULL; if (PartnerRight == NULL) { if (PartnerTerm==term_FirstArgument(PartnerEq)) PartnerRight = term_SecondArgument(PartnerEq); else PartnerRight = term_FirstArgument(PartnerEq); PartnerRight = subst_Apply(PartnerSubst, term_Copy(PartnerRight)); } if (Left) SupAtom = inf_AllTermsLeftRplac(Atom, Term, PartnerRight, Subst); else SupAtom = inf_AllTermsRightRplac(Atom, Term, PartnerRight, Subst); #ifdef CHECK if (SupAtom == NULL) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSPRightEqToGiven:"); misc_ErrorReport(" replacement wasn't possible."); misc_FinishErrorReport(); } #endif Result = list_Cons(inf_ApplyGenSuperposition(PartnerClause, j, PartnerSubst, Clause, i, Subst, SupAtom, TRUE,OrdPara,MaxPara, Flags, Precedence), Result); } if (PartnerLeft != term_Null()) term_Delete(PartnerLeft); if (PartnerRight != term_Null()) term_Delete(PartnerRight); } subst_Delete(Subst); subst_Delete(PartnerSubst); } } } } } } } return Result; } static LIST inf_GenSPRightLitToGiven(CLAUSE Clause, int i, TERM Atom, SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara, BOOL Unit, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: An unshared clause, the index of a succedent literal that is not an equality literal and its atom, three boolean flags for controlling inference preconditions (see inf_GenSuperpositionRight), a flag store and a precedence. RETURNS: A list of clauses derivable from general superposition right on the GivenCopy wrt. the Index. (see inf_GenSuperpositionRight for selection of inference rule by OrdPara/MaxPara) MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result, TermList, ParentList; int Bottom; TERM Term, PartnerTerm, PartnerEq; Result = list_Nil(); Bottom = stack_Bottom(); sharing_PushListOnStack(term_ArgumentList(Atom)); while (!stack_Empty(Bottom)) { Term = (TERM)stack_PopResult(); if (!term_IsVariable(Term)) { /* Superposition into variables is not necessary */ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Term); for ( ; !list_Empty(TermList); TermList=list_Pop(TermList)) { PartnerTerm = (TERM)list_Car(TermList); for (ParentList = term_SupertermList(PartnerTerm); !list_Empty(ParentList); ParentList = list_Cdr(ParentList)) { PartnerEq = (TERM)list_Car(ParentList); if (fol_IsEquality(PartnerEq)) { CLAUSE PartnerClause; LITERAL PartnerLit; LIST Scl; int j; for (Scl = sharing_NAtomDataList(PartnerEq); !list_Empty(Scl); Scl = list_Cdr(Scl)) { PartnerLit = (LITERAL)list_Car(Scl); j = clause_LiteralGetIndex(PartnerLit); PartnerClause = clause_LiteralOwningClause(PartnerLit); if (!clause_GetFlag(PartnerClause,CLAUSESELECT) && (!MaxPara || clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) && (!OrdPara || PartnerTerm==term_FirstArgument(PartnerEq) || !clause_LiteralIsOrientedEquality(PartnerLit)) && clause_LiteralIsPositive(PartnerLit) && clause_Number(PartnerClause) != clause_Number(Clause) && (!Unit || clause_Length(PartnerClause) == 1) && clause_HasSolvedConstraint(PartnerClause)) { /* We exclude the same clause since that inference will be */ /* made by the "forward" function inf_GenLitSPRight. */ SYMBOL MaxVar; TERM PartnerLeft,PartnerRight; SUBST Subst, PartnerSubst; TERM SupAtom; SupAtom = (TERM)NULL; MaxVar = clause_MaxVar(PartnerClause); clause_RenameVarsBiggerThan(Clause,MaxVar); cont_Check(); unify_UnifyNoOC(cont_LeftContext(), Term, cont_RightContext(),PartnerTerm); subst_ExtractUnifier(cont_LeftContext(), &Subst, cont_RightContext(),&PartnerSubst); cont_Reset(); if (!MaxPara || inf_LiteralsMax(Clause, i, Subst, PartnerClause, j, PartnerSubst, Flags, Precedence)) { PartnerLeft = subst_Apply(PartnerSubst, term_Copy(PartnerTerm)); if (PartnerTerm == term_FirstArgument(PartnerEq)) PartnerRight = subst_Apply(PartnerSubst, term_Copy(term_SecondArgument(PartnerEq))); else PartnerRight = subst_Apply(PartnerSubst, term_Copy(term_FirstArgument(PartnerEq))); if (!OrdPara || clause_LiteralIsOrientedEquality(PartnerLit) || ord_Compare(PartnerLeft,PartnerRight, Flags, Precedence) != ord_SmallerThan()) { SupAtom = inf_AllTermsRplac(Atom,Term,PartnerRight,Subst); #ifdef CHECK if (SupAtom == NULL) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSPRightLitToGiven:"); misc_ErrorReport(" replacement wasn't possible."); misc_FinishErrorReport(); } #endif Result = list_Cons(inf_ApplyGenSuperposition(PartnerClause, j, PartnerSubst, Clause, i, Subst, SupAtom, TRUE,OrdPara,MaxPara, Flags, Precedence), Result); } term_Delete(PartnerLeft); term_Delete(PartnerRight); } subst_Delete(Subst); subst_Delete(PartnerSubst); } } } } } } } return Result; } static LIST inf_GenSPRightToGiven(CLAUSE Clause, int i, SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara, BOOL Unit, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: An unshared clause, the index of a succedent literal and an index of shared clauses, three boolean flags for controlling inference preconditions (see inf_GenSuperpositionRight), a flag store and a precedence. RETURNS: A list of clauses derivable from superposition right on the GivenCopy wrt. the Index. (see inf_GenSuperpositionRight for selection of inference rule by OrdPara/MaxPara) MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { TERM Atom; LIST Result; #ifdef CHECK if (clause_GetFlag(Clause, NOPARAINTO) || clause_GetFlag(Clause, CLAUSESELECT) || (MaxPara && !clause_LiteralGetFlag(clause_GetLiteral(Clause,i), STRICTMAXIMAL))) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSPRightToGiven: Illegal input."); misc_FinishErrorReport(); } #endif Result = list_Nil(); Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i)); if (fol_IsEquality(Atom)) { Result = list_Nconc(inf_GenSPRightEqToGiven(Clause,i,TRUE,ShIndex,OrdPara, MaxPara,Unit,Flags, Precedence), Result); if (!MaxPara || !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i))) /* For SPm and OPm always try other direction, for SpR try it */ /* only if the literal is not oriented. */ Result = list_Nconc(inf_GenSPRightEqToGiven(Clause, i, FALSE, ShIndex, OrdPara,MaxPara,Unit, Flags, Precedence), Result); } else Result = list_Nconc(inf_GenSPRightLitToGiven(Clause,i,Atom,ShIndex, OrdPara,MaxPara,Unit, Flags, Precedence), Result); return Result; } LIST inf_GenSuperpositionRight(CLAUSE GivenClause, SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara, BOOL Unit, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause and an Index, usually the WorkedOffIndex, three boolean flags for controlling inference preconditions, a flag store and a precedence. RETURNS: A list of clauses derivable from the given clause by superposition right wrt. the Index. OrdPara=TRUE, MaxPara=TRUE -> Superposition Right OrdPara=TRUE, MaxPara=FALSE -> ordered Paramodulation OrdPara=FALSE, MaxPara=FALSE -> simple Paramodulation OrdPara=FALSE, MaxPara=TRUE -> not defined If ==TRUE the clause with the maximal equality additionally must be a unit clause. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result; TERM Atom; CLAUSE Copy; int i, n; LITERAL ActLit; #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSuperpositionRight: Illegal input."); misc_FinishErrorReport(); } if (!OrdPara && MaxPara) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSuperpositionRight: Illegal inference"); misc_ErrorReport("\n rule selection, OrdPara=FALSE & MaxPara=TRUE."); misc_FinishErrorReport(); } #endif if (clause_GetFlag(GivenClause,CLAUSESELECT) || clause_HasEmptySuccedent(GivenClause) || !clause_HasSolvedConstraint(GivenClause)) return list_Nil(); Result = list_Nil(); Copy = clause_Copy(GivenClause); n = clause_LastSuccedentLitIndex(Copy); for (i = clause_FirstSuccedentLitIndex(Copy); i <= n; i++) { ActLit = clause_GetLiteral(Copy, i); Atom = clause_LiteralSignedAtom(ActLit); if (!MaxPara || clause_LiteralGetFlag(ActLit,STRICTMAXIMAL)) { if (fol_IsEquality(Atom) && (!Unit || clause_Length(GivenClause) == 1)) { Result = list_Nconc(inf_GenLitSPRight(Copy, term_FirstArgument(Atom), term_SecondArgument(Atom), i, ShIndex,OrdPara,MaxPara,Flags, Precedence), Result); if (!OrdPara || !clause_LiteralIsOrientedEquality(ActLit)) Result = list_Nconc(inf_GenLitSPRight(Copy, term_SecondArgument(Atom), term_FirstArgument(Atom), i, ShIndex,OrdPara,MaxPara,Flags, Precedence), Result); } if (!clause_GetFlag(Copy, NOPARAINTO)) Result = list_Nconc(inf_GenSPRightToGiven(Copy, i, ShIndex, OrdPara, MaxPara,Unit,Flags,Precedence), Result); } } clause_Delete(Copy); return Result; } /* END of block with new superposition right rule */ static LIST inf_ApplyMParamod(CLAUSE C1, CLAUSE C2, int i, int j, int k, TERM u_tau, TERM v, TERM s2, TERM t, TERM v2_sigma, SUBST tau, SUBST rho, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: Two clauses, is a literal index in , and are literal indices in , with applied is used as left side of the two new literals, with subterm replaced by is used as right side of the first new literal, as right side of the second new literal, two substitutions and a flag store. The substitution is applied after . A flag store. A precedence. RETURNS: A list containing one clause derived from the given clauses and literals by merging paramodulation. MEMORY: Memory for the list and the clause is allocated. ***************************************************************/ { CLAUSE newClause; TERM u_sigma; int m, lc, la, ls, pls, pla, plc, help; pls = clause_LastSuccedentLitIndex(C2); pla = clause_LastAntecedentLitIndex(C2); plc = clause_LastConstraintLitIndex(C2); ls = clause_LastSuccedentLitIndex(C1); la = clause_LastAntecedentLitIndex(C1); lc = clause_LastConstraintLitIndex(C1); newClause = clause_CreateBody(clause_Length(C1) + clause_Length(C2) - 1); clause_SetNumOfConsLits(newClause, (clause_NumOfConsLits(C1) + clause_NumOfConsLits(C2))); clause_SetNumOfAnteLits(newClause, (clause_NumOfAnteLits(C1) + clause_NumOfAnteLits(C2))); clause_SetNumOfSuccLits(newClause, (clause_NumOfSuccLits(C1) - 1 + clause_NumOfSuccLits(C2))); for (m = clause_FirstLitIndex(); m <= lc; m++) clause_SetLiteral(newClause, m, clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau, term_Copy(clause_GetLiteralTerm(C1, m)))), newClause)); /* help = number of literals to leave empty */ help = clause_NumOfConsLits(C2); for ( ; m <= la; m++) clause_SetLiteral(newClause, (m + help), clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau, term_Copy(clause_GetLiteralTerm(C1, m)))), newClause)); /* help = number of literals to leave empty */ help += clause_NumOfAnteLits(C2); for ( ; m <= ls; m++) { if (m != i) /* The literal used in the inference isn't copied */ clause_SetLiteral(newClause, (m + help), clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau, term_Copy(clause_GetLiteralTerm(C1, m)))),newClause)); else /* the index has to be decreased to avoid an empty literal! */ help--; } /* Now we consider the PartnerClause : */ /* help = number of already set constraint (Clause) literals */ help = clause_NumOfConsLits(C1); for (m = clause_FirstLitIndex(); m <= plc; m++) clause_SetLiteral(newClause, (m + help), clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau, term_Copy(clause_GetLiteralTerm(C2, m)))),newClause)); /* help = number of already set constraint and antecedent Given-literals */ help += clause_NumOfAnteLits(C1); for ( ; m <= pla; m++) clause_SetLiteral(newClause, (m + help), clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau, term_Copy(clause_GetLiteralTerm(C2, m)))),newClause)); /* help = number of already set literals */ help += clause_NumOfSuccLits(C1) - 1; /*help = clause_Length(Clause) - 1;*/ u_sigma = subst_Apply(rho, term_Copy(u_tau)); for ( ; m <= pls; m++) { TERM newAtom; if (m == j) { /* The first partner literal is modified appropriately! */ TERM right; if (v == s2) /* Necessary because term_ReplaceSubtermBy doesn't treat top level */ right = term_Copy(t); else { right = term_Copy(v); term_ReplaceSubtermBy(right, s2, t); } newAtom = term_Create(fol_Equality(), list_Cons(term_Copy(u_sigma), list_List(subst_Apply(rho, subst_Apply(tau, right))))); } else if (m == k) { /* The second partner lit is modified appropriately! */ newAtom = term_Create(fol_Equality(), list_Cons(term_Copy(u_sigma), list_List(term_Copy(v2_sigma)))); } else { /* Apply substitutions to all other literals */ newAtom = subst_Apply(rho, subst_Apply(tau, term_Copy(clause_GetLiteralTerm(C2, m)))); } clause_SetLiteral(newClause, (m + help), clause_LiteralCreate(newAtom, newClause)); } term_Delete(u_sigma); clause_SetFromMergingParamodulation(newClause); clause_AddParentClause(newClause, clause_Number(C2)); clause_AddParentLiteral(newClause, k); clause_SetDataFromParents(newClause, C2, j, C1, k, Flags, Precedence); return list_List(newClause); } static LIST inf_Lit2MParamod(CLAUSE C1, CLAUSE C2, int i, int j, TERM s, TERM t, TERM s2, TERM v, TERM u_tau, SUBST tau, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: Two clauses, the index of a strict maximal literal in , the index of a strict maximal index in , and are from literal , is a subterm of , is from literal , is with substitution applied, a flag store, and a precedence. must be greater than tau wrt. the ordering. RETURNS: A list of clauses derivable from the given data by merging paramodulation. This function searches for a second positive literal u'=v', where u' is unifiable with . MEMORY: Memory is allocated for the list and the clauses. ***************************************************************/ { LIST result; int k, last; result = list_Nil(); /* Now find the 3rd literal u' = v' in C2 */ last = clause_LastSuccedentLitIndex(C2); /* Last index */ for (k = clause_FirstSuccedentLitIndex(C2); k <= last; k++) { LITERAL partnerLit2 = clause_GetLiteral(C2, k); TERM partnerAtom2 = clause_LiteralSignedAtom(partnerLit2); if (k != j && fol_IsEquality(partnerAtom2)) { /* partnerLit2: u' = v' or v' = u' */ SUBST rho; TERM pLeft2, pRight2, s_sigma, t_sigma, v2_sigma; ord_RESULT ordResult; BOOL checkPassed; pLeft2 = subst_Apply(tau, term_Copy(term_FirstArgument(partnerAtom2))); pRight2 = subst_Apply(tau, term_Copy(term_SecondArgument(partnerAtom2))); /* First try unification with left side */ cont_Check(); if (unify_UnifyCom(cont_LeftContext(), u_tau, pLeft2)) { subst_ExtractUnifierCom(cont_LeftContext(), &rho); s_sigma = t_sigma = (TERM) NULL; checkPassed = TRUE; if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(C1,i))) { s_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(s))); t_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(t))); ordResult = ord_Compare(s_sigma, t_sigma, Flags, Precedence); if (ordResult == ord_SmallerThan() || ordResult == ord_Equal()) checkPassed = FALSE; } if (checkPassed && inf_LiteralsMaxWith2Subst(C1,i,C2,j,rho,tau, Flags, Precedence)) { v2_sigma = subst_Apply(rho, term_Copy(pRight2)); result = list_Nconc(inf_ApplyMParamod(C1,C2,i,j,k,u_tau,v,s2, t,v2_sigma,tau,rho, Flags, Precedence), result); term_Delete(v2_sigma); } /* Now cleanup */ if (s_sigma != NULL) { /* Also t_sigma != NULL */ term_Delete(s_sigma); term_Delete(t_sigma); } subst_Delete(rho); } cont_Reset(); /* Now try unification with right side */ if (unify_UnifyCom(cont_LeftContext(), u_tau, pRight2)) { subst_ExtractUnifierCom(cont_LeftContext(), &rho); s_sigma = t_sigma = (TERM) NULL; checkPassed = TRUE; if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(C1,i))) { s_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(s))); t_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(t))); ordResult = ord_Compare(s_sigma, t_sigma, Flags, Precedence); if (ordResult == ord_SmallerThan() || ordResult == ord_Equal()) checkPassed = FALSE; } if (checkPassed && inf_LiteralsMaxWith2Subst(C1,i,C2,j,rho,tau, Flags, Precedence)) { v2_sigma = subst_Apply(rho, term_Copy(pLeft2)); result = list_Nconc(inf_ApplyMParamod(C1,C2,i,j,k,u_tau,v,s2, t,v2_sigma,tau,rho, Flags, Precedence), result); term_Delete(v2_sigma); } /* Now cleanup */ if (s_sigma != NULL) { /* Also t_sigma != NULL */ term_Delete(s_sigma); term_Delete(t_sigma); } subst_Delete(rho); } cont_Reset(); term_Delete(pLeft2); term_Delete(pRight2); } /* k != j */ } /* for k */ return result; } static LIST inf_LitMParamod(CLAUSE Clause, int i, BOOL Turn, SHARED_INDEX ShIndex, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause with a strict maximal equality literal at position , a boolean value, a shared index, a flag store and a precedence. If is TRUE, the left and right term of the equality are exchanged. RETURNS: A list of clauses derivable from the given clause by merging paramodulation. This function searches a second clause with at least two positive equalities, where the first equation has a subterm s', that is unifiable with the left (or right) side of the given equation. ***************************************************************/ { LIST result, unifiers, literals; LITERAL actLit; TERM s, t, help; actLit = clause_GetLiteral(Clause, i); s = term_FirstArgument(clause_LiteralSignedAtom(actLit)); t = term_SecondArgument(clause_LiteralSignedAtom(actLit)); if (Turn) { /* Exchange s and t */ help = s; s = t; t = help; } result = list_Nil(); unifiers = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), s); for ( ; !list_Empty(unifiers); unifiers = list_Pop(unifiers)) { TERM s2 = (TERM) list_Car(unifiers); /* Unifiable with s */ if (!term_IsVariable(s2) && !term_IsAtom(s2)) { for (literals = sharing_GetDataList(s2, ShIndex); !list_Empty(literals); literals = list_Pop(literals)) { LITERAL partnerLit = (LITERAL) list_Car(literals); /* u = v[s'] */ CLAUSE partnerClause = clause_LiteralOwningClause(partnerLit); TERM partnerAtom = clause_LiteralAtom(partnerLit); int pli = clause_LiteralGetIndex(partnerLit); if (!clause_GetFlag(partnerClause, CLAUSESELECT) && clause_LiteralGetFlag(partnerLit, STRICTMAXIMAL) && clause_LiteralIsPositive(partnerLit) && /* succedent literal */ clause_LiteralIsEquality(partnerLit) && clause_NumOfSuccLits(partnerClause) > 1 && /* > 1 pos. literals */ clause_HasSolvedConstraint(partnerClause)) { TERM partnerLeft = term_FirstArgument(partnerAtom); TERM partnerRight = term_SecondArgument(partnerAtom); BOOL inPartnerRight = term_HasPointerSubterm(partnerRight, s2); if (!clause_LiteralIsOrientedEquality(partnerLit) || inPartnerRight){ /* Don't do this if u=v is oriented and s2 is not a subterm of v */ TERM newPLeft, newPRight; SUBST tau; SYMBOL partnerMaxVar; ord_RESULT ordResult; partnerMaxVar = clause_MaxVar(partnerClause); clause_RenameVarsBiggerThan(Clause, partnerMaxVar); cont_Check(); unify_UnifyNoOC(cont_LeftContext(), s, cont_RightContext(), s2); subst_ExtractUnifierCom(cont_LeftContext(), &tau); cont_Reset(); newPLeft = subst_Apply(tau, term_Copy(partnerLeft)); newPRight = subst_Apply(tau, term_Copy(partnerRight)); if (clause_LiteralIsOrientedEquality(partnerLit)) ordResult = ord_GreaterThan(); else ordResult = ord_Compare(newPLeft, newPRight, Flags, Precedence); if (inPartnerRight && ord_IsGreaterThan(ordResult)) { /* Take a look at right side */ result = list_Nconc(inf_Lit2MParamod(Clause,partnerClause,i,pli, s, t,s2,partnerRight,newPLeft, tau, Flags, Precedence), result); } if (ord_IsSmallerThan(ordResult) && (!inPartnerRight || term_HasPointerSubterm(partnerLeft, s2))) { /* If s2 is not in partnerRight, it MUST be in partnerLeft, else really do the test */ /* Take a look at left side */ result = list_Nconc(inf_Lit2MParamod(Clause,partnerClause,i,pli, s,t,s2,partnerLeft,newPRight, tau,Flags, Precedence), result); } term_Delete(newPLeft); term_Delete(newPRight); subst_Delete(tau); } } } /* for all Literals containing s2 */ } /* if s2 isn't a variable */ } /* for all unifiers s2 */ return result; } static LIST inf_MParamodLitToGiven(CLAUSE Clause, int j, BOOL Turn, SHARED_INDEX ShIndex, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause with a strict maximal equality literal at position , a boolean value, a shared index a flag store and a precedence. If is TRUE, the left and right term of the equality are exchanged. RETURNS: A list of clauses derivable from the given clause by merging paramodulation with this literal as second literal of the rule. ***************************************************************/ { LIST result, unifiers, superterms, literals; LITERAL actLit; TERM u, v; int bottom; if (clause_NumOfSuccLits(Clause) < 2) return list_Nil(); /* There must be at least two positive literals */ actLit = clause_GetLiteral(Clause, j); u = term_FirstArgument(clause_LiteralSignedAtom(actLit)); v = term_SecondArgument(clause_LiteralSignedAtom(actLit)); if (Turn) { /* Exchange s and t */ TERM help = u; u = v; v = help; } result = list_Nil(); bottom = stack_Bottom(); sharing_PushReverseOnStack(v); /* Without variables! */ while (!stack_Empty(bottom)) { TERM s2 = (TERM) stack_PopResult(); for (unifiers = st_GetUnifier(cont_LeftContext(),sharing_Index(ShIndex), cont_RightContext(), s2); !list_Empty(unifiers); unifiers = list_Pop(unifiers)) { TERM s = (TERM) list_Car(unifiers); for (superterms = term_SupertermList(s); !list_Empty(superterms); superterms = list_Cdr(superterms)) { TERM partnerAtom = (TERM) list_Car(superterms); if (fol_IsEquality(partnerAtom)) { for (literals = sharing_NAtomDataList(partnerAtom); !list_Empty(literals); literals = list_Cdr(literals)) { LITERAL partnerLit = (LITERAL) list_Car(literals); CLAUSE partnerClause = clause_LiteralOwningClause(partnerLit); int i = clause_LiteralGetIndex(partnerLit); if (!clause_GetFlag(partnerClause,CLAUSESELECT) && clause_LiteralGetFlag(partnerLit,STRICTMAXIMAL) && clause_LiteralIsPositive(partnerLit) && (s == term_FirstArgument(partnerAtom) || !clause_LiteralIsOrientedEquality(partnerLit)) && clause_HasSolvedConstraint(partnerClause) && clause_Number(partnerClause) != clause_Number(Clause)) { /* We don't allow self inferences (both clauses having the */ /* same number) here, because they're already made in function */ /* inf_LitMParamod. */ SYMBOL partnerMaxVar; SUBST tau; TERM u_tau, v_tau; BOOL checkPassed; partnerMaxVar = clause_MaxVar(partnerClause); clause_RenameVarsBiggerThan(Clause, partnerMaxVar); cont_Check(); unify_UnifyNoOC(cont_LeftContext(), s, cont_RightContext(), s2); subst_ExtractUnifierCom(cont_LeftContext(), &tau); cont_Reset(); u_tau = v_tau = (TERM) NULL; checkPassed = TRUE; /* u_tau must be greater than v_tau */ if (!clause_LiteralIsOrientedEquality(actLit)) { u_tau = subst_Apply(tau, term_Copy(u)); v_tau = subst_Apply(tau, term_Copy(v)); if (ord_Compare(u_tau, v_tau, Flags, Precedence) != ord_GreaterThan()) checkPassed = FALSE; } if (checkPassed) { /* u_tau > v_tau */ TERM t; if (s == term_FirstArgument(partnerAtom)) t = term_SecondArgument(partnerAtom); else t = term_FirstArgument(partnerAtom); if (u_tau == (TERM)NULL) { u_tau = subst_Apply(tau, term_Copy(u)); v_tau = subst_Apply(tau, term_Copy(v)); } result = list_Nconc(inf_Lit2MParamod(partnerClause,Clause,i,j, s,t,s2,v,u_tau, tau,Flags, Precedence), result); } /* Now cleanup */ if (u_tau != (TERM)NULL) { term_Delete(u_tau); term_Delete(v_tau); } subst_Delete(tau); clause_Normalize(Clause); } } } /* partnerAtom is equality */ } } } return result; } LIST inf_MergingParamodulation(CLAUSE GivenClause, SHARED_INDEX ShIndex, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause, a shared index, a flag store and a precedence. RETURNS: A list of clauses derivable from the given clause by merging paramodulation. MEMORY: Memory is allocated for the list and the clauses. ***************************************************************/ { LIST result; CLAUSE copy; int last, i; #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_MergingParamodulation: Illegal input."); misc_FinishErrorReport(); } #endif if (clause_GetFlag(GivenClause, CLAUSESELECT) || clause_HasEmptySuccedent(GivenClause) || !clause_HasSolvedConstraint(GivenClause)) return list_Nil(); result = list_Nil(); copy = clause_Copy(GivenClause); last = clause_LastSuccedentLitIndex(copy); for (i = clause_FirstSuccedentLitIndex(copy); i <= last; i++) { LITERAL actLit = clause_GetLiteral(copy, i); TERM atom = clause_LiteralSignedAtom(actLit); if (clause_LiteralGetFlag(actLit, STRICTMAXIMAL) && fol_IsEquality(atom)) { result = list_Nconc(inf_LitMParamod(copy,i,FALSE,ShIndex, Flags, Precedence), result); /* Assume GivenClause is the second clause of the rule */ result = list_Nconc(inf_MParamodLitToGiven(copy,i,FALSE,ShIndex, Flags, Precedence), result); if (!clause_LiteralIsOrientedEquality(actLit)) { /* First check rule with left and right side exchanged */ result = list_Nconc(inf_LitMParamod(copy, i, TRUE, ShIndex, Flags, Precedence), result); /* Now assume GivenClause is the second clause of the rule */ /* Check with sides exchanged */ result = list_Nconc(inf_MParamodLitToGiven(copy,i,TRUE,ShIndex, Flags, Precedence), result); } } } /* for */ clause_Delete(copy); return result; } static CLAUSE inf_ApplyGenRes(LITERAL PosLit, LITERAL NegLit, SUBST SubstTermS, SUBST SubstPartnerTermS, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause to use for Resolution, the index of a positive non-equality literal, a unifiable literal, the substitutions for the terms to unify, a flag store and a precedence. RETURNS: A clause derivable from the literals owning clause by Resolution wrt. the Index. MEMORY: Memory for the new clause is allocated. ***************************************************************/ { CLAUSE NewClause, GivenClause, PartnerClause; int i,j,lc,la,ls,pi,pls,pla,plc,help,ConNeg,AntNeg; /* p=Partner,l=last */ PartnerClause = clause_LiteralOwningClause(NegLit); GivenClause = clause_LiteralOwningClause(PosLit); pls = clause_LastSuccedentLitIndex(PartnerClause); pla = clause_LastAntecedentLitIndex(PartnerClause); plc = clause_LastConstraintLitIndex(PartnerClause); pi = clause_LiteralGetIndex(NegLit); ls = clause_LastSuccedentLitIndex(GivenClause); la = clause_LastAntecedentLitIndex(GivenClause); lc = clause_LastConstraintLitIndex(GivenClause); i = clause_LiteralGetIndex(PosLit); if (pi <= plc) { ConNeg = 1; AntNeg = 0; } else { ConNeg = 0; AntNeg = 1; } NewClause = clause_CreateBody((clause_Length(GivenClause) -1) + clause_Length(PartnerClause) -1); clause_SetNumOfConsLits(NewClause, (clause_NumOfConsLits(GivenClause) + (clause_NumOfConsLits(PartnerClause)-ConNeg))); clause_SetNumOfAnteLits(NewClause, (clause_NumOfAnteLits(GivenClause) + (clause_NumOfAnteLits(PartnerClause)-AntNeg))); clause_SetNumOfSuccLits(NewClause, ((clause_NumOfSuccLits(GivenClause) -1)+ clause_NumOfSuccLits(PartnerClause))); /* First set the literals from the GivenClause : */ for (j = clause_FirstLitIndex(); j <= lc; j++) { clause_SetLiteral(NewClause, j, clause_LiteralCreate(subst_Apply(SubstTermS, term_Copy(clause_GetLiteralTerm(GivenClause, j))),NewClause)); } /* help = number of literals to leave empty */ help = clause_NumOfConsLits(PartnerClause)-ConNeg; for ( ; j <= la; j++) { clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(subst_Apply(SubstTermS, term_Copy(clause_GetLiteralTerm(GivenClause, j))),NewClause)); } /* help = number of literals to leave empty */ help += clause_NumOfAnteLits(PartnerClause)-AntNeg; for ( ; j <= ls; j++) { if (j != i) { /* The ActLit isn't copied! */ clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(subst_Apply(SubstTermS, term_Copy(clause_GetLiteralTerm(GivenClause, j))),NewClause)); } else { /*the index has to be decreased to avoid an empty literal! */ help--; } } /* Now we consider the PartnerClause : */ /* help = number of already set constraint (GivenClause-) literals */ help = clause_NumOfConsLits(GivenClause); for (j = clause_FirstLitIndex(); j <= plc; j++) { if (j != pi) { clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(subst_Apply(SubstPartnerTermS, term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause)); } else { help--; } } /* help = number of already set constraint and antecedent Given-literals */ help += clause_NumOfAnteLits(GivenClause); for ( ; j <= pla; j++) { if (j != pi) { /* The NegLit isn't copied! */ clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(subst_Apply(SubstPartnerTermS, term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause)); } else { /* The index has to be shifted as above. */ help--; } } /* help = number of already set (GivenClause-) literals */ help += clause_NumOfSuccLits(GivenClause) - 1; for ( ; j <= pls; j++) { clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(subst_Apply(SubstPartnerTermS, term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause)); } /* end of NewClause creation (last for loop). */ clause_SetDataFromParents(NewClause,PartnerClause,pi,GivenClause,i, Flags, Precedence); clause_SetFromGeneralResolution(NewClause); return(NewClause); } LIST inf_GeneralResolution(CLAUSE GivenClause, SHARED_INDEX ShIndex, BOOL Ordered, BOOL Equations, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause and an Index, usually the WorkedOffIndex, two boolean flags, a flag store and a precedence. RETURNS: A list of clauses derivable from the GivenClause by GeneralResolution wrt. the Index. If =TRUE, this function generates ordered resolution inferences (the literals must be selected or (strict) maximal), otherwise it generates standard resolution inferences. If =TRUE, equations are allowed for inferences, else no inferences with equations are generated. The default is =FALSE.. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { CLAUSE GivenCopy; LIST Result; LITERAL ActLit; TERM Atom; int i,n; #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GeneralResolution: Illegal input."); misc_FinishErrorReport(); } #endif if (!clause_HasSolvedConstraint(GivenClause)) return list_Nil(); Result = list_Nil(); GivenCopy = clause_Copy(GivenClause); if (clause_GetFlag(GivenCopy,CLAUSESELECT)) n = clause_LastAntecedentLitIndex(GivenCopy); else n = clause_LastSuccedentLitIndex(GivenCopy); for (i = clause_FirstAntecedentLitIndex(GivenCopy); i <= n; i++) { ActLit = clause_GetLiteral(GivenCopy, i); Atom = clause_LiteralAtom(ActLit); if ((Equations || !fol_IsEquality(Atom)) && (clause_LiteralGetFlag(ActLit,LITSELECT) || (!clause_GetFlag(GivenCopy,CLAUSESELECT) && (!Ordered || clause_LiteralIsMaximal(ActLit)))) && (!Ordered || clause_LiteralIsFromAntecedent(ActLit) || clause_LiteralGetFlag(ActLit,STRICTMAXIMAL))) { /* Positive literals must be strict maximal for ORe, */ /* negative literals must be either selected or maximal. */ LIST TermList; BOOL Swapped; Swapped = FALSE; /* The 'endless' loop may run twice for equations, once for other atoms */ while (TRUE) { TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Atom); for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) { LIST LitList; TERM PartnerAtom; PartnerAtom = list_First(TermList); if (!term_IsVariable(PartnerAtom)) { LITERAL PartnerLit; int j; CLAUSE PartnerClause; for (LitList = sharing_NAtomDataList(PartnerAtom); !list_Empty(LitList); LitList = list_Cdr(LitList)) { PartnerLit = list_Car(LitList); j = clause_LiteralGetIndex(PartnerLit); PartnerClause = clause_LiteralOwningClause(PartnerLit); if (clause_LiteralsAreComplementary(PartnerLit,ActLit) && clause_HasSolvedConstraint(PartnerClause) && /* Negative literals must be from the antecedent */ (clause_LiteralIsPositive(PartnerLit) || clause_LiteralIsFromAntecedent(PartnerLit)) && /* Check whether literal is selected or maximal */ (clause_LiteralGetFlag(PartnerLit,LITSELECT) || (!clause_GetFlag(PartnerClause,CLAUSESELECT) && (!Ordered || clause_LiteralIsMaximal(PartnerLit)))) && /* Positive literals must be strict maximal for ORe */ (!Ordered || clause_LiteralIsNegative(PartnerLit) || clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) && /* Avoid duplicate self-inferences */ (clause_LiteralIsPositive(PartnerLit) || clause_Number(GivenClause) != clause_Number(PartnerClause))) { SUBST Subst, PartnerSubst; SYMBOL MaxVar; MaxVar = clause_MaxVar(PartnerClause); clause_RenameVarsBiggerThan(GivenCopy, MaxVar); cont_Check(); if (!unify_UnifyNoOC(cont_LeftContext(), Atom, cont_RightContext(), PartnerAtom)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GeneralResolution: Unification failed."); misc_FinishErrorReport(); } subst_ExtractUnifier(cont_LeftContext(), &Subst, cont_RightContext(), &PartnerSubst); cont_Reset(); if (!Ordered || inf_LiteralsMax(GivenCopy, i, Subst, PartnerClause, j, PartnerSubst, Flags, Precedence)) { if (clause_LiteralIsNegative(PartnerLit)) Result = list_Cons(inf_ApplyGenRes(ActLit,PartnerLit,Subst, PartnerSubst, Flags, Precedence), Result); else Result = list_Cons(inf_ApplyGenRes(PartnerLit, ActLit, PartnerSubst,Subst, Flags, Precedence), Result); } subst_Delete(Subst); subst_Delete(PartnerSubst); } } /* end of for (LitList = sharing_NAtomDataList ...). */ } /* end of if (!term_IsVariable(PartnerAtom)). */ } /* end of for (TermList = st_GetUnifier...). */ if (!Swapped && fol_IsEquality(Atom)) { term_EqualitySwap(Atom); /* Atom is from copied clause */ Swapped = TRUE; } else break; } /* end of 'endless' loop */ } /* end of if (clause_LiteralIsMaximal(ActLit)). */ } /* end of for 'all antecedent and succedent literals'. */ clause_Delete(GivenCopy); return Result; } LIST inf_UnitResolution(CLAUSE GivenClause, SHARED_INDEX ShIndex, BOOL Equations, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause and an Index, usually the WorkedOffIndex, a boolean flag, a flag store and a precedence. RETURNS: A list of clauses derivable from the Givenclause by Unit Resolution wrt. the Index. This function does the same inferences as standard resolution, except that at least one of the clauses must be a unit clause. The involved literals don't have to be maximal. If =TRUE, equations are allowed for inferences, else no inferences with equations are made. The default is =FALSE.. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { CLAUSE GivenCopy; LIST Result; LITERAL ActLit; TERM Atom; BOOL GivenIsUnit; int i,n; #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_UnitResolution: Illegal input."); misc_FinishErrorReport(); } #endif if (!clause_HasSolvedConstraint(GivenClause)) return list_Nil(); Result = list_Nil(); GivenCopy = clause_Copy(GivenClause); GivenIsUnit = (clause_Length(GivenCopy) == 1); if (clause_GetFlag(GivenCopy,CLAUSESELECT)) n = clause_LastAntecedentLitIndex(GivenCopy); else n = clause_LastSuccedentLitIndex(GivenCopy); for (i=clause_FirstAntecedentLitIndex(GivenCopy); i <= n; i++) { ActLit = clause_GetLiteral(GivenCopy, i); Atom = clause_LiteralAtom(ActLit); if ((Equations || !fol_IsEquality(Atom)) && (clause_LiteralGetFlag(ActLit,LITSELECT) || !clause_GetFlag(GivenCopy,CLAUSESELECT))) { LIST TermList; BOOL Swapped; Swapped = FALSE; /* The 'endless' loop runs twice for equations, once for other atoms */ while (TRUE) { TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Atom); for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) { LIST LitList; TERM PartnerAtom; PartnerAtom = list_First(TermList); if (!term_IsVariable(PartnerAtom)) { LITERAL PartnerLit; CLAUSE PartnerClause; for (LitList = sharing_NAtomDataList(PartnerAtom); !list_Empty(LitList); LitList = list_Cdr(LitList)) { PartnerLit = list_Car(LitList); PartnerClause = clause_LiteralOwningClause(PartnerLit); if ((GivenIsUnit || clause_Length(PartnerClause) == 1) && clause_LiteralsAreComplementary(PartnerLit,ActLit) && clause_HasSolvedConstraint(PartnerClause) && /* Negative literals must be from the antecedent */ (clause_LiteralIsPositive(PartnerLit) || clause_LiteralIsFromAntecedent(PartnerLit)) && /* Either the literal is selected or no literal is selected */ (clause_LiteralGetFlag(PartnerLit,LITSELECT) || !clause_GetFlag(PartnerClause,CLAUSESELECT))) { /* Self-inferences aren't possible, since then the clause must */ /* be a unit and a single literal can't be both positive and */ /* negative. */ SUBST Subst, PartnerSubst; SYMBOL MaxVar; MaxVar = clause_MaxVar(PartnerClause); clause_RenameVarsBiggerThan(GivenCopy, MaxVar); cont_Check(); if (!unify_UnifyNoOC(cont_LeftContext(), Atom, cont_RightContext(), PartnerAtom)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_UnitResolution: Unification failed."); misc_FinishErrorReport(); } subst_ExtractUnifier(cont_LeftContext(), &Subst, cont_RightContext(), &PartnerSubst); cont_Reset(); if (clause_LiteralIsNegative(PartnerLit)) Result = list_Cons(inf_ApplyGenRes(ActLit, PartnerLit, Subst, PartnerSubst, Flags, Precedence), Result); else Result = list_Cons(inf_ApplyGenRes(PartnerLit, ActLit, PartnerSubst,Subst, Flags, Precedence), Result); subst_Delete(Subst); subst_Delete(PartnerSubst); } } /* end of for (LitList = sharing_NAtomDataList ...). */ } /* end of if (!term_IsVariable(PartnerAtom)). */ } /* end of for (TermList = st_GetUnifier...). */ if (!Swapped && fol_IsEquality(Atom)) { term_EqualitySwap(Atom); /* Atom is from copied clause */ Swapped = TRUE; } else break; } /* end of 'endless' loop */ } /* end of if (clause_LiteralIsMaximal(ActLit)). */ } /* end of for 'all antecedent and succedent literals'. */ clause_Delete(GivenCopy); return Result; } LIST inf_BoundedDepthUnitResolution(CLAUSE GivenClause, SHARED_INDEX ShIndex, BOOL ConClause, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause and an Index, usually the WorkedOffIndex, a flag indicating whether the partner clause must be a conjecture clause, a flag store and a precedence. RETURNS: A list of clauses derivable from the Givenclause by bounded depth unit resolution wrt. the Index. This acts similar to inf_UnitResolution, except that it limits the depth of resolvents to the maximum depth of its parent clauses. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ /* GivenClause is always a CONCLAUSE */ { CLAUSE GivenCopy; LIST Result; LITERAL ActLit; TERM Atom; int i,n,depth; #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_BoundedDepthUnitResolution: Illegal input."); misc_FinishErrorReport(); } cont_Check(); #endif Result = list_Nil(); GivenCopy = clause_Copy(GivenClause); n = clause_LastLitIndex(GivenCopy); depth = clause_ComputeTermDepth(GivenCopy); for (i = clause_FirstLitIndex(); i <= n; i++) { LIST TermList; BOOL Swapped; ActLit = clause_GetLiteral(GivenCopy, i); Atom = clause_LiteralAtom(ActLit); Swapped = FALSE; /* The 'endless' loop runs twice for equations, once for other atoms */ while (TRUE) { TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Atom); for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) { LIST LitList; TERM PartnerAtom; PartnerAtom = list_First(TermList); if (!term_IsVariable(PartnerAtom)) { LITERAL PartnerLit; CLAUSE PartnerClause; for (LitList = sharing_NAtomDataList(PartnerAtom); !list_Empty(LitList); LitList = list_Cdr(LitList)) { PartnerLit = list_Car(LitList); PartnerClause = clause_LiteralOwningClause(PartnerLit); if (clause_LiteralsAreComplementary(PartnerLit,ActLit) && (clause_Length(GivenCopy)==1 || clause_Length(PartnerClause)==1) && (clause_GetFlag(GivenCopy,CONCLAUSE) || clause_GetFlag(PartnerClause,CONCLAUSE)) && (!ConClause || clause_GetFlag(PartnerClause,CONCLAUSE))) { SUBST Subst, PartnerSubst; SYMBOL MaxVar; int maxdepth; CLAUSE Resolvent; maxdepth = misc_Max(depth, clause_ComputeTermDepth(PartnerClause)); MaxVar = clause_MaxVar(PartnerClause); clause_RenameVarsBiggerThan(GivenCopy, MaxVar); cont_Check(); if (!unify_UnifyNoOC(cont_LeftContext(), Atom, cont_RightContext(), PartnerAtom)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_BoundedDepthUnitResolution: Unification failed."); misc_FinishErrorReport(); } subst_ExtractUnifier(cont_LeftContext(), &Subst, cont_RightContext(), &PartnerSubst); cont_Reset(); if (clause_LiteralIsNegative(PartnerLit)) Resolvent = inf_ApplyGenRes(ActLit, PartnerLit, Subst, PartnerSubst, Flags, Precedence); else Resolvent = inf_ApplyGenRes(PartnerLit, ActLit, PartnerSubst, Subst, Flags, Precedence); if (clause_ComputeTermDepth(Resolvent) > maxdepth) clause_Delete(Resolvent); else { Result = list_Cons(Resolvent,Result); } subst_Delete(Subst); subst_Delete(PartnerSubst); } } } } if (!Swapped && fol_IsEquality(Atom)) { term_EqualitySwap(Atom); /* Given Clause is a copy */ Swapped = TRUE; } else break; } /* end of 'endless' loop */ } clause_Delete(GivenCopy); return(Result); } static CLAUSE inf_ApplyGeneralFactoring(CLAUSE Clause, NAT i, NAT j, SUBST Subst, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause an index in the clause, a substitution a flag store and a precedence. RETURNS: A new clause obtained from by applying and deleting literal keeping literal ***************************************************************/ { CLAUSE NewClause; NewClause = clause_Copy(Clause); clause_ClearFlags(NewClause); clause_SubstApply(Subst, NewClause); clause_DeleteLiteral(NewClause, i, Flags, Precedence); list_Delete(clause_ParentClauses(NewClause)); list_Delete(clause_ParentLiterals(NewClause)); clause_SetParentLiterals(NewClause,list_Nil()); clause_SetParentClauses(NewClause,list_Nil()); clause_SetDataFromFather(NewClause, Clause, j, Flags, Precedence); clause_SetFromGeneralFactoring(NewClause); clause_AddParentClause(NewClause, clause_Number(Clause)); clause_AddParentLiteral(NewClause, i); clause_NewNumber(NewClause); return NewClause; } LIST inf_GeneralFactoring(CLAUSE GivenClause, BOOL Ordered, BOOL Left, BOOL Equations, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause, three boolean flags, a flag store and a precedence. If =TRUE, this function generates ordered factoring inferences, otherwise standard factoring inferences. If is FALSE, this function only makes factoring right inferences, otherwise it also makes factoring left inferences. If =TRUE, equations are allowed for inferences, else no inferences with equations are generated. The default is =TRUE. RETURNS: A list of clauses derivable from by GF. ***************************************************************/ { LIST Result; LITERAL ActLit; int i,j,last; #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GeneralFactoring: Illegal input."); misc_FinishErrorReport(); } #endif if (!clause_HasSolvedConstraint(GivenClause)) return list_Nil(); Result = list_Nil(); /* Always try Factoring Right inferences */ last = clause_LastSuccedentLitIndex(GivenClause); if (!clause_GetFlag(GivenClause,CLAUSESELECT)) { for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= last; i++) { ActLit = clause_GetLiteral(GivenClause, i); if ((!Ordered || clause_LiteralIsMaximal(ActLit)) && (Equations || !clause_LiteralIsEquality(ActLit))) { TERM Atom, PartnerAtom; LITERAL PartnerLit; Atom = clause_LiteralAtom(ActLit); for (j = clause_FirstSuccedentLitIndex(GivenClause); j <= last; j++) { if (i != j) { PartnerLit = clause_GetLiteral(GivenClause, j); PartnerAtom = clause_LiteralAtom(PartnerLit); if ((j>i ||(Ordered && !clause_LiteralIsMaximal(PartnerLit))) && term_EqualTopSymbols(Atom, PartnerAtom)) { /* This condition avoids duplicate inferences */ cont_Check(); if (unify_UnifyCom(cont_LeftContext(), Atom, PartnerAtom)) { SUBST mgu; subst_ExtractUnifierCom(cont_LeftContext(), &mgu); if (!Ordered || inf_LitMax(GivenClause,i,j,mgu,FALSE, Flags, Precedence)) Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j, mgu,Flags, Precedence), Result); subst_Delete(mgu); } cont_Reset(); if (fol_IsEquality(Atom) && /* PartnerAtom is equality, too */ unify_UnifyCom(cont_LeftContext(), term_SecondArgument(Atom), term_FirstArgument(PartnerAtom)) && unify_UnifyCom(cont_LeftContext(), term_FirstArgument(Atom), term_SecondArgument(PartnerAtom))) { SUBST mgu; subst_ExtractUnifierCom(cont_LeftContext(), &mgu); if (!Ordered || inf_LitMax(GivenClause,i,j,mgu,FALSE, Flags, Precedence)) Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j, mgu,Flags, Precedence), Result); subst_Delete(mgu); } cont_Reset(); } } } } } } /* Try Factoring Left inferences only if ==TRUE */ if (Left) { last = clause_LastAntecedentLitIndex(GivenClause); for (i = clause_FirstAntecedentLitIndex(GivenClause); i <= last; i++) { ActLit = clause_GetLiteral(GivenClause, i); if ((Equations || !clause_LiteralIsEquality(ActLit)) && (clause_LiteralGetFlag(ActLit,LITSELECT) || (!clause_GetFlag(GivenClause,CLAUSESELECT) && (!Ordered || clause_LiteralIsMaximal(ActLit))))) { TERM Atom, PartnerAtom; LITERAL PartnerLit; Atom = clause_LiteralAtom(ActLit); for (j = clause_FirstAntecedentLitIndex(GivenClause);j <= last; j++) { if (i != j) { PartnerLit = clause_GetLiteral(GivenClause, j); PartnerAtom = clause_LiteralAtom(PartnerLit); /* In order to avoid duplicate inferences, we do the following */ /* somewhat "tricky" test. What we want is something like */ /* "if (j>i || j wasn't considered within the outer loop) {...} */ /* This lengthy condition can be transformed into the following */ /* condition, because only one negative literal is selected. */ /* This implies that the literal at index j can't be selected. */ if ((j>i || clause_LiteralGetFlag(ActLit,LITSELECT) || (Ordered && !clause_LiteralIsMaximal(PartnerLit))) && term_EqualTopSymbols(Atom, PartnerAtom)) { PartnerAtom = clause_LiteralAtom(PartnerLit); cont_Check(); if (unify_UnifyCom(cont_LeftContext(), Atom, PartnerAtom)) { SUBST mgu; subst_ExtractUnifierCom(cont_LeftContext(), &mgu); if (!Ordered || clause_LiteralGetFlag(ActLit,LITSELECT) || inf_LitMax(GivenClause,i,j,mgu,FALSE,Flags, Precedence)) Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j, mgu,Flags, Precedence), Result); subst_Delete(mgu); } cont_Reset(); if (fol_IsEquality(Atom) && /* PartnerAtom is equality, too */ unify_UnifyCom(cont_LeftContext(), term_SecondArgument(Atom), term_FirstArgument(PartnerAtom)) && unify_UnifyCom(cont_LeftContext(), term_FirstArgument(Atom), term_SecondArgument(PartnerAtom))) { SUBST mgu; subst_ExtractUnifierCom(cont_LeftContext(), &mgu); if (!Ordered || clause_LiteralGetFlag(ActLit,LITSELECT) || inf_LitMax(GivenClause,i,j,mgu,FALSE,Flags, Precedence)) Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j, mgu,Flags, Precedence), Result); subst_Delete(mgu); } cont_Reset(); } } } } } } cont_Check(); return Result; } /***************************************************************/ /* START of code for new Superposition Left rule */ /***************************************************************/ static LIST inf_GenLitSPLeft(CLAUSE Clause, TERM Left, TERM Right, int i, SHARED_INDEX ShIndex,BOOL OrdPara, BOOL MaxPara, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause (unshared) with a positive equality literal at position where and are the arguments of just that literal, two boolean flags, a flag store and a precedence. For Ordered Paramodulation and Superposition mustn't be greater wrt. the ordering than . For Superposition the literal must be strictly maximal. RETURNS: A list of clauses derivable with the literals owning clause by Superposition Left wrt. the Index. MEMORY: The list of clauses is extended, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result, Terms; #ifdef CHECK if (clause_GetFlag(Clause, CLAUSESELECT) || (OrdPara && clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)) && Left == term_SecondArgument(clause_GetLiteralAtom(Clause,i))) || (MaxPara && !clause_LiteralGetFlag(clause_GetLiteral(Clause,i), STRICTMAXIMAL))) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenLitSPLeft: Illegal input."); misc_FinishErrorReport(); } #endif Result = list_Nil(); Terms = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Left); for ( ; !list_Empty(Terms); Terms = list_Pop(Terms)) { LIST Lits; TERM Term; Term = (TERM)list_First(Terms); if (!term_IsVariable(Term) && !symbol_IsPredicate(term_TopSymbol(Term))) { Lits = sharing_GetDataList(Term, ShIndex); for ( ; !list_Empty(Lits); Lits = list_Pop(Lits)){ LITERAL PartnerLit; TERM PartnerAtom; CLAUSE PartnerClause; int pli; PartnerLit = (LITERAL)list_Car(Lits); /* Antecedent Literal ! */ PartnerAtom = clause_LiteralAtom(PartnerLit); pli = clause_LiteralGetIndex(PartnerLit); PartnerClause = clause_LiteralOwningClause(PartnerLit); if ((clause_LiteralGetFlag(PartnerLit,LITSELECT) || (!clause_GetFlag(PartnerClause,CLAUSESELECT) && (!MaxPara || clause_LiteralIsMaximal(PartnerLit)))) && clause_LiteralIsNegative(PartnerLit) && !clause_GetFlag(PartnerClause,NOPARAINTO) && clause_HasSolvedConstraint(PartnerClause)) { /* If has a solved constraint and */ /* is negative then is from the antecedent. */ SUBST Subst, PartnerSubst; TERM NewLeft,NewRight; SYMBOL PartnerMaxVar; TERM SupAtom; SupAtom = (TERM)NULL; PartnerMaxVar = clause_MaxVar(PartnerClause); NewLeft = Left; clause_RenameVarsBiggerThan(Clause, PartnerMaxVar); cont_Check(); unify_UnifyNoOC(cont_LeftContext(), Left, cont_RightContext(), Term); subst_ExtractUnifier(cont_LeftContext(), &Subst, cont_RightContext(), &PartnerSubst); cont_Reset(); if (!MaxPara || inf_LiteralsMax(Clause, i, Subst, PartnerClause, pli, PartnerSubst, Flags, Precedence)) { NewRight = subst_Apply(Subst, term_Copy(Right)); if (OrdPara && !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i))) NewLeft = subst_Apply(Subst, term_Copy(Left)); if (!OrdPara || NewLeft == Left || ord_Compare(NewLeft,NewRight,Flags, Precedence) != ord_SmallerThan()) { if (!MaxPara || clause_LiteralIsPredicate(PartnerLit)) { SupAtom = inf_AllTermsRplac(PartnerAtom,Term,NewRight, PartnerSubst); } else { /* Superposition and is equality */ if (clause_LiteralIsOrientedEquality(PartnerLit)) SupAtom = inf_AllTermsLeftRplac(PartnerAtom,Term,NewRight, PartnerSubst); else { TERM NewPartnerLeft,NewPartnerRight; NewPartnerLeft = subst_Apply(PartnerSubst, term_Copy(term_FirstArgument(PartnerAtom))); NewPartnerRight = subst_Apply(PartnerSubst, term_Copy(term_SecondArgument(PartnerAtom))); switch (ord_Compare(NewPartnerLeft,NewPartnerRight, Flags, Precedence)) { case ord_SMALLER_THAN: SupAtom = inf_AllTermsRightRplac(PartnerAtom,Term, NewRight,PartnerSubst); break; case ord_GREATER_THAN: SupAtom = inf_AllTermsLeftRplac(PartnerAtom,Term, NewRight,PartnerSubst); break; default: SupAtom = inf_AllTermsRplac(PartnerAtom,Term, NewRight,PartnerSubst); } term_Delete(NewPartnerLeft); term_Delete(NewPartnerRight); } } if (SupAtom != NULL) Result = list_Cons(inf_ApplyGenSuperposition(Clause, i, Subst, PartnerClause, pli, PartnerSubst, SupAtom, FALSE, OrdPara, MaxPara, Flags, Precedence), Result); } if (NewLeft != Left) term_Delete(NewLeft); term_Delete(NewRight); } subst_Delete(Subst); subst_Delete(PartnerSubst); } } } } return Result; } static LIST inf_GenSPLeftEqToGiven(CLAUSE Clause, int i, BOOL Left, SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara, BOOL Unit, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: An unshared clause, the index of an antecedent literal that is an equality literal, a boolean value, a shared index, three boolean flags controlling inference preconditions, a flag store and a precedence. If Left==TRUE then the left argument of the literal is used otherwise the right argument. OrdPara and MaxPara control inference conditions. If ==TRUE the clause with the maximal, positive equality must be a unit clause. RETURNS: A list of clauses derivable from generalized superposition Left on the GivenCopy wrt. the Index. See GenSuperpositionLeft for effects of OrdPara and MaxPara MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result, TermList, ParentList; int Bottom; LITERAL Lit; TERM Atom, Term, PartnerTerm, PartnerEq; Result = list_Nil(); Lit = clause_GetLiteral(Clause,i); /* Is an antecedent Literal ! */ Atom = clause_LiteralAtom(Lit); #ifdef CHECK if (clause_GetFlag(Clause, NOPARAINTO) || !clause_LiteralIsEquality(Lit) || !clause_LiteralIsFromAntecedent(Lit) || (MaxPara && clause_LiteralIsOrientedEquality(Lit) && !Left) || (!clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT) && (clause_GetFlag(Clause, CLAUSESELECT) || (MaxPara && !clause_LiteralIsMaximal(clause_GetLiteral(Clause,i)))))) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSPLeftEqToGiven: Illegal input."); misc_FinishErrorReport(); } #endif Bottom = stack_Bottom(); if (Left) sharing_PushOnStack(term_FirstArgument(Atom)); else sharing_PushOnStack(term_SecondArgument(Atom)); while (!stack_Empty(Bottom)) { Term = (TERM)stack_PopResult(); if (!term_IsVariable(Term)) { /* Superposition into variables is not necessary */ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Term); for ( ;!list_Empty(TermList); TermList = list_Pop(TermList)) { PartnerTerm = (TERM)list_Car(TermList); for (ParentList = term_SupertermList(PartnerTerm); !list_Empty(ParentList); ParentList = list_Cdr(ParentList)) { PartnerEq = (TERM)list_Car(ParentList); if (fol_IsEquality(PartnerEq)) { CLAUSE PartnerClause; LITERAL PartnerLit; LIST Scl; int j; for (Scl = sharing_NAtomDataList(PartnerEq); !list_Empty(Scl); Scl = list_Cdr(Scl)) { PartnerLit = (LITERAL)list_Car(Scl); j = clause_LiteralGetIndex(PartnerLit); PartnerClause = clause_LiteralOwningClause(PartnerLit); if (!clause_GetFlag(PartnerClause,CLAUSESELECT) && (!MaxPara || clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) && (!OrdPara || PartnerTerm == term_FirstArgument(PartnerEq) || !clause_LiteralIsOrientedEquality(PartnerLit)) && clause_LiteralIsPositive(PartnerLit) && clause_Number(PartnerClause) != clause_Number(Clause) && (!Unit || clause_Length(PartnerClause) == 1) && clause_HasSolvedConstraint(PartnerClause)) { SYMBOL MaxVar; SUBST Subst, PartnerSubst; MaxVar = clause_MaxVar(PartnerClause); clause_RenameVarsBiggerThan(Clause,MaxVar); cont_Check(); unify_UnifyNoOC(cont_LeftContext(), Term, cont_RightContext(),PartnerTerm); subst_ExtractUnifier(cont_LeftContext(), &Subst, cont_RightContext(),&PartnerSubst); cont_Reset(); if (!MaxPara || inf_LiteralsMax(Clause, i, Subst, PartnerClause, j, PartnerSubst, Flags, Precedence)) { TERM PartnerLeft,PartnerRight; BOOL Check, PartnerCheck; PartnerLeft = PartnerRight = NULL; PartnerCheck = Check = TRUE; if (OrdPara && !clause_LiteralIsOrientedEquality(PartnerLit)) { /* Check post condition for partner literal */ if (PartnerTerm == term_FirstArgument(PartnerEq)) PartnerRight = term_SecondArgument(PartnerEq); else PartnerRight = term_FirstArgument(PartnerEq); PartnerLeft = subst_Apply(PartnerSubst, term_Copy(PartnerTerm)); PartnerRight = subst_Apply(PartnerSubst, term_Copy(PartnerRight)); PartnerCheck = (ord_Compare(PartnerLeft,PartnerRight, Flags, Precedence) != ord_SmallerThan()); } if (PartnerCheck && MaxPara && !clause_LiteralIsOrientedEquality(Lit)) { /* Check post condition for literal in given clause */ TERM NewLeft, NewRight; if (Left) { NewLeft = term_FirstArgument(Atom); NewRight = term_SecondArgument(Atom); } else { NewLeft = term_SecondArgument(Atom); NewRight = term_FirstArgument(Atom); } NewLeft = subst_Apply(Subst, term_Copy(NewLeft)); NewRight = subst_Apply(Subst, term_Copy(NewRight)); Check = (ord_Compare(NewLeft, NewRight, Flags, Precedence) != ord_SmallerThan()); term_Delete(NewLeft); term_Delete(NewRight); } if (Check && PartnerCheck) { /* Make inference only if both tests were successful */ TERM SupAtom; SupAtom = NULL; if (PartnerRight == NULL) { if (PartnerTerm==term_FirstArgument(PartnerEq)) PartnerRight = term_SecondArgument(PartnerEq); else PartnerRight = term_FirstArgument(PartnerEq); PartnerRight = subst_Apply(PartnerSubst, term_Copy(PartnerRight)); } if (Left) SupAtom = inf_AllTermsLeftRplac(Atom, Term, PartnerRight, Subst); else SupAtom = inf_AllTermsRightRplac(Atom, Term, PartnerRight, Subst); #ifdef CHECK if (SupAtom == NULL) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSPLeftEqToGiven:"); misc_ErrorReport(" replacement wasn't possible."); misc_FinishErrorReport(); } #endif Result = list_Cons(inf_ApplyGenSuperposition(PartnerClause, j, PartnerSubst,Clause, i,Subst,SupAtom, FALSE,OrdPara, MaxPara,Flags, Precedence), Result); } if (PartnerLeft != term_Null()) term_Delete(PartnerLeft); if (PartnerRight != term_Null()) term_Delete(PartnerRight); } subst_Delete(Subst); subst_Delete(PartnerSubst); } } } } } } } return Result; } static LIST inf_GenSPLeftLitToGiven(CLAUSE Clause, int i, TERM Atom, SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara, BOOL Unit, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: An unshared clause, the index of an antecedent literal that is not an equality literal and its atom, a shared index, three boolean flags controlling inference preconditions (see also inf_GenSuperpositionLeft), a flag store and a precedence. RETURNS: A list of clauses derivable from superposition left on the GivenCopy wrt. the Index. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result, TermList, ParentList; int Bottom; LITERAL Lit; TERM Term, PartnerTerm, PartnerEq; Result = list_Nil(); Lit = clause_GetLiteral(Clause,i); #ifdef CHECK if (clause_LiteralIsEquality(Lit) || !clause_LiteralIsFromAntecedent(Lit)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSPLeftLitToGiven: Illegal input."); misc_FinishErrorReport(); } #endif Bottom = stack_Bottom(); sharing_PushListOnStack(term_ArgumentList(Atom)); while (!stack_Empty(Bottom)) { Term = (TERM)stack_PopResult(); if (!term_IsVariable(Term)) { /* Superposition into variables is not necessary */ TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Term); for ( ; !list_Empty(TermList); TermList=list_Pop(TermList)) { PartnerTerm = (TERM)list_Car(TermList); for (ParentList = term_SupertermList(PartnerTerm); !list_Empty(ParentList); ParentList = list_Cdr(ParentList)) { PartnerEq = (TERM)list_Car(ParentList); if (fol_IsEquality(PartnerEq)) { CLAUSE PartnerClause; LITERAL PartnerLit; TERM PartnerAtom; LIST Scl; int j; for (Scl = sharing_NAtomDataList(PartnerEq); !list_Empty(Scl); Scl = list_Cdr(Scl)) { PartnerLit = (LITERAL)list_Car(Scl); j = clause_LiteralGetIndex(PartnerLit); PartnerClause = clause_LiteralOwningClause(PartnerLit); PartnerAtom = clause_LiteralAtom(PartnerLit); if (!clause_GetFlag(PartnerClause,CLAUSESELECT) && (!MaxPara || clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) && (!OrdPara || PartnerTerm == term_FirstArgument(PartnerAtom) || !clause_LiteralIsOrientedEquality(PartnerLit)) && clause_LiteralIsPositive(PartnerLit) && clause_Number(PartnerClause) != clause_Number(Clause) && (!Unit || clause_Length(PartnerClause) == 1) && clause_HasSolvedConstraint(PartnerClause)) { SYMBOL MaxVar; TERM PartnerLeft,PartnerRight; SUBST Subst, PartnerSubst; TERM SupAtom; SupAtom = (TERM)NULL; MaxVar = clause_MaxVar(PartnerClause); clause_RenameVarsBiggerThan(Clause,MaxVar); cont_Check(); unify_UnifyNoOC(cont_LeftContext(),Term,cont_RightContext(),PartnerTerm); subst_ExtractUnifier(cont_LeftContext(),&Subst,cont_RightContext(),&PartnerSubst); cont_Reset(); if (!MaxPara || inf_LiteralsMax(Clause, i, Subst, PartnerClause, j, PartnerSubst, Flags, Precedence)) { PartnerLeft = subst_Apply(PartnerSubst, term_Copy(PartnerTerm)); if (PartnerTerm == term_FirstArgument(PartnerAtom)) PartnerRight = subst_Apply(PartnerSubst, term_Copy(term_SecondArgument(PartnerAtom))); else PartnerRight = subst_Apply(PartnerSubst, term_Copy(term_FirstArgument(PartnerAtom))); if (!OrdPara || clause_LiteralIsOrientedEquality(PartnerLit) || ord_Compare(PartnerLeft,PartnerRight,Flags, Precedence) != ord_SmallerThan()) { SupAtom = inf_AllTermsRplac(Atom,Term,PartnerRight,Subst); #ifdef CHECK if (SupAtom == NULL) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSPRightLitToGiven:"); misc_ErrorReport(" replacement wasn't possible."); misc_FinishErrorReport(); } #endif Result = list_Cons(inf_ApplyGenSuperposition(PartnerClause, j, PartnerSubst, Clause, i, Subst, SupAtom, FALSE, OrdPara, MaxPara, Flags, Precedence), Result); } term_Delete(PartnerLeft); term_Delete(PartnerRight); } subst_Delete(Subst); subst_Delete(PartnerSubst); } } } } } } } return Result; } static LIST inf_GenSPLeftToGiven(CLAUSE Clause, int i, SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara, BOOL Unit, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: An unshared clause, the index of an antecedent literal, an index of shared clauses, three boolean flags for controlling inference preconditions (see inf_GenSuperpositionLeft), a flag store and a precedence. RETURNS: A list of clauses derivable from Superposition Left on the GivenCopy wrt. the Index. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { TERM Atom; LIST Result; #ifdef CHECK if (clause_GetFlag(Clause, NOPARAINTO) || (!clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT) && (clause_GetFlag(Clause, CLAUSESELECT) || (MaxPara && !clause_LiteralIsMaximal(clause_GetLiteral(Clause,i)))))) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSPLeftToGiven: Illegal input."); misc_FinishErrorReport(); } #endif Result = list_Nil(); Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i)); if (fol_IsEquality(Atom)) { Result = list_Nconc(inf_GenSPLeftEqToGiven(Clause,i, TRUE,ShIndex, OrdPara, MaxPara, Unit, Flags,Precedence), Result); if (!MaxPara || !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i))) /* For SPm and OPm always try other direction, for SpR try it */ /* only if the literal is not oriented. */ Result = list_Nconc(inf_GenSPLeftEqToGiven(Clause,i,FALSE,ShIndex,OrdPara, MaxPara,Unit,Flags,Precedence), Result); } else Result = list_Nconc(inf_GenSPLeftLitToGiven(Clause,i,Atom,ShIndex,OrdPara, MaxPara,Unit,Flags,Precedence), Result); return Result; } LIST inf_GenSuperpositionLeft(CLAUSE GivenClause, SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara, BOOL Unit, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause and an Index, usually the WorkedOffIndex, two boolean flags for controlling inference preconditions, a flag store and a precedence. RETURNS: A list of clauses derivable from the Givenclause by one of the following inference rules wrt. the Index: OrdPara=TRUE, MaxPara=TRUE -> Superposition Left OrdPara=TRUE, MaxPara=FALSE -> ordered Paramodulation OrdPara=FALSE, MaxPara=FALSE -> simple Paramodulation OrdPara=FALSE, MaxPara=TRUE -> not defined If ==TRUE the clause with the maximal equality additionally must be a unit clause. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result; TERM Atom; CLAUSE Copy; int i, n; LITERAL ActLit; #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSuperpositionLeft: Illegal input."); misc_FinishErrorReport(); } if (!OrdPara && MaxPara) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GenSuperpositionLeft: Illegal inference rule selection,"); misc_ErrorReport("\n OrdPara=FALSE & MaxPara=TRUE."); misc_FinishErrorReport(); } #endif Result = list_Nil(); if (!clause_HasSolvedConstraint(GivenClause)) return Result; Copy = clause_Copy(GivenClause); n = clause_LastSuccedentLitIndex(Copy); if (!clause_GetFlag(Copy, CLAUSESELECT) && (!Unit || clause_Length(Copy) == 1)) { for (i = clause_FirstSuccedentLitIndex(Copy); i <= n; i++) { ActLit = clause_GetLiteral(Copy, i); Atom = clause_LiteralSignedAtom(ActLit); if (fol_IsEquality(Atom) && (!MaxPara || clause_LiteralGetFlag(ActLit,STRICTMAXIMAL))) { Result = list_Nconc(inf_GenLitSPLeft(Copy, term_FirstArgument(Atom), term_SecondArgument(Atom), i, ShIndex, OrdPara, MaxPara, Flags, Precedence), Result); if (!OrdPara || !clause_LiteralIsOrientedEquality(ActLit)) /* For SPm always try the other direction, for OPm and SpL */ /* only try it if the literal is not oriented. */ Result = list_Nconc(inf_GenLitSPLeft(Copy, term_SecondArgument(Atom), term_FirstArgument(Atom), i, ShIndex, OrdPara, MaxPara, Flags, Precedence), Result); } } } n = clause_LastAntecedentLitIndex(Copy); if (!clause_GetFlag(Copy,NOPARAINTO)) { for (i = clause_FirstAntecedentLitIndex(Copy); i <= n; i++) { ActLit = clause_GetLiteral(Copy, i); if (clause_LiteralGetFlag(ActLit, LITSELECT) || (!clause_GetFlag(Copy, CLAUSESELECT) && (!MaxPara || clause_LiteralIsMaximal(ActLit)))) Result = list_Nconc(inf_GenSPLeftToGiven(Copy, i, ShIndex, OrdPara, MaxPara,Unit,Flags,Precedence), Result); } } clause_Delete(Copy); return(Result); } LIST inf_ApplyDefinition(PROOFSEARCH Search, CLAUSE Clause, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A proof search object, a clause, a flag store and a precedence. RETURNS: A list of clauses derivable from the given clause by applying the (potential) definitions in . MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result, Defs; DEF Def; Result = list_Nil(); for (Defs=prfs_Definitions(Search); !list_Empty(Defs); Defs=list_Cdr(Defs)) { Def = (DEF)list_Car(Defs); Result = list_Nconc(def_ApplyDefToClauseOnce(Def, Clause, Flags, Precedence), Result); } return Result; } /************************************************************** block with hyperresolution code starts here ***************************************************************/ typedef struct { LITERAL NucleusLit; LITERAL ElectronLit; SUBST ElectronSubst; } INF_MAPNODE, *INF_MAPITEM; static void inf_CopyHyperElectron(CLAUSE Clause, SUBST Subst2, SUBST Subst1, int PLitInd, LIST* Constraint, LIST* Succedent) /************************************************************** INPUT: An electron clause, a substitution, an index of a succedent literal in this clause (the matched one), and two lists by reference. RETURNS: Nothing. EFFECTS: The constraint and succedent literals are copied into the corresponding lists except for the literal with the given index. The composition ° is applied to all copied literals. The antecedent of the electron clause is empty, so there's no need for a third list by reference. ***************************************************************/ { TERM Atom; int n, lc, j; #ifdef CHECK if (clause_NumOfAnteLits(Clause) != 0) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_CopyHyperElectron: Electron contains antecedent literals."); misc_FinishErrorReport(); } #endif n = clause_LastSuccedentLitIndex(Clause); lc = clause_LastConstraintLitIndex(Clause); for (j = clause_FirstConstraintLitIndex(Clause); j <= n; j++) { if (j != PLitInd) { Atom = subst_Apply(Subst1, term_Copy(clause_GetLiteralAtom(Clause, j))); Atom = subst_Apply(Subst2, Atom); if (j <= lc) *Constraint = list_Cons(Atom, *Constraint); else /* Literal must be from succedent */ *Succedent = list_Cons(Atom, *Succedent); } } } static CLAUSE inf_BuildHyperResolvent(CLAUSE Nucleus, SUBST Subst, LIST FoundMap, BOOL StrictlyMaximal, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause with solved sort constraint, the substitution for , a mapping of literals of already found partner clauses, a boolean flag indicating whether this is a ordered or a standard hyper resolution inference a flag store and a precedence. RETURNS: The newly created hyper resolvent. ***************************************************************/ { CLAUSE NewClause; LIST Constraint, Succedent, Parents, ParentNum, ParentLits, Scan; int i, bound, Depth; LITERAL Lit; SUBST ESubst; INF_MAPITEM MapItem; Parents = list_List(Nucleus); /* parent clauses */ ParentNum = list_Nil(); /* parent clause numbers */ ParentLits = list_Nil(); /* literal indices */ Constraint = Succedent = list_Nil(); /* literals of the new clause */ /* Get constraint literals from nucleus */ bound = clause_LastConstraintLitIndex(Nucleus); for (i = clause_FirstConstraintLitIndex(Nucleus); i <= bound; i++) Constraint = list_Cons(subst_Apply(Subst,term_Copy(clause_GetLiteralAtom(Nucleus,i))), Constraint); /* Get succedent literals from nucleus */ bound = clause_LastSuccedentLitIndex(Nucleus); for (i = clause_FirstSuccedentLitIndex(Nucleus); i <= bound; i++) Succedent = list_Cons(subst_Apply(Subst,term_Copy(clause_GetLiteralAtom(Nucleus,i))), Succedent); /* Now get the remaining data for the resolvent */ Depth = clause_Depth(Nucleus); bound = clause_LastAntecedentLitIndex(Nucleus); for (i = clause_FirstAntecedentLitIndex(Nucleus); i <= bound; i++) { /* Search for the nucleus literal with index */ Lit = clause_GetLiteral(Nucleus, i); for (Scan = FoundMap, MapItem = NULL; !list_Empty(Scan); Scan = list_Cdr(Scan)) { MapItem = list_Car(Scan); if (MapItem->NucleusLit == Lit) break; } if (MapItem == NULL || MapItem->NucleusLit != Lit) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_BuildHyperResolvent: Map entry not found."); misc_FinishErrorReport(); } Lit = MapItem->ElectronLit; NewClause = clause_LiteralOwningClause(Lit); ESubst = MapItem->ElectronSubst; Depth = misc_Max(Depth, clause_Depth(NewClause)); Parents = list_Cons(NewClause, Parents); ParentNum = list_Cons((POINTER) clause_Number(Nucleus), ParentNum); ParentLits = list_Cons((POINTER) i, ParentLits); ParentNum = list_Cons((POINTER) clause_Number(NewClause), ParentNum); ParentLits = list_Cons((POINTER) clause_LiteralGetIndex(Lit), ParentLits); /* Get the remaining constraint and succedent literals from electron */ inf_CopyHyperElectron(NewClause,Subst,ESubst,clause_LiteralGetIndex(Lit), &Constraint, &Succedent); } /* create new clause and set clause data */ NewClause = clause_Create(Constraint, list_Nil(), Succedent, Flags,Precedence); if (StrictlyMaximal) clause_SetFromOrderedHyperResolution(NewClause); else clause_SetFromSimpleHyperResolution(NewClause); clause_SetDepth(NewClause, Depth + 1); clause_SetSplitDataFromList(NewClause, Parents); clause_SetParentClauses(NewClause, list_NReverse(ParentNum)); clause_SetParentLiterals(NewClause, list_NReverse(ParentLits)); /* clean up */ list_Delete(Parents); list_Delete(Constraint); list_Delete(Succedent); return NewClause; } static LIST inf_GetHyperResolutionPartnerLits(TERM Atom, SHARED_INDEX Index, BOOL StrictlyMaximal) /************************************************************** INPUT: An atom, a clause index, and a boolean flag. RETURNS: A list of literals from purely positive clauses from the index where either is false or the literals are strictly maximal in their respective clauses. ***************************************************************/ { LIST Result, TermList, LitScan; LITERAL NextLit; CLAUSE Clause; #ifdef CHECK if (!term_IsAtom(Atom)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_GetHyperResolutionPartnerLits: Illegal input."); misc_FinishErrorReport(); } #endif Result = list_Nil(); TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(Index), cont_RightContext(), Atom); for (; !list_Empty(TermList); TermList = list_Pop(TermList)) { if (!term_IsVariable(list_Car(TermList))) { for (LitScan = sharing_NAtomDataList(list_Car(TermList)); !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) { NextLit = list_Car(LitScan); Clause = clause_LiteralOwningClause(NextLit); if (clause_LiteralIsFromSuccedent(NextLit) && (!StrictlyMaximal || clause_LiteralGetFlag(NextLit, STRICTMAXIMAL)) && clause_HasSolvedConstraint(Clause) && clause_HasEmptyAntecedent(Clause)) Result = list_Cons(NextLit, Result); } } } return Result; } static LIST inf_HyperResolvents(CLAUSE Clause, SUBST Subst, LIST Restlits, int GlobalMaxVar, LIST FoundMap, BOOL StrictlyMaximal, SHARED_INDEX Index, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A nucleus where the sort constraint is solved, a substitution, that has to be applied to the nucleus, a list of antecedent literals for which a partner clause is searched, a list of map items (n,e,s), where n is an antecedent literal from the nucleus, e is a positive literal from an electron clause, that is unifiable with n and s is a substitution that has to be applied to the electron clause, a flag store and a precedence. A main invariant of our algorithm is that all involved clauses are pairwise variable disjoint. For that reason we need, when building the resolvent, only apply the electron specific substitution and the composed substitution to the electron clauses, and only to the nucleus clause. RETURNS: The list of hyper-resolvents. ***************************************************************/ { LITERAL Lit, PLit; if (list_Empty(Restlits)) { /* This case stops the recursion */ LIST Scan; INF_MAPITEM MapItem; /* A posteriori test for the electron literals */ if (StrictlyMaximal) { /* only for ordered hyper resolution */ for (Scan = FoundMap; !list_Empty(Scan); Scan = list_Cdr(Scan)) { MapItem = list_Car(Scan); Lit = MapItem->ElectronLit; if (!inf_LitMaxWith2Subst(clause_LiteralOwningClause(Lit), clause_LiteralGetIndex(Lit), -1, Subst, MapItem->ElectronSubst,TRUE,Flags,Precedence)) return list_Nil(); } } /* Build the resolvent */ return list_List(inf_BuildHyperResolvent(Clause, Subst, FoundMap, StrictlyMaximal,Flags,Precedence)); } else { CLAUSE PartnerCopy; LIST Result, NextLits; TERM AtomCopy; SUBST NewSubst, RightSubst, HelpSubst; SYMBOL NewMaxVar; int PLitInd; BOOL Swapped; INF_MAPNODE MapNode; Result = list_Nil(); Restlits = clause_MoveBestLiteralToFront(list_Copy(Restlits), Subst, GlobalMaxVar, clause_HyperLiteralIsBetter); Lit = list_Car(Restlits); Restlits = list_Pop(Restlits); AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit))); Swapped = FALSE; /* The 'endless' loop may run twice for equations, once for other atoms */ while (TRUE) { NextLits = inf_GetHyperResolutionPartnerLits(AtomCopy,Index, StrictlyMaximal); for ( ; !list_Empty(NextLits); NextLits = list_Pop(NextLits)) { PLit = list_Car(NextLits); PLitInd = clause_LiteralGetIndex(PLit); PartnerCopy = clause_Copy(clause_LiteralOwningClause(PLit)); clause_RenameVarsBiggerThan(PartnerCopy, GlobalMaxVar); PLit = clause_GetLiteral(PartnerCopy, PLitInd); NewMaxVar = term_MaxVar(clause_LiteralAtom(PLit)); NewMaxVar = symbol_GreaterVariable(GlobalMaxVar, NewMaxVar) ? GlobalMaxVar : NewMaxVar; cont_Check(); if (!unify_UnifyNoOC(cont_LeftContext(), AtomCopy, cont_RightContext(), clause_LiteralAtom(PLit))) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_HyperResolvents: Unification failed."); misc_FinishErrorReport(); } subst_ExtractUnifier(cont_LeftContext(), &NewSubst, cont_RightContext(), &RightSubst); cont_Reset(); HelpSubst = NewSubst; NewSubst = subst_Compose(NewSubst, subst_Copy(Subst)); subst_Delete(HelpSubst); MapNode.NucleusLit = Lit; MapNode.ElectronLit = PLit; MapNode.ElectronSubst = RightSubst; FoundMap = list_Cons(&MapNode, FoundMap); Result = list_Nconc(inf_HyperResolvents(Clause, NewSubst, Restlits, NewMaxVar, FoundMap, StrictlyMaximal, Index, Flags, Precedence), Result); subst_Delete(NewSubst); subst_Delete(RightSubst); clause_Delete(PartnerCopy); FoundMap = list_Pop(FoundMap); } if (!Swapped && fol_IsEquality(AtomCopy)) { term_EqualitySwap(AtomCopy); Swapped = TRUE; } else break; } /* end of 'endless' loop */ list_Delete(Restlits); term_Delete(AtomCopy); return Result; } } static LIST inf_GetAntecedentLiterals(CLAUSE Clause) /************************************************************** INPUT: A clause RETURNS: The list of all antecedent literals of the clause. ***************************************************************/ { int lc, i; LIST Result; Result = list_Nil(); lc = clause_LastAntecedentLitIndex(Clause); for (i = clause_FirstAntecedentLitIndex(Clause); i <= lc ; i++) { Result = list_Cons(clause_GetLiteral(Clause, i), Result); } return Result; } static LIST inf_ForwardHyperResolution(CLAUSE GivenClause, SHARED_INDEX Index, BOOL StrictlyMaximal, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause with an solved sort constraint, an 'Index' of clauses, a boolean flag, a flag store and a precedence. RETURNS: A list of clauses inferred from by hyper resolution wrt. the index. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result, RestLits; ; #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_ForwardHyperResolution: Illegal input."); misc_FinishErrorReport(); } #endif if (clause_HasEmptyAntecedent(GivenClause)) return list_Nil(); Result = list_Nil(); /* Build up list of all antecedent literals. */ RestLits = inf_GetAntecedentLiterals(GivenClause); Result = list_Nconc(inf_HyperResolvents(GivenClause, subst_Nil(), RestLits,clause_MaxVar(GivenClause), list_Nil(),StrictlyMaximal,Index, Flags, Precedence), Result); list_Delete(RestLits); return Result; } static LIST inf_BackwardHyperResolution(CLAUSE Electron, SHARED_INDEX Index, BOOL StrictlyMaximal, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause with an solved sort constraint, an 'Index' of clauses, a boolean flag, a flag store, and a precedence. RETURNS: A list of clauses inferred by hyper resolution wrt. the index with as an electron. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { CLAUSE ElectronCopy; LIST Result; int i, ls; if (!clause_HasEmptyAntecedent(Electron) || clause_HasEmptySuccedent(Electron)) return list_Nil(); Result = list_Nil(); ElectronCopy = clause_Copy(Electron); /* Search succedent literal in */ ls = clause_LastSuccedentLitIndex(ElectronCopy); for (i = clause_FirstSuccedentLitIndex(Electron); i <= ls; i++) { LITERAL ElecLit; TERM ElecAtom; ElecLit = clause_GetLiteral(ElectronCopy, i); ElecAtom = clause_LiteralAtom(ElecLit); if (!StrictlyMaximal || clause_LiteralGetFlag(ElecLit, STRICTMAXIMAL)) { LIST CandAtoms; BOOL Swapped; Swapped = FALSE; /* The 'endless' loop may run twice for equations, once for other atoms */ while (TRUE) { /* Get unifiable antecedent literals in nucleus */ CandAtoms = st_GetUnifier(cont_LeftContext(), sharing_Index(Index), cont_RightContext(), ElecAtom); for ( ; !list_Empty(CandAtoms); CandAtoms = list_Pop(CandAtoms)) { if (!term_IsVariable(list_Car(CandAtoms))) { LIST CandLits; CandLits = sharing_NAtomDataList(list_Car(CandAtoms)); for (; !list_Empty(CandLits); CandLits = list_Cdr(CandLits)) { LITERAL NucLit; TERM NucAtom; CLAUSE Nucleus; NucLit = list_Car(CandLits); NucAtom = clause_LiteralAtom(NucLit); Nucleus = clause_LiteralOwningClause(NucLit); if (clause_LiteralIsFromAntecedent(NucLit) && clause_HasSolvedConstraint(Nucleus)) { LIST FoundMap, RestLits; SUBST LeftSubst, RightSubst; SYMBOL GlobalMaxVar, MaxVar; INF_MAPNODE MapNode; GlobalMaxVar = clause_MaxVar(Nucleus); clause_RenameVarsBiggerThan(ElectronCopy, GlobalMaxVar); MaxVar = clause_SearchMaxVar(ElectronCopy); GlobalMaxVar = symbol_GreaterVariable(GlobalMaxVar, MaxVar) ? GlobalMaxVar : MaxVar; /* Now ElecLit is renamed, too */ RestLits = inf_GetAntecedentLiterals(Nucleus); RestLits = list_PointerDeleteElement(RestLits, NucLit); /* Get unifier */ cont_Check(); if (!unify_UnifyNoOC(cont_LeftContext(), NucAtom, cont_RightContext(), ElecAtom)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_BackwardHyperResolution: Unification failed."); misc_FinishErrorReport(); } subst_ExtractUnifier(cont_LeftContext(), &LeftSubst, cont_RightContext(), &RightSubst); cont_Reset(); MapNode.NucleusLit = NucLit; MapNode.ElectronLit = ElecLit; MapNode.ElectronSubst = RightSubst; FoundMap = list_List(&MapNode); Result = list_Nconc(inf_HyperResolvents(Nucleus, LeftSubst, RestLits, GlobalMaxVar, FoundMap,StrictlyMaximal, Index, Flags,Precedence), Result); /* clean up */ subst_Delete(LeftSubst); subst_Delete(RightSubst); list_Delete(RestLits); list_Free(FoundMap); } /* if a nucleus has been found */ } /* for all nucleus candidate literals */ } /* if term is atom */ } /* for all nucleus candidate atoms */ if (!Swapped && fol_IsEquality(ElecAtom)) { term_EqualitySwap(ElecAtom); /* Atom is from copied clause */ Swapped = TRUE; } else break; } /* end of 'endless' loop */ } /* for all lits usable in electron for hyper resolution */ } /* for all lits in succedent */ clause_Delete(ElectronCopy); return Result; } LIST inf_GeneralHyperResolution(CLAUSE GivenClause, SHARED_INDEX Index, BOOL Ordered, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause, an 'Index' of clauses, a boolean flag, a flag store and a precedence. RETURNS: A list of clauses inferred by (ordered) hyper resolution wrt. the index. If =TRUE then ordered hyper resolution inferences are made, else standard hyper resolution inferences. MEMORY: A list of clauses is produced, where memory for the list and the clauses is allocated. ***************************************************************/ { LIST Result; Result = list_Nil(); if (clause_HasSolvedConstraint(GivenClause)) { Result = inf_ForwardHyperResolution(GivenClause, Index, Ordered, Flags, Precedence); Result = list_Nconc(inf_BackwardHyperResolution(GivenClause, Index, Ordered, Flags, Precedence), Result); } return Result; } LIST inf_DerivableClauses(PROOFSEARCH Search, CLAUSE GivenClause) /************************************************************** INPUT: A clause and an Index, usually the WorkedOffIndex. RETURNS: A list of clauses derivable from 'GivenClause' wrt index. EFFECT: Allocates memory for the clauselistnodes and new clauses. ***************************************************************/ { LIST ListOfDerivedClauses; SHARED_INDEX ShIndex; SORTTHEORY Dynamic; FLAGSTORE Flags; PRECEDENCE Precedence; Flags = prfs_Store(Search); Precedence = prfs_Precedence(Search); #ifdef CHECK if (!clause_IsClause(GivenClause, Flags, Precedence)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_DerivableClauses: Illegal input."); misc_FinishErrorReport(); } #endif ListOfDerivedClauses = list_Nil(); ShIndex = prfs_WorkedOffSharingIndex(Search); Dynamic = prfs_DynamicSortTheory(Search); if (Dynamic && !clause_HasSolvedConstraint(GivenClause)) { if (clause_HasTermSortConstraintLits(GivenClause)) { if (flag_GetFlagValue(Flags, flag_ISOR)) ListOfDerivedClauses = list_Nconc(inf_ForwardSortResolution(GivenClause, sort_TheoryIndex(Dynamic), Dynamic, FALSE, Flags,Precedence), ListOfDerivedClauses); } else if (flag_GetFlagValue(Flags, flag_IEMS)) ListOfDerivedClauses = list_Nconc(inf_ForwardEmptySort(GivenClause, sort_TheoryIndex(Dynamic), Dynamic, FALSE, Flags, Precedence), ListOfDerivedClauses); } else { /* Given with solved Constraint! */ if (Dynamic && flag_GetFlagValue(Flags, flag_IEMS)) ListOfDerivedClauses = list_Nconc(inf_BackwardEmptySort(GivenClause, sharing_Index(ShIndex), Dynamic, FALSE, Flags, Precedence), ListOfDerivedClauses); if (Dynamic && flag_GetFlagValue(Flags, flag_ISOR)) ListOfDerivedClauses = list_Nconc(inf_BackwardSortResolution(GivenClause, sharing_Index(ShIndex), Dynamic, FALSE, Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_IEQR)) ListOfDerivedClauses = list_Nconc(inf_EqualityResolution(GivenClause, TRUE, Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_IERR)) ListOfDerivedClauses = list_Nconc(inf_EqualityResolution(GivenClause, FALSE, Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_IMPM)) ListOfDerivedClauses = list_Nconc(inf_MergingParamodulation(GivenClause, ShIndex, Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_IEQF)) ListOfDerivedClauses = list_Nconc(inf_EqualityFactoring(GivenClause,Flags, Precedence), ListOfDerivedClauses); switch (flag_GetFlagValue(Flags, flag_IOFC)) { case flag_FACTORINGOFF: break; /* Do nothing */ case flag_FACTORINGONLYRIGHT: ListOfDerivedClauses = list_Nconc(inf_GeneralFactoring(GivenClause, TRUE, FALSE,TRUE, Flags, Precedence), ListOfDerivedClauses); break; case flag_FACTORINGRIGHTANDLEFT: ListOfDerivedClauses = list_Nconc(inf_GeneralFactoring(GivenClause, TRUE, TRUE, TRUE, Flags, Precedence), ListOfDerivedClauses); break; default: misc_StartUserErrorReport(); misc_UserErrorReport("\n Error: Flag \"IOFC\" has invalid value.\n"); misc_FinishUserErrorReport(); } if (flag_GetFlagValue(Flags, flag_ISFC)) ListOfDerivedClauses = list_Nconc(inf_GeneralFactoring(GivenClause, FALSE, TRUE, TRUE, Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_ISPR)) ListOfDerivedClauses = list_Nconc(inf_SuperpositionRight(GivenClause,ShIndex,Flags,Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_ISPM)) ListOfDerivedClauses = list_Nconc(inf_Paramodulation(GivenClause, ShIndex, Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_IOPM)) ListOfDerivedClauses = list_Nconc(inf_OrderedParamodulation(GivenClause, ShIndex, Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_ISPL)) ListOfDerivedClauses = list_Nconc(inf_SuperpositionLeft(GivenClause, ShIndex, Flags,Precedence), ListOfDerivedClauses); switch (flag_GetFlagValue(Flags, flag_IORE)) { case flag_ORDEREDRESOLUTIONOFF: break; /* Do nothing */ case flag_ORDEREDRESOLUTIONNOEQUATIONS: /* no equations */ ListOfDerivedClauses = list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,TRUE,FALSE,Flags, Precedence), ListOfDerivedClauses); break; case flag_ORDEREDRESOLUTIONWITHEQUATIONS: /* allow equations */ ListOfDerivedClauses = list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,TRUE,TRUE, Flags, Precedence), ListOfDerivedClauses); break; default: misc_StartUserErrorReport(); misc_UserErrorReport("\n Error: Flag \"IORE\" has invalid value.\n"); misc_FinishUserErrorReport(); } switch (flag_GetFlagValue(Flags, flag_ISRE)) { case flag_STANDARDRESOLUTIONOFF: break; /* Do nothing */ case flag_STANDARDRESOLUTIONNOEQUATIONS: /* no equations */ ListOfDerivedClauses = list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,FALSE,FALSE,Flags, Precedence), ListOfDerivedClauses); break; case flag_STANDARDRESOLUTIONWITHEQUATIONS: /* allow equations */ ListOfDerivedClauses = list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,FALSE,TRUE,Flags, Precedence), ListOfDerivedClauses); break; default: misc_StartUserErrorReport(); misc_UserErrorReport("\n Error: Flag \"ISRE\" has invalid value.\n"); misc_FinishUserErrorReport(); } if (flag_GetFlagValue(Flags, flag_IUNR)) ListOfDerivedClauses = list_Nconc(inf_UnitResolution(GivenClause, ShIndex, FALSE, Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_IBUR)) ListOfDerivedClauses = list_Nconc(inf_BoundedDepthUnitResolution(GivenClause,ShIndex,FALSE, Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_ISHY)) ListOfDerivedClauses = list_Nconc(inf_GeneralHyperResolution(GivenClause,ShIndex,FALSE,Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_IOHY)) ListOfDerivedClauses = list_Nconc(inf_GeneralHyperResolution(GivenClause,ShIndex,TRUE,Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_IURR)) ListOfDerivedClauses = list_Nconc(inf_URResolution(GivenClause, ShIndex, Flags, Precedence), ListOfDerivedClauses); if (flag_GetFlagValue(Flags, flag_IDEF)) ListOfDerivedClauses = list_Nconc(inf_ApplyDefinition(Search, GivenClause, Flags, Precedence), ListOfDerivedClauses); } return ListOfDerivedClauses; }