BOOL cmdlne_SetArgument(const char* token, const char* value) /************************************************************** INPUT: two pointers RETURNS: TRUE if the argument <token> has not been added to the list of arguments before and FALSE otherwise. EFFECT: Adds argument <token> with value <value> to list of arguments (<cmdlne_ArgumentsList>) CAUTION: <value> has to be a character pointer pointing to a string representing an integer ***************************************************************/ { LIST Pair; LIST Scan; /* Check if Argument has already been defined */ for(Scan=cmdlne_ArgumentsList; !list_Empty(Scan); Scan = list_Cdr(Scan)) { if(string_Equal(list_PairFirst(list_Car(Scan)),token)) { misc_StartUserErrorReport(); misc_UserErrorReport("\n Option %s is multiply defined.\n\n", token); misc_FinishUserErrorReport(); return FALSE; } } /* Add <token> to argument list with value <value>*/ Pair = list_PairCreate(string_StringCopy(token), string_StringCopy(value)); cmdlne_ArgumentsList = list_Cons(Pair, cmdlne_ArgumentsList); return TRUE; }
static LIST ana_CalculateFunctionPrecedence(LIST Functions, LIST Clauses, FLAGSTORE Flags) /************************************************************** INPUT: A list of functions, a list of clauses and a flag store. RETURNS: A list of function symbols, which should be used for setting the symbol precedence. The list is sorted in descending order, that means function with highest precedence come first. EFFECT: Analyzes the clauses to build a directed graph G with function symbol as nodes. An edge (f,g) or in G means f should have lower precedence than g. An edge (f,g) or (g,f) is created if there's an equation equal(f(...), g(...)) in the clause list. The direction of the edge depends on the degree of the nodes and the symbol arity. Then find the strongly connected components of this graph. The "Ordering" flag will be set in the flag store. CAUTION: The value of "ana_PEQUATIONS" must be up to date. ***************************************************************/ { GRAPH graph; GRAPHNODE n1, n2; LIST result, scan, scan2, distrPairs; int i, j; SYMBOL s, Add, Mult; if (list_Empty(Functions)) return Functions; /* Problem contains no functions */ else if (!ana_PEQUATIONS) { Functions = list_NumberSort(Functions, (NAT (*)(POINTER)) symbol_PositiveArity); return Functions; } graph = graph_Create(); /* First create the nodes: one node for every function symbol. */ for (; !list_Empty(Functions); Functions = list_Pop(Functions)) graph_AddNode(graph, symbol_Index((SYMBOL)list_Car(Functions))); /* Now sort the node list wrt descending symbol arity. */ graph_SortNodes(graph, ana_NodeGreater); /* A list of pairs (add, multiply) of distributive symbols */ distrPairs = list_Nil(); /* Now add undirected edges: there's an undirected edge between */ /* two nodes if the symbols occur as top symbols in a positive */ /* equation. */ for (scan = Clauses; !list_Empty(scan); scan = list_Cdr(scan)) { CLAUSE c = list_Car(scan); for (i = clause_FirstSuccedentLitIndex(c); i <= clause_LastSuccedentLitIndex(c); i++) { if (clause_LiteralIsEquality(clause_GetLiteral(c, i))) { /* Consider only positive equations */ TERM t1, t2; if (fol_DistributiveEquation(clause_GetLiteralAtom(c,i), &Add, &Mult)) { /* Add a pair (Add, Mult) to <distrTerms> */ distrPairs = list_Cons(list_PairCreate((POINTER)Add, (POINTER)Mult), distrPairs); /*fputs("\nDISTRIBUTIVITY: ", stdout); term_PrintPrefix(clause_GetLiteralAtom(c,i)); fputs(" Add=", stdout); symbol_Print(Add); fputs(" Mult=", stdout); symbol_Print(Mult); fflush(stdout); DBG */ } t1 = term_FirstArgument(clause_GetLiteralAtom(c, i)); t2 = term_SecondArgument(clause_GetLiteralAtom(c, i)); if (!term_IsVariable(t1) && !term_IsVariable(t2) && !term_EqualTopSymbols(t1, t2) && /* No self loops! */ !term_HasSubterm(t1, t2) && /* No subterm property */ !term_HasSubterm(t2, t1)) { n1 = graph_GetNode(graph, symbol_Index(term_TopSymbol(t1))); n2 = graph_GetNode(graph, symbol_Index(term_TopSymbol(t2))); /* Create an undirected edge by adding two directed edges */ graph_AddEdge(n1, n2); graph_AddEdge(n2, n1); /* Use the node info for the degree of the node */ ana_IncNodeDegree(n1); ana_IncNodeDegree(n2); } } } } /* putchar('\n'); for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) { n1 = list_Car(scan); printf("(%s,%d,%u), ", symbol_Name(symbol_GetSigSymbol(graph_NodeNumber(n1))), graph_NodeNumber(n1), ana_NodeDegree(n1)); } graph_Print(graph); fflush(stdout); DBG */ graph_DeleteDuplicateEdges(graph); /* Transform the undirected graph into a directed graph. */ for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) { n1 = list_Car(scan); result = list_Nil(); /* Collect edges from n1 that shall be deleted */ for (scan2 = graph_NodeNeighbors(n1); !list_Empty(scan2); scan2 = list_Cdr(scan2)) { int a1, a2; n2 = list_Car(scan2); /* Get the node degrees in the undirected graph with multiple edges */ i = ana_NodeDegree(n1); j = ana_NodeDegree(n2); a1 = symbol_Arity(symbol_GetSigSymbol(graph_NodeNumber(n1))); a2 = symbol_Arity(symbol_GetSigSymbol(graph_NodeNumber(n2))); if (i > j || (i==j && a1 >= a2)) { /* symbol2 <= symbol1, so remove edge n1 -> n2 */ result = list_Cons(n2, result); } if (i < j || (i==j && a1 <= a2)) { /* symbol1 <= symbol2, so remove edge n2 -> n1 */ graph_DeleteEdge(n2, n1); } /* NOTE: If (i==j && a1==a2) both edges are deleted! */ } /* Now delete edges from n1 */ for ( ; !list_Empty(result); result = list_Pop(result)) graph_DeleteEdge(n1, list_Car(result)); } if (!list_Empty(distrPairs) && !ana_BidirectionalDistributivity(distrPairs)) { /* Enable RPO ordering, otherwise the default KBO will be used. */ flag_SetFlagIntValue(Flags, flag_ORD, flag_ORDRPOS); } /* Now examine the list of distribute symbols */ /* since they've highest priority. */ for ( ; !list_Empty(distrPairs); distrPairs = list_Pop(distrPairs)) { scan = list_Car(distrPairs); /* A pair (Add, Mult) */ /* Addition */ n1 = graph_GetNode(graph, symbol_Index((SYMBOL)list_PairFirst(scan))); /* Multiplication */ n2 = graph_GetNode(graph, symbol_Index((SYMBOL)list_PairSecond(scan))); /* Remove any edges between n1 and n2 */ graph_DeleteEdge(n1, n2); graph_DeleteEdge(n2, n1); /* Add one edge Addition -> Multiplication */ graph_AddEdge(n1, n2); list_PairFree(scan); } /* fputs("\n------------------------",stdout); graph_Print(graph); fflush(stdout); DBG */ /* Calculate the strongly connected components of the graph. */ /* <i> is the number of SCCs. */ i = 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(); while (i-- > 0) { /* for i = numberOfSCCs -1 dowto 0 */ for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) { n1 = list_Car(scan); if (graph_NodeCompNum(n1) == i) { /* The symbol represented by the node <n> belongs to component <i> */ s = symbol_GetSigSymbol(graph_NodeNumber(n1)); 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); fputs(" > ", stdout); } 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; }
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; } }