#ifdef DOC_BUILD_INTERNAL
#endif
#include "symbol.h"
int symbol_MinimalStandardVar(void)
{
  return 0;
}
SYMBSTATE symbol_Init(MEMORY mem, int types, int sig, int vars)
{
  SYMBSTATE symbstate;
  int i;
  symbstate = (SYMBSTATE)memory_Malloc(mem, sizeof(SYMBSTATE_NODE));
  symbstate->mem = mem;
  symbstate->sigsize = sig;
  symbstate->siglength = 0;
  symbstate->typesigsize = types;
  symbstate->typesiglength = 0;
  symbstate->maxvars = vars;
  symbstate->svarcounter = symbol_MinimalStandardVar();
  symbstate->ivarcounter = 1;
  symbstate->symbmark = 0;
  symbstate->varmark = (NAT *)memory_Malloc(mem, vars * sizeof(NAT));
  symbstate->varvalue = (intptr_t *)memory_Malloc(mem, vars * sizeof(intptr_t));
  symbstate->bindmark = symbol_NullMark() + 1;
  symbstate->bindphase = FALSE;
  symbstate->sig = (SYMBSIG)memory_Malloc(mem, sig * sizeof(SYMBSIG_NODE));
  symbstate->typesig = (SYMBTYPESIG)memory_Malloc(mem, types * sizeof(SYMBTYPESIG_NODE));
  for (i=0; i<vars; i++) {
    symbstate->varmark[i] = 0;
    symbstate->varvalue[i] = 0;
  }
  for (i=0; i < sig; i++) {
    symbstate->sig[i].name = (char *) NULL;
    symbstate->sig[i].length = 0;
    symbstate->sig[i].arity = 0;
    symbstate->sig[i].weight = 0;
    symbstate->sig[i].precedence = 0;
    symbstate->sig[i].result = -1;
    symbstate->sig[i].value = -1;
    symbstate->sig[i].tdinfo.arguments = (TYPE *)NULL;
  }
  for (i = 0; i < types; i++) {
    symbstate->typesig[i].name = (char *) NULL;
    symbstate->typesig[i].length = 0;
    symbstate->typesig[i].arity = 0;
    symbstate->typesig[i].arguments = (TYPE *)NULL;
  }
  symbstate->dummytype = symbol_CreateTypeConstant(symbstate, "dummy");
  symbstate->dummyconstant = symbol_CreateConstant(symbstate, symbstate->dummytype, "dummy");
  symbol_SetWeight(symbstate, symbstate->dummyconstant, 1);
  symbol_SetPrecedence(symbstate, symbstate->dummyconstant, 0);
  symbstate->idleconstant = symbol_CreateConstant(symbstate, symbstate->dummytype, "idle");
  return symbstate;
}
TYPE symbol_GetDummyType(SYMBSTATE Symbstate)
{
  return Symbstate->dummytype;
}
SYMBOL symbol_GetDummyConstant(SYMBSTATE Symbstate)
{
  return Symbstate->dummyconstant;
}
SYMBOL symbol_GetIdleConstant(SYMBSTATE Symbstate)
{
  return Symbstate->idleconstant;
}
MEMORY symbol_GetStateMemory(SYMBSTATE symbstate)
{
  return symbstate->mem;
}
SYMBSIG symbol_GetStateSig(SYMBSTATE symbstate)
{
  return symbstate->sig;
}
unsigned symbol_GetStateSigSize(SYMBSTATE symbstate)
{
  return symbstate->sigsize;
}
unsigned symbol_GetStateSigLength(SYMBSTATE symbstate)
{
  return symbstate->siglength;
}
void symbol_SetLength(SYMBSTATE symbstate, unsigned n)
{
  symbstate->siglength = n;
}
int symbol_GetMaxVars(SYMBSTATE symbstate)
{
  return symbstate->maxvars;
}
void symbol_SetMaxVars(SYMBSTATE symbstate, int n)
{
  symbstate->maxvars = n;
}
void symbol_AdjustStateMaxVars(SYMBSTATE symbstate)
{
  intptr_t *oldvalue;
  NAT *oldmark;
  unsigned oldmaxvars;
  unsigned i;
  oldmaxvars = symbol_GetMaxVars(symbstate);
  oldvalue = symbstate->varvalue;
  oldmark = symbstate->varmark;
  symbstate->maxvars = (unsigned)oldmaxvars * 1.5;
  symbstate->varvalue = (intptr_t *)memory_Malloc(symbstate->mem, symbstate->maxvars * sizeof(intptr_t));
  symbstate->varmark = (NAT *)memory_Malloc(symbstate->mem, symbstate->maxvars * sizeof(NAT));
  memcpy(symbstate->varvalue, oldvalue, oldmaxvars * sizeof(intptr_t));
  memcpy(symbstate->varmark, oldmark, oldmaxvars * sizeof(NAT));
  for (i = oldmaxvars; i < symbstate->maxvars; i++) {
    symbstate->varvalue[i] = (intptr_t)NULL;
    symbstate->varmark[i] = 0;
  }
  memory_Free(symbstate->mem, oldvalue, oldmaxvars * sizeof(intptr_t));
  memory_Free(symbstate->mem, oldmark, oldmaxvars * sizeof(NAT));
  return;
}
void symbol_AdjustStateMaxVarsLimit(SYMBSTATE Symbstate, unsigned Maxvars)
{
  intptr_t *oldvalue;
  NAT *oldmark;
  unsigned oldmaxvars;
  unsigned i;
  oldmaxvars = symbol_GetMaxVars(Symbstate);
#ifdef SPASS_CHECK
  if (oldmaxvars > Maxvars){
    misc_StartUserErrorReport();
    misc_UserErrorReport("%s: Symbol maxvar update with smaller limit.",__func__);
    misc_FinishUserErrorReport();
  }
#endif
  oldvalue = Symbstate->varvalue;
  oldmark = Symbstate->varmark;
  Symbstate->maxvars = Maxvars;
  Symbstate->varvalue = (intptr_t *)memory_Malloc(Symbstate->mem, Maxvars * sizeof(intptr_t));
  Symbstate->varmark = (NAT *)memory_Malloc(Symbstate->mem, Maxvars * sizeof(NAT));
  memcpy(Symbstate->varvalue, oldvalue, oldmaxvars * sizeof(intptr_t));
  memcpy(Symbstate->varmark, oldmark, oldmaxvars * sizeof(NAT));
  for (i = oldmaxvars; i < Maxvars; i++) {
    Symbstate->varvalue[i] = (intptr_t)NULL;
    Symbstate->varmark[i] = 0;
  }
  memory_Free(Symbstate->mem, oldvalue, oldmaxvars * sizeof(intptr_t));
  memory_Free(Symbstate->mem, oldmark, oldmaxvars * sizeof(NAT));
  return;
}
int symbol_GetStandardVarCounter(SYMBSTATE symbstate)
{
  return symbstate->svarcounter;
}
void symbol_ResetStandardVarCounter(SYMBSTATE symbstate)
{
  symbstate->svarcounter = 0;
}
void symbol_ResetStandardVarCounterNonZero(SYMBSTATE symbstate)
{
#if defined(SPASS_SYMBOL_INDEXVARS)
  symbstate->svarcounter = 2;
#else
  symbstate->svarcounter = 1;
#endif
}
void symbol_ResetStandardVarCounterVariable(SYMBSTATE Symbstate, SYMBOL Var)
{
  Symbstate->svarcounter = Var;
#if defined(SPASS_SYMBOL_INDEXVARS)
  Symbstate->svarcounter += 2;
#else
  Symbstate->svarcounter += 1;
#endif
}
void symbol_SetStandardVarCounter(SYMBSTATE symbstate, int n)
{
#if defined(SPASS_SYMBOL_INDEXVARS)
  if (n & 1)
    n++;
#endif
  symbstate->svarcounter = n;
}
int symbol_GetNextStandardVar(SYMBSTATE symbstate)
{
  int n;
  n = symbstate->svarcounter;
#if defined(SPASS_SYMBOL_INDEXVARS)
  symbstate->svarcounter = n + 2;
#else
  symbstate->svarcounter = n + 1;
#endif
  if (n >= symbol_GetMaxVars(symbstate))
    symbol_AdjustStateMaxVars(symbstate);
  return n;
}
#if defined(SPASS_SYMBOL_INDEXVARS)
int symbol_GetIndexVarCounter(SYMBSTATE symbstate)
{
  return symbstate->ivarcounter;
}
int symbol_GetNextIndexVar(SYMBSTATE symbstate)
{
  int n;
  n = symbstate->ivarcounter;
  symbstate->ivarcounter = n + 2;
  if (n >= symbol_GetMaxVars(symbstate))
    symbol_AdjustStateMaxVars(symbstate);
  return n;
}
void symbol_ResetIndexVarCounter(SYMBSTATE symbstate)
{
  symbstate->ivarcounter = 0;
}
void symbol_SetIndexVarCounter(SYMBSTATE symbstate, int n)
{
  if (!(n & 1))
    n++;
  symbstate->ivarcounter = n;
}
#endif
BOOL symbol_IsVariable(SYMBSTATE symbstate, SYMBOL var)
{
  return (var >= 0 && var < symbol_GetMaxVars(symbstate));
}
BOOL symbol_IsVariableFast(SYMBOL var)
{
  return (var >= 0);
}
#if defined(SPASS_SYMBOL_INDEXVARS)
BOOL symbol_IsStandardVariable(SYMBSTATE symbstate, SYMBOL var)
{
  return (symbol_IsVariable(symbstate, var) && !(var & 1));
}
BOOL symbol_IsIndexVariable(SYMBSTATE symbstate, SYMBOL var)
{
  return (symbol_IsVariable(symbstate, var) && (var & 1));
}
#endif
SYMBOL symbol_SetIndexType(int index, SYMBTYPE type)
{
  return ((index << SYMBTBITS) + type);
}
SYMBTYPE symbol_GetType(SYMBOL symb)
{
  return ((-symb) & SYMBTMASK);
}
unsigned symbol_GetIndex(SYMBOL symb)
{
  return ((-symb) >> SYMBTBITS);
}
SYMBOL symbol_IndexGetSymbol(SYMBSTATE symbstate, int index)
{
  return -((int)((index << SYMBTBITS) + symbol_GetStateSig(symbstate)[index].type));
}
BOOL symbol_IsConstant(SYMBOL symb)
{
  return (symb < 0 && symbol_GetType(symb) == CONSTANT);
}
BOOL symbol_IsValueConstant(SYMBOL symb)
{
  return (symb < 0 && symbol_GetType(symb) == VALUECONSTANT);
}
BOOL symbol_IsPredicate(SYMBOL symb)
{
  return (symb < 0 && symbol_GetType(symb) == PREDICATE);
}
BOOL symbol_IsFunction(SYMBOL symb)
{
  return (symb < 0 && symbol_GetType(symb) == FUNCTION);
}
BOOL symbol_IsOperator(SYMBOL symb)
{
  return (symb < 0 && symbol_GetType(symb) == OPERATOR);
}
BOOL symbol_IsSymbol(SYMBSTATE symbstate, SYMBOL symb)
{
  return (symbol_IsVariable(symbstate, symb) || (symb < 0 && symbol_GetIndex(symb) < symbol_GetStateSigLength(symbstate)));
}
BOOL symbol_IsSigSymbol(SYMBSTATE symbstate, SYMBOL symb)
{
  return (symb < 0 && symbol_GetIndex(symb) < symbol_GetStateSigLength(symbstate));
}
BOOL symbol_Equal(SYMBOL symb1, SYMBOL symb2)
{
  return (symb1 == symb2);
}
int symbol_Compare(SYMBOL symb1, SYMBOL symb2)
{
  int res;
  res = misc_IntCmp(&symb1,&symb2);
#ifdef SPASS_CHECK
  if(symbol_IsValueConstant(symb1)){
    misc_StartUserErrorReport();
    misc_ErrorReport("\n In %s:", __func__);
    misc_UserErrorReport("%s: can't compare value constant",__func__);
    misc_FinishUserErrorReport();
  }
#endif
  return res;
}
int symbol_CompareName(SYMBSTATE symbstate, SYMBOL symb1, SYMBOL symb2)
{
  char *n1,*n2;
  n1 = symbol_GetName(symbstate,symb1);
  n2 = symbol_GetName(symbstate,symb2);
  if (n1==NULL && n2 == NULL)
    return symbol_Compare(symb1,symb2);
  if(n1==NULL)
    return 1;
  if(n2==NULL)
    return -1;
  return strcmp(n1,n2);
}
void symbol_PrintSymbolType(SYMBOL symb)
{
  switch ((-symb) & 3) {
  case CONSTANT:
    printf("constant");
    break;
  case VALUECONSTANT:
    printf("valueconstant");
    break;
  case PREDICATE:
    printf("predicate");
    break;
  case FUNCTION:
    printf("function");
    break;
  case OPERATOR:
    printf("operator");
    break;
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s:", __func__);
    misc_ErrorReport("\n Unknown symbol type. ");
    misc_FinishErrorReport();
  }
}
intptr_t symbol_GetValue(SYMBSTATE symbstate, SYMBOL symb)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symb)].value;
}
BOOL symbol_ValueUndefined(SYMBSTATE symbstate, SYMBOL symb)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return (symbsig[symbol_GetIndex(symb)].value == -1);
}
void symbol_SetValue(SYMBSTATE symbstate, SYMBOL symb, intptr_t value)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  symbsig[symbol_GetIndex(symb)].value = value;
}
int symbol_GetArity(SYMBSTATE symbstate, SYMBOL symb)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symb)].arity;
}
char * symbol_GetName(SYMBSTATE symbstate, SYMBOL symb)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symb)].name;
}
void symbol_SetName(SYMBSTATE symbstate, SYMBOL symb, const char * name)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  if (symbsig[symbol_GetIndex(symb)].name) {
    string_StringFree(symbol_GetStateMemory(symbstate), symbsig[symbol_GetIndex(symb)].name);
    symbsig[symbol_GetIndex(symb)].length = 0;
  }
  if (name){
    symbsig[symbol_GetIndex(symb)].name = string_StringCopy(symbstate->mem, name);
    symbsig[symbol_GetIndex(symb)].length = strlen(name);
  }
}
TYPE symbol_GetResultType(SYMBSTATE symbstate, SYMBOL symb)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symb)].result;
}
TYPE * symbol_GetArgumentTypes(SYMBSTATE symbstate, SYMBOL symb)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symb)].tdinfo.arguments;
}
SYMBVALDEL symbol_GetDelFunc(SYMBSTATE symbstate, SYMBOL symb)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symb)].tdinfo.avalfuncs.delfunc;
}
SYMBVALCOPY symbol_GetCopyFunc(SYMBSTATE symbstate, SYMBOL symb)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symb)].tdinfo.avalfuncs.copyfunc;
}
SYMBVALEQUAL symbol_GetEqualFunc(SYMBSTATE symbstate, SYMBOL symb)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symb)].tdinfo.avalfuncs.equalfunc;
}
SYMBVALPRINT symbol_GetPrintFunc(SYMBSTATE symbstate, SYMBOL symb)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symb)].tdinfo.avalfuncs.printfunc;
}
void symbol_AdjustStateSigSize(SYMBSTATE symbstate)
{
  SYMBSIG oldsig;
  unsigned oldsize;
  unsigned i;
  oldsig = symbol_GetStateSig(symbstate);
  oldsize = symbstate->sigsize;
  symbstate->sigsize = (unsigned)symbstate->sigsize * 1.5;
  symbstate->sig = (SYMBSIG)memory_Malloc(symbstate->mem, symbstate->sigsize * sizeof(SYMBSIG_NODE));
  memcpy(symbstate->sig, oldsig, oldsize * sizeof(SYMBSIG_NODE));
  for (i = oldsize; i < symbstate->sigsize; i++) {
    symbstate->sig[i].name = (char *) NULL;
    symbstate->sig[i].length = 0;
    symbstate->sig[i].arity = 0;
    symbstate->sig[i].precedence = 0;
    symbstate->sig[i].weight = 0;
    symbstate->sig[i].mark = 0;
    symbstate->sig[i].result = -1;
    symbstate->sig[i].value = -1;
    symbstate->sig[i].tdinfo.arguments = (TYPE *)NULL;
  }
  memory_Free(symbstate->mem, oldsig, oldsize * sizeof(SYMBSIG_NODE));
}
void symbol_AdjustStateTypeSigSize(SYMBSTATE symbstate)
{
  SYMBTYPESIG oldtypesig;
  unsigned oldsize;
  unsigned i;
  oldtypesig = symbstate->typesig;
  oldsize = symbstate->typesigsize;
  symbstate->typesigsize = (unsigned)symbstate->typesigsize * 1.5;
  symbstate->typesig = (SYMBTYPESIG)memory_Malloc(symbstate->mem, symbstate->typesigsize * sizeof(SYMBTYPESIG_NODE));
  memcpy(symbstate->typesig, oldtypesig, oldsize * sizeof(SYMBTYPESIG_NODE));
  for (i = oldsize; i < symbstate->typesigsize; i++) {
    symbstate->typesig[i].name = (char *) NULL;
    symbstate->typesig[i].length = 0;
    symbstate->typesig[i].arity = 0;
    symbstate->typesig[i].arguments = (TYPE *)NULL;
  }
  memory_Free(symbstate->mem, oldtypesig, oldsize * sizeof(SYMBTYPESIG_NODE));
}
SYMBOL symbol_CreateConstant(SYMBSTATE symbstate, TYPE result, const char * name)
{
  unsigned length;
  SYMBSIG symbsig;
  SYMBOL symbol;
  length = symbol_GetStateSigLength(symbstate);
  if (length == symbol_GetStateSigSize(symbstate))
    symbol_AdjustStateSigSize(symbstate);
  symbsig = symbol_GetStateSig(symbstate);
  if (name){
    symbsig[length].name = string_StringCopy(symbstate->mem, name);
    symbsig[length].length = strlen(name);
  }
  symbsig[length].arity = 0;
  symbsig[length].mark = 0;
  symbsig[length].result = result;
  symbsig[length].value = -1;
  symbsig[length].type = CONSTANT;
  symbsig[length].tdinfo.arguments = (TYPE *)NULL;
  symbsig[length].index = -1;
  symbol_SetLength(symbstate, length + 1);
  symbol = symbol_SetIndexType(length, CONSTANT);
  return -symbol;
}
SYMBOL symbol_CreateValueConstant(SYMBSTATE symbstate, TYPE result, const char * name,
      SYMBVALDEL DelFunc, SYMBVALPRINT PrintFunc, SYMBVALCOPY CopyFunc, SYMBVALEQUAL EqualFunc)
{
  unsigned length;
  SYMBSIG symbsig;
  SYMBOL symbol;
  length = symbol_GetStateSigLength(symbstate);
  if (length == symbol_GetStateSigSize(symbstate))
    symbol_AdjustStateSigSize(symbstate);
  symbsig = symbol_GetStateSig(symbstate);
  if (name) {
    symbsig[length].name = string_StringCopy(symbstate->mem, name);
    symbsig[length].length = strlen(name);
  }
  symbsig[length].arity = 0;
  symbsig[length].result = result;
  symbsig[length].value = -1;
  symbsig[length].mark = 0;
  symbsig[length].type = VALUECONSTANT;
  symbsig[length].index = -1;
  symbsig[length].tdinfo.avalfuncs.delfunc = DelFunc;
  symbsig[length].tdinfo.avalfuncs.printfunc = PrintFunc;
  symbsig[length].tdinfo.avalfuncs.copyfunc = CopyFunc;
  symbsig[length].tdinfo.avalfuncs.equalfunc = EqualFunc;
  symbol_SetLength(symbstate, length + 1);
  symbol = symbol_SetIndexType(length, VALUECONSTANT);
  return -symbol;
}
SYMBOL symbol_CreatePredicate(SYMBSTATE symbstate, TYPE result, const char * name, int arity)
{
  unsigned length;
  SYMBSIG symbsig;
  SYMBOL symbol;
  length = symbol_GetStateSigLength(symbstate);
  if (length == symbol_GetStateSigSize(symbstate))
    symbol_AdjustStateSigSize(symbstate);
  symbsig = symbol_GetStateSig(symbstate);
  if (name) {
    symbsig[length].name = string_StringCopy(symbstate->mem, name);
    symbsig[length].length = strlen(name);
  }
  symbsig[length].arity = arity;
  symbsig[length].mark = 0;
  symbsig[length].result = result;
  symbsig[length].value = -1;
  symbsig[length].type = PREDICATE;
  symbsig[length].index = -1;
  if (arity != 0)
    symbsig[length].tdinfo.arguments = memory_Malloc(symbstate->mem, ((arity < 0) ? sizeof(TYPE) : sizeof(TYPE)*arity));
  else
    symbsig[length].tdinfo.arguments = (TYPE *)NULL;
  symbol_SetLength(symbstate, length + 1);
  symbol = symbol_SetIndexType(length, PREDICATE);
  return -symbol;
}
void symbol_CleanAllValues(SYMBSTATE Symbstate)
{
  unsigned length, i;
  SYMBSIG symbsig;
  length = symbol_GetStateSigLength(Symbstate);
  symbsig = symbol_GetStateSig(Symbstate);
  for (i=0;i<length;i++)
    symbsig[i].value = -1;
}
SYMBOL symbol_CreateFunction(SYMBSTATE symbstate, TYPE result, const char * name, int arity)
{
  unsigned length;
  SYMBSIG symbsig;
  SYMBOL symbol;
  length = symbol_GetStateSigLength(symbstate);
  if (length == symbol_GetStateSigSize(symbstate))
    symbol_AdjustStateSigSize(symbstate);
  symbsig = symbol_GetStateSig(symbstate);
  if (name) {
    symbsig[length].name = string_StringCopy(symbstate->mem, name);
    symbsig[length].length = strlen(name);
  }
  symbsig[length].arity = arity;
  symbsig[length].mark = 0;
  symbsig[length].result = result;
  symbsig[length].value = -1;
  symbsig[length].type = FUNCTION;
  symbsig[length].index = -1;
  if (arity != 0)
    symbsig[length].tdinfo.arguments = memory_Malloc(symbstate->mem, ((arity < 0) ? sizeof(TYPE) : sizeof(TYPE)*arity));
  else {
    misc_StartUserErrorReport();
    misc_UserErrorReport("%s: functions with zero arguments have to be created as constants.",__func__);
    misc_FinishUserErrorReport();
    symbsig[length].tdinfo.arguments = (TYPE *)NULL;
  }
  symbol_SetLength(symbstate, length + 1);
  symbol = symbol_SetIndexType(length, FUNCTION);
  return -symbol;
}
SYMBOL symbol_CreateOperator(SYMBSTATE symbstate, TYPE result, const char * name, int arity)
{
  unsigned length;
  SYMBSIG symbsig;
  SYMBOL symbol;
  length = symbol_GetStateSigLength(symbstate);
  if (length == symbol_GetStateSigSize(symbstate))
    symbol_AdjustStateSigSize(symbstate);
  symbsig = symbol_GetStateSig(symbstate);
  if (name) {
    symbsig[length].name = string_StringCopy(symbstate->mem, name);
    symbsig[length].length = strlen(name);
  }
  symbsig[length].arity = arity;
  symbsig[length].mark = 0;
  symbsig[length].result = result;
  symbsig[length].value = -1;
  symbsig[length].type = OPERATOR;
  symbsig[length].index = -1;
  if (arity != 0)
    symbsig[length].tdinfo.arguments = memory_Malloc(symbstate->mem, sizeof(TYPE)*abs(arity));
  else
    symbsig[length].tdinfo.arguments = (TYPE *)NULL;
  symbol_SetLength(symbstate, length + 1);
  symbol = symbol_SetIndexType(length, OPERATOR);
  return -symbol;
}
void symbol_SetArgumentType(SYMBSTATE symbstate, SYMBOL symbol, TYPE arg, int position)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  (symbsig[symbol_GetIndex(symbol)].tdinfo.arguments)[position] = arg;
}
void symbol_PrintSigDetailed(SYMBSTATE symbstate, SYMBOL symbol)
{
  int i, index, arity;
  index = symbol_GetIndex(symbol);
  arity = symbstate->sig[index].arity;
  printf("%s ", symbstate->sig[index].name);
  symbol_PrintSymbolType(symbol);
  printf(" %d Resulttype ", arity);
  symbol_PrintType(symbstate, symbstate->sig[index].result);
  printf(" ");
  if (arity != 0) {
    printf(" Argumenttypes (");
    if (arity < 0)
      arity = 1;
    for (i=0; i < arity; i++) {
      symbol_PrintType(symbstate, (symbstate->sig[index].tdinfo.arguments)[i]);
      if (i+1< arity)
 printf(", ");
    }
    printf(")");
  }
}
void symbol_Print(SYMBSTATE symbstate, SYMBOL symbol)
{
  symbol_FPrint(stdout,symbstate,symbol);
}
void symbol_FPrint(FILE *File, SYMBSTATE symbstate, SYMBOL symbol)
{
  char* name;
  if (symbol_IsVariable(symbstate, symbol))
#if defined(SPASS_SYMBOL_INDEXVARS)
    if (symbol_IsStandardVariable(symbstate, symbol))
      fprintf(File, "x%lu", (NAT)symbol);
    else
      fprintf(File, "i%lu", (NAT)symbol);
#else
    fprintf(File, "x%lu", (NAT)symbol);
#endif
  else{
    name = symbol_GetName(symbstate, symbol);
    if(name)
      fprintf(File, "%s", symbol_GetName(symbstate, symbol));
    else
      fprintf(File, "__SPASS_UNNAMED_0x%"PRIxPTR, symbol);
  }
}
void symbol_FPrintTPTPVariable(FILE *File, SYMBOL symbol)
{
  fprintf(File, "X%lu", (NAT)symbol);
}
void symbol_Free(SYMBSTATE symbstate)
{
  int arity;
  SYMBSIG symbsig;
  MEMORY mem ;
  unsigned i;
  symbsig = symbol_GetStateSig(symbstate);
  mem = symbstate->mem;
  for (i=0; i < symbol_GetStateSigLength(symbstate) ; i++) {
    if (symbsig[i].name) {
      string_StringFree(mem, symbsig[i].name);
    }
    arity = symbsig[i].arity;
    if (arity != 0) {
      if (arity < 0)
 arity = abs(arity);
      memory_Free(mem, symbsig[i].tdinfo.arguments, sizeof(TYPE)*arity);
    }
  }
  for (i=0; i<symbstate->typesiglength ; i++) {
    if (symbstate->typesig[i].name)
      string_StringFree(mem, symbstate->typesig[i].name);
    if (symbstate->typesig[i].arity != 0)
      memory_Free(mem, symbstate->typesig[i].arguments, sizeof(TYPE)*abs(symbstate->typesig[i].arity));
  }
  memory_Free(mem, symbstate->varmark, symbol_GetMaxVars(symbstate) * sizeof(NAT));
  memory_Free(mem, symbstate->varvalue, symbol_GetMaxVars(symbstate) * sizeof(intptr_t));
  memory_Free(mem, symbsig, sizeof(SYMBSIG_NODE) * symbol_GetStateSigSize(symbstate));
  memory_Free(mem, symbstate->typesig, sizeof(SYMBTYPESIG_NODE) * symbstate->typesigsize);
  memory_Free(mem, symbstate, sizeof(SYMBSTATE_NODE));
}
#ifdef SPASS_CHECK
void symbol_StartBinding(SYMBSTATE symbstate)
{
  symbstate->bindphase =TRUE;
}
void symbol_StopBinding(SYMBSTATE symbstate)
{
  symbstate->bindphase =FALSE;
}
BOOL symbol_InBindingPhase(SYMBSTATE symbstate)
{
  return symbstate->bindphase;
}
#else
void symbol_StartBinding(SYMBSTATE symbstate)
{
  return;
}
void symbol_StopBinding(SYMBSTATE symbstate)
{
  return;
}
#endif
NAT symbol_NullMark(void)
{
  return 0;
}
NAT symbol_GetBindingMark(SYMBSTATE symbstate, SYMBOL Var)
{
  return symbstate->varmark[Var];
}
void symbol_SetBindingMark(SYMBSTATE symbstate, SYMBOL Var, NAT n)
{
  symbstate->varmark[Var] = n;
}
intptr_t symbol_BindingValue(SYMBSTATE symbstate, SYMBOL Var)
{
  return symbstate->varvalue[Var];
}
void symbol_SetBindingValue(SYMBSTATE symbstate, SYMBOL Var, intptr_t Value)
{
  symbstate->varvalue[Var] = Value;
}
void symbol_CreateBinding(SYMBSTATE symbstate, SYMBOL Var, NAT Mark)
{
  symbol_SetBindingMark(symbstate, Var, Mark);
}
void symbol_ClearBinding(SYMBSTATE symbstate, SYMBOL Var)
{
  symbol_SetBindingMark(symbstate, Var, symbol_NullMark());
}
void symbol_CreateValueBinding(SYMBSTATE symbstate, SYMBOL Var, NAT Mark, intptr_t Value)
{
  symbol_SetBindingMark(symbstate, Var, Mark);
  symbol_SetBindingValue(symbstate, Var, Value);
}
BOOL symbol_VarIsMarked(SYMBSTATE symbstate, SYMBOL Var, NAT Mark)
{
  return symbol_GetBindingMark(symbstate, Var) >= Mark;
}
NAT symbol_NewMark(SYMBSTATE symbstate)
{
  NAT Mark;
  Mark = symbstate->bindmark;
  if (Mark == NAT_MAX) {
    int i;
    for (i = 0; i < symbol_GetMaxVars(symbstate) ; i++)
      symbol_SetBindingMark(symbstate, i, symbol_NullMark());
    Mark = 1;
  }
  Mark++;
  symbstate->bindmark = Mark;
  return Mark;
}
NAT symbol_NewSigMark(SYMBSTATE symbstate, BOOL New)
{
  NAT Mark;
  Mark = symbstate->symbmark;
  if (New || Mark == NAT_MAX) {
    SYMBSIG symbsig;
    unsigned i;
    symbsig = symbol_GetStateSig(symbstate);
    for (i=0; i<symbol_GetStateSigLength(symbstate) ; i++)
      symbsig[i].mark = 0;
    Mark = 0;
  }
  Mark++;
  symbstate->symbmark = Mark;
  return Mark;
}
void symbol_SetSigMark(SYMBSTATE symbstate, SYMBOL symbol, NAT mark)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  symbsig[symbol_GetIndex(symbol)].mark = mark;
}
NAT symbol_GetSigMark(SYMBSTATE symbstate, SYMBOL symbol)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symbol)].mark;
}
BOOL symbol_SigIsMarked(SYMBSTATE symbstate, SYMBOL symbol, NAT mark)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(symbstate);
  return symbsig[symbol_GetIndex(symbol)].mark == mark;
}
NAT symbol_OldMark(SYMBSTATE symbstate)
{
  return symbstate->bindmark - 1;
}
TYPE symbol_CreateTypeConstant(SYMBSTATE symbstate, const char * name)
{
  unsigned length;
  length = symbstate->typesiglength;
  if (length == symbstate->typesigsize) {
    symbol_AdjustStateTypeSigSize(symbstate);
  }
  symbstate->typesig[length].name = string_StringCopy(symbstate->mem, name);
  symbstate->typesig[length].length = strlen(name);
  symbstate->typesig[length].arity = 0;
  symbstate->typesig[length].arguments = (TYPE *)NULL;
  symbstate->typesiglength = length + 1;
  return (TYPE)length;
}
TYPE symbol_CreateTypeClass(SYMBSTATE symbstate, const char * name, int n)
{
  unsigned length;
  if (n < 2) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s:", __func__);
    misc_ErrorReport("\n Type classes must have at least two elements. ");
    misc_FinishErrorReport();
  }
  length = symbstate->typesiglength;
  if (length == symbstate->typesigsize) {
    symbol_AdjustStateTypeSigSize(symbstate);
  }
  symbstate->typesig[length].name = string_StringCopy(symbstate->mem, name);
  symbstate->typesig[length].length = strlen(name);
  symbstate->typesig[length].arity = -n;
  symbstate->typesig[length].arguments = memory_Malloc(symbstate->mem, sizeof(TYPE)*n);
  symbstate->typesiglength = length + 1;
  return (TYPE)length;
}
BOOL symbol_TypeClassContainsType(SYMBSTATE symbstate, TYPE Typeclass, TYPE Type)
{
  int i;
  for(i=0;i<abs(symbstate->typesig[Typeclass].arity);i++)
    if (symbstate->typesig[Typeclass].arguments[i] == Type)
      return TRUE;
  return FALSE;
}
void symbol_ClassAddType(SYMBSTATE symbstate, TYPE type, TYPE argtype, int position)
{
  (symbstate->typesig[type].arguments)[position] = argtype;
}
BOOL symbol_IsConstantType(SYMBSTATE symbstate, TYPE type)
{
  return (symbstate->typesig[type].arity == 0);
}
BOOL symbol_IsConstructorType(SYMBSTATE symbstate, TYPE type)
{
  return (symbstate->typesig[type].arity > 0);
}
BOOL symbol_IsClassType(SYMBSTATE symbstate, TYPE type)
{
  return (symbstate->typesig[type].arity < 0);
}
char* symbol_TypeName(SYMBSTATE Symbstate, TYPE Type)
{
  return Symbstate->typesig[Type].name;
}
void symbol_PrintType(SYMBSTATE symbstate, TYPE type)
{
  int i, arity;
  arity = symbstate->typesig[type].arity;
  printf("%s %s %d", symbstate->typesig[type].name, (arity == 0 ? "Constant" : (arity < 0 ? "Class" : "Constructor")), abs(arity));
  if (arity != 0) {
    printf(" (");
    for (i=0; i < abs(arity); i++) {
      symbol_PrintType(symbstate, (symbstate->typesig[type].arguments)[i]);
      if (i+1<abs(arity))
 printf(", ");
    }
    printf(")");
  }
}
TYPING symbol_CreateVarTyping(MEMORY Mem, int Vars)
{
  TYPING result;
  int i;
  result = (TYPING)memory_Malloc(Mem, (Vars + 1) * sizeof(TYPE));
  result[0] = Vars;
  result++;
  for (i=0;i<Vars;i++)
    result[i] = 0;
  return result;
}
unsigned symbol_VarTypingSize(TYPING Typing)
{
  return (unsigned)Typing[-1];
}
TYPING symbol_CopyVarTyping(MEMORY Mem, TYPING Typing, int Vars)
{
  if (Typing) {
    TYPING result;
    int i;
    result = (TYPING)memory_Malloc(Mem, (Vars + 1) * sizeof(TYPE));
    result[0] = Vars;
    result++;
    for (i=0;i<Vars;i++)
      result[i] = Typing[i];
    return result;
  }
  return (TYPING)NULL;
}
void symbol_DeleteVarTyping(MEMORY Mem, TYPING Typing)
{
  Typing--;
  memory_Free(Mem, Typing, (Typing[0]+1) * sizeof(TYPE));
}
void symbol_SetVarTyping(TYPING Typing, SYMBOL Var, TYPE Type)
{
#ifdef SPASS_CHECK
  if (Var < 0 || Var >= Typing[-1]) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s:", __func__);
    misc_ErrorReport("\n Var: %ld is not supported variable.", Var);
    misc_FinishErrorReport();
  }
#endif
  Typing[Var] = Type;
}
void symbol_ClearVarTyping(SYMBSTATE Symbstate, TYPING Typing, SYMBOL Var)
{
  Typing[Var] = 0;
}
void symbol_ReplaceVarTyping(TYPING Typing1, TYPING Typing2, SYMBOL Var)
{
  while (Var < Typing1[-1]) {
    Typing1[Var] = Typing2[Var];
    Var++;
  }
}
TYPING symbol_ExtendVarTyping(MEMORY Mem, TYPING Typing, int Newmaxvar)
{
  TYPING result;
  int i,oldmaxvar;
  Typing--;
  oldmaxvar = Typing[0];
  result = (TYPING)memory_Realloc(Mem, Typing, (oldmaxvar + 1)* sizeof(TYPE), (Newmaxvar + 1) * sizeof(TYPE));
  result[0] = Newmaxvar;
  result++;
  for (i=oldmaxvar;i<Newmaxvar;i++)
    result[i] = 0;
  return result;
}
TYPE symbol_GetVarTypingType(TYPING Typing, SYMBOL Var)
{
#ifdef SPASS_CHECK
  if(Var < 0 || Var >= Typing[-1]) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s:", __func__);
    misc_ErrorReport("\n Var: %ld is not a variable or out of bound %ld.", Var, Typing[-1]);
    misc_FinishErrorReport();
  }
#endif
  return Typing[Var];
}
void symbol_PrintVarTypingType(SYMBSTATE Symbstate, TYPE Type)
{
  printf("%s", Symbstate->typesig[Type].name);
}
void symbol_PrintTyping(SYMBSTATE Symbstate, TYPING Typing)
{
  unsigned i;
  for (i=0;i<symbol_VarTypingSize(Typing);i++) {
    symbol_Print(Symbstate, i);
    printf(":");
    symbol_PrintVarTypingType(Symbstate, symbol_GetVarTypingType(Typing, i));
    printf(" ");
  }
}
BOOL symbol_PrecedenceGreater(SYMBSTATE Symbstate, SYMBOL Symbol1, SYMBOL Symbol2)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(Symbstate);
  return symbsig[symbol_GetIndex(Symbol1)].precedence > symbsig[symbol_GetIndex(Symbol2)].precedence;
}
BOOL symbol_PrecedenceSmaller(SYMBSTATE Symbstate, SYMBOL Symbol1, SYMBOL Symbol2)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(Symbstate);
  return symbsig[symbol_GetIndex(Symbol1)].precedence < symbsig[symbol_GetIndex(Symbol2)].precedence;
}
void symbol_SetPrecedence(SYMBSTATE Symbstate, SYMBOL Symbol, NAT Precedence)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(Symbstate);
  symbsig[symbol_GetIndex(Symbol)].precedence = Precedence;
}
void symbol_SigSetPrecedenceWeight(SYMBSIG Symbsig, unsigned Index, NAT Precedence, NAT Weight)
{
  Symbsig[Index].precedence = Precedence;
  Symbsig[Index].weight = Weight;
}
BOOL symbol_SigIsConstant(SYMBSIG Symbsig, unsigned Index)
{
  return Symbsig[Index].type == CONSTANT;
}
void symbol_SetWeight(SYMBSTATE Symbstate, SYMBOL Symbol, NAT Weight)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(Symbstate);
  symbsig[symbol_GetIndex(Symbol)].weight = Weight;
}
NAT symbol_GetWeight(SYMBSTATE Symbstate, SYMBOL Symbol)
{
  SYMBSIG symbsig;
  symbsig = symbol_GetStateSig(Symbstate);
  return symbsig[symbol_GetIndex(Symbol)].weight;
}
