static CLAUSE inf_CreateURUnitResolvent(CLAUSE Clause, int i, SUBST Subst, LIST FoundMap, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A non-unit clause, a literal index from the clause, a substitution, a list of pairs (l1, l2) of literals, where l1 is from the non-unit clause and l2 is from a unit clause, a flag store and a precedence. RETURNS: The resolvent of this UR resolution inference. The clause consists of the literal at index <i> in <Clause> after application of <Subst>. EFFECT: The flag store and the precedence are needed to create the new clause. ***************************************************************/ { CLAUSE Result, PClause; LITERAL Lit; TERM Atom; LIST Parents; NAT depth; /* Create atom for resolvent */ Atom = subst_Apply(Subst, term_Copy(clause_GetLiteralAtom(Clause, i))); /* Create clause */ Parents = list_List(Atom); if (i <= clause_LastConstraintLitIndex(Clause)) Result = clause_Create(Parents, list_Nil(), list_Nil(), Flags, Precedence); else if (i <= clause_LastAntecedentLitIndex(Clause)) Result = clause_Create(list_Nil(), Parents, list_Nil(), Flags, Precedence); else Result = clause_Create(list_Nil(), list_Nil(), Parents, Flags, Precedence); list_Delete(Parents); /* Get parent clauses and literals, calculate depth of resolvent */ Parents = list_List(Clause); depth = clause_Depth(Clause); for ( ; !list_Empty(FoundMap); FoundMap = list_Cdr(FoundMap)) { Lit = list_PairSecond(list_Car(FoundMap)); /* Literal from unit */ PClause = clause_LiteralOwningClause(Lit); Parents = list_Cons(PClause, Parents); depth = misc_Max(depth, clause_Depth(PClause)); clause_AddParentClause(Result, clause_Number(PClause)); clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit)); Lit = list_PairFirst(list_Car(FoundMap)); /* Is from <Clause> */ clause_AddParentClause(Result, clause_Number(Clause)); clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit)); } clause_SetFromURResolution(Result); clause_SetDepth(Result, depth+1); clause_SetSplitDataFromList(Result, Parents); list_Delete(Parents); return Result; }
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; } }
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; } }