| /**************************************************************/ |
| /* ********************************************************** */ |
| /* * * */ |
| /* * REDUCTION RULES * */ |
| /* * * */ |
| /* * $Module: REDRULES * */ |
| /* * * */ |
| /* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */ |
| /* * MPI fuer Informatik * */ |
| /* * * */ |
| /* * This program is free software; you can redistribute * */ |
| /* * it and/or modify it under the terms of the GNU * */ |
| /* * General Public License as published by the Free * */ |
| /* * Software Foundation; either version 2 of the License, * */ |
| /* * or (at your option) any later version. * */ |
| /* * * */ |
| /* * This program is distributed in the hope that it will * */ |
| /* * be useful, but WITHOUT ANY WARRANTY; without even * */ |
| /* * the implied warranty of MERCHANTABILITY or FITNESS * */ |
| /* * FOR A PARTICULAR PURPOSE. See the GNU General Public * */ |
| /* * License for more details. * */ |
| /* * * */ |
| /* * You should have received a copy of the GNU General * */ |
| /* * Public License along with this program; if not, write * */ |
| /* * to the Free Software Foundation, Inc., 59 Temple * */ |
| /* * Place, Suite 330, Boston, MA 02111-1307 USA * */ |
| /* * * */ |
| /* * * */ |
| /* $Revision$ * */ |
| /* $State$ * */ |
| /* $Date$ * */ |
| /* $Author$ * */ |
| /* * * */ |
| /* * Contact: * */ |
| /* * Christoph Weidenbach * */ |
| /* * MPI fuer Informatik * */ |
| /* * Stuhlsatzenhausweg 85 * */ |
| /* * 66123 Saarbruecken * */ |
| /* * Email: weidenb@mpi-sb.mpg.de * */ |
| /* * Germany * */ |
| /* * * */ |
| /* ********************************************************** */ |
| /**************************************************************/ |
| |
| |
| /* $RCSfile$ */ |
| |
| #include "rules-red.h" |
| |
| /**************************************************************/ |
| /* ********************************************************** */ |
| /* * * */ |
| /* * Globals * */ |
| /* * * */ |
| /* ********************************************************** */ |
| /**************************************************************/ |
| |
| |
| /* Needed for term stamping in red_RewriteRedUnitClause */ |
| static NAT red_STAMPID; |
| |
| const NAT red_USABLE = 1; |
| const NAT red_WORKEDOFF = 2; |
| const NAT red_ALL = 3; |
| |
| |
| /**************************************************************/ |
| /* FUNTION PROTOTYPES */ |
| /**************************************************************/ |
| |
| static BOOL red_SortSimplification(SORTTHEORY, CLAUSE, NAT, BOOL, FLAGSTORE, |
| PRECEDENCE, CLAUSE*); |
| static BOOL red_SelectedStaticReductions(PROOFSEARCH, CLAUSE*, CLAUSE*, LIST*, |
| NAT); |
| |
| |
| /**************************************************************/ |
| /* ********************************************************** */ |
| /* * * */ |
| /* * Functions * */ |
| /* * * */ |
| /* ********************************************************** */ |
| /**************************************************************/ |
| |
| |
| |
| static void red_HandleRedundantIndexedClauses(PROOFSEARCH Search, LIST Blocked, |
| CLAUSE RedClause) |
| /********************************************************* |
| INPUT: A proof search object, a list <Blocked> of clauses from |
| the proof search object and a clause that causes the |
| already indexed clauses in <Blocked> to be redundant. |
| RETURNS: Nothing. |
| **********************************************************/ |
| { |
| FLAGSTORE Flags; |
| CLAUSE Clause; |
| LIST Scan; |
| |
| Flags = prfs_Store(Search); |
| for (Scan = Blocked; !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| Clause = (CLAUSE)list_Car(Scan); |
| if (prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause), |
| prfs_LastBacktrackLevel(Search))) |
| split_DeleteClauseAtLevel(Search, Clause, clause_SplitLevel(RedClause)); |
| else { |
| if (clause_GetFlag(Clause, WORKEDOFF)) { |
| if (flag_GetFlagValue(Flags, flag_DOCPROOF)) |
| prfs_MoveWorkedOffDocProof(Search, Clause); |
| else |
| prfs_DeleteWorkedOff(Search, Clause); |
| } |
| else |
| if (flag_GetFlagValue(Flags, flag_DOCPROOF)) |
| prfs_MoveUsableDocProof(Search, Clause); |
| else |
| prfs_DeleteUsable(Search, Clause); |
| } |
| } |
| } |
| |
| static void red_HandleRedundantDerivedClauses(PROOFSEARCH Search, LIST Blocked, |
| CLAUSE RedClause) |
| /********************************************************* |
| INPUT: A proof search object, a list <Blocked> of clauses from |
| the proof search object and a clause that causes the |
| derived clauses in <Blocked> to be redundant. |
| RETURNS: Nothing. |
| **********************************************************/ |
| { |
| CLAUSE Clause; |
| LIST Scan; |
| |
| for (Scan = Blocked; !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| Clause = (CLAUSE)list_Car(Scan); |
| if (prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause), |
| prfs_LastBacktrackLevel(Search))) { |
| split_KeepClauseAtLevel(Search, Clause, clause_SplitLevel(RedClause)); |
| } |
| else { |
| if (flag_GetFlagValue(prfs_Store(Search), flag_DOCPROOF)) |
| prfs_InsertDocProofClause(Search, Clause); |
| else |
| clause_Delete(Clause); |
| } |
| } |
| } |
| |
| |
| void red_Init(void) |
| /********************************************************* |
| INPUT: None. |
| RETURNS: Nothing. |
| EFFECT: Initializes the Reduction module, in particular |
| its stampid to stamp terms. |
| **********************************************************/ |
| { |
| red_STAMPID = term_GetStampID(); |
| } |
| |
| |
| static void red_DocumentObviousReductions(CLAUSE Clause, LIST Indexes) |
| /********************************************************* |
| INPUT: A clause and a list of literal indexes removed by |
| obvious reductions. |
| RETURNS: None |
| MEMORY: The <Indexes> list is consumed. |
| **********************************************************/ |
| { |
| list_Delete(clause_ParentClauses(Clause)); |
| list_Delete(clause_ParentLiterals(Clause)); |
| clause_SetParentClauses(Clause, list_Nil()); |
| clause_SetParentLiterals(Clause, Indexes); |
| |
| clause_AddParentClause(Clause,clause_Number(Clause)); /* Has to be done before increasing it! */ |
| |
| clause_SetNumber(Clause, clause_IncreaseCounter()); |
| clause_SetFromObviousReductions(Clause); |
| } |
| |
| |
| static BOOL red_ObviousReductions(CLAUSE Clause, BOOL Document, |
| FLAGSTORE Flags, PRECEDENCE Precedence, |
| CLAUSE *Changed) |
| /********************************************************** |
| INPUT: A clause, a boolean flag for proof |
| documentation, a flag store and a precedence. |
| RETURNS: TRUE iff obvious reductions are possible. |
| If <Document> is false the clause is |
| destructively changed, |
| else a reduced copy of the clause is returned |
| in <*Changed>. |
| EFFECT: Multiple occurrences of the same literal as |
| well as trivial equations are removed. |
| ********************************************************/ |
| { |
| int i, j, end; |
| LIST Indexes; |
| TERM Atom, PartnerAtom; |
| |
| #ifdef CHECK |
| clause_Check(Clause, Flags, Precedence); |
| #endif |
| |
| Indexes = list_Nil(); |
| end = clause_LastAntecedentLitIndex(Clause); |
| |
| for (i = clause_FirstConstraintLitIndex(Clause); i <= end; i++) { |
| Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i)); |
| if (fol_IsEquality(Atom) && |
| !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause, i)) && |
| term_Equal(term_FirstArgument(Atom),term_SecondArgument(Atom))) { |
| Indexes = list_Cons((POINTER)i,Indexes); |
| } |
| else |
| for (j = i+1; j <= end; j++) { |
| PartnerAtom = clause_LiteralAtom(clause_GetLiteral(Clause,j)); |
| if (term_Equal(PartnerAtom, Atom) || |
| (fol_IsEquality(Atom) && |
| fol_IsEquality(PartnerAtom) && |
| term_Equal(term_FirstArgument(Atom),term_SecondArgument(PartnerAtom)) && |
| term_Equal(term_FirstArgument(PartnerAtom),term_SecondArgument(Atom)))) { |
| Indexes = list_Cons((POINTER)i,Indexes); |
| j = end; |
| } |
| } |
| } |
| |
| end = clause_LastSuccedentLitIndex(Clause); |
| |
| for (i = clause_FirstSuccedentLitIndex(Clause); i <= end; i++) { |
| Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i)); |
| for (j = i+1; j <= end; j++) { |
| PartnerAtom = clause_LiteralAtom(clause_GetLiteral(Clause,j)); |
| if (term_Equal(PartnerAtom,Atom) || |
| (fol_IsEquality(Atom) && |
| fol_IsEquality(PartnerAtom) && |
| term_Equal(term_FirstArgument(Atom),term_SecondArgument(PartnerAtom)) && |
| term_Equal(term_FirstArgument(PartnerAtom),term_SecondArgument(Atom)))) { |
| Indexes = list_Cons((POINTER)i,Indexes); |
| j = end; |
| } |
| } |
| } |
| |
| if (clause_Length(Clause) == 1 && |
| clause_NumOfAnteLits(Clause) == 1 && |
| !list_PointerMember(Indexes,(POINTER)clause_FirstAntecedentLitIndex(Clause)) && |
| fol_IsEquality(clause_GetLiteralAtom(Clause,clause_FirstAntecedentLitIndex(Clause)))) { |
| cont_StartBinding(); |
| if (unify_UnifyCom(cont_LeftContext(), |
| term_FirstArgument(clause_LiteralAtom(clause_GetLiteral(Clause,clause_FirstAntecedentLitIndex(Clause)))), |
| term_SecondArgument(clause_LiteralAtom(clause_GetLiteral(Clause,clause_FirstAntecedentLitIndex(Clause)))))) |
| Indexes = list_Cons((POINTER)clause_FirstAntecedentLitIndex(Clause),Indexes); |
| cont_BackTrack(); |
| } |
| |
| if (!list_Empty(Indexes)) { |
| if (flag_GetFlagValue(Flags, flag_POBV)) { |
| fputs("\nObvious: ", stdout); |
| clause_Print(Clause); |
| fputs(" ==> ", stdout); |
| } |
| if (Document) { |
| CLAUSE Copy; |
| Copy = clause_Copy(Clause); |
| clause_DeleteLiterals(Copy,Indexes, Flags, Precedence); |
| red_DocumentObviousReductions(Copy,Indexes); /* Indexes is consumed */ |
| if (flag_GetFlagValue(Flags, flag_POBV)) |
| clause_Print(Copy); |
| *Changed = Copy; |
| } |
| else { |
| clause_DeleteLiterals(Clause,Indexes, Flags, Precedence); |
| list_Delete(Indexes); |
| if (flag_GetFlagValue(Flags, flag_POBV)) |
| clause_Print(Clause); |
| } |
| return TRUE; |
| } |
| |
| return FALSE; |
| } |
| |
| |
| static void red_DocumentCondensing(CLAUSE Clause, LIST Indexes) |
| /********************************************************* |
| INPUT: A clause and a list of literal indexes removed by condensing. |
| RETURNS: Nothing. |
| MEMORY: The <Indexes> list is consumed. |
| **********************************************************/ |
| { |
| list_Delete(clause_ParentClauses(Clause)); |
| list_Delete(clause_ParentLiterals(Clause)); |
| clause_SetParentClauses(Clause, list_Nil()); |
| clause_SetParentLiterals(Clause, Indexes); |
| |
| clause_AddParentClause(Clause,clause_Number(Clause)); /* Has to be done before increasing it! */ |
| |
| clause_SetNumber(Clause, clause_IncreaseCounter()); |
| clause_SetFromCondensing(Clause); |
| } |
| |
| static BOOL red_Condensing(CLAUSE Clause, BOOL Document, FLAGSTORE Flags, |
| PRECEDENCE Precedence, CLAUSE *Changed) |
| /********************************************************** |
| INPUT: A non-empty unshared clause, a boolean flag |
| concerning proof documentation, a flag store and |
| a precedence. |
| RETURNS: TRUE iff condensing is applicable to <Clause>. |
| If <Document> is false the clause is |
| destructively changed else a condensed copy of |
| the clause is returned in <*Changed>. |
| ***********************************************************/ |
| { |
| LIST Indexes; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(Clause, Flags, Precedence) || |
| (*Changed != (CLAUSE)NULL)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_Condensing : "); |
| misc_ErrorReport("Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(Clause, Flags, Precedence); |
| #endif |
| |
| Indexes = cond_CondFast(Clause); |
| |
| if (!list_Empty(Indexes)) { |
| if (flag_GetFlagValue(Flags, flag_PCON)) { |
| fputs("\nCondensing: ", stdout); |
| clause_Print(Clause); |
| fputs(" ==> ", stdout); |
| } |
| if (Document) { |
| CLAUSE Copy; |
| Copy = clause_Copy(Clause); |
| clause_DeleteLiterals(Copy, Indexes, Flags, Precedence); |
| red_DocumentCondensing(Copy, Indexes); |
| if (flag_GetFlagValue(Flags, flag_PCON)) |
| clause_Print(Copy); |
| *Changed = Copy; |
| } |
| else { |
| clause_DeleteLiterals(Clause, Indexes, Flags, Precedence); |
| list_Delete(Indexes); |
| if (flag_GetFlagValue(Flags, flag_PCON)) |
| clause_Print(Clause); |
| } |
| return TRUE; |
| } |
| return FALSE; |
| } |
| |
| |
| static void red_DocumentAssignmentEquationDeletion(CLAUSE Clause, LIST Indexes, |
| NAT NonTrivClauseNumber) |
| /********************************************************* |
| INPUT: A clause and a list of literal indexes pointing to |
| redundant equations and the clause number of a clause |
| implying a non-trivial domain. |
| RETURNS: Nothing. |
| MEMORY: The <Indexes> list is consumed. |
| **********************************************************/ |
| { |
| list_Delete(clause_ParentClauses(Clause)); |
| list_Delete(clause_ParentLiterals(Clause)); |
| clause_SetParentClauses(Clause, list_Nil()); |
| clause_SetParentLiterals(Clause, Indexes); |
| |
| clause_AddParentClause(Clause,clause_Number(Clause)); /* Has to be done before increasing it! */ |
| |
| clause_SetNumber(Clause, clause_IncreaseCounter()); |
| clause_SetFromAssignmentEquationDeletion(Clause); |
| |
| if (NonTrivClauseNumber != 0) { /* Such a clause exists */ |
| clause_AddParentClause(Clause, NonTrivClauseNumber); |
| clause_AddParentLiteral(Clause, 0); /* The non triv clause has exactly one negative literal */ |
| } |
| } |
| |
| |
| static BOOL red_AssignmentEquationDeletion(CLAUSE Clause, FLAGSTORE Flags, |
| PRECEDENCE Precedence, CLAUSE *Changed, |
| NAT NonTrivClauseNumber, |
| BOOL NonTrivDomain) |
| /********************************************************** |
| INPUT: A non-empty unshared clause, a flag store, a |
| precedence, the clause number of a clause |
| implying a non-trivial domain and a boolean |
| flag indicating whether the current domain has |
| more than one element. |
| RETURNS: TRUE iff equations are removed. |
| If the <DocProof> flag is false the clause is |
| destructively changed else a copy of the clause |
| where redundant equations are removed is |
| returned in <*Changed>. |
| ***********************************************************/ |
| { |
| LIST Indexes; /* List of indexes of redundant equations*/ |
| NAT i; |
| TERM LeftArg, RightArg; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(Clause, Flags, Precedence) || |
| (*Changed != (CLAUSE)NULL) || |
| (NonTrivDomain && NonTrivClauseNumber == 0) || |
| (!NonTrivDomain && NonTrivClauseNumber > 0)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_AssignmentEquationDeletion: "); |
| misc_ErrorReport("Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(Clause, Flags, Precedence); |
| #endif |
| |
| Indexes = list_Nil(); |
| |
| if (clause_ContainsNegativeEquations(Clause)) { |
| for (i = clause_FirstAntecedentLitIndex(Clause); i <= clause_LastAntecedentLitIndex(Clause); i++) { |
| if (clause_LiteralIsEquality(clause_GetLiteral(Clause,i))) { |
| LeftArg = term_FirstArgument(clause_GetLiteralAtom(Clause,i)); |
| RightArg = term_SecondArgument(clause_GetLiteralAtom(Clause,i)); |
| if ((term_IsVariable(LeftArg) && |
| clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(LeftArg)) == 1) || |
| (term_IsVariable(RightArg) && |
| clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(RightArg)) == 1)) |
| Indexes = list_Cons((POINTER)i, Indexes); |
| } |
| } |
| } |
| else |
| if (NonTrivDomain && clause_ContainsPositiveEquations(Clause)) { |
| for (i = clause_FirstSuccedentLitIndex(Clause); i <= clause_LastSuccedentLitIndex(Clause); i++) { |
| if (clause_LiteralIsEquality(clause_GetLiteral(Clause,i))) { |
| LeftArg = term_FirstArgument(clause_GetLiteralAtom(Clause,i)); |
| RightArg = term_SecondArgument(clause_GetLiteralAtom(Clause,i)); |
| if ((term_IsVariable(LeftArg) && |
| clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(LeftArg)) == 1) || |
| (term_IsVariable(RightArg) && |
| clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(RightArg)) == 1)) |
| Indexes = list_Cons((POINTER)i, Indexes); |
| } |
| } |
| } |
| |
| if (!list_Empty(Indexes)) { |
| if (flag_GetFlagValue(Flags, flag_PAED)) { |
| fputs("\nAED: ", stdout); |
| clause_Print(Clause); |
| fputs(" ==> ", stdout); |
| } |
| if (flag_GetFlagValue(Flags, flag_DOCPROOF)) { |
| CLAUSE Copy; |
| Copy = clause_Copy(Clause); |
| clause_DeleteLiterals(Copy, Indexes, Flags, Precedence); |
| red_DocumentAssignmentEquationDeletion(Copy, Indexes, NonTrivClauseNumber); |
| if (flag_GetFlagValue(Flags, flag_PAED)) |
| clause_Print(Copy); |
| *Changed = Copy; |
| } |
| else { |
| clause_DeleteLiterals(Clause, Indexes, Flags, Precedence); |
| list_Delete(Indexes); |
| if (flag_GetFlagValue(Flags, flag_PAED)) |
| clause_Print(Clause); |
| } |
| return TRUE; |
| } |
| |
| return FALSE; |
| } |
| |
| |
| static BOOL red_Tautology(CLAUSE Clause, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /********************************************************** |
| INPUT: A non-empty clause, a flag store and a |
| precedence. |
| RETURNS: The boolean value TRUE if 'Clause' is a |
| tautology. |
| ***********************************************************/ |
| { |
| TERM Atom; |
| int i,j, la,n; |
| BOOL Result; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(Clause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_Tautology :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(Clause, Flags, Precedence); |
| #endif |
| |
| la = clause_LastAntecedentLitIndex(Clause); |
| n = clause_Length(Clause); |
| Result = FALSE; |
| |
| for (j = clause_FirstSuccedentLitIndex(Clause); j < n && !Result; j++) { |
| |
| Atom = clause_LiteralAtom(clause_GetLiteral(Clause, j)); |
| |
| if (fol_IsEquality(Atom) && |
| !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause, j)) && |
| term_Equal(term_FirstArgument(Atom),term_SecondArgument(Atom))) |
| Result = TRUE; |
| |
| for (i = clause_FirstLitIndex(); i <= la && !Result; i++) |
| if (term_Equal(Atom, clause_LiteralAtom(clause_GetLiteral(Clause, i)))) |
| Result = TRUE; |
| } |
| |
| |
| if (!Result && |
| flag_GetFlagValue(Flags, flag_RTAUT) == flag_RTAUTSEMANTIC && |
| clause_NumOfAnteLits(Clause) != 0 && |
| clause_NumOfSuccLits(Clause) != 0) { |
| Result = cc_Tautology(Clause); |
| } |
| |
| if (Result && flag_GetFlagValue(Flags, flag_PTAUT)) { |
| fputs("\nTautology: ", stdout); |
| clause_Print(Clause); |
| } |
| return Result; |
| } |
| |
| static LITERAL red_GetMRResLit(LITERAL ActLit, SHARED_INDEX ShIndex) |
| /************************************************************** |
| INPUT: A literal and an Index. |
| RETURNS: The most valid clause with a complementary literal, |
| (CLAUSE)NULL, if no such clause exists. |
| ***************************************************************/ |
| { |
| LITERAL NextLit; |
| int i; |
| CLAUSE ActClause; |
| TERM CandTerm; |
| LIST LitScan; |
| |
| NextLit = (LITERAL)NULL; |
| ActClause = clause_LiteralOwningClause(ActLit); |
| i = clause_LiteralGetIndex(ActLit); |
| CandTerm = st_ExistGen(cont_LeftContext(), |
| sharing_Index(ShIndex), |
| clause_LiteralAtom(ActLit)); |
| |
| while (CandTerm) { /* First check units */ |
| if (!term_IsVariable(CandTerm)) { /* Has to be an Atom! */ |
| LitScan = sharing_NAtomDataList(CandTerm); /* CAUTION !!! the List is not a copy */ |
| while (!list_Empty(LitScan)) { |
| NextLit = list_Car(LitScan); |
| if (clause_LiteralsAreComplementary(ActLit,NextLit)) |
| if (clause_Length(clause_LiteralOwningClause(NextLit)) == 1 || |
| subs_SubsumesBasic(clause_LiteralOwningClause(NextLit),ActClause, |
| clause_LiteralGetIndex(NextLit),i)) { |
| st_CancelExistRetrieval(); |
| return NextLit; |
| } |
| LitScan = list_Cdr(LitScan); |
| } |
| } |
| CandTerm = st_NextCandidate(); |
| } |
| return (LITERAL)NULL; |
| } |
| |
| static void red_DocumentMatchingReplacementResolution(CLAUSE Clause, LIST LitInds, |
| LIST ClauseNums, LIST PLitInds) |
| /********************************************************* |
| INPUT: A clause, the involved literals indices in <Clause>, |
| the literal indices of the reduction literals |
| and the clauses number. |
| RETURNS: Nothing. |
| MEMORY: All input lists are consumed. |
| **********************************************************/ |
| { |
| LIST Scan,Help; |
| |
| Help = list_Nil(); |
| |
| for (Scan=LitInds; !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| Help = list_Cons((POINTER)clause_Number(Clause), Help); |
| /* Has to be done before increasing the clause number! */ |
| } |
| list_Delete(clause_ParentClauses(Clause)); |
| list_Delete(clause_ParentLiterals(Clause)); |
| clause_SetParentClauses(Clause, list_Nconc(Help,ClauseNums)); |
| clause_SetParentLiterals(Clause, list_Nconc(LitInds,PLitInds)); |
| |
| clause_SetNumber(Clause, clause_IncreaseCounter()); |
| clause_SetFromMatchingReplacementResolution(Clause); |
| } |
| |
| static BOOL red_MatchingReplacementResolution(CLAUSE Clause, SHARED_INDEX ShIndex, |
| FLAGSTORE Flags, PRECEDENCE Precedence, |
| CLAUSE *Changed, int Level) |
| /************************************************************** |
| INPUT: A clause, an Index, a flag store, a precedence and a |
| split level indicating the need of a copy if |
| <Clause> is reduced by a clause of higher split |
| level than <Level>. |
| RETURNS: TRUE if reduction wrt the indexed clauses was |
| possible. |
| If the <DocProof> flag is true or the clauses used |
| for reductions have a higher split level then a |
| changed copy is returned in <*Changed>. |
| Otherwise <Clause> is destructively changed. |
| ***************************************************************/ |
| { |
| CLAUSE PClause,Copy; |
| LITERAL ActLit,PLit; |
| int i, j, length; |
| LIST ReducedBy,ReducedLits,PLits,Scan1,Scan2; |
| BOOL Document; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(Clause, Flags, Precedence) || |
| (*Changed != (CLAUSE)NULL)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_MatchingReplacementResolution:"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(Clause, Flags, Precedence); |
| #endif |
| |
| Copy = Clause; |
| length = clause_Length(Clause); |
| ReducedBy = list_Nil(); |
| ReducedLits = list_Nil(); |
| PLits = list_Nil(); |
| i = clause_FirstLitIndex(); |
| j = 0; |
| Document = flag_GetFlagValue(Flags, flag_DOCPROOF); |
| |
| while (i < length) { |
| ActLit = clause_GetLiteral(Copy, i); |
| |
| if (!fol_IsEquality(clause_LiteralAtom(ActLit)) || /* Reduce with negative equations. */ |
| clause_LiteralIsPositive(ActLit)) { |
| PLit = red_GetMRResLit(ActLit, ShIndex); |
| if (clause_LiteralExists(PLit)) { |
| if (list_Empty(PLits) && flag_GetFlagValue(Flags, flag_PMRR)) { |
| fputs("\nFMatchingReplacementResolution: ", stdout); |
| clause_Print(Copy); |
| } |
| PClause = clause_LiteralOwningClause(PLit); |
| ReducedBy = list_Cons((POINTER)clause_Number(PClause), ReducedBy); |
| PLits = list_Cons((POINTER)clause_LiteralGetIndex(PLit),PLits); |
| ReducedLits = list_Cons((POINTER)(i+j), ReducedLits); |
| if (Copy == Clause && |
| (Document || prfs_SplitLevelCondition(clause_SplitLevel(PClause),clause_SplitLevel(Copy),Level))) |
| Copy = clause_Copy(Clause); |
| clause_UpdateSplitDataFromPartner(Copy, PClause); |
| clause_DeleteLiteral(Copy,i, Flags, Precedence); |
| length--; |
| j++; |
| } |
| else |
| i++; |
| } |
| else |
| i++; |
| } |
| |
| if (!list_Empty(ReducedBy)) { |
| if (Document) { |
| ReducedBy = list_NReverse(ReducedBy); |
| ReducedLits = list_NReverse(ReducedLits); |
| PLits = list_NReverse(PLits); |
| red_DocumentMatchingReplacementResolution(Copy, ReducedLits, ReducedBy, PLits); /* Lists are consumed */ |
| if (flag_GetFlagValue(Flags, flag_PMRR)) { |
| fputs(" ==> [ ", stdout); |
| for(Scan1=ReducedBy,Scan2=ReducedLits;!list_Empty(Scan1); |
| Scan1=list_Cdr(Scan1),Scan2=list_Cdr(Scan2)) |
| printf("%d.%d ",(NAT)list_Car(Scan1),(NAT)list_Car(Scan2)); |
| fputs("] ", stdout); |
| clause_Print(Copy); |
| } |
| } |
| else { |
| if (flag_GetFlagValue(Flags, flag_PMRR)) { |
| fputs(" ==> [ ", stdout); |
| for(Scan1=ReducedBy,Scan2=ReducedLits;!list_Empty(Scan1); |
| Scan1=list_Cdr(Scan1),Scan2=list_Cdr(Scan2)) |
| printf("%d.%d ",(NAT)list_Car(Scan1),(NAT)list_Car(Scan2)); |
| fputs("] ", stdout); |
| clause_Print(Copy); |
| } |
| list_Delete(ReducedBy); |
| list_Delete(ReducedLits); |
| list_Delete(PLits); |
| } |
| if (Copy != Clause) |
| *Changed = Copy; |
| return TRUE; |
| } |
| return FALSE; |
| } |
| |
| static void red_DocumentUnitConflict(CLAUSE Clause, LIST LitInds, |
| LIST ClauseNums, LIST PLitInds) |
| /********************************************************* |
| INPUT: A clause, the involved literals indices and the clauses number. |
| RETURNS: Nothing. |
| MEMORY: All input lists are consumed. |
| **********************************************************/ |
| { |
| list_Delete(clause_ParentClauses(Clause)); |
| list_Delete(clause_ParentLiterals(Clause)); |
| clause_SetParentClauses(Clause, list_Nconc(list_List((POINTER)clause_Number(Clause)),ClauseNums)); |
| clause_SetParentLiterals(Clause, list_Nconc(LitInds,PLitInds)); |
| |
| clause_SetNumber(Clause, clause_IncreaseCounter()); |
| clause_SetFromUnitConflict(Clause); |
| } |
| |
| |
| static BOOL red_UnitConflict(CLAUSE Clause, SHARED_INDEX ShIndex, |
| FLAGSTORE Flags, PRECEDENCE Precedence, |
| CLAUSE *Changed, int Level) |
| /************************************************************** |
| INPUT: A clause, an Index, a flag store and a splitlevel |
| indicating the need of a copy if <Clause> is reduced |
| by a clause of higher split level than <Level>. |
| RETURNS: TRUE if a unit conflict with <Clause> and the |
| clauses in <ShIndex> happened. |
| If the <DocProof> flag is true or the clauses used for |
| reductions have a higher split level then a changed |
| copy is returned in <*Changed>. |
| Otherwise <Clause> is destructively changed. |
| ***************************************************************/ |
| { |
| CLAUSE PClause,Copy; |
| LITERAL ActLit,PLit; |
| LIST Scan; |
| TERM CandTerm; |
| BOOL Document; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(Clause, Flags, Precedence) || (*Changed != (CLAUSE)NULL)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_ForwardUnitConflict :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(Clause, Flags, Precedence); |
| #endif |
| |
| if (clause_Length(Clause) == 1) { |
| Copy = Clause; |
| Document = flag_GetFlagValue(Flags, flag_DOCPROOF); |
| ActLit = clause_GetLiteral(Copy, clause_FirstLitIndex()); |
| PLit = (LITERAL)NULL; |
| CandTerm = st_ExistUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), |
| clause_LiteralAtom(ActLit)); |
| while (PLit == (LITERAL)NULL && CandTerm) { |
| if (!term_IsVariable(CandTerm)) { |
| Scan = sharing_NAtomDataList(CandTerm); /* CAUTION !!! the List is not a copy */ |
| while (!list_Empty(Scan)) { |
| PLit = list_Car(Scan); |
| if (clause_LiteralsAreComplementary(ActLit,PLit) && |
| clause_Length(clause_LiteralOwningClause(PLit)) == 1) { |
| st_CancelExistRetrieval(); |
| Scan = list_Nil(); |
| } |
| else { |
| PLit = (LITERAL)NULL; |
| Scan = list_Cdr(Scan); |
| } |
| } |
| } |
| if (PLit == (LITERAL)NULL) |
| CandTerm = st_NextCandidate(); |
| } |
| |
| if (PLit == (LITERAL)NULL && fol_IsEquality(clause_LiteralAtom(ActLit))) { |
| TERM Atom; |
| Atom = term_Create(fol_Equality(),list_Reverse(term_ArgumentList(clause_LiteralAtom(ActLit)))); |
| CandTerm = st_ExistUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Atom); |
| while (PLit == (LITERAL)NULL && CandTerm) { |
| if (!term_IsVariable(CandTerm)) { |
| Scan = sharing_NAtomDataList(CandTerm); /* CAUTION !!! the List is not a copy */ |
| while (!list_Empty(Scan)) { |
| PLit = list_Car(Scan); |
| if (clause_LiteralsAreComplementary(ActLit,PLit) && |
| clause_Length(clause_LiteralOwningClause(PLit)) == 1) { |
| st_CancelExistRetrieval(); |
| Scan = list_Nil(); |
| } |
| else { |
| PLit = (LITERAL)NULL; |
| Scan = list_Cdr(Scan); |
| } |
| } |
| } |
| if (PLit == (LITERAL)NULL) |
| CandTerm = st_NextCandidate(); |
| } |
| list_Delete(term_ArgumentList(Atom)); |
| term_Free(Atom); |
| } |
| |
| if (clause_LiteralExists(PLit)) { |
| if (flag_GetFlagValue(Flags, flag_PUNC)) { |
| fputs("\nUnitConflict: ", stdout); |
| clause_Print(Copy); |
| } |
| PClause = clause_LiteralOwningClause(PLit); |
| if (Copy == Clause && |
| (Document || prfs_SplitLevelCondition(clause_SplitLevel(PClause),clause_SplitLevel(Copy),Level))) |
| Copy = clause_Copy(Clause); |
| clause_UpdateSplitDataFromPartner(Copy, PClause); |
| clause_DeleteLiteral(Copy,clause_FirstLitIndex(), Flags, Precedence); |
| if (Document) |
| red_DocumentUnitConflict(Copy, list_List((POINTER)clause_FirstLitIndex()), |
| list_List((POINTER)clause_Number(PClause)), |
| list_List((POINTER)clause_FirstLitIndex())); |
| if (flag_GetFlagValue(Flags, flag_PUNC)) { |
| printf(" ==> [ %d.%d ]", clause_Number(PClause), clause_FirstLitIndex()); |
| clause_Print(Copy); |
| } |
| if (Copy != Clause) |
| *Changed = Copy; |
| return TRUE; |
| } |
| } |
| return FALSE; |
| } |
| |
| |
| static CLAUSE red_ForwardSubsumer(CLAUSE RedCl, SHARED_INDEX ShIndex, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /********************************************************** |
| INPUT: A pointer to a non-empty clause, an index of |
| clauses, a flag store and a precedence. |
| RETURNS: A clause that subsumes <RedCl>, or NULL if no such |
| clause exists. |
| ***********************************************************/ |
| { |
| TERM Atom,AtomGen; |
| CLAUSE CandCl; |
| LITERAL CandLit; |
| LIST LitScan; |
| int i, lc, fa, la, fs, ls; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RedCl, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_ForwardSubsumer:"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedCl, Flags, Precedence); |
| #endif |
| |
| lc = clause_LastConstraintLitIndex(RedCl); |
| fa = clause_FirstAntecedentLitIndex(RedCl); |
| la = clause_LastAntecedentLitIndex(RedCl); |
| fs = clause_FirstSuccedentLitIndex(RedCl); |
| ls = clause_LastSuccedentLitIndex(RedCl); |
| |
| for (i = 0; i <= ls; i++) { |
| Atom = clause_GetLiteralAtom(RedCl, i); |
| AtomGen = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), Atom); |
| |
| while (AtomGen) { |
| if (!term_IsVariable(AtomGen)) { |
| for (LitScan = sharing_NAtomDataList(AtomGen); |
| !list_Empty(LitScan); |
| LitScan = list_Cdr(LitScan)) { |
| CandLit = list_Car(LitScan); |
| CandCl = clause_LiteralOwningClause(CandLit); |
| |
| if (CandCl != RedCl && |
| clause_GetLiteral(CandCl,clause_FirstLitIndex()) == CandLit && |
| /* Literals must be from same part of the clause */ |
| ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) || |
| (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) || |
| (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) && |
| subs_SubsumesBasic(CandCl, RedCl, clause_FirstLitIndex(), i)) { |
| st_CancelExistRetrieval(); |
| return (CandCl); |
| } |
| } |
| } |
| AtomGen = st_NextCandidate(); |
| } |
| |
| if (fol_IsEquality(Atom) && |
| clause_LiteralIsNotOrientedEquality(clause_GetLiteral(RedCl,i))) { |
| Atom = term_Create(fol_Equality(),list_Reverse(term_ArgumentList(Atom))); |
| AtomGen = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), Atom); |
| while (AtomGen) { |
| if (!term_IsVariable(AtomGen)) { |
| for (LitScan = sharing_NAtomDataList(AtomGen); |
| !list_Empty(LitScan); |
| LitScan = list_Cdr(LitScan)) { |
| CandLit = list_Car(LitScan); |
| CandCl = clause_LiteralOwningClause(CandLit); |
| if (CandCl != RedCl && |
| clause_GetLiteral(CandCl,clause_FirstLitIndex()) == CandLit && |
| /* Literals must be from same part of the clause */ |
| ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) || |
| (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) || |
| (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) && |
| subs_SubsumesBasic(CandCl, RedCl, clause_FirstLitIndex(), i)) { |
| st_CancelExistRetrieval(); |
| list_Delete(term_ArgumentList(Atom)); |
| term_Free(Atom); |
| return (CandCl); |
| } |
| } |
| } |
| AtomGen = st_NextCandidate(); |
| } |
| list_Delete(term_ArgumentList(Atom)); |
| term_Free(Atom); |
| } |
| } |
| |
| return((CLAUSE)NULL); |
| } |
| |
| |
| static CLAUSE red_ForwardSubsumption(CLAUSE RedClause, SHARED_INDEX ShIndex, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /********************************************************** |
| INPUT: A clause, an index of clauses, a flag store and |
| a precedence. |
| RETURNS: The clause <RedClause> is subsumed by in <ShIndex>. |
| ***********************************************************/ |
| { |
| CLAUSE Subsumer; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RedClause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_ForwardSubsumption:"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| Subsumer = red_ForwardSubsumer(RedClause, ShIndex, Flags, Precedence); |
| |
| if (flag_GetFlagValue(Flags, flag_PSUB) && Subsumer) { |
| fputs("\nFSubsumption: ", stdout); |
| clause_Print(RedClause); |
| printf(" by %d %d ",clause_Number(Subsumer),clause_SplitLevel(Subsumer)); |
| } |
| |
| return Subsumer; |
| } |
| |
| |
| static void red_DocumentRewriting(CLAUSE Clause, int i, CLAUSE Rule, int ri) |
| /********************************************************* |
| INPUT: Two clauses and the literal indices involved in the rewrite step. |
| RETURNS: Nothing. |
| EFFECT: Documentation in <Clause> is set. |
| **********************************************************/ |
| { |
| list_Delete(clause_ParentClauses(Clause)); |
| list_Delete(clause_ParentLiterals(Clause)); |
| clause_SetParentClauses(Clause, |
| list_List((POINTER)clause_Number(Clause))); |
| /* Has to be done before increasing the number! */ |
| |
| clause_SetParentLiterals(Clause, list_List((POINTER)i)); |
| clause_NewNumber(Clause); |
| clause_SetFromRewriting(Clause); |
| |
| clause_AddParentClause(Clause,clause_Number(Rule)); |
| clause_AddParentLiteral(Clause,ri); |
| } |
| |
| |
| static void red_DocumentFurtherRewriting(CLAUSE Clause, int i, CLAUSE Rule, int ri) |
| /********************************************************* |
| INPUT: Two clauses and the literal indices involved in the rewrite step. |
| RETURNS: Nothing. |
| EFFECT: Documentation in <Clause> is set. |
| **********************************************************/ |
| { |
| clause_AddParentClause(Clause, |
| (int) list_Car(list_Cdr(clause_ParentClauses(Clause)))); |
| clause_AddParentLiteral(Clause, i); |
| clause_AddParentClause(Clause, clause_Number(Rule)); |
| clause_AddParentLiteral(Clause, ri); |
| } |
| |
| |
| static BOOL red_RewriteRedUnitClause(CLAUSE RedClause, SHARED_INDEX ShIndex, |
| FLAGSTORE Flags, PRECEDENCE Precedence, |
| CLAUSE *Changed, int Level) |
| /************************************************************** |
| INPUT: A unit (!) clause, an Index, a flag store, a |
| precedence and a split level indicating the need of |
| a copy if <Clause> is reduced by a clause of higher |
| split level than <Level>. |
| RETURNS: TRUE iff rewriting was possible. |
| If the <DocProof> flag is true or the split level of |
| the rewrite rule is higher a copy of RedClause that |
| is rewritten wrt. the indexed clauses is returned in |
| <*Changed>. |
| Otherwise the clause is destructively rewritten. |
| ***************************************************************/ |
| { |
| TERM RedAtom, RedTermS; |
| int B_Stack; |
| BOOL Rewritten, Result, Oriented, Renamed, Document; |
| TERM TermS,PartnerEq; |
| LIST EqList,EqScan,LitScan; |
| CLAUSE Copy; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RedClause, Flags, Precedence) || |
| *Changed != (CLAUSE)NULL || |
| clause_Length(RedClause) != 1) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_RewriteRedUnitClause :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| Result = FALSE; |
| Renamed = FALSE; |
| Copy = RedClause; |
| RedAtom = clause_GetLiteralAtom(Copy, clause_FirstLitIndex()); |
| Rewritten = TRUE; |
| Document = flag_GetFlagValue(Flags, flag_DOCPROOF); |
| |
| /* Don't apply this rule on constraint or propositional literals */ |
| if (clause_FirstLitIndex() <= clause_LastConstraintLitIndex(RedClause) || |
| list_Empty(term_ArgumentList(RedAtom))) |
| return Result; |
| |
| if (term_StampOverflow(red_STAMPID)) |
| term_ResetTermStamp(clause_LiteralSignedAtom(clause_GetLiteral(RedClause, clause_FirstLitIndex()))); |
| term_StartStamp(); |
| |
| while (Rewritten) { |
| Rewritten = FALSE; |
| B_Stack = stack_Bottom(); |
| sharing_PushListOnStackNoStamps(term_ArgumentList(RedAtom)); |
| |
| while (!stack_Empty(B_Stack)) { |
| RedTermS = (TERM)stack_PopResult(); |
| TermS = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), RedTermS); |
| while (TermS && !Rewritten) { |
| EqList = term_SupertermList(TermS); |
| for (EqScan = EqList; !list_Empty(EqScan) && !Rewritten; |
| EqScan = list_Cdr(EqScan)) { |
| PartnerEq = list_Car(EqScan); |
| if (fol_IsEquality(PartnerEq)) { |
| CLAUSE RewriteClause; |
| LITERAL RewriteLit; |
| TERM Right; |
| |
| if (TermS == term_FirstArgument(PartnerEq)) |
| Right = term_SecondArgument(PartnerEq); |
| else |
| Right = term_FirstArgument(PartnerEq); |
| |
| for (LitScan = sharing_NAtomDataList(PartnerEq); |
| !list_Empty(LitScan) && !Rewritten; |
| LitScan = list_Cdr(LitScan)) { |
| RewriteLit = list_Car(LitScan); |
| RewriteClause = clause_LiteralOwningClause(RewriteLit); |
| if (clause_LiteralIsPositive(RewriteLit) && |
| clause_Length(RewriteClause) == 1) { |
| Oriented = (clause_LiteralIsOrientedEquality(RewriteLit) && |
| TermS == term_FirstArgument(PartnerEq)); |
| if (!Oriented && !clause_LiteralIsOrientedEquality(RewriteLit)) { |
| Renamed = TRUE; /* If oriented, no renaming needed! */ |
| term_StartMaxRenaming(clause_MaxVar(RewriteClause)); |
| term_Rename(RedAtom); /* Renaming destructive, no extra match needed !! */ |
| Oriented = ord_ContGreater(cont_LeftContext(), TermS, |
| cont_LeftContext(), Right, |
| Flags, Precedence); |
| |
| /*if (Oriented) { |
| fputs("\n\n\tRedAtom: ",stdout);term_PrintPrefix(RedAtom); |
| fputs("\n\tSubTerm: ",stdout);term_PrintPrefix(RedTermS); |
| fputs("\n\tGenTerm: ",stdout);term_PrintPrefix(TermS); |
| fputs("\n\tGenRight: ",stdout);term_PrintPrefix(Right); |
| putchar('\n');cont_PrintCurrentTrail();putchar('\n'); |
| }*/ |
| } |
| if (Oriented) { |
| TERM TermT; |
| |
| if (RedClause == Copy && |
| (Document || |
| prfs_SplitLevelCondition(clause_SplitLevel(RewriteClause), |
| clause_SplitLevel(RedClause),Level))) { |
| Copy = clause_Copy(RedClause); |
| RedAtom = clause_GetLiteralAtom(Copy, clause_FirstLitIndex()); |
| } |
| |
| if (!Result) |
| if (flag_GetFlagValue(Flags, flag_PREW)) { |
| fputs("\nFRewriting: ", stdout); |
| clause_Print(Copy); |
| fputs(" ==>[ ", stdout); |
| } |
| |
| if (Document) { |
| if (!Result) |
| red_DocumentRewriting(Copy, clause_FirstLitIndex(), |
| RewriteClause, clause_FirstLitIndex()); |
| else |
| red_DocumentFurtherRewriting(Copy, clause_FirstLitIndex(), |
| RewriteClause, clause_FirstLitIndex()); |
| } |
| Result = TRUE; |
| TermT = cont_ApplyBindingsModuloMatching(cont_LeftContext(), term_Copy(Right), TRUE); |
| if (cont_BindingsAreRenamingModuloMatching(cont_RightContext())) |
| term_SetTermSubtermStamp(TermT); |
| term_ReplaceSubtermBy(RedAtom, RedTermS, TermT); |
| Rewritten = TRUE; |
| clause_UpdateSplitDataFromPartner(Copy, RewriteClause); |
| term_Delete(TermT); |
| stack_SetBottom(B_Stack); |
| |
| if (flag_GetFlagValue(Flags, flag_PREW)) |
| printf("%d.%d ",clause_Number(RewriteClause), clause_FirstLitIndex()); |
| clause_UpdateWeight(Copy, Flags); |
| } |
| } |
| } |
| } |
| } |
| if (!Rewritten) |
| TermS = st_NextCandidate(); |
| } |
| st_CancelExistRetrieval(); |
| if (!Rewritten) |
| term_SetTermStamp(RedTermS); |
| } |
| } |
| term_StopStamp(); |
| |
| if (Result) { |
| clause_OrientAndReInit(Copy, Flags, Precedence); |
| if (Copy != RedClause) |
| clause_OrientAndReInit(RedClause, Flags, Precedence); |
| if (flag_GetFlagValue(Flags, flag_PREW)) { |
| fputs("] ", stdout); |
| clause_Print(Copy); |
| } |
| if (Copy != RedClause) |
| *Changed = Copy; |
| } |
| else |
| if (Renamed) |
| clause_OrientAndReInit(Copy, Flags, Precedence); |
| |
| |
| #ifdef CHECK |
| clause_Check(Copy, Flags, Precedence); |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| return Result; |
| } |
| |
| |
| static BOOL red_RewriteRedClause(CLAUSE RedClause, SHARED_INDEX ShIndex, |
| FLAGSTORE Flags, PRECEDENCE Precedence, |
| CLAUSE *Changed, int Level) |
| /************************************************************** |
| INPUT: A clause, an Index, a flag store, a precedence and |
| a split level indicating the need of a copy if |
| <Clause> is reduced by a clause of higher split |
| level than <Level>. |
| RETURNS: NULL, if no rewriting was possible. |
| If the <DocProof> flag is true or the split level of |
| the rewrite rule is higher a copy of RedClause |
| that is rewritten wrt. the indexed clauses. |
| Otherwise the clause is destructively rewritten and |
| returned. |
| ***************************************************************/ |
| { |
| TERM RedAtom, RedTermS; |
| int B_Stack; |
| int ci, length; |
| BOOL Rewritten, Result, Document; |
| TERM TermS,PartnerEq; |
| LIST EqScan,LitScan; |
| CLAUSE Copy; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RedClause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_RewriteRedClause :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| length = clause_Length(RedClause); |
| Document = flag_GetFlagValue(Flags, flag_DOCPROOF); |
| |
| if (length == 1) |
| return red_RewriteRedUnitClause(RedClause, ShIndex, Flags, Precedence, |
| Changed, Level); |
| |
| Result = FALSE; |
| Copy = RedClause; |
| |
| /* Don't apply this rule on constraint literals! */ |
| for (ci = clause_FirstAntecedentLitIndex(RedClause); ci < length; ci++) { |
| Rewritten = TRUE; |
| if (!list_Empty(term_ArgumentList(clause_GetLiteralAtom(Copy, ci)))) { |
| while (Rewritten) { |
| Rewritten = FALSE; |
| RedAtom = clause_GetLiteralAtom(Copy, ci); |
| |
| B_Stack = stack_Bottom(); |
| /* push subterms on stack except variables */ |
| sharing_PushListReverseOnStack(term_ArgumentList(RedAtom)); |
| |
| while (!stack_Empty(B_Stack)) { |
| RedTermS = (TERM)stack_PopResult(); |
| TermS = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), RedTermS); |
| |
| while (TermS && !Rewritten) { |
| /* A variable can't be greater than any other term, */ |
| /* so don't consider any variables here */ |
| if (!term_IsVariable(TermS)) { |
| EqScan = term_SupertermList(TermS); |
| |
| for ( ; !list_Empty(EqScan) && !Rewritten; |
| EqScan = list_Cdr(EqScan)) { |
| PartnerEq = list_Car(EqScan); |
| if (fol_IsEquality(PartnerEq) && |
| (term_FirstArgument(PartnerEq) == TermS)) { |
| CLAUSE RewriteClause; |
| LITERAL RewriteLit; |
| int ri; |
| |
| for (LitScan = sharing_NAtomDataList(PartnerEq); |
| !list_Empty(LitScan) && !Rewritten; |
| LitScan = list_Cdr(LitScan)) { |
| RewriteLit = list_Car(LitScan); |
| RewriteClause = clause_LiteralOwningClause(RewriteLit); |
| ri = clause_LiteralGetIndex(RewriteLit); |
| |
| if (clause_LiteralIsPositive(RewriteLit) && |
| clause_LiteralIsOrientedEquality(RewriteLit) && |
| subs_SubsumesBasic(RewriteClause, Copy, ri, ci)) { |
| TERM TermT; |
| |
| if (RedClause == Copy && |
| (Document || |
| prfs_SplitLevelCondition(clause_SplitLevel(RewriteClause), |
| clause_SplitLevel(RedClause),Level))) { |
| Copy = clause_Copy(RedClause); |
| RedAtom = clause_GetLiteralAtom(Copy, ci); |
| } |
| |
| if (!Result) { |
| if (flag_GetFlagValue(Flags, flag_PREW)) { |
| fputs("\nFRewriting: ", stdout); |
| clause_Print(Copy); |
| fputs(" ==>[ ", stdout); |
| } |
| } |
| |
| if (Document) { |
| if (!Result) |
| red_DocumentRewriting(Copy, ci, RewriteClause, ri); |
| else |
| red_DocumentFurtherRewriting(Copy,ci,RewriteClause,ri); |
| } |
| Result = TRUE; |
| /* Since <TermS> is the bigger term of an oriented */ |
| /* equation and all variables in <TermS> are bound, */ |
| /* all variables in the smaller term are bound, too. */ |
| /* So the strict version of cont_Apply... will work. */ |
| TermT = cont_ApplyBindingsModuloMatching(cont_LeftContext(), |
| term_Copy(term_SecondArgument(PartnerEq)), |
| TRUE); |
| |
| /* No variable renaming is necessary before creation */ |
| /* of bindings and replacement of subterms because all */ |
| /* variables of <TermT> are from <RedClause>/<Copy>. */ |
| term_ReplaceSubtermBy(RedAtom, RedTermS, TermT); |
| Rewritten = TRUE; |
| clause_UpdateSplitDataFromPartner(Copy,RewriteClause); |
| term_Delete(TermT); |
| stack_SetBottom(B_Stack); |
| |
| if (flag_GetFlagValue(Flags, flag_PREW)) |
| printf("%d.%d ",clause_Number(RewriteClause), ri); |
| clause_UpdateWeight(Copy, Flags); |
| } |
| } |
| } |
| } |
| } |
| if (!Rewritten) |
| TermS = st_NextCandidate(); |
| } |
| st_CancelExistRetrieval(); |
| } |
| } |
| } |
| } |
| if (Result) { |
| clause_OrientAndReInit(Copy, Flags, Precedence); |
| if (flag_GetFlagValue(Flags, flag_PREW)) { |
| fputs("] ", stdout); |
| clause_Print(Copy); |
| } |
| if (Copy != RedClause) { |
| clause_OrientAndReInit(RedClause, Flags, Precedence); |
| *Changed = Copy; |
| } |
| } |
| |
| #ifdef CHECK |
| clause_Check(Copy, Flags, Precedence); |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| return Result; |
| } |
| |
| |
| /**************************************************************/ |
| /* FORWARD CONTEXTUAL REWRITING */ |
| /**************************************************************/ |
| |
| static BOOL red_LeftTermOfEquationIsStrictlyMaximalTerm(CLAUSE Clause, |
| LITERAL Equation, |
| FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause, a literal of the clause, that is an |
| oriented equation, a flag store and a precedence. |
| RETURNS: TRUE, iff the bigger (i.e. left) term of the equation |
| is the strictly maximal term of the clause. |
| A term s is strictly maximal in a clause, iff for every atom |
| u=v (A=tt) of the clause s > u and s > v (s > A). |
| ***************************************************************/ |
| { |
| int i, except, last; |
| TERM LeftTerm, Atom; |
| LITERAL ActLit; |
| |
| #ifdef CHECK |
| if (!clause_LiteralIsOrientedEquality(Equation)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_LeftTermOfEquationIsStrictlyMaximalTerm: "); |
| misc_ErrorReport("literal is not oriented"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| LeftTerm = term_FirstArgument(clause_LiteralSignedAtom(Equation)); |
| except = clause_LiteralGetIndex(Equation); |
| |
| /* Compare <LeftTerm> with all terms in the clause */ |
| last = clause_LastLitIndex(Clause); |
| for (i = clause_FirstLitIndex() ; i <= last; i++) { |
| if (i != except) { |
| ActLit = clause_GetLiteral(Clause, i); |
| Atom = clause_LiteralAtom(ActLit); |
| if (fol_IsEquality(Atom)) { |
| /* Atom is an equation */ |
| if (ord_Compare(LeftTerm, term_FirstArgument(Atom), Flags, Precedence) |
| != ord_GREATER_THAN || |
| (!clause_LiteralIsOrientedEquality(ActLit) && |
| ord_Compare(LeftTerm, term_SecondArgument(Atom), Flags, Precedence) |
| != ord_GREATER_THAN)) |
| /* Compare only with left (i.e. greater) subterm if the atom is */ |
| /* an oriented equation. */ |
| return FALSE; |
| } else { |
| /* Atom is not an equation */ |
| if (ord_Compare(LeftTerm, Atom, Flags, Precedence) != ord_GREATER_THAN) |
| return FALSE; |
| } |
| } |
| } |
| return TRUE; |
| } |
| |
| |
| static void red_CRwCalculateAdditionalParents(CLAUSE Reduced, |
| LIST RedundantClauses, |
| CLAUSE Subsumer, |
| int OriginalClauseNumber) |
| /************************************************************** |
| INPUT: A clause that was just reduced by forward reduction, |
| a list of intermediate clauses that were derived from |
| the original clause, a clause that subsumes <Reduced> |
| (NULL, if <Reduced> is not subsumed), and the clause |
| number of <Reduced> before it was reduced. |
| RETURNS: Nothing. |
| EFFECT: This function collects the information about parent |
| clauses and parent literals that is necessary for |
| proof documentation for Contextual Rewriting |
| and sets the parent information of <Reduced> accordingly. |
| The clause <Reduced> was derived in several steps |
| C1 -> C2 -> ... Cn -> <Reduced> from some clause C1. |
| <RedundantClauses> contains all those clauses C1, ..., Cn. |
| This function first collects the parent information from |
| the clauses C1, C2, ..., Cn, <Reduced>. All those clauses |
| were needed to derive <Reduced>, but for proof documentation |
| of the rewriting step we have to delete the numbers of |
| all clauses C1,...,Cn,Reduced. |
| |
| As a simplification this function doesn't set the |
| correct parent literals. It simply assumes that every |
| reduction step was done by literal 0. |
| This isn't a problem since only the correct parent |
| clause numbers are really needed for proof documentation. |
| ***************************************************************/ |
| { |
| LIST Parents, Scan; |
| int ActNum; |
| |
| /* First collect all parent clause numbers from the redundant clauses. */ |
| /* Also add number of <Subsumer> if it exists. */ |
| Parents = clause_ParentClauses(Reduced); |
| clause_SetParentClauses(Reduced, list_Nil()); |
| for (Scan = RedundantClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) |
| Parents = list_Append(clause_ParentClauses(list_Car(Scan)), Parents); |
| if (Subsumer != NULL) |
| Parents = list_Cons((POINTER)clause_Number(Subsumer), Parents); |
| |
| /* Now delete <OriginalClauseNumber> and the numbers of all clauses */ |
| /* that were derived from it. */ |
| Parents = list_PointerDeleteElement(Parents, (POINTER) OriginalClauseNumber); |
| for (Scan = RedundantClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| ActNum = clause_Number(list_Car(Scan)); |
| Parents = list_PointerDeleteElement(Parents, (POINTER) ActNum); |
| } |
| |
| /* Finally set data of result clause <Reduced>. */ |
| Parents = list_PointerDeleteDuplicates(Parents); |
| clause_SetParentClauses(Reduced, Parents); |
| /* Build list of literal numbers: in this simple version we just build */ |
| /* a list with the same length as the parent clauses containing only the */ |
| /* literal indices 0. */ |
| Parents = list_Copy(Parents); |
| for (Scan = Parents; !list_Empty(Scan); Scan = list_Cdr(Scan)) |
| list_Rplaca(Scan, (POINTER)0); |
| list_Delete(clause_ParentLiterals(Reduced)); |
| clause_SetParentLiterals(Reduced, Parents); |
| } |
| |
| |
| static BOOL red_LiteralIsDefinition(LITERAL Literal) |
| /************************************************************** |
| INPUT: A literal. |
| RETURNS: TRUE, iff the literal is a definition, i.e. an equation x=t, |
| where x is a variable and x doesn't occur in t. |
| The function needs time O(1), it is independent of the size |
| of the literal. |
| CAUTION: The orientation of the literal must be correct. |
| ***************************************************************/ |
| { |
| TERM Atom; |
| |
| Atom = clause_LiteralAtom(Literal); |
| if (fol_IsEquality(Atom) && |
| !clause_LiteralIsOrientedEquality(Literal) && |
| (term_IsVariable(term_FirstArgument(Atom)) || |
| term_IsVariable(term_SecondArgument(Atom))) && |
| !term_VariableEqual(term_FirstArgument(Atom), |
| term_SecondArgument(Atom))) |
| return TRUE; |
| else |
| return FALSE; |
| } |
| |
| |
| static BOOL red_PropagateDefinitions(CLAUSE Clause, TERM LeadingTerm, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause, a term, a flag store and a precedence. |
| RETURNS: TRUE, iff any definitions in <Clause> where propagated, |
| false otherwise. |
| |
| Here, a definitions means a negative literal x=t, where |
| x is a variable and x doesn't occur in t. |
| Definitions are only propagated if all terms in the |
| resulting clause would be smaller than <LeadingTerm>. |
| The flag store and the precedence are only needed for |
| term comparisons with respect to the reduction ordering. |
| CAUTION: <Clause> is changed destructively! |
| ***************************************************************/ |
| { |
| LITERAL Lit; |
| TERM Term, Atom; |
| SYMBOL Var; |
| int i, last, j, lj; |
| BOOL success, applied; |
| LIST litsToRemove; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(Clause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_PropagateDefinitions: clause is corrupted."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| applied = FALSE; |
| litsToRemove = list_Nil(); /* collect indices of redundant literals */ |
| last = clause_LastAntecedentLitIndex(Clause); |
| |
| for (i = clause_FirstAntecedentLitIndex(Clause); i <= last; i++) { |
| Lit = clause_GetLiteral(Clause, i); |
| |
| if (red_LiteralIsDefinition(Lit)) { |
| /* <Lit> is an equation x=t where the variable x doesn't occur in t. */ |
| |
| Term = term_FirstArgument(clause_LiteralAtom(Lit)); |
| if (term_IsVariable(Term)) { |
| Var = term_TopSymbol(Term); |
| Term = term_SecondArgument(clause_LiteralAtom(Lit)); |
| } else { |
| Var = term_TopSymbol(term_SecondArgument(clause_LiteralAtom(Lit))); |
| } |
| |
| /* Establish variable binding x -> t in context */ |
| #ifdef CHECK |
| cont_SaveState(); |
| #endif |
| cont_StartBinding(); |
| cont_CreateBinding(cont_LeftContext(), Var, cont_InstanceContext(), Term); |
| |
| /* Check that for each literal u=v (A=tt) the conditions */ |
| /* u{x->t} < LeadingTerm and v{x->t} < LeadingTerm (A < LeadingTerm) */ |
| /* hold. */ |
| success = TRUE; |
| Lit = NULL; |
| lj = clause_LastLitIndex(Clause); |
| |
| for (j = clause_FirstLitIndex(); j <= lj && success; j++) { |
| if (j != i) { |
| success = FALSE; |
| Lit = clause_GetLiteral(Clause, j); |
| Atom = clause_LiteralAtom(Lit); |
| if (fol_IsEquality(Atom)) { |
| /* Atom is an equation */ |
| if (ord_ContGreater(cont_InstanceContext(), LeadingTerm, |
| cont_LeftContext(), term_FirstArgument(Atom), |
| Flags, Precedence) && |
| (clause_LiteralIsOrientedEquality(Lit) || |
| ord_ContGreater(cont_InstanceContext(), LeadingTerm, |
| cont_LeftContext(), term_SecondArgument(Atom), |
| Flags, Precedence))) |
| /* Compare only with left (i.e. greater) subterm if the atom is */ |
| /* an oriented equation. */ |
| success = TRUE; |
| } else { |
| /* Atom is not an equation */ |
| if (ord_ContGreater(cont_InstanceContext(), LeadingTerm, |
| cont_LeftContext(), Atom, Flags, Precedence)) |
| success = TRUE; |
| } |
| } |
| } |
| |
| cont_BackTrack(); |
| |
| #ifdef CHECK |
| cont_CheckState(); |
| #endif |
| |
| if (success) { |
| /* Replace variable <Var> in <Clause> by <Term> */ |
| clause_ReplaceVariable(Clause, Var, Term); |
| /* The clause literals aren't reoriented here. For the detection of */ |
| /* definitions it suffices to know the non-oriented literals in the */ |
| /* original clause. */ |
| litsToRemove = list_Cons((POINTER)i, litsToRemove); |
| applied = TRUE; |
| } |
| } |
| } |
| |
| if (applied) { |
| /* Now remove the definition literals. */ |
| clause_DeleteLiterals(Clause, litsToRemove, Flags, Precedence); |
| list_Delete(litsToRemove); |
| |
| /* Equations have to be reoriented. */ |
| clause_OrientEqualities(Clause, Flags, Precedence); |
| |
| #ifdef CHECK |
| if (!clause_IsClause(Clause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_PropagateDefinitions: clause is corrupted "); |
| misc_ErrorReport("after propagation of definitions"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| } |
| |
| return applied; |
| } |
| |
| |
| static CLAUSE red_CRwLitTautologyCheck(PROOFSEARCH Search, CLAUSE RedClause, |
| int Except, CLAUSE RuleClause, int i, |
| TERM LeadingTerm, NAT Mode) |
| /************************************************************** |
| INPUT: A proof search object, two clauses, two literal indices |
| (one per clause), a mode defining the clause index used |
| for intermediate reductions. |
| RETURNS: NULL, if the tautology check for literal <i> in <RuleClause> |
| failed. |
| |
| If the test succeeds an auxiliary clause is returned that |
| contains part of the splitting information for the current |
| rewriting step. If the 'DocProof' flag is set, the necessary |
| parent information is set, too. |
| MEMORY: Remember to delete the returned clause! |
| ***************************************************************/ |
| { |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| CLAUSE aux, NewClause; |
| LITERAL Lit; |
| TERM Atom; |
| BOOL DocProof, Negative, Redundant; |
| LIST NegLits, PosLits, RedundantList; |
| int OrigNum; |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| DocProof = flag_GetFlagValue(Flags, flag_DOCPROOF); |
| |
| Lit = clause_GetLiteral(RuleClause, i); |
| Atom = clause_LiteralAtom(Lit); |
| Negative = clause_LiteralIsNegative(Lit); |
| |
| #ifdef CRW_DEBUG |
| printf("\n ----------\n "); |
| if (Negative) |
| printf((i <= clause_LastConstraintLitIndex(RuleClause)) ? "Cons" : "Ante"); |
| else |
| printf("Succ"); |
| printf(" aux = "); |
| #endif |
| |
| if (i <= clause_LastConstraintLitIndex(RuleClause)) { |
| |
| /* Apply Sort Simplification for constraint literals only */ |
| NegLits = list_List(term_Copy(Atom)); |
| aux = clause_Create(NegLits, list_Nil(), list_Nil(), Flags, Precedence); |
| clause_SetTemporary(aux); |
| list_Delete(NegLits); |
| |
| #ifdef CRW_DEBUG |
| clause_Print(aux); |
| #endif |
| |
| NewClause = NULL; |
| OrigNum = clause_Number(aux); |
| if (red_SortSimplification(prfs_DynamicSortTheory(Search), aux, NAT_MAX, |
| DocProof, Flags, Precedence, &NewClause)) { |
| /* Sort Simplification was possible, so the unit clause was reduced */ |
| /* to the empty clause. */ |
| |
| /* The splitting information is already set in <aux> or <NewClause>. */ |
| if (DocProof) |
| /* If 'DocProof' is turned on, a copy was created and assigned */ |
| /* to <NewClause>. */ |
| red_CRwCalculateAdditionalParents(NewClause, list_Nil(), NULL, OrigNum); |
| |
| if (NewClause != NULL) { |
| clause_Delete(aux); |
| return NewClause; |
| } else |
| return aux; |
| } |
| clause_Delete(aux); |
| |
| #ifdef CRW_DEBUG |
| printf("\n Cons aux2 = "); |
| #endif |
| } |
| |
| /* Collect literals for tautology test */ |
| if (Negative) { |
| if (i <= clause_LastConstraintLitIndex(RuleClause)) |
| NegLits = clause_CopyConstraint(RedClause); |
| else |
| NegLits = clause_CopyAntecedentExcept(RedClause, Except); |
| PosLits = list_List(term_Copy(Atom)); |
| } else { |
| NegLits = list_List(term_Copy(Atom)); |
| PosLits = clause_CopySuccedentExcept(RedClause, Except); |
| } |
| |
| /* Create clause for tautology test */ |
| aux = clause_Create(list_Nil(), NegLits, PosLits, Flags, Precedence); |
| clause_SetTemporary(aux); |
| list_Delete(NegLits); |
| list_Delete(PosLits); |
| |
| #ifdef CRW_DEBUG |
| clause_Print(aux); |
| #endif |
| |
| /* Apply special reduction. Propagate definitions x=t if for all literals */ |
| /* u=v (A=tt) of the resulting clause the conditions holds: */ |
| /* LeadingTerm > u{x->t} and LeadingTerm > v{x->t} (LeadingTerm > A{x->t}. */ |
| if (red_PropagateDefinitions(aux, LeadingTerm, Flags, Precedence)) { |
| #ifdef CRW_DEBUG |
| printf("\n After propagation of definitions:\n aux = "); |
| clause_Print(aux); |
| #endif |
| } |
| |
| /* Invoke forward reduction and tautology test */ |
| NewClause = NULL; |
| RedundantList = list_Nil(); |
| OrigNum = clause_Number(aux); |
| Redundant = red_SelectedStaticReductions(Search, &aux, &NewClause, |
| &RedundantList, Mode); |
| clause_SetTemporary(aux); |
| /* <aux> was possibly changed by some reductions, so mark it as */ |
| /* temporary again. */ |
| |
| /* Invoke tautology test if <aux> isn't redundant. */ |
| if (Redundant || (!clause_IsEmptyClause(aux) && cc_Tautology(aux))) { |
| |
| if (NewClause != NULL) |
| /* <aux> is subsumed by <NewClause> */ |
| clause_UpdateSplitDataFromPartner(aux, NewClause); |
| |
| if (DocProof) |
| red_CRwCalculateAdditionalParents(aux, RedundantList, NewClause, OrigNum); |
| } else { |
| /* test failed */ |
| |
| clause_Delete(aux); |
| aux = NULL; |
| } |
| |
| #ifdef CRW_DEBUG |
| if (aux != NULL) { |
| if (NewClause != NULL) { |
| printf("\n Subsumer = "); |
| clause_Print(NewClause); |
| } |
| if (!list_Empty(RedundantList)) { |
| printf("\n RedundantList: "); |
| clause_ListPrint(RedundantList); |
| } |
| |
| printf("\n aux reduced = "); |
| clause_Print(aux); |
| } |
| printf("\n ----------"); |
| #endif |
| |
| /* Delete list of redundant clauses */ |
| clause_DeleteClauseList(RedundantList); |
| |
| return aux; |
| } |
| |
| |
| static BOOL red_CRwTautologyCheck(PROOFSEARCH Search, CLAUSE RedClause, int i, |
| TERM TermSInstance, CLAUSE RuleClause, |
| int j, NAT Mode, CLAUSE *Result) |
| /************************************************************** |
| INPUT: A proof search object, two clauses, two literal indices |
| (one per clause), <TermSInstance> is a subterm of |
| literal <i> in <RedClause>, a mode defining the clause |
| index used for intermediate reductions, and a pointer |
| to a clause used as return value. |
| RETURNS: FALSE, if the clauses failed some tautology test or |
| the literal <i> in <RedClause> is not greater than literal |
| <j> in <RedClause> with the substitution <sigma> applied. |
| In this case <Result> is set to NULL. |
| |
| TRUE is returned if the clauses passed all tautology tests |
| and literal <i> in <RedClause> is greater than literal <j> |
| in <RuleClause> with the substitution <sigma> applied. |
| In some cases <Result> is set to some auxiliary clause. |
| This is done if some clauses from the index were used to |
| reduce the intermediate clauses before the tautology test. |
| The auxiliary clause is used to return the necessary splitting |
| information for the current rewriting step. |
| If the <DocProof> flag is true, the information about |
| parent clauses is set in <Result>, too. |
| MEMORY: Remember to delete the <Result> clause if it is not NULL. |
| ***************************************************************/ |
| { |
| FLAGSTORE Flags, BackupFlags; |
| PRECEDENCE Precedence; |
| CLAUSE RuleCopy, aux; |
| TERM TermS; |
| int last, h; |
| BOOL Rewrite; |
| |
| #ifdef CHECK |
| if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(RuleClause, j))) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_CRwTautologyCheck:"); |
| misc_ErrorReport(" literal %d in <RuleClause> %d", j, |
| clause_Number(RuleClause)); |
| misc_ErrorReport(" isn't an oriented equation"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| *Result = NULL; |
| |
| /* copy <RuleClause> and rename variables in copy */ |
| RuleCopy = clause_Copy(RuleClause); |
| clause_RenameVarsBiggerThan(RuleCopy, clause_MaxVar(RedClause)); |
| TermS = term_FirstArgument(clause_GetLiteralAtom(RuleCopy, j)); |
| |
| /* Remove parent information of copied clause and mark it as temporary */ |
| list_Delete(clause_ParentClauses(RuleCopy)); |
| clause_SetParentClauses(RuleCopy, list_Nil()); |
| list_Delete(clause_ParentLiterals(RuleCopy)); |
| clause_SetParentLiterals(RuleCopy, list_Nil()); |
| clause_SetTemporary(RuleCopy); |
| |
| /* establish bindings */ |
| cont_StartBinding(); |
| if (!unify_MatchBindings(cont_LeftContext(), TermS, TermSInstance)) { |
| #ifdef CHECK |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_CRwTautologyCheck: terms aren't matchable"); |
| misc_FinishErrorReport(); |
| #endif |
| } |
| |
| /* Apply bindings to equation s=t, where s > t. Here the strict version */ |
| /* of cont_Apply... can be applied, because all variables in s and t */ |
| /* are bound. */ |
| cont_ApplyBindingsModuloMatching(cont_LeftContext(), |
| clause_GetLiteralAtom(RuleCopy, j), |
| TRUE); |
| |
| /* Check whether E > (s=t)sigma. It suffices to check only positive */ |
| /* equations. All other cases imply the condition. */ |
| if (i >= clause_FirstSuccedentLitIndex(RedClause) && |
| clause_LiteralIsEquality(clause_GetLiteral(RedClause, i)) && |
| ord_LiteralCompare(clause_GetLiteralTerm(RedClause, i), |
| clause_LiteralIsOrientedEquality(clause_GetLiteral(RedClause, i)), |
| clause_GetLiteralTerm(RuleCopy, j), TRUE, |
| FALSE, Flags, Precedence) != ord_GREATER_THAN) { |
| cont_BackTrack(); |
| clause_Delete(RuleCopy); |
| return FALSE; |
| } |
| |
| /* if (subs_SubsumesBasic(RuleClause, RedClause, j, i)) { Potential improvement, not completely |
| cont_BackTrack(); developed .... |
| return TRUE; |
| } else */ |
| { |
| int OldClauseCounter; |
| /* Apply bindings to the rest of <RuleCopy> */ |
| last = clause_LastLitIndex(RuleCopy); |
| for (h = clause_FirstLitIndex(); h <= last; h++) { |
| if (h != j) |
| cont_ApplyBindingsModuloMatching(cont_LeftContext(), |
| clause_GetLiteralAtom(RuleCopy, h), |
| FALSE); |
| } |
| |
| /* Backtrack bindings before reduction rules are invoked */ |
| cont_BackTrack(); |
| |
| /* Create new flag store and save current settings. Must be improved **** */ |
| /* Then turn off flags for printing and contextual rewriting. */ |
| /* IMPORTANT: the DocProof flag mustn't be changed! */ |
| BackupFlags = flag_CreateStore(); |
| flag_TransferAllFlags(Flags, BackupFlags); |
| #ifndef CRW_DEBUG |
| flag_ClearPrinting(Flags); |
| #else |
| { /* HACK: turn on all printing flags for debugging */ |
| FLAG_ID f; |
| |
| for (f = (FLAG_ID) 0; f < flag_MAXFLAG; f++) { |
| if (flag_IsPrinting(f)) |
| flag_SetFlagValue(Flags, f, flag_ON); |
| } |
| } |
| #endif |
| |
| /* ATTENTION: to apply CRw recursively, uncomment the following */ |
| /* line and comment out the following two lines! */ |
| /* flag_SetFlagValue(Flags, flag_RFCRW, flag_RFCRWON); */ |
| flag_SetFlagValue(Flags, flag_RBCRW, flag_RBCRWOFF); |
| flag_SetFlagValue(Flags, flag_RFCRW, flag_RFCRWOFF); |
| |
| /* Examine all literals of <RuleCopy> except <j> */ |
| Rewrite = TRUE; |
| last = clause_LastLitIndex(RuleCopy); |
| OldClauseCounter = clause_Counter(); |
| |
| for (h = clause_FirstLitIndex(); Rewrite && h <= last; h++) { |
| if (h != j) { |
| aux = red_CRwLitTautologyCheck(Search, RedClause, i, RuleCopy, h, |
| TermSInstance, Mode); |
| if (aux == NULL) |
| Rewrite = FALSE; |
| else { |
| /* Store splitting data of <aux> in RuleCopy */ |
| clause_UpdateSplitDataFromPartner(RuleCopy, aux); |
| /* Collect additonal parent information, if <DocProof> is turned on */ |
| if (flag_GetFlagValue(Flags, flag_DOCPROOF)) { |
| clause_SetParentClauses(RuleCopy, |
| list_Nconc(clause_ParentClauses(aux), |
| clause_ParentClauses(RuleCopy))); |
| clause_SetParentLiterals(RuleCopy, |
| list_Nconc(clause_ParentLiterals(aux), |
| clause_ParentLiterals(RuleCopy))); |
| clause_SetParentClauses(aux, list_Nil()); |
| clause_SetParentLiterals(aux, list_Nil()); |
| } |
| clause_Delete(aux); |
| } |
| } |
| } |
| /* restore clause counter */ |
| clause_SetCounter(OldClauseCounter); |
| |
| /* reset flag store of proof search object and free backup store */ |
| flag_TransferAllFlags(BackupFlags, Flags); |
| flag_DeleteStore(BackupFlags); |
| } |
| |
| if (Rewrite) |
| *Result = RuleCopy; |
| else |
| /* cleanup */ |
| clause_Delete(RuleCopy); |
| |
| return Rewrite; |
| } |
| |
| |
| static void red_DocumentContextualRewriting(CLAUSE Clause, int i, |
| CLAUSE RuleClause, int ri, |
| LIST AdditionalPClauses, |
| LIST AdditionalPLits) |
| /************************************************************** |
| INPUT: Two clauses and two literal indices (one per clause), |
| and two lists of additional parent clause numbers and |
| parent literals. |
| RETURNS: Nothing. |
| EFFECT: <Clause> is rewritten for the first time by |
| Contextual Rewriting. This function sets the parent |
| clause and parent literal information in <Clause>. |
| <Clause> gets a new clause number. |
| CAUTION: The lists are not copied! |
| ***************************************************************/ |
| { |
| #ifdef CHECK |
| if (list_Length(AdditionalPClauses) != list_Length(AdditionalPLits)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_DocumentContextualRewriting: lists of parent "); |
| misc_ErrorReport("clauses\n and literals have different length."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| list_Delete(clause_ParentClauses(Clause)); |
| list_Delete(clause_ParentLiterals(Clause)); |
| clause_SetParentClauses(Clause, AdditionalPClauses); |
| clause_SetParentLiterals(Clause, AdditionalPLits); |
| /* Add the old number of <Clause> as parent clause, */ |
| /* before it gets a new clause number. */ |
| clause_AddParentClause(Clause, clause_Number(Clause)); |
| clause_AddParentLiteral(Clause, i); |
| clause_AddParentClause(Clause, clause_Number(RuleClause)); |
| clause_AddParentLiteral(Clause, ri); |
| |
| clause_NewNumber(Clause); |
| clause_SetFromContextualRewriting(Clause); |
| } |
| |
| |
| static void red_DocumentFurtherCRw(CLAUSE Clause, int i, CLAUSE RuleClause, |
| int ri, LIST AdditionalPClauses, |
| LIST AdditionalPLits) |
| /************************************************************** |
| INPUT: Two clauses, two literal indices (one per clause), |
| and two lists of additional parent clause numbers and |
| parent literal indices. |
| RETURNS: Nothing. |
| EFFECT: <Clause> is a clause, that was rewritten before by |
| Contextual Rewriting. This function adds the parent |
| clause and parent literal information from one more |
| rewriting step to <Clause>. The information is added |
| to the front of the respective lists. |
| CAUTION: The lists are not copied! |
| ***************************************************************/ |
| { |
| int PClauseNum; |
| |
| #ifdef CHECK |
| if (list_Length(AdditionalPClauses) != list_Length(AdditionalPLits)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_DocumentFurtherCRw: lists of parent "); |
| misc_ErrorReport("clauses\n and literals have different length."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| PClauseNum = (int)list_Second(clause_ParentClauses(Clause)); |
| |
| clause_SetParentClauses(Clause, list_Nconc(AdditionalPClauses, |
| clause_ParentClauses(Clause))); |
| clause_SetParentLiterals(Clause, list_Nconc(AdditionalPLits, |
| clause_ParentLiterals(Clause))); |
| |
| clause_AddParentClause(Clause, PClauseNum); |
| clause_AddParentLiteral(Clause, i); |
| clause_AddParentClause(Clause, clause_Number(RuleClause)); |
| clause_AddParentLiteral(Clause, ri); |
| } |
| |
| |
| static BOOL red_ContextualRewriting(PROOFSEARCH Search, CLAUSE RedClause, |
| NAT Mode, int Level, CLAUSE *Changed) |
| /************************************************************** |
| INPUT: A proof search object, a clause to reduce, the |
| reduction mode which defines the clause set used for |
| reduction, a split level indicating the need of a copy |
| if <Clause> is reduced by a clause of higher split level |
| than <Level>, and a pointer to a clause used as return value. |
| RETURNS: TRUE, if contextual rewriting was possible, FALSE otherwise. |
| If rewriting was possible and the <DocProof> flag is true |
| or the split level of the rewrite rule is higher than |
| <Level>, a copy of <RedClause> that is rewritten wrt. |
| the indexed clauses is returned in <*Changed>. |
| Otherwise the clause is destructively rewritten and |
| returned. |
| CAUTION: If rewriting wasn't applied, the value of <*Changed> |
| isn't set explicitely in this function. |
| ***************************************************************/ |
| { |
| TERM RedAtom, RedTermS; |
| int B_Stack; |
| int ri, last; |
| BOOL Rewritten, Result, Document; |
| TERM TermS, PartnerEq; |
| LIST Gen, EqScan, LitScan; |
| CLAUSE Copy; |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| SHARED_INDEX ShIndex; |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RedClause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_ContextualRewriting: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| /* Select clause index */ |
| if (red_WorkedOffMode(Mode)) |
| ShIndex = prfs_WorkedOffSharingIndex(Search); |
| else |
| ShIndex = prfs_UsableSharingIndex(Search); |
| |
| last = clause_LastSuccedentLitIndex(RedClause); |
| Document = flag_GetFlagValue(Flags, flag_DOCPROOF); |
| |
| Result = FALSE; |
| Copy = RedClause; |
| |
| /* Don't apply this rule on constraint literals! */ |
| for (ri = clause_FirstAntecedentLitIndex(RedClause); ri <= last; ri++) { |
| if (!list_Empty(term_ArgumentList(clause_GetLiteralAtom(Copy, ri)))) { |
| Rewritten = TRUE; |
| while (Rewritten) { |
| Rewritten = FALSE; |
| RedAtom = clause_GetLiteralAtom(Copy, ri); |
| |
| B_Stack = stack_Bottom(); |
| /* push subterms on stack except variables */ |
| sharing_PushListReverseOnStack(term_ArgumentList(RedAtom)); |
| |
| while (!stack_Empty(B_Stack)) { |
| RedTermS = (TERM)stack_PopResult(); |
| Gen = st_GetGen(cont_LeftContext(), sharing_Index(ShIndex), RedTermS); |
| |
| for ( ; !list_Empty(Gen) && !Rewritten; Gen = list_Pop(Gen)) { |
| TermS = list_Car(Gen); |
| |
| /* A variable can't be greater than any other term, */ |
| /* so don't consider any variables here. */ |
| if (!term_IsVariable(TermS)) { |
| EqScan = term_SupertermList(TermS); |
| |
| for ( ; !list_Empty(EqScan) && !Rewritten; |
| EqScan = list_Cdr(EqScan)) { |
| PartnerEq = list_Car(EqScan); |
| if (fol_IsEquality(PartnerEq) && |
| (term_FirstArgument(PartnerEq) == TermS)) { |
| CLAUSE RuleClause, HelpClause; |
| LITERAL RuleLit; |
| int i; |
| |
| for (LitScan = sharing_NAtomDataList(PartnerEq); |
| !list_Empty(LitScan) && !Rewritten; |
| LitScan = list_Cdr(LitScan)) { |
| RuleLit = list_Car(LitScan); |
| RuleClause = clause_LiteralOwningClause(RuleLit); |
| i = clause_LiteralGetIndex(RuleLit); |
| HelpClause = NULL; |
| |
| #ifdef CRW_DEBUG |
| if (clause_LiteralIsPositive(RuleLit) && |
| clause_LiteralGetFlag(RuleLit,STRICTMAXIMAL) && |
| clause_LiteralIsOrientedEquality(RuleLit) && |
| red_LeftTermOfEquationIsStrictlyMaximalTerm(RuleClause, |
| RuleLit, |
| Flags, |
| Precedence)) { |
| printf("\n------\nFCRw: %s\n%d ", red_WorkedOffMode(Mode) |
| ? "WorkedOff" : "Usable", i); |
| clause_Print(RuleClause); |
| printf("\n%d ", ri); |
| clause_Print(RedClause); |
| } |
| #endif |
| |
| if (clause_LiteralIsPositive(RuleLit) && |
| clause_LiteralGetFlag(RuleLit,STRICTMAXIMAL) && |
| clause_LiteralIsOrientedEquality(RuleLit) && |
| red_LeftTermOfEquationIsStrictlyMaximalTerm(RuleClause, |
| RuleLit, |
| Flags, |
| Precedence) && |
| red_CRwTautologyCheck(Search, Copy, ri, RedTermS, |
| RuleClause, i, Mode, |
| &HelpClause)) { |
| TERM TermT; |
| |
| if (RedClause == Copy && |
| (Document || |
| prfs_SplitLevelCondition(clause_SplitLevel(RuleClause), |
| clause_SplitLevel(RedClause),Level) || |
| prfs_SplitLevelCondition(clause_SplitLevel(HelpClause), |
| clause_SplitLevel(RedClause), |
| Level))) { |
| Copy = clause_Copy(RedClause); |
| RedAtom = clause_GetLiteralAtom(Copy, ri); |
| } |
| |
| if (!Result && flag_GetFlagValue(Flags, flag_PCRW)) { |
| /* Clause is rewitten for the first time and */ |
| /* printing is turned on. */ |
| fputs("\nFContRewriting: ", stdout); |
| clause_Print(Copy); |
| fputs(" ==>[ ", stdout); |
| } |
| |
| if (Document) { |
| LIST PClauses, PLits; |
| |
| /* Get additional parent information from */ |
| /* <HelpClause> */ |
| PClauses = PLits = list_Nil(); |
| if (HelpClause != NULL) { |
| PClauses = clause_ParentClauses(HelpClause); |
| PLits = clause_ParentLiterals(HelpClause); |
| clause_SetParentClauses(HelpClause, list_Nil()); |
| clause_SetParentLiterals(HelpClause, list_Nil()); |
| } else |
| PClauses = PLits = list_Nil(); |
| |
| if (!Result) |
| red_DocumentContextualRewriting(Copy, ri, |
| RuleClause, i, |
| PClauses, PLits); |
| else |
| red_DocumentFurtherCRw(Copy, ri, RuleClause, i, |
| PClauses, PLits); |
| } |
| Result = TRUE; |
| |
| cont_StartBinding(); |
| unify_MatchBindings(cont_LeftContext(), TermS, RedTermS); |
| TermT = cont_ApplyBindingsModuloMatching(cont_LeftContext(), |
| term_Copy(term_SecondArgument(PartnerEq)), |
| TRUE); |
| cont_BackTrack(); |
| |
| term_ReplaceSubtermBy(RedAtom, RedTermS, TermT); |
| Rewritten = TRUE; |
| /* Set splitting data from parents */ |
| clause_UpdateSplitDataFromPartner(Copy, RuleClause); |
| if (HelpClause != NULL) { |
| /* Store splitting data from intermediate clauses */ |
| clause_UpdateSplitDataFromPartner(Copy, HelpClause); |
| clause_Delete(HelpClause); |
| } |
| term_Delete(TermT); |
| stack_SetBottom(B_Stack); |
| |
| if (flag_GetFlagValue(Flags, flag_PCRW)) |
| printf("%d.%d ",clause_Number(RuleClause), i); |
| clause_UpdateWeight(Copy, Flags); |
| } |
| } |
| } |
| } |
| } |
| } |
| list_Delete(Gen); |
| } |
| } |
| } |
| } |
| if (Result) { |
| clause_OrientAndReInit(Copy, Flags, Precedence); |
| if (flag_GetFlagValue(Flags, flag_PCRW)) { |
| fputs("] ", stdout); |
| clause_Print(Copy); |
| } |
| if (Copy != RedClause) { |
| clause_OrientAndReInit(RedClause, Flags, Precedence); |
| *Changed = Copy; |
| } |
| } |
| |
| #ifdef CHECK |
| if (Copy != RedClause) |
| clause_Check(Copy, Flags, Precedence); |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| return Result; |
| } |
| |
| |
| static LIST red_BackSubsumption(CLAUSE RedCl, SHARED_INDEX ShIndex, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /********************************************************** |
| INPUT: A pointer to a non-empty clause, an index of |
| clauses, a flag store and a precedence. |
| RETURNS: The list of clauses that are subsumed by the |
| clause RedCl. |
| ***********************************************************/ |
| { |
| TERM Atom,CandTerm; |
| CLAUSE SubsumedCl; |
| LITERAL CandLit; |
| LIST CandLits, Scan, SubsumedList; |
| int i, j, lc, fa, la, fs, l; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RedCl, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_BackSubsumption :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedCl, Flags, Precedence); |
| #endif |
| |
| /* Special case: clause is empty */ |
| if (clause_IsEmptyClause(RedCl)) |
| return list_Nil(); |
| |
| SubsumedList = list_Nil(); |
| |
| lc = clause_LastConstraintLitIndex(RedCl); |
| fa = clause_FirstAntecedentLitIndex(RedCl); |
| la = clause_LastAntecedentLitIndex(RedCl); |
| fs = clause_FirstSuccedentLitIndex(RedCl); |
| l = clause_LastLitIndex(RedCl); |
| |
| /* Choose the literal with the greatest weight to start the search */ |
| i = clause_FirstLitIndex(); |
| for (j = i + 1; j <= l; j++) { |
| if (clause_LiteralWeight(clause_GetLiteral(RedCl, j)) > |
| clause_LiteralWeight(clause_GetLiteral(RedCl, i))) |
| i = j; |
| } |
| |
| Atom = clause_GetLiteralAtom(RedCl, i); |
| CandTerm = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), Atom); |
| |
| while (CandTerm) { |
| CandLits = sharing_NAtomDataList(CandTerm); |
| |
| for (Scan = CandLits; !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| CandLit = list_Car(Scan); |
| SubsumedCl = clause_LiteralOwningClause(CandLit); |
| j = clause_LiteralGetIndex(CandLit); |
| |
| if (RedCl != SubsumedCl && |
| /* Literals must be from same part of the clause */ |
| ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) || |
| (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) || |
| (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) && |
| !list_PointerMember(SubsumedList, SubsumedCl) && |
| subs_SubsumesBasic(RedCl, SubsumedCl, i, j)) |
| SubsumedList = list_Cons(SubsumedCl, SubsumedList); |
| } |
| |
| CandTerm = st_NextCandidate(); |
| } |
| |
| if (fol_IsEquality(Atom) && |
| clause_LiteralIsNotOrientedEquality(clause_GetLiteral(RedCl, i))) { |
| Atom = term_Create(fol_Equality(), |
| list_Reverse(term_ArgumentList(Atom))); |
| CandTerm = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), Atom); |
| |
| while (CandTerm) { |
| CandLits = sharing_NAtomDataList(CandTerm); |
| |
| for (Scan = CandLits; !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| CandLit = list_Car(Scan); |
| SubsumedCl = clause_LiteralOwningClause(list_Car(Scan)); |
| /* if (!clause_GetFlag(SubsumedCl, BLOCKED)) { */ |
| j = clause_LiteralGetIndex(list_Car(Scan)); |
| |
| if ((RedCl != SubsumedCl) && |
| /* Literals must be from same part of the clause */ |
| ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) || |
| (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) || |
| (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) && |
| !list_PointerMember(SubsumedList, SubsumedCl) && |
| subs_SubsumesBasic(RedCl, SubsumedCl, i, j)) |
| SubsumedList = list_Cons(SubsumedCl, SubsumedList); |
| /* } */ |
| } |
| |
| CandTerm = st_NextCandidate(); |
| } |
| |
| list_Delete(term_ArgumentList(Atom)); |
| term_Free(Atom); |
| } |
| |
| if (flag_GetFlagValue(Flags, flag_PSUB)) { |
| for (Scan = SubsumedList; !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| SubsumedCl = list_Car(Scan); |
| fputs("\nBSubsumption: ", stdout); |
| clause_Print(SubsumedCl); |
| printf(" by %d ",clause_Number(RedCl)); |
| } |
| } |
| return SubsumedList; |
| } |
| |
| |
| static LIST red_GetBackMRResLits(CLAUSE Clause, LITERAL ActLit, SHARED_INDEX ShIndex) |
| /************************************************************** |
| INPUT: A clause, one of its literals and an Index. |
| RETURNS: A list of clauses with a complementary literal instance |
| that are subsumed if these literals are ignored. |
| the empty list if no such clause exists. |
| MEMORY: Allocates the needed listnodes. |
| ***************************************************************/ |
| { |
| CLAUSE PClause; |
| LITERAL PLit; |
| LIST LitScan, PClLits; |
| TERM CandTerm; |
| int i; |
| |
| PClLits = list_Nil(); |
| i = clause_LiteralGetIndex(ActLit); |
| |
| CandTerm = st_ExistInstance(cont_LeftContext(), |
| sharing_Index(ShIndex), |
| clause_LiteralAtom(ActLit)); |
| |
| while (CandTerm) { |
| |
| LitScan = sharing_NAtomDataList(CandTerm); /* CAUTION ! */ |
| |
| for ( ; !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) { |
| |
| PLit = list_Car(LitScan); |
| PClause = clause_LiteralOwningClause(PLit); |
| |
| if (PClause != Clause && |
| clause_LiteralsAreComplementary(ActLit,PLit) && |
| subs_SubsumesBasic(Clause,PClause,i,clause_LiteralGetIndex(PLit))) |
| PClLits = list_Cons(PLit, PClLits); |
| } |
| |
| CandTerm = st_NextCandidate(); |
| } |
| return PClLits; |
| } |
| |
| |
| static LIST red_BackMatchingReplacementResolution(CLAUSE RedClause, SHARED_INDEX ShIndex, |
| FLAGSTORE Flags, PRECEDENCE Precedence, |
| LIST* Result) |
| /************************************************************** |
| INPUT: A clause, a shared index, a flag store, a |
| precedence, and a pointer to a result list. |
| RETURNS: The return value itself contains a list of clauses |
| from <ShIndex> that is reducible by <RedClause> via |
| clause reduction. |
| The return value stored in <*Result> contains the |
| result of this operation. |
| If the <DocProof> flag is true then the clauses in |
| <*Result> contain information about the reduction. |
| ***************************************************************/ |
| { |
| LIST Blocked; |
| CLAUSE Copy; |
| BOOL Document; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RedClause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_BackMatchingReplacementResolution:"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| Blocked = list_Nil(); |
| Document = flag_GetFlagValue(Flags, flag_DOCPROOF); |
| |
| if (clause_Length(RedClause) == 1) { |
| LITERAL ActLit, PLit; |
| LIST LitList, Scan, Iter; |
| TERM CandTerm; |
| int RedClNum; |
| |
| ActLit = clause_GetLiteral(RedClause, clause_FirstLitIndex()); |
| |
| if (!fol_IsEquality(clause_LiteralAtom(ActLit)) || /* Reduce with negative equations too */ |
| clause_LiteralIsNegative(ActLit)) { |
| CLAUSE PClause; |
| LIST PIndL; |
| |
| CandTerm = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), clause_LiteralAtom(ActLit)); |
| RedClNum = clause_Number(RedClause); |
| LitList = list_Nil(); |
| |
| while (CandTerm) { |
| for (Iter = sharing_NAtomDataList(CandTerm); !list_Empty(Iter); Iter = list_Cdr(Iter)) |
| if (clause_LiteralsAreComplementary(ActLit,list_Car(Iter))) |
| LitList = list_Cons(list_Car(Iter),LitList); |
| CandTerm = st_NextCandidate(); |
| } |
| |
| /* It is important to get all literals first, |
| because there may be several literals in the same clause which can be reduced by <ActLit> */ |
| |
| while (!list_Empty(LitList)) { |
| PLit = list_Car(LitList); |
| PIndL = list_List(PLit); |
| PClause = clause_LiteralOwningClause(PLit); |
| Blocked = list_Cons(PClause, Blocked); |
| |
| if (flag_GetFlagValue(Flags, flag_PMRR)) { |
| fputs("\nBMatchingReplacementResolution: ", stdout); |
| clause_Print(PClause); |
| printf(" ==>[ %d.%d ] ",clause_Number(RedClause),clause_FirstLitIndex()); |
| } |
| |
| Iter = LitList; |
| for (Scan=list_Cdr(LitList);!list_Empty(Scan);Scan=list_Cdr(Scan)) /* Get brothers of PLit */ |
| if (PClause == clause_LiteralOwningClause(list_Car(Scan))) { |
| list_Rplacd(Iter,list_Cdr(Scan)); |
| list_Rplacd(Scan,PIndL); |
| PIndL = Scan; |
| Scan = Iter; |
| } |
| else |
| Iter = Scan; |
| Iter = LitList; |
| LitList = list_Cdr(LitList); |
| list_Free(Iter); |
| Copy = clause_Copy(PClause); |
| clause_RemoveFlag(Copy,WORKEDOFF); |
| clause_UpdateSplitDataFromPartner(Copy, RedClause); |
| for(Scan=PIndL;!list_Empty(Scan);Scan=list_Cdr(Scan)) /* Change lits to indexes */ |
| list_Rplaca(Scan,(POINTER)clause_LiteralGetIndex(list_Car(Scan))); |
| clause_DeleteLiterals(Copy, PIndL, Flags, Precedence); |
| |
| if (Document) |
| /* Lists are consumed */ |
| red_DocumentMatchingReplacementResolution(Copy, PIndL, list_List((POINTER)RedClNum), |
| list_List((POINTER)clause_FirstLitIndex())); |
| |
| else |
| list_Delete(PIndL); |
| |
| if (flag_GetFlagValue(Flags, flag_PMRR)) |
| clause_Print(Copy); |
| *Result = list_Cons(Copy, *Result); |
| } |
| } |
| return Blocked; |
| } |
| else { |
| CLAUSE PClause; |
| LITERAL ActLit, PLit; |
| LIST LitScan,LitList; |
| int i,length,RedClNum,PInd; |
| |
| RedClNum = clause_Number(RedClause); |
| length = clause_Length(RedClause); |
| |
| for (i = clause_FirstLitIndex(); i < length; i++) { |
| ActLit = clause_GetLiteral(RedClause, i); |
| |
| if (!fol_IsEquality(clause_LiteralAtom(ActLit))) { |
| LitList = red_GetBackMRResLits(RedClause, ActLit, ShIndex); |
| |
| for (LitScan = LitList;!list_Empty(LitScan);LitScan = list_Cdr(LitScan)) { |
| PLit = list_Car(LitScan); |
| PClause = clause_LiteralOwningClause(PLit); |
| PInd = clause_LiteralGetIndex(PLit); |
| Copy = clause_Copy(PClause); |
| if (list_PointerMember(Blocked,PClause)) { |
| if (!flag_GetFlagValue(Flags, flag_DOCPROOF)) |
| clause_NewNumber(Copy); |
| } |
| else |
| Blocked = list_Cons(PClause, Blocked); |
| clause_RemoveFlag(Copy,WORKEDOFF); |
| clause_UpdateSplitDataFromPartner(Copy, RedClause); |
| clause_DeleteLiteral(Copy, PInd, Flags, Precedence); |
| |
| if (Document) |
| red_DocumentMatchingReplacementResolution(Copy, list_List((POINTER)PInd), |
| list_List((POINTER)RedClNum), |
| list_List((POINTER)i)); |
| |
| if (flag_GetFlagValue(Flags, flag_PMRR)) { |
| fputs("\nBMatchingReplacementResolution: ", stdout); |
| clause_Print(PClause); |
| printf(" ==>[ %d.%d ] ",clause_Number(RedClause),i); |
| clause_Print(Copy); |
| } |
| *Result = list_Cons(Copy, *Result); |
| } |
| list_Delete(LitList); |
| } |
| } |
| return Blocked; |
| } |
| } |
| |
| |
| static void red_ApplyRewriting(CLAUSE RuleCl, int ri, CLAUSE PartnerClause, |
| int pli, TERM PartnerTermS, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause to use for rewriting, the index of a |
| positive equality literal where the first equality |
| argument is greater, a clause, the index of a |
| literal with subterm <PartnerTermS> that can be |
| rewritten, a flag store and a precedence. |
| RETURNS: Nothing. |
| EFFECT: The atom of literal pli in PartnerClause is |
| destructively changed !!! |
| The <DocProof> flag is considered. |
| ***************************************************************/ |
| { |
| LITERAL PartnerLit; |
| TERM ReplaceTermT, NewAtom; |
| |
| #ifdef CHECK |
| clause_Check(PartnerClause, Flags, Precedence); |
| clause_Check(RuleCl, Flags, Precedence); |
| #endif |
| |
| if (flag_GetFlagValue(Flags, flag_DOCPROOF)) |
| red_DocumentRewriting(PartnerClause, pli, RuleCl, ri); |
| |
| if (flag_GetFlagValue(Flags, flag_PREW)) { |
| fputs("\nBRewriting: ", stdout); |
| clause_Print(PartnerClause); |
| printf(" ==>[ %d.%d ] ", clause_Number(RuleCl), ri); |
| } |
| |
| PartnerLit = clause_GetLiteral(PartnerClause, pli); |
| |
| ReplaceTermT = |
| cont_ApplyBindingsModuloMatchingReverse(cont_LeftContext(), |
| term_Copy(term_SecondArgument(clause_GetLiteralTerm(RuleCl, ri)))); |
| |
| NewAtom = clause_LiteralSignedAtom(PartnerLit); |
| term_ReplaceSubtermBy(NewAtom, PartnerTermS, ReplaceTermT); |
| term_Delete(ReplaceTermT); |
| |
| clause_OrientAndReInit(PartnerClause, Flags, Precedence); |
| clause_UpdateSplitDataFromPartner(PartnerClause, RuleCl); |
| |
| if (flag_GetFlagValue(Flags, flag_PREW)) |
| clause_Print(PartnerClause); |
| } |
| |
| |
| static LIST red_LiteralRewriting(CLAUSE RedClause, LITERAL ActLit, int ri, |
| SHARED_INDEX ShIndex, FLAGSTORE Flags, |
| PRECEDENCE Precedence, LIST* Result) |
| /************************************************************** |
| INPUT: A clause, a positive equality literal where the |
| first equality argument is greater, its index, an |
| index of clauses, a flag store, a precedence and a |
| pointer to a list of clauses that were rewritten. |
| RETURNS: The list of clauses from the index that can be |
| rewritten by <ActLit> and <RedClause>. |
| The rewritten clauses are stored in <*Result>. |
| EFFECT: The <DocProof> flag is considered. |
| ***************************************************************/ |
| { |
| TERM TermS, CandTerm; |
| LIST Blocked; |
| |
| #ifdef CHECK |
| if (!clause_LiteralIsLiteral(ActLit) || !clause_LiteralIsEquality(ActLit) || |
| !clause_LiteralIsOrientedEquality(ActLit)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_LiteralRewriting: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| Blocked = list_Nil(); |
| TermS = term_FirstArgument(clause_LiteralSignedAtom(ActLit)); /* Vars can't be greater ! */ |
| |
| CandTerm = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), TermS); |
| |
| while (CandTerm) { |
| |
| if (!term_IsVariable(CandTerm) && |
| !symbol_IsPredicate(term_TopSymbol(CandTerm))) { |
| LIST LitList; |
| |
| LitList = sharing_GetDataList(CandTerm, ShIndex); |
| |
| for ( ; !list_Empty(LitList); LitList = list_Pop(LitList)){ |
| LITERAL PartnerLit; |
| CLAUSE PartnerClause; |
| int pli; |
| |
| PartnerLit = list_Car(LitList); |
| pli = clause_LiteralGetIndex(PartnerLit); |
| PartnerClause = clause_LiteralOwningClause(PartnerLit); |
| |
| /* Partner literal must be from antecedent or succedent */ |
| if (clause_Number(RedClause) != clause_Number(PartnerClause) && |
| pli >= clause_FirstAntecedentLitIndex(PartnerClause) && |
| !list_PointerMember(Blocked, PartnerClause) && |
| subs_SubsumesBasic(RedClause, PartnerClause, ri, pli)) { |
| CLAUSE Copy; |
| |
| Blocked = list_Cons(PartnerClause, Blocked); |
| Copy = clause_Copy(PartnerClause); |
| clause_RemoveFlag(Copy, WORKEDOFF); |
| red_ApplyRewriting(RedClause, ri, Copy, pli, CandTerm, |
| Flags, Precedence); |
| *Result = list_Cons(Copy, *Result); |
| } |
| } |
| } |
| CandTerm = st_NextCandidate(); |
| } |
| return Blocked; |
| } |
| |
| |
| static LIST red_BackRewriting(CLAUSE RedClause, SHARED_INDEX ShIndex, |
| FLAGSTORE Flags, PRECEDENCE Precedence, |
| LIST* Result) |
| /************************************************************** |
| INPUT: A clause, and Index, a flag store, a precedence and |
| a pointer to the list of rewritten clauses. |
| RETURNS: A list of clauses that can be rewritten with |
| <RedClause> and the result of this operation is |
| stored in <*Result>. |
| EFFECT: The <DocProof> flag is considered. |
| ***************************************************************/ |
| { |
| int i,length; |
| LITERAL ActLit; |
| LIST Blocked; |
| |
| #ifdef CHECK |
| if (!(clause_IsClause(RedClause, Flags, Precedence))) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_BackRewriting :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| Blocked = list_Nil(); |
| length = clause_Length(RedClause); |
| |
| for (i=clause_FirstSuccedentLitIndex(RedClause); i < length; i++) { |
| ActLit = clause_GetLiteral(RedClause, i); |
| if (clause_LiteralIsOrientedEquality(ActLit)) { |
| Blocked = list_Nconc(red_LiteralRewriting(RedClause, ActLit, i, |
| ShIndex, Flags, Precedence, |
| Result), |
| Blocked); |
| } |
| |
| #ifdef CHECK |
| if (fol_IsEquality(clause_LiteralSignedAtom(ActLit))) { |
| ord_RESULT HelpRes; |
| |
| HelpRes = |
| ord_Compare(term_FirstArgument(clause_LiteralSignedAtom(ActLit)), |
| term_SecondArgument(clause_LiteralSignedAtom(ActLit)), |
| Flags, Precedence); |
| |
| if (ord_IsSmallerThan(HelpRes)){ /* For Debugging */ |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_BackRewriting:"); |
| misc_ErrorReport("First Argument smaller than second in RedClause.\n"); |
| misc_FinishErrorReport(); |
| } |
| } /* end of if (fol_IsEquality). */ |
| #endif |
| } /* end of for 'all succedent literals'. */ |
| Blocked = list_PointerDeleteDuplicates(Blocked); |
| return Blocked; |
| } |
| |
| |
| /**************************************************************/ |
| /* BACKWARD CONTEXTUAL REWRITING */ |
| /**************************************************************/ |
| |
| static LIST red_BackCRwOnLiteral(PROOFSEARCH Search, CLAUSE RuleClause, |
| LITERAL Lit, int i, NAT Mode, LIST* Result) |
| /************************************************************** |
| INPUT: A proof search object, a clause that is used to rewrite |
| other clauses, a positive literal from the clause, |
| that is a strictly maximal, oriented equation, the index |
| of the literal, a mode defining which clause index |
| is used to find rewritable clauses, and a pointer |
| to a list that is used as return value. |
| The left term of the equation has to be the strictly |
| maximal term in the clause, i.e. it is bigger than |
| any other term. |
| RETURNS: The list of clauses from the clause index that can be |
| rewritten by <Lit> and <RuleClause>. |
| The rewritten clauses are stored in <*Result>. |
| EFFECT: The <DocProof> flag is considered. |
| ***************************************************************/ |
| { |
| TERM TermS, CandTerm, ReplaceTermT; |
| LIST Inst, Blocked; |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| SHARED_INDEX ShIndex; |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| if (red_WorkedOffMode(Mode)) |
| ShIndex = prfs_WorkedOffSharingIndex(Search); |
| else |
| ShIndex = prfs_UsableSharingIndex(Search); |
| |
| #ifdef CHECK |
| if (!clause_LiteralIsLiteral(Lit) || !clause_LiteralIsEquality(Lit) || |
| !clause_LiteralGetFlag(Lit, STRICTMAXIMAL) || |
| !clause_LiteralIsOrientedEquality(Lit)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_BackCRwOnLiteral: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RuleClause, Flags, Precedence); |
| #endif |
| |
| Blocked = list_Nil(); |
| TermS = term_FirstArgument(clause_LiteralSignedAtom(Lit)); |
| |
| /* Get all instances of <TermS> at once. This can't be done iteratively */ |
| /* since other reduction rules are invoked within the following loop. */ |
| Inst = st_GetInstance(cont_LeftContext(), sharing_Index(ShIndex), TermS); |
| |
| for ( ; !list_Empty(Inst); Inst = list_Pop(Inst)) { |
| CandTerm = list_Car(Inst); |
| |
| if (!term_IsVariable(CandTerm) && |
| !symbol_IsPredicate(term_TopSymbol(CandTerm))) { |
| LIST LitList; |
| |
| LitList = sharing_GetDataList(CandTerm, ShIndex); |
| |
| for ( ; !list_Empty(LitList); LitList = list_Pop(LitList)){ |
| LITERAL RedLit; |
| CLAUSE RedClause, HelpClause; |
| int ri; |
| |
| RedLit = list_Car(LitList); |
| ri = clause_LiteralGetIndex(RedLit); |
| RedClause = clause_LiteralOwningClause(RedLit); |
| HelpClause = NULL; |
| |
| #ifdef CRW_DEBUG |
| if (clause_Number(RuleClause) != clause_Number(RedClause) && |
| ri >= clause_FirstAntecedentLitIndex(RedClause) && |
| !list_PointerMember(Blocked, RedClause)) { |
| printf("\n------\nBCRw: %s\n%d ", red_WorkedOffMode(Mode) ? |
| "WorkedOff" : "Usable", i); |
| clause_Print(RuleClause); |
| printf("\n%d ", ri); |
| clause_Print(RedClause); |
| } |
| #endif |
| |
| /* Partner literal must be from antecedent or succedent */ |
| if (clause_Number(RuleClause) != clause_Number(RedClause) && |
| ri >= clause_FirstAntecedentLitIndex(RedClause) && |
| /* Check that clause wasn't already rewritten by this literal. */ |
| /* Necessary because then the old version of the clause is still */ |
| /* in the index, but the rewritten version in not in the index. */ |
| !list_PointerMember(Blocked, RedClause) && |
| red_CRwTautologyCheck(Search, RedClause, ri, CandTerm, |
| RuleClause, i, Mode, &HelpClause)) { |
| CLAUSE Copy; |
| |
| /* The <PartnerClause> has to be copied because it's indexed. */ |
| Blocked = list_Cons(RedClause, Blocked); |
| Copy = clause_Copy(RedClause); |
| clause_RemoveFlag(Copy, WORKEDOFF); |
| |
| /* Establish bindings */ |
| cont_StartBinding(); |
| if (!unify_MatchBindings(cont_LeftContext(), TermS, CandTerm)) { |
| #ifdef CHECK |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_BackCRwOnLiteral: terms aren't "); |
| misc_ErrorReport("matchable."); |
| misc_FinishErrorReport(); |
| #endif |
| } |
| /* The variable check in cont_ApplyBindings... is turned on here */ |
| /* because all variables is s are bound, and s > t. So all */ |
| /* variables in t are bound, too. */ |
| ReplaceTermT = |
| cont_ApplyBindingsModuloMatching(cont_LeftContext(), |
| term_Copy(term_SecondArgument(clause_GetLiteralTerm(RuleClause, i))), |
| TRUE); |
| cont_BackTrack(); |
| |
| /* Modify copied clause */ |
| term_ReplaceSubtermBy(clause_GetLiteralAtom(Copy, ri), CandTerm, |
| ReplaceTermT); |
| term_Delete(ReplaceTermT); |
| |
| /* Proof documentation */ |
| if (flag_GetFlagValue(Flags, flag_DOCPROOF)) { |
| LIST PClauses, PLits; |
| |
| if (HelpClause != NULL) { |
| /* Get additional parent clauses and literals from the */ |
| /* tautology check. */ |
| PClauses = clause_ParentClauses(HelpClause); |
| PLits = clause_ParentLiterals(HelpClause); |
| clause_SetParentClauses(HelpClause, list_Nil()); |
| clause_SetParentLiterals(HelpClause, list_Nil()); |
| } else |
| PClauses = PLits = list_Nil(); |
| |
| red_DocumentContextualRewriting(Copy, ri, RuleClause, i, |
| PClauses, PLits); |
| } |
| |
| /* Set splitting data according to all parents */ |
| clause_UpdateSplitDataFromPartner(Copy, RuleClause); |
| if (HelpClause != NULL) { |
| clause_UpdateSplitDataFromPartner(Copy, HelpClause); |
| clause_Delete(HelpClause); |
| } |
| |
| clause_OrientAndReInit(Copy, Flags, Precedence); |
| |
| if (flag_GetFlagValue(Flags, flag_PCRW)) { |
| fputs("\nBContRewriting: ", stdout); |
| clause_Print(RedClause); |
| printf(" ==>[ %d.%d ] ", clause_Number(RuleClause), i); |
| clause_Print(Copy); |
| } |
| |
| *Result = list_Cons(Copy, *Result); |
| } |
| } |
| } |
| } |
| |
| return Blocked; |
| } |
| |
| |
| static LIST red_BackContextualRewriting(PROOFSEARCH Search, CLAUSE RuleClause, |
| NAT Mode, LIST* Result) |
| /************************************************************** |
| INPUT: A proof search object, a clause that is used to rewrite |
| other clauses, a mode flag that indicates which clause |
| index is used to find rewritable clauses, and a pointer |
| to a list that is used as return value. |
| RETURNS: A list of clauses that can be reduced |
| with Contextual Rewriting with <RuleClause>. |
| The clauses resulting from the rewriting steps are |
| stored in <*Result>. |
| EFFECT: The <DocProof> flag is considered. Every rewritable clause |
| is copied before rewriting is applied! This has to be done, |
| because the rewritable clauses are indexed. |
| ***************************************************************/ |
| { |
| BOOL found; |
| int i, ls; |
| LITERAL Lit; |
| LIST Blocked; |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RuleClause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_BackContextualRewriting: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RuleClause, Flags, Precedence); |
| #endif |
| |
| Blocked = list_Nil(); |
| ls = clause_LastSuccedentLitIndex(RuleClause); |
| found = FALSE; |
| |
| for (i = clause_FirstSuccedentLitIndex(RuleClause); i <= ls && !found; i++) { |
| Lit = clause_GetLiteral(RuleClause, i); |
| if (clause_LiteralIsOrientedEquality(Lit) && |
| clause_LiteralGetFlag(Lit, STRICTMAXIMAL) && |
| red_LeftTermOfEquationIsStrictlyMaximalTerm(RuleClause, Lit, Flags, |
| Precedence)) { |
| Blocked = list_Nconc(red_BackCRwOnLiteral(Search, RuleClause, Lit, i, |
| Mode, Result), |
| Blocked); |
| /* Stop loop: there's only one strictly maximal term per clause */ |
| found = TRUE; |
| } |
| } |
| |
| Blocked = list_PointerDeleteDuplicates(Blocked); |
| return Blocked; |
| } |
| |
| |
| static void red_DocumentSortSimplification(CLAUSE Clause, LIST Indexes, |
| LIST Clauses) |
| /********************************************************* |
| INPUT: A clause and the literal indices and clauses |
| involved in sort simplification. |
| RETURNS: Nothing. |
| MEMORY: Consumes the input lists. |
| **********************************************************/ |
| { |
| LIST Scan,Declarations,Self; |
| |
| Declarations = list_Nil(); |
| Self = list_Nil(); |
| |
| list_Delete(clause_ParentClauses(Clause)); |
| list_Delete(clause_ParentLiterals(Clause)); |
| |
| for(Scan=Indexes;!list_Empty(Scan);Scan=list_Cdr(Scan)) |
| Self = list_Cons((POINTER)clause_Number(Clause),Self); |
| |
| for(Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) { |
| Declarations = list_Cons((POINTER)clause_FirstSuccedentLitIndex(list_Car(Scan)),Declarations); |
| list_Rplaca(Scan,(POINTER)clause_Number(list_Car(Scan))); |
| } |
| |
| clause_SetParentLiterals(Clause, list_Nconc(Indexes,Declarations)); |
| clause_SetParentClauses(Clause, list_Nconc(Self,Clauses)); |
| |
| clause_SetNumber(Clause, clause_IncreaseCounter()); |
| clause_SetFromSortSimplification(Clause); |
| } |
| |
| |
| static BOOL red_SortSimplification(SORTTHEORY Theory, CLAUSE Clause, NAT Level, |
| BOOL Document, FLAGSTORE Flags, |
| PRECEDENCE Precedence, CLAUSE *Changed) |
| /********************************************************** |
| INPUT: A sort theory, a clause, the last backtrack |
| level of the current proof search, a boolean |
| flag concerning proof documentation, a flag |
| store and a precedence. |
| RETURNS: TRUE iff sort simplification was possible. |
| If <Document> is true or the split level of the |
| used declaration clauses requires copying a |
| simplified copy of the clause is returned in |
| <*Changed>. |
| Otherwise the clause is destructively |
| simplified. |
| ***********************************************************/ |
| { |
| if (Theory != (SORTTHEORY)NULL) { |
| TERM Atom,Term; |
| SOJU SortPair; |
| SORT TermSort,LitSort; |
| LIST Indexes,NewClauses,Clauses,Scan; |
| int i,lc,j,OldSplitLevel; |
| CLAUSE Copy; |
| CONDITION Cond; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(Clause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_SortSimplification :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(Clause, Flags, Precedence); |
| #endif |
| |
| lc = clause_LastConstraintLitIndex(Clause); |
| i = clause_FirstLitIndex(); |
| j = 0; |
| OldSplitLevel = clause_SplitLevel(Clause); |
| Copy = Clause; |
| Indexes = list_Nil(); |
| Clauses = list_Nil(); |
| |
| while (i <= lc) { |
| |
| Atom = clause_LiteralAtom(clause_GetLiteral(Copy, i)); |
| Term = term_FirstArgument(Atom); |
| SortPair = sort_ComputeSortNoResidues(Theory, Term, Copy, i, |
| Flags, Precedence); |
| TermSort = sort_PairSort(SortPair); |
| NewClauses = sort_ConditionClauses(sort_PairCondition(SortPair)); |
| sort_ConditionPutClauses(sort_PairCondition(SortPair),list_Nil()); |
| LitSort = sort_TheorySortOfSymbol(Theory,term_TopSymbol(Atom)); |
| |
| if ((Cond = sort_TheoryIsSubsortOfNoResidues(Theory, TermSort, LitSort)) != (CONDITION)NULL) { |
| |
| if (j == 0 && flag_GetFlagValue(Flags, flag_PSSI)) { |
| fputs("\nSortSimplification: ", stdout); |
| clause_Print(Copy); |
| fputs(" ==>[ ", stdout); |
| } |
| |
| NewClauses = list_Nconc(NewClauses,sort_ConditionClauses(Cond)); |
| sort_ConditionPutClauses(Cond,list_Nil()); |
| sort_ConditionDelete(Cond); |
| |
| for (Scan = NewClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| if (Clause == Copy && |
| (Document || |
| prfs_SplitLevelCondition(clause_SplitLevel(list_Car(Scan)),OldSplitLevel,Level))) |
| Copy = clause_Copy(Clause); |
| clause_UpdateSplitDataFromPartner(Copy, list_Car(Scan)); |
| if (flag_GetFlagValue(Flags, flag_PSSI)) |
| printf("%d ",clause_Number(list_Car(Scan))); |
| } |
| |
| if (Document) |
| Indexes = list_Cons((POINTER)(i+j), Indexes); |
| |
| clause_DeleteLiteral(Copy, i, Flags, Precedence); |
| Clauses = list_Nconc(NewClauses,Clauses); |
| j++; |
| lc--; |
| } |
| else { |
| list_Delete(NewClauses); |
| i++; |
| } |
| sort_DeleteSortPair(SortPair); |
| sort_Delete(LitSort); |
| } |
| |
| #ifdef CHECK |
| clause_Check(Copy, Flags, Precedence); |
| #endif |
| |
| if (j > 0) { |
| if (Document) |
| red_DocumentSortSimplification(Copy,Indexes,Clauses); |
| else |
| list_Delete(Clauses); |
| clause_ReInit(Copy, Flags, Precedence); |
| if (flag_GetFlagValue(Flags, flag_PSSI)) { |
| fputs("] ", stdout); |
| clause_Print(Copy); |
| } |
| if (Copy != Clause) |
| *Changed = Copy; |
| return TRUE; |
| } |
| } |
| |
| return FALSE; |
| } |
| |
| static void red_ExchangeClauses(CLAUSE *RedClause, CLAUSE *Copy, LIST *Result) |
| /********************************************************** |
| INPUT: Two pointers to clauses and a pointer to a list. |
| RETURNS: Nothing. |
| EFFECT: If *Copy is NULL, nothing is done. Otherwise *RedClause |
| is added to the list, *Copy is assigned to *RedClause, |
| and NULL is assigned to *Copy. |
| ***********************************************************/ |
| { |
| if (*Copy) { |
| *Result = list_Cons(*RedClause,*Result); |
| *RedClause = *Copy; |
| *Copy = (CLAUSE)NULL; |
| } |
| } |
| |
| |
| |
| static BOOL red_SimpleStaticReductions(CLAUSE *RedClause, FLAGSTORE Flags, |
| PRECEDENCE Precedence, LIST* Result) |
| /********************************************************** |
| INPUT: A clause (by reference), a flag store and a |
| precedence. |
| RETURNS: TRUE if <*RedClause> is redundant. |
| If the <DocProof> flag is false and no copying is necessary |
| with respect to splitting, the clause is destructively changed, |
| otherwise (intermediate) copies are made and returned in <*Result>. |
| EFFECT: Used reductions are tautology deletion and |
| obvious reductions. |
| ***********************************************************/ |
| { |
| CLAUSE Copy; |
| BOOL DocProof; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(*RedClause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_SimpleStaticReductions :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(*RedClause, Flags, Precedence); |
| #endif |
| |
| Copy = (CLAUSE)NULL; |
| DocProof = flag_GetFlagValue(Flags, flag_DOCPROOF); |
| |
| if (flag_GetFlagValue(Flags, flag_RTAUT) != flag_RTAUTOFF && |
| red_Tautology(*RedClause, Flags, Precedence)) |
| return TRUE; |
| |
| if (flag_GetFlagValue(Flags, flag_ROBV)) { |
| red_ObviousReductions(*RedClause, DocProof, Flags, Precedence, &Copy); |
| red_ExchangeClauses(RedClause, &Copy, Result); |
| } |
| |
| if (flag_GetFlagValue(Flags, flag_RCON)) { |
| red_Condensing(*RedClause, DocProof, Flags, Precedence, &Copy); |
| red_ExchangeClauses(RedClause, &Copy, Result); |
| } |
| |
| return FALSE; |
| } |
| |
| |
| |
| |
| static BOOL red_StaticReductions(PROOFSEARCH Search, CLAUSE *Clause, |
| CLAUSE *Subsumer, LIST* Result, NAT Mode) |
| /********************************************************** |
| INPUT: A proof search object, a clause (by reference) to be reduced, |
| a shared index of clauses and the mode of the reductions, |
| determining which sets (Usable, WorkedOff) in <Search> |
| are considered for reductions. |
| RETURNS: TRUE iff the clause is redundant. |
| If the <DocProof> flag is false and no copying is necessary |
| with respect to splitting, the clause is destructively changed, |
| otherwise (intermediate) copies are made and returned in <*Result>. |
| If <Clause> gets redundant with respect to forward subsumption, |
| the subsuming clause is returned in <*Subsumer>. |
| EFFECT: Used reductions are tautology deletion, obvious reductions, |
| forward subsumption, forward rewriting, forward contextual |
| rewriting, forward matching replacement resolution, |
| sort simplification, unit conflict and static soft typing. |
| Depending on <Mode>, then clauses are reduced with respect |
| to WorkedOff or Usable Clauses. |
| ***********************************************************/ |
| { |
| CLAUSE Copy; |
| BOOL Redundant; |
| SHARED_INDEX Index; |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| #ifdef CHECK |
| if (!clause_IsClause(*Clause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_StaticReductions:"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(*Clause, Flags, Precedence); |
| #endif |
| |
| Index = (red_OnlyWorkedOffMode(Mode) ? |
| prfs_WorkedOffSharingIndex(Search) : prfs_UsableSharingIndex(Search)); |
| Copy = (CLAUSE)NULL; |
| Redundant = red_SimpleStaticReductions(Clause, Flags, Precedence, Result); |
| |
| if (Redundant) |
| return Redundant; |
| |
| /* Assignment Equation Deletion */ |
| if (flag_GetFlagValue(Flags, flag_RAED) != flag_RAEDOFF && |
| red_AssignmentEquationDeletion(*Clause, Flags, Precedence, &Copy, |
| prfs_NonTrivClauseNumber(Search), |
| (flag_GetFlagValue(Flags, flag_RAED) == flag_RAEDPOTUNSOUND))) { |
| red_ExchangeClauses(Clause, &Copy, Result); |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| } |
| |
| /* Subsumption */ |
| if (flag_GetFlagValue(Flags, flag_RFSUB)) { |
| *Subsumer = red_ForwardSubsumption(*Clause, Index, Flags, Precedence); |
| if ((Redundant = (*Subsumer != (CLAUSE)NULL))) |
| return Redundant; |
| } |
| |
| /* Forward Rewriting and Forward Contextual Rewriting */ |
| if ((flag_GetFlagValue(Flags, flag_RFREW) && |
| red_RewriteRedClause(*Clause, Index, Flags, Precedence, |
| &Copy, prfs_LastBacktrackLevel(Search))) || |
| (flag_GetFlagValue(Flags, flag_RFCRW) && |
| red_ContextualRewriting(Search, *Clause, Mode, |
| prfs_LastBacktrackLevel(Search), &Copy))) { |
| red_ExchangeClauses(Clause, &Copy, Result); |
| Redundant = red_SimpleStaticReductions(Clause, Flags, Precedence, Result); |
| if (Redundant) |
| return Redundant; |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| if (flag_GetFlagValue(Flags, flag_RFSUB)) { |
| *Subsumer = red_ForwardSubsumption(*Clause, Index, Flags, Precedence); |
| if ((Redundant = (*Subsumer != (CLAUSE)NULL))) |
| return Redundant; |
| } |
| } |
| |
| /* Sort Simplification */ |
| if (red_OnlyWorkedOffMode(Mode) && flag_GetFlagValue(Flags, flag_RSSI)) { |
| red_SortSimplification(prfs_DynamicSortTheory(Search), *Clause, |
| prfs_LastBacktrackLevel(Search), |
| flag_GetFlagValue(Flags, flag_DOCPROOF), |
| Flags, Precedence, &Copy); |
| red_ExchangeClauses(Clause, &Copy, Result); |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| } |
| |
| /* Matching Replacement Resolution */ |
| if (flag_GetFlagValue(Flags, flag_RFMRR)) { |
| red_MatchingReplacementResolution(*Clause, Index, Flags, Precedence, |
| &Copy, prfs_LastBacktrackLevel(Search)); |
| red_ExchangeClauses(Clause, &Copy, Result); |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| } |
| |
| /* Unit Conflict */ |
| if (flag_GetFlagValue(Flags, flag_RUNC)) { |
| red_UnitConflict(*Clause, Index, Flags, Precedence, |
| &Copy, prfs_LastBacktrackLevel(Search)); |
| red_ExchangeClauses(Clause, &Copy, Result); |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| } |
| |
| /* Static Soft Typing */ |
| if (red_OnlyWorkedOffMode(Mode) && flag_GetFlagValue(Flags, flag_RSST)) |
| Redundant = red_ClauseDeletion(prfs_StaticSortTheory(Search),*Clause, |
| Flags, Precedence); |
| |
| #ifdef CHECK |
| clause_Check(*Clause, Flags, Precedence); |
| #endif |
| |
| return Redundant; |
| } |
| |
| static BOOL red_SelectedStaticReductions(PROOFSEARCH Search, CLAUSE *Clause, |
| CLAUSE *Subsumer, LIST* Result, |
| NAT Mode) |
| /********************************************************** |
| INPUT: A proof search object, a clause (by reference) to be reduced, |
| and the mode of the reductions, determining which sets |
| (Usable, WorkedOff) in <Search> are considered for reductions. |
| EFFECT: Used reductions are tautology deletion, obvious reductions, |
| forward subsumption, forward rewriting, forward matching |
| replacement resolution, sort simplification, unit conflict |
| and static soft typing. |
| Depending on <Mode>, the clauses are reduced with respect |
| to WorkedOff and/or Usable Clauses. |
| RETURNS: TRUE iff the clause is redundant. |
| If the <DocProof> flag is false and no copying is necessary |
| with respect to splitting, the clause is destructively changed, |
| otherwise (intermediate) copies are made and returned in <*Result>. |
| If <Clause> gets redundant with respect to forward subsumption, |
| the subsuming clause is returned in <*Subsumer>. |
| ***********************************************************/ |
| { |
| CLAUSE Copy; |
| BOOL Redundant ,Rewritten, Tried, ContextualRew, StandardRew; |
| SHARED_INDEX WoIndex,UsIndex; |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| #ifdef CHECK |
| if (!clause_IsClause(*Clause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_SelectedStaticReductions:"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(*Clause, Flags, Precedence); |
| #endif |
| |
| WoIndex = (SHARED_INDEX)NULL; |
| UsIndex = (SHARED_INDEX)NULL; |
| if (red_WorkedOffMode(Mode)) |
| WoIndex = prfs_WorkedOffSharingIndex(Search); |
| if (red_UsableMode(Mode)) |
| UsIndex = prfs_UsableSharingIndex(Search); |
| Copy = (CLAUSE)NULL; |
| Redundant = red_SimpleStaticReductions(Clause, Flags, Precedence, Result); |
| |
| if (Redundant) |
| return Redundant; |
| |
| if (flag_GetFlagValue(Flags, flag_RAED) != flag_RAEDOFF && |
| red_AssignmentEquationDeletion(*Clause, Flags, Precedence, &Copy, |
| prfs_NonTrivClauseNumber(Search), |
| (flag_GetFlagValue(Flags, flag_RAED)==flag_RAEDPOTUNSOUND))) { |
| red_ExchangeClauses(Clause, &Copy, Result); |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| } |
| |
| if (flag_GetFlagValue(Flags, flag_RFSUB)) { |
| *Subsumer = (CLAUSE)NULL; |
| if (WoIndex != NULL) { |
| *Subsumer = red_ForwardSubsumption(*Clause, WoIndex, Flags, Precedence); |
| if (*Subsumer != (CLAUSE)NULL) |
| return TRUE; |
| } |
| if (UsIndex != NULL) { |
| *Subsumer = red_ForwardSubsumption(*Clause, UsIndex, Flags, Precedence); |
| if (*Subsumer != (CLAUSE)NULL) |
| return TRUE; |
| } |
| } |
| |
| StandardRew = flag_GetFlagValue(Flags, flag_RFREW); |
| ContextualRew = flag_GetFlagValue(Flags, flag_RFCRW); |
| |
| Rewritten = (StandardRew || ContextualRew); |
| Tried = FALSE; |
| while (Rewritten) { |
| Rewritten = FALSE; |
| |
| if (WoIndex != NULL && |
| ((StandardRew && |
| red_RewriteRedClause(*Clause, WoIndex, Flags, Precedence, &Copy, |
| prfs_LastBacktrackLevel(Search))) || |
| (ContextualRew && |
| red_ContextualRewriting(Search, *Clause, red_WORKEDOFF, |
| prfs_LastBacktrackLevel(Search), &Copy)))) { |
| Rewritten = TRUE; |
| red_ExchangeClauses(Clause, &Copy, Result); |
| Redundant = red_SimpleStaticReductions(Clause, Flags, |
| Precedence, Result); |
| if (Redundant) |
| return Redundant; |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| if (flag_GetFlagValue(Flags, flag_RFSUB)) { |
| *Subsumer = (CLAUSE)NULL; |
| *Subsumer = red_ForwardSubsumption(*Clause, WoIndex, |
| Flags, Precedence); |
| if (*Subsumer != (CLAUSE)NULL) |
| return TRUE; /* Clause is redundant */ |
| if (UsIndex != NULL) { |
| *Subsumer = red_ForwardSubsumption(*Clause, UsIndex, |
| Flags, Precedence); |
| if (*Subsumer != (CLAUSE)NULL) |
| return TRUE; |
| } |
| } |
| } |
| |
| if (UsIndex != NULL && |
| (!Tried || Rewritten) && |
| ((StandardRew && |
| red_RewriteRedClause(*Clause, UsIndex, Flags, Precedence, |
| &Copy, prfs_LastBacktrackLevel(Search))) || |
| (ContextualRew && |
| red_ContextualRewriting(Search, *Clause, red_USABLE, |
| prfs_LastBacktrackLevel(Search), &Copy)))) { |
| Rewritten = TRUE; |
| red_ExchangeClauses(Clause, &Copy, Result); |
| Redundant = red_SimpleStaticReductions(Clause, Flags, |
| Precedence, Result); |
| if (Redundant) |
| return Redundant; |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| if (flag_GetFlagValue(Flags, flag_RFSUB)) { |
| *Subsumer = (CLAUSE)NULL; |
| if (WoIndex != NULL) |
| *Subsumer = red_ForwardSubsumption(*Clause, WoIndex, |
| Flags, Precedence); |
| if (*Subsumer != (CLAUSE)NULL) |
| return TRUE; |
| *Subsumer = red_ForwardSubsumption(*Clause, UsIndex, |
| Flags, Precedence); |
| if (*Subsumer != (CLAUSE)NULL) |
| return TRUE; |
| } |
| } |
| |
| Tried = TRUE; |
| } /* end of while(Rewritten) */ |
| |
| |
| if (flag_GetFlagValue(Flags, flag_RSSI)) { |
| red_SortSimplification(prfs_DynamicSortTheory(Search), *Clause, |
| prfs_LastBacktrackLevel(Search), |
| flag_GetFlagValue(Flags, flag_DOCPROOF), |
| Flags, Precedence, &Copy); |
| red_ExchangeClauses(Clause, &Copy, Result); |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| } |
| |
| if (flag_GetFlagValue(Flags, flag_RFMRR)) { |
| if (WoIndex) |
| red_MatchingReplacementResolution(*Clause, WoIndex, Flags, Precedence, |
| &Copy, prfs_LastBacktrackLevel(Search)); |
| red_ExchangeClauses(Clause, &Copy, Result); |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| if (UsIndex) |
| red_MatchingReplacementResolution(*Clause, UsIndex, Flags, Precedence, |
| &Copy, prfs_LastBacktrackLevel(Search)); |
| red_ExchangeClauses(Clause, &Copy, Result); |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| } |
| |
| if (flag_GetFlagValue(Flags, flag_RUNC)) { |
| if (WoIndex) |
| red_UnitConflict(*Clause, WoIndex, Flags, Precedence, |
| &Copy, prfs_LastBacktrackLevel(Search)); |
| red_ExchangeClauses(Clause, &Copy, Result); |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| if (UsIndex) |
| red_UnitConflict(*Clause, UsIndex, Flags, Precedence, |
| &Copy, prfs_LastBacktrackLevel(Search)); |
| red_ExchangeClauses(Clause, &Copy, Result); |
| if (clause_IsEmptyClause(*Clause)) |
| return FALSE; |
| } |
| |
| if (flag_GetFlagValue(Flags, flag_RSST)) |
| Redundant = red_ClauseDeletion(prfs_StaticSortTheory(Search),*Clause, |
| Flags, Precedence); |
| |
| #ifdef CHECK |
| clause_Check(*Clause, Flags, Precedence); |
| #endif |
| |
| return Redundant; |
| } |
| |
| |
| CLAUSE red_ReductionOnDerivedClause(PROOFSEARCH Search, CLAUSE Clause, |
| NAT Mode) |
| /************************************************************** |
| INPUT: A proof search object, a derived clause and a mode |
| indicating which indexes should be used for reductions. |
| RETURNS: The non-redundant clause after reducing <Clause>, |
| NULL if <Clause> is redundant. |
| EFFECT: Clauses probably generated, but redundant are kept according |
| to the <DocProof> flag and the split level of involved clauses. |
| depending on <Mode>, then clauses are reduced |
| with respect to WorkedOff and/or Usable Clauses. |
| ***************************************************************/ |
| { |
| CLAUSE RedClause; |
| LIST Redundant; |
| |
| #ifdef CHECK |
| cont_SaveState(); |
| #endif |
| |
| Redundant = list_Nil(); |
| RedClause = (CLAUSE)NULL; |
| |
| if (red_StaticReductions(Search,&Clause,&RedClause,&Redundant,Mode)) { |
| /* Clause is redundant */ |
| red_HandleRedundantDerivedClauses(Search, Redundant, Clause); |
| list_Delete(Redundant); |
| if (RedClause && |
| prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause), |
| prfs_LastBacktrackLevel(Search))) { |
| split_KeepClauseAtLevel(Search,Clause,clause_SplitLevel(RedClause)); |
| } |
| else |
| if (flag_GetFlagValue(prfs_Store(Search), flag_DOCPROOF)) |
| prfs_InsertDocProofClause(Search,Clause); |
| else |
| clause_Delete(Clause); |
| Clause = (CLAUSE)NULL; |
| } |
| else { |
| red_HandleRedundantDerivedClauses(Search, Redundant, Clause); |
| list_Delete(Redundant); |
| } |
| |
| #ifdef CHECK |
| cont_CheckState(); |
| #endif |
| |
| return Clause; |
| } |
| |
| CLAUSE red_CompleteReductionOnDerivedClause(PROOFSEARCH Search, CLAUSE Clause, |
| NAT Mode) |
| /************************************************************** |
| INPUT: A proof search object, a derived clause and a mode determining |
| which clauses to consider for reduction. |
| RETURNS: The non-redundant clause after reducing <Clause>, |
| NULL if <Clause> is redundant. |
| EFFECT: Clauses probably generated, but redundant are kept according |
| to the <DocProof> flag and the split level of involved clauses. |
| The clause is reduced with respect to all indexes determined |
| by <Mode> |
| ***************************************************************/ |
| { |
| CLAUSE RedClause; |
| LIST Redundant; |
| |
| #ifdef CHECK |
| cont_SaveState(); |
| #endif |
| |
| Redundant = list_Nil(); |
| RedClause = (CLAUSE)NULL; |
| |
| if (red_SelectedStaticReductions(Search,&Clause,&RedClause,&Redundant,Mode)) { |
| /* <Clause> is redundant */ |
| red_HandleRedundantDerivedClauses(Search, Redundant, Clause); |
| list_Delete(Redundant); |
| if (RedClause && |
| prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause), |
| prfs_LastBacktrackLevel(Search))) { |
| split_KeepClauseAtLevel(Search, Clause, clause_SplitLevel(RedClause)); |
| } |
| else |
| if (flag_GetFlagValue(prfs_Store(Search), flag_DOCPROOF)) |
| prfs_InsertDocProofClause(Search, Clause); |
| else |
| clause_Delete(Clause); |
| Clause = (CLAUSE)NULL; |
| } |
| else { |
| red_HandleRedundantDerivedClauses(Search, Redundant, Clause); |
| list_Delete(Redundant); |
| } |
| |
| #ifdef CHECK |
| cont_CheckState(); |
| #endif |
| |
| return Clause; |
| } |
| |
| |
| LIST red_BackReduction(PROOFSEARCH Search, CLAUSE Clause, NAT Mode) |
| /************************************************************** |
| INPUT: A proof search object, a clause and a mode flag. |
| RETURNS: A list of reduced clauses in usable and worked-off |
| (depending on <Mode>) in <Search> with respect to <Clause>. |
| The original clauses that become redundant are either deleted |
| or kept for proof documentation or splitting. |
| EFFECT: The original clauses that become redundant are either deleted |
| or kept for proof documentation or splitting. |
| ***************************************************************/ |
| { |
| LIST Result, Redundant; |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| |
| #ifdef CHECK |
| cont_SaveState(); |
| #endif |
| |
| Result = list_Nil(); |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| /* Subsumption */ |
| if (flag_GetFlagValue(Flags, flag_RBSUB)) { |
| Redundant = list_Nil(); |
| if (red_WorkedOffMode(Mode)) |
| Redundant = red_BackSubsumption(Clause, |
| prfs_WorkedOffSharingIndex(Search), |
| Flags, Precedence); |
| if (red_UsableMode(Mode)) |
| Redundant = list_Nconc(Redundant, |
| red_BackSubsumption(Clause, |
| prfs_UsableSharingIndex(Search), |
| Flags, Precedence)); |
| red_HandleRedundantIndexedClauses(Search, Redundant, Clause); |
| list_Delete(Redundant); |
| } |
| |
| /* Matching Replacement Resolution */ |
| if (flag_GetFlagValue(Flags, flag_RBMRR)) { |
| Redundant = list_Nil(); |
| if (red_WorkedOffMode(Mode)) |
| Redundant = red_BackMatchingReplacementResolution(Clause, |
| prfs_WorkedOffSharingIndex(Search), |
| Flags, Precedence, &Result); |
| if (red_UsableMode(Mode)) |
| Redundant = list_Nconc(Redundant, |
| red_BackMatchingReplacementResolution(Clause, |
| prfs_UsableSharingIndex(Search), |
| Flags, Precedence, &Result)); |
| red_HandleRedundantIndexedClauses(Search, Redundant, Clause); |
| list_Delete(Redundant); |
| } |
| |
| /* Standard Rewriting */ |
| if (flag_GetFlagValue(Flags, flag_RBREW)) { |
| Redundant = list_Nil(); |
| if (red_WorkedOffMode(Mode)) |
| Redundant = red_BackRewriting(Clause,prfs_WorkedOffSharingIndex(Search), |
| Flags, Precedence, &Result); |
| if (red_UsableMode(Mode)) |
| Redundant = list_Nconc(Redundant, |
| red_BackRewriting(Clause, |
| prfs_UsableSharingIndex(Search), |
| Flags, Precedence, &Result)); |
| |
| red_HandleRedundantIndexedClauses(Search, Redundant, Clause); |
| list_Delete(Redundant); |
| } |
| |
| /* Contextual Rewriting */ |
| if (flag_GetFlagValue(Flags, flag_RBCRW)) { |
| Redundant = list_Nil(); |
| if (red_WorkedOffMode(Mode)) |
| Redundant = red_BackContextualRewriting(Search, Clause, red_WORKEDOFF, |
| &Result); |
| if (red_UsableMode(Mode)) |
| Redundant = list_Nconc(Redundant, |
| red_BackContextualRewriting(Search, Clause, |
| red_USABLE, &Result)); |
| |
| red_HandleRedundantIndexedClauses(Search, Redundant, Clause); |
| list_Delete(Redundant); |
| } |
| |
| #ifdef CHECK |
| cont_CheckState(); |
| #endif |
| |
| return Result; |
| } |
| |
| |
| static __inline__ LIST red_MergeClauseListsByWeight(LIST L1, LIST L2) |
| /************************************************************** |
| INPUT: Two lists of clauses, sorted by weight. |
| RETURNS: |
| EFFECT: |
| ***************************************************************/ |
| { |
| return list_NNumberMerge(L1, L2, (NAT (*)(POINTER))clause_Weight); |
| } |
| |
| |
| LIST red_CompleteReductionOnDerivedClauses(PROOFSEARCH Search, |
| LIST DerivedClauses, NAT Mode, |
| int Bound, NAT BoundMode, |
| int *BoundApplied) |
| /************************************************************** |
| INPUT: A proof search object, a list of newly derived (unshared) clauses, |
| a mode determining which clause lists to consider for reduction, |
| a bound and a bound mode to cut off generated clauses. |
| RETURNS: A list of empty clauses that may be derived during the |
| reduction process. |
| <*BoundApplied> is set to the mode dependent value of the |
| smallest clause if a clause is deleted because of a bound. |
| EFFECT: The <DerivedClauses> are destructively reduced and reduced clauses |
| from the indexes are checked out and all finally reduced clauses |
| are checked into the indexes. Depending on <Mode> either the |
| WorkedOff, Usable or both indexes are considered. |
| The <DocProof> Flag is considered. |
| ***************************************************************/ |
| { |
| LIST EmptyClauses,NewClauses,Scan; |
| NAT ClauseBound; |
| CLAUSE Clause; |
| FLAGSTORE Flags; |
| |
| #ifdef CHECK |
| cont_SaveState(); |
| #endif |
| |
| EmptyClauses = list_Nil(); |
| DerivedClauses = clause_ListSortWeighed(DerivedClauses); |
| ClauseBound = 0; |
| Flags = prfs_Store(Search); |
| |
| while (!list_Empty(DerivedClauses)) { |
| #ifdef WIN |
| clock_PingOneSecond(); |
| #endif |
| Clause = list_NCar(&DerivedClauses); |
| if (prfs_SplitStackEmpty(Search)) /* Otherwise splitting not compatible with bound deletion */ |
| Clause = red_CompleteReductionOnDerivedClause(Search, Clause, Mode); |
| |
| if (Clause != NULL && BoundMode != flag_BOUNDMODEUNLIMITED && |
| Bound != flag_BOUNDSTARTUNLIMITED && !clause_IsFromInput(Clause) && |
| !clause_IsFromSplitting(Clause)) { |
| switch (BoundMode) { |
| case flag_BOUNDMODERESTRICTEDBYWEIGHT: |
| ClauseBound = clause_Weight(Clause); |
| break; |
| case flag_BOUNDMODERESTRICTEDBYDEPTH: |
| ClauseBound = clause_ComputeTermDepth(Clause); |
| break; |
| default: |
| misc_StartUserErrorReport(); |
| misc_UserErrorReport("\n Error while applying bound restrictions:"); |
| misc_UserErrorReport("\n You selected an unknown bound mode.\n"); |
| misc_FinishUserErrorReport(); |
| } |
| if (ClauseBound > Bound) { |
| if (flag_GetFlagValue(Flags, flag_PBDC)) { |
| fputs("\nDeleted by bound: ", stdout); |
| clause_Print(Clause); |
| } |
| clause_Delete(Clause); |
| if (*BoundApplied == -1 || ClauseBound < *BoundApplied) |
| *BoundApplied = ClauseBound; |
| Clause = (CLAUSE)NULL; |
| } |
| } |
| |
| if (Clause != (CLAUSE)NULL && /* For clauses below bound, splitting is */ |
| !prfs_SplitStackEmpty(Search)) /* compatible with bound deletion */ |
| Clause = red_CompleteReductionOnDerivedClause(Search, Clause, Mode); |
| |
| if (Clause) { |
| prfs_IncKeptClauses(Search); |
| if (flag_GetFlagValue(Flags, flag_PKEPT)) { |
| fputs("\nKept: ", stdout); |
| clause_Print(Clause); |
| } |
| if (clause_IsEmptyClause(Clause)) |
| EmptyClauses = list_Cons(Clause,EmptyClauses); |
| else { |
| NewClauses = red_BackReduction(Search, Clause, Mode); |
| prfs_IncDerivedClauses(Search, list_Length(NewClauses)); |
| if (flag_GetFlagValue(Flags, flag_PDER)) |
| for (Scan=NewClauses; !list_Empty(Scan); Scan=list_Cdr(Scan)) { |
| fputs("\nDerived: ", stdout); |
| clause_Print(list_Car(Scan)); |
| } |
| NewClauses = split_ExtractEmptyClauses(NewClauses,&EmptyClauses); |
| |
| prfs_InsertUsableClause(Search,Clause); |
| NewClauses = list_NumberSort(NewClauses, (NAT (*) (POINTER)) clause_Weight); |
| DerivedClauses = red_MergeClauseListsByWeight(DerivedClauses,NewClauses); |
| } |
| } |
| } |
| |
| #ifdef CHECK |
| cont_CheckState(); |
| #endif |
| |
| return EmptyClauses; |
| } |
| |
| |
| |
| static CLAUSE red_CDForwardSubsumer(CLAUSE RedCl, st_INDEX Index, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /********************************************************** |
| INPUT: A pointer to a non-empty clause, an index of |
| clauses, a flag store and a precedence. |
| RETURNS: The first clause from the Approx Set which |
| subsumes 'RedCl'. |
| ***********************************************************/ |
| { |
| TERM Atom,AtomGen; |
| LIST LitScan; |
| int i,length; |
| CLAUSE CandCl; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RedCl, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_CDForwardSubsumer :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedCl, Flags, Precedence); |
| #endif |
| |
| length = clause_Length(RedCl); |
| |
| for (i = 0; i < length; i++) { |
| Atom = clause_GetLiteralAtom(RedCl, i); |
| AtomGen = st_ExistGen(cont_LeftContext(), Index, Atom); |
| |
| while (AtomGen) { |
| for (LitScan = term_SupertermList(AtomGen); |
| !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) { |
| CandCl = clause_LiteralOwningClause(list_Car(LitScan)); |
| |
| if (clause_GetLiteral(CandCl,clause_FirstLitIndex()) == (LITERAL)list_Car(LitScan) && |
| subs_Subsumes(CandCl, RedCl, clause_FirstLitIndex(), i)) { |
| st_CancelExistRetrieval(); |
| return CandCl; |
| } |
| } |
| AtomGen = st_NextCandidate(); |
| } |
| } |
| return (CLAUSE)NULL; |
| } |
| |
| |
| static BOOL red_CDForwardSubsumption(CLAUSE RedClause, st_INDEX Index, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /********************************************************** |
| INPUT: A clause, an index of clauses, a flag store and |
| a precedence. |
| RETURNS: The boolean value TRUE if the clause is subsumed |
| by an indexed clause, if so, the clause is deleted, |
| either really or locally. |
| ***********************************************************/ |
| { |
| BOOL IsSubsumed; |
| CLAUSE Subsumer; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RedClause, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_CDForwardSubSumption :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| IsSubsumed = FALSE; |
| Subsumer = red_CDForwardSubsumer(RedClause, Index, Flags, Precedence); |
| |
| if (clause_Exists(Subsumer)) { |
| IsSubsumed = TRUE; |
| |
| if (flag_GetFlagValue(Flags, flag_DOCSST) && |
| flag_GetFlagValue(Flags, flag_PSUB)) { |
| fputs("\nFSubsumption:", stdout); |
| clause_Print(RedClause); |
| printf(" by %d ",clause_Number(Subsumer)); |
| } |
| } |
| return IsSubsumed; |
| } |
| |
| |
| static void red_CDBackSubsumption(CLAUSE RedCl, FLAGSTORE Flags, |
| PRECEDENCE Precedence, |
| LIST* UsListPt, LIST* WOListPt, |
| st_INDEX Index) |
| /********************************************************** |
| INPUT: A pointer to a non-empty clause, a flag store, |
| a precedence, and an index of clauses. |
| RETURNS: Nothing. |
| ***********************************************************/ |
| { |
| TERM Atom,AtomInst; |
| CLAUSE SubsumedCl; |
| LIST Scan, SubsumedList; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(RedCl, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_CDBackupSubSumption :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedCl, Flags, Precedence); |
| #endif |
| |
| SubsumedList = list_Nil(); |
| |
| if (!clause_IsEmptyClause(RedCl)) { |
| Atom = clause_GetLiteralAtom(RedCl, clause_FirstLitIndex()); |
| AtomInst = st_ExistInstance(cont_LeftContext(), Index, Atom); |
| |
| while(AtomInst) { |
| for (Scan = term_SupertermList(AtomInst); !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| SubsumedCl = clause_LiteralOwningClause(list_Car(Scan)); |
| if ((RedCl != SubsumedCl) && |
| subs_Subsumes(RedCl, SubsumedCl, clause_FirstLitIndex(), |
| clause_LiteralGetIndex(list_Car(Scan))) && |
| !list_PointerMember(SubsumedList, SubsumedCl)) |
| SubsumedList = list_Cons(SubsumedCl, SubsumedList); |
| } |
| AtomInst = st_NextCandidate(); |
| } |
| |
| for (Scan = SubsumedList; !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| SubsumedCl = list_Car(Scan); |
| |
| if (flag_GetFlagValue(Flags, flag_DOCSST) && flag_GetFlagValue(Flags, flag_PSUB)) { |
| fputs("\nBSubsumption: ", stdout); |
| clause_Print(SubsumedCl); |
| printf(" by %d ",clause_Number(RedCl)); |
| } |
| |
| |
| if (clause_GetFlag(SubsumedCl,WORKEDOFF)) { |
| *WOListPt = list_PointerDeleteOneElement(*WOListPt, SubsumedCl); |
| }else { |
| *UsListPt = list_PointerDeleteOneElement(*UsListPt, SubsumedCl); |
| } |
| clause_DeleteFlatFromIndex(SubsumedCl, Index); |
| } |
| list_Delete(SubsumedList); |
| } |
| } |
| |
| |
| static LIST red_CDDerivables(SORTTHEORY Theory, CLAUSE GivenClause, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A sort theory, a clause, a flag store and a |
| precedence. |
| RETURNS: A list of clauses derivable from <GivenClause> and |
| the declaration clauses in <Theory>. |
| ***************************************************************/ |
| { |
| LIST ListOfDerivedClauses; |
| |
| #ifdef CHECK |
| if (!(clause_IsClause(GivenClause, Flags, Precedence))) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_CDDeriveables :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(GivenClause, Flags, Precedence); |
| #endif |
| |
| if (clause_HasTermSortConstraintLits(GivenClause)) |
| ListOfDerivedClauses = inf_ForwardSortResolution(GivenClause, |
| sort_TheoryIndex(Theory), |
| Theory, TRUE, |
| Flags, Precedence); |
| else |
| ListOfDerivedClauses = inf_ForwardEmptySort(GivenClause, |
| sort_TheoryIndex(Theory), |
| Theory, TRUE, |
| Flags, Precedence); |
| |
| return ListOfDerivedClauses; |
| } |
| |
| |
| static BOOL red_CDReduce(SORTTHEORY Theory, CLAUSE RedClause, |
| FLAGSTORE Flags, PRECEDENCE Precedence, |
| LIST *ApproxUsListPt, LIST *ApproxWOListPt, |
| st_INDEX Index) |
| /************************************************************** |
| INPUT: A sort theory, an unshared clause, a flag store, |
| a precedence, their index and two pointers to the |
| sort reduction subproof usable and worked off list. |
| RETURNS: TRUE iff <RedClause> is redundant with respect to |
| clauses in the index or theory. |
| EFFECT: <RedClause> is destructively changed. |
| The <DocProof> flag is changed temporarily. |
| ***************************************************************/ |
| { |
| CLAUSE Copy; |
| |
| #ifdef CHECK |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| Copy = (CLAUSE)NULL; /* Only needed for interface */ |
| |
| red_ObviousReductions(RedClause, FALSE, Flags, Precedence, &Copy); |
| red_SortSimplification(Theory, RedClause, NAT_MAX, FALSE, |
| Flags, Precedence, &Copy); |
| |
| if (clause_IsEmptyClause(RedClause)) |
| return FALSE; |
| |
| red_Condensing(RedClause, FALSE, Flags, Precedence, &Copy); |
| |
| if (red_CDForwardSubsumption(RedClause, Index, Flags, Precedence)) |
| return TRUE; |
| else { /* RedClause isn't subsumed! */ |
| red_CDBackSubsumption(RedClause, Flags, Precedence, |
| ApproxUsListPt, ApproxWOListPt, Index); |
| clause_InsertFlatIntoIndex(RedClause, Index); |
| *ApproxUsListPt = list_Cons(RedClause, *ApproxUsListPt); |
| } |
| |
| #ifdef CHECK |
| clause_Check(RedClause, Flags, Precedence); |
| if (Copy != (CLAUSE)NULL) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_CDReduce :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| |
| #endif |
| |
| return FALSE; |
| } |
| |
| |
| BOOL red_ClauseDeletion(SORTTHEORY Theory, CLAUSE RedClause, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A sort theory, a clause (unshared), a flag store |
| and a precedence. |
| RETURNS: TRUE iff the sort constraint of the clause is |
| unsolvable with respect to the sort theory. |
| ***************************************************************/ |
| { |
| if (Theory != (SORTTHEORY)NULL) { |
| CLAUSE ConstraintClause, GivenClause; |
| LIST ApproxUsableList, ApproxWOList, EmptyClauses, ApproxDerivables, Scan; |
| int i,nc, Count, OldClauseCounter; |
| st_INDEX Index; |
| |
| #ifdef CHECK |
| if (!(clause_IsClause(RedClause, Flags, Precedence))) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_ClauseDeletion :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| |
| if (clause_HasEmptyConstraint(RedClause) || !flag_GetFlagValue(Flags, flag_RSST)) |
| return FALSE; |
| |
| if (flag_GetFlagValue(Flags, flag_DOCSST)) { |
| fputs("\n\nStatic Soft Typing tried on: ", stdout); |
| clause_Print(RedClause); |
| } |
| |
| Index = st_IndexCreate(); |
| Scan = list_Nil(); |
| nc = clause_NumOfConsLits(RedClause); |
| OldClauseCounter = clause_Counter(); |
| |
| /* Make constraint clause, insert it into the Approx-usable-list: */ |
| |
| for (i = clause_FirstLitIndex(); i < nc; i++) |
| Scan = list_Cons(term_Copy(clause_LiteralAtom( |
| clause_GetLiteral(RedClause, i))), Scan); |
| |
| Scan = list_NReverse(Scan); |
| ConstraintClause = clause_Create(Scan, list_Nil(), list_Nil(), |
| Flags, Precedence); |
| list_Delete(Scan); |
| clause_InitSplitData(ConstraintClause); |
| clause_AddParentClause(ConstraintClause, clause_Number(RedClause)); |
| clause_AddParentLiteral(ConstraintClause, clause_FirstLitIndex()); |
| clause_SetFromClauseDeletion(ConstraintClause); |
| clause_InsertFlatIntoIndex(ConstraintClause, Index); |
| ApproxUsableList = list_List(ConstraintClause); |
| ApproxWOList = list_Nil(); |
| |
| /* fputs("\nConstraint clause: ",stdout); clause_Print(ConstraintClause); */ |
| |
| /* Now the lists are initialized, the subproof is started: */ |
| |
| EmptyClauses = list_Nil(); |
| Count = 0; |
| |
| if (flag_GetFlagValue(Flags, flag_DOCSST)) { |
| puts("\n*************** Static Soft Typing Subproof: ***************"); |
| puts("The usable list:"); |
| clause_ListPrint(ApproxUsableList); |
| puts("\nThe worked-off list:"); |
| clause_ListPrint(ApproxWOList); |
| /* fputs("\nAll indexed clauses: ", stdout); |
| clause_PrintAllIndexedClauses(ShIndex); */ |
| } |
| while (!list_Empty(ApproxUsableList) && list_Empty(EmptyClauses)) { |
| GivenClause = list_Car(ApproxUsableList); |
| clause_SetFlag(GivenClause,WORKEDOFF); |
| |
| if (flag_GetFlagValue(Flags, flag_DOCSST)) { |
| fputs("\n\tSubproof Given clause: ", stdout); |
| clause_Print(GivenClause); fflush(stdout); |
| } |
| ApproxWOList = list_Cons(GivenClause, ApproxWOList); |
| ApproxUsableList = list_PointerDeleteOneElement(ApproxUsableList,GivenClause); |
| ApproxDerivables = red_CDDerivables(Theory,GivenClause, Flags, Precedence); |
| ApproxDerivables = split_ExtractEmptyClauses(ApproxDerivables, &EmptyClauses); |
| |
| if (!list_Empty(EmptyClauses)) { /* Exit while loop! */ |
| if (flag_GetFlagValue(Flags, flag_DOCSST)) { |
| fputs("\nStatic Soft Typing not successful: ", stdout); |
| clause_Print(list_Car(EmptyClauses)); |
| } |
| clause_DeleteClauseList(ApproxDerivables); |
| ApproxDerivables = list_Nil(); |
| } |
| else { |
| CLAUSE DerClause; |
| for (Scan = ApproxDerivables; !list_Empty(Scan) && list_Empty(EmptyClauses); |
| Scan = list_Cdr(Scan)) { |
| DerClause = (CLAUSE)list_Car(Scan); |
| if (red_CDReduce(Theory, DerClause, Flags, Precedence, |
| &ApproxUsableList, &ApproxWOList, Index)) |
| clause_Delete(DerClause); |
| else{ |
| Count++; |
| if (flag_GetFlagValue(Flags, flag_DOCSST)) { |
| putchar('\n'); |
| clause_Print(DerClause); |
| } |
| if (clause_IsEmptyClause(DerClause)) |
| EmptyClauses = list_Cons(DerClause,EmptyClauses); |
| } |
| list_Rplaca(Scan,(CLAUSE)NULL); |
| } |
| |
| if (!list_Empty(EmptyClauses)) { |
| if (flag_GetFlagValue(Flags, flag_DOCSST)) { |
| fputs(" Static Soft Typing not successful!", stdout); |
| clause_Print(list_Car(EmptyClauses)); |
| } |
| clause_DeleteClauseList(ApproxDerivables); /* There still may be clauses in the list */ |
| ApproxDerivables = list_Nil(); |
| } |
| else { |
| list_Delete(ApproxDerivables); |
| ApproxDerivables = list_Nil(); |
| } |
| } |
| } |
| |
| if (!list_Empty(EmptyClauses)) { |
| if (flag_GetFlagValue(Flags, flag_DOCSST)) { |
| puts("\nStatic Soft Typing failed, constraint solvable."); |
| puts("************ Static Soft Typing Subproof finished. ************"); |
| } |
| } |
| else |
| if (flag_GetFlagValue(Flags, flag_PSST)) { |
| fputs("\nStatic Soft Typing deleted: ", stdout); |
| clause_Print(RedClause); |
| } |
| |
| /* Cleanup */ |
| clause_DeleteClauseListFlatFromIndex(ApproxUsableList, Index); |
| clause_DeleteClauseListFlatFromIndex(ApproxWOList, Index); |
| st_IndexDelete(Index); |
| clause_SetCounter(OldClauseCounter); |
| |
| if (!list_Empty(EmptyClauses)) { |
| clause_DeleteClauseList(EmptyClauses); |
| return FALSE; |
| } |
| |
| return TRUE; |
| |
| #ifdef CHECK |
| clause_Check(RedClause, Flags, Precedence); |
| #endif |
| } |
| return FALSE; |
| } |
| |
| LIST red_SatUnit(PROOFSEARCH Search, LIST ClauseList) |
| /********************************************************* |
| INPUT: A proof search object and a list of unshared clauses. |
| RETURNS: A possibly empty list of empty clauses. |
| EFFECT: Does a shallow saturation of the conclauses depending on the |
| flag_SATUNIT flag. |
| The <DocProof> flag is considered. |
| **********************************************************/ |
| { |
| CLAUSE Given,Clause; |
| LIST Scan, Derivables, EmptyClauses, BackReduced; |
| NAT n, Derived; |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| Derived = flag_GetFlagValue(Flags, flag_CNFPROOFSTEPS); |
| EmptyClauses = list_Nil(); |
| |
| ClauseList = clause_ListSortWeighed(ClauseList); |
| |
| while (!list_Empty(ClauseList) && list_Empty(EmptyClauses)) { |
| Given = (CLAUSE)list_NCar(&ClauseList); |
| Given = red_ReductionOnDerivedClause(Search, Given, red_USABLE); |
| if (Given) { |
| if (clause_IsEmptyClause(Given)) |
| EmptyClauses = list_List(Given); |
| else { |
| BackReduced = red_BackReduction(Search, Given, red_USABLE); |
| |
| if (Derived != 0) { |
| Derivables = inf_BoundedDepthUnitResolution(Given, |
| prfs_UsableSharingIndex(Search), |
| FALSE, Flags, Precedence); |
| n = list_Length(Derivables); |
| if (n > Derived) |
| Derived = 0; |
| else |
| Derived = Derived - n; |
| } |
| else |
| Derivables = list_Nil(); |
| |
| Derivables = list_Nconc(BackReduced,Derivables); |
| Derivables = split_ExtractEmptyClauses(Derivables, &EmptyClauses); |
| |
| prfs_InsertUsableClause(Search, Given); |
| |
| for(Scan = Derivables; !list_Empty(Scan); Scan = list_Cdr(Scan)) { |
| Clause = (CLAUSE)list_Car(Scan); |
| clause_SetDepth(Clause,0); |
| } |
| ClauseList = list_Nconc(ClauseList,Derivables); |
| Derivables = list_Nil(); |
| } |
| } |
| } |
| for(Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan)) |
| prfs_InsertUsableClause(Search, list_Car(Scan)); |
| list_Delete(ClauseList); |
| return EmptyClauses; |
| } |
| |
| static CLAUSE red_SpecialInputReductions(CLAUSE Clause, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /********************************************************* |
| INPUT: A clause and a flag store. |
| RETURNS: The clause where the logical constants TRUE, FALSE |
| are removed. |
| EFFECT: The clause is destructively changed. |
| **********************************************************/ |
| { |
| int i,end; |
| LIST Indexes; |
| TERM Atom; |
| |
| #ifdef CHECK |
| clause_Check(Clause, Flags, Precedence); |
| #endif |
| |
| Indexes = list_Nil(); |
| end = clause_LastAntecedentLitIndex(Clause); |
| |
| for (i = clause_FirstConstraintLitIndex(Clause); i <= end; i++) { |
| Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i)); |
| if (fol_IsTrue(Atom)) |
| Indexes = list_Cons((POINTER)i,Indexes); |
| } |
| |
| end = clause_LastSuccedentLitIndex(Clause); |
| |
| for (i = clause_FirstSuccedentLitIndex(Clause); i <= end; i++) { |
| Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i)); |
| if (fol_IsFalse(Atom)) |
| Indexes = list_Cons((POINTER)i,Indexes); |
| } |
| |
| clause_DeleteLiterals(Clause,Indexes, Flags, Precedence); |
| list_Delete(Indexes); |
| |
| return Clause; |
| } |
| |
| |
| LIST red_ReduceInput(PROOFSEARCH Search, LIST ClauseList) |
| /********************************************************* |
| INPUT: A proof search object and a list of unshared clauses. |
| RETURNS: A list of empty clauses. |
| EFFECT: Interreduces the clause list and inserts the clauses into <Search>. |
| Keeps track of derived and kept clauses. |
| Time limits and the DocProof flag are considered. |
| **********************************************************/ |
| { |
| CLAUSE Given; |
| LIST Scan, EmptyClauses, BackReduced; |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| EmptyClauses = list_Nil(); |
| ClauseList = clause_ListSortWeighed(list_Copy(ClauseList)); |
| ClauseList = split_ExtractEmptyClauses(ClauseList, &EmptyClauses); |
| |
| while (!list_Empty(ClauseList) && list_Empty(EmptyClauses) && |
| (flag_GetFlagValue(Flags,flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED || |
| flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) { |
| Given = (CLAUSE)list_NCar(&ClauseList); |
| #ifdef CHECK |
| if (!clause_IsClause(Given, Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_ReduceInput :"); |
| misc_ErrorReport(" Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| Given = red_SpecialInputReductions(Given, Flags, Precedence); |
| Given = red_ReductionOnDerivedClause(Search, Given, red_USABLE); |
| if (Given) { |
| prfs_IncKeptClauses(Search); |
| if (clause_IsEmptyClause(Given)) |
| EmptyClauses = list_List(Given); |
| else { |
| BackReduced = red_BackReduction(Search, Given, red_USABLE); |
| prfs_IncDerivedClauses(Search, list_Length(BackReduced)); |
| BackReduced = split_ExtractEmptyClauses(BackReduced, &EmptyClauses); |
| prfs_InsertUsableClause(Search, Given); |
| BackReduced = clause_ListSortWeighed(BackReduced); |
| ClauseList = red_MergeClauseListsByWeight(ClauseList, BackReduced); |
| } |
| } |
| } |
| for(Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan)) |
| prfs_InsertUsableClause(Search, list_Car(Scan)); |
| list_Delete(ClauseList); |
| return EmptyClauses; |
| } |
| |
| |
| LIST red_SatInput(PROOFSEARCH Search) |
| /********************************************************* |
| INPUT: A proof search object. |
| RETURNS: A list of derived empty clauses. |
| EFFECT: Does a saturation from the conjectures into the axioms/conjectures |
| Keeps track of derived and kept clauses. Keeps track of a possible |
| time limit. |
| Considers the Usable clauses in <Search> and a possible time limit. |
| **********************************************************/ |
| { |
| CLAUSE Given; |
| LIST Scan, ClauseList, Derivables, EmptyClauses; |
| int n; |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| EmptyClauses = list_Nil(); |
| ClauseList = list_Nil(); |
| Scan = prfs_UsableClauses(Search); |
| n = list_Length(Scan); |
| |
| while(!list_Empty(Scan) && |
| n > 0 && |
| (flag_GetFlagValue(Flags,flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED || |
| flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) { |
| Given = (CLAUSE)list_Car(Scan); |
| if (clause_GetFlag(Given,CONCLAUSE)) { |
| Derivables = inf_BoundedDepthUnitResolution(Given, |
| prfs_UsableSharingIndex(Search), |
| FALSE, Flags, Precedence); |
| n -= list_Length(Derivables); |
| ClauseList = list_Nconc(Derivables,ClauseList); |
| } |
| Scan = list_Cdr(Scan); |
| } |
| |
| prfs_IncDerivedClauses(Search, list_Length(ClauseList)); |
| EmptyClauses = red_ReduceInput(Search, ClauseList); |
| list_Delete(ClauseList); |
| ClauseList = list_Nil(); |
| if (list_Empty(EmptyClauses)) { |
| Scan=prfs_UsableClauses(Search); |
| while (!list_Empty(Scan) && |
| n > 0 && |
| (flag_GetFlagValue(Flags,flag_TIMELIMIT)==flag_TIMELIMITUNLIMITED || |
| flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) { |
| Given = (CLAUSE)list_Car(Scan); |
| if (clause_GetFlag(Given,CONCLAUSE) && clause_IsFromInput(Given)) { |
| Derivables = inf_BoundedDepthUnitResolution(Given, |
| prfs_UsableSharingIndex(Search), |
| TRUE, Flags, Precedence); |
| n -= list_Length(Derivables); |
| ClauseList = list_Nconc(Derivables,ClauseList); |
| } |
| Scan = list_Cdr(Scan); |
| } |
| prfs_IncDerivedClauses(Search, list_Length(ClauseList)); |
| EmptyClauses = red_ReduceInput(Search, ClauseList); |
| list_Delete(ClauseList); |
| } |
| return EmptyClauses; |
| } |
| |
| void red_CheckSplitSubsumptionCondition(PROOFSEARCH Search) |
| /********************************************************* |
| INPUT: A proof search object. |
| EFFECT: For all deleted clauses in the split stack, it |
| is checked whether they are subsumed by some |
| existing clause. If they are not, a core is dumped. |
| Used for debugging. |
| **********************************************************/ |
| { |
| LIST Scan1,Scan2; |
| CLAUSE Clause; |
| FLAGSTORE Flags; |
| PRECEDENCE Precedence; |
| |
| Flags = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| for (Scan1=prfs_SplitStack(Search);!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) |
| for (Scan2=prfs_SplitDeletedClauses(list_Car(Scan1));!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) { |
| Clause = (CLAUSE)list_Car(Scan2); |
| if (!red_ForwardSubsumer(Clause, prfs_WorkedOffSharingIndex(Search), |
| Flags, Precedence) && |
| !red_ForwardSubsumer(Clause, prfs_UsableSharingIndex(Search), |
| Flags, Precedence) && |
| !red_ClauseDeletion(prfs_StaticSortTheory(Search),Clause, |
| Flags, Precedence)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In red_CheckSplitSubsumptionCondition: No clause found implying "); |
| clause_Print(Clause); |
| misc_ErrorReport("\n Current Split: "); |
| prfs_PrintSplit(list_Car(Scan1)); |
| misc_FinishErrorReport(); |
| } |
| } |
| } |