#ifdef DOC_BUILD_INTERNAL
#endif
#include "fredund.h"
uint32_t fred_DestrHash(const OHASH_KEY_TYPE Data)
{
  return (clause_GetId((CLAUSE)array_PairFirst((ARRAY)Data)) * ((unsigned)array_PairSecond((ARRAY)Data) + 1) * 387780157) % 1378999961;
}
void fred_DestrPrint(TERMSTATE Termstate, intptr_t Data)
{
  printf("\n Clause %u,%u", clause_GetId((CLAUSE)array_PairFirst((ARRAY)Data)), (unsigned)array_PairSecond((ARRAY)Data));
}
BOOL fred_DestrEntryObsolete(intptr_t State, intptr_t Element)
{
  CLAUSE clause;
  clause = (CLAUSE)array_PairFirst((ARRAY)Element);
  return (clause_IsMarkedDelete(clause) || clause_IsMarkedNullAtoms(clause));
}
BOOL fred_DestrEntryIsClause(intptr_t Clause, intptr_t Element)
{
  return (Clause == array_PairFirst((ARRAY)Element));
}
void fred_DestrDeleteEntry(MEMORY Mem, intptr_t Element)
{
  array_Delete(Mem, (ARRAY)Element);
}
void fred_ShareClause(SHARER Sharer, CLAUSE Clause)
{
  unsigned i;
  TERM atom;
  for (i=0; i<clause_GetFolLiterals(Clause); i++) {
    atom = (TERM)Clause[i];
    atom = sharing_GetSharedTerm(Sharer,atom);
    Clause[i] = (intptr_t)atom;
  }
}
void fred_RemoveClauseFromIndex(SCLSTATE State, CLAUSE Clause)
{
  unsigned i;
  DISTRN poslits, neglits;
  TERMSTATE termstate;
  termstate = state_GetTermstate(State);
  poslits = state_GetPoslits(State);
  neglits = state_GetNeglits(State);
  for(i=0;i<clause_GetPremiseLiterals(Clause);i++) {
    distrn_RemoveIf(neglits, termstate, clause_GetAtom(Clause,i), NULL, fred_DestrEntryIsClause, (intptr_t)Clause, fred_DestrDeleteEntry);
  }
  for(;i<clause_GetFolLiterals(Clause);i++) {
    distrn_RemoveIf(poslits, termstate, clause_GetAtom(Clause,i), NULL, fred_DestrEntryIsClause, (intptr_t)Clause, fred_DestrDeleteEntry);
  }
}
void fred_InsertClauseToIndex(SCLSTATE State, CLAUSE Clause)
{
  unsigned j;
  DISTRN poslits, neglits;
  TERMSTATE termstate;
  MEMORY mem;
  termstate = state_GetTermstate(State);
  poslits = state_GetPoslits(State);
  neglits = state_GetNeglits(State);
  mem = state_GetMemory(State);
  for(j=0;j<clause_GetPremiseLiterals(Clause);j++) {
    distrn_InsertDataHash(mem, neglits, termstate, clause_GetAtom(Clause,j), NULL, (intptr_t)array_PairCreate(mem, (intptr_t)Clause,j), fred_DestrHash);
  }
  for(;j<clause_GetFolLiterals(Clause);j++) {
    distrn_InsertDataHash(mem, poslits, termstate, clause_GetAtom(Clause,j), NULL, (intptr_t)array_PairCreate(mem, (intptr_t)Clause,j), fred_DestrHash);
  }
}
BOOL fred_ClauseIsTautology(FOLSTATE Folstate, CLAUSE Clause, BOOL Shared)
{
  unsigned i,j;
  if (clause_GetPremiseLiterals(Clause) > 0) {
    for (i=0; i < clause_GetPremiseLiterals(Clause); i++) {
      if (term_TopSymbol((TERM)Clause[i]) == fol_False(Folstate))
 return TRUE;
      if (term_TopSymbol((TERM)Clause[i]) == fol_True(Folstate)) {
 if (!Shared)
   term_Delete(fol_GetTermstate(Folstate), (TERM)Clause[i]);
 Clause[i] = (intptr_t)NULL;
 clause_MarkNullAtoms(Clause, TRUE);
      }
      for (j=clause_GetPremiseLiterals(Clause); j < clause_GetFolLiterals(Clause); j++) {
 if (Clause[j] != (intptr_t)NULL) {
   if (term_TopSymbol((TERM)Clause[j]) == fol_True(Folstate))
     return TRUE;
   if (term_TopSymbol((TERM)Clause[j]) == fol_False(Folstate)) {
     if (!Shared)
       term_Delete(fol_GetTermstate(Folstate), (TERM)Clause[j]);
     Clause[j] = (intptr_t)NULL;
     clause_MarkNullAtoms(Clause, TRUE);
   }
   else {
     if (Clause[i] != (intptr_t)NULL) {
       if (Shared) {
  if (Clause[i] == Clause[j])
    return TRUE;
       }
       else {
  if (term_EqualNoValues((TERM)Clause[i], (TERM)Clause[j]))
    return TRUE;
       }
     }
   }
 }
      }
    }
  }
  else {
    for (j=clause_GetPremiseLiterals(Clause); j < clause_GetFolLiterals(Clause); j++) {
      if (term_TopSymbol((TERM)Clause[j]) == fol_True(Folstate))
 return TRUE;
      if (term_TopSymbol((TERM)Clause[j]) == fol_False(Folstate)) {
 if (!Shared)
   term_Delete(fol_GetTermstate(Folstate), (TERM)Clause[j]);
 Clause[j] = (intptr_t)NULL;
 clause_MarkNullAtoms(Clause, TRUE);
      }
    }
  }
  if (clause_IsMarkedNullAtoms(Clause)) {
    clause_RemoveNullLiterals(Clause);
    clause_MarkNullAtoms(Clause, FALSE);
    clause_SetSymbolOccurrences(fol_GetTermstate(Folstate), Clause);
  }
  return FALSE;
}
void fred_ExhaustiveBackwardSubRes(SCLSTATE State, CLAUSE Clause, BOOL Shared, ARRAY *Reduced, ARRAY *ReducedAtoms)
{
  unsigned i,j,k,gindex;
  DISTRN poslits, neglits;
  TERMSTATE termstate;
  MEMORY mem;
  ARRAY candidates;
  CLAUSE gclause,copy;
  TERM reducedatom;
  SHARER sharer;
  termstate = state_GetTermstate(State);
  poslits = state_GetPoslits(State);
  neglits = state_GetNeglits(State);
  mem = state_GetMemory(State);
  sharer = state_GetSharer(State);
  candidates = array_Create(mem,10);
  sharer = state_GetSharer(State);
  for(j=0;j<clause_GetPremiseLiterals(Clause);j++) {
    array_Clean(candidates);
    candidates = distrn_SearchInstances(mem, poslits, termstate, clause_GetAtom(Clause,j), &candidates);
    for (k=0;k<array_GetSize(candidates);k++) {
      gclause = (CLAUSE)array_PairFirst((ARRAY)candidates[k]);
      gindex = (unsigned)array_PairSecond((ARRAY)candidates[k]);
      if (gclause != Clause && !clause_IsMarkedDelete(gclause) && clause_GetAtom(gclause,gindex) != (TERM)NULL) {
 if (subsume_CheckWithResolvableLiterals(State, Clause, j, gclause, gindex)) {
   copy = clause_Copy(termstate, gclause, TRUE);
   fred_ShareClause(sharer, copy);
   state_SetRedClauses(State, array_Add(mem, state_GetRedClauses(State), (intptr_t)copy));
   if (!Shared) {
            reducedatom = sharing_GetSharedTerm(sharer, (TERM)gclause[gindex]);
     term_Delete(termstate, (TERM)gclause[gindex]);
          }
          else {
            reducedatom = (TERM)gclause[gindex];
          }
   clause_NullLiteral(gclause,gindex);
   clause_SetSymbolOccurrences(termstate, gclause);
   clause_AddParent(mem, gclause, clause_GetId(gclause), gindex);
   clause_AddParent(mem, gclause, clause_GetId(Clause), j);
   clause_SetId(gclause, state_GetNextIncrementId(State));
   state_IncSubResolutions(State);
   *Reduced = array_Add(mem, *Reduced, (intptr_t)gclause);
          *ReducedAtoms = array_Add(mem, *ReducedAtoms, (intptr_t)reducedatom);
 }
      }
    }
  }
  for(;j<clause_GetFolLiterals(Clause);j++) {
    array_Clean(candidates);
    candidates = distrn_SearchInstances(mem, neglits, termstate, clause_GetAtom(Clause,j), &candidates);
    for (k=0;k<array_GetSize(candidates);k++) {
      gclause = (CLAUSE)array_PairFirst((ARRAY)candidates[k]);
      gindex = (unsigned)array_PairSecond((ARRAY)candidates[k]);
      if (gclause != Clause && !clause_IsMarkedDelete(gclause) && clause_GetAtom(gclause,gindex) != (TERM)NULL) {
 if (subsume_CheckWithResolvableLiterals(State, Clause, j, gclause, gindex)) {
   printf("\n%% BsubResHit: %u ", (unsigned)array_PairSecond((ARRAY)candidates[k])); clause_Print(termstate, (CLAUSE)array_PairFirst((ARRAY)candidates[k]));
          reducedatom = sharing_GetSharedTerm(sharer, (TERM)gclause[gindex]);
   copy = clause_Copy(termstate, gclause, TRUE);
   fred_ShareClause(sharer, copy);
   state_SetRedClauses(State, array_Add(mem, state_GetRedClauses(State), (intptr_t)copy));
   if (!Shared)
     term_Delete(termstate, (TERM)gclause[gindex]);
   clause_NullLiteral(gclause,gindex);
   clause_SetSymbolOccurrences(termstate, gclause);
   clause_AddParent(mem, gclause, clause_GetId(gclause), gindex);
   clause_AddParent(mem, gclause, clause_GetId(Clause), j);
   clause_SetId(gclause, state_GetNextIncrementId(State));
   state_IncSubResolutions(State);
   *Reduced = array_Add(mem, *Reduced, (intptr_t)gclause);
          *ReducedAtoms = array_Add(mem, *ReducedAtoms, (intptr_t)reducedatom);
 }
      }
    }
  }
  array_Delete(mem,candidates);
  if (*Reduced) {
  }
}
void fred_ExhaustiveForwardSubRes(SCLSTATE State, CLAUSE Clause, BOOL Shared)
{
  unsigned j,k,gindex;
  DISTRN poslits, neglits;
  TERMSTATE termstate;
  MEMORY mem;
  ARRAY candidates;
  BOOL hit,reduced;
  CLAUSE gclause,copy;
  SHARER sharer;
  termstate = state_GetTermstate(State);
  poslits = state_GetPoslits(State);
  neglits = state_GetNeglits(State);
  mem = state_GetMemory(State);
  candidates = array_Create(mem,10);
  reduced = FALSE;
  sharer = state_GetSharer(State);
  for(j=0;j<clause_GetPremiseLiterals(Clause);j++) {
    hit = FALSE;
    array_Clean(candidates);
    candidates = distrn_SearchGeneralizations(mem, poslits, termstate, clause_GetAtom(Clause,j), &candidates);
    for (k=0;k<array_GetSize(candidates) && !hit;k++) {
      gclause = (CLAUSE)array_PairFirst((ARRAY)candidates[k]);
      gindex = (unsigned)array_PairSecond((ARRAY)candidates[k]);
      if (gclause != Clause && !clause_IsMarkedDelete(gclause) && clause_GetAtom(gclause,gindex) != (TERM)NULL) {
 if (subsume_CheckWithResolvableLiterals(State, gclause, gindex, Clause, j)) {
   copy = clause_Copy(termstate, Clause, TRUE);
   if (clause_IsMarkedNullAtoms(Clause)) {
     clause_RemoveNullLiterals(copy);
     clause_NormalizeVars(state_GetSubststate(State), termstate, copy);
     clause_MarkNullAtoms(copy, FALSE);
     clause_SetSymbolOccurrences(termstate, copy);
   }
   fred_ShareClause(sharer, copy);
   state_SetRedClauses(State, array_Add(mem, state_GetRedClauses(State), (intptr_t)copy));
   if (!Shared)
     term_Delete(termstate, (TERM)Clause[j]);
   clause_NullLiteral(Clause,j);
   clause_SetSymbolOccurrences(termstate, Clause);
   array_Clean((ARRAY)clause_GetParents(Clause));
   clause_AddParent(mem, Clause, clause_GetId(gclause), gindex);
   clause_AddParent(mem, Clause, clause_GetId(Clause), j);
   clause_SetId(Clause, state_GetNextIncrementId(State));
   state_IncSubResolutions(State);
   hit = TRUE;
   reduced = TRUE;
 }
      }
    }
  }
  for(;j<clause_GetFolLiterals(Clause);j++) {
    hit = FALSE;
    array_Clean(candidates);
    candidates = distrn_SearchGeneralizations(mem, neglits, termstate, clause_GetAtom(Clause,j), &candidates);
    for (k=0;k<array_GetSize(candidates) && !hit;k++) {
      gclause = (CLAUSE)array_PairFirst((ARRAY)candidates[k]);
      gindex = (unsigned)array_PairSecond((ARRAY)candidates[k]);
      if (gclause != Clause && !clause_IsMarkedDelete(gclause) && clause_GetAtom(gclause,gindex) != (TERM)NULL) {
 if (subsume_CheckWithResolvableLiterals(State, gclause, gindex, Clause, j)) {
   copy = clause_Copy(termstate, Clause, TRUE);
   if (clause_IsMarkedNullAtoms(Clause)) {
     clause_RemoveNullLiterals(copy);
     clause_NormalizeVars(state_GetSubststate(State), termstate, copy);
     clause_MarkNullAtoms(copy, FALSE);
     clause_SetSymbolOccurrences(termstate, copy);
   }
   fred_ShareClause(sharer, copy);
   state_SetRedClauses(State, array_Add(mem, state_GetRedClauses(State), (intptr_t)copy));
   if (!Shared)
     term_Delete(termstate, (TERM)Clause[j]);
   clause_NullLiteral(Clause,j);
   clause_SetSymbolOccurrences(termstate, Clause);
   array_Clean((ARRAY)clause_GetParents(Clause));
   clause_AddParent(mem, Clause, clause_GetId(gclause), gindex);
   clause_AddParent(mem, Clause, clause_GetId(Clause), j);
   clause_SetId(Clause, state_GetNextIncrementId(State));
   state_IncSubResolutions(State);
   hit = TRUE;
   reduced = TRUE;
 }
      }
    }
  }
  if (reduced) {
    clause_RemoveNullLiterals(Clause);
    clause_MarkNullAtoms(Clause, FALSE);
    clause_NormalizeVars(state_GetSubststate(State), termstate, Clause);
    clause_SetSymbolOccurrences(termstate, Clause);
    if (clause_GetFolLiterals(Clause) == 0)
      state_SetEmptyClause(State,Clause);
  }
  array_Delete(mem,candidates);
}
void fred_InitialStateRedundancy(SCLSTATE State)
{
  ARRAY oclauses, candidates, subresolved;
  TERMSTATE termstate;
  FOLSTATE folstate;
  SUBSTSTATE subststate;
  SYMBSTATE symbstate;
  CLAUSE clause, gclause, copy;
  unsigned i, j, k, cnum, gindex;
  MEMORY mem;
  DISTRN poslits, neglits;
  BOOL redundant,hit;
  SHARER sharer;
  termstate = state_GetTermstate(State);
  symbstate = state_GetSymbstate(State);
  folstate = state_GetFolstate(State);
  subststate = state_GetSubststate(State);
  oclauses = state_GetClauses(State);
  cnum = array_GetSize(oclauses);
  mem = state_GetMemory(State);
  poslits = state_GetPoslits(State);
  neglits = state_GetNeglits(State);
  sharer = state_GetSharer(State);
  for (i=0;i<cnum;i++) {
    clause = (CLAUSE)oclauses[i];
    clause_RemoveDuplicateLiterals(termstate, clause, FALSE);
    if (condense_Condense(State, clause)) {
      state_IncCondensations(State);
    }
    if (fred_ClauseIsTautology(folstate,clause, FALSE)) {
      clause_Delete(mem, termstate, clause);
      if (i + 1 != cnum) {
 oclauses[i] = oclauses[cnum-1];
 i--;
      }
      cnum--;
    }
    else {
      for(j=0;j<clause_GetPremiseLiterals(clause);j++) {
 distrn_InsertDataHash(mem, neglits, termstate, clause_GetAtom(clause,j), NULL, (intptr_t)array_PairCreate(mem, (intptr_t)clause,j), fred_DestrHash);
      }
      for(;j<clause_GetFolLiterals(clause);j++) {
 distrn_InsertDataHash(mem, poslits, termstate, clause_GetAtom(clause,j), NULL, (intptr_t)array_PairCreate(mem, (intptr_t)clause,j), fred_DestrHash);
      }
    }
  }
  array_SetSize(oclauses, cnum);
  candidates = state_GetCandidates(State);
  array_Clean(candidates);
  subresolved = array_Create(mem, 10);
  for (i=0;i<cnum;i++) {
    clause = (CLAUSE)oclauses[i];
    if (!clause_IsMarkedDelete(clause)) {
      redundant = FALSE;
      for(j=0;j<clause_GetPremiseLiterals(clause) && !redundant;j++) {
 array_Clean(candidates);
 candidates = distrn_SearchGeneralizations(mem, neglits, termstate, clause_GetAtom(clause,j), &candidates);
 for (k=0;k<array_GetSize(candidates) && !redundant;k++) {
   gclause = (CLAUSE)array_PairFirst((ARRAY)candidates[k]);
   if (gclause != clause && !clause_IsMarkedDelete(gclause)) {
     if (subsume_Check(State, gclause, clause)) {
       clause_MarkDelete(clause,TRUE);
       redundant = TRUE;
     }
   }
 }
      }
      for(;j<clause_GetFolLiterals(clause) && !redundant;j++) {
 array_Clean(candidates);
 candidates = distrn_SearchGeneralizations(mem, poslits, termstate, clause_GetAtom(clause,j), &candidates);
 for (k=0;k<array_GetSize(candidates) && !redundant;k++) {
   gclause = (CLAUSE)array_PairFirst((ARRAY)candidates[k]);
   if (gclause != clause && !clause_IsMarkedDelete(gclause)) {
     if (subsume_Check(State, gclause, clause)) {
       clause_MarkDelete(clause,TRUE);
       redundant = TRUE;
     }
   }
 }
      }
      if (!redundant) {
 for(j=0;j<clause_GetPremiseLiterals(clause);j++) {
   hit = FALSE;
   array_Clean(candidates);
   candidates = distrn_SearchGeneralizations(mem, poslits, termstate, clause_GetAtom(clause,j), &candidates);
   for (k=0;k<array_GetSize(candidates) && !hit;k++) {
     gclause = (CLAUSE)array_PairFirst((ARRAY)candidates[k]);
     gindex = (unsigned)array_PairSecond((ARRAY)candidates[k]);
     if (gclause != clause && !clause_IsMarkedDelete(gclause) && clause_GetAtom(gclause,gindex) != (TERM)NULL) {
       if (subsume_CheckWithResolvableLiterals(State, gclause, gindex, clause, j)) {
  copy = clause_Copy(termstate, clause, TRUE);
  if (clause_IsMarkedNullAtoms(clause)) {
    clause_RemoveNullLiterals(copy);
    clause_NormalizeVars(state_GetSubststate(State), termstate, copy);
    clause_MarkNullAtoms(copy, FALSE);
    clause_SetSymbolOccurrences(termstate, copy);
  }
  fred_ShareClause(sharer, copy);
  state_SetRedClauses(State, array_Add(mem, state_GetRedClauses(State), (intptr_t)copy));
  term_Delete(termstate, (TERM)clause[j]);
  clause_NullLiteral(clause,j);
  clause_SetSymbolOccurrences(termstate, clause);
  clause_AddParent(mem, clause, clause_GetId(gclause), gindex);
                clause_AddParent(mem, clause, clause_GetId(clause), j);
                clause_SetId(clause, state_GetNextIncrementId(State));
  subresolved = array_Add(mem, subresolved, (intptr_t)clause);
  state_IncSubResolutions(State);
  hit = TRUE;
       }
     }
   }
 }
 for(;j<clause_GetFolLiterals(clause);j++) {
   hit = FALSE;
   array_Clean(candidates);
   candidates = distrn_SearchGeneralizations(mem, neglits, termstate, clause_GetAtom(clause,j), &candidates);
   for (k=0;k<array_GetSize(candidates) && !hit;k++) {
     gclause = (CLAUSE)array_PairFirst((ARRAY)candidates[k]);
     gindex = (unsigned)array_PairSecond((ARRAY)candidates[k]);
     if (gclause != clause && !clause_IsMarkedDelete(gclause) && clause_GetAtom(gclause,gindex) != (TERM)NULL) {
       if (subsume_CheckWithResolvableLiterals(State, gclause, gindex, clause, j)) {
  copy = clause_Copy(termstate, clause, TRUE);
  if (clause_IsMarkedNullAtoms(clause)) {
    clause_RemoveNullLiterals(copy);
    clause_NormalizeVars(state_GetSubststate(State), termstate, copy);
    clause_MarkNullAtoms(copy, FALSE);
    clause_SetSymbolOccurrences(termstate, copy);
  }
  fred_ShareClause(sharer, copy);
  state_SetRedClauses(State, array_Add(mem, state_GetRedClauses(State), (intptr_t)copy));
  term_Delete(termstate, (TERM)clause[j]);
  clause_NullLiteral(clause,j);
  clause_SetSymbolOccurrences(termstate, clause);
  clause_AddParent(mem, clause, clause_GetId(gclause), gindex);
  clause_AddParent(mem, clause, clause_GetId(clause), j);
                clause_SetId(clause, state_GetNextIncrementId(State));
  subresolved = array_Add(mem, subresolved, (intptr_t)clause);
  state_IncSubResolutions(State);
  hit = TRUE;
       }
     }
   }
 }
      }
    }
  }
  distrn_RemoveIfTrue(mem, poslits, symbstate, fred_DestrEntryObsolete, (intptr_t)State, fred_DestrDeleteEntry);
  distrn_RemoveIfTrue(mem, neglits, symbstate, fred_DestrEntryObsolete, (intptr_t)State, fred_DestrDeleteEntry);
  for (i=0;i<array_GetSize(subresolved);i++) {
    clause = (CLAUSE)subresolved[i];
    if (!clause_IsMarkedDelete(clause) && clause_IsMarkedNullAtoms(clause)) {
      clause_RemoveNullLiterals(clause);
      clause_NormalizeVars(state_GetSubststate(State), termstate, clause);
      clause_MarkNullAtoms(clause, FALSE);
      clause_SetSymbolOccurrences(termstate, clause);
      fred_InsertClauseToIndex(State,clause);
    }
  }
  for (i=0;i<cnum;i++) {
    clause = (CLAUSE)oclauses[i];
    if (clause_IsMarkedDelete(clause)) {
      clause_Delete(mem, termstate, clause);
      if (i + 1 != cnum) {
 oclauses[i] = oclauses[cnum-1];
 i--;
      }
      cnum--;
    }
  }
  array_SetSize(oclauses, cnum);
  redundant = TRUE;
  array_Clean(subresolved);
  array_Clean(candidates);
  for (i=0;i<cnum ;i++) {
    clause = (CLAUSE)oclauses[i];
    k = clause_GetFolLiterals(clause);
    if (k == 0 || (k == 1 && clause_GetPremiseLiterals(clause) == 0 && symbol_Equal(term_TopSymbol((TERM)clause[0]),fol_False(folstate)))) {
      state_SetEmptyClause(State,clause);
      break;
    }
    if (state_IsEqualityProblem(State) && redundant) {
      for (j=0;j<clause_GetPremiseLiterals(clause);j++) {
 if (symbol_Equal(term_TopSymbol((TERM)clause[j]),fol_Equal(folstate))) {
   subresolved = array_Add(mem, subresolved, (intptr_t)clause);
   break;
 }
      }
      for(j=clause_GetPremiseLiterals(clause);j<clause_GetFolLiterals(clause);j++) {
 if (symbol_Equal(term_TopSymbol((TERM)clause[j]),fol_Equal(folstate)))
   redundant = FALSE;
      }
    }
  }
  if (redundant && !state_GetEmptyClause(State)) {
    for (i=0;i<array_GetSize(subresolved);i++) {
      clause = (CLAUSE)subresolved[i];
      fred_RemoveClauseFromIndex(State,clause);
      if (clause_ApplyEqualityResolution(folstate,termstate, subststate, clause)) {
 if (clause_GetFolLiterals(clause) == 0)
   state_SetEmptyClause(State,clause);
 else {
   if (condense_Condense(State, clause)) {
     state_IncCondensations(State);
   }
   fred_InsertClauseToIndex(State,clause);
 }
      }
    }
    state_SetProblemHasEquations(State,FALSE);
  }
  array_Delete(mem, subresolved);
  state_SetCandidates(State, candidates);
  printf("\n");
}
BOOL fred_BackReduction(SCLSTATE State, TRAIL Trail, TWFO Twfo, ARRAY *Reductions)
{
  ARRAY candidates, workedoff, usable, oclauses;
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  CLAUSE clause, rclause, copy;
  unsigned i, j, k, cnum, rindex,shits,rhits;
  MEMORY mem;
  DISTRN poslits, neglits;
  TERM atom, rterm;
  SHARER sharer;
  BOOL emptyclause;
  termstate = state_GetTermstate(State);
  symbstate = state_GetSymbstate(State);
  oclauses = state_GetClauses(State);
  cnum = array_GetSize(oclauses);
  mem = state_GetMemory(State);
  poslits = state_GetPoslits(State);
  neglits = state_GetNeglits(State);
  sharer = state_GetSharer(State);
  shits = 0;
  rhits = 0;
  emptyclause = FALSE;
  workedoff = state_GetWorkedOff(State);
  usable = state_GetUsables(State);
  candidates = state_GetCandidates(State);
  array_Clean(workedoff);
  array_Clean(usable);
  array_Clean(candidates);
  if (*Reductions)
    array_Clean(*Reductions);
  for (i=cnum-1; i>0 && clause_GetId((CLAUSE)oclauses[i]) >= state_GetLastClauseId(State); i--) {
    usable = array_Add(mem, usable, oclauses[i]);
  }
  array_Reverse(usable);
  while (array_GetSize(usable)>0 && !emptyclause) {
    while (array_GetSize(usable)>0 && !emptyclause) {
      clause = (CLAUSE)array_Pop(usable);
      if (!clause_IsMarkedDelete(clause)) {
 atom = clause_GetAtom(clause,0);
 j = 1;
 while (atom == (TERM)NULL && j < clause_GetFolLiterals(clause))
   atom = clause_GetAtom(clause,j++);
 array_Clean(candidates);
 candidates = distrn_SearchInstances(mem, (clause_GetPremiseLiterals(clause)>0?neglits:poslits), termstate, atom, &candidates);
 for (j=0; j<array_GetSize(candidates); j++) {
   rclause = (CLAUSE)array_PairFirst((ARRAY)candidates[j]);
   if (!clause_IsMarkedDelete(rclause)) {
     if (rclause != clause && subsume_Check(State, clause, rclause)) {
       shits++;
       clause_MarkDelete(rclause,TRUE);
       state_SetRedClauses(State, array_Add(mem, state_GetRedClauses(State), (intptr_t)rclause));
       if (!clause_IsMarkedNullAtoms(rclause))
  instset_DeleteClause(mem, termstate, twfo_GetInstset(Twfo), rclause);
     }
   }
 }
 for(j=0;j<clause_GetPremiseLiterals(clause) && !emptyclause;j++) {
   if (clause_GetAtom(clause,j) != (TERM)NULL) {
     array_Clean(candidates);
     candidates = distrn_SearchInstances(mem, poslits, termstate, clause_GetAtom(clause,j), &candidates);
     for (k=0;k<array_GetSize(candidates) && !emptyclause;k++) {
       rclause = (CLAUSE)array_PairFirst((ARRAY)candidates[k]);
       rindex = (unsigned)array_PairSecond((ARRAY)candidates[k]);
       rterm = clause_GetAtom(rclause,rindex);
       if (rclause != clause && !clause_IsMarkedDelete(rclause) && rterm != (TERM)NULL) {
  if (subsume_CheckWithResolvableLiterals(State, clause, j, rclause, rindex)) {
    copy = clause_Copy(termstate, rclause, TRUE);
    if (clause_IsMarkedNullAtoms(rclause)) {
      clause_RemoveNullLiterals(copy);
      clause_NormalizeVars(state_GetSubststate(State), termstate, copy);
      clause_MarkNullAtoms(copy, FALSE);
      clause_SetSymbolOccurrences(termstate, copy);
    }
    else
      instset_DeleteClause(mem, termstate, twfo_GetInstset(Twfo), rclause);
    fred_ShareClause(sharer, copy);
    state_SetRedClauses(State, array_Add(mem, state_GetRedClauses(State), (intptr_t)copy));
    clause_AddParent(mem, rclause, clause_GetId(clause), j);
    clause_AddParent(mem, rclause, clause_GetId(rclause), rindex);
    clause_SetId(rclause, state_GetNextIncrementId(State));
    clause_NullLiteral(rclause,rindex);
    if (clause_NullIsEmpty(rclause)) {
      emptyclause = TRUE;
      state_SetEmptyClause(State, rclause);
    }
    clause_SetSymbolOccurrences(termstate, rclause);
    state_IncSubResolutions(State);
    usable = array_Add(mem, usable, (intptr_t)rclause);
    if (*Reductions) {
      *Reductions = array_Add(mem, *Reductions, (intptr_t)copy);
      *Reductions = array_Add(mem, *Reductions, (intptr_t)rterm);
    }
    rhits++;
  }
       }
     }
   }
 }
 for(;j<clause_GetFolLiterals(clause) && !emptyclause;j++) {
   if (clause_GetAtom(clause,j) != (TERM)NULL) {
     array_Clean(candidates);
     candidates = distrn_SearchInstances(mem, neglits, termstate, clause_GetAtom(clause,j), &candidates);
     for (k=0;k<array_GetSize(candidates) && !emptyclause;k++) {
       rclause = (CLAUSE)array_PairFirst((ARRAY)candidates[k]);
       rindex = (unsigned)array_PairSecond((ARRAY)candidates[k]);
       rterm = clause_GetAtom(rclause,rindex);
       if (rclause != clause && !clause_IsMarkedDelete(rclause) && rterm != (TERM)NULL) {
  if (subsume_CheckWithResolvableLiterals(State, clause, j, rclause, rindex)) {
    copy = clause_Copy(termstate, rclause, TRUE);
    if (clause_IsMarkedNullAtoms(rclause)) {
      clause_RemoveNullLiterals(copy);
      clause_NormalizeVars(state_GetSubststate(State), termstate, copy);
      clause_MarkNullAtoms(copy, FALSE);
      clause_SetSymbolOccurrences(termstate, copy);
    }
    else
      instset_DeleteClause(mem, termstate, twfo_GetInstset(Twfo), rclause);
    fred_ShareClause(sharer, copy);
    state_SetRedClauses(State, array_Add(mem, state_GetRedClauses(State), (intptr_t)copy));
    clause_AddParent(mem, rclause, clause_GetId(clause), j);
    clause_AddParent(mem, rclause, clause_GetId(rclause), rindex);
    clause_SetId(rclause, state_GetNextIncrementId(State));
    clause_NullLiteral(rclause,rindex);
    if (clause_NullIsEmpty(rclause)) {
      emptyclause = TRUE;
      state_SetEmptyClause(State, rclause);
    }
    clause_SetSymbolOccurrences(termstate, rclause);
    state_IncSubResolutions(State);
    usable = array_Add(mem, usable, (intptr_t)rclause);
    if (*Reductions) {
      *Reductions = array_Add(mem, *Reductions, (intptr_t)copy);
      *Reductions = array_Add(mem, *Reductions, (intptr_t)rterm);
    }
    rhits++;
  }
       }
     }
   }
 }
      }
    }
    state_SetLastClauseId(State, state_GetId(State));
    if (shits > 0 || rhits>0) {
      distrn_RemoveIfTrue(mem, poslits, symbstate, fred_DestrEntryObsolete, (intptr_t)State, fred_DestrDeleteEntry);
      distrn_RemoveIfTrue(mem, neglits, symbstate, fred_DestrEntryObsolete, (intptr_t)State, fred_DestrDeleteEntry);
      twfo_ClearStackDeletedUnits(Twfo);
#if (SPASS_CHECK && (SPASS_CHECK & SPASS_CHECK_NTWFO))
      ntwfo_ClearStackDeletedUnits(State->ntwfo);
#endif
      for(j=0,k=0;k<cnum;k++) {
 clause = (CLAUSE)oclauses[k];
 if (clause_IsMarkedNullAtoms(clause)) {
   clause_RemoveNullLiterals(clause);
   for(i=0;i<clause_GetFolLiterals(clause);i++)
     clause[i] = (intptr_t)term_Copy(termstate, (TERM)clause[i]);
   clause_NormalizeVars(state_GetSubststate(State), termstate, clause);
   if (!clause_IsMarkedDelete(clause) && !emptyclause && condense_Condense(State, clause)) {
     state_IncCondensations(State);
     usable = array_Add(mem, usable, (intptr_t)clause);
   }
   for(i=0;i<clause_GetFolLiterals(clause);i++)
     clause[i] = (intptr_t)sharing_GetSharedTerm(sharer, (TERM)clause[i]);
   clause_SetSymbolOccurrences(termstate, clause);
 }
 if (!clause_IsMarkedDelete(clause)) {
   oclauses[j] = oclauses[k];
   j++;
   if (clause_IsMarkedNullAtoms(clause)) {
     clause_MarkNullAtoms(clause, FALSE);
     fred_InsertClauseToIndex(State,clause);
     if (clause_GetFolLiterals(clause) > 0) {
       twfo_LearnNewClause(Twfo, Trail, clause, FALSE, 0);
#if (SPASS_CHECK && (SPASS_CHECK & SPASS_CHECK_NTWFO))
              ntwfo_ComputeBacktrackLevelLearnNewClause(State->ntwfo, Trail, clause);
#endif
     }
   }
 }
      }
      array_SetSize(oclauses,j);
      cnum = j;
    }
    shits = 0;
    rhits = 0;
  }
  state_SetWorkedOff(State, workedoff);
  state_SetUsables(State, usable);
  state_SetCandidates(State, candidates);
  return emptyclause;
}
