TERM cont_CopyAndApplyBindings(CONTEXT TermContext, TERM Term) { while (term_IsVariable(Term)) { SYMBOL TermTop; TermTop = term_TopSymbol(Term); if (cont_VarIsBound(TermContext, TermTop)) { CONTEXT HelpContext; HelpContext = cont_ContextBindingContext(TermContext, TermTop); Term = cont_ContextBindingTerm(TermContext, TermTop); TermContext = HelpContext; } else break; } if (term_IsComplex(Term)) { LIST Scan, ArgumentList; for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term)); !list_Empty(Scan); Scan = list_Cdr(Scan)) list_Rplaca(Scan, cont_CopyAndApplyBindings(TermContext, list_Car(Scan))); return term_Create(term_TopSymbol(Term), ArgumentList); } else return term_Create(term_TopSymbol(Term), list_Nil()); }
static LIST rpos_ContMultisetDifference(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2) /************************************************************** INPUT: Two contexts and two terms. RETURNS: The multiset difference between the arguments of both terms with respect to rpos_ContEqual. EFFECT: Variable bindings are considered. ***************************************************************/ { LIST result, scan1, scan2; /* Don't apply bindings at top level, since that happened */ /* in rpos_ContGreaterEqual */ /* We can't use list_NMultisetDifference, since that function */ /* expects an equality functions for terms that takes two terms */ /* as arguments. We also need the two contexts resolve variable */ /* bindings. */ result = list_Copy(term_ArgumentList(T1)); for (scan2 = term_ArgumentList(T2); !list_Empty(scan2); scan2 = list_Cdr(scan2)) { /* Delete at most one occurrence of the */ /* current element of list2 from list1 */ for (scan1 = result; !list_Empty(scan1); scan1 = list_Cdr(scan1)) { if (list_Car(scan1) != NULL && rpos_ContEqual(C1, list_Car(scan1), C2, list_Car(scan2))) { /* arg of list1 wasn't deleted earlier and terms are equal */ list_Rplaca(scan1, NULL); /* Mark argument of T1 as deleted */ break; } } } return list_PointerDeleteElement(result, NULL); /* Delete all marked terms */ }
static TERM cont_CopyAndApplyIndexVariableBindings(const CONTEXT Context, TERM Term) { SYMBOL TermTop; #ifdef CHECK if (symbol_IsIndexVariable(term_TopSymbol(Term)) && !cont_VarIsBound(Context, term_TopSymbol(Term))) { misc_StartErrorReport(); misc_ErrorReport("\n In cont_CopyAndApplyIndexVariableBindings:"); misc_ErrorReport(" Expected bound index variable."); misc_FinishErrorReport(); } #endif TermTop = term_TopSymbol(Term); while (symbol_IsIndexVariable(TermTop)) { if (cont_VarIsBound(Context, TermTop)) { Term = cont_ContextBindingTerm(Context, TermTop); TermTop = term_TopSymbol(Term); } } if (term_IsComplex(Term)) { LIST Scan, ArgumentList; for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term)); !list_Empty(Scan); Scan = list_Cdr(Scan)) list_Rplaca(Scan, cont_CopyAndApplyIndexVariableBindings(Context, list_Car(Scan))); return term_Create(TermTop, ArgumentList); } else return term_Create(TermTop, list_Nil()); }
static LIST rpos_MultisetDifference(TERM T1, TERM T2) /************************************************************** INPUT: Two terms. RETURNS: The multiset difference between the arguments of both terms with respect to rpos_Equal. ***************************************************************/ { LIST result; result = list_Copy(term_ArgumentList(T1)); result = list_NMultisetDifference(result, term_ArgumentList(T2), (BOOL (*)(POINTER,POINTER)) rpos_Equal); return result; }
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); }
TERM cont_CopyAndApplyBindingsCom(const CONTEXT Context, TERM Term) { while (term_IsVariable(Term) && cont_VarIsBound(Context, term_TopSymbol(Term))) Term = cont_ContextBindingTerm(Context, term_TopSymbol(Term)); if (term_IsComplex(Term)) { LIST Scan, ArgumentList; for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term)); !list_Empty(Scan); Scan = list_Cdr(Scan)) list_Rplaca(Scan, cont_CopyAndApplyBindingsCom(Context, list_Car(Scan))); return term_Create(term_TopSymbol(Term), ArgumentList); } else return term_Create(term_TopSymbol(Term), list_Nil()); }
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; }
TERM cont_SymbolApplyBindings(CONTEXT TermContext, SYMBOL Symbol) /************************************************************** INPUT: A call-by-ref context and a variable symbol. RETURNS: The recursively dereferenced term and the corresponding context, NULL if the symbol is not bound SUMMARY: Dereferences bindings of variables. CAUTION: In general, the context of the returned term is different to the input context. ***************************************************************/ { TERM Term; Term = (TERM)NULL; while (symbol_IsVariable(Symbol)) { if (cont_VarIsBound(TermContext, Symbol)) { CONTEXT HelpContext; HelpContext = cont_ContextBindingContext(TermContext, Symbol); Term = cont_ContextBindingTerm(TermContext, Symbol); TermContext = HelpContext; Symbol = term_TopSymbol(Term); } else break; } if (Term != (TERM)NULL && term_IsComplex(Term)) { LIST Scan, ArgumentList; for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term)); !list_Empty(Scan); Scan = list_Cdr(Scan)) list_Rplaca(Scan, cont_CopyAndApplyBindings(TermContext, list_Car(Scan))); return term_Create(term_TopSymbol(Term), ArgumentList); } return Term; }
LIST list_NListTimes(LIST List1, LIST List2) /************************************************************** INPUT: Two lists of lists. RETURNS: The list of combinations of element lists. CAUTION: Destroys List1 and List2. ***************************************************************/ { LIST Result, Scan1, Scan2; Result = list_Nil(); if (!list_Empty(List2)) { for (Scan1=List1; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) for (Scan2=List2; !list_Empty(Scan2); Scan2=list_Cdr(Scan2)) Result = list_Cons(list_Append(((LIST)list_Car(Scan1)), list_Copy((LIST)list_Car(Scan2))), Result); } list_DeleteWithElement(List1, (void (*)(POINTER))list_Delete); list_DeleteWithElement(List2, (void (*)(POINTER))list_Delete); return Result; }
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; } }
stat_t *copyStats(stat_t *stat) { node_t *node; int c; stat_t *newStat = (stat_t *) malloc(sizeof(stat_t)); newStat->type = stat->type; newStat->sex = stat->sex; newStat->appearance = stat->appearance; strcpy(newStat->name,stat->name); strcpy(newStat->obituary,stat->obituary); newStat->HP = stat->HP; newStat->MAXHP = stat->MAXHP; newStat->OLDHP = stat->OLDHP; newStat->MP = stat->MP; newStat->MAXMP = stat->MAXMP; newStat->STR = stat->STR; newStat->DEX = stat->DEX; newStat->CON = stat->CON; newStat->INT = stat->PER; newStat->CHR = stat->CHR; newStat->EXP = stat->EXP; newStat->LVL = stat->LVL; newStat->GOLD = stat->GOLD; newStat->HUNGER = stat->HUNGER; for( c=0; c<NUMPROFICIENCIES; c++ ) { newStat->PROFICIENCIES[c] = stat->PROFICIENCIES[c]; } for( c=0; c<NUMEFFECTS; c++ ) { newStat->EFFECTS[c] = stat->EFFECTS[c]; newStat->EFFECTS_TIMERS[c] = stat->EFFECTS_TIMERS[c]; } newStat->defending = stat->defending; newStat->leader_uid = stat->leader_uid; newStat->FOLLOWERS.first = NULL; newStat->FOLLOWERS.last = NULL; list_Copy(&newStat->FOLLOWERS,&stat->FOLLOWERS); newStat->stache_x1 = stat->stache_x1; newStat->stache_x2 = stat->stache_x2; newStat->stache_y1 = stat->stache_y1; newStat->stache_y2 = stat->stache_y2; newStat->inventory.first = NULL; newStat->inventory.last = NULL; list_Copy(&newStat->inventory,&stat->inventory); for( node=newStat->inventory.first; node!=NULL; node=node->next ) { Item *item = (Item *)node->element; item->node = node; } if( stat->helmet ) { if( stat->helmet->node ) { node_t *node = list_Node(&newStat->inventory,list_Index(stat->helmet->node)); newStat->helmet = (Item *) node->element; } else { newStat->helmet = (Item *) malloc(sizeof(Item)); memcpy(newStat->helmet,stat->helmet,sizeof(Item)); } } else { newStat->helmet = NULL; } if( stat->breastplate ) { if( stat->breastplate->node ) { node_t *node = list_Node(&newStat->inventory,list_Index(stat->breastplate->node)); newStat->breastplate = (Item *) node->element; } else { newStat->breastplate = (Item *) malloc(sizeof(Item)); memcpy(newStat->breastplate,stat->breastplate,sizeof(Item)); } } else { newStat->breastplate = NULL; } if( stat->gloves ) { if( stat->gloves->node ) { node_t *node = list_Node(&newStat->inventory,list_Index(stat->gloves->node)); newStat->gloves = (Item *) node->element; } else { newStat->gloves = (Item *) malloc(sizeof(Item)); memcpy(newStat->gloves,stat->gloves,sizeof(Item)); } } else { newStat->gloves = NULL; } if( stat->shoes ) { if( stat->shoes->node ) { node_t *node = list_Node(&newStat->inventory,list_Index(stat->shoes->node)); newStat->shoes = (Item *) node->element; } else { newStat->shoes = (Item *) malloc(sizeof(Item)); memcpy(newStat->shoes,stat->shoes,sizeof(Item)); } } else { newStat->shoes = NULL; } if( stat->shield ) { if( stat->shield->node ) { node_t *node = list_Node(&newStat->inventory,list_Index(stat->shield->node)); newStat->shield = (Item *) node->element; } else { newStat->shield = (Item *) malloc(sizeof(Item)); memcpy(newStat->shield,stat->shield,sizeof(Item)); } } else { newStat->shield = NULL; } if( stat->weapon ) { if( stat->weapon->node ) { node_t *node = list_Node(&newStat->inventory,list_Index(stat->weapon->node)); newStat->weapon = (Item *) node->element; } else { newStat->weapon = (Item *) malloc(sizeof(Item)); memcpy(newStat->weapon,stat->weapon,sizeof(Item)); } } else { newStat->weapon = NULL; } if( stat->cloak ) { if( stat->cloak->node ) { node_t *node = list_Node(&newStat->inventory,list_Index(stat->cloak->node)); newStat->cloak = (Item *) node->element; } else { newStat->cloak = (Item *) malloc(sizeof(Item)); memcpy(newStat->cloak,stat->cloak,sizeof(Item)); } } else { newStat->cloak = NULL; } if( stat->amulet ) { if( stat->amulet->node ) { node_t *node = list_Node(&newStat->inventory,list_Index(stat->amulet->node)); newStat->amulet = (Item *) node->element; } else { newStat->amulet = (Item *) malloc(sizeof(Item)); memcpy(newStat->amulet,stat->amulet,sizeof(Item)); } } else { newStat->amulet = NULL; } if( stat->ring ) { if( stat->ring->node ) { node_t *node = list_Node(&newStat->inventory,list_Index(stat->ring->node)); newStat->ring = (Item *) node->element; } else { newStat->ring = (Item *) malloc(sizeof(Item)); memcpy(newStat->ring,stat->ring,sizeof(Item)); } } else { newStat->ring = NULL; } if( stat->mask ) { if( stat->mask->node ) { node_t *node = list_Node(&newStat->inventory,list_Index(stat->mask->node)); newStat->mask = (Item *) node->element; } else { newStat->mask = (Item *) malloc(sizeof(Item)); memcpy(newStat->mask,stat->mask,sizeof(Item)); } } else { newStat->mask = NULL; } newStat->monster_sound = NULL; newStat->monster_idlevar = stat->monster_idlevar; newStat->magic_effects.first = NULL; newStat->magic_effects.last = NULL; return newStat; }
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; } }