#ifdef DOC_BUILD_INTERNAL
#endif
#include "term.h"
#include "misc.h"
const unsigned term_EXTRA = 11;
const int term_PROPVAR = -11;
const int term_PROPIND = -10;
const int term_PROFIT = -9;
const int term_CAPACITY = -8;
const int term_PROPERTY = -7;
const int term_INDEX = -6;
const int term_SIZE = -5;
const int term_STAMP = -4;
const int term_SUPER = -3;
const int term_SYMBOL = -2;
const int term_ARITY = -1;
const unsigned term_NOVAR = UINT_MAX;
MEMORY term_GetMemory(TERMSTATE Termstate)
{
  return symbol_GetStateMemory(term_GetSymbstate(Termstate));
}
SYMBSTATE term_GetSymbstate(TERMSTATE Termstate)
{
  return Termstate->symbstate;
}
TERM term_Null(void)
{
  return (TERM)NULL;
}
SYMBOL term_TopSymbol(TERM T)
{
  return (SYMBOL)T[term_SYMBOL];
}
 void term_RplacTop(TERM T, SYMBOL S)
{
  T[term_SYMBOL] = (intptr_t)S;
}
ARRAY term_SupertermArray(TERM T)
{
  return (ARRAY)T[term_SUPER];
}
void term_RplacSupertermArray(TERM T, ARRAY Ar)
{
  T[term_SUPER] = (intptr_t)Ar;
}
ARRAY term_AtomsLiterals(TERM T)
{
  return (ARRAY)T[term_SUPER];
}
TERM term_Superterm(TERM T)
{
  return (TERM)T[term_SUPER];
}
void term_RplacSuperterm(TERM T1, TERM T2)
{
  T1[term_SUPER] = (intptr_t)T2;
}
BOOL term_IsVariable(TERMSTATE Termstate, TERM T)
{
  return symbol_IsVariable(term_GetSymbstate(Termstate),
      term_TopSymbol(T));
}
#if defined(SPASS_SYMBOL_INDEXVARS)
BOOL term_IsStandardVariable(TERMSTATE Termstate, TERM T)
{
  return symbol_IsStandardVariable(term_GetSymbstate(Termstate),
       term_TopSymbol(T));
}
BOOL term_IsIndexVariable(TERMSTATE Termstate, TERM T)
{
  return symbol_IsIndexVariable(term_GetSymbstate(Termstate),
    term_TopSymbol(T));
}
#endif
TERM term_GetArgument(TERM T, unsigned Idx)
{
#ifdef SPASS_CHECK
  if (!symbol_IsValueConstant(term_TopSymbol(T)) && !(Idx < term_GetArity(T))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n %s: argument index %u too large"
       "(for arity %u)", __func__,
       Idx, term_GetArity(T));
    misc_FinishErrorReport();
  }
#endif
  return (TERM)T[Idx];
}
void term_SetArgument(TERM T, unsigned Idx, TERM Arg)
{
#ifdef SPASS_CHECK
  if (!symbol_IsValueConstant(term_TopSymbol(T)) && !(Idx < term_GetArity(T))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n %s: argument index %u too large"
       "(for arity %u)", __func__,
       Idx, term_GetArity(T));
    misc_FinishErrorReport();
 }
#endif
  T[Idx] = (intptr_t)Arg;
}
unsigned term_GetArity(TERM T)
{
  return T[term_ARITY];
}
unsigned term_GetCapacity(TERM T)
{
  return T[term_CAPACITY];
}
void term_SetArity(TERM T, unsigned Arity)
{
#ifdef SPASS_CHECK
  if (Arity > term_GetCapacity(T)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input: arity larger than capacity.", __func__);
    misc_FinishErrorReport();
  }
#endif
  T[term_ARITY] = Arity;;
}
intptr_t term_GetProperty(TERM T)
{
  return T[term_PROPERTY];
}
void term_SetProperty(TERM T, intptr_t Prop)
{
  T[term_PROPERTY] = Prop;
}
void term_ResetPropertyRec(TERM T)
 {
  unsigned i, arity;
  arity = term_GetArity(T);
  for (i = 0; i < arity; i++) {
    term_ResetPropertyRec(term_GetArgument(T, i));
  }
  T[term_PROPERTY] = (uintptr_t)NULL;
}
void term_PropertySetPhase(TERM T, BOOL Phase)
{
  if (Phase)
    T[term_PROPERTY] = T[term_PROPERTY] | (intptr_t)1;
  else
    T[term_PROPERTY] = T[term_PROPERTY] & ~(intptr_t)1;
}
void term_SetPropertyPhasePositive(TERM T)
{
  T[term_PROPERTY] = T[term_PROPERTY] | (intptr_t)1;
}
void term_SetPropertyPhaseNegative(TERM T)
{
  T[term_PROPERTY] = T[term_PROPERTY] & ~(intptr_t)1;
}
void term_SetPropagatable(TERM T, BOOL Propagatable)
{
  if (Propagatable) {
    T[term_PROPERTY] = T[term_PROPERTY] | (uintptr_t)2;
  } else {
    T[term_PROPERTY] = T[term_PROPERTY] & ~(uintptr_t)2;
  }
}
BOOL term_IsPropagatable(TERM T)
{
  return (T[term_PROPERTY] & (uintptr_t)2) ? TRUE : FALSE;
}
BOOL term_IsActive(TERM T)
{
  return (T[term_PROPERTY] & (uintptr_t)4) ? TRUE : FALSE;
}
void term_SetActive(TERM T, BOOL Active)
{
  if (Active) {
    T[term_PROPERTY] = T[term_PROPERTY] | (uintptr_t)4;
  } else {
    T[term_PROPERTY] = T[term_PROPERTY] & ~(uintptr_t)4;
  }
}
BOOL term_IsPersAtom(TERM T)
{
  return (T[term_PROPERTY] & (uintptr_t)16) ? TRUE : FALSE;
}
void term_SetPersAtom(TERM T, BOOL Active)
{
  if (Active) {
    T[term_PROPERTY] = T[term_PROPERTY] | (uintptr_t)16;
  } else {
    T[term_PROPERTY] = T[term_PROPERTY] & ~(uintptr_t)16;
  }
}
BOOL term_HasPhase(TERM T)
{
  return (T[term_PROPERTY] & (uintptr_t)8) ? TRUE : FALSE;
}
void term_SetHasPhase(TERM T, BOOL hasphase)
{
  if (hasphase) {
    T[term_PROPERTY] = T[term_PROPERTY] | (uintptr_t)8;
  } else {
    T[term_PROPERTY] = T[term_PROPERTY] & ~(uintptr_t)8;
  }
}
int term_GetPrLitIndex(TERM T)
{
  return (int)T[term_PROPIND];
}
void term_SetPrLitIndex(TERM T, int Index)
{
  T[term_PROPIND] = Index;
}
BOOL term_PropertyPhasePositive(TERM T)
{
  return (T[term_PROPERTY] & (uintptr_t)1);
}
unsigned term_QueryProfit(TERM T, unsigned VSIDS_BONUS)
{
  return (int)T[term_PROFIT] + term_IsPropagatable(T) * VSIDS_BONUS;
}
unsigned term_GetProfit(TERM T)
{
  return T[term_PROFIT];
}
void term_ShiftProfit(TERM T)
{
  T[term_PROFIT] >>= 20;
}
void term_SetProfit(TERM T, unsigned Profit)
{
  T[term_PROFIT] = Profit;
}
void term_SetPropVar(TERM T, unsigned P)
{
  T[term_PROPVAR] = P;
}
unsigned term_GetPropVar(TERM T)
{
  return T[term_PROPVAR];
}
BOOL term_PropVarSet(TERM T)
{
  return (T[term_PROPVAR] != term_NOVAR);
}
void term_IncreaseProfit(TERM T, unsigned Profit)
{
  T[term_PROFIT] += Profit;
}
BOOL term_IsComplex(TERM T)
{
  return term_GetArity(T) > 0;
}
BOOL term_IsValueConstant(TERMSTATE Termstate, TERM T)
{
  return !term_IsComplex(T) &&
    symbol_IsValueConstant(term_TopSymbol(T));
}
intptr_t term_GetValue(TERMSTATE Termstate, TERM T)
{
#ifdef SPASS_CHECK
  if (!term_IsValueConstant(Termstate, T)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input: No Value Constant.", __func__);
    misc_FinishErrorReport();
  }
#endif
  return (intptr_t)term_GetArgument(T, 0);
}
 void term_SetValue(TERMSTATE Termstate, TERM T, intptr_t Value)
{
#ifdef SPASS_CHECK
  if (!term_IsValueConstant(Termstate, T)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input: No Value Constant.", __func__);
    misc_FinishErrorReport();
  }
#endif
  term_SetArgument(T, 0, (TERM)Value);
}
BOOL term_IsConstant(TERMSTATE Termstate, TERM T)
{
  return !term_IsComplex(T) &&
    symbol_IsConstant(term_TopSymbol(T));
}
BOOL term_IsAtom(TERM T)
{
  return symbol_IsPredicate(term_TopSymbol(T));
}
TERM term_FirstArgument(TERM T)
{
  return term_GetArgument(T, 0);
}
void term_RplacFirstArgument(TERM T1, TERM T2)
{
  term_SetArgument(T1, 0, T2);
}
TERM term_SecondArgument(TERM T)
{
  return term_GetArgument(T, 1);
}
TERM term_ThirdArgument(TERM T)
{
  return term_GetArgument(T, 2);
}
void term_RplacSecondArgument(TERM T1, TERM T2)
{
  term_SetArgument(T1, 1, T2);
}
void term_SwapArguments(TERM Term, unsigned I, unsigned J)
{
  TERM tmp;
  tmp = term_GetArgument(Term, I);
  term_SetArgument(Term, I, term_GetArgument(Term, J));
  term_SetArgument(Term, J, tmp);
}
void term_Free(TERMSTATE Termstate, TERM T)
{
  memory_Free(term_GetMemory(Termstate), T-term_EXTRA,
  ((term_IsValueConstant(Termstate, T) ?
  1 : term_GetCapacity(T))
  + term_EXTRA) * sizeof(intptr_t));
}
void term_FreeNoValueConstants(MEMORY Mem, TERM T)
{
  memory_Free(Mem, T-term_EXTRA, (term_GetCapacity(T) + term_EXTRA) * sizeof(intptr_t));
}
BOOL term_EqualTopSymbols(TERM T, TERM S)
{
  return symbol_Equal(term_TopSymbol(T), term_TopSymbol(S));
}
void term_EqualitySwap(TERM T)
{
  TERM Aux;
  Aux = term_FirstArgument(T);
  term_RplacFirstArgument(T, (TERM) term_SecondArgument(T));
  term_RplacSecondArgument(T, (TERM)Aux);
}
#ifdef SPASS_CHECK
void term_StopStamp(TERMSTATE Termstate)
{
  Termstate->stampblocked = FALSE;
}
#else
void term_StartStamp(TERMSTATE Termstate)
{
  Termstate->stamp++;
}
void term_StopStamp(TERMSTATE Termstate)
{ }
#endif
NAT term_TermStamp(TERM T)
{
  return T[term_STAMP];
}
void term_SetTermStamp(TERMSTATE Termstate, TERM T)
{
  T[term_STAMP] = Termstate->stamp;
}
NAT term_Size(TERM T)
{
  return T[term_SIZE];
}
void term_SetSize(TERM T, NAT S)
{
  T[term_SIZE] = S;
}
intptr_t term_Index(TERM T)
{
  return T[term_INDEX];
}
void term_SetIndex(TERM T, intptr_t Index)
{
  T[term_INDEX] = Index;
}
BOOL term_AlreadyVisited(TERMSTATE Termstate, TERM T)
{
  return T[term_STAMP] == Termstate->stamp;
}
BOOL term_HasTermStamp(TERMSTATE Termstate, TERM T)
{
  return T[term_STAMP] == Termstate->stamp;
}
void term_ResetTermStamp(TERM T)
{
  T[term_STAMP] = 0;
}
BOOL term_StampAlreadyReset(TERM T)
{
  return T[term_STAMP] == 0;
}
void term_CopyTermsInArray(TERMSTATE Termstate, ARRAY Ar)
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++)
    array_SetElement(Ar, i, (intptr_t)
       term_Copy(Termstate,
          (TERM)array_GetElement(Ar, i)));
}
ARRAY term_CopyTermArray(TERMSTATE Termstate, ARRAY Ar)
{
  ARRAY res;
  res = array_Copy(term_GetMemory(Termstate), Ar);
  term_CopyTermsInArray(Termstate, res);
  return res;
}
void term_DeleteTermArray(TERMSTATE Termstate, ARRAY Ar)
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++)
    term_Delete(Termstate, (TERM)array_GetElement(Ar, i));
  array_Delete(term_GetMemory(Termstate), Ar);
}
BOOL term_ArrayContainsTerm(TERMSTATE Termstate, ARRAY Ar, TERM Term)
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++)
    if (term_Equal(Termstate, Term,
     (TERM)array_GetElement(Ar, i)))
      return TRUE;
  return FALSE;
}
ARRAY term_DeleteDuplicatesFromArray(TERMSTATE Termstate, ARRAY Ar)
{
  unsigned i,j,k;
  for (i = 0; i < array_GetSize(Ar); i++) {
    for (j = i+1, k = i+1; j < array_GetSize(Ar); j++)
      if (!term_Equal(Termstate, (TERM) array_GetElement(Ar, i),
        (TERM) array_GetElement(Ar, j))) {
 array_SetElement(Ar, k, array_GetElement(Ar, j));
 k++;
      }
    array_SetSize(Ar, k);
  }
  return Ar;
}
ARRAY term_DestroyDuplicatesInArray(TERMSTATE Termstate,
        ARRAY Ar)
{
  unsigned i, j, k;
  for (i = 0; i < array_GetSize(Ar); i++) {
    for (j = i+1, k = i+1; j < array_GetSize(Ar); j++)
      if (!term_Equal(Termstate, (TERM)array_GetElement(Ar, i),
        (TERM)array_GetElement(Ar, j))) {
 array_SetElement(Ar, k, array_GetElement(Ar, j));
 k++;
      } else
 term_Delete(Termstate, (TERM)array_GetElement(Ar, j));
    array_SetSize(Ar, k);
  }
  return Ar;
}
void term_PrintPosition(TERM TopTerm, TERM Subterm)
{
  term_FPrintPosition(stdout, TopTerm, Subterm);
}
TERMSTATE term_Init(SYMBSTATE Symbstate, unsigned Maxusers)
{
  unsigned i;
  TERMSTATE res;
  MEMORY mem;
  mem = symbol_GetStateMemory(Symbstate);
  res = memory_Malloc(mem, sizeof(TERMSTATE_NODE) + Maxusers * sizeof(BOOL));
  res->stamp = 0;
#ifdef SPASS_CHECK
  res->stampblocked = FALSE;
#endif
  res->stampusers = 0;
  res->maxstampusers = Maxusers;
  res->symbstate = Symbstate;
  for (i = 0; i < Maxusers; i++)
    res->stampoverflow[i] = FALSE;
  return res;
}
void term_TermstateFree(TERMSTATE Termstate)
{
  MEMORY mem;
  mem = term_GetMemory(Termstate);
  memory_Free(mem, Termstate, sizeof(TERMSTATE_NODE) + Termstate->maxstampusers * sizeof(BOOL));
}
TERM term_CreateArity(TERMSTATE Termstate, SYMBOL Symbol,
        unsigned Arity)
{
  TERM res;
#ifdef SPASS_CHECK
  if (!symbol_IsSymbol(term_GetSymbstate(Termstate), Symbol)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal symbol.", __func__);
    misc_FinishErrorReport();
  }
#endif
  res = (TERM)memory_Malloc(term_GetMemory(Termstate),
     (term_EXTRA + Arity)*sizeof(*res));
  res += term_EXTRA;
  res[term_INDEX] = 0;
  res[term_PROFIT] = 0;
  res[term_SIZE] = 0;
  res[term_STAMP] = 0;
  res[term_PROPVAR] = term_NOVAR;
  res[term_PROPIND] = (intptr_t)NULL;
  res[term_PROPERTY] = (intptr_t)NULL;
  res[term_SUPER] = (intptr_t)NULL;
  res[term_SYMBOL] = (intptr_t) Symbol;
  res[term_ARITY] = Arity;
  res[term_CAPACITY] = Arity;
  return res;
}
TERM term_CreateArityNullInit(TERMSTATE Termstate, SYMBOL Symbol,
        unsigned Arity)
{
  unsigned i;
  TERM res;
  res = term_CreateArity(Termstate, Symbol, Arity);
  for (i=0; i<Arity; ++i) term_SetArgument(res, i, NULL);
  return res;
}
TERM term_Create(TERMSTATE Termstate, SYMBOL Symbol,
   ARRAY Ar)
{
  TERM res;
  unsigned argcount;
  argcount = (Ar ? array_GetSize(Ar) : 0);
  res = term_CreateArity(Termstate, Symbol, argcount);
  if (argcount > 0)
    memcpy(res, Ar, array_GetSize(Ar)*sizeof(*res));
  return res;
}
TERM term_CreateValueConstant(TERMSTATE Termstate,
         SYMBOL Symbol, intptr_t Value)
{
  TERM res;
#ifdef SPASS_CHECK
  if (!symbol_IsValueConstant(Symbol)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal symbol:"
       "Not Value Constant.", __func__);
    misc_FinishErrorReport();
  }
#endif
  res = term_CreateArity(Termstate, Symbol, 1);
  res[term_ARITY] = 0;
  term_SetArgument(res, 0, (TERM)Value);
  return res;
}
TERM term_CreateAddFather(TERMSTATE Termstate,
     SYMBOL Symbol, ARRAY Ar)
{
  unsigned i;
  TERM res;
  res = term_Create(Termstate, Symbol, Ar);
  for (i = 0; i < term_GetArity(res); i++)
    term_RplacSuperterm(term_GetArgument(res, i), res);
  return res;
}
TERM term_GetNextStandardVar(TERMSTATE Termstate)
{
  return term_Create(Termstate,
       symbol_GetNextStandardVar(term_GetSymbstate(Termstate)),
       NULL);
}
void term_DeleteNoValueConstants(MEMORY Mem, TERM Term)
{
  unsigned i;
  for (i = 0; i < term_GetArity(Term); i++)
    term_DeleteNoValueConstants(Mem, term_GetArgument(Term, i));
  term_FreeNoValueConstants(Mem, Term);
}
void term_Delete(TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  if (term_IsValueConstant(Termstate, Term))
    symbol_GetDelFunc(term_GetSymbstate(Termstate),
        term_TopSymbol(Term))(term_GetMemory(Termstate), (intptr_t)term_GetValue(Termstate, Term));
  else
    for (i = 0; i < term_GetArity(Term); i++)
      term_Delete(Termstate, term_GetArgument(Term, i));
  term_Free(Termstate, Term);
}
void term_DeleteIterative(TERMSTATE Termstate, TERM Term)
{
  ARRAY stack;
  unsigned i;
  MEMORY mem;
  mem = term_GetMemory(Termstate);
  if (term_IsComplex(Term)) {
    stack = array_Push(mem, array_Create(mem, 1),
         (intptr_t)Term);
    while(!array_IsEmpty(stack)) {
      Term = (TERM)array_Pop(stack);
      if (term_IsComplex(Term)) {
 for (i = 0; i < term_GetArity(Term); i++)
   stack = array_Push(mem, stack,
        (intptr_t)term_GetArgument(Term, i));
      } else
 if (term_IsValueConstant(Termstate, Term))
   symbol_GetDelFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))(mem, (intptr_t)term_GetValue(Termstate, Term));
      term_Free(Termstate, Term);
    }
    array_Delete(mem, stack);
  }
  else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetDelFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))(mem, (intptr_t)term_GetValue(Termstate, Term));
    term_Free(Termstate, Term);
  }
}
BOOL term_EqualNoValues(TERM Term1, TERM Term2)
{
  unsigned i;
  if (Term1 == Term2)
    return TRUE;
  else {
    if (!term_EqualTopSymbols(Term1, Term2))
      return FALSE;
    else {
      if (term_GetArity(Term1) != term_GetArity(Term2))
 return FALSE;
      for (i = 0; i < term_GetArity(Term1); i++)
 if (!term_EqualNoValues(term_GetArgument(Term1, i), term_GetArgument(Term2, i)))
   return FALSE;
      return TRUE;
    }
  }
}
BOOL term_Equal(TERMSTATE Termstate, TERM Term1, TERM Term2)
{
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term1)
      || !term_IsTerm(Termstate, Term2)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (Term1 == Term2)
    return TRUE;
  else {
    if (!term_EqualTopSymbols(Term1, Term2))
      return FALSE;
    else {
      if (term_GetArity(Term1) != term_GetArity(Term2))
 return FALSE;
      for (i = 0; i < term_GetArity(Term1); i++)
 if (!term_Equal(Termstate, term_GetArgument(Term1, i),
   term_GetArgument(Term2, i)))
   return FALSE;
      if (term_IsValueConstant(Termstate, Term1) &&
   !symbol_GetEqualFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term1))
   (term_GetValue(Termstate, Term1), term_GetValue(Termstate, Term2)))
 return FALSE;
      return TRUE;
    }
  }
}
BOOL term_EqualIterative(TERMSTATE Termstate, TERM Term1, TERM Term2)
{
  ARRAY stack1, stack2;
  unsigned i;
  MEMORY mem;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term1)
      || !term_IsTerm(Termstate, Term2)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  mem = term_GetMemory(Termstate);
  stack1 = array_Push(mem, array_Create(mem, 1), (intptr_t)Term1);
  stack2 = array_Push(mem, array_Create(mem, 1), (intptr_t)Term2);
  while (!array_IsEmpty(stack1)) {
    Term1 = (TERM)array_Pop(stack1);
    Term2 = (TERM)array_Pop(stack2);
    if (!term_EqualTopSymbols(Term1,Term2) ||
 term_GetArity(Term1) != term_GetArity(Term2)) {
      array_Delete(mem, stack1);
      array_Delete(mem, stack2);
      return FALSE;
    }
    for (i = 0; i < term_GetArity(Term1); i++) {
      stack1 = array_Push(mem, stack1, (intptr_t)term_GetArgument(Term1, i));
      stack2 = array_Push(mem, stack2, (intptr_t)term_GetArgument(Term2, i));
    }
    if (term_IsValueConstant(Termstate, Term1) &&
 !symbol_GetEqualFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term1))
 (term_GetValue(Termstate, Term1), term_GetValue(Termstate, Term2)))
      return FALSE;
  }
  array_Delete(mem, stack1);
  array_Delete(mem, stack2);
  return TRUE;
}
BOOL term_VariableEqual(TERM Variable1, TERM Variable2)
{
  return term_EqualTopSymbols(Variable1, Variable2);
}
BOOL term_IsGround(TERMSTATE Termstate, TERM Term)
{
  ARRAY stack;
  unsigned i;
  MEMORY mem;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (term_IsComplex(Term)) {
    mem = term_GetMemory(Termstate);
    stack = array_Add(mem, array_Create(mem, 1), (intptr_t)Term);
    while (!array_IsEmpty(stack)) {
      Term = (TERM)array_Pop(stack);
      if (term_IsComplex(Term))
 for (i = 0; i < term_GetArity(Term); i++)
   stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
      else
 if (term_IsVariable(Termstate, Term)) {
          array_Delete(mem, stack);
   return FALSE;
 }
    }
    array_Delete(mem, stack);
    return TRUE;
  } else
    return !term_IsVariable(Termstate, Term);
}
BOOL term_IsTerm(TERMSTATE Termstate, TERM Term)
{
  return (Term != (TERM)NULL &&
   symbol_IsSymbol(term_GetSymbstate(Termstate),
     term_TopSymbol(Term)));
}
BOOL term_IsTermArray(TERMSTATE Termstate, ARRAY TermArray)
{
  unsigned i;
  for (i = 0; i < array_GetSize(TermArray); i++)
    if (!term_IsTerm(Termstate,
       (TERM)array_GetElement(TermArray, i)))
      return FALSE;
  return TRUE;
}
BOOL term_AllArgsAreVar(TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  for (i = 0; i < term_GetArity(Term); i++)
    if (!term_IsVariable(Termstate, term_GetArgument(Term, i)))
      return FALSE;
  return TRUE;
}
TERM term_CopyShallow(TERMSTATE Termstate, TERM Term)
{
  TERM res;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (term_IsValueConstant(Termstate, Term))
    res = term_CreateValueConstant(Termstate,
       term_TopSymbol(Term),
       symbol_GetCopyFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
       (term_GetMemory(Termstate), term_GetValue(Termstate, Term)));
  else {
    res = term_CreateArity(Termstate, term_TopSymbol(Term),
      term_GetArity(Term));
    if (term_GetArity(Term) > 0)
      memcpy(res, Term, term_GetArity(Term)*sizeof(*Term));
  }
  res[term_INDEX] = 0;
  res[term_STAMP] = Term[term_STAMP];
  res[term_SIZE] = Term[term_SIZE];
  return res;
}
TERM term_Copy(TERMSTATE Termstate, TERM Term)
{
  TERM res;
  unsigned i;
  if(!Term) return (TERM)NULL;
  res = term_CopyShallow(Termstate, Term);
  for (i = 0; i < term_GetArity(res); i++)
    term_SetArgument(res, i, term_Copy(Termstate,
           term_GetArgument(Term, i)));
  return res;
}
TERM term_CopyIterative(TERMSTATE Termstate, TERM Term)
{
  ARRAY termstack, idxstack;
  TERM oterm, topterm;
  unsigned i;
  MEMORY mem;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (term_IsComplex(Term)) {
    mem = term_GetMemory(Termstate);
    topterm = term_CopyShallow(Termstate, Term);
    termstack = array_Push(mem, array_Create(mem, 1),
      (intptr_t)topterm);
    idxstack = array_Push(mem, array_Create(mem, 1),
      (intptr_t)0);
    while (!array_IsEmpty(termstack)) {
      Term = (TERM)array_Pop(termstack);
      i = array_Pop(idxstack);
      oterm = term_GetArgument(Term, i);
      oterm = term_CopyShallow(Termstate, oterm);
      term_SetArgument(Term, i, oterm);
      if (i+1 < term_GetArity(Term)) {
 termstack = array_Push(mem, termstack,
          (intptr_t)Term);
 idxstack = array_Push(mem, idxstack,
          i+1);
      }
      if (term_IsComplex(oterm)) {
 termstack = array_Push(mem, termstack,
          (intptr_t)oterm);
 idxstack = array_Push(mem, idxstack, 0);
      }
    }
    array_Delete(mem, termstack);
    array_Delete(mem, idxstack);
    return topterm;
  } else
    return term_CopyShallow(Termstate, Term);
}
void term_PrintWithEmptyArgArrayNode(TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  if (Term == (TERM)NULL)
    fputs("(NULL)", stdout);
  else if (term_IsComplex(Term)) {
    putchar('(');
    symbol_Print(term_GetSymbstate(Termstate),
   term_TopSymbol(Term));
    putchar(' ');
    for (i = 0; i < term_GetArity(Term); i++)
      term_PrintWithEmptyArgArrayNode(Termstate,
          term_GetArgument(Term, i));
    putchar(')');
  } else if (term_IsVariable(Termstate, Term)) {
    symbol_Print(term_GetSymbstate(Termstate), term_TopSymbol(Term));
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (stdout, term_GetValue(Termstate, Term));
    else {
      putchar('(');
      symbol_Print(term_GetSymbstate(Termstate),
     term_TopSymbol(Term));
      putchar(')');
    }
  }
}
BOOL term_ReplaceSubtermBy(TERMSTATE Termstate, TERM Atom, TERM TermS, TERM TermT)
{
  BOOL Replaced;
  ARRAY Stack;
  unsigned i;
  MEMORY mem;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Atom) ||
      !term_IsTerm(Termstate, TermS) ||
      !term_IsTerm(Termstate, TermT) ||
      term_Equal(Termstate, Atom, TermS)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  Replaced = FALSE;
  mem = term_GetMemory(Termstate);
  TermS = term_Copy(Termstate, TermS);
  if (!term_Equal(Termstate, Atom, TermS) &&
      term_IsComplex(Atom)) {
    Stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Atom);
    while (!array_IsEmpty(Stack)) {
      Atom = (TERM)array_Pop(Stack);
      for (i = 0; i < term_GetArity(Atom); i++) {
 if (term_Equal(Termstate,
         term_GetArgument(Atom, i), TermS)) {
   Replaced = TRUE;
   term_Delete(Termstate, term_GetArgument(Atom, i));
   term_SetArgument(Atom, i, term_Copy(Termstate, TermT));
 } else
   Stack = array_Push(mem, Stack, (intptr_t)term_GetArgument(Atom, i));
      }
    }
    array_Delete(mem, Stack);
  }
  term_Delete(Termstate, TermS);
  return Replaced;
}
TERM term_ReplaceVariable(TERMSTATE Termstate, TERM Term,
     SYMBOL Symbol, TERM Repl)
{
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)
      || !term_IsTerm(Termstate, Repl) ||
      !symbol_IsVariable(term_GetSymbstate(Termstate), Symbol)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (symbol_Equal(term_TopSymbol(Term), Symbol)) {
    return term_Copy(Termstate, Repl);
  } else
    for (i = 0; i < term_GetArity(Term); i++)
      term_SetArgument(Term, i, term_ReplaceVariable(Termstate,
           term_GetArgument(Term, i),
           Symbol, Repl));
  return Term;
}
void term_ReplaceSymbol(TERMSTATE Termstate, TERM Term,
     SYMBOL Symbol, SYMBOL Repl)
{
  unsigned i;
  if (symbol_Equal(term_TopSymbol(Term), Symbol)) {
    term_RplacTop(Term, Repl);
  } else
    for (i = 0; i < term_GetArity(Term); i++)
      term_ReplaceSymbol(Termstate, term_GetArgument(Term, i), Symbol, Repl);
}
void term_ExchangeVariable(TERMSTATE Termstate, TERM Term,
      SYMBOL Old, SYMBOL New)
{
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) ||
      !symbol_IsVariable(term_GetSymbstate(Termstate), Old) ||
      !symbol_IsVariable(term_GetSymbstate(Termstate), New)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (symbol_Equal(term_TopSymbol(Term), Old))
    term_RplacTop(Term,New);
  else
    for (i = 0; i < term_GetArity(Term); i++)
      term_ExchangeVariable(Termstate,
       term_GetArgument(Term, i), Old, New);
}
TERM term_SubstituteVariable(TERMSTATE Termstate,
        SYMBOL Symbol,
        TERM Repl, TERM Term)
{
  BOOL Result;
  unsigned i;
  TERM New;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) ||
      !term_IsTerm(Termstate, Repl) ||
      !symbol_IsSymbol(term_GetSymbstate(Termstate), Symbol)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (symbol_Equal(term_TopSymbol(Term), Symbol)) {
    New = term_Copy(Termstate, Repl);
    term_Free(Termstate, Term);
    return New;
  } else {
    Result = FALSE;
    for (i = 0; i < term_GetArity(Term); i++) {
      New = term_SubstituteVariable(Termstate, Symbol, Repl, term_GetArgument(Term, i));
      if (New) {
        term_SetArgument(Term, i, New);
 Result = TRUE;
     }
    }
    return Result ? Term : (TERM)NULL;
  }
}
static int term_CompareByConstants(TERMSTATE Termstate,
       TERM Left, TERM Right)
{
  ARRAY lconsts, rconsts;
  int result;
  lconsts = term_ArrayOfConstants(Termstate, Left);
  rconsts = term_ArrayOfConstants(Termstate, Right);
  result = array_CompareMultisetsByElementDistribution(term_GetMemory(Termstate),
       lconsts, rconsts);
  array_Delete(term_GetMemory(Termstate), lconsts);
  array_Delete(term_GetMemory(Termstate), rconsts);
  return result;
}
static int term_CompareByFunctions(TERMSTATE Termstate,
       TERM Left, TERM Right)
{
  ARRAY lfuns, rfuns;
  int result;
  lfuns = term_ArrayOfFunctions(Termstate, Left);
  rfuns = term_ArrayOfFunctions(Termstate, Right);
  result = array_CompareMultisetsByElementDistribution(term_GetMemory(Termstate),
       lfuns, rfuns);
  array_Delete(term_GetMemory(Termstate), lfuns);
  array_Delete(term_GetMemory(Termstate), rfuns);
  return result;
}
static int term_CompareByVariables(TERMSTATE Termstate,
       TERM Left, TERM Right)
{
  ARRAY lvars, rvars;
  int result;
  lvars = term_ArrayOfVariables(Termstate, Left);
  rvars = term_ArrayOfVariables(Termstate, Right);
  result = array_CompareMultisetsByElementDistribution(term_GetMemory(Termstate),
       lvars, rvars);
  array_Delete(term_GetMemory(Termstate), lvars);
  array_Delete(term_GetMemory(Termstate), rvars);
  return result;
}
ARRAY term_ArrayOfConstants(TERMSTATE Termstate, TERM Term)
{
  ARRAY result;
  ARRAY aux;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  result = array_Create(term_GetMemory(Termstate), 1);
  if (symbol_IsConstant(term_TopSymbol(Term)))
    return array_Add(term_GetMemory(Termstate), result,
       (intptr_t) term_TopSymbol(Term));
  else {
    for (i = 0; i < term_GetArity(Term); i++) {
      aux = term_ArrayOfConstants(Termstate,
         term_GetArgument(Term, i));
      result = array_Append(term_GetMemory(Termstate),
       result, aux);
      array_Delete(term_GetMemory(Termstate), aux);
    }
    return result;
  }
}
ARRAY term_ArrayOfFunctions(TERMSTATE Termstate, TERM Term)
{
  ARRAY result, aux;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  result = array_Create(term_GetMemory(Termstate), 1);
  if (symbol_IsFunction(term_TopSymbol(Term))) {
    result = array_Add(term_GetMemory(Termstate),
         result, (intptr_t) term_TopSymbol(Term));
  }
  for (i = 0; i < term_GetArity(Term); i++) {
    aux = term_ArrayOfFunctions(Termstate,
       term_GetArgument(Term, i));
    result = array_Append(term_GetMemory(Termstate),
     result, aux);
    array_Delete(term_GetMemory(Termstate), aux);
  }
  return result;
}
static int term_CompareByArity(TERMSTATE Termstate,
          TERM Left, TERM Right)
{
  NAT lval, rval;
  SYMBOL lsymb, rsymb;
  int result;
  unsigned i;
  result = 0;
  lsymb = term_TopSymbol(Left);
  rsymb = term_TopSymbol(Right);
  if (symbol_IsVariable(term_GetSymbstate(Termstate), lsymb)) {
    if (symbol_IsVariable(term_GetSymbstate(Termstate), rsymb))
      return 0;
    else
      return 1;
  }
  else
    if (symbol_IsVariable(term_GetSymbstate(Termstate), rsymb))
      return -1;
  lval = term_GetArity(Left);
  rval = term_GetArity(Right);
  if (lval > rval)
    return -1;
  if (lval < rval)
    return 1;
  for (i = 0; i < term_GetArity(Left); i++) {
    result = term_CompareByArity(Termstate, term_GetArgument(Left, i),
     term_GetArgument(Right, i));
    if (result != 0)
      break;
  }
  return result;
}
int term_CompareTotal(TERMSTATE termstate,
          TERM Left, TERM Right)
{
  NAT lval, rval;
  SYMBOL lsymb, rsymb;
  int result;
  unsigned i;
  result = 0;
  lsymb = term_TopSymbol(Left);
  rsymb = term_TopSymbol(Right);
  if(term_IsValueConstant(termstate,Left)){
    if(term_IsValueConstant(termstate,Right)){
      intptr_t valLeft, valRight;
      valLeft = term_GetValue(termstate,Left);
      valRight = term_GetValue(termstate,Right);
      result = misc_IntCmp(&valLeft,&valRight);
    }
    else
      result = 1;
  }
  else if(term_IsValueConstant(termstate,Right)){
    result = -1;
  }
  else
    result = symbol_Compare(lsymb,rsymb);
  if(result != 0)
    return result;
  lval = term_GetArity(Left);
  rval = term_GetArity(Right);
  if (lval > rval)
    return -1;
  if (lval < rval)
    return 1;
  for (i = 0; i < lval; i++) {
    result = term_CompareTotal(termstate, term_GetArgument(Left, i),
     term_GetArgument(Right, i));
    if (result != 0)
      break;
  }
  return result;
}
int term_CompareAbstract(TERMSTATE Termstate,
    TERM Left, TERM Right)
{
  int result;
  int i;
  int functions;
  typedef int (*TERM_COMPARE_FUNCTION) (TERMSTATE, TERM, TERM);
  static const TERM_COMPARE_FUNCTION term_compare_functions [] = {
    term_CompareByArity,
    term_CompareByConstants,
    term_CompareByVariables,
    term_CompareByFunctions
  };
#ifdef SPASS_CHECK
  if (!(term_IsTerm(Termstate, Left) &&
 term_IsTerm(Termstate, Right))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  result = 0;
  functions = sizeof(term_compare_functions)/sizeof(TERM_COMPARE_FUNCTION);
  for (i = 0; i < functions; i++) {
    result = term_compare_functions[i](Termstate, Left, Right);
    if ( result != 0) {
      return result;
    }
  }
  return result;
}
BOOL term_CompareAbstractLEQ(TERMSTATE Termstate,
        TERM Left, TERM Right)
{
  return (term_CompareAbstract(Termstate, Left, Right) >= 0);
}
NAT term_ComputeSize(TERMSTATE Termstate, TERM Term)
{
  NAT Weight;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  Weight = 1;
  for (i = 0; i < term_GetArity(Term); i++)
    Weight += term_ComputeSize(Termstate, term_GetArgument(Term, i));
  return Weight;
}
NAT term_RootDistance(TERM Term)
{
  NAT Distance;
  Distance = 0;
  while (term_Superterm(Term) != (TERM)NULL) {
    Distance++;
    Term = term_Superterm(Term);
  }
  return Distance;
}
BOOL term_RootDistanceSmaller(TERM Term1, TERM Term2)
{
  return (term_RootDistance(Term1)<term_RootDistance(Term2));
}
void term_InstallSize(TERMSTATE Termstate, TERM Term)
{
  NAT Weight;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  Weight = 1;
  for (i = 0; i < term_GetArity(Term); i++) {
    term_InstallSize(Termstate, term_GetArgument(Term, i));
    Weight += term_Size(term_GetArgument(Term, i));
  };
  term_SetSize(Term, Weight);
}
NAT term_Depth(TERMSTATE Termstate, TERM Term)
{
  NAT depth, help;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  depth = 0;
  for (i = 0; i < term_GetArity(Term); i++) {
    help = term_Depth(Termstate, term_GetArgument(Term, i));
    if (help > depth)
      depth = help;
  }
  return (depth+1);
}
BOOL term_ContainsSymbol(TERMSTATE Termstate, TERM Term, SYMBOL Symbol)
{
  ARRAY stack;
  unsigned i;
  MEMORY mem;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) ||
      !symbol_IsSymbol(term_GetSymbstate(Termstate), Symbol)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  mem = term_GetMemory(Termstate);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  while(!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (term_TopSymbol(Term) == Symbol) {
      array_Delete(mem, stack);
      return TRUE;
    }
    else
      if (term_IsComplex(Term))
 for (i = 0; i < term_GetArity(Term); i++)
   stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
  }
  array_Delete(mem, stack);
  return FALSE;
}
TERM term_FindSubterm(TERMSTATE Termstate,
        TERM Term, SYMBOL Symbol)
{
  ARRAY stack;
  unsigned i;
  MEMORY mem;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) ||
      !symbol_IsSymbol(term_GetSymbstate(Termstate), Symbol)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  mem = term_GetMemory(Termstate);
  stack = array_Add(mem, array_Create(mem, 1), (intptr_t)Term);
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (term_TopSymbol(Term) == Symbol) {
      array_Delete(mem, stack);
      return Term;
    } else
      if (term_IsComplex(Term))
 for (i = 0; i < term_GetArity(Term); i++)
   stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
  }
  array_Delete(mem, stack);
  return NULL;
}
static int term_SharingTerm(TERMSTATE Termstate,
       TERM Term, TERM CompareTerm)
{
  unsigned i;
  int n;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  n = 0;
  if (Term == CompareTerm)
    n = 1;
  for (i = 0; i < term_GetArity(Term); i++)
    n += term_SharingTerm(Termstate, term_GetArgument(Term, i),
     CompareTerm);
  return n;
}
BOOL term_Sharing(TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  ARRAY stack;
  TERM actTerm;
  MEMORY mem;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  mem = term_GetMemory(Termstate);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  while (!array_IsEmpty(stack)) {
    actTerm = (TERM)array_Pop(stack);
    if (term_SharingTerm(Termstate, Term, actTerm) > 1) {
      array_Delete(mem, stack);
      return TRUE;
    }
    for (i = 0; i < term_GetArity(actTerm); i++)
      stack = array_Push(mem, stack, (intptr_t)term_GetArgument(actTerm, i));
  }
  array_Delete(mem, stack);
  return FALSE;
}
void term_AddFatherLinks(TERM Term)
{
  unsigned i;
  TERM ActTerm;
  term_RplacSuperterm(Term,(TERM)NULL);
  for (i = 0; i < term_GetArity(Term); i++) {
    ActTerm = term_GetArgument(Term, i);
    term_AddFatherLinks(ActTerm);
    term_RplacSuperterm(ActTerm,Term);
  }
}
BOOL term_FatherLinksEstablished(TERM Term)
{
  unsigned i;
  for (i = 0; i < term_GetArity(Term); i++)
    if (Term != term_Superterm(term_GetArgument(Term, i)) || !term_FatherLinksEstablished(term_GetArgument(Term, i)))
      return FALSE;
  return TRUE;
}
TERM term_TopLevelTerm(TERM Term)
{
  while (term_Superterm(Term))
    Term = term_Superterm(Term);
  return Term;
}
BOOL term_HasPointerSubterm(TERM Term, TERM Subterm)
{
  unsigned i;
  if (Term == Subterm)
    return TRUE;
  else {
    for (i = 0; i < term_GetArity(Term); i++) {
      if (term_HasPointerSubterm(term_GetArgument(Term, i), Subterm))
 return TRUE;
    }
  }
  return FALSE;
}
BOOL term_HasSubterm(TERMSTATE Termstate, TERM Term, TERM Subterm)
{
  unsigned i;
  if (term_Equal(Termstate, Term,Subterm))
    return TRUE;
  else {
    for (i = 0; i < term_GetArity(Term); i++)
      if (term_HasSubterm(Termstate,
     term_GetArgument(Term, i), Subterm))
 return TRUE;
  }
  return FALSE;
}
BOOL term_HasProperSuperterm(TERM Term, TERM Super)
{
  if (Term == Super)
    return FALSE;
  while (Term != (TERM) NULL) {
    if (Term == Super)
      return TRUE;
    else
      Term = term_Superterm(Term);
  }
  return FALSE;
}
void term_Print(TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    putchar('(');
    symbol_Print(term_GetSymbstate(Termstate),
   term_TopSymbol(Term));
    putchar(' ');
    for (i = 0; i < term_GetArity(Term); i++) {
      term_Print(Termstate, term_GetArgument(Term, i));
      fflush(stdout);
      if (i < term_GetArity(Term)-1)
 putchar(' ');
    }
    putchar(')');
  } else if (term_IsVariable(Termstate, Term)) {
    symbol_Print(term_GetSymbstate(Termstate),
   term_TopSymbol(Term));
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (stdout, term_GetValue(Termstate, Term));
    else {
      putchar('(');
      symbol_Print(term_GetSymbstate(Termstate), term_TopSymbol(Term));
      putchar(')');
    }
  }
}
static void term_PrettyPrintIntern(TERMSTATE Termstate,
       TERM Term, unsigned Depth)
{
  unsigned i;
  for (i=0; i < Depth; i++)
    fputs("  ", stdout);
  if (symbol_IsOperator(term_TopSymbol(Term))) {
    if (term_IsComplex(Term)) {
      symbol_Print(term_GetSymbstate(Termstate),
     term_TopSymbol(Term));
      putchar('(');
      fputs("\n", stdout);
      for (i = 0; i < term_GetArity(Term); i++) {
 term_PrettyPrintIntern(Termstate,
          term_GetArgument(Term, i), Depth+1);
 if (i < term_GetArity(Term)-1)
   fputs(",\n", stdout);
      }
      putchar(')');
    }
    else {
      if (term_IsVariable(Termstate, Term)) {
 symbol_Print(term_GetSymbstate(Termstate),
       term_TopSymbol(Term));
      }
      else {
 if (term_IsValueConstant(Termstate, Term))
   symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
     (stdout, term_GetValue(Termstate, Term));
 else {
   putchar('(');
   symbol_Print(term_GetSymbstate(Termstate),
         term_TopSymbol(Term));
   putchar(')');
 }
      }
    }
  }
  else {
    term_PrintPrefix(Termstate, Term);
  }
}
void term_PrettyPrint(TERMSTATE Termstate, TERM Term)
{
  term_PrettyPrintIntern(Termstate, Term, 0);
}
void term_FPrint(FILE* File, TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    putc('(', File);
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
    putc(' ', File);
    for (i = 0; i < term_GetArity(Term); i++) {
      term_FPrint(File, Termstate, term_GetArgument(Term, i));
      if (i < term_GetArity(Term)-1)
 putc(' ', File);
    }
    putc(')', File);
  } else if (term_IsVariable(Termstate, Term)) {
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (File, term_GetValue(Termstate, Term));
    else {
      putc('(', File);
      symbol_FPrint(File, term_GetSymbstate(Termstate),
      term_TopSymbol(Term));
      putc(')', File);
    }
  }
}
void term_TermArrayPrint(TERMSTATE Termstate, ARRAY ar)
{
  unsigned i;
  for (i = 0; i < array_GetSize(ar); i++) {
    term_Print(Termstate, (TERM)array_GetElement(ar, i));
    fflush(stdout);
    printf("\n");
    if (i < array_GetSize(ar)-1)
      putchar(' ');
  }
}
void term_TermArrayFPrint(FILE* File, TERMSTATE Termstate,
     ARRAY Ar)
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++) {
    term_FPrint(File, Termstate, (TERM)array_GetElement(Ar, i));
    if (i < array_GetSize(Ar)-1)
      putc(' ', File);
  }
}
void term_PrintPrefix(TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    symbol_Print(term_GetSymbstate(Termstate),
   term_TopSymbol(Term));
    putchar('(');
    for (i = 0; i < term_GetArity(Term); i++) {
      term_PrintPrefix(Termstate, term_GetArgument(Term, i));
      if (i < term_GetArity(Term)-1)
 putchar(',');
    }
    putchar(')');
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (stdout, term_GetValue(Termstate, Term));
    else {
      symbol_Print(term_GetSymbstate(Termstate),
     term_TopSymbol(Term));
    }
  }
}
void term_PrintPrefixI(TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    symbol_Print(term_GetSymbstate(Termstate),
   term_TopSymbol(Term));
    putchar('(');
    for (i = 0; i < term_GetArity(Term); i++) {
      term_PrintPrefixI(Termstate, term_GetArgument(Term, i));
      if (i < term_GetArity(Term)-1)
 putchar(',');
    }
    putchar(')');
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (stdout, term_GetValue(Termstate, Term));
    else
      if (term_IsConstant(Termstate, Term) && symbol_GetName(term_GetSymbstate(Termstate), term_TopSymbol(Term))[0] == 'i')
 {
   Term = (TERM)symbol_GetValue(term_GetSymbstate(Termstate), term_TopSymbol(Term));
   symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
     (stdout, term_GetValue(Termstate, Term));
 }
      else {
 symbol_Print(term_GetSymbstate(Termstate), term_TopSymbol(Term));
      }
  }
}
void term_PrintPrefixDatalog(TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    symbol_Print(term_GetSymbstate(Termstate),
   term_TopSymbol(Term));
    putchar('(');
    for (i = 0; i < term_GetArity(Term); i++) {
      term_PrintPrefixDatalog(Termstate, term_GetArgument(Term, i));
      if (i < term_GetArity(Term)-1)
 putchar(',');
    }
    putchar(')');
  } else {
    if (term_IsValueConstant(Termstate, Term)) {
      putchar('i');
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (stdout, term_GetValue(Termstate, Term));
    }
    else {
      if (symbol_IsVariable(term_GetSymbstate(Termstate),term_TopSymbol(Term)))
 putchar('?');
      symbol_Print(term_GetSymbstate(Termstate),
     term_TopSymbol(Term));
    }
  }
}
void term_FPrintPrefix(FILE* File, TERMSTATE Termstate, TERM Term, BOOL TPTP)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
    putc('(', File);
    for (i = 0; i < term_GetArity(Term); i++) {
      term_FPrintPrefix(File, Termstate, (TERM)term_GetArgument(Term, i),TPTP);
      if (i < term_GetArity(Term)-1)
 putc(',', File);
    }
    putc(')', File);
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (File, term_GetValue(Termstate, Term));
    else {
      if (TPTP && term_IsVariable(Termstate, Term))
 symbol_FPrintTPTPVariable(File, term_TopSymbol(Term));
      else
 symbol_FPrint(File, term_GetSymbstate(Termstate), term_TopSymbol(Term));
    }
  }
}
void term_TermArrayPrintPrefix(TERMSTATE Termstate, ARRAY Ar)
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++) {
    term_PrintPrefix(Termstate, (TERM)array_GetElement(Ar, i));
    if (i < array_GetSize(Ar)-1)
      putchar(',');
  }
}
void term_TermArrayFPrintPrefix(FILE* File, TERMSTATE Termstate,
    ARRAY Ar)
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++) {
    term_FPrintPrefix(File, Termstate, (TERM)array_GetElement(Ar, i), FALSE);
    if (i < array_GetSize(Ar)-1)
      putc(',', File);
  }
}
void term_FPrintPosition(FILE* File, TERM TopTerm, TERM Subterm)
{
  unsigned i;
  if (TopTerm == Subterm)
    return;
  for (i = 0; i < term_GetArity(TopTerm); i++) {
    if (term_HasPointerSubterm(term_GetArgument(TopTerm, i), Subterm)) {
      fprintf(File, "%u", i+1);
      if (Subterm != term_GetArgument(TopTerm, i)) {
 putc('.', File);
 term_FPrintPosition(File, (TERM)term_GetArgument(TopTerm, i), Subterm);
      }
      return;
    }
  }
  misc_StartErrorReport();
  misc_ErrorReport("\n In %s: Term isn't subterm of the other one.", __func__);
  misc_FinishErrorReport();
}
void term_FPrintSMT(FILE* File, TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    putc('(', File);
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
    putc(' ', File);
    for (i = 0; i < term_GetArity(Term); i++) {
      term_FPrintSMT(File, Termstate, term_GetArgument(Term, i));
      if (i < term_GetArity(Term)-1)
 putc(' ', File);
    }
    putc(')', File);
  } else if (term_IsVariable(Termstate, Term)) {
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (File, term_GetValue(Termstate, Term));
    else {
 symbol_FPrint(File, term_GetSymbstate(Termstate),
        term_TopSymbol(Term));
    }
  }
}
void term_FPrintSMTI(FILE* File, TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    putc('(', File);
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
    putc(' ', File);
    for (i = 0; i < term_GetArity(Term); i++) {
      term_FPrintSMTI(File, Termstate, term_GetArgument(Term, i));
      if (i < term_GetArity(Term)-1)
 putc(' ', File);
    }
    putc(')', File);
  } else if (term_IsVariable(Termstate, Term)) {
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (File, term_GetValue(Termstate, Term));
    else {
      if (term_IsConstant(Termstate, Term) && symbol_GetName(term_GetSymbstate(Termstate), term_TopSymbol(Term))[0] == 'i')
 {
   Term = (TERM)symbol_GetValue(term_GetSymbstate(Termstate), term_TopSymbol(Term));
   symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
     (File, term_GetValue(Termstate, Term));
 }
      else {
 symbol_FPrint(File, term_GetSymbstate(Termstate),
        term_TopSymbol(Term));
      }
    }
  }
}
void term_FPrintCHCI(FILE* File, TERMSTATE Termstate, TERM Term)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    putc('(', File);
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
    putc(' ', File);
    for (i = 0; i < term_GetArity(Term); i++) {
      term_FPrintCHCI(File, Termstate, term_GetArgument(Term, i));
      if (i < term_GetArity(Term)-1)
 putc(' ', File);
    }
    putc(')', File);
  } else if (term_IsVariable(Termstate, Term)) {
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (File, term_GetValue(Termstate, Term));
    else {
      if (term_IsConstant(Termstate, Term) && symbol_GetName(term_GetSymbstate(Termstate), term_TopSymbol(Term))[0] == 'i')
 {
   Term = (TERM)symbol_GetValue(term_GetSymbstate(Termstate), term_TopSymbol(Term));
   symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
     (File, term_GetValue(Termstate, Term));
 }
      else {
 printf("%u",symbol_GetIndex(term_TopSymbol(Term)));
      }
    }
  }
}
void term_FPrintSMTGC(FILE* File, TERMSTATE Termstate, TERM Term, const char* VarHead)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    putc('(', File);
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
    putc(' ', File);
    for (i = 0; i < term_GetArity(Term); i++) {
      term_FPrintSMTIGC(File, Termstate, term_GetArgument(Term, i),VarHead);
      if (i < term_GetArity(Term)-1)
 putc(' ', File);
    }
    putc(')', File);
  } else if (term_IsVariable(Termstate, Term)) {
    fprintf(File,"%s%lu",VarHead,(NAT)term_TopSymbol(Term));
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (File, term_GetValue(Termstate, Term));
    else {
      symbol_FPrint(File, term_GetSymbstate(Termstate),
      term_TopSymbol(Term));
    }
  }
}
void term_FPrintSMTIGC(FILE* File, TERMSTATE Termstate, TERM Term, const char* VarHead)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    putc('(', File);
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
    putc(' ', File);
    for (i = 0; i < term_GetArity(Term); i++) {
      term_FPrintSMTIGC(File, Termstate, term_GetArgument(Term, i),VarHead);
      if (i < term_GetArity(Term)-1)
 putc(' ', File);
    }
    putc(')', File);
  } else if (term_IsVariable(Termstate, Term)) {
    fprintf(File,"%s%lu",VarHead,(NAT)term_TopSymbol(Term));
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (File, term_GetValue(Termstate, Term));
    else {
      if (term_IsConstant(Termstate, Term) && symbol_GetName(term_GetSymbstate(Termstate), term_TopSymbol(Term))[0] == 'i')
 {
   Term = (TERM)symbol_GetValue(term_GetSymbstate(Termstate), term_TopSymbol(Term));
   symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
     (File, term_GetValue(Termstate, Term));
 }
      else {
 symbol_FPrint(File, term_GetSymbstate(Termstate),
        term_TopSymbol(Term));
      }
    }
  }
}
void term_FPrintCHCIGC(FILE* File, TERMSTATE Termstate, TERM Term, const char* VarHead)
{
  unsigned i;
  if (term_IsComplex(Term)) {
    putc('(', File);
    symbol_FPrint(File, term_GetSymbstate(Termstate),
    term_TopSymbol(Term));
    putc(' ', File);
    for (i = 0; i < term_GetArity(Term); i++) {
      term_FPrintCHCIGC(File, Termstate, term_GetArgument(Term, i),VarHead);
      if (i < term_GetArity(Term)-1)
 putc(' ', File);
    }
    putc(')', File);
  } else if (term_IsVariable(Termstate, Term)) {
    fprintf(File,"%s%lu",VarHead,(NAT)term_TopSymbol(Term));
  } else {
    if (term_IsValueConstant(Termstate, Term))
      symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
 (File, term_GetValue(Termstate, Term));
    else {
      if (term_IsConstant(Termstate, Term) && symbol_GetName(term_GetSymbstate(Termstate), term_TopSymbol(Term))[0] == 'i')
 {
   Term = (TERM)symbol_GetValue(term_GetSymbstate(Termstate), term_TopSymbol(Term));
   symbol_GetPrintFunc(term_GetSymbstate(Termstate), term_TopSymbol(Term))
     (File, term_GetValue(Termstate, Term));
 }
      else {
 printf("%u",symbol_GetIndex(term_TopSymbol(Term)));
      }
    }
  }
}
NAT term_Bytes(TERMSTATE Termstate, TERM Term)
{
  unsigned bytes, i;
  bytes = ((term_IsValueConstant(Termstate, Term) ? 1 :
     term_GetArity(Term)) + term_EXTRA)
    * sizeof(*Term) ;
  for (i = 0; i < term_GetArity(Term); i++)
    bytes += term_Bytes(Termstate, term_GetArgument(Term, i));
  return bytes;
}
ARRAY term_ArrayOfVariables(TERMSTATE Termstate, TERM Term)
{
  ARRAY stack, variables;
  unsigned i;
  MEMORY mem;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  mem = term_GetMemory(Termstate);
  variables = array_Create(mem, 1);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (term_IsComplex(Term))
      for (i = 0; i < term_GetArity(Term); i++)
 stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
    else
      if (term_IsVariable(Termstate, Term))
 variables = array_Add(mem, variables, (intptr_t)Term);
  }
  array_Delete(mem,stack);
  return variables;
}
void term_MarkVariables(TERMSTATE Termstate,
   TERM Term, NAT Mark)
{
  MEMORY mem;
  ARRAY stack;
  unsigned i;
#ifdef SPASS_CHECK
  if (!symbol_InBindingPhase(term_GetSymbstate(Termstate))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s:", __func__);
    misc_ErrorReport(" Called while not in binding phase.");
    misc_FinishErrorReport();
  }
#endif
  mem = term_GetMemory(Termstate);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (term_IsComplex(Term))
      for (i = 0; i < term_GetArity(Term); i++)
        stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
    else
      if (term_IsVariable(Termstate, Term))
 symbol_CreateBinding(term_GetSymbstate(Termstate),
        term_TopSymbol(Term), Mark);
  }
  array_Delete(mem, stack);
}
ARRAY term_VariableSymbols(TERMSTATE Termstate, TERM Term)
{
  MEMORY mem;
  ARRAY variables, stack;
  SYMBOL top;
  NAT actMark;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) ||
      symbol_InBindingPhase(term_GetSymbstate(Termstate))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input or context.", __func__);
    misc_FinishErrorReport();
  }
#endif
  symbol_StartBinding(term_GetSymbstate(Termstate));
  mem = term_GetMemory(Termstate);
  variables = array_Create(mem, 1);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  actMark = symbol_NewMark(term_GetSymbstate(Termstate));
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (term_IsComplex(Term))
      for (i = 0; i < term_GetArity(Term); i++)
 stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
    else {
      top = term_TopSymbol(Term);
      if (symbol_IsVariable(term_GetSymbstate(Termstate), top) &&
   !symbol_VarIsMarked(term_GetSymbstate(Termstate), top, actMark)) {
 variables = array_Add(mem, variables, (intptr_t)top);
 symbol_CreateBinding(term_GetSymbstate(Termstate), top, actMark);
      }
    }
  }
  symbol_StopBinding(term_GetSymbstate(Termstate));
  array_Delete(mem, stack);
  return variables;
}
BOOL term_IsLinear(TERMSTATE Termstate, TERM Term)
{
  MEMORY mem;
  ARRAY stack;
  SYMBOL top;
  NAT actMark;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) ||
      symbol_InBindingPhase(term_GetSymbstate(Termstate))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input or context.", __func__);
    misc_FinishErrorReport();
  }
#endif
  symbol_StartBinding(term_GetSymbstate(Termstate));
  mem = term_GetMemory(Termstate);
  stack = array_Push(mem, array_Create(mem, 5), (intptr_t)Term);
  actMark = symbol_NewMark(term_GetSymbstate(Termstate));
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (term_IsComplex(Term))
      for (i = 0; i < term_GetArity(Term); i++)
 stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
    else {
      top = term_TopSymbol(Term);
      if (symbol_IsVariable(term_GetSymbstate(Termstate), top)) {
 if (symbol_VarIsMarked(term_GetSymbstate(Termstate), top, actMark)) {
   symbol_StopBinding(term_GetSymbstate(Termstate));
   array_Delete(mem, stack);
   return FALSE;
 }
 else
   symbol_CreateBinding(term_GetSymbstate(Termstate), top, actMark);
      }
    }
  }
  symbol_StopBinding(term_GetSymbstate(Termstate));
  array_Delete(mem, stack);
  return TRUE;
}
unsigned term_NumberOfVariableSymbolsIntern(TERMSTATE Termstate, TERM Term, NAT Mark)
{
  SYMBOL top;
  unsigned i, result;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) ||
      !symbol_InBindingPhase(term_GetSymbstate(Termstate))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input or context.", __func__);
    misc_FinishErrorReport();
  }
#endif
  result = 0;
  if (term_IsComplex(Term)) {
    for (i = 0; i < term_GetArity(Term); i++)
      result += term_NumberOfVariableSymbolsIntern(Termstate, term_GetArgument(Term,i), Mark);
  }
  else {
    top = term_TopSymbol(Term);
    if (symbol_IsVariable(term_GetSymbstate(Termstate), top) &&
 !symbol_VarIsMarked(term_GetSymbstate(Termstate), top, Mark)) {
      result++;
      symbol_CreateBinding(term_GetSymbstate(Termstate), top, Mark);
    }
  }
  return result;
}
unsigned term_NumberOfVariableSymbols(TERMSTATE Termstate, TERM Term)
{
  SYMBOL top;
  NAT actMark;
  unsigned i, result;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) ||
      symbol_InBindingPhase(term_GetSymbstate(Termstate))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input or context.", __func__);
    misc_FinishErrorReport();
  }
#endif
  symbol_StartBinding(term_GetSymbstate(Termstate));
  result = 0;
  actMark = symbol_NewMark(term_GetSymbstate(Termstate));
  if (term_IsComplex(Term)) {
    for (i = 0; i < term_GetArity(Term); i++)
      result += term_NumberOfVariableSymbolsIntern(Termstate, term_GetArgument(Term,i), actMark);
  }
  else {
    top = term_TopSymbol(Term);
    if (symbol_IsVariable(term_GetSymbstate(Termstate), top) &&
 !symbol_VarIsMarked(term_GetSymbstate(Termstate), top, actMark)) {
      result++;
      symbol_CreateBinding(term_GetSymbstate(Termstate), top, actMark);
    }
  }
  symbol_StopBinding(term_GetSymbstate(Termstate));
  return result;
}
NAT term_NumberOfVarOccs(TERMSTATE Termstate, TERM Term)
{
  MEMORY mem;
  NAT Result;
  ARRAY stack;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  Result = 0;
  mem = term_GetMemory(Termstate);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (term_IsComplex(Term))
      for (i = 0; i < term_GetArity(Term); i++)
 stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
    else {
      if (symbol_IsVariable(term_GetSymbstate(Termstate),
       term_TopSymbol(Term)))
 Result++;
    }
  }
  array_Delete(mem, stack);
  return Result;
}
NAT term_CountSymbolOccurrences(TERMSTATE Termstate, TERM Term)
{
  MEMORY mem;
  NAT Result;
  ARRAY stack;
  unsigned i;
  misc_ASSERT(term_IsTerm(Termstate, Term));
  Result = 0;
  mem = term_GetMemory(Termstate);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (!term_IsVariable(Termstate, Term)) {
      Result++;
      for(i = 0; i < term_GetArity(Term); i++) {
        stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
      }
    }
  }
  array_Delete(mem, stack);
  return Result;
}
NAT term_NumberOfSymbolOccurrences(TERMSTATE Termstate, TERM Term, SYMBOL Symbol)
{
  NAT Result;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) ||
      !symbol_IsSymbol(term_GetSymbstate(Termstate), Symbol)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  Result = 0;
  if (symbol_Equal(term_TopSymbol(Term),Symbol))
    Result++;
  for (i = 0; i < term_GetArity(Term); i++)
    Result += term_NumberOfSymbolOccurrences(Termstate,
          term_GetArgument(Term, i),
          Symbol);
  return Result;
}
BOOL term_ContainsFunctions(TERMSTATE Termstate, TERM Term)
{
  MEMORY mem;
  ARRAY stack;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  mem = term_GetMemory(Termstate);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (term_IsComplex(Term)) {
      if (symbol_IsFunction(term_TopSymbol(Term)) && !symbol_IsConstant(term_TopSymbol(Term))) {
 array_Delete(mem, stack);
 return TRUE;
      }
      for(i = 0; i < term_GetArity(Term); i++)
 stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
    }
  }
  array_Delete(mem, stack);
  return FALSE;
}
BOOL term_ContainsVariable(TERMSTATE Termstate,
      TERM Term, SYMBOL Var)
{
  MEMORY mem;
  ARRAY stack;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) ||
      !symbol_IsSymbol(term_GetSymbstate(Termstate), Var)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  mem = term_GetMemory(Termstate);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (term_IsComplex(Term))
      for (i = 0; i < term_GetArity(Term); i++)
 stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
    else
      if (symbol_Equal(term_TopSymbol(Term),Var)) {
 array_Delete(mem, stack);
 return TRUE;
      }
  }
  array_Delete(mem, stack);
  return FALSE;
}
SYMBOL term_MaxVar(TERMSTATE Termstate, TERM Term)
{
  MEMORY mem;
  ARRAY stack;
  SYMBOL result;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  result = (SYMBOL)NULL;
  mem = term_GetMemory(Termstate);
  stack = array_Create(mem, 1);
#if defined(SPASS_SYMBOL_INDEXVARS)
  if (term_IsStandardVariable(Termstate, Term)) {
#else
  if (term_IsVariable(Termstate, Term)) {
#endif
    if (term_TopSymbol(Term)>result)
      result = term_TopSymbol(Term);
  }
  else
    if (term_IsComplex(Term))
      for (i = 0; i < term_GetArity(Term); i++)
 stack = array_Push(mem, stack,
      (intptr_t)term_GetArgument(Term, i));
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
#if defined(SPASS_SYMBOL_INDEXVARS)
    if (term_IsStandardVariable(Termstate, Term)) {
#else
    if (term_IsVariable(Termstate, Term)) {
#endif
      if (term_TopSymbol(Term)>result)
 result = term_TopSymbol(Term);
    }
    else
      if (term_IsComplex(Term))
 for (i = 0; i < term_GetArity(Term); i++)
   stack = array_Push(mem, stack,
        (intptr_t)term_GetArgument(Term, i));
  }
  array_Delete(mem, stack);
  return result;
}
TERM term_RenameVariablesInTerm(TERMSTATE Termstate, TERM Term, unsigned Offset)
{
  unsigned i;
  SYMBOL top;
  TERM result;
  top = term_TopSymbol(Term);
  if (symbol_IsVariable(term_GetSymbstate(Termstate), top))
    return term_Create(Termstate, top+Offset, NULL);
  result = term_CopyShallow(Termstate, Term);
  for (i = 0; i < term_GetArity(result); i++)
    term_SetArgument(result, i, term_RenameVariablesInTerm(Termstate, (TERM)Term[i], Offset));
  return result;
}
TERM term_Rename(TERMSTATE Termstate, TERM Term)
{
  MEMORY mem;
  ARRAY stack;
  SYMBOL Top;
  NAT ActMark;
  TERM ActTerm;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
  if (symbol_InBindingPhase(term_GetSymbstate(Termstate))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal context.", __func__);
    misc_FinishErrorReport();
  }
#endif
  symbol_StartBinding(term_GetSymbstate(Termstate));
  mem = term_GetMemory(Termstate);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  ActMark = symbol_OldMark(term_GetSymbstate(Termstate));
  ActTerm = Term;
  while (!array_IsEmpty(stack)) {
    ActTerm = (TERM)array_Pop(stack);
    if (term_IsComplex(ActTerm))
      for (i = 0; i < term_GetArity(ActTerm); i++)
 stack = array_Push(mem, stack,
      (intptr_t)term_GetArgument(ActTerm, i));
    else {
      Top = term_TopSymbol(ActTerm);
      if (symbol_IsVariable(term_GetSymbstate(Termstate), Top)) {
 if (!symbol_VarIsMarked(term_GetSymbstate(Termstate), Top, ActMark))
   symbol_CreateValueBinding(term_GetSymbstate(Termstate),
        Top, ActMark, (intptr_t)
        symbol_GetNextStandardVar(term_GetSymbstate(Termstate)));
 term_RplacTop(ActTerm,(SYMBOL)
        symbol_BindingValue(term_GetSymbstate(Termstate), Top));
      }
    }
  }
  symbol_StopBinding(term_GetSymbstate(Termstate));
  array_Delete(mem, stack);
  return Term;
}
SYMBOL term_GetRenamedVarSymbol(TERMSTATE Termstate, SYMBOL Var)
{
  NAT ActMark;
#ifdef SPASS_CHECK
  #ifdef SPASS_SYMBOL_INDEXVARS
  if (!symbol_IsStandardVariable(term_GetSymbstate(Termstate), Var)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
  #endif
#endif
  ActMark = symbol_OldMark(term_GetSymbstate(Termstate));
  if (symbol_VarIsMarked(term_GetSymbstate(Termstate), Var, ActMark))
    return (SYMBOL)symbol_BindingValue(term_GetSymbstate(Termstate), Var);
  return Var;
}
unsigned term_GetStampID(TERMSTATE Termstate)
{
  if (Termstate->stampusers >= Termstate->maxstampusers) {
    misc_StartUserErrorReport();
    misc_UserErrorReport("\n In %s: no more free stamp IDs.", __func__);
    misc_UserErrorReport("\n You have to increase the constant term_MAXSTAMPUSERS.");
    misc_FinishUserErrorReport();
  }
  return Termstate->stampusers++;
}
BOOL term_StampOverflow(TERMSTATE Termstate, unsigned ID)
{
  BOOL Result = FALSE;
  NAT i;
#ifdef SPASS_CHECK
  if (ID >= Termstate->maxstampusers) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (Termstate->stamp == NAT_MAX) {
    Termstate->stamp = 0;
    for (i = 0; i < Termstate->maxstampusers; i++)
      Termstate->stampoverflow[i] = TRUE;
    Termstate->stampoverflow[ID] = FALSE;
    Result = TRUE;
  } else if (Termstate->stampoverflow[ID]) {
    Termstate->stampoverflow[ID] = FALSE;
    Result = TRUE;
  }
  return Result;
}
void term_SetTermSubtermStamp(TERMSTATE Termstate, TERM Term)
{
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  term_SetTermStamp(Termstate, Term);
  for (i = 0; i < term_GetArity(Term); i++)
    term_SetTermSubtermStamp(Termstate, term_GetArgument(Term, i));
}
ARRAY term_ArrayOfAtoms(TERMSTATE Termstate, TERM Term, SYMBOL Predicate)
{
  ARRAY result, aux;
  unsigned i;
  result = array_Create(term_GetMemory(Termstate), 1);
  if (symbol_Equal(term_TopSymbol(Term), Predicate))
    return array_Add(term_GetMemory(Termstate),
       result, (intptr_t)Term);
  else {
    for (i = 0; i < term_GetArity(Term); i++) {
      aux = term_ArrayOfAtoms(Termstate,
     term_GetArgument(Term, i),
     Predicate);
      result = array_Append(term_GetMemory(Termstate),
       result, aux);
      array_Delete(term_GetMemory(Termstate), aux);
    }
    return result;
  }
}
#ifdef SPASS_CHECK
void term_StartStamp(TERMSTATE Termstate)
{
  if (Termstate->stampblocked) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal context, term stamp is already used.", __func__);
    misc_FinishErrorReport();
  }
  else {
    Termstate->stamp++;
    Termstate->stampblocked = TRUE;
  }
}
#endif
ARRAY term_FindAllAtoms(TERMSTATE Termstate,
   TERM Term, SYMBOL Predicate)
{
  MEMORY mem;
  ARRAY stack, result;
  unsigned i;
#ifdef SPASS_CHECK
  if (!term_IsTerm(Termstate, Term) || !symbol_IsPredicate(Predicate)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Illegal input.", __func__);
    misc_FinishErrorReport();
  }
#endif
  mem = term_GetMemory(Termstate);
  stack = array_Push(mem, array_Create(mem, 1), (intptr_t)Term);
  result = array_Create(mem, 1);
  while (!array_IsEmpty(stack)) {
    Term = (TERM)array_Pop(stack);
    if (term_TopSymbol(Term) == Predicate)
      result = array_Add(mem, result, (intptr_t)Term);
    else
      if (term_IsComplex(Term))
 for (i = 0; i < term_GetArity(Term); i++)
   stack = array_Push(mem, stack, (intptr_t)term_GetArgument(Term, i));
  }
  array_Delete(mem, stack);
  return result;
}
BOOL term_CheckTermIntern(TERMSTATE Termstate, TERM Term, BOOL Links)
{
  SYMBOL Top;
  unsigned i;
  if (!term_IsTerm(Termstate, Term))
    return FALSE;
  Top = term_TopSymbol(Term);
  if (symbol_IsSigSymbol(term_GetSymbstate(Termstate), Top) &&
      symbol_GetArity(term_GetSymbstate(Termstate), Top) != -1 &&
      symbol_GetArity(term_GetSymbstate(Termstate), Top) != (int)term_GetArity(Term))
    return FALSE;
  if (symbol_IsVariable(term_GetSymbstate(Termstate), Top) &&
      term_GetArity(Term) > 0)
    return FALSE;
  if (Links) {
    for (i = 0; i < term_GetArity(Term); i++) {
      if (term_Superterm(term_GetArgument(Term, i)) != Term ||
   !term_CheckTermIntern(Termstate, term_GetArgument(Term, i), Links))
 return FALSE;
    }
  }
  else {
    for (i = 0; i < term_GetArity(Term); i++) {
      if (term_Superterm(term_GetArgument(Term, i)) != term_Null() ||
   !term_CheckTermIntern(Termstate, term_GetArgument(Term, i), Links))
 return FALSE;
    }
  }
  return TRUE;
}
BOOL term_CheckTerm(TERMSTATE Termstate, TERM Term)
{
  if (term_IsComplex(Term) &&
      term_Superterm(term_FirstArgument(Term)) != term_Null())
    return term_CheckTermIntern(Termstate, Term, TRUE);
  else
    return term_CheckTermIntern(Termstate, Term, FALSE);
}
void term_GroundTermConstant(TERMSTATE Termstate, TERM Term, SYMBOL Constant)
{
  if (symbol_IsVariable(term_GetSymbstate(Termstate), term_TopSymbol(Term)))
    term_RplacTop(Term, Constant);
  else {
    unsigned i;
    for (i = 0; i < term_GetArity(Term); i++)
      term_GroundTermConstant(Termstate, (TERM)Term[i], Constant);
  }
}
void term_GroundTermConstants(TERMSTATE Termstate, TERM Term, ARRAY Constants)
{
  if (symbol_IsVariable(term_GetSymbstate(Termstate), term_TopSymbol(Term)))
    term_RplacTop(Term, (SYMBOL)Constants[term_TopSymbol(Term)]);
  else {
    unsigned i;
    for (i = 0; i < term_GetArity(Term); i++)
      term_GroundTermConstants(Termstate, (TERM)Term[i], Constants);
  }
}
BOOL term_CompareSizeSortingFunc(POINTER *Term1, POINTER *Term2)
{
  return (term_Size((TERM)*Term1) > term_Size((TERM)*Term2));
}
void term_ReplaceVarsWithConsts(TERMSTATE Termstate, TERM Term, ARRAY VarConst)
{
  if (symbol_IsVariable(term_GetSymbstate(Termstate), term_TopSymbol(Term)))
    term_RplacTop(Term, (SYMBOL)VarConst[term_TopSymbol(Term)]);
  else {
    unsigned i;
    for (i = 0; i < term_GetArity(Term); i++)
      term_ReplaceVarsWithConsts(Termstate, (TERM)Term[i], VarConst);
  }
}
