#ifdef DOC_BUILD_INTERNAL
#endif
#include "kbo.h"
KBOSTATE kbo_Init(TERMSTATE Termstate, SYMBOL minconst, unsigned Vars, unsigned Minweight)
{
  KBOSTATE kstate;
  MEMORY mem;
  mem = term_GetMemory(Termstate);
  kstate = (KBOSTATE)memory_Malloc(mem, sizeof(KBOSTATE_NODE));
  kstate->minweight = Minweight;
  kstate->varcount = memory_Malloc(mem, 2 * Vars * sizeof(unsigned) + 1);
  kstate->varcount[0] = Vars;
  kstate->varcount++;
  kstate->termstate = Termstate;
  kstate->minconst = minconst;
  return kstate;
}
void kbo_Free(KBOSTATE Kstate)
{
  MEMORY mem;
  mem = term_GetMemory(kbo_GetTermstate(Kstate));
  Kstate->varcount--;
  memory_Free(mem, Kstate->varcount, 2 * Kstate->varcount[0] * sizeof(unsigned) + 1);
  memory_Free(mem, Kstate, sizeof(KBOSTATE_NODE));
}
void kbo_AdjustMaxVars(KBOSTATE Kstate, unsigned Maxvar)
{
  if (Maxvar > Kstate->varcount[-1]) {
    Kstate->varcount--;
    memory_Free(term_GetMemory(kbo_GetTermstate(Kstate)), Kstate->varcount, 2 * Kstate->varcount[0] * sizeof(unsigned) + 1);
    Maxvar *= 2;
    Kstate->varcount = memory_Malloc(term_GetMemory(kbo_GetTermstate(Kstate)), 2 * Maxvar * sizeof(unsigned) + 1);
    Kstate->varcount[0] = Maxvar;
    Kstate->varcount++;
  }
}
kbo_RESULT kbo_Not(kbo_RESULT Result)
{
  if (Result == kbo_UNCOMPARABLE || Result == kbo_EQUAL)
    return Result;
  if (Result == kbo_GREATER_THAN)
    return kbo_SMALLER_THAN;
  return kbo_GREATER_THAN;
}
SYMBOL kbo_GetMinConstant(KBOSTATE Kstate)
{
  return Kstate->minconst;
}
void kbo_SetMinConstant(KBOSTATE Kstate, SYMBOL MinConstant)
{
  Kstate->minconst = MinConstant;
}
void kbo_SetVarcount(unsigned *Varcount, SYMBOL Var, unsigned Id, unsigned Value)
{
  Varcount[(Var<<1) + Id] = Value;
}
void kbo_IncreaseVarcount(unsigned *Varcount, SYMBOL Var, unsigned Id)
{
  Varcount[(Var<<1) + Id]++;
}
unsigned kbo_GetVarcount(unsigned *Varcount, SYMBOL Var, unsigned Id)
{
  return Varcount[(Var<<1) + Id];
}
unsigned kbo_GetMinWeight(KBOSTATE Kstate)
{
  return Kstate->minweight;
}
TERMSTATE kbo_GetTermstate(KBOSTATE Kstate)
{
  return Kstate->termstate;
}
void kbo_CompareVarCondAndWeightIntern(TERMSTATE Termstate, SYMBSTATE Symbstate, TERM Term, unsigned *Varcount, unsigned id, unsigned *Weight, unsigned Minweight)
{
  unsigned i;
  if (term_IsVariable(Termstate, Term)) {
    *Weight += Minweight;
    kbo_IncreaseVarcount(Varcount, term_TopSymbol(Term), id);
    }
    else {
      *Weight += symbol_GetWeight(Symbstate, term_TopSymbol(Term));
      if (term_IsComplex(Term)) {
 for (i=0;i<term_GetArity(Term);i++)
   kbo_CompareVarCondAndWeightIntern(Termstate, Symbstate, (TERM)Term[i], Varcount, id, Weight, Minweight);
      }
    }
}
int kbo_CompVarCondAndWeight(KBOSTATE Kstate, TERM Term1, BOOL *VarCond1, TERM Term2, BOOL *VarCond2)
{
  SYMBOL maxvar1,maxvar2;
  unsigned weight1, weight2;
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  int weight,i;
  *VarCond1 = *VarCond2 = TRUE;
  termstate = kbo_GetTermstate(Kstate);
  symbstate = term_GetSymbstate(termstate);
  maxvar1 = term_MaxVar(termstate, Term1);
  maxvar2 = term_MaxVar(termstate, Term2);
  weight1 = 0;
  weight2 = 0;
  if (maxvar1 < maxvar2)
    maxvar1 = maxvar2;
  for (i = 0; i <= maxvar1; i++) {
    kbo_SetVarcount(Kstate->varcount, i, 0, 0);
    kbo_SetVarcount(Kstate->varcount, i, 1, 0);
  }
  kbo_CompareVarCondAndWeightIntern(termstate, symbstate, Term1, Kstate->varcount, 0, &weight1, Kstate->minweight);
  kbo_CompareVarCondAndWeightIntern(termstate, symbstate, Term2, Kstate->varcount, 1, &weight2, Kstate->minweight);
  weight = weight1 - weight2;
  for (i = 0; i <= maxvar1; i++) {
    if (kbo_GetVarcount(Kstate->varcount,i,0) < kbo_GetVarcount(Kstate->varcount,i,1)) {
      *VarCond1 = FALSE;
      if (!*VarCond2)
 return weight;
    }
   if (kbo_GetVarcount(Kstate->varcount,i,0) > kbo_GetVarcount(Kstate->varcount,i,1)) {
      *VarCond2 = FALSE;
      if (!*VarCond1)
 return weight;
    }
  }
  return weight;
}
static kbo_RESULT kbo_CompareStruc(KBOSTATE Kstate, TERM Term1, TERM Term2, int WeightDiff, BOOL VarIsConst)
{
  SYMBOL Top1,Top2;
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  termstate = kbo_GetTermstate(Kstate);
  symbstate = term_GetSymbstate(termstate);
  Top1 = term_TopSymbol(Term1);
  Top2 = term_TopSymbol(Term2);
  if (WeightDiff > 0)
    return kbo_GREATER_THAN;
  else
    if (WeightDiff == 0) {
      if (symbol_IsVariable(symbstate, Top1)) {
 if (symbol_IsVariable(symbstate, Top2)) {
   if(VarIsConst) {
     if(symbol_PrecedenceGreater(symbstate, Top1, Top2))
       return kbo_GREATER_THAN;
     if(symbol_PrecedenceGreater(symbstate, Top2, Top1))
       return kbo_SMALLER_THAN;
     else
       return kbo_EQUAL;
   }
   else
     return kbo_EQUAL;
        }
 else
   return kbo_UNCOMPARABLE;
      }
      else
 if (symbol_IsVariable(symbstate, Top2) ||
     symbol_PrecedenceGreater(symbstate, Top1, Top2))
   return kbo_GREATER_THAN;
 else
   if (Top1 == Top2) {
     int RecWeightDiff, i;
     BOOL T1VarCond, T2VarCond;
     for (i = 0; i < symbol_GetArity(symbstate, Top1) && term_Equal(termstate,(TERM)Term1[i],(TERM)Term2[i]); i++);
     if (i == symbol_GetArity(symbstate, Top1))
       return kbo_EQUAL;
     RecWeightDiff = kbo_CompVarCondAndWeight(Kstate, (TERM)Term1[i], &T1VarCond, (TERM)Term2[i], &T2VarCond);
     if (RecWeightDiff >= 0 && (T1VarCond || VarIsConst))
       return kbo_CompareStruc(Kstate, (TERM)Term1[i], (TERM)Term2[i], RecWeightDiff, VarIsConst);
     else
       return kbo_UNCOMPARABLE;
   }
   else
     return kbo_UNCOMPARABLE;
    }
    else
      return kbo_UNCOMPARABLE;
  return kbo_UNCOMPARABLE;
}
kbo_RESULT kbo_CompareAux(KBOSTATE Kstate, TERM Term1, TERM Term2, BOOL VarIsConst)
{
  int WeightDiff;
  BOOL T1VarCond, T2VarCond;
  kbo_RESULT Result;
#ifdef SPASS_CHECK
  if (!term_IsTerm(kbo_GetTermstate(Kstate), Term1) || !term_IsTerm(kbo_GetTermstate(Kstate), Term2)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In kbo_Compare:");
    misc_ErrorReport("\n Illegal input.");
    misc_FinishErrorReport();
  }
#endif
  WeightDiff = kbo_CompVarCondAndWeight(Kstate, Term1, &T1VarCond, Term2, &T2VarCond);
  if(VarIsConst) {
    Result = kbo_CompareStruc(Kstate, Term1, Term2, WeightDiff, VarIsConst);
    if(Result == kbo_UNCOMPARABLE)
      return kbo_Not(kbo_CompareStruc(Kstate, Term2, Term1, -WeightDiff, VarIsConst));
    else
      return Result;
  }
  if (T1VarCond && !T2VarCond)
    return kbo_CompareStruc(Kstate,Term1,Term2,WeightDiff, FALSE);
  if (!T1VarCond && T2VarCond)
    return kbo_Not(kbo_CompareStruc(Kstate,Term2,Term1,-WeightDiff, FALSE));
  if (T1VarCond && T2VarCond) {
    Result = kbo_CompareStruc(Kstate,Term1,Term2,WeightDiff, FALSE);
    if (Result == kbo_UNCOMPARABLE)
      return kbo_Not(kbo_CompareStruc(Kstate,Term2,Term1,-WeightDiff, FALSE));
    else
      return Result;
  }
  return kbo_UNCOMPARABLE;
}
kbo_RESULT kbo_Compare(KBOSTATE Kstate, TERM Term1, TERM Term2)
{
  return kbo_CompareAux(Kstate, Term1, Term2, FALSE);
}
unsigned kbo_ComputeWeight(KBOSTATE Kstate, SYMBSTATE Symbstate, TERM Term)
{
  SYMBOL top;
  unsigned weight,i;
  top = term_TopSymbol(Term);
  if (symbol_IsVariable(Symbstate, top))
    return kbo_GetMinWeight(Kstate);
  weight = symbol_GetWeight(Symbstate, top);
  for (i=0;i<term_GetArity(Term);i++)
    weight += kbo_ComputeWeight(Kstate, Symbstate, (TERM)Term[i]);
  return weight;
}
unsigned kbo_ComputeWeightSubstContext(KBOSTATE Kstate, SUBSTSTATE SState, SYMBSTATE Symbstate, SUBST Subst, TERM Term)
{
  SYMBOL top;
  unsigned weight,i;
  top = term_TopSymbol(Term);
  if (Subst != NULL && symbol_IsVariable(Symbstate, top) && subst_VarDefined(Subst, top)) {
    Term = subst_GetValue(Subst,top);
    top = term_TopSymbol(Term);
    Subst = NULL;
  }
  if (symbol_IsVariable(Symbstate, top) && subst_ContextValueIsMarked(SState, top)) {
    Term = subst_ContextGetTermValueFollowSymbolChain(SState, Symbstate, Term);
    top = term_TopSymbol(Term);
    Subst = NULL;
  }
  if (symbol_IsVariable(Symbstate, top))
    return kbo_GetMinWeight(Kstate);
  weight = symbol_GetWeight(Symbstate, top);
  for (i=0;i<term_GetArity(Term);i++)
    weight += kbo_ComputeWeightSubstContext(Kstate, SState, Symbstate, Subst, (TERM)Term[i]);
  return weight;
}
unsigned kbo_ComputeWeightSubst(KBOSTATE Kstate, SUBSTSTATE SState, SYMBSTATE Symbstate, SUBST Subst, TERM Term)
{
  SYMBOL top;
  unsigned weight,i;
  top = term_TopSymbol(Term);
  if (Subst != NULL && symbol_IsVariable(Symbstate, top) && subst_VarDefined(Subst, top)) {
    Term = subst_GetValue(Subst,top);
    top = term_TopSymbol(Term);
    Subst = NULL;
  }
  if (symbol_IsVariable(Symbstate, top))
    return kbo_GetMinWeight(Kstate);
  weight = symbol_GetWeight(Symbstate, top);
  for (i=0;i<term_GetArity(Term);i++)
    weight += kbo_ComputeWeightSubst(Kstate, SState, Symbstate, Subst, (TERM)Term[i]);
  return weight;
}
BOOL kbo_TermSubstContextEqual(KBOSTATE Kstate, SUBSTSTATE SState, SYMBSTATE Symbstate, SUBST Subst, TERM Term1, TERM Term2)
{
  SYMBOL top;
  unsigned i;
  top = term_TopSymbol(Term1);
  if (Subst != NULL && symbol_IsVariable(Symbstate, top) && subst_VarDefined(Subst, top)) {
    Term1 = subst_GetValue(Subst,top);
    top = term_TopSymbol(Term1);
    Subst = NULL;
  }
  if (symbol_IsVariable(Symbstate, top) && subst_ContextValueIsMarked(SState, top)) {
    Term1 = subst_ContextGetTermValueFollowSymbolChain(SState, Symbstate, Term1);
    top = term_TopSymbol(Term1);
    Subst = NULL;
  }
  if (symbol_IsVariable(Symbstate, top))
    top = kbo_GetMinConstant(Kstate);
  if (!symbol_Equal(top, term_TopSymbol(Term2)) || term_GetArity(Term1) != term_GetArity(Term2))
    return FALSE;
  for (i=0;i<term_GetArity(Term1);i++)
    if (!kbo_TermSubstContextEqual(Kstate, SState, Symbstate, Subst, (TERM)Term1[i], (TERM)Term2[i]))
      return FALSE;
  return TRUE;
}
BOOL kbo_TermSubstEqual(KBOSTATE Kstate, SUBSTSTATE SState, SYMBSTATE Symbstate, SUBST Subst, TERM Term1, TERM Term2)
{
  SYMBOL top;
  unsigned i;
  top = term_TopSymbol(Term1);
  if (Subst != NULL && symbol_IsVariable(Symbstate, top) && subst_VarDefined(Subst, top)) {
    Term1 = subst_GetValue(Subst,top);
    top = term_TopSymbol(Term1);
    Subst = NULL;
  }
  if (symbol_IsVariable(Symbstate, top))
    top = kbo_GetMinConstant(Kstate);
  if (!symbol_Equal(top, term_TopSymbol(Term2)) || term_GetArity(Term1) != term_GetArity(Term2))
    return FALSE;
  for (i=0;i<term_GetArity(Term1);i++)
    if (!kbo_TermSubstEqual(Kstate, SState, Symbstate, Subst, (TERM)Term1[i], (TERM)Term2[i]))
      return FALSE;
  return TRUE;
}
BOOL kbo_SmallerSubstContextGround(KBOSTATE Kstate, SUBSTSTATE SState, SUBST Subst, TERM Term1, TERM Term2)
{
  unsigned weight1, weight2;
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  SYMBOL top1, top2;
  unsigned i;
  termstate = kbo_GetTermstate(Kstate);
  symbstate = term_GetSymbstate(termstate);
  top1 = term_TopSymbol(Term1);
  top2 = term_TopSymbol(Term2);
  if (Subst != NULL && symbol_IsVariable(symbstate, top1) && subst_VarDefined(Subst, top1)) {
    Term1 = subst_GetValue(Subst,top1);
    top1 = term_TopSymbol(Term1);
    Subst = NULL;
  }
  if (symbol_IsVariable(symbstate, top1) && subst_ContextValueIsMarked(SState, top1)) {
    Term1 = subst_ContextGetTermValueFollowSymbolChain(SState, symbstate, Term1);
    top1 = term_TopSymbol(Term1);
    Subst = NULL;
  }
  if (symbol_IsVariable(symbstate, top1))
    top1 = kbo_GetMinConstant(Kstate);
  weight1 = kbo_ComputeWeightSubstContext(Kstate, SState, symbstate, Subst, Term1);
  weight2 = kbo_ComputeWeight(Kstate, symbstate, Term2);
  if (weight1 < weight2)
    return TRUE;
  else {
    if (weight1 > weight2 || kbo_TermSubstContextEqual(Kstate, SState, symbstate, Subst, Term1, Term2))
      return FALSE;
  }
  if (symbol_PrecedenceSmaller(symbstate, top1, top2))
    return TRUE;
  else {
    if (symbol_PrecedenceGreater(symbstate, top1, top2))
      return FALSE;
  }
  for (i=0;i<term_GetArity(Term1);i++) {
    if (kbo_SmallerSubstContextGround(Kstate, SState, Subst, (TERM)Term1[i], (TERM)Term2[i]))
      return TRUE;
    if (!kbo_TermSubstContextEqual(Kstate, SState, symbstate, Subst, (TERM)Term1[i], (TERM)Term2[i]))
      return FALSE;
  }
  return FALSE;
}
BOOL kbo_SmallerSubstGround(KBOSTATE Kstate, SUBSTSTATE SState, SUBST Subst, TERM Term1, TERM Term2)
{
  unsigned weight1, weight2;
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  SYMBOL top1, top2;
  unsigned i;
  termstate = kbo_GetTermstate(Kstate);
  symbstate = term_GetSymbstate(termstate);
  top1 = term_TopSymbol(Term1);
  top2 = term_TopSymbol(Term2);
  if (Subst != NULL && symbol_IsVariable(symbstate, top1) && subst_VarDefined(Subst, top1)) {
    Term1 = subst_GetValue(Subst,top1);
    top1 = term_TopSymbol(Term1);
    Subst = NULL;
  }
  if (symbol_IsVariable(symbstate, top1))
    top1 = kbo_GetMinConstant(Kstate);
  weight1 = kbo_ComputeWeightSubst(Kstate, SState, symbstate, Subst, Term1);
  weight2 = kbo_ComputeWeight(Kstate, symbstate, Term2);
  if (weight1 < weight2)
    return TRUE;
  else {
    if (weight1 > weight2 || kbo_TermSubstEqual(Kstate, SState, symbstate, Subst, Term1, Term2))
      return FALSE;
  }
  if (symbol_PrecedenceSmaller(symbstate, top1, top2))
    return TRUE;
  else {
    if (symbol_PrecedenceGreater(symbstate, top1, top2))
      return FALSE;
  }
  for (i=0;i<term_GetArity(Term1);i++) {
    if (kbo_SmallerSubstGround(Kstate, SState, Subst, (TERM)Term1[i], (TERM)Term2[i]))
      return TRUE;
    if (!kbo_TermSubstEqual(Kstate, SState, symbstate, Subst, (TERM)Term1[i], (TERM)Term2[i]))
      return FALSE;
  }
  return FALSE;
}
BOOL kbo_Smaller(KBOSTATE Kstate, TERM Term1, TERM Term2)
{
  return (kbo_Compare(Kstate, Term1, Term2) == kbo_SMALLER_THAN);
}
BOOL kbo_CompareSortingFunc(POINTER Term1, POINTER Term2, POINTER Kstate)
{
  return (kbo_Compare((KBOSTATE)Kstate, *((TERM*)Term1), *((TERM*) Term2)) == kbo_GREATER_THAN);
}
ARRAY kbo_BuildTerm(KBOSTATE Kstate, TERMSTATE Termstate, SYMBSTATE Symbstate, SYMBOL Symb, unsigned arity, ARRAY Result, ARRAY Argscounter, unsigned Oweight, TERM Term)
{
  unsigned weight, i;
  TERM term;
  kbo_RESULT comp;
  weight = 0;
  for (i=0;i<arity;i++)
    weight += kbo_ComputeWeight(Kstate, Symbstate, (TERM)Result[Argscounter[i]]);
  weight += symbol_GetWeight(Symbstate, Symb);
  if (weight > Oweight)
    return Result;
  term = term_CreateArity(Termstate, Symb, arity);
  for (i=0;i<arity;i++)
    term_SetArgument(term, i, term_Copy(Termstate, (TERM)Result[Argscounter[i]]));
  comp = kbo_Compare(Kstate, term, Term);
  if (comp != kbo_SMALLER_THAN) {
    term_Delete(Termstate,term);
    return Result;
  }
  Result = array_Add(term_GetMemory(Termstate), Result, (intptr_t)term);
  return Result;
}
BOOL kbo_BuildTermNewArgument(ARRAY Argsnew, unsigned Arity)
{
  unsigned i;
  for (i=0; i<Arity; i++) {
    if (Argsnew[i] == (intptr_t)TRUE) {
      return TRUE;
    }
  }
  return FALSE;
}
ARRAY kbo_SmallerTerms(KBOSTATE Kstate, ARRAY Signature, TERM Term)
{
  ARRAY result, functions, argscounter, argsnew;
  unsigned oweight, i, j, maxarity,fsymbs,subtermstart,subtermend, subtermround, minweight,ominweight,arity,fweight;
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  SYMBOL symb;
  MEMORY mem;
  BOOL update;
  termstate = kbo_GetTermstate(Kstate);
  symbstate = term_GetSymbstate(termstate);
  mem = term_GetMemory(termstate);
  oweight = kbo_ComputeWeight(Kstate, symbstate, Term);
  result = array_Create(mem, oweight * array_GetSize(Signature));
  functions = array_Create(mem, array_GetSize(Signature));
  maxarity = 0;
  for (i=0; i<array_GetSize(Signature);i++) {
    symb = (SYMBOL)Signature[i];
    if (symbol_GetWeight(symbstate, symb) < oweight) {
      if (symbol_IsConstant(symb)) {
 result = array_Add(mem, result, (intptr_t)term_CreateArity(termstate, symb, 0));
      }
      else {
 functions = array_Add(mem, functions, symb);
 if (symbol_GetArity(symbstate,symb) > (int)maxarity)
   maxarity = symbol_GetArity(symbstate,symb);
      }
    }
  }
  if (array_GetSize(result) == 0) {
    array_Delete(mem,result);
    return NULL;
  }
  srtg_AMergeSortWithState(mem, result, result, result + (array_GetSize(result) - 1), (int (*)(POINTER, POINTER, POINTER))kbo_CompareSortingFunc, (POINTER)Kstate);
  fsymbs = array_GetSize(functions);
  i = 0;
  subtermstart = 0;
  subtermround = 0;
  subtermend = array_GetSize(result);
  minweight = kbo_ComputeWeight(Kstate, symbstate, (TERM)result[subtermstart]);
  ominweight = minweight;
  argscounter = array_Create(mem, maxarity);
  argsnew = array_Create(mem, maxarity);
  while (fsymbs>0 && i < fsymbs) {
    symb = (SYMBOL)functions[i];
    arity = symbol_GetArity(symbstate,symb);
    fweight = symbol_GetWeight(symbstate, symb);
    if ((fweight + minweight + (arity-1)*ominweight) > oweight) {
      fsymbs--;
      if (fsymbs != 0 && i < fsymbs)
 functions[i] = functions[fsymbs];
      if (i == fsymbs)
 i = 0;
    }
    else {
      for (j = 0; j < arity; j++ ) {
 argscounter[j] = subtermstart;
 argsnew[j] = (subtermstart >= subtermround ? (intptr_t)TRUE : (intptr_t)FALSE);
      }
      j = 0;
      arity--;
      while (argscounter[j] < subtermend) {
 if (j == arity) {
   if (kbo_BuildTermNewArgument(argsnew, symbol_GetArity(symbstate,symb)))
     result = kbo_BuildTerm(Kstate, termstate, symbstate, symb, arity+1, result, argscounter, oweight, Term);
   update = TRUE;
   while (update) {
     if (argscounter[j] + 1 < subtermend) {
       update = FALSE;
       argscounter[j]++;
       argsnew[j] = (argscounter[j] >= subtermround ? TRUE : FALSE);
     }
     else {
       if (j != 0) {
  argscounter[j] = subtermstart;
  argsnew[j] = (subtermstart >= subtermround ? TRUE : FALSE);
  j--;
       }
       if (j == 0 && argscounter[j] + 1 == subtermend) {
  argscounter[j]++;
  update = FALSE;
       }
     }
   }
 }
 else
   j++;
      }
      i++;
    }
    if (fsymbs > 0 && i == fsymbs) {
      i=0;
      srtg_AMergeSortWithState(mem, result, &result[subtermstart], result + (array_GetSize(result) - 1), (int (*)(POINTER, POINTER, POINTER))kbo_CompareSortingFunc, (POINTER)Kstate);
      subtermround = subtermend;
      subtermend = array_GetSize(result);
      if (subtermround == subtermend)
 fsymbs = 0;
      else
 minweight = kbo_ComputeWeight(Kstate, symbstate, (TERM)result[subtermround]);
    }
  }
  array_Delete(mem, argscounter);
  array_Delete(mem, argsnew);
  array_Delete(mem, functions);
  srtg_AMergeSortWithState(mem, result, result, result + (array_GetSize(result) - 1), (int (*)(POINTER, POINTER, POINTER))kbo_CompareSortingFunc, (POINTER)Kstate);
  return result;
}
void kbo_SetSimpleKBO(KBOSTATE KState)
{
  SYMBSTATE symbstate;
  SYMBSIG symbsig;
  unsigned i;
  symbstate = term_GetSymbstate(kbo_GetTermstate(KState));
  symbsig = symbol_GetStateSig(symbstate);
  kbo_SetMinConstant(KState, (SYMBOL)NULL);
  KState->minweight = 1;
  for (i=0;i<symbol_GetStateSigLength(symbstate);i++) {
    symbol_SigSetPrecedenceWeight(symbsig, i, i, 1);
    if (kbo_GetMinConstant(KState) == (SYMBOL)NULL && symbol_SigIsConstant(symbsig,i))
      kbo_SetMinConstant(KState, -symbol_SetIndexType(i, CONSTANT));
  }
}
kbo_RESULT kbo_SymbolCountCompareShared(TERM Term1, TERM Term2)
{
  if (term_Size(Term1) < term_Size(Term2))
    return kbo_SMALLER_THAN;
  else {
    if (term_Size(Term1) > term_Size(Term2))
      return kbo_GREATER_THAN;
    else
      return kbo_EQUAL;
  }
}
BOOL kbo_SymbolCountSmallerEqualShared(TERM Term1, TERM Term2)
{
  return (term_Size(Term1) <= term_Size(Term2));
}
BOOL kbo_SymbolCountSmallerEqual(TERMSTATE Termstate, TERM Term1, TERM Term2)
{
  return (term_ComputeSize(Termstate, Term1) <= term_ComputeSize(Termstate, Term2));
}
