static ord_RESULT rpos_LexGreaterEqual(TERM T1, TERM T2, BOOL VarIsConst) /************************************************************** INPUT: Two terms with equal top symbols and lexicographic status. RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>, ord_EQUAL if both terms are equal and ord_UNCOMPARABLE otherwise. CAUTION: 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; LIST l1, l2, scan1, scan2; if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) { l1 = list_Reverse(term_ArgumentList(T1)); /* Create new lists */ l2 = list_Reverse(term_ArgumentList(T2)); } else { l1 = term_ArgumentList(T1); l2 = term_ArgumentList(T2); } /* First ignore equal arguments */ result = ord_Equal(); for (scan1 = l1, scan2 = l2; !list_Empty(scan1); scan1 = list_Cdr(scan1), scan2 = list_Cdr(scan2)) { result = rpos_GreaterEqual(list_Car(scan1), list_Car(scan2), VarIsConst); if (!ord_IsEqual(result)) break; } if (ord_IsEqual(result)) /* All arguments are equal, so the terms */ /* empty */; /* are equal with respect to RPOS */ else if (ord_IsGreaterThan(result)) { /* Check if T1 > each remaining argument of T2 */ for (scan2 = list_Cdr(scan2); !list_Empty(scan2) && rpos_Greater(T1, list_Car(scan2), VarIsConst); scan2 = list_Cdr(scan2)); /* Empty body */ if (list_Empty(scan2)) result = ord_GreaterThan(); else result = ord_Uncomparable(); } else { /* Argument of T1 was not >= argument of T2. */ /* Try to find an argument of T1 that is >= T2 */ for (scan1 = list_Cdr(scan1), result = ord_Uncomparable(); !list_Empty(scan1) && !ord_IsGreaterThan(result); scan1 = list_Cdr(scan1)) { if (!ord_IsUncomparable(rpos_GreaterEqual(list_Car(scan1), T2, VarIsConst))) result = ord_GreaterThan(); } } if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) { list_Delete(l1); /* Delete the lists create above */ list_Delete(l2); } return result; }
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 */ } } }
BOOL rpos_Equal(TERM T1, TERM T2) /************************************************************** INPUT: Two terms. RETURNS: TRUE, if <T1> is equal to <T2> and FALSE otherwise. ***************************************************************/ { LIST l1, l2; if (!term_EqualTopSymbols(T1, T2)) return FALSE; else if (!term_IsComplex(T1)) /* Equal variable or constant */ return TRUE; else { if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) { /* MUL case */ l1 = rpos_MultisetDifference(T1, 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_Equal(list_Car(l1), list_Car(l2)); l1 = list_Cdr(l1), l2 = list_Cdr(l2)) /* empty */; return list_Empty(l1); /* All arguments were equal */ } } }
ord_RESULT rpos_GreaterEqual(TERM T1, TERM T2, BOOL VarIsConst) /************************************************************** INPUT: Two terms. RETURNS: ord_GREATER_THAN if <T1> is greater than <T2> ord_EQUAL if both terms are equal ord_UNCOMPARABLE otherwise. 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. ***************************************************************/ { LIST scan; if (term_IsVariable(T1)) { if (term_EqualTopSymbols(T1, T2)) return ord_Equal(); /* T2 is the same variable */ else if(VarIsConst && term_IsVariable(T2)) { if(term_TopSymbol(T1) > term_TopSymbol(T2)) return ord_GreaterThan(); else return ord_Uncomparable(); } else /* A variable can't be greater than another term */ return ord_Uncomparable(); } else if (!VarIsConst && term_IsVariable(T2)) { /* T1 isn't a variable */ if (term_ContainsSymbol(T1, term_TopSymbol(T2))) return ord_GreaterThan(); else return ord_Uncomparable(); } else if(VarIsConst && term_IsVariable(T2)){ return ord_GreaterThan(); } else if (term_EqualTopSymbols(T1, T2)) { if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) return rpos_MulGreaterEqual(T1, T2, VarIsConst); else return rpos_LexGreaterEqual(T1, 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_Greater(T1, 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_GreaterEqual(list_Car(scan), T2, VarIsConst))) return ord_GreaterThan(); /* Argument of T1 >= T2 */ 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(); } } }
static ord_RESULT rpos_ContLexGreaterEqual(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2) /************************************************************** INPUT: Two contexts and two terms with equal top symbols and lexicographic status. RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>, ord_EQUAL if both terms are equal and ord_UNCOMPARABLE otherwise. EFFECT: Variable bindings are considered. ***************************************************************/ { ord_RESULT result; LIST l1, l2, scan1, scan2; /* Don't apply bindings at top level, since that happened */ /* in rpos_ContGreaterEqual */ if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) { l1 = list_Reverse(term_ArgumentList(T1)); /* Create new lists */ l2 = list_Reverse(term_ArgumentList(T2)); } else { l1 = term_ArgumentList(T1); l2 = term_ArgumentList(T2); } /* First ignore equal arguments */ result = ord_Equal(); for (scan1 = l1, scan2 = l2; !list_Empty(scan1); scan1 = list_Cdr(scan1), scan2 = list_Cdr(scan2)) { result = rpos_ContGreaterEqual(C1, list_Car(scan1), C2, list_Car(scan2)); if (!ord_IsEqual(result)) break; } if (ord_IsEqual(result)) /* All arguments are equal, so the terms */ /* empty */; /* are equal with respect to RPOS */ else if (ord_IsGreaterThan(result)) { /* Check if T1 > each remaining argument of T2 */ for (scan2 = list_Cdr(scan2); !list_Empty(scan2) && rpos_ContGreater(C1, T1, C2, list_Car(scan2)); scan2 = list_Cdr(scan2)); /* Empty body */ if (list_Empty(scan2)) result = ord_GreaterThan(); else result = ord_Uncomparable(); } else { /* Argument of T1 was not >= argument of T2. */ /* Try to find an argument of T1 that is >= T2 */ for (scan1 = list_Cdr(scan1), result = ord_Uncomparable(); !list_Empty(scan1) && !ord_IsGreaterThan(result); scan1 = list_Cdr(scan1)) { if (!ord_IsUncomparable(rpos_ContGreaterEqual(C1,list_Car(scan1),C2,T2))) result = ord_GreaterThan(); } } if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) { list_Delete(l1); /* Delete the lists create above */ list_Delete(l2); } return result; }
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; }
static ord_RESULT kbo_CompareStruc(TERM Term1, TERM Term2, int WeightDiff) /************************************************************** INPUT: Two terms where the kbo-variable condition for <Term1> and <Term2> is satisfied and <WeightDiff> is the kbo weight difference between <Term1> and <Term2> RETURNS: ord_UNCOMPARABLE, if Term1 and Term2 are uncomparable ord_EQUAL, if Term1 and Term2 are equal ord_GREATER_THAN, if Term1 is greater than Term2 CAUTION: The precedence from the order module is used to determine the precedence of symbols! ***************************************************************/ { LIST Scan1,Scan2; SYMBOL Top1,Top2; Top1 = term_TopSymbol(Term1); Top2 = term_TopSymbol(Term2); if (WeightDiff > 0) return ord_GREATER_THAN; else if (WeightDiff == 0) { if (symbol_IsStandardVariable(Top1)) { if (symbol_IsStandardVariable(Top2)) return ord_EQUAL; else return ord_UNCOMPARABLE; } else if (symbol_IsStandardVariable(Top2) || symbol_PrecedenceGreater(ord_PRECEDENCE, Top1, Top2)) return ord_GREATER_THAN; 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 && term_Equal(list_NthElement(Scan1,i),list_NthElement(Scan2,i)); i--); if (i > 0) { RecTerm1 = (TERM)list_NthElement(Scan1,i); RecTerm2 = (TERM)list_NthElement(Scan2,i); } else return ord_EQUAL; } else { while (!list_Empty(Scan1) && term_Equal(list_Car(Scan1),list_Car(Scan2))) { Scan1 = list_Cdr(Scan1); Scan2 = list_Cdr(Scan2); } if (list_Empty(Scan1)) /* Implies that list_Empty(Scan2) */ return ord_EQUAL; else { RecTerm1 = (TERM)list_Car(Scan1); RecTerm2 = (TERM)list_Car(Scan2); } } RecWeightDiff = kbo_CompVarCondAndWeight(RecTerm1,&T1VarCond,RecTerm2,&T2VarCond); if (RecWeightDiff >= 0 && T1VarCond) return kbo_CompareStruc(RecTerm1, RecTerm2, RecWeightDiff); else return ord_UNCOMPARABLE; } else return ord_UNCOMPARABLE; } else return ord_UNCOMPARABLE; return ord_UNCOMPARABLE; }
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(); } } }