static BOOL ana_BidirectionalDistributivity(LIST SymbolPairs) /************************************************************** INPUT: A list of symbol pairs defining distributivity. RETURNS: TRUE, if the list contains two pairs (s1, s2) and (s2, s1) FALSE otherwise. EFFECT: This function is used to detect symbols that are distributive in both directions, logical OR and AND for example. ***************************************************************/ { LIST scan, actPair, nextPair; for ( ; !list_Empty(SymbolPairs); SymbolPairs = list_Cdr(SymbolPairs)) { actPair = list_Car(SymbolPairs); /* If actPair = (s1, s2), check whether there's a pair (s2, s1) in list */ for (scan = list_Cdr(SymbolPairs); !list_Empty(scan); scan = list_Cdr(scan)) { nextPair = list_Car(scan); if (symbol_Equal((SYMBOL)list_PairFirst(actPair),(SYMBOL)list_PairSecond(nextPair)) && symbol_Equal((SYMBOL)list_PairSecond(actPair),(SYMBOL)list_PairFirst(nextPair))) return TRUE; } } return FALSE; }
void cont_Check(void) /********************************************************** INPUT: None. RETURNS: None. EFFECT: Frees internal structures of the unify module. ********************************************************/ { #ifdef CHECK if (cont_LASTBINDING || (cont_BINDINGS != 0) || !symbol_Equal(cont_INDEXVARSCANNER, symbol_GetInitialIndexVarCounter())) { misc_StartErrorReport(); misc_ErrorReport("\n In cont_Check: There are variable bindings not reset.\n"); misc_FinishErrorReport(); } #endif }
void symbol_FPrint(FILE* File, SYMBOL Symbol) /************************************************************** INPUT: A file and a symbol. RETURNS: None. SUMMARY: Prints a symbol to the file. ***************************************************************/ { #ifdef CHECK if (!symbol_IsSymbol(Symbol)) { misc_StartErrorReport(); misc_ErrorReport("\n In symbol_FPrint: Illegal input.\n"); misc_FinishErrorReport(); } #endif if (symbol_Equal(symbol_Null(),Symbol)) fputs("NULL", File); else if (symbol_IsVariable(Symbol)) { SYMBOL NormSymbol; NormSymbol = symbol_NormVar(Symbol); if (symbol_IsStandardVariable(Symbol)) { if (Symbol <= 6) /* U, V, W, X, Y, Z */ sprintf(symbol_VARSTRING,"%c", 'U' + NormSymbol - 1); else /* X1, X2, X3, ... */ sprintf(symbol_VARSTRING,"X%d", NormSymbol - 6); } else if (symbol_IsIndexVariable(Symbol)) /* I1, I2, I3, ... */ sprintf(symbol_VARSTRING,"I%d", NormSymbol); fputs(symbol_VARSTRING, File); } else if (symbol_SignatureExists()) fputs(symbol_Name(Symbol), File); else fprintf(File, "%d", Symbol); }
BOOL cont_TermContainsSymbol(CONTEXT Context, TERM Term, SYMBOL Symbol) /********************************************************* INPUT: A context, a term and a symbol. RETURNS: TRUE, if <Symbol> occurs in <Term> with respect to the bindings in <Context>, FALSE otherwise. ********************************************************/ { LIST scan; Term = cont_Deref(&Context, Term); if (symbol_Equal(term_TopSymbol(Term), Symbol)) return TRUE; else for (scan = term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan)) { if (cont_TermContainsSymbol(Context, list_Car(scan), Symbol)) return TRUE; } return FALSE; }
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; }