static LIST split_DeleteClausesDependingOnLevelFromList(PROOFSEARCH Search, LIST ClauseList, int Level, LIST* New) /************************************************************** INPUT: A proof search object, a list of unshared clauses and a split level. EFFECT: Deletes all clauses depending on split level from <ClauseList>. All split stored deleted clauses from the level of the deleted clauses from <ClauseList> are stored in <*New>. RETURNS: The updated list and the recover clauses in <*New>. ***************************************************************/ { LIST Scan; CLAUSE Clause; SPLIT Reinsert; for (Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan)) { Clause = list_Car(Scan); if (clause_DependsOnSplitLevel(Clause, Level)) { Reinsert = prfs_GetSplitOfLevel(clause_SplitLevel(Clause), Search); if (prfs_SplitDeletedClauses(Reinsert) != list_Nil()) { *New = list_Nconc(prfs_SplitDeletedClauses(Reinsert), *New); prfs_SplitSetDeletedClauses(Reinsert, list_Nil()); } prfs_InsertDocProofClause(Search,Clause); list_Rplaca(Scan, NULL); } } return list_PointerDeleteElement(ClauseList, NULL); }
static void tab_DeleteGen(TABLEAU T, LIST* Clauses, BOOL DeleteClauses) /************************************************************** INPUT: A tableau, a list of clauses by reference, a flag RETURNS: Nothing EFFECTS: Depending on <DeleteClauses>, all clauses in the tableau are added to <Clauses> or just deleted. The memory for the tableau and its clause lists is freed. ***************************************************************/ { if (tab_IsEmpty(T)) return; tab_DeleteGen(tab_RightBranch(T), Clauses, DeleteClauses); tab_DeleteGen(tab_LeftBranch(T), Clauses, DeleteClauses); list_Delete(tab_RightSplitClauses(T)); if (DeleteClauses) list_Delete(tab_Clauses(T)); else *Clauses = list_Nconc(tab_Clauses(T), *Clauses); tab_DeleteFlat(T); }
LIST list_NUnion(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER)) /************************************************************** INPUT: Two lists and an equality test for the elements. RETURNS: Regarding both lists as sets, the union of the sets. CAUTION: Destructive. ***************************************************************/ { return list_DeleteDuplicates(list_Nconc(List1,List2), Test); }
LIST list_NPointerUnion(LIST List1, LIST List2) /************************************************************** INPUT: Two lists. RETURNS: Regarding both lists as sets, the union of the sets. CAUTION: Destructive. ***************************************************************/ { return list_PointerDeleteDuplicates(list_Nconc(List1,List2)); }
TABLEAU tab_RemoveIncompleteSplits(TABLEAU T, LIST* Clauses) /************************************************************** INPUT: A Tableau, a list of clauses by reference RETURNS: The reduced tableau: If a node has exactly one successor (that is, the corresponding split was not completed), delete the successor and move its subtrees to <T>. EFFECTS: The successor node is deleted, and its clauses added to <Clauses> ***************************************************************/ { LIST NewClauses; TABLEAU Child; if (tab_IsEmpty(T)) return T; if (tab_IsLeaf(T)) return T; if (!tab_IsEmpty(tab_RightBranch(T)) && !tab_IsEmpty(tab_LeftBranch(T))) { tab_SetRightBranch(T, tab_RemoveIncompleteSplits(tab_RightBranch(T), Clauses)); tab_SetLeftBranch(T, tab_RemoveIncompleteSplits(tab_LeftBranch(T), Clauses)); return T; } if (tab_IsEmpty(tab_RightBranch(T))) Child = tab_LeftBranch(T); else Child = tab_RightBranch(T); Child = tab_RemoveIncompleteSplits(Child, Clauses); tab_SetLeftBranch(T, tab_LeftBranch(Child)); tab_SetRightBranch(T, tab_RightBranch(Child)); /* copy split data */ tab_SetSplitClause(T, tab_SplitClause(Child)); tab_SetLeftSplitClause(T, tab_LeftSplitClause(Child)); tab_SetRightSplitClauses(T, tab_RightSplitClauses(Child)); /* delete ancestors of deleted clauses and remember */ NewClauses = tab_DeleteFlat(Child); (*Clauses) = list_Nconc(NewClauses, *Clauses); return T; }
void tab_ToClauseList(TABLEAU T, LIST* Proof) /************************************************************** INPUT: A tableau <T>, a list of clauses RETURNS: Nothing. EFFECTS: All clauses in T are added to <Proof> ***************************************************************/ { if (tab_IsEmpty(T)) return; (*Proof) = list_Nconc(list_Copy(tab_Clauses(T)), *Proof); tab_ToClauseList(tab_LeftBranch(T),Proof); tab_ToClauseList(tab_RightBranch(T),Proof); }
LIST hsh_GetAllEntries(HASH H) /************************************************************** INPUT: A hasharray RETURNS: A new list of all data items stored in the hasharray ***************************************************************/ { LIST Scan, Result; NAT i; Result = list_Nil(); for (i = 0; i < hsh__SIZE; i++) { for (Scan = H[i]; !list_Empty(Scan); Scan = list_Cdr(Scan)) Result = list_Nconc(Result, list_Copy(list_PairSecond(list_Car(Scan)))); } return Result; }
LIST hsh_NGetAllKeyValueListPairs(HASH H) /************************************************************** INPUT: A hasharray RETURNS: A new list of all key valuelist pairs, where the key valuelist pairs are not copied ***************************************************************/ { LIST Result; NAT i; Result = list_Nil(); for (i = 0; i < hsh__SIZE; i++) { if (!list_Empty(H[i])) Result = list_Nconc(list_Copy(H[i]), Result); } return Result; }
static LIST inf_NonUnitURResolution(CLAUSE Clause, int SpecialLitIndex, LIST FoundMap, SUBST Subst, SYMBOL GlobalMaxVar, SHARED_INDEX Index, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A non-unit clause, a literal index from <Clause>. <FoundMap> is a list of pairs (l1,l2) of unifiable literals, where l1 is from <Clause> and l2 is from a unit clause. At this point the list has at most one element. <Subst> is the substitution for <Clause>. <GlobalMaxVar> is the maximal variable encountered so far. <Index> is used to search unifiable literals. The flag store and the precedence are needed to create the new clauses. RETURNS: The list of UR resolution resolvents. EFFECT: If inf_URResolution was called with a unit clause, <SpecialLitIndex> is the index of a literal from a non-unit clause, that is unifiable with the unit clause's literal, otherwise it is set to -1. ***************************************************************/ { LIST Result, RestLits; int i, last; Result = list_Nil(); RestLits = clause_GetLiteralListExcept(Clause, SpecialLitIndex); last = clause_LastLitIndex(Clause); for (i = clause_FirstLitIndex(); i <= last; i++) { /* <i> is the index of the literal that remains in the resolvent */ if (i != SpecialLitIndex) { RestLits = list_PointerDeleteOneElement(RestLits, clause_GetLiteral(Clause,i)); Result = list_Nconc(inf_SearchURResolvents(Clause, i, FoundMap, RestLits, Subst, GlobalMaxVar, Index, Flags, Precedence), Result); RestLits = list_Cons(clause_GetLiteral(Clause, i), RestLits); } } list_Delete(RestLits); return Result; }
static LIST split_DeleteClausesDependingOnLevelFromSet(PROOFSEARCH PS, LIST ClauseList, int SplitLevel) /************************************************************** INPUT: A PROOFSEARCH object, a list of shared clauses and a split level. RETURNS: A list of clauses that have to be recovered possibly. EFFECT: Clauses from the clause list depending on <SplitLevel> are moved to the doc proof index of <PS>. All formerly redundant clauses that were reduced by a clause of the same split level as a clause from the list depending on <SplitLevel> are returned. ***************************************************************/ { LIST scan, delList, recover; CLAUSE clause; SPLIT reinsert; delList = recover = list_Nil(); for (scan = ClauseList; !list_Empty(scan); scan = list_Cdr(scan)){ clause = list_Car(scan); if (clause_DependsOnSplitLevel(clause, SplitLevel)) { reinsert = prfs_GetSplitOfLevel(clause_SplitLevel(clause), PS); recover = list_Nconc(prfs_SplitDeletedClauses(reinsert), recover); prfs_SplitSetDeletedClauses(reinsert, list_Nil()); delList = list_Cons(clause, delList); } } /* WARNING: The following move operations change the worked off */ /* and usable sets of the proof search object destructively. */ /* So it's impossible to move those function calls into the */ /* loop above. */ for ( ; !list_Empty(delList); delList = list_Pop(delList)) { clause = list_Car(delList); if (clause_GetFlag(clause, WORKEDOFF)) prfs_MoveWorkedOffDocProof(PS, clause); else prfs_MoveUsableDocProof(PS, clause); } return recover; }
LIST dp_PrintProof(PROOFSEARCH Search, LIST Clauses, const char *FilePrefix) /********************************************************* INPUT: A proofsearch object, a list of empty clauses and the prefix of the output file name. RETURNS: The list of clauses required for the proof. MEMORY: The returned list must be freed. EFFECT: The proof is printed both to standard output and to the file <FilePrefix>.prf. **********************************************************/ { LIST ProofClauses,Scan,EmptyClauses,AllClauses, ReducedProof; LIST Missing, Incomplete, SplitClauses; FLAGSTORE Flags; Flags = prfs_Store(Search); Missing = pcheck_ConvertParentsInSPASSProof(Search, Clauses); if (!list_Empty(Missing)) { puts("\nNOTE: clauses with following numbers have not been found:"); for (; !list_Empty(Missing); Missing = list_Pop(Missing)) printf("%d ", (int)list_Car(Missing)); putchar('\n'); } EmptyClauses = list_Copy(Clauses); ProofClauses = list_Nil(); AllClauses = list_Nconc(list_Copy(prfs_DocProofClauses(Search)), list_Nconc(list_Copy(prfs_UsableClauses(Search)), list_Copy(prfs_WorkedOffClauses(Search)))); /* * collect proof clauses by noodling upward in the * proof tree, starting from <EmptyClauses>. * Before, add all splitting clauses to avoid gaps in split tree */ SplitClauses = list_Nil(); for (Scan = AllClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) if (clause_IsFromSplitting(list_Car(Scan))) SplitClauses = list_Cons(list_Car(Scan), SplitClauses); /* mark all needed clauses */ pcheck_ClauseListRemoveFlag(EmptyClauses, MARKED); pcheck_ClauseListRemoveFlag(AllClauses, MARKED); pcheck_MarkRecursive(EmptyClauses); pcheck_MarkRecursive(SplitClauses); /* collect all marked clauses */ ProofClauses = list_Nil(); for (Scan = AllClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) { if (clause_GetFlag(list_Car(Scan), MARKED)) ProofClauses = list_Cons(list_Car(Scan), ProofClauses); } /* build reduced proof */ ProofClauses = list_Nconc(ProofClauses, list_Copy(EmptyClauses)); ProofClauses = pcheck_ClauseNumberMergeSort(ProofClauses); ReducedProof = pcheck_ReduceSPASSProof(ProofClauses); dp_SetProofDepth(pcheck_SeqProofDepth(ReducedProof)); pcheck_ParentPointersToParentNumbers(AllClauses); pcheck_ParentPointersToParentNumbers(Clauses); /* check reduced proof for clauses whose parents have been marked as incomplete (HIDDEN flag) by ConvertParentsInSPASSProof */ Incomplete = list_Nil(); for (Scan = ReducedProof; !list_Empty(Scan); Scan = list_Cdr(Scan)) { if (clause_GetFlag(list_Car(Scan), HIDDEN)) Incomplete = list_Cons(list_Car(Scan), Incomplete); } if (!list_Empty(Incomplete)) { puts("NOTE: Following clauses in reduced proof have incomplete parent sets:"); for (Scan = Incomplete; !list_Empty(Scan); Scan = list_Cdr(Scan)) printf("%d ", clause_Number(list_Car(Scan))); putchar('\n'); } printf("\n\nHere is a proof with depth %d, length %d :\n", dp_ProofDepth(), list_Length(ReducedProof)); clause_ListPrint(ReducedProof); if (flag_GetFlagValue(Flags, flag_FPDFGPROOF)) dp_FPrintDFGProof(ReducedProof, FilePrefix, Flags, prfs_Precedence(Search)); fflush(stdout); list_Delete(EmptyClauses); list_Delete(AllClauses); list_Delete(ProofClauses); list_Delete(SplitClauses); list_Delete(Incomplete); return ReducedProof; }
static CLAUSE red_SearchTerminator(NAT n, LIST RestLits, LIST FoundMap, SUBST Subst, SYMBOL GlobalMaxVar, LIST IndexList, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A natural number, a list of literals, a list of pairs, a substitution, the maximum variable occurring in all involved clauses, a list of SHARED_INDEXes, a flag store and a precedence. RETURNS: An empty clause, if a terminator situation was found, NULL otherwise. EFFECT: This recursive function implements the search for a terminator situation with at most <n> non-unit clauses. <RestLits> is the lists of literals actually missing a complementary partner literal. <FoundMap> is a list of pairs (l1,l2), where l1 and l2 are complementary, unifiable literals. <Subst> is the common substitution of all those pairs. <GlobalMaxVar> is the maximum variable from all involved clauses. To enable the search all involved clauses are made variable-disjoint. At the moment the function stops, if ANY terminator situation occurred. This might not be desirable if splitting is enabled, since there might be other terminator situations resulting in an empty clause of lower split level. The flag store and the precedence are needed to create the new clause. ***************************************************************/ { if (list_Empty(RestLits)) { /* We found a terminator situation, so stop the recursion */ return red_CreateTerminatorEmptyClause(FoundMap, Flags, Precedence); } else { CLAUSE Result, PClauseCopy; LITERAL Lit, PLit; SYMBOL NewMaxVar; SUBST NewSubst, RightSubst; TERM AtomCopy; LIST ClashList, ToDoList; BOOL Swapped; NAT Limit; int PLitInd; Swapped = FALSE; Result = clause_Null(); clause_MoveBestLiteralToFront(RestLits, Subst, GlobalMaxVar, red_TerminatorLitIsBetter); Lit = list_Car(RestLits); RestLits = list_Cdr(RestLits); AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit))); /* The following 'endless' loop runs twice for equality literals */ /* and only once for other literals. */ while (TRUE) { ClashList = red_GetTerminatorPartnerLits(AtomCopy, Lit, n==0, IndexList); for (; !list_Empty(ClashList) && Result==NULL; ClashList = list_Pop(ClashList)) { PLit = list_Car(ClashList); PLitInd = clause_LiteralGetIndex(PLit); PClauseCopy = clause_Copy(clause_LiteralOwningClause(PLit)); Limit = clause_Length(PClauseCopy) == 1 ? n : n-1; clause_RenameVarsBiggerThan(PClauseCopy, GlobalMaxVar); PLit = clause_GetLiteral(PClauseCopy, PLitInd); FoundMap = list_Cons(list_PairCreate(Lit, PLit), FoundMap); ToDoList = clause_GetLiteralListExcept(PClauseCopy, PLitInd); ToDoList = list_Nconc(ToDoList, list_Copy(RestLits)); NewMaxVar = clause_SearchMaxVar(PClauseCopy); if (symbol_GreaterVariable(GlobalMaxVar, NewMaxVar)) NewMaxVar = GlobalMaxVar; cont_Check(); if (!unify_UnifyNoOC(cont_LeftContext(), AtomCopy, cont_RightContext(), clause_LiteralAtom(PLit))) { misc_StartErrorReport(); misc_ErrorReport("\n In red_SearchTerminator: Unification failed."); misc_FinishErrorReport(); } subst_ExtractUnifier(cont_LeftContext(), &NewSubst, cont_RightContext(), &RightSubst); cont_Reset(); /* The domains of both substitutions are disjoint */ /* so we do just a simple union operation. */ NewSubst = subst_NUnion(NewSubst, RightSubst); RightSubst = NewSubst; NewSubst = subst_Compose(NewSubst, subst_Copy(Subst)); subst_Delete(RightSubst); Result = red_SearchTerminator(Limit, ToDoList, FoundMap, NewSubst, NewMaxVar, IndexList, Flags, Precedence); clause_Delete(PClauseCopy); subst_Delete(NewSubst); list_Delete(ToDoList); list_PairFree(list_Car(FoundMap)); FoundMap = list_Pop(FoundMap); } /* loop control */ if (!fol_IsEquality(AtomCopy) || Swapped || Result!=NULL) break; else { list_Delete(ClashList); term_EqualitySwap(AtomCopy); Swapped = TRUE; } } /* cleanup */ term_Delete(AtomCopy); /* <ClashList> may be non-empty since the loop stops */ /* if a terminator was found. */ list_Delete(ClashList); return Result; } }
int main(int argc, const char* argv[]) { LIST Clauses,Axioms,Conjectures,Sorts,Scan, UserPrecedence,UserSelection,ClAxRelation; FILE *Input; CLAUSE Clause; const char *Filename; FLAGSTORE Flags; PRECEDENCE Precedence; BOOL HasPlainClauses; DFGDESCRIPTION Description; memory_Init(memory__UNLIMITED); atexit(memory_FreeAllMem); symbol_Init(TRUE); stack_Init(); term_Init(); flag_Init(flag_SPASS); cmdlne_Init(); Flags = flag_CreateStore(); flag_InitStoreByDefaults(Flags); Precedence = symbol_CreatePrecedence(); Description = desc_Create(); fol_Init(TRUE, Precedence); eml_Init(Precedence); clause_Init(); if (argc < 2 || !cmdlne_Read(argc, argv)) { fputs("\n\t dfg2ascii Version ", stdout); fputs(DFG2ASCII__VERSION, stdout); puts("\n\t Usage: dfg2ascii <input-file>\n"); return EXIT_FAILURE; } if (!cmdlne_SetFlags(Flags)) return EXIT_FAILURE; Axioms = list_Nil(); Conjectures = list_Nil(); Sorts = list_Nil(); UserPrecedence = list_Nil(); UserSelection = list_Nil(); ClAxRelation = list_Nil(); Filename = cmdlne_GetInputFile(); Input = misc_OpenFile(Filename,"r"); Clauses = dfg_DFGParser(Input, Flags, Precedence, Description, &Axioms, &Conjectures, &Sorts, &UserPrecedence, &UserSelection, &ClAxRelation, &HasPlainClauses); misc_CloseFile(Input,Filename); Axioms = list_Nconc(Axioms, Sorts); if (!list_Empty(Axioms) || !list_Empty(Conjectures)) { puts("\n\n\t\t Axioms:\n"); if (list_Empty(Axioms)) puts("None.\n"); else for (Scan=Axioms; !list_Empty(Scan);Scan=list_Cdr(Scan)) { if (list_PairFirst(list_Car(Scan)) != NULL) printf("%s:\n",(char *)list_PairFirst(list_Car(Scan))); fol_PrettyPrintDFG(list_PairSecond(list_Car(Scan))); puts("\n"); } puts("\n\n\t\t Conjectures:\n"); if (list_Empty(Conjectures)) puts("None.\n"); else for (Scan=Conjectures; !list_Empty(Scan);Scan=list_Cdr(Scan)) { if (list_PairFirst(list_Car(Scan)) != NULL) printf("%s:\n",(char *)list_PairFirst(list_Car(Scan))); fol_PrettyPrintDFG(list_PairSecond(list_Car(Scan))); puts("\n"); } } else { BOOL SetExist; LIST ClauseScan; /* Before we sort the clauses, we need to make sure that they have been assigned a weight. */ for (ClauseScan = Clauses; !list_Empty(ClauseScan); ClauseScan = list_Cdr(ClauseScan)) { clause_UpdateWeight((CLAUSE) list_Car(ClauseScan), Flags); } Clauses = clause_ListSortWeighed(Clauses); clause_SetCounter(1); for (Scan = Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) { Clause = (CLAUSE)list_Car(Scan); clause_SetSortConstraint(Clause, FALSE, Flags, Precedence); clause_NewNumber(Clause); clause_OrientAndReInit(Clause, Flags, Precedence); } puts("\n\n\t\t Axiom Clauses:\n"); SetExist = FALSE; for (Scan = Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) { Clause = (CLAUSE)list_Car(Scan); if (!clause_GetFlag(Clause,CONCLAUSE)) { SetExist = TRUE; clause_Print(Clause); putchar('\n'); } } if (SetExist) SetExist = FALSE; else puts("None.\n"); puts("\n\n\t\t Conjecture Clauses:\n"); for (Scan = Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) { Clause = (CLAUSE)list_Car(Scan); if (clause_GetFlag(Clause,CONCLAUSE)) { SetExist = TRUE; clause_Print(Clause); putchar('\n'); } } if (SetExist) SetExist = FALSE; else puts("None.\n"); } clause_DeleteClauseList(Clauses); dfg_StripLabelsFromList(Axioms); dfg_StripLabelsFromList(Conjectures); term_DeleteTermList(Axioms); term_DeleteTermList(Conjectures); eml_Free(); flag_DeleteStore(Flags); symbol_DeletePrecedence(Precedence); list_Delete(UserPrecedence); list_Delete(UserSelection); dfg_DeleteClAxRelation(ClAxRelation); desc_Delete(Description); /*symbol_Dump();*/ cmdlne_Free(); fol_Free(); symbol_FreeAllSymbols(); #ifdef CHECK memory_Print(); #endif return 0; }
LIST inf_URResolution(CLAUSE Clause, SHARED_INDEX Index, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause, a shared index, a flag store and a precedence. RETURNS: The list of UR resolution resolvents. EFFECT: The flag store and the precedence are needed to create the resolvents. ***************************************************************/ { LIST Result; if (clause_Length(Clause) != 1) { /* Clause isn't unit clause */ Result = inf_NonUnitURResolution(Clause, -1, list_Nil(), subst_Nil(), clause_MaxVar(Clause), Index, Flags, Precedence); } else { /* Clause is unit clause, so search partner literals in non-unit clauses */ LITERAL Lit, PLit; TERM Atom; LIST Partners, FoundMap; SYMBOL MaxVar, PMaxVar; SUBST LeftSubst, RightSubst; CLAUSE PClause; int PLitInd; BOOL Swapped; Result = list_Nil(); Lit = clause_GetLiteral(Clause, clause_FirstLitIndex()); Atom = term_Copy(clause_LiteralAtom(Lit)); Swapped = FALSE; /* The following 'endless' loop runs twice for equality literals */ /* and only once for other literals. */ while (TRUE) { /* Get complementary literals from non-unit clauses */ Partners = inf_GetURPartnerLits(Atom, Lit, FALSE, Index); for ( ; !list_Empty(Partners); Partners = list_Pop(Partners)) { PLit = list_Car(Partners); PLitInd = clause_LiteralGetIndex(PLit); PClause = clause_LiteralOwningClause(PLit); /* non-unit clause */ PMaxVar = clause_MaxVar(PClause); term_StartMaxRenaming(PMaxVar); term_Rename(Atom); /* Rename atom from unit clause */ MaxVar = term_MaxVar(Atom); if (symbol_GreaterVariable(PMaxVar, MaxVar)) MaxVar = PMaxVar; /* Get the substitution */ cont_Check(); unify_UnifyNoOC(cont_LeftContext(), clause_LiteralAtom(PLit), cont_RightContext(), Atom); subst_ExtractUnifier(cont_LeftContext(), &LeftSubst, cont_RightContext(), &RightSubst); cont_Reset(); /* We don't need the substitution for the unit clause */ subst_Delete(RightSubst); FoundMap = list_List(list_PairCreate(PLit, Lit)); Result = list_Nconc(inf_NonUnitURResolution(PClause, PLitInd, FoundMap, LeftSubst, MaxVar, Index, Flags, Precedence), Result); list_DeletePairList(FoundMap); subst_Delete(LeftSubst); } /* loop control */ if (!fol_IsEquality(Atom) || Swapped) break; else { term_EqualitySwap(Atom); Swapped = TRUE; } } /* end of endless loop */ term_Delete(Atom); } return Result; }
static LIST split_RemoveUnnecessarySplits(PROOFSEARCH PS, CLAUSE EmptyClause) /************************************************************** INPUT: An empty clause and a proof search object EFFECT: Removes all splits up to the last backtrack level that were not necessary to derive the empty clause. RETURNS: A list of recovered clauses. ***************************************************************/ { LIST Scan; LIST Recover, New; LIST Deleted; LIST ScanStack; int SplitLevel; int LastBacktrackLevel; SPLIT Split,ScanSplit; Scan = prfs_SplitStack(PS); SplitLevel = prfs_ValidLevel(PS); LastBacktrackLevel = prfs_LastBacktrackLevel(PS); Recover = list_Nil(); while (SplitLevel > LastBacktrackLevel) { if (prfs_SplitIsUnused(list_Car(Scan)) && !clause_DependsOnSplitLevel(EmptyClause, SplitLevel)) { New = list_Nil(); Split = list_Car(Scan); /*printf("\n\t Removed: %d",prfs_SplitSplitLevel(Split));*/ clause_DeleteClauseList(prfs_SplitBlockedClauses(Split)); prfs_SplitSetBlockedClauses(Split, list_Nil()); Recover = list_Nconc(prfs_SplitDeletedClauses(Split), Recover); prfs_SplitSetDeletedClauses(Split, list_Nil()); if (prfs_SplitFatherClause(Split) != (CLAUSE)NULL) { Recover = list_Cons(prfs_SplitFatherClause(Split),Recover); prfs_SplitSetFatherClause(Split,NULL); } Recover = split_DeleteClausesDependingOnLevelFromList(PS, Recover, SplitLevel, &New); ScanStack = prfs_SplitStack(PS); while (!list_StackEmpty(ScanStack) && prfs_SplitSplitLevel((ScanSplit = (SPLIT)list_Car(ScanStack))) > LastBacktrackLevel) { Deleted = prfs_SplitDeletedClauses(ScanSplit); prfs_SplitSetDeletedClauses(ScanSplit, list_Nil()); /* IMPORTANT!, see next line */ Deleted = split_DeleteClausesDependingOnLevelFromList(PS, Deleted, SplitLevel, &New); prfs_SplitSetDeletedClauses(ScanSplit, Deleted); ScanStack = list_Cdr(ScanStack); } while (!list_Empty(New)) { Deleted = list_Nil(); Recover = list_Nconc(split_DeleteClausesDependingOnLevelFromList(PS, New, SplitLevel, &Deleted), Recover); New = Deleted; } Recover = list_Nconc(Recover, split_DeleteClausesDependingOnLevelFromSet(PS, prfs_UsableClauses(PS), SplitLevel)); Recover = list_Nconc(Recover, split_DeleteClausesDependingOnLevelFromSet(PS, prfs_WorkedOffClauses(PS), SplitLevel)); prfs_SplitSetUsed(Split); } SplitLevel--; Scan = list_Cdr(Scan); } return Recover; }
LIST split_Backtrack(PROOFSEARCH PS, CLAUSE EmptyClause, CLAUSE* SplitClause) /************************************************************** INPUT: A proofsearch object, an empty clause and a pointer to a clause used as return value. RETURNS: A list of clauses deleted in the backtracked split levels. <*SplitClause> is set to the split clause for the right branch of the splitting step, or NULL, if the tableau is finished. EFFECT: Backtracks the top of the split stack wrt the empty clause's level ***************************************************************/ { SPLIT ActBacktrackSplit; LIST RecoverList, Scan; int Backtracklevel; ActBacktrackSplit = (SPLIT)NULL; RecoverList = split_RemoveUnnecessarySplits(PS, EmptyClause); Backtracklevel = clause_SplitLevel(EmptyClause); *SplitClause = NULL; /* Backtrack all split levels bigger than the level of the empty clause */ while (!prfs_SplitStackEmpty(PS) && (prfs_ValidLevel(PS) > Backtracklevel)) { ActBacktrackSplit = prfs_SplitStackTop(PS); prfs_SplitStackPop(PS); if (prfs_SplitFatherClause(ActBacktrackSplit) != (CLAUSE)NULL) { RecoverList = list_Cons(prfs_SplitFatherClause(ActBacktrackSplit), RecoverList); prfs_SplitSetFatherClause(ActBacktrackSplit, NULL); } RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit), RecoverList); clause_DeleteClauseList(prfs_SplitBlockedClauses(ActBacktrackSplit)); prfs_SplitFree(ActBacktrackSplit); prfs_DecValidLevel(PS); } /* Backtrack further for all right branches on top of the stack */ while (!prfs_SplitStackEmpty(PS) && list_Empty(prfs_SplitBlockedClauses(prfs_SplitStackTop(PS)))) { ActBacktrackSplit = prfs_SplitStackTop(PS); prfs_SplitStackPop(PS); if (prfs_SplitFatherClause(ActBacktrackSplit) != (CLAUSE)NULL) RecoverList = list_Cons(prfs_SplitFatherClause(ActBacktrackSplit), RecoverList); RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit), RecoverList); prfs_SplitFree(ActBacktrackSplit); prfs_DecValidLevel(PS); } if (!prfs_SplitStackEmpty(PS)) { /* Enter the right branch of the splitting step */ int SplitMinus1; LIST RightClauses; SplitMinus1 = prfs_ValidLevel(PS) - 1; ActBacktrackSplit = prfs_SplitStackTop(PS); RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit), RecoverList); prfs_SplitSetDeletedClauses(ActBacktrackSplit, list_Nil()); RecoverList = split_DeleteInvalidClausesFromList(PS, SplitMinus1, RecoverList); RightClauses = prfs_SplitBlockedClauses(ActBacktrackSplit); prfs_SplitSetBlockedClauses(ActBacktrackSplit, list_Nil()); for (Scan = RightClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) { if (clause_Number(list_Car(Scan)) == 0) { /* Found the right clause, the negation clauses have number -1. */ #ifdef CHECK if (*SplitClause != NULL) { misc_StartErrorReport(); misc_ErrorReport("\n In split_Backtrack:"); misc_ErrorReport(" Found two blocked clauses "); misc_ErrorReport("\n with clause number 0 (this marks the clause "); misc_ErrorReport("\n for the right branch of the tableau)."); misc_FinishErrorReport(); } #endif *SplitClause = list_Car(Scan); } clause_NewNumber((CLAUSE) list_Car(Scan)); clause_AddParentClause((CLAUSE) list_Car(Scan), clause_Number(EmptyClause)); clause_AddParentLiteral((CLAUSE) list_Car(Scan), 0); /* dummy literal */ } #ifdef CHECK if (*SplitClause == NULL) { misc_StartErrorReport(); misc_ErrorReport("\n In split_Backtrack: DidnĀ“t find a blocked clause"); misc_ErrorReport("\n with clause number 0. (this marks the clause "); misc_ErrorReport("\n for the right branch of the tableau)."); misc_FinishErrorReport(); } #endif RecoverList = list_Nconc(RightClauses, RecoverList); /* Then, delete clauses from current level (Hack) */ prfs_DecValidLevel(PS); prfs_MoveInvalidClausesDocProof(PS); split_DeleteInvalidClausesFromStack(PS); prfs_IncValidLevel(PS); } else { /* Don't delete clauses from current level (split is top level) */ prfs_MoveInvalidClausesDocProof(PS); for (Scan = RecoverList; !list_Empty(Scan); Scan = list_Cdr(Scan)) prfs_InsertDocProofClause(PS, list_Car(Scan)); list_Delete(RecoverList); RecoverList = list_Nil(); } prfs_SetLastBacktrackLevel(PS, prfs_ValidLevel(PS)); return RecoverList; }
static LIST inf_SearchURResolvents(CLAUSE Clause, int i, LIST FoundMap, LIST RestLits, SUBST Subst, SYMBOL GlobalMaxVar, SHARED_INDEX Index, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A non-unit clause, a literal index from <Clause>. <FoundMap> is a list of pairs (l1,l2) of unifiable literals, where l1 is from <Clause> and l2 is from a unit clause. <RestLits> is a list of literals from <Clause> where we haven't found unifiable literals from unit clauses so far. <Subst> is the overall substitution for <Clause> (not for the unit-clauses!). <GlobalMaxVar> is the maximal variable encountered so far. <Index> is used to search unifiable literals. The flag store and the precedence are needed to create the new clauses. RETURNS: A list of UR resolution resolvents. ***************************************************************/ { if (list_Empty(RestLits)) { /* Stop the recursion */ return list_List(inf_CreateURUnitResolvent(Clause, i, Subst, FoundMap, Flags, Precedence)); } else { LITERAL Lit, PLit; SYMBOL NewMaxVar; SUBST NewSubst, RightSubst; TERM AtomCopy, PAtom; LIST Result, Partners; BOOL Swapped; Result = list_Nil(); Swapped = FALSE; /* Choose the unmatched literal with the most symbols */ RestLits = clause_MoveBestLiteralToFront(list_Copy(RestLits), Subst, GlobalMaxVar, clause_HyperLiteralIsBetter); Lit = list_Car(RestLits); RestLits = list_Pop(RestLits); AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit))); /* The following 'endless' loop runs twice for equality literals */ /* and only once for other literals. */ while (TRUE) { Partners = inf_GetURPartnerLits(AtomCopy, Lit, TRUE, Index); for ( ; !list_Empty(Partners); Partners = list_Pop(Partners)) { PLit = list_Car(Partners); /* Rename the atom */ PAtom = term_Copy(clause_LiteralAtom(PLit)); term_StartMaxRenaming(GlobalMaxVar); term_Rename(PAtom); /* Get the new global maximal variable */ NewMaxVar = term_MaxVar(PAtom); if (symbol_GreaterVariable(GlobalMaxVar, NewMaxVar)) NewMaxVar = GlobalMaxVar; /* Get the substitution */ cont_Check(); if (!unify_UnifyNoOC(cont_LeftContext(), AtomCopy, cont_RightContext(), PAtom)) { misc_StartErrorReport(); misc_ErrorReport("\n In inf_SearchURResolvents: Unification failed."); misc_FinishErrorReport(); } subst_ExtractUnifier(cont_LeftContext(), &NewSubst, cont_RightContext(), &RightSubst); cont_Reset(); subst_Delete(RightSubst); /* Forget substitution for unit clause */ term_Delete(PAtom); /* Was just needed to get the substitution */ /* Build the composition of the substitutions */ RightSubst = NewSubst; NewSubst = subst_Compose(NewSubst, subst_Copy(Subst)); subst_Delete(RightSubst); FoundMap = list_Cons(list_PairCreate(Lit, PLit), FoundMap); Result = list_Nconc(inf_SearchURResolvents(Clause,i,FoundMap,RestLits, NewSubst,NewMaxVar,Index, Flags, Precedence), Result); list_PairFree(list_Car(FoundMap)); FoundMap = list_Pop(FoundMap); subst_Delete(NewSubst); } /* loop control */ if (!fol_IsEquality(AtomCopy) || Swapped) break; else { term_EqualitySwap(AtomCopy); Swapped = TRUE; } } /* cleanup */ term_Delete(AtomCopy); list_Delete(RestLits); return Result; } }