LIST list_PointerDeleteElement(LIST List, POINTER Element) /************************************************************** INPUT: A list and an element pointer RETURNS: The list where Element is deleted from List with respect to pointer equality. EFFECTS: If <List> contains <Element> with respect to pointer equality, <Element> is deleted from <List>. This function needs time O(n), where <n> is the length of the list. CAUTION: Destructive. Be careful, the first element of a list cannot be changed destructively by call by reference. ***************************************************************/ { LIST Scan1,Scan2; while (!list_Empty(List) && Element == list_Car(List)) { Scan1 = list_Cdr(List); list_Free(List); List = Scan1; } if (list_Empty(List)) return list_Nil(); Scan2 = List; Scan1 = list_Cdr(List); while (!list_Empty(Scan1)) { if (Element == list_Car(Scan1)) { list_Rplacd(Scan2, list_Cdr(Scan1)); list_Free(Scan1); Scan1 = list_Cdr(Scan2); } else { Scan2 = Scan1; Scan1 = list_Cdr(Scan1); } } return List; }
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; }
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 symbol_GetAllSymbols(void) /************************************************************** INPUT: None. RETURNS: A list of all generated symbols. ***************************************************************/ { LIST Result; Result = list_Nil(); if (symbol_SignatureExists()) { int Index; SIGNATURE S; for (Index = 1; Index < symbol_ACTINDEX; Index++) { S = symbol_Signature(Index); if (S != NULL) { Result = list_Cons((POINTER)symbol_GetSigSymbol(Index), Result); } } } return Result; }
LIST list_DeleteElementIf(LIST List, BOOL (*Test)(POINTER)) /************************************************************** INPUT: A list and a test for elements. RETURNS: The list where an element is deleted if <Test> on it succeeds. CAUTION: Destructive. Be careful, the first element of a list cannot be changed destructively by call by reference. ***************************************************************/ { LIST Scan1,Scan2; while (!list_Empty(List) && Test(list_Car(List))) { Scan1 = list_Cdr(List); list_Free(List); List = Scan1; } if (list_Empty(List)) return list_Nil(); Scan2 = List; Scan1 = list_Cdr(List); while (!list_Empty(Scan1)) { if (Test(list_Car(Scan1))) { list_Rplacd(Scan2, list_Cdr(Scan1)); list_Free(Scan1); Scan1 = list_Cdr(Scan2); } else { Scan2 = Scan1; Scan1 = list_Cdr(Scan1); } } return List; }
void cont_Init(void) /********************************************************** INPUT: None. RETURNS: None. EFFECT: Initializes the unify module. ********************************************************/ { cont_LASTBINDING = (CONTEXT)NULL; cont_ResetIndexVarScanner(); cont_NOOFCONTEXTS = 0; cont_LISTOFCONTEXTS = list_Nil(); cont_BINDINGS = 0; cont_INSTANCECONTEXT = (CONTEXT)memory_Malloc(sizeof(CONTEXT_NODE)); cont_LEFTCONTEXT = cont_Create(); cont_RIGHTCONTEXT = cont_Create(); cont_StackInit(); cont_StackPush(0); cont_StackPop(); }
LIST split_Backtrack(PROOFSEARCH PS, CLAUSE EmptyClause, CLAUSE* SplitClause) /************************************************************** INPUT: A proofsearch object, an empty clause and a pointer to a clause used as return value. RETURNS: A list of clauses deleted in the backtracked split levels. <*SplitClause> is set to the split clause for the right branch of the splitting step, or NULL, if the tableau is finished. EFFECT: Backtracks the top of the split stack wrt the empty clause's level ***************************************************************/ { SPLIT ActBacktrackSplit; LIST RecoverList, Scan; int Backtracklevel; ActBacktrackSplit = (SPLIT)NULL; RecoverList = split_RemoveUnnecessarySplits(PS, EmptyClause); Backtracklevel = clause_SplitLevel(EmptyClause); *SplitClause = NULL; /* Backtrack all split levels bigger than the level of the empty clause */ while (!prfs_SplitStackEmpty(PS) && (prfs_ValidLevel(PS) > Backtracklevel)) { ActBacktrackSplit = prfs_SplitStackTop(PS); prfs_SplitStackPop(PS); if (prfs_SplitFatherClause(ActBacktrackSplit) != (CLAUSE)NULL) { RecoverList = list_Cons(prfs_SplitFatherClause(ActBacktrackSplit), RecoverList); prfs_SplitSetFatherClause(ActBacktrackSplit, NULL); } RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit), RecoverList); clause_DeleteClauseList(prfs_SplitBlockedClauses(ActBacktrackSplit)); prfs_SplitFree(ActBacktrackSplit); prfs_DecValidLevel(PS); } /* Backtrack further for all right branches on top of the stack */ while (!prfs_SplitStackEmpty(PS) && list_Empty(prfs_SplitBlockedClauses(prfs_SplitStackTop(PS)))) { ActBacktrackSplit = prfs_SplitStackTop(PS); prfs_SplitStackPop(PS); if (prfs_SplitFatherClause(ActBacktrackSplit) != (CLAUSE)NULL) RecoverList = list_Cons(prfs_SplitFatherClause(ActBacktrackSplit), RecoverList); RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit), RecoverList); prfs_SplitFree(ActBacktrackSplit); prfs_DecValidLevel(PS); } if (!prfs_SplitStackEmpty(PS)) { /* Enter the right branch of the splitting step */ int SplitMinus1; LIST RightClauses; SplitMinus1 = prfs_ValidLevel(PS) - 1; ActBacktrackSplit = prfs_SplitStackTop(PS); RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit), RecoverList); prfs_SplitSetDeletedClauses(ActBacktrackSplit, list_Nil()); RecoverList = split_DeleteInvalidClausesFromList(PS, SplitMinus1, RecoverList); RightClauses = prfs_SplitBlockedClauses(ActBacktrackSplit); prfs_SplitSetBlockedClauses(ActBacktrackSplit, list_Nil()); for (Scan = RightClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) { if (clause_Number(list_Car(Scan)) == 0) { /* Found the right clause, the negation clauses have number -1. */ #ifdef CHECK if (*SplitClause != NULL) { misc_StartErrorReport(); misc_ErrorReport("\n In split_Backtrack:"); misc_ErrorReport(" Found two blocked clauses "); misc_ErrorReport("\n with clause number 0 (this marks the clause "); misc_ErrorReport("\n for the right branch of the tableau)."); misc_FinishErrorReport(); } #endif *SplitClause = list_Car(Scan); } clause_NewNumber((CLAUSE) list_Car(Scan)); clause_AddParentClause((CLAUSE) list_Car(Scan), clause_Number(EmptyClause)); clause_AddParentLiteral((CLAUSE) list_Car(Scan), 0); /* dummy literal */ } #ifdef CHECK if (*SplitClause == NULL) { misc_StartErrorReport(); misc_ErrorReport("\n In split_Backtrack: Didn´t find a blocked clause"); misc_ErrorReport("\n with clause number 0. (this marks the clause "); misc_ErrorReport("\n for the right branch of the tableau)."); misc_FinishErrorReport(); } #endif RecoverList = list_Nconc(RightClauses, RecoverList); /* Then, delete clauses from current level (Hack) */ prfs_DecValidLevel(PS); prfs_MoveInvalidClausesDocProof(PS); split_DeleteInvalidClausesFromStack(PS); prfs_IncValidLevel(PS); } else { /* Don't delete clauses from current level (split is top level) */ prfs_MoveInvalidClausesDocProof(PS); for (Scan = RecoverList; !list_Empty(Scan); Scan = list_Cdr(Scan)) prfs_InsertDocProofClause(PS, list_Car(Scan)); list_Delete(RecoverList); RecoverList = list_Nil(); } prfs_SetLastBacktrackLevel(PS, prfs_ValidLevel(PS)); return RecoverList; }
static LIST split_RemoveUnnecessarySplits(PROOFSEARCH PS, CLAUSE EmptyClause) /************************************************************** INPUT: An empty clause and a proof search object EFFECT: Removes all splits up to the last backtrack level that were not necessary to derive the empty clause. RETURNS: A list of recovered clauses. ***************************************************************/ { LIST Scan; LIST Recover, New; LIST Deleted; LIST ScanStack; int SplitLevel; int LastBacktrackLevel; SPLIT Split,ScanSplit; Scan = prfs_SplitStack(PS); SplitLevel = prfs_ValidLevel(PS); LastBacktrackLevel = prfs_LastBacktrackLevel(PS); Recover = list_Nil(); while (SplitLevel > LastBacktrackLevel) { if (prfs_SplitIsUnused(list_Car(Scan)) && !clause_DependsOnSplitLevel(EmptyClause, SplitLevel)) { New = list_Nil(); Split = list_Car(Scan); /*printf("\n\t Removed: %d",prfs_SplitSplitLevel(Split));*/ clause_DeleteClauseList(prfs_SplitBlockedClauses(Split)); prfs_SplitSetBlockedClauses(Split, list_Nil()); Recover = list_Nconc(prfs_SplitDeletedClauses(Split), Recover); prfs_SplitSetDeletedClauses(Split, list_Nil()); if (prfs_SplitFatherClause(Split) != (CLAUSE)NULL) { Recover = list_Cons(prfs_SplitFatherClause(Split),Recover); prfs_SplitSetFatherClause(Split,NULL); } Recover = split_DeleteClausesDependingOnLevelFromList(PS, Recover, SplitLevel, &New); ScanStack = prfs_SplitStack(PS); while (!list_StackEmpty(ScanStack) && prfs_SplitSplitLevel((ScanSplit = (SPLIT)list_Car(ScanStack))) > LastBacktrackLevel) { Deleted = prfs_SplitDeletedClauses(ScanSplit); prfs_SplitSetDeletedClauses(ScanSplit, list_Nil()); /* IMPORTANT!, see next line */ Deleted = split_DeleteClausesDependingOnLevelFromList(PS, Deleted, SplitLevel, &New); prfs_SplitSetDeletedClauses(ScanSplit, Deleted); ScanStack = list_Cdr(ScanStack); } while (!list_Empty(New)) { Deleted = list_Nil(); Recover = list_Nconc(split_DeleteClausesDependingOnLevelFromList(PS, New, SplitLevel, &Deleted), Recover); New = Deleted; } Recover = list_Nconc(Recover, split_DeleteClausesDependingOnLevelFromSet(PS, prfs_UsableClauses(PS), SplitLevel)); Recover = list_Nconc(Recover, split_DeleteClausesDependingOnLevelFromSet(PS, prfs_WorkedOffClauses(PS), SplitLevel)); prfs_SplitSetUsed(Split); } SplitLevel--; Scan = list_Cdr(Scan); } return Recover; }
LIST subs_CompList(LITPTR litptr) /********************************************************** INPUT: A pointer litptr. RETURNS: A list with indexes which represents the first component of with respect to the actual bindings and to litptr. CAUTION: The structure to which litptr points to is changed destructively in the used slot. ***********************************************************/ { BOOL found,hasinter; LIST scan,complist,compindexlist; int n,i,j,lit; compindexlist = list_Nil(); /* the result will be placed into this list */ complist = list_Nil(); /* added afterwards */ n = litptr_Length(litptr); if (n > 0) { for (j = 0; j < n; j++) { printf("\nj = %d\n",j); if (!literal_GetUsed(litptr_Literal(litptr,j))) { complist = list_Nil(); complist = list_Cons((POINTER)j,complist); compindexlist = list_Cons((POINTER)(litptr->litptr[j]->litindex), compindexlist); literal_PutUsed(litptr_Literal(litptr,j), TRUE); j = n+1; printf("\nj == %d\n",j); } } if (j == n) { list_Delete(complist); /* There is no more component */ return compindexlist; /* should be empty here */ } found = TRUE; while (found) { found = FALSE; for (scan = complist; !list_Empty(scan); scan = list_Cdr(scan)) { lit = (int)list_Car(scan); for (i = 0; i < n; i++) { if (!literal_GetUsed(litptr_Literal(litptr,i))) { printf("lit = %d\n",lit); printf("i = %d\n",i); hasinter = list_HasIntersection(litptr->litptr[lit]->litvarlist, litptr->litptr[i]->litvarlist); if (hasinter) { puts("hasinter = TRUE"); complist = list_Cons((POINTER)i,complist); compindexlist = list_Cons((POINTER)(litptr->litptr[i]->litindex),compindexlist); literal_PutUsed(litptr_Literal(litptr,i), TRUE); found = TRUE; } } } } if (!found) { /* one component is finished */ list_Delete(complist); found = FALSE; } } } return compindexlist; }
static void dp_FPrintDFGProof(LIST Clauses, const char *FilePrefix, FLAGSTORE Flags, PRECEDENCE Precedence) /********************************************************* INPUT: A list of clauses representing a proof, a string indicating a file name prefix, a flag store and a precedence. RETURNS: void. EFFECT: Outputs the proof in DFG proof format to <FilePrefix>.prf **********************************************************/ { FILE *Output; CLAUSE Clause; LIST AxClauses,ConClauses,ProofClauses,Scan; char *name; AxClauses = ConClauses = ProofClauses = list_Nil(); name = memory_Malloc(sizeof(char)*(strlen(FilePrefix)+5)); sprintf(name,"%s.prf", FilePrefix); Output = misc_OpenFile(name,"w"); fputs("begin_problem(Unknown).\n\n", Output); fputs("list_of_descriptions.\n", Output); fputs("name({*", Output); fputs(FilePrefix, Output); fputs("*}).\n", Output); fputs("author({*SPASS ", Output); fputs(misc_VERSION, Output); fputs("*}).\n", Output); fputs("status(unsatisfiable).\n", Output); fputs("description({*File generated by SPASS containing a proof.*}).\n", Output); fputs("end_of_list.\n\n", Output); fputs("list_of_symbols.\n", Output); fol_FPrintDFGSignature(Output); fputs("end_of_list.\n\n", Output); for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) { Clause = (CLAUSE)list_Car(Scan); if (clause_IsFromInput(Clause)) { if (clause_GetFlag(Clause, CONCLAUSE)) ConClauses = list_Cons(Clause, ConClauses); else AxClauses = list_Cons(Clause, AxClauses); } else ProofClauses = list_Cons(Clause, ProofClauses); } ConClauses = list_NReverse(ConClauses); AxClauses = list_NReverse(AxClauses); ProofClauses = list_NReverse(ProofClauses); clause_FPrintCnfDFG(Output, FALSE, AxClauses, ConClauses, Flags, Precedence); fputs("\nlist_of_proof(SPASS).\n", Output); for (Scan=ProofClauses; !list_Empty(Scan); Scan=list_Cdr(Scan)) { clause_FPrintDFGStep(Output,list_Car(Scan),TRUE); } fputs("end_of_list.\n\n", Output); fputs("end_problem.\n\n", Output); misc_CloseFile(Output, name); fputs("\nDFG Proof printed to: ", stdout); puts(name); list_Delete(ConClauses); list_Delete(AxClauses); list_Delete(ProofClauses); memory_Free(name, sizeof(char)*(strlen(FilePrefix)+5)); }
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 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; }
static SYMBOL symbol_SignatureCreate(char* String, int Type, int Arity, int Status, PRECEDENCE Precedence) /************************************************************** INPUT: A pointer to a string, a type, the arity and the status RETURNS: The symbol containing the passed parameters. SUMMARY: Establishes a new symbol in the symbol table and returns the internal representation (pointer and type). CAUTION: The string is not copied! ***************************************************************/ { SIGNATURE Entry; #ifdef CHECK if (!symbol_SignatureExists()) { misc_StartErrorReport(); misc_ErrorReport("\n In symbol_SignatureCreate:"); misc_ErrorReport(" Module was initialized with no signature.\n"); misc_FinishErrorReport(); } if (Type < 0 || Type >= symbol_SIGTYPES) { misc_StartErrorReport(); misc_ErrorReport("\n In symbol_SignatureCreate: Illegal input.\n"); misc_FinishErrorReport(); } #endif if ((int)symbol_ACTINDEX >= symbol__MAXSIGNATURE && list_Empty(symbol_FREEDSYMBOLS)) { misc_StartUserErrorReport(); misc_UserErrorReport("\n In symbol_SignatureCreate: No more symbols available.\n"); misc_FinishUserErrorReport(); } if (strlen(String)>=symbol__SYMBOLMAXLEN) { misc_StartUserErrorReport(); misc_UserErrorReport("\n In symbol_SignatureCreate: String too long.\n"); misc_FinishUserErrorReport(); } Entry = symbol_GetSignature(); Entry->weight = 1; Entry->props = 0; Entry->name = String; Entry->length = strlen(String); Entry->arity = Arity; Entry->generatedBy = list_Nil(); if (list_Empty(symbol_FREEDSYMBOLS)) { Entry->info = symbol_SignatureSymbol(symbol_ACTINDEX, Type, Status); symbol_SetSignature(symbol_ACTINDEX++, Entry); } else { int Index; Index = (int)list_Car(symbol_FREEDSYMBOLS); symbol_FREEDSYMBOLS = list_PointerDeleteElement(symbol_FREEDSYMBOLS, (POINTER)Index); Entry->info = symbol_SignatureSymbol(Index, Type, Status); symbol_SetSignature(Index, Entry); } /* Define precedence of symbol */ symbol_SetIncreasedOrdering(Precedence, Entry->info); return Entry->info; }
int main(int argc, const char* argv[]) { LIST Clauses,Axioms,Conjectures,Sorts,Scan, UserPrecedence,UserSelection,ClAxRelation; FILE *Input; CLAUSE Clause; const char *Filename; FLAGSTORE Flags; PRECEDENCE Precedence; BOOL HasPlainClauses; DFGDESCRIPTION Description; memory_Init(memory__UNLIMITED); atexit(memory_FreeAllMem); symbol_Init(TRUE); stack_Init(); term_Init(); flag_Init(flag_SPASS); cmdlne_Init(); Flags = flag_CreateStore(); flag_InitStoreByDefaults(Flags); Precedence = symbol_CreatePrecedence(); Description = desc_Create(); fol_Init(TRUE, Precedence); eml_Init(Precedence); clause_Init(); if (argc < 2 || !cmdlne_Read(argc, argv)) { fputs("\n\t dfg2ascii Version ", stdout); fputs(DFG2ASCII__VERSION, stdout); puts("\n\t Usage: dfg2ascii <input-file>\n"); return EXIT_FAILURE; } if (!cmdlne_SetFlags(Flags)) return EXIT_FAILURE; Axioms = list_Nil(); Conjectures = list_Nil(); Sorts = list_Nil(); UserPrecedence = list_Nil(); UserSelection = list_Nil(); ClAxRelation = list_Nil(); Filename = cmdlne_GetInputFile(); Input = misc_OpenFile(Filename,"r"); Clauses = dfg_DFGParser(Input, Flags, Precedence, Description, &Axioms, &Conjectures, &Sorts, &UserPrecedence, &UserSelection, &ClAxRelation, &HasPlainClauses); misc_CloseFile(Input,Filename); Axioms = list_Nconc(Axioms, Sorts); if (!list_Empty(Axioms) || !list_Empty(Conjectures)) { puts("\n\n\t\t Axioms:\n"); if (list_Empty(Axioms)) puts("None.\n"); else for (Scan=Axioms; !list_Empty(Scan);Scan=list_Cdr(Scan)) { if (list_PairFirst(list_Car(Scan)) != NULL) printf("%s:\n",(char *)list_PairFirst(list_Car(Scan))); fol_PrettyPrintDFG(list_PairSecond(list_Car(Scan))); puts("\n"); } puts("\n\n\t\t Conjectures:\n"); if (list_Empty(Conjectures)) puts("None.\n"); else for (Scan=Conjectures; !list_Empty(Scan);Scan=list_Cdr(Scan)) { if (list_PairFirst(list_Car(Scan)) != NULL) printf("%s:\n",(char *)list_PairFirst(list_Car(Scan))); fol_PrettyPrintDFG(list_PairSecond(list_Car(Scan))); puts("\n"); } } else { BOOL SetExist; LIST ClauseScan; /* Before we sort the clauses, we need to make sure that they have been assigned a weight. */ for (ClauseScan = Clauses; !list_Empty(ClauseScan); ClauseScan = list_Cdr(ClauseScan)) { clause_UpdateWeight((CLAUSE) list_Car(ClauseScan), Flags); } Clauses = clause_ListSortWeighed(Clauses); clause_SetCounter(1); for (Scan = Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) { Clause = (CLAUSE)list_Car(Scan); clause_SetSortConstraint(Clause, FALSE, Flags, Precedence); clause_NewNumber(Clause); clause_OrientAndReInit(Clause, Flags, Precedence); } puts("\n\n\t\t Axiom Clauses:\n"); SetExist = FALSE; for (Scan = Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) { Clause = (CLAUSE)list_Car(Scan); if (!clause_GetFlag(Clause,CONCLAUSE)) { SetExist = TRUE; clause_Print(Clause); putchar('\n'); } } if (SetExist) SetExist = FALSE; else puts("None.\n"); puts("\n\n\t\t Conjecture Clauses:\n"); for (Scan = Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) { Clause = (CLAUSE)list_Car(Scan); if (clause_GetFlag(Clause,CONCLAUSE)) { SetExist = TRUE; clause_Print(Clause); putchar('\n'); } } if (SetExist) SetExist = FALSE; else puts("None.\n"); } clause_DeleteClauseList(Clauses); dfg_StripLabelsFromList(Axioms); dfg_StripLabelsFromList(Conjectures); term_DeleteTermList(Axioms); term_DeleteTermList(Conjectures); eml_Free(); flag_DeleteStore(Flags); symbol_DeletePrecedence(Precedence); list_Delete(UserPrecedence); list_Delete(UserSelection); dfg_DeleteClAxRelation(ClAxRelation); desc_Delete(Description); /*symbol_Dump();*/ cmdlne_Free(); fol_Free(); symbol_FreeAllSymbols(); #ifdef CHECK memory_Print(); #endif return 0; }
void ana_AutoConfiguration(LIST Clauses, FLAGSTORE Flags, PRECEDENCE Precedence) /************************************************************** INPUT: A list of clauses, a flag store and a precedence. RETURNS: Nothing. EFFECT: Based on the values of the ana analysis module, an appropriate complete configuration of inference, reduction rules and other settings is established. ***************************************************************/ { LIST Scan, Functions, Predicates, Constants; Functions = symbol_GetAllFunctions(); Predicates = fol_GetNonFOLPredicates(); /* Set precedence */ Predicates = ana_CalculatePredicatePrecedence(Predicates, Clauses); Functions = ana_CalculateFunctionPrecedence(Functions, Clauses, Flags); Constants = list_Nil(); for (Scan=Functions; !list_Empty(Scan); Scan=list_Cdr(Scan)) if (symbol_IsConstant((SYMBOL)list_Car(Scan))) Constants = list_Cons(list_Car(Scan),Constants); Functions = list_NPointerDifference(Functions,Constants); Constants = list_NReverse(Constants); for ( ; !list_Empty(Functions); Functions = list_Pop(Functions)) symbol_SetIncreasedOrdering(Precedence, (SYMBOL)list_Car(Functions)); /* Predicates < Functions */ for ( ; !list_Empty(Predicates); Predicates = list_Pop(Predicates)) symbol_SetIncreasedOrdering(Precedence, (SYMBOL)list_Car(Predicates)); /* Constants < Predicates */ /* Predicates < Functions */ for ( ; !list_Empty(Constants); Constants = list_Pop(Constants)) symbol_SetIncreasedOrdering(Precedence, (SYMBOL)list_Car(Constants)); flag_ClearInferenceRules(Flags); flag_ClearReductionRules(Flags); flag_SetFlagIntValue(Flags, flag_ROBV, flag_ROBVON); flag_SetFlagIntValue(Flags, flag_RTAUT, flag_RTAUTSYNTACTIC); flag_SetFlagIntValue(Flags, flag_RFSUB, flag_RFSUBON); flag_SetFlagIntValue(Flags, flag_RBSUB, flag_RBSUBON); flag_SetFlagIntValue(Flags, flag_RFMRR, flag_RFMRRON); flag_SetFlagIntValue(Flags, flag_RBMRR, flag_RBMRRON); flag_SetFlagIntValue(Flags, flag_RUNC, flag_RUNCON); flag_SetFlagIntValue(Flags, flag_FULLRED, flag_FULLREDON); /*flag_SetFlagIntValue(Flags, flag_FUNCWEIGHT,1); flag_SetFlagIntValue(Flags, flag_VARWEIGHT,1);*/ flag_SetFlagIntValue(Flags, flag_WDRATIO,5); if (ana_NEQUATIONS) { flag_SetFlagIntValue(Flags, flag_IEQR, flag_EQUALITYRESOLUTIONON); if (ana_NONUNIT) { if (ana_NONTRIVDOMAIN) flag_SetFlagIntValue(Flags, flag_RAED, flag_RAEDPOTUNSOUND); else flag_SetFlagIntValue(Flags, flag_RAED, flag_RAEDSOUND); } } if (ana_PEQUATIONS) { flag_SetFlagIntValue(Flags, flag_ISPR, flag_SUPERPOSITIONRIGHTON); flag_SetFlagIntValue(Flags, flag_ISPL, flag_SUPERPOSITIONLEFTON); if (ana_NONHORNCLAUSES > 0) flag_SetFlagIntValue(Flags, flag_IEQF, flag_EQUALITYFACTORINGON); if (ana_NONUNIT) flag_SetFlagIntValue(Flags, flag_RCON, flag_RCONON); flag_SetFlagIntValue(Flags, flag_RFREW, flag_RFREWON); flag_SetFlagIntValue(Flags, flag_RBREW, flag_RBREWON); } if (ana_SORTRES) { flag_SetFlagIntValue(Flags, flag_SORTS, flag_SORTSMONADICWITHVARIABLE); flag_SetFlagIntValue(Flags, flag_IEMS, flag_EMPTYSORTON); flag_SetFlagIntValue(Flags, flag_ISOR, flag_SORTRESOLUTIONON); flag_SetFlagIntValue(Flags, flag_RSSI, flag_RSSION); if (!ana_PEQUATIONS || ana_SORTMANYEQUATIONS) flag_SetFlagIntValue(Flags, flag_RSST, flag_RSSTON); } else flag_SetFlagIntValue(Flags, flag_SORTS, flag_SORTSOFF); if (ana_MONADIC || ana_NONMONADIC) { /* Problem contains real predicates */ flag_SetFlagIntValue(Flags, flag_IORE, flag_ORDEREDRESOLUTIONNOEQUATIONS); if (ana_NONHORNCLAUSES > 0) flag_SetFlagIntValue(Flags, flag_IOFC, flag_FACTORINGONLYRIGHT); if (ana_NONUNIT) flag_SetFlagIntValue(Flags, flag_RCON, flag_RCONON); } if (!ana_FUNCTIONS) flag_SetFlagIntValue(Flags, flag_SELECT, flag_SELECTALWAYS); else if (ana_NONUNIT) flag_SetFlagIntValue(Flags, flag_SELECT, flag_SELECTIFSEVERALMAXIMAL); else flag_SetFlagIntValue(Flags, flag_SELECT, flag_SELECTOFF); if (ana_CONCLAUSES < ana_AXIOMCLAUSES || (ana_CONGROUND && !ana_PUREPROPOSITIONAL)) flag_SetFlagIntValue(Flags, flag_SATINPUT, flag_SATINPUTON); else flag_SetFlagIntValue(Flags, flag_SATINPUT, flag_SATINPUTOFF); if (ana_NONHORNCLAUSES > 0) flag_SetFlagIntValue(Flags, flag_SPLITS, flag_SPLITSUNLIMITED); else flag_SetFlagIntValue(Flags, flag_SPLITS, flag_SPLITSOFF); /* if (ana_PUREPROPOSITIONAL) */ /* flag_SetFlagIntValue(Flags, flag_SPLITHEURISTIC, flag_SPLITHEURISTICALWAYS); */ }
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 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; }
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 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; } }