BOOL res_BackSubWithLength(CLAUSE clause, st_INDEX stindex) /********************************************************** INPUT: A clauses and an index. RETURNS: TRUE if a clause of the index subsumes the clause clause and length(clause) >= length(clause of index). CAUTION: None. ***********************************************************/ { int n,i; LIST scan,generals; TERM term; LITERAL litres; n = clause_Length(clause); for (i = 0; i < n; i++) { term = clause_GetLiteralTerm(clause,i); generals = st_GetGen(cont_LeftContext(), stindex, term); for (scan = generals; !list_Empty(scan); scan = list_Cdr(scan)) { litres = (LITERAL) list_Car(scan); if (litres == clause_GetLiteral(clause_LiteralOwningClause(litres),0) && clause_Length(clause) >= clause_Length(clause_LiteralOwningClause(litres)) && clause_Weight(clause) >= clause_Weight(clause_LiteralOwningClause(litres)) && subs_Idc(clause_LiteralOwningClause(litres),clause)) { list_Delete(generals); return TRUE; } } list_Delete(generals); } return FALSE; }
LIST cond_CondFast(CLAUSE c) /********************************************************** INPUT: A clause c. RETURNS: A list with indexes with respect to c that can be deleted due to condensing. CAUTION: None. ***********************************************************/ { int vec, i, j, k; LIST indexlist; indexlist = list_Nil(); vec = vec_ActMax(); for (i = 0; i < clause_Length(c); i++) { vec_Push((POINTER) i); } for (k = clause_Length(c) - 1; k >= 0; k--) { for (i = vec; i < vec_ActMax(); i++) { if ((int)vec_GetNth(i) != k) { cont_StartBinding(); if (unify_Match(cont_LeftContext(), clause_GetLiteralTerm(c,k), clause_GetLiteralTerm(c,(int)vec_GetNth(i)))) { cont_BackTrack(); for (j = vec; j < vec_ActMax(); j++) { if (k == (int)vec_GetNth(j)) { vec_Swap((vec_ActMax() -1) ,j); j = vec_ActMax(); } } if (subs_IdcRes(c,vec,(vec_ActMax() -1))) { indexlist = list_Cons((POINTER)k,indexlist); vec_Pop(); } i = vec_ActMax()+1; } else cont_BackTrack(); } } } vec_SetMax(vec); return indexlist; }
CLAUSE red_Terminator(CLAUSE RedClause, NAT n, SHARED_INDEX WoIndex, SHARED_INDEX UsIndex, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A clause, two shared indexes, a number <n> restricting the number of non-unit clauses in a possible terminator situation, a flag store and a precedence. RETURNS: An empty clause if a terminator with at most <n> non-unit clauses is found, NULL otherwise. EFFECT: See also description of red_SearchTerminator. ***************************************************************/ { LIST Rest, IndexList; CLAUSE Result; if (clause_Length(RedClause) > 1) /* non-unit clause */ n--; /* Pass the indexes as a list to sub-functions */ IndexList = list_Cons(WoIndex, list_List(UsIndex)); Rest = clause_GetLiteralList(RedClause); Result = red_SearchTerminator(n, Rest, list_Nil(), subst_Nil(), clause_MaxVar(RedClause), IndexList, Flags, Precedence); /* cleanup */ list_Delete(IndexList); list_Delete(Rest); return Result; }
BOOL res_HasTautology(CLAUSE clause) /********************************************************** INPUT: A clauses. RETURNS: TRUE if the clause contains a complementary literal pair and FALSE otherwise. CAUTION: None. ***********************************************************/ { BOOL found; TERM literal1; int i, j, n; found = FALSE; n = clause_Length(clause); for (i = 0; i < n && !found; i++) { literal1 = fol_ComplementaryTerm(clause_GetLiteralTerm(clause,i)); for (j = 0; j < n && !found; j++) if (j != i && term_Equal(literal1, clause_GetLiteralTerm(clause,j))) found = TRUE; term_Delete(literal1); } return found; }
void res_InsertClauseIndex(CLAUSE clause, st_INDEX stindex) /********************************************************** INPUT: A st_INDEX and a clause. RETURNS: Inserts the clause in the st_INDEX stindex. CAUTION: None. ***********************************************************/ { int n,j; n = clause_Length(clause); for (j = 0; j < n; j++) st_EntryCreate(stindex, clause_GetLiteral(clause,j), clause_GetLiteralTerm(clause,j), cont_LeftContext()); }
void res_DeleteClauseIndex(CLAUSE clause, st_INDEX stindex) /********************************************************** INPUT: A st_INDEX and a clause. RETURNS: Deletes the clause from the st_INDEX stindex. CAUTION: None. ***********************************************************/ { int n, j; n = clause_Length(clause); for (j = 0; j < n; j++) if (!st_EntryDelete(stindex, clause_GetLiteral(clause,j), clause_GetLiteralTerm(clause,j), cont_LeftContext())) misc_DumpCore(); }
static LIST red_GetTerminatorPartnerLits(TERM Atom, LITERAL Lit, BOOL UnitsOnly, LIST IndexList) /************************************************************** INPUT: An atom, a literal, a boolean flag and a list of SHARED_INDEXes. RETURNS: A list of literals with sign complementary to <Lit> that are unifiable with <Atom>. The literals are searched in all SHARED_INDEXes from <IndexList>. Additionally, if <Unitsonly> is true, only literals from unit clauses are returned. EFFECT: <Atom> is a copy of <Lit> where some substitution was applied and equality literals might have been swapped. <Lit> is just needed to check whether the unifiable literals are complementary. ***************************************************************/ { LIST Result, Unifiers, LitScan; LITERAL NextLit; Result = list_Nil(); for ( ; !list_Empty(IndexList); IndexList = list_Cdr(IndexList)) { Unifiers = st_GetUnifier(cont_LeftContext(), sharing_Index(list_Car(IndexList)), cont_RightContext(), Atom); for ( ; !list_Empty(Unifiers); Unifiers = list_Pop(Unifiers)) { if (!term_IsVariable(list_Car(Unifiers))) { for (LitScan = sharing_NAtomDataList(list_Car(Unifiers)); !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) { NextLit = list_Car(LitScan); if (clause_LiteralsAreComplementary(Lit, NextLit) && (!UnitsOnly || clause_Length(clause_LiteralOwningClause(NextLit))==1)) /* The partner literals must have complementary sign and if <UnitsOnly> == TRUE they must be from unit clauses. */ Result = list_Cons(NextLit, Result); } } } } return Result; }
static LIST inf_GetURPartnerLits(TERM Atom, LITERAL Lit, BOOL Unit, SHARED_INDEX Index) /************************************************************** INPUT: An atom, a literal, a boolean flag and a SHARED_INDEX. RETURNS: A list of literals with sign complementary to <Lit> that are unifiable with <Atom>. If <Unit> is true, only literals from unit clauses are returned, if <Unit> is false, only literals from non-unit clauses are returned. EFFECT: <Atom> is a copy of <Lit>'s atom where some substitution was applied and equality literals might have been swapped. <Lit> is just needed to check whether the unifiable literals are complementary. ***************************************************************/ { LIST Result, Unifiers, LitScan; LITERAL PLit; int length; Result = list_Nil(); Unifiers = st_GetUnifier(cont_LeftContext(), sharing_Index(Index), cont_RightContext(), Atom); for ( ; !list_Empty(Unifiers); Unifiers = list_Pop(Unifiers)) { if (!term_IsVariable(list_Car(Unifiers))) { for (LitScan = sharing_NAtomDataList(list_Car(Unifiers)); !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) { PLit = list_Car(LitScan); length = clause_Length(clause_LiteralOwningClause(PLit)); if (clause_LiteralsAreComplementary(Lit, PLit) && ((Unit && length==1) || (!Unit && length!=1))) /* The partner literals must have complementary sign and if <Unit> == TRUE they must be from unit clauses, if <Unit> == FALSE they must be from non-unit clauses. */ Result = list_Cons(PLit, Result); } } } return Result; }
void ana_AnalyzeProblem(PROOFSEARCH Search, LIST Clauses) /************************************************************** INPUT: A proofsearch object and a list of clauses. RETURNS: Void. EFFECT: Analyzes the clauses and sets the analyze variables. Recomputes the weight for the clauses. <Search> is modified according to clauses: non trivial domain number is set ***************************************************************/ { CLAUSE Clause; ana_EQUATIONS = FALSE; ana_PEQUATIONS = FALSE; /* Defaults for properties */ ana_NEQUATIONS = FALSE; ana_FUNCTIONS = FALSE; ana_FINDOMAIN = FALSE; ana_NONTRIVDOMAIN = FALSE; ana_MONADIC = FALSE; ana_NONMONADIC = FALSE; ana_PROP = FALSE; ana_GROUND = FALSE; ana_SORTRES = FALSE; ana_USORTRES = FALSE; ana_NONUNIT = FALSE; ana_CONGROUND = TRUE; ana_AXIOMCLAUSES = 0; ana_CONCLAUSES = 0; ana_NONHORNCLAUSES = 0; list_Delete(ana_FINITEMONADICPREDICATES); ana_FINITEMONADICPREDICATES = list_Nil(); if (list_Empty(Clauses)) return; ana_FINITEMONADICPREDICATES = clause_FiniteMonadicPredicates(Clauses); while (!list_Empty(Clauses)) { Clause = (CLAUSE)list_Car(Clauses); clause_UpdateWeight(Clause, prfs_Store(Search)); if (clause_GetFlag(Clause,CONCLAUSE)) ana_CONCLAUSES++; else ana_AXIOMCLAUSES++; if (clause_NumOfSuccLits(Clause) > 1) ana_NONHORNCLAUSES++; if (ana_CONGROUND && clause_GetFlag(Clause,CONCLAUSE) && clause_MaxVar(Clause) != symbol_GetInitialStandardVarCounter()) ana_CONGROUND = FALSE; if (!ana_PEQUATIONS && clause_ContainsPositiveEquations(Clause)) { ana_PEQUATIONS = TRUE; } if (!ana_NEQUATIONS && clause_ContainsNegativeEquations(Clause)) { ana_NEQUATIONS = TRUE; } if (!ana_MONADIC || !ana_NONMONADIC || !ana_PROP || !ana_GROUND) clause_ContainsFolAtom(Clause,&ana_PROP,&ana_GROUND,&ana_MONADIC,&ana_NONMONADIC); if (!ana_FUNCTIONS && clause_ContainsFunctions(Clause)) { ana_FUNCTIONS = TRUE; } if (!ana_FINDOMAIN && clause_ImpliesFiniteDomain(Clause)) { ana_FINDOMAIN = TRUE; } if (!ana_NONTRIVDOMAIN && clause_ImpliesNonTrivialDomain(Clause)) { prfs_SetNonTrivClauseNumber(Search, clause_Number(Clause)); ana_NONTRIVDOMAIN = TRUE; } if (!ana_NONUNIT && clause_Length(Clause) > 1) { ana_NONUNIT = TRUE; } if (!ana_SORTRES || !ana_USORTRES) clause_ContainsSortRestriction(Clause,&ana_SORTRES,&ana_USORTRES); Clauses = list_Cdr(Clauses); } ana_PUREEQUATIONAL = ((ana_PEQUATIONS || ana_NEQUATIONS) && !ana_MONADIC && !ana_NONMONADIC && !ana_PROP && !ana_GROUND); ana_EQUATIONS = (ana_PEQUATIONS || ana_NEQUATIONS); ana_PUREPROPOSITIONAL = (!ana_PEQUATIONS && !ana_NEQUATIONS &&!ana_MONADIC && !ana_NONMONADIC && ana_PROP); }
static LIST ana_CalculatePredicatePrecedence(LIST Predicates, LIST Clauses) /************************************************************** INPUT: A list of predicates and a list of clauses. RETURNS: A list of predicate symbols, which should be used for setting the symbol precedence. The list is sorted in descending order, that means predicates with highest precedence come first. EFFECT: Analyze the clause list to build a directed graph G where the predicates are vertices. There's an edge (P,Q) in G iff a clause exists where P is a negative literal and Q is a positive literal and P != Q. Apply DFS to find the strongly connected components of this graph. The <Predicates> list is deleted. CAUTION: The predicate list must contain ALL predicates occurring in the clause list! ***************************************************************/ { GRAPH graph; LIST result, scan; int i, j; NAT count; SYMBOL s; /* clause_ListPrint(Clauses); DBG */ if (list_Empty(Predicates)) { return Predicates; } graph = graph_Create(); /* First create the nodes: one node for every predicate symbol. */ for ( ; !list_Empty(Predicates); Predicates = list_Pop(Predicates)) graph_AddNode(graph, symbol_Index((SYMBOL)list_Car(Predicates))); /* Now scan the clause clause list to create the edges */ /* An edge (P,Q) means P is smaller than Q */ for (scan = Clauses; !list_Empty(scan); scan = list_Cdr(scan)) { CLAUSE c = list_Car(scan); for (i = clause_FirstLitIndex(); i < clause_FirstSuccedentLitIndex(c); i++) { SYMBOL negPred = term_TopSymbol(clause_GetLiteralAtom(c, i)); if (!symbol_Equal(negPred, fol_Equality())) { /* negative predicate */ for (j = clause_FirstSuccedentLitIndex(c); j < clause_Length(c); j++) { SYMBOL posPred = term_TopSymbol(clause_GetLiteralAtom(c, j)); if (!symbol_Equal(posPred, fol_Equality()) && /* positive predicate */ negPred != posPred) { /* No self loops! */ graph_AddEdge(graph_GetNode(graph, symbol_Index(negPred)), graph_GetNode(graph, symbol_Index(posPred))); } } } } } /* graph_Print(graph); fflush(stdout); DBG */ /* Calculate the strongly connected components of the graph */ count = graph_StronglyConnectedComponents(graph); /* Now create the precedence list by scanning the nodes. */ /* If there's a link between two strongly connected components */ /* c1 and c2 then component_num(c1) > component_num(c2), so the */ /* following code creates a valid precedence list in descending */ /* order. */ result = list_Nil(); for (i = count - 1; i >= 0; i--) { for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) { GRAPHNODE n = list_Car(scan); if (graph_NodeCompNum(n) == i) { /* The symbol represented by the node <<n> belongs to component <i> */ s = symbol_GetSigSymbol(graph_NodeNumber(n)); result = list_Cons((POINTER)s, result); } } } /* putchar('\n'); for (scan = result; !list_Empty(scan); scan = list_Cdr(scan)) { s = (SYMBOL) list_Car(scan); symbol_Print(s); putchar(' '); } putchar('\n'); fflush(stdout); DBG */ graph_Delete(graph); 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; } }
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; }