static void cc_InitData(CLAUSE clause) /*************************************************************** INPUT: the clause to investigate EFFECT: pushes clause's atoms and their subterms on the pending stack, initializes each predecessor list with the list containing only a term's father, and unions the equivalence classes of the terms of the same antecedent equation ***************************************************************/ { int last, actno, i, ld; TERM atom; RAS cdr, size; cc_SetCars(ras_InitWithSize(cc_GetCars(), cc_RASSTDSIZE)); cc_SetPending(ras_InitWithSize(cc_GetPending(), cc_RASSTDSIZE)); ras_FastPush(cc_GetCars(), term_Null()); /* "true" has no predecessors */ actno = 1; last = clause_LastLitIndex(clause); for (i = clause_FirstLitIndex(); i <= last; i++) { atom = clause_GetLiteralAtom(clause, i); if (fol_IsEquality(atom)) { actno = cc_Number(actno, term_FirstArgument(atom), term_Null()); actno = cc_Number(actno, term_SecondArgument(atom), term_Null()); } else actno = cc_Number(actno, atom, term_Null()); } cc_SetPartition(part_Init(cc_GetPartition(), actno)); cc_SetTable(table_Init(cc_GetTable(), symbol_ActIndex() - 1, clause_MaxVar(clause), actno - 1)); cdr = ras_InitWithSize(cc_GetCdrs(), actno); size = ras_InitWithSize(cc_GetSizes(), actno); for (i = 0; i < actno; i++) { ras_FastPush(cdr, (POINTER) i); /* form a cycle */ ras_FastPush(size, (POINTER) (cc_GetCar(i) == term_Null()? 0 : 1)); } cc_SetCdrs(cdr); cc_SetSizes(size); /* compute ceil(ld(actno)) avoiding mathbib-logarithm's rounding errors: */ for (ld = 0, i = actno - 1; i > 0; i >>= 1) ld++; cc_SetCombine(ras_InitWithSize(cc_GetCombine(), actno * ld + 1)); /* for every antecedent equation union equivalence classes of its terms */ /* (a non-equational atom is represented as the equation atom = "true"): */ last = clause_LastAntecedentLitIndex(clause); for (i = clause_FirstLitIndex(); i <= last; i++) { atom = clause_GetLiteralAtom(clause, i); if (fol_IsEquality(atom)) cc_Union(term_Size(term_FirstArgument(atom)), /* clause not shared, therefore */ term_Size(term_SecondArgument(atom))); /* here no cc_Find needed */ else cc_Union(term_Size(atom), part_Find(cc_GetPartition(), cc_NOOFTRUE)); } }
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 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; }
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; }