BOOL cont_TermEqual(CONTEXT Context1, TERM Term1, CONTEXT Context2, TERM Term2) /********************************************************* INPUT: Two terms and two contexts. RETURNS: TRUE iff the two terms are equal, where variables are interpreted with respect to the bindings in the contexts. ********************************************************/ { #ifdef CHECK if (!(term_IsTerm(Term1) && term_IsTerm(Term2))) { misc_StartErrorReport(); misc_ErrorReport("\n In cont_TermEqual: Input terms are corrupted.\n"); misc_FinishErrorReport(); } #endif Term1 = cont_Deref(&Context1,Term1); Term2 = cont_Deref(&Context2,Term2); if (!term_EqualTopSymbols(Term1, Term2)) return FALSE; else if (term_ArgumentList(Term1)) { LIST Scan1, Scan2; for (Scan1=term_ArgumentList(Term1), Scan2=term_ArgumentList(Term2); list_Exist(Scan1) && list_Exist(Scan2); Scan1=list_Cdr(Scan1), Scan2=list_Cdr(Scan2)) if (!cont_TermEqual(Context1,list_Car(Scan1), Context2,list_Car(Scan2))) return FALSE; return (list_Empty(Scan1) ? list_Empty(Scan2) : FALSE); } else return TRUE; }
ord_RESULT rpos_ContCompare(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2) /************************************************************** INPUT: Two contexts and two terms. RETURNS: The relation between the two terms with respect to the RPOS ordering: ord_GREATER_THAN if <T1> is greater than <T2>, ord_EQUAL if both terms are equal, ord_SMALLER_THAN if <T2> is greater than <T1> and ord_UNCOMPARABLE otherwise. EFFECT: Variable bindings are considered. CAUTION: The precedence from the order module is used to determine the precedence of symbols! ***************************************************************/ { ord_RESULT result; T1 = cont_Deref(&C1, T1); T2 = cont_Deref(&C2, T2); result = rpos_ContGreaterEqual(C1, T1, C2, T2); if (!ord_IsUncomparable(result)) return result; else if (rpos_ContGreater(C2, T2, C1, T1)) return ord_SmallerThan(); else return ord_UNCOMPARABLE; }
BOOL rpos_ContEqual(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2) /************************************************************** INPUT: Two contexts and two terms. RETURNS: TRUE, if <T1> is equal to <T2> and FALSE otherwise. EFFECT: Variable bindings are considered. ***************************************************************/ { LIST l1, l2; T1 = cont_Deref(&C1, T1); T2 = cont_Deref(&C2, T2); if (!term_EqualTopSymbols(T1, T2)) return FALSE; else if (!term_IsComplex(T1)) return TRUE; else { if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) { l1 = rpos_ContMultisetDifference(C1, T1, C2, T2); if (list_Empty(l1)) return TRUE; else { list_Delete(l1); return FALSE; } } else { /* LEX case */ for (l1 = term_ArgumentList(T1), l2 = term_ArgumentList(T2); !list_Empty(l1) && rpos_ContEqual(C1,list_Car(l1),C2,list_Car(l2)); l1 = list_Cdr(l1), l2 = list_Cdr(l2)); /* empty body */ return list_Empty(l1); /* All arguments were equal */ } } }
ord_RESULT rpos_ContCompareAux(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2, BOOL VarIsConst) /************************************************************** INPUT: Two contexts and two terms. RETURNS: The relation between the two terms with respect to the RPOS ordering: ord_GREATER_THAN if <T1> is greater than <T2>, ord_EQUAL if both terms are equal, ord_SMALLER_THAN if <T2> is greater than <T1> and ord_UNCOMPARABLE otherwise. EFFECT: Variable bindings are considered. If VarIsConst is true variables are interpreted as constants CAUTION: The precedence from the order module is used to determine the precedence of symbols! If <VarIsConst> is set then variables are interpreted as constants with lowest precedence. They are ranked to each other using their variable index. ***************************************************************/ { ord_RESULT result; CONTEXT GlobalC1, GlobalC2; GlobalC1 = C1; GlobalC2 = C2; T1 = cont_Deref(GlobalC1, &C1, T1); T2 = cont_Deref(GlobalC2, &C2, T2); result = rpos_ContGreaterEqual(GlobalC1, C1, T1, GlobalC2, C2, T2, VarIsConst); if (!ord_IsUncomparable(result)) return result; else if (rpos_ContGreaterAux(GlobalC2, C2, T2, GlobalC1, C1, T1, VarIsConst)) return ord_SmallerThan(); else return ord_UNCOMPARABLE; }
ord_RESULT rpos_ContGreaterEqual(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2) /************************************************************** INPUT: Two contexts and two terms. RETURNS: ord_GREATER_THAN if <T1> is greater than <T2> ord_EQUAL if both terms are equal ord_UNCOMPARABLE otherwise. EFFECT: Variable bindings are considered. CAUTION: The precedence from the order module is used to determine the precedence of symbols! ***************************************************************/ { LIST scan; T1 = cont_Deref(&C1, T1); T2 = cont_Deref(&C2, T2); if (term_IsVariable(T1)) { if (term_EqualTopSymbols(T1, T2)) return ord_Equal(); /* T2 is the same variable */ else /* A variable can't be greater than another term */ return ord_Uncomparable(); } else if (term_IsVariable(T2)) { /* T1 isn't a variable */ if (cont_TermContainsSymbol(C1, T1, term_TopSymbol(T2))) return ord_GreaterThan(); else return ord_Uncomparable(); } else if (term_EqualTopSymbols(T1, T2)) { if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) return rpos_ContMulGreaterEqual(C1, T1, C2, T2); else return rpos_ContLexGreaterEqual(C1, T1, C2, T2); } else { if (symbol_PrecedenceGreater(ord_PRECEDENCE, term_TopSymbol(T1), term_TopSymbol(T2))) { /* Different top symbols, symbol of T1 > symbol of T2. */ /* Try if T1 > each argument of T2. */ for (scan = term_ArgumentList(T2); !list_Empty(scan); scan = list_Cdr(scan)) if (!rpos_ContGreater(C1, T1, C2, list_Car(scan))) return ord_Uncomparable(); return ord_GreaterThan(); } else { /* Try to find an argument of T1 that is >= T2 */ for (scan = term_ArgumentList(T1); !list_Empty(scan); scan = list_Cdr(scan)) if (!ord_IsUncomparable(rpos_ContGreaterEqual(C1,list_Car(scan),C2,T2))) return ord_GreaterThan(); /* Argument of T1 >= T2 */ return ord_Uncomparable(); } } }
void cont_TermPrintPrefix(CONTEXT GlobalContext, CONTEXT TermContext, TERM Term) /************************************************************** INPUT: A global context where index variables are bound, a context and a term. RETURNS: none. SUMMARY: Prints the term modulo the context to stdout. CAUTION: Variables of <Term1> are bound in <TermContext1> and the index variables are bound in <GlobalContext1> ***************************************************************/ { Term = cont_Deref(GlobalContext,&TermContext, Term); symbol_Print(term_TopSymbol(Term)); if (term_IsComplex(Term)) { LIST List; putchar('('); for (List = term_ArgumentList(Term); !list_Empty(List); List = list_Cdr(List)) { cont_TermPrintPrefix(GlobalContext, TermContext, list_Car(List)); if (!list_Empty(list_Cdr(List))) putchar(','); } putchar(')'); } }
void cont_TermPrintPrefix(CONTEXT Context, TERM Term) /************************************************************** INPUT: A context and a term. RETURNS: none. SUMMARY: Prints the term modulo the context to stdout. CAUTION: none. ***************************************************************/ { Term = cont_Deref(&Context, Term); symbol_Print(term_TopSymbol(Term)); if (term_IsComplex(Term)) { LIST List; putchar('('); for (List = term_ArgumentList(Term); !list_Empty(List); List = list_Cdr(List)) { cont_TermPrintPrefix(Context, list_Car(List)); if (!list_Empty(list_Cdr(List))) putchar(','); } putchar(')'); } }
SYMBOL cont_TermMaxVar(CONTEXT Context, TERM Term) /********************************************************* INPUT: A context and a term. RETURNS: The maximal variable in <Term> with respect to the bindings in <Context> ********************************************************/ { LIST scan; SYMBOL result; #ifdef CHECK if (!term_IsTerm(Term)) { misc_StartErrorReport(); misc_ErrorReport("\n In cont_TermMaxVar: Input term is corrupted.\n"); misc_FinishErrorReport(); } #endif Term = cont_Deref(&Context,Term); result = symbol_Null(); if (term_IsStandardVariable(Term)) { if (term_TopSymbol(Term) > result) result = term_TopSymbol(Term); } else { for (scan = term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan)) { SYMBOL max = cont_TermMaxVar(Context, list_Car(scan)); if (max > result) result = max; } } return result; }
BOOL cont_TermEqual(CONTEXT GlobalContext1, CONTEXT TermContext1, TERM Term1, CONTEXT GlobalContext2, CONTEXT TermContext2, TERM Term2) /********************************************************* INPUT: Two terms and two local contexts for the terms and two global contexts RETURNS: TRUE iff the two terms are equal, where variables are interpreted with respect to the bindings in the contexts. CAUTION: Variables of <Term1> and <Term2> are bound in <TermContext1> and <TermContext2> respectively and the index variables are bound in <GlobalContext1> and <GlobalContext2> respectively. ********************************************************/ { #ifdef CHECK if (!(term_IsTerm(Term1) && term_IsTerm(Term2))) { misc_StartErrorReport(); misc_ErrorReport("\n In cont_TermEqual: Input terms are corrupted.\n"); misc_FinishErrorReport(); } #endif Term1 = cont_Deref(GlobalContext1,&TermContext1,Term1); Term2 = cont_Deref(GlobalContext2,&TermContext2,Term2); if (!term_EqualTopSymbols(Term1, Term2)) return FALSE; else if (term_ArgumentList(Term1)) { LIST Scan1, Scan2; for (Scan1=term_ArgumentList(Term1), Scan2=term_ArgumentList(Term2); list_Exist(Scan1) && list_Exist(Scan2); Scan1=list_Cdr(Scan1), Scan2=list_Cdr(Scan2)) if (!cont_TermEqual(GlobalContext1, TermContext1,list_Car(Scan1), GlobalContext2, TermContext2,list_Car(Scan2))) return FALSE; return (list_Empty(Scan1) ? list_Empty(Scan2) : FALSE); } else return TRUE; }
NAT cont_TermSize(CONTEXT Context, TERM Term) /********************************************************* INPUT: A context and a term. RETURNS: The number of symbols in <Term> with respect to the bindings in <Context> ********************************************************/ { NAT result; LIST scan; Term = cont_Deref(&Context, Term); result = 1; for (scan = term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan)) result += cont_TermSize(Context, list_Car(scan)); return result; }
NAT cont_TermSize(CONTEXT GlobalContext, CONTEXT TermContext, TERM Term) /********************************************************* INPUT: A global context where index variables are bound a context and a term. RETURNS: The number of symbols in <Term> with respect to the bindings in <Context> CAUTION: Variables of <Term1> are bound in <TermContext1> and the index variables are bound in <GlobalContext1> ********************************************************/ { NAT result; LIST scan; Term = cont_Deref(GlobalContext, &TermContext, Term); result = 1; for (scan = term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan)) result += cont_TermSize(GlobalContext, TermContext, list_Car(scan)); return result; }
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 int kbo_ContCompVarCondAndWeightIntern(CONTEXT Context, TERM Term, int Index) /************************************************************** INPUT: EFFECT: ***************************************************************/ { int Weight; Weight = 0; Term = cont_Deref(&Context,Term); if (term_IsStandardVariable(Term)) { ord_VARCOUNT[term_TopSymbol(Term)][Index]++; Weight += kbo_MINWEIGHT; } else { LIST Scan; Weight += symbol_Weight(term_TopSymbol(Term)); for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan)) Weight += kbo_ContCompVarCondAndWeightIntern(Context, list_Car(Scan), Index); } return Weight; }
static BOOL kbo_ContGreaterCompareStruc(CONTEXT Context1, TERM Term1, CONTEXT Context2, TERM Term2) /************************************************************** INPUT: Two contexts and two terms where the kbo-variable condition for <Term1> and <Term2> is satisfied as well as the weight difference between the terms is zero. RETURNS: TRUE if Term1 is greater than Term2. The Terms are interpreted with respect to the contexts. CAUTION: The precedence from the order module is used to determine the precedence of symbols! ***************************************************************/ { LIST Scan1,Scan2; SYMBOL Top1,Top2; Term1 = cont_Deref(&Context1,Term1); Term2 = cont_Deref(&Context2,Term2); Top1 = term_TopSymbol(Term1); Top2 = term_TopSymbol(Term2); if (symbol_IsStandardVariable(Top1)) { if (symbol_IsStandardVariable(Top2)) return FALSE; else return FALSE; } else if (symbol_IsStandardVariable(Top2) || symbol_PrecedenceGreater(ord_PRECEDENCE, Top1, Top2)) return TRUE; else if (Top1 == Top2) { int RecWeightDiff; BOOL T1VarCond, T2VarCond; TERM RecTerm1,RecTerm2; Scan1 = term_ArgumentList(Term1); Scan2 = term_ArgumentList(Term2); if (symbol_HasProperty(Top1,ORDRIGHT)) { int i; for (i = symbol_Arity(Top1); i > 0 && cont_TermEqual(Context1,list_NthElement(Scan1,i), Context2,list_NthElement(Scan2,i)); i--); if (i > 0) { RecTerm1 = cont_Deref(&Context1,list_NthElement(Scan1,i)); RecTerm2 = cont_Deref(&Context2,list_NthElement(Scan2,i)); } else return FALSE; } else { while (!list_Empty(Scan1) && cont_TermEqual(Context1,list_Car(Scan1),Context2,list_Car(Scan2))) { Scan1 = list_Cdr(Scan1); Scan2 = list_Cdr(Scan2); } if (list_Empty(Scan1)) /* Implies that list_Empty(Scan2) */ return FALSE; else { RecTerm1 = cont_Deref(&Context1,list_Car(Scan1)); RecTerm2 = cont_Deref(&Context2,list_Car(Scan2)); } } RecWeightDiff = kbo_ContCompVarCondAndWeight(Context1,RecTerm1,&T1VarCond, Context2,RecTerm2,&T2VarCond); if (T1VarCond) { if (RecWeightDiff > 0) return TRUE; else if (RecWeightDiff == 0) return kbo_ContGreaterCompareStruc(Context1, RecTerm1, Context2, RecTerm2); } } return FALSE; }
ord_RESULT rpos_ContGreaterEqual(CONTEXT GlobalC1, CONTEXT TermC1, TERM T1, CONTEXT GlobalC2, CONTEXT TermC2, TERM T2, BOOL VarIsConst) /************************************************************** INPUT: Two contexts and two terms. RETURNS: ord_GREATER_THAN if <T1> is greater than <T2> ord_EQUAL if both terms are equal ord_UNCOMPARABLE otherwise. EFFECT: Variable bindings are considered. CAUTION: The precedence from the order module is used to determine the precedence of symbols! If <VarIsConst> is set then variables are interpreted as constants with lowest precedence. They are ranked to each other using their variable index. ASSUMPTION: All index variables of <T1> and <T2> are bound in <GlobalC1> and <GlobalCt2>, respectively ***************************************************************/ { LIST scan; T1 = cont_Deref(GlobalC1, &TermC1, T1); T2 = cont_Deref(GlobalC2, &TermC2, T2); if (term_IsVariable(T1)) { if (term_EqualTopSymbols(T1, T2)) return ord_Equal(); /* T2 is the same variable */ else /* A variable can't be greater than another term */ return ord_Uncomparable(); } else if (term_IsVariable(T2)) { /* T1 isn't a variable */ if (cont_TermContainsSymbol(GlobalC1, TermC1, T1, term_TopSymbol(T2))) return ord_GreaterThan(); else return ord_Uncomparable(); } else if (term_EqualTopSymbols(T1, T2)) { if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) return rpos_ContMulGreaterEqual(GlobalC1, TermC1, T1, GlobalC2, TermC2, T2, VarIsConst); else return rpos_ContLexGreaterEqual(GlobalC1, TermC1, T1, GlobalC2, TermC2, T2, VarIsConst); } else { if (symbol_PrecedenceGreater(ord_PRECEDENCE, term_TopSymbol(T1), term_TopSymbol(T2))) { /* Different top symbols, symbol of T1 > symbol of T2. */ /* Try if T1 > each argument of T2. */ for (scan = term_ArgumentList(T2); !list_Empty(scan); scan = list_Cdr(scan)) if (!rpos_ContGreaterAux(GlobalC1, TermC1, T1, GlobalC2, TermC2, list_Car(scan), VarIsConst)) return ord_Uncomparable(); return ord_GreaterThan(); } else { /* Try to find an argument of T1 that is >= T2 */ for (scan = term_ArgumentList(T1); !list_Empty(scan); scan = list_Cdr(scan)) if (!ord_IsUncomparable(rpos_ContGreaterEqual(GlobalC1, TermC1,list_Car(scan), GlobalC2, TermC2,T2, VarIsConst))) return ord_GreaterThan(); /* Argument of T1 >= T2 */ return ord_Uncomparable(); } } }