blob: 5f00e80b67333c50d5c5eaef5b9654b0976b35d9 [file] [log] [blame]
/**************************************************************/
/* ********************************************************** */
/* * * */
/* * INTERFACE FOR ALL ORDERING IMPLEMENTATIONS * */
/* * * */
/* * $Module: ORDER * */
/* * * */
/* * Copyright (C) 1997, 1998, 1999, 2000, 2001 * */
/* * MPI fuer Informatik * */
/* * * */
/* * This program is free software; you can redistribute * */
/* * it and/or modify it under the terms of the GNU * */
/* * General Public License as published by the Free * */
/* * Software Foundation; either version 2 of the License, * */
/* * or (at your option) any later version. * */
/* * * */
/* * This program is distributed in the hope that it will * */
/* * be useful, but WITHOUT ANY WARRANTY; without even * */
/* * the implied warranty of MERCHANTABILITY or FITNESS * */
/* * FOR A PARTICULAR PURPOSE. See the GNU General Public * */
/* * License for more details. * */
/* * * */
/* * You should have received a copy of the GNU General * */
/* * Public License along with this program; if not, write * */
/* * to the Free Software Foundation, Inc., 59 Temple * */
/* * Place, Suite 330, Boston, MA 02111-1307 USA * */
/* * * */
/* * * */
/* $Revision$ * */
/* $State$ * */
/* $Date$ * */
/* $Author$ * */
/* * * */
/* * Contact: * */
/* * Christoph Weidenbach * */
/* * MPI fuer Informatik * */
/* * Stuhlsatzenhausweg 85 * */
/* * 66123 Saarbruecken * */
/* * Email: weidenb@mpi-sb.mpg.de * */
/* * Germany * */
/* * * */
/* ********************************************************** */
/**************************************************************/
/* $RCSfile$ */
#include "flags.h"
#include "order.h"
#include "kbo.h"
#include "rpos.h"
#include "symbol.h"
NAT ord_VARCOUNT[symbol__MAXSTANDARDVAR][2];
PRECEDENCE ord_PRECEDENCE;
static ord_RESULT ord_CheckDomPred(TERM T1, TERM T2, PRECEDENCE P)
/**************************************************************
INPUT: Two terms and a precedence.
RETURNS: An ordering result with respect to a possible domination
of leading predicates in <T1> or <T2>.
***************************************************************/
{
if ((term_IsAtom(T1) && symbol_HasProperty(term_TopSymbol(T1), DOMPRED)) ||
(term_IsAtom(T2) && symbol_HasProperty(term_TopSymbol(T2), DOMPRED))) {
if (term_IsAtom(T1)) {
if (term_IsAtom(T2)) {
if (symbol_HasProperty(term_TopSymbol(T1), DOMPRED) &&
(!symbol_HasProperty(term_TopSymbol(T2), DOMPRED) ||
symbol_PrecedenceGreater(P,term_TopSymbol(T1),term_TopSymbol(T2))))
return ord_GREATER_THAN;
if (!symbol_HasProperty(term_TopSymbol(T1), DOMPRED) ||
term_TopSymbol(T1) != term_TopSymbol(T2))
return ord_SMALLER_THAN;
/* If the top symbols are equal, do the normal comparison */
} else {
/* T1 is an atom, T2 is not, so T1 is greater */
return ord_GREATER_THAN;
}
} else {
/* T1 is not an atom, so T2 must be an atom */
return ord_SMALLER_THAN;
}
}
return ord_UNCOMPARABLE;
}
ord_RESULT ord_Compare(TERM T1, TERM T2, FLAGSTORE FlagStore, PRECEDENCE P)
/**************************************************************
INPUT:
RETURNS:
***************************************************************/
{
ord_RESULT Aux;
#ifdef CHECK
if (fol_IsEquality(T1) || fol_IsEquality(T2)) {
misc_StartErrorReport();
misc_ErrorReport("\n In ord_Compare:");
misc_ErrorReport("\n Illegal input. One input term is an equality.");
misc_FinishErrorReport();
}
#endif
Aux = ord_CheckDomPred(T1, T2, P);
if (Aux != ord_UNCOMPARABLE)
return Aux;
else {
ord_PRECEDENCE = P;
switch(flag_GetFlagValue(FlagStore, flag_ORD)) {
case flag_ORDKBO: return kbo_Compare(T1, T2); break;
case flag_ORDRPOS: return rpos_Compare(T1, T2); break;
default:
misc_StartErrorReport();
misc_ErrorReport("\n In ord_Compare:");
misc_ErrorReport("\n Illegal ordering type.");
misc_FinishErrorReport();
}
}
return ord_UNCOMPARABLE;
}
BOOL ord_CompareEqual(TERM T1, TERM T2, FLAGSTORE Flags)
/**************************************************************
INPUT: Two terms and a flag store.
RETURNS: TRUE, iff the two terms are equal with respect to the
reduction ordering selected by the 'flag_ORD' flag.
***************************************************************/
{
switch(flag_GetFlagValue(Flags, flag_ORD)) {
case flag_ORDKBO: return term_Equal(T1, T2); break;
case flag_ORDRPOS: return rpos_Equal(T1, T2); break;
default:
misc_StartErrorReport();
misc_ErrorReport("\n In ord_Compare: Illegal ordering type.");
misc_FinishErrorReport();
return FALSE; /* unreachable code ... */
}
}
ord_RESULT ord_ContCompare(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2,
FLAGSTORE FlagStore, PRECEDENCE P)
{
ord_RESULT Aux;
#ifdef CHECK
if (fol_IsEquality(T1) || fol_IsEquality(T2)) {
misc_StartErrorReport();
misc_ErrorReport("\n In ord_ContCompare:");
misc_ErrorReport("\n Illegal input. One input term is an equality.");
misc_FinishErrorReport();
}
#endif
Aux = ord_CheckDomPred(T1, T2, P);
if (Aux != ord_UNCOMPARABLE)
return Aux;
else {
ord_PRECEDENCE = P;
switch(flag_GetFlagValue(FlagStore, flag_ORD)) {
case flag_ORDKBO: return kbo_ContCompare(C1, T1, C2, T2); break;
case flag_ORDRPOS: return rpos_ContCompare(C1, T1, C2, T2); break;
default:
misc_StartErrorReport();
misc_ErrorReport("\n In ord_ContCompare:");
misc_ErrorReport("\n Illegal ordering type.");
misc_FinishErrorReport();
}
}
return ord_UNCOMPARABLE;
}
BOOL ord_ContGreater(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2,
FLAGSTORE FlagStore, PRECEDENCE P)
{
ord_RESULT Aux;
#ifdef CHECK
if (fol_IsEquality(T1) || fol_IsEquality(T2)) {
misc_StartErrorReport();
misc_ErrorReport("\n In ord_ContGreater:");
misc_ErrorReport("\n Illegal input. One input term is an equality.");
misc_FinishErrorReport();
}
#endif
Aux = ord_CheckDomPred(T1, T2, P);
if (Aux != ord_UNCOMPARABLE)
return (Aux == ord_GREATER_THAN);
else {
ord_PRECEDENCE = P;
switch(flag_GetFlagValue(FlagStore, flag_ORD)) {
case flag_ORDKBO: return kbo_ContGreater(C1, T1, C2, T2); break;
case flag_ORDRPOS: return rpos_ContGreater(C1, T1, C2, T2); break;
default:
misc_StartErrorReport();
misc_ErrorReport("\n In ord_ContGreater:");
misc_ErrorReport("\n Illegal ordering type.");
misc_FinishErrorReport();
}
}
return FALSE; /* This line is never reached ... */
}
ord_RESULT ord_Not(ord_RESULT Result)
/**************************************************************
INPUT: An ord_RESULT
RETURNS: The negation with respect to argument switching.
***************************************************************/
{
if (Result == ord_UNCOMPARABLE || Result == ord_EQUAL)
return Result;
if (Result == ord_GREATER_THAN)
return ord_SMALLER_THAN;
return ord_GREATER_THAN;
}
void ord_Print(ord_RESULT Result)
/**************************************************************
INPUT: An ord_Result.
RETURNS: None, prints the Result as a string to stdout.
***************************************************************/
{
switch(Result) {
case ord_UNCOMPARABLE: fputs(" uncomparable ",stdout); break;
case ord_EQUAL: fputs(" equal ",stdout); break;
case ord_GREATER_THAN: fputs(" greater than ",stdout); break;
case ord_SMALLER_THAN: fputs(" smaller than ",stdout); break;
default: fputs(" Nonsense! ",stdout);
}
}
ord_RESULT ord_LiteralCompare(TERM Lit1, BOOL Orient1, TERM Lit2, BOOL Orient2,
BOOL Check, FLAGSTORE FlagStore,
PRECEDENCE Precedence)
/*********************************************************
INPUT: Two term literals and two flags indicating whether these
two literals are oriented equalities.
Additionally a check flag that indicates whether
the orientation flags are sufficient or necessary and sufficient:
If Check=TRUE then if flag is FALSE it is interpreted that it is not
known whether the (possible) equation can be oriented oriented.
However, if flag is TRUE we assume that it is oriented.
A flag store.
A precedence.
RETURNS: The result if these literals are compared with
respect to the ordering. Dependent on their sign, the literals
are compared as multiset of their topsymbol terms,
where any literal is considered to be an equation
and non equational literals are considered to be
equations with the artificial, non-existent, minimal
constant tt.
EFFECT: The arguments of the literals are possibly, destructively flipped.
**********************************************************/
{
ord_RESULT result,auxResult,AuxRl1r2,AuxRr1r2,AuxRr1l2,Comp1,Comp2;
BOOL pos1,pos2;
pos1 = pos2 = TRUE;
Comp1 = Comp2 = result = ord_UNCOMPARABLE;
if (symbol_Equal(term_TopSymbol(Lit1),fol_Not())) {
Lit1 = term_FirstArgument(Lit1);
pos1 = FALSE;
}
if (symbol_Equal(term_TopSymbol(Lit2),fol_Not())) {
Lit2 = term_FirstArgument(Lit2);
pos2 = FALSE;
}
if (fol_IsEquality(Lit1)) { /* Real equation */
if (fol_IsEquality(Lit2)) {
TERM l1,r1,l2,r2,aux;
l1 = term_FirstArgument(Lit1);
r1 = term_SecondArgument(Lit1);
l2 = term_FirstArgument(Lit2);
r2 = term_SecondArgument(Lit2);
if (Orient1 ||
(Check &&
((Comp1 = ord_Compare(l1,r1,FlagStore,Precedence)) == ord_GREATER_THAN ||
Comp1 == ord_SMALLER_THAN))) {
if (Comp1 == ord_SMALLER_THAN) {
aux = l1; l1 = r1; r1 = aux;
}
if (Orient2 ||
(Check &&
((Comp2 = ord_Compare(l2,r2,FlagStore,Precedence))==ord_GREATER_THAN ||
Comp2 == ord_SMALLER_THAN))) {
/* Both equations are oriented */
if (Comp2 == ord_SMALLER_THAN) {
aux = l2; l2 = r2; r2 = aux;
}
result = ord_Compare(l1,l2, FlagStore, Precedence);
if (result == ord_EQUAL) {
if (pos1) {
if (pos2)
return ord_Compare(r1,r2, FlagStore, Precedence);
else
return ord_SMALLER_THAN;
}
else
if (pos2)
return ord_GREATER_THAN;
else
return ord_Compare(r1,r2, FlagStore, Precedence);
}
return result;
}
else { /* Lit2 is not oriented equation */
if (term_Equal(l1,l2)) {
result = ord_Compare(r1,r2, FlagStore, Precedence);
if (result == ord_EQUAL) {
if (pos1 && !pos2)
return ord_SMALLER_THAN;
else
if (!pos1 && pos2)
return ord_GREATER_THAN;
}
return result;
}
if (term_Equal(l1,r2)) {
result = ord_Compare(r1,l2, FlagStore, Precedence);
if (result == ord_EQUAL) {
if (pos1 && !pos2)
return ord_SMALLER_THAN;
else
if (!pos1 && pos2)
return ord_GREATER_THAN;
}
return result;
}
result = ord_Compare(l1,l2, FlagStore, Precedence);
AuxRl1r2 = ord_Compare(l1,r2, FlagStore, Precedence);
if (result == AuxRl1r2)
return result;
AuxRr1r2 = ord_Compare(r1,r2, FlagStore, Precedence);
if (result == AuxRr1r2)
return result;
if (AuxRl1r2 == AuxRr1r2 && AuxRl1r2 == ord_SMALLER_THAN)
return ord_SMALLER_THAN;
AuxRr1l2 = ord_Compare(r1,l2, FlagStore, Precedence);
if (result == AuxRr1l2 && result == ord_SMALLER_THAN)
return ord_SMALLER_THAN;
return ord_UNCOMPARABLE;
}
}
else /* Lit1 is unorientable equation */
if (Orient2 ||
(Check &&
((Comp2 = ord_Compare(term_FirstArgument(Lit2),
term_SecondArgument(Lit2),
FlagStore, Precedence) == ord_GREATER_THAN) ||
Comp2 == ord_SMALLER_THAN))) { /* Lit2 is orientable equation */
if (Comp2 == ord_SMALLER_THAN) {
aux = l2; l2 = r2; r2 = aux;
}
if (term_Equal(l1,l2)) {
result = ord_Compare(r1,r2, FlagStore, Precedence);
if (result == ord_EQUAL) {
if (pos1 && !pos2)
return ord_SMALLER_THAN;
else
if (!pos1 && pos2)
return ord_GREATER_THAN;
}
return result;
}
if (term_Equal(r1,l2)) {
result = ord_Compare(l1,r2, FlagStore, Precedence);
if (result == ord_EQUAL) {
if (pos1 && !pos2)
return ord_SMALLER_THAN;
else
if (!pos1 && pos2)
return ord_GREATER_THAN;
}
return result;
}
result = ord_Compare(l1,l2, FlagStore, Precedence);
AuxRr1l2 = ord_Compare(r1,l2, FlagStore, Precedence);
if (result == AuxRr1l2)
return result;
AuxRr1r2 = ord_Compare(r1,r2, FlagStore, Precedence);
if (result == AuxRr1r2)
return result;
if (AuxRr1l2 == AuxRr1r2 && AuxRr1l2 == ord_GREATER_THAN)
return ord_GREATER_THAN;
AuxRl1r2 = ord_Compare(l1,r2, FlagStore, Precedence);
if (result == AuxRl1r2 && result == ord_GREATER_THAN)
return ord_GREATER_THAN;
return ord_UNCOMPARABLE;
}
else { /* Both literals are unorientable equations */
if (term_Equal(l1,l2)) {
result = ord_Compare(r1,r2, FlagStore, Precedence);
if (result == ord_EQUAL) {
if (pos1 && !pos2)
return ord_SMALLER_THAN;
else if (!pos1 && pos2)
return ord_GREATER_THAN;
}
return result;
}
if (term_Equal(r1,l2)) {
result = ord_Compare(l1,r2, FlagStore, Precedence);
if (result == ord_EQUAL) {
if (pos1 && !pos2)
return ord_SMALLER_THAN;
else if (!pos1 && pos2)
return ord_GREATER_THAN;
}
return result;
}
if (term_Equal(l1,r2)) {
result = ord_Compare(r1,l2, FlagStore, Precedence);
if (result == ord_EQUAL) {
if (pos1 && !pos2)
return ord_SMALLER_THAN;
else if (!pos1 && pos2)
return ord_GREATER_THAN;
}
return result;
}
if (term_Equal(r1,r2)) {
result = ord_Compare(l1,l2, FlagStore, Precedence);
if (result == ord_EQUAL) {
if (pos1 && !pos2)
return ord_SMALLER_THAN;
else if (!pos1 && pos2)
return ord_GREATER_THAN;
}
return result;
}
result = ord_Compare(l1,l2, FlagStore, Precedence);
if (result == ord_UNCOMPARABLE) {
result = ord_Compare(l1,r2, FlagStore, Precedence);
if (result == ord_UNCOMPARABLE) {
if (ord_Compare(r1,l2, FlagStore, Precedence) == ord_GREATER_THAN &&
ord_Compare(r1,r2, FlagStore, Precedence) == ord_GREATER_THAN)
return ord_GREATER_THAN;
return ord_UNCOMPARABLE;
}
if (result == ord_GREATER_THAN) {
if (ord_Compare(r1,l2, FlagStore, Precedence) == ord_GREATER_THAN)
return ord_GREATER_THAN;
return ord_UNCOMPARABLE;
}
if (result == ord_SMALLER_THAN) {
if (ord_Compare(r1,l2, FlagStore, Precedence) == ord_SMALLER_THAN ||
ord_Compare(r1,r2, FlagStore, Precedence) == ord_SMALLER_THAN)
return ord_SMALLER_THAN;
return ord_UNCOMPARABLE;
}
}
if (result == ord_GREATER_THAN) {
if ((result = ord_Compare(l1,r2,FlagStore,Precedence)) == ord_GREATER_THAN ||
(auxResult = ord_Compare(r1,r2,FlagStore,Precedence)) == ord_GREATER_THAN)
return ord_GREATER_THAN;
if (result == ord_UNCOMPARABLE || auxResult == ord_UNCOMPARABLE)
return ord_UNCOMPARABLE;
return ord_SMALLER_THAN;
}
if (result == ord_SMALLER_THAN) {
if ((result = ord_Compare(r1,l2,FlagStore,Precedence)) == ord_SMALLER_THAN ||
(auxResult = ord_Compare(r1,r2,FlagStore,Precedence)) == ord_SMALLER_THAN)
return ord_SMALLER_THAN;
if (result == ord_UNCOMPARABLE || auxResult == ord_UNCOMPARABLE)
return ord_UNCOMPARABLE;
return ord_GREATER_THAN;
}
}
}
else {/* Second Atom is not an equation */
/* They can't be equal ! */
result = ord_Compare(term_FirstArgument(Lit1),Lit2,FlagStore,Precedence);
if (!Orient1 && result != ord_GREATER_THAN) {
auxResult = ord_Compare(term_SecondArgument(Lit1),Lit2,FlagStore,Precedence);
if (auxResult == ord_GREATER_THAN)
result = ord_GREATER_THAN;
else if (result != auxResult)
result = ord_UNCOMPARABLE;
}
}
}
else /* First Atom is not an equation */
/* They can't be equal ! */
if (fol_IsEquality(Lit2)) {
result = ord_Compare(Lit1,term_FirstArgument(Lit2), FlagStore, Precedence);
if (!Orient2 && result != ord_SMALLER_THAN) {
auxResult = ord_Compare(Lit1,term_SecondArgument(Lit2),FlagStore,Precedence);
if (auxResult == ord_SMALLER_THAN)
result = ord_SMALLER_THAN;
else if (result != auxResult)
result = ord_UNCOMPARABLE;
}
} else { /* None of the atoms is an equation */
result = ord_Compare(Lit1,Lit2, FlagStore, Precedence);
if (result == ord_EQUAL) {
if (pos1 && !pos2)
result = ord_SMALLER_THAN;
else if (!pos1 && pos2)
result = ord_GREATER_THAN;
}
}
return result;
}