#ifdef DOC_BUILD_INTERNAL
#endif
#include "groundgen.h"
GROUNDGEN groundgen_Create(MEMORY mem, SCLSTATE state, SHARER sharer)
{
  GROUNDGEN groundgen;
  unsigned i, ar;
  SYMBOL symb;
  groundgen = memory_Malloc(mem, sizeof(GROUNDGEN_NODE));
  groundgen->mem = mem;
  groundgen->state = state;
  groundgen->sharer = sharer;
  groundgen->groundterms = array_Create(mem, 1);
  groundgen->dp = array_Create(mem, 1);
  groundgen->numterms = array_Create(mem, 1);
  groundgen->maxarity = 1;
  for (i = 0; i < array_GetSize(state_GetFunctions(state)); i++) {
    if (symbol_GetArity(state_GetSymbstate(groundgen->state), (SYMBOL)state_GetFunctions(state)[i]) > (int)groundgen->maxarity) {
      groundgen->maxarity = symbol_GetArity(state_GetSymbstate(state), (SYMBOL)state_GetFunctions(state)[i]);
    }
  }
  groundgen->functions = array_Create(mem, groundgen->maxarity);
  for (i = 0; i < groundgen->maxarity; i++) {
    groundgen->functions = array_Add(mem, groundgen->functions, (intptr_t)array_Create(mem, 1));
  }
  for (i = 0; i < array_GetSize(state_GetFunctions(state)); i++) {
    symb = (SYMBOL)array_GetElement(state_GetFunctions(state), i);
    ar = symbol_GetArity(state_GetSymbstate(state), symb);
    groundgen->functions[ar-1] = (intptr_t)array_Add(mem, (ARRAY)groundgen->functions[ar-1], symb);
  }
  for (i = 0; i < array_GetSize(state_GetConstants(state)); i++) {
    groundgen->groundterms = array_Add(mem, groundgen->groundterms, (intptr_t)sharing_GetSharedTermByArgs(sharer, (SYMBOL)state_GetConstants(state)[i], NULL));
  }
  groundgen->dp = array_Add(mem, groundgen->dp, (intptr_t)array_Create(mem, groundgen->maxarity));
  for (i = 0; i < groundgen->maxarity; i++) {
    groundgen->dp[0] = (intptr_t)array_Add(mem, (ARRAY)groundgen->dp[0], (intptr_t)array_Create(mem, 1));
  }
  for (i = 0; i < array_GetSize(groundgen->groundterms); i++) {
    ((ARRAY)groundgen->dp[0])[0] = (intptr_t)array_Add(mem, (ARRAY)((ARRAY)groundgen->dp[0])[0], groundgen->groundterms[i]);
  }
  groundgen->dp = array_Add(mem, groundgen->dp, (intptr_t)array_Create(mem, groundgen->maxarity));
  for (i = 0; i < groundgen->maxarity; i++) {
    groundgen->dp[1] = (intptr_t)array_Add(mem, (ARRAY)groundgen->dp[1], (intptr_t)array_Create(mem, 1));
  }
  groundgen->numsymbols = 0;
  groundgen->arity = 0;
  groundgen->tuple = 0;
  groundgen->function = 0;
  groundgen->start = array_Create(mem, 2);
  groundgen->start = array_Add(mem, groundgen->start, 0);
  groundgen->start = array_Add(mem, groundgen->start, array_GetSize(groundgen->groundterms));
  groundgen->numterms = array_Add(mem, groundgen->numterms, (intptr_t)array_Create(mem, groundgen->maxarity));
  for (i = 0; i < groundgen->maxarity; i++) {
    groundgen->numterms[0] = (intptr_t)array_Add(mem, (ARRAY)groundgen->numterms[0], 0);
  }
  ((ARRAY)groundgen->numterms[0])[0] = (intptr_t)array_GetSize(state_GetConstants(state));
  return groundgen;
}
void groundgen_Delete(GROUNDGEN groundgen)
{
  unsigned i, j, k;
  ARRAY tmp0, tmp1;
  array_Delete(groundgen->mem, groundgen->start);
  array_Delete(groundgen->mem, groundgen->groundterms);
  for (i = 0; i < array_GetSize(groundgen->dp); i++) {
    tmp0 = (ARRAY)array_GetElement(groundgen->dp, i);
    array_Delete(groundgen->mem, (ARRAY)array_GetElement(tmp0, 0));
    for (j = 1; j < array_GetSize(tmp0); j++) {
      tmp1 = (ARRAY)array_GetElement(tmp0, j);
      for (k = 0; k < array_GetSize(tmp1); k++) {
        array_Delete(groundgen->mem, (ARRAY)array_GetElement(tmp1, k));
      }
      array_Delete(groundgen->mem, tmp1);
    }
    array_Delete(groundgen->mem, tmp0);
  }
  array_Delete(groundgen->mem, groundgen->dp);
  for (i = 0; i < array_GetSize(groundgen->functions); i++) {
    array_Delete(groundgen->mem, (ARRAY)array_GetElement(groundgen->functions, i));
  }
  array_Delete(groundgen->mem, groundgen->functions);
  for (i = 0; i < array_GetSize(groundgen->numterms); i++) {
    array_Delete(groundgen->mem, (ARRAY)array_GetElement(groundgen->numterms, i));
  }
  array_Delete(groundgen->mem, groundgen->numterms);
  memory_Free(groundgen->mem, groundgen, sizeof(GROUNDGEN_NODE));
}
ARRAY groundgen_GetCurrentGroundterms(GROUNDGEN groundgen)
{
  return groundgen->groundterms;
}
void groundgen_AtomStreamSetProfit(ATOMSTREAM atomstream, int profit)
{
  atomstream->profit = profit;
}
int groundgen_AtomStreamGetProfit(ATOMSTREAM atomstream)
{
  return atomstream->profit;
}
void groundgen_AtomStreamIncreaseProfit(ATOMSTREAM atomstream, int profit)
{
  atomstream->profit += profit;
}
BOOL groundgen_AtomStreamIsFromConjecture(ATOMSTREAM atomstream)
{
  return atomstream->is_from_conjecture;
}
void groundgen_AtomStreamSetFromConjecture(ATOMSTREAM atomstream, BOOL is_from_conjecture)
{
  atomstream->is_from_conjecture = is_from_conjecture;
}
TERM groundgen_AtomStreamGetAtom(ATOMSTREAM atomstream)
{
  return atomstream->atom;
}
SHARER groundgen_GetSharer(GROUNDGEN groundgen)
{
  return groundgen->sharer;
}
TERM groundgen_GenerateNextTerm(GROUNDGEN groundgen)
{
  TERM next;
  ARRAY tmp;
  unsigned i;
#ifdef SPASS_CHECK
  if (array_IsEmpty(state_GetFunctions(groundgen->state))) {
    misc_StartErrorReport();
    misc_ErrorReport("In %s: No next term can be generated since there are no functions\n", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (array_IsEmpty(state_GetFunctions(groundgen->state))) return NULL;
  while (groundgen->function == array_GetSize((ARRAY)groundgen->functions[groundgen->arity])) {
    groundgen->function = 0;
    if (groundgen->arity == 0) {
      if (groundgen->tuple+1 < array_GetSize((ARRAY)((ARRAY)groundgen->dp[groundgen->numsymbols])[0])) {
        groundgen->tuple++;
        continue;
      }
      groundgen->tuple = 0;
      if (groundgen->maxarity == 1 || groundgen->numsymbols == 0) {
        groundgen->numsymbols++;
        groundgen->start = array_Add(groundgen->mem, groundgen->start, array_GetSize(groundgen->groundterms));
        groundgen->dp = array_Add(groundgen->mem, groundgen->dp, (intptr_t)array_Create(groundgen->mem, groundgen->maxarity));
        for (i = 0; i < groundgen->maxarity; i++) {
          groundgen->dp[groundgen->numsymbols+1] = (intptr_t)array_Add(groundgen->mem, (ARRAY)groundgen->dp[groundgen->numsymbols+1], (intptr_t)array_Create(groundgen->mem, 1));
        }
        continue;
      }
      groundgen->arity++;
      groundgen->prevnum = 0;
      groundgen->prevterm = 0;
      groundgen->prevtuple = 0;
    }
    while (groundgen->prevtuple == array_GetSize((ARRAY)((ARRAY)groundgen->dp[groundgen->numsymbols - groundgen->prevnum - 1])[groundgen->arity - 1]) || groundgen->prevterm == array_GetSize((ARRAY)((ARRAY)groundgen->dp[groundgen->prevnum])[0])) {
      if (groundgen->prevterm == array_GetSize((ARRAY)((ARRAY)groundgen->dp[groundgen->prevnum])[0])) {
        groundgen->prevnum++;
        groundgen->prevterm = 0;
        groundgen->prevtuple = 0;
      } else {
        groundgen->prevterm++;
        groundgen->prevtuple = 0;
      }
      if (groundgen->prevnum == groundgen->numsymbols) {
        groundgen->prevnum = 0;
        if (groundgen->arity+1 == groundgen->maxarity) {
          groundgen->arity = 0;
          groundgen->numsymbols++;
          groundgen->start = array_Add(groundgen->mem, groundgen->start, array_GetSize(groundgen->groundterms));
          groundgen->tuple = 0;
          groundgen->dp = array_Add(groundgen->mem, groundgen->dp, (intptr_t)array_Create(groundgen->mem, groundgen->maxarity));
          for (i = 0; i < groundgen->maxarity; i++) {
            groundgen->dp[groundgen->numsymbols+1] = (intptr_t)array_Add(groundgen->mem, (ARRAY)groundgen->dp[groundgen->numsymbols+1], (intptr_t)array_Create(groundgen->mem, 1));
          }
          if (!array_IsEmpty((ARRAY)((ARRAY)groundgen->dp[groundgen->numsymbols])[0])) {
            break;
          }
        }
        groundgen->arity++;
      }
    }
    if (groundgen->arity > 0) {
      if (groundgen->arity == 1) {
        tmp = array_Add(groundgen->mem, array_Create(groundgen->mem, 1), ((ARRAY)((ARRAY)groundgen->dp[groundgen->numsymbols - groundgen->prevnum - 1])[0])[groundgen->prevtuple]);
      } else {
        tmp = array_Copy(groundgen->mem, (ARRAY)((ARRAY)((ARRAY)groundgen->dp[groundgen->numsymbols - groundgen->prevnum - 1])[groundgen->arity - 1])[groundgen->prevtuple]);
      }
      tmp = array_Add(groundgen->mem, tmp, ((ARRAY)((ARRAY)groundgen->dp[groundgen->prevnum])[0])[groundgen->prevterm]);
      groundgen->tuple = array_GetSize((ARRAY)((ARRAY)groundgen->dp[groundgen->numsymbols])[groundgen->arity]);
      ((ARRAY)groundgen->dp[groundgen->numsymbols])[groundgen->arity] = (intptr_t)array_Add(groundgen->mem, (ARRAY)((ARRAY)groundgen->dp[groundgen->numsymbols])[groundgen->arity], (intptr_t)tmp);
      groundgen->prevtuple++;
    }
  }
  if (groundgen->arity == 0) {
    tmp = array_Add(groundgen->mem, array_Create(groundgen->mem, 1), ((ARRAY)((ARRAY)groundgen->dp[groundgen->numsymbols])[0])[groundgen->tuple]);
    next = sharing_GetSharedTermByArgs(groundgen->sharer, (SYMBOL)((ARRAY)groundgen->functions[groundgen->arity])[groundgen->function], tmp);
    array_Delete(groundgen->mem, tmp);
  } else {
    next = sharing_GetSharedTermByArgs(groundgen->sharer, (SYMBOL)((ARRAY)groundgen->functions[groundgen->arity])[groundgen->function], (ARRAY)((ARRAY)((ARRAY)groundgen->dp[groundgen->numsymbols])[groundgen->arity])[groundgen->tuple]);
  }
  groundgen->groundterms = array_Add(groundgen->mem, groundgen->groundterms, (intptr_t)next);
  ((ARRAY)groundgen->dp[groundgen->numsymbols+1])[0] = (intptr_t)array_Add(groundgen->mem, (ARRAY)((ARRAY)groundgen->dp[groundgen->numsymbols+1])[0], (intptr_t)next);
  groundgen->function++;
  return (TERM)array_Top(groundgen->groundterms);
}
void groundgen_ComputeNextNumTerms(GROUNDGEN groundgen) {
  unsigned index, i, j;
  groundgen->numterms = array_Add(groundgen->mem, groundgen->numterms, (intptr_t)array_Create(groundgen->mem, groundgen->maxarity));
  index = array_GetSize(groundgen->numterms) - 1;
  groundgen->numterms[index] = (intptr_t)array_Add(groundgen->mem, (ARRAY)groundgen->numterms[index], 0);
  for (i = 0; i < groundgen->maxarity; i++) {
    ((ARRAY)groundgen->numterms[index])[0] += array_GetSize((ARRAY)groundgen->functions[i]) * ((ARRAY)groundgen->numterms[index - 1])[i];
  }
  for (i = 1; i < groundgen->maxarity; i++) {
    groundgen->numterms[index] = (intptr_t)array_Add(groundgen->mem, (ARRAY)groundgen->numterms[index], 0);
    for (j = 0; j < index; j++) {
      ((ARRAY)groundgen->numterms[index])[i] += ((ARRAY)groundgen->numterms[j])[0] * ((ARRAY)groundgen->numterms[index-j-1])[i-1];
    }
  }
}
unsigned long long groundgen_NumTermsWithNumSymbols(GROUNDGEN groundgen, unsigned numsymbols) {
  while (array_GetSize(groundgen->numterms) < numsymbols) {
    groundgen_ComputeNextNumTerms(groundgen);
  }
  return ((ARRAY)groundgen->numterms[numsymbols - 1])[0];
}
unsigned long long groundgen_NumTermsWithLeqNumSymbols(GROUNDGEN groundgen, unsigned numsymbols) {
  unsigned result, i;
  while (array_GetSize(groundgen->numterms) < numsymbols) {
    groundgen_ComputeNextNumTerms(groundgen);
  }
  result = 0;
  for (i = 0; i < numsymbols; i++) {
    result += ((ARRAY)groundgen->numterms[i])[0];
  }
  return result;
}
BOOL groundgen_AtMostKGroundAtoms(GROUNDGEN groundgen, SCLSTATE state, unsigned k)
{
  unsigned i, j, arity, numconstants;
  unsigned long long cur;
  if (!array_IsEmpty(state_GetFunctions(state))) {
    return FALSE;
  }
  numconstants = groundgen_NumTermsWithNumSymbols(groundgen, 1);
  for (i = 0; i < array_GetSize(state_GetPredicates(state)); i++) {
    arity = symbol_GetArity(state_GetSymbstate(state), (SYMBOL)array_GetElement(state_GetPredicates(state), i));
    if (arity == 0) {
      if (!k) {
        return FALSE;
      }
      k--;
    } else {
      cur = 1;
      for (j = 0; j <= arity; j++) {
        if (j) {
          cur *= numconstants;
        }
        if (cur > k) {
          return FALSE;
        }
      }
      k -= cur;
    }
  }
  return TRUE;
}
int groundgen_CompareVariables(POINTER var1, POINTER var2, POINTER occ)
{
  return array_GetElement((ARRAY)occ, *(int*)var1) < array_GetElement((ARRAY)occ, *(int*)var2);
}
TERM groundgen_CopyAndRename(TERMSTATE termstate, TERM t, ARRAY rename)
{
  unsigned i;
  ARRAY args;
  TERM result;
  if (term_IsVariable(termstate, t)) {
    return term_Create(termstate, rename[term_TopSymbol(t)], NULL);
  }
  args = array_Create(term_GetMemory(termstate), 1);
  for (i = 0; i < term_GetArity(t); i++) {
    args = array_Add(term_GetMemory(termstate), args, (intptr_t)groundgen_CopyAndRename(termstate, (TERM)t[i], rename));
  }
  result = term_Create(termstate, term_TopSymbol(t), args);
  array_Delete(term_GetMemory(termstate), args);
  return result;
}
void groundgen_TraverseTermAssignIndices(TERMSTATE termstate, TERM t, ARRAY occ, unsigned *counter, unsigned mult)
{
  unsigned i;
  if (term_IsVariable(termstate, t)) {
    if (occ[term_TopSymbol(t)] % mult == 0) {
      occ[term_TopSymbol(t)] += (*counter)--;
    }
    return;
  }
  for (i = 0; i < term_GetArity(t); i++) {
    groundgen_TraverseTermAssignIndices(termstate, (TERM)t[i], occ, counter, mult);
  }
}
ATOMSTREAM groundgen_CreateAtomStream(GROUNDGEN groundgen, TERM atom)
{
  unsigned i, maxvar, counter;
  ARRAY variables, occ, order;
  ATOMSTREAM atomstream;
  atomstream = memory_Malloc(groundgen->mem, sizeof(ATOMSTREAM_NODE));
  atomstream->profit = 0;
  if (term_IsGround(groundgen->state->termstate, atom)) {
    atomstream->atom = atom;
    atomstream->occ = NULL;
    atomstream->suffix = NULL;
    atomstream->cursymbols = 0;
    atomstream->pos = -1;
    atomstream->restsymbols = NULL;
    atomstream->curterm = NULL;
    atomstream->profit = 0;
    atomstream->is_from_conjecture = FALSE;
    return atomstream;
  }
  variables = term_ArrayOfVariables(state_GetTermstate(groundgen->state), atom);
  if (array_IsEmpty(variables)) maxvar = 0;
  else maxvar = term_MaxVar(state_GetTermstate(groundgen->state), atom)+1;
  occ = array_Create(groundgen->mem, maxvar + 1);
  for (i = 0; i < maxvar; i++) {
    occ = array_Add(groundgen->mem, occ, 0);
  }
  for (i = 0; i < array_GetSize(variables); i++) {
    occ[term_TopSymbol((TERM)array_GetElement(variables, i))]++;
  }
  array_Delete(groundgen->mem, variables);
  for (i = 0; i < array_GetSize(occ); i++) {
   occ[i] *= maxvar + 1;
  }
  counter = maxvar;
  groundgen_TraverseTermAssignIndices(state_GetTermstate(groundgen->state), atom, occ, &counter, maxvar + 1);
  order = array_Create(groundgen->mem, maxvar + 1);
  for (i = 0; i < maxvar; i++) {
    order = array_Add(groundgen->mem, order, i);
  }
  srtg_AMergeSortWithState(groundgen->mem, order, order, order + maxvar - 1, groundgen_CompareVariables, occ);
  atomstream->occ = array_Create(groundgen->mem, 1);
  for (i = 0; i < maxvar; i++) {
    if (occ[array_GetElement(order, i)] == 0) break;
    atomstream->occ = array_Add(groundgen->mem, atomstream->occ, occ[array_GetElement(order, i)]);
  }
  atomstream->suffix = array_Create(groundgen->mem, array_GetSize(atomstream->occ));
  for (i = 0; i < array_GetSize(atomstream->occ); i++) {
    atomstream->suffix = array_Add(groundgen->mem, atomstream->suffix, 0);
  }
  for (i = array_GetSize(atomstream->occ)? array_GetSize(atomstream->occ)-1 : 0; i > 0; i--) {
    atomstream->suffix[i-1] = atomstream->suffix[i] + atomstream->occ[i];
  }
  for (i = 0; i < maxvar; i++) {
    occ[array_GetElement(order, i)] = i;
  }
  array_Delete(groundgen->mem, order);
  atomstream->atom = sharing_GetSharedTerm(groundgen->sharer, groundgen_CopyAndRename(state_GetTermstate(groundgen->state), atom, occ));
  array_Delete(groundgen->mem, occ);
  atomstream->cursymbols = 0;
  atomstream->pos = -1;
  atomstream->restsymbols = array_Create(groundgen->mem, array_GetSize(atomstream->occ));
  for (i = 0; i < array_GetSize(atomstream->occ); i++) {
    atomstream->restsymbols = array_Add(groundgen->mem, atomstream->restsymbols, 0);
  }
  atomstream->curterm = array_Create(groundgen->mem, array_GetSize(atomstream->occ));
  for (i = 0; i < array_GetSize(atomstream->occ); i++) {
    atomstream->curterm = array_Add(groundgen->mem, atomstream->curterm, (intptr_t)-1);
  }
  atomstream->profit = 0;
  atomstream->is_from_conjecture = FALSE;
  return atomstream;
}
TERM groundgen_CreateTerm(GROUNDGEN groundgen, ATOMSTREAM atomstream, TERM t)
{
  unsigned i;
  SYMBOL top;
  ARRAY args;
  TERM result;
  top = term_TopSymbol(t);
  if (symbol_IsVariable(state_GetSymbstate(groundgen->state), top)) {
    return (TERM)groundgen->groundterms[atomstream->curterm[top]];
  }
  if (symbol_IsConstant(top)) {
    return t;
  }
  args = array_Create(groundgen->mem, term_GetArity(t));
  for (i = 0; i < term_GetArity(t); i++) {
    args = array_Add(groundgen->mem, args, (intptr_t)groundgen_CreateTerm(groundgen, atomstream, (TERM)t[i]));
  }
  result = sharing_GetSharedTermByArgs(groundgen->sharer, top, args);
  array_Delete(groundgen->mem, args);
  return result;
}
void groundgen_PrintAtomStream(GROUNDGEN groundgen, ATOMSTREAM atomstream) {
  unsigned i;
  printf("\n===============\nocc: ");
  for (i = 0; i < array_GetSize(atomstream->occ); i++) {
    printf("%d ", (int)atomstream->occ[i]);
  }
  printf("\n");
  printf("cursymbols: %u, pos: %d ", atomstream->cursymbols, atomstream->pos);
  printf("\nrestsymbols: ");
  for (i = 0; i < array_GetSize(atomstream->restsymbols); i++) {
    printf("%d ", (int)atomstream->restsymbols[i]);
  }
  printf("\ncurterm: ");
  for (i = 0; i < array_GetSize(atomstream->curterm); i++) {
    printf("%d ", (int)atomstream->curterm[i]);
  }
  printf("\n%lu groundterms: ", array_GetSize(groundgen->groundterms));
  for (i = 0; i < array_GetSize(groundgen->groundterms); i++) {
    term_PrettyPrint(state_GetTermstate(groundgen->state), (TERM)groundgen->groundterms[i]);
    printf(" ");
  }
  printf("\n");
}
TERM groundgen_AtomStreamGetNext(GROUNDGEN groundgen, ATOMSTREAM atomstream)
{
  unsigned num;
  if (atomstream->occ == NULL) {
    if (atomstream->cursymbols) return NULL;
    atomstream->cursymbols++;
    return atomstream->atom;
  }
  while (atomstream->pos != array_GetSize(atomstream->occ)) {
    if (atomstream->pos == -1) {
      atomstream->cursymbols++;
      atomstream->pos = 0;
      atomstream->restsymbols[0] = atomstream->cursymbols;
      continue;
    }
    if (atomstream->pos == array_GetSize(atomstream->occ)-1) {
      if (array_IsEmpty(state_GetFunctions(groundgen->state)) && atomstream->restsymbols[atomstream->pos] > atomstream->occ[atomstream->pos]) {
        return NULL;
      }
      if (atomstream->restsymbols[atomstream->pos] % atomstream->occ[atomstream->pos]) {
        atomstream->pos--;
        continue;
      }
      num = atomstream->restsymbols[atomstream->pos] / atomstream->occ[atomstream->pos];
      while (num > array_GetSize(groundgen->start)) groundgen_GenerateNextTerm(groundgen);
      if ((int)atomstream->curterm[atomstream->pos] < (int)groundgen->start[num-1]) atomstream->curterm[atomstream->pos] = (intptr_t)(groundgen->start[num-1]-1);
    }
    atomstream->curterm[atomstream->pos]++;
    if (atomstream->curterm[atomstream->pos] == array_GetSize(groundgen->groundterms)){
      if (array_IsEmpty(state_GetFunctions(groundgen->state))) {
        atomstream->curterm[atomstream->pos] = (intptr_t)-1;
        atomstream->pos--;
        continue;
      }
      groundgen_GenerateNextTerm(groundgen);
    }
    num = term_Size((TERM)groundgen->groundterms[atomstream->curterm[atomstream->pos]]);
    if (num * atomstream->occ[atomstream->pos] + atomstream->suffix[atomstream->pos] > atomstream->restsymbols[atomstream->pos]) {
      atomstream->curterm[atomstream->pos] = (intptr_t)-1;
      atomstream->pos--;
      continue;
    }
    if (atomstream->pos < array_GetSize(atomstream->occ)-1)
      atomstream->restsymbols[atomstream->pos+1] = atomstream->restsymbols[atomstream->pos] - num * atomstream->occ[atomstream->pos];
    atomstream->pos++;
  }
  atomstream->pos--;
  return groundgen_CreateTerm(groundgen, atomstream, atomstream->atom);
}
void groundgen_DeleteAtomStream(GROUNDGEN groundgen, ATOMSTREAM atomstream)
{
  if (atomstream->occ)
    array_Delete(groundgen->mem, atomstream->occ);
  if (atomstream->suffix)
    array_Delete(groundgen->mem, atomstream->suffix);
  if (atomstream->restsymbols)
    array_Delete(groundgen->mem, atomstream->restsymbols);
  if (atomstream->curterm)
    array_Delete(groundgen->mem, atomstream->curterm);
  memory_Free(groundgen->mem, atomstream, sizeof(ATOMSTREAM_NODE));
}
