#ifdef DOC_BUILD_INTERNAL
#endif
#include "twfo.h"
const unsigned twfo_INITIALCANDIDATESIZE = 32;
const unsigned twfo_INITIALNEWINSTANCESSIZE = 8;
TWFO twfo_Create(MEMORY Mem, SUBSTSTATE Subststate, TERMSTATE Termstate, SYMBSTATE Symbstate, FOLSTATE Folstate, SHARER Sharer, ARRAY Clauses, TRAIL Trail)
{
#ifdef SPASS_CHECK
  int c_i;
  CLAUSE c_clause;
  if (trail_GetSize(Trail) > 0) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Trail is not empty.", __func__);
    misc_FinishErrorReport();
  }
  twfo_CheckSetOfOriginsDuplicateFree(Termstate, Clauses);
  for (c_i = 0; c_i < array_GetSize(Clauses); c_i++) {
    c_clause = (CLAUSE)array_GetElement(Clauses, c_i);
    twfo_CheckIfOriginIsShared(Termstate, c_clause);
    twfo_CheckIfOriginNoDuplicates(Termstate, c_clause);
    twfo_CheckIfNotSimpleTautology(Termstate, c_clause);
  }
#endif
  TWFO new;
  ARRAY insts;
  int it;
  INST cur;
  new = memory_Malloc(Mem, sizeof(struct TWFO_HELP));
  insts = array_Create(Mem, array_GetSize(Clauses));
  new->mem = Mem;
  new->subststate = Subststate;
  new->termstate = Termstate;
  new->symbstate = Symbstate;
  new->folstate = Folstate;
  new->sharer = Sharer;
  new->prlit = prlits_Create(Mem);
  new->instset = instset_Create(Mem, Clauses, Termstate, Trail, &insts);
  new->candidates = array_Create(Mem, twfo_INITIALCANDIDATESIZE);
  new->newInstances = array_Create(Mem, twfo_INITIALNEWINSTANCESSIZE);
  new->props = array_Create(Mem, 3*twfo_INITIALNEWINSTANCESSIZE);
  new->factors = 0;
  for (it = 0; it < array_GetSize(insts); it++) {
    cur = (INST)array_GetElement(insts, it);
    twfo_FullyFactorizeInst(new, cur, Trail, FALSE, trail_GetSize(Trail));
  }
  array_Delete(Mem, insts);
  return new;
}
void twfo_Delete(TWFO Twfo)
{
  MEMORY mem;
  mem = twfo_GetMemory(Twfo);
  array_Delete(mem, twfo_GetCandidates(Twfo));
  array_Delete(mem, twfo_GetNewInstances(Twfo));
  array_Delete(mem, Twfo->props);
  instset_Delete(twfo_GetMemory(Twfo), twfo_GetInstset(Twfo), twfo_GetSymbstate(Twfo));
  prlits_Delete(twfo_GetPrlit(Twfo));
  memory_Free(mem, Twfo, sizeof(struct TWFO_HELP));
}
MEMORY twfo_GetMemory(TWFO Twfo)
{
  return Twfo->mem;
}
unsigned twfo_GetFactors(TWFO Twfo)
{
  return Twfo->factors;
}
void twfo_SetFactors(TWFO Twfo, unsigned Value)
{
  Twfo->factors = Value;
}
void twfo_IncrementFactors(TWFO Twfo)
{
  Twfo->factors++;
}
SUBSTSTATE twfo_GetSubststate(TWFO Twfo)
{
  return Twfo->subststate;
}
TERMSTATE twfo_GetTermstate(TWFO Twfo)
{
  return Twfo->termstate;
}
SYMBSTATE twfo_GetSymbstate(TWFO Twfo)
{
  return Twfo->symbstate;
}
FOLSTATE twfo_GetFolstate(TWFO Twfo)
{
  return Twfo->folstate;
}
SHARER twfo_Sharer(TWFO Twfo)
{
  return Twfo->sharer;
}
INSTSET twfo_GetInstset(TWFO Twfo)
{
  return Twfo->instset;
}
PRLITS twfo_GetPrlit(TWFO Twfo)
{
  return Twfo->prlit;
}
ARRAY twfo_GetCandidates(TWFO Twfo)
{
  return Twfo->candidates;
}
void twfo_SetCandidates(TWFO Twfo, ARRAY Candidates)
{
  Twfo->candidates = Candidates;
}
ARRAY twfo_GetNewInstances(TWFO Twfo)
{
  return Twfo->newInstances;
}
void twfo_SetNewInstances(TWFO Twfo, ARRAY NewInstances)
{
  Twfo->newInstances = NewInstances;
}
BOOL twfo_AlreadySet(TWFO Twfo, TERM Atom, SUBST Subst, TRAIL Trail, unsigned Trailsize)
{
  return (subst_TermIsGrounded(Twfo->termstate, Atom, Subst) && trail_AtomDataPos(Trail, Atom, Subst, Trailsize - 1) != NULL);
}
void twfo_PopProp(TWFO Twfo, CLAUSE *Clause, SUBST *Subst, unsigned *Litpos)
{
  *Litpos = (unsigned)array_Pop(Twfo->props);
  *Subst = (SUBST)array_Pop(Twfo->props);
  *Clause = (CLAUSE)array_Pop(Twfo->props);
}
void twfo_PushProp(TWFO Twfo, CLAUSE Clause, SUBST Subst, unsigned Litpos)
{
  Twfo->props = array_Push(Twfo->mem, Twfo->props, (intptr_t)Clause);
  Twfo->props = array_Push(Twfo->mem, Twfo->props, (intptr_t)Subst);
  Twfo->props = array_Push(Twfo->mem, Twfo->props, (intptr_t)Litpos);
}
ARRAY twfo_GetProps(TWFO Twfo)
{
  return Twfo->props;
}
void twfo_PrintPropLiterals(TWFO Twfo)
{
  unsigned i;
  ARRAY prlits;
  prlits = prlits_GetStack(twfo_GetPrlit(Twfo));
  printf("\n\n Prlits:  %lu ", array_GetSize(prlits));
  for (i=0;i<array_GetSize(prlits);i++) {
    if (!prlits_GetAnnoLitValue((PRLITS_ANNO_LIT)prlits[i]))
      printf("~");
    term_PrintPrefix(twfo_GetTermstate(Twfo), prlits_GetAnnoLitAtom((PRLITS_ANNO_LIT)prlits[i]));
    printf(":%u:P%d:I%d:C%u ", i, term_IsPropagatable(prlits_GetAnnoLitAtom((PRLITS_ANNO_LIT)prlits[i])), term_GetPrLitIndex(prlits_GetAnnoLitAtom((PRLITS_ANNO_LIT)prlits[i])), clause_GetId(prlits_GetAnnoLitOriginClause((PRLITS_ANNO_LIT)prlits[i])));
  }
}
BOOL twfo_CheckInstContextSize(TWFO Twfo, INST Inst)
{
  return TRUE;
}
INST twfo_CheckForUnifiableWatched(TWFO Twfo, INST Inst, TRAIL Trail, unsigned Pos)
{
  SUBSTSTATE subststate;
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  FOLSTATE folstate;
  CLAUSE clause;
  SUBST subst;
  unsigned w1, w2;
  INST new;
  subststate = twfo_GetSubststate(Twfo);
  termstate = twfo_GetTermstate(Twfo);
  symbstate = twfo_GetSymbstate(Twfo);
  folstate = twfo_GetFolstate(Twfo);
  clause = inst_GetOrigin(Inst);
  subst = inst_GetSubst(Inst);
  w1 = inst_GetFirstWatched(Inst);
  w2 = inst_GetSecondWatched(Inst);
  if (clause_LiteralIsPositive(clause, w1) != clause_LiteralIsPositive(clause, w2))
    return NULL;
  new = NULL;
  subst_ContextStart(subststate, symbstate);
  if (subst_FolTermUnifyIdenticalVarsSubst(subststate, folstate, termstate, symbstate,
                                        clause_GetTypes(clause), subst, clause_GetAtom(clause, w1), clause_GetAtom(clause, w2), TRUE)) {
    if (twfo_CheckInstContextSize(Twfo, Inst)) {
      new = instset_IfNotInAddNewInstanceFromContext(twfo_GetMemory(Twfo), twfo_Sharer(Twfo), termstate, twfo_GetInstset(Twfo), Inst, subststate, 0, Trail, FALSE, Pos);
      if (new)
 twfo_IncrementFactors(Twfo);
#ifdef SPASS_CHECK
      if (new) {
 inst_CheckWatchedCorrect(new, termstate, Trail, Pos);
      }
#endif
    }
  }
  subst_ContextStop(subststate);
  return new;
}
BOOL twfo_CheckForUnit(SYMBSTATE Symbstate, INST Inst)
{
  CLAUSE clause;
  SUBST subst;
  TERM first_atom;
  unsigned it;
  clause = inst_GetOrigin(Inst);
  if (clause_GetPremiseLiterals(clause) != 0 && clause_GetConclusionLiterals(clause) != 0)
    return FALSE;
  subst = inst_GetSubst(Inst);
  first_atom = clause_GetAtom(clause, 0);
  for (it = 1; it < clause_GetFolLiterals(clause); it++)
    if (!subst_TermEqualModuloSubsts(Symbstate, first_atom, subst, clause_GetAtom(clause, it), subst))
      return FALSE;
  return TRUE;
}
void twfo_FullyFactorizeInst(TWFO Twfo, INST NewInst, TRAIL Trail, BOOL Lazy, unsigned Pos)
{
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  SUBSTSTATE subststate;
  SHARER sharer;
  PRLITS prlit;
  INST cur, next;
  CLAUSE clause;
  termstate = twfo_GetTermstate(Twfo);
  symbstate = twfo_GetSymbstate(Twfo);
  subststate = twfo_GetSubststate(Twfo);
  sharer = twfo_Sharer(Twfo);
  prlit = twfo_GetPrlit(Twfo);
  cur = NewInst;
  if (inst_GetFirstWatched(cur) != inst_GetSecondWatched(cur)) {
    next = NewInst;
    while (next != NULL) {
      cur = next;
      next = twfo_CheckForUnifiableWatched(Twfo, cur, Trail, Pos);
    }
  }
  if (twfo_CheckForUnit(symbstate, cur)) {
    clause = inst_GetOrigin(cur);
    if (Lazy) {
      twfo_PushProp(Twfo, clause, inst_GetSubst(cur), 0);
    }
    else
      prlits_AddIfNotMember(prlit, sharer, termstate, subststate, clause, inst_GetSubst(cur), 0, 0);
  }
}
void twfo_ClearStackDeletedUnits(TWFO Twfo)
{
  PRLITS_ANNO_LIT cur;
  ARRAY stack;
  PRLITS plits;
  unsigned i,j;
  plits = twfo_GetPrlit(Twfo);
  stack = prlits_GetStack(plits);
  for (i=0, j=0; i< array_GetSize(stack); i++) {
    cur = (PRLITS_ANNO_LIT)stack[i];
    if (clause_IsMarkedDelete(prlits_GetAnnoLitOriginClause(cur))) {
      prlits_SetLitsmap(plits, ohash_Remove(prlits_GetLitsmap(plits), (OHASH_KEY_TYPE)cur, NULL, (OHASH_DELETE_DATA_FCT)prlits_HashDataDelete));
    }
    else {
      stack[j] = stack[i];
      j++;
    }
  }
  array_SetSize(stack,j);
}
void twfo_Backtrack(TWFO Twfo, TRAIL Trail)
{
  TERMSTATE termstate;
  termstate = twfo_GetTermstate(Twfo);
  prlits_RemoveUntilTrailsize(twfo_GetPrlit(Twfo), termstate, trail_GetSize(Trail));
}
void twfo_LearnNewClause(TWFO Twfo, TRAIL Trail, CLAUSE NewClause, BOOL Lazy, unsigned Pos)
{
#ifdef SPASS_CHECK
  twfo_CheckIfOriginIsShared(twfo_GetTermstate(Twfo), NewClause);
  if (!instset_CheckIfOriginNotMember(twfo_GetInstset(Twfo), NewClause)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Given clause\n ", __func__);
    clause_Print(twfo_GetTermstate(Twfo), NewClause);
    printf("\n");
    misc_ErrorReport(" is already as an origin clause in the set of instances.");
    misc_FinishErrorReport();
  }
  twfo_CheckIfOriginNoDuplicates(twfo_GetTermstate(Twfo), NewClause);
  twfo_CheckIfNotSimpleTautology(twfo_GetTermstate(Twfo), NewClause);
#endif
  TERMSTATE termstate;
  INST new;
  termstate = twfo_GetTermstate(Twfo);
  new = instset_NewOriginClause(twfo_GetMemory(Twfo), twfo_GetInstset(Twfo), NewClause, termstate, Trail, Pos);
  if (Lazy || trail_GetSize(Trail) == 0)
    twfo_FullyFactorizeInst(Twfo, new, Trail, Lazy, Pos);
  else
    twfo_CheckInstForRuleApplications(Twfo, new, Trail);
}
void twfo_BacktrackAndLearn(TWFO Twfo, TRAIL Trail, CLAUSE LearntClause)
{
  twfo_Backtrack(Twfo, Trail);
  twfo_LearnNewClause(Twfo, Trail, LearntClause, FALSE, trail_GetSize(Trail));
}
void twfo_GenerateAllFalseInstancesFromWatched(TWFO Twfo, INST Inst, BOOL FirstWatched, TRAIL Trail, ARRAY * NewInstances)
{
#ifdef SPASS_CHECK
  if (trail_GetSize(Trail) == 0) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Trail is empty.", __func__);
    misc_FinishErrorReport();
  }
#endif
  MEMORY mem;
  TERMSTATE termstate;
  SUBSTSTATE subststate;
  SHARER sharer;
  CLAUSE clause;
  TYPING types;
  SUBST subst;
  unsigned watched;
  TERM atom;
  BOOL pol;
  INST new;
  mem = twfo_GetMemory(Twfo);
  termstate = twfo_GetTermstate(Twfo);
  subststate = twfo_GetSubststate(Twfo);
  sharer = twfo_Sharer(Twfo);
  clause = inst_GetOrigin(Inst);
  types = clause_GetTypes(clause);
  subst = inst_GetSubst(Inst);
  if (FirstWatched)
    watched = inst_GetFirstWatched(Inst);
  else
    watched = inst_GetSecondWatched(Inst);
  atom = clause_GetAtom(clause, watched);
  pol = clause_LiteralIsPositive(clause, watched);
  if (trail_StartFalseInstancesIterator(Trail, atom, subst, pol, types))
    while (trail_NextFalseInstanceFromIterator(Trail, atom, subst, pol, types)) {
      if (twfo_CheckInstContextSize(Twfo, Inst)) {
        new = instset_IfNotInAddNewInstanceFromContext(mem, sharer, termstate, twfo_GetInstset(Twfo), Inst, subststate, (FirstWatched ? 1 : 2), Trail, TRUE, trail_GetSize(Trail));
        if (new != NULL) {
          *NewInstances = array_Add(mem, *NewInstances, (intptr_t) new);
 }
      }
      else {
      }
      subst_ContextStop(subststate);
    }
  trail_StopInstancesIterator(Trail);
}
void twfo_GenerateAllFalseInstancesFromWatchedPos(TWFO Twfo, INST Inst, BOOL FirstWatched, TRAIL Trail, ARRAY * NewInstances, unsigned Pos)
{
#ifdef SPASS_CHECK
  if (trail_GetSize(Trail) == 0) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Trail is empty.", __func__);
    misc_FinishErrorReport();
  }
#endif
  MEMORY mem;
  TERMSTATE termstate;
  SUBSTSTATE subststate;
  SHARER sharer;
  CLAUSE clause;
  TYPING types;
  SUBST subst;
  unsigned watched;
  TERM atom;
  BOOL pol;
  INST new;
  mem = twfo_GetMemory(Twfo);
  termstate = twfo_GetTermstate(Twfo);
  subststate = twfo_GetSubststate(Twfo);
  sharer = twfo_Sharer(Twfo);
  clause = inst_GetOrigin(Inst);
  types = clause_GetTypes(clause);
  subst = inst_GetSubst(Inst);
  if (FirstWatched)
    watched = inst_GetFirstWatched(Inst);
  else
    watched = inst_GetSecondWatched(Inst);
  atom = clause_GetAtom(clause, watched);
  pol = clause_LiteralIsPositive(clause, watched);
  if (trail_StartFalseInstancesIterator(Trail, atom, subst, pol, types))
    while (trail_NextFalseInstanceFromIteratorPos(Trail, atom, subst, pol, types, Pos)) {
      if (twfo_CheckInstContextSize(Twfo, Inst)) {
        new = instset_IfNotInAddNewInstanceFromContext(mem, sharer, termstate, twfo_GetInstset(Twfo), Inst, subststate, (FirstWatched ? 1 : 2), Trail, TRUE, Pos);
        if (new != NULL) {
          *NewInstances = array_Add(mem, *NewInstances, (intptr_t) new);
 }
      }
      subst_ContextStop(subststate);
    }
  trail_StopInstancesIterator(Trail);
}
INST twfo_CheckInstForRuleApplications(TWFO Twfo, INST Inst, TRAIL Trail)
{
#ifdef SPASS_CHECK
  if (trail_GetSize(Trail) == 0) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Trail is empty.", __func__);
    misc_FinishErrorReport();
  }
#endif
  MEMORY mem;
  ARRAY insts;
  INST result;
  mem = twfo_GetMemory(Twfo);
  insts = array_Clean(twfo_GetNewInstances(Twfo));
  insts = array_Add(mem, insts, (intptr_t)Inst);
  result = twfo_CheckArrayOfInstsForRuleApplications(Twfo, &insts, Trail);
  twfo_SetNewInstances(Twfo, insts);
  return result;
}
INST twfo_CheckInstForRuleApplicationsPos(TWFO Twfo, INST Inst, TRAIL Trail, unsigned Pos)
{
#ifdef SPASS_CHECK
  if (trail_GetSize(Trail) == 0) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Trail is empty.", __func__);
    misc_FinishErrorReport();
  }
#endif
  MEMORY mem;
  ARRAY insts;
  INST result;
  mem = twfo_GetMemory(Twfo);
  insts = array_Clean(twfo_GetNewInstances(Twfo));
  insts = array_Add(mem, insts, (intptr_t)Inst);
  result = twfo_CheckArrayOfInstsForRuleApplicationsPos(Twfo, &insts, Trail, Pos);
  twfo_SetNewInstances(Twfo, insts);
  return result;
}
INST twfo_CheckArrayOfInstsForRuleApplications(TWFO Twfo, ARRAY * Insts, TRAIL Trail)
{
#ifdef SPASS_CHECK
  if (trail_GetSize(Trail) == 0) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Trail is empty.", __func__);
    misc_FinishErrorReport();
  }
  if (array_IsEmpty(*Insts)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Array of instances that sould be checked is empty.", __func__);
    misc_FinishErrorReport();
  }
#endif
  MEMORY mem;
  TERMSTATE termstate;
  SUBSTSTATE subststate;
  SHARER sharer;
  PRLITS prlit;
  INST cur, new, conflict;
  CLAUSE clause;
  SUBST subst;
  unsigned w1, w2;
  TERM atom1, atom2;
  BOOL ground1, ground2, pol1, pol2;
  VAR_STATUS value1, value2;
  mem = twfo_GetMemory(Twfo);
  termstate = twfo_GetTermstate(Twfo);
  subststate = twfo_GetSubststate(Twfo);
  sharer = twfo_Sharer(Twfo);
  prlit = twfo_GetPrlit(Twfo);
  conflict = NULL;
  while (!array_IsEmpty(*Insts)) {
    cur = (INST)array_Pop(*Insts);
    clause = inst_GetOrigin(cur);
    subst = inst_GetSubst(cur);
    new = twfo_CheckForUnifiableWatched(Twfo, cur, Trail, trail_GetSize(Trail));
    if (new != NULL)
      *Insts = array_Add(mem, *Insts, (intptr_t) new);
    w1 = inst_GetFirstWatched(cur);
    w2 = inst_GetSecondWatched(cur);
    atom1 = clause_GetAtom(clause, w1);
    atom2 = clause_GetAtom(clause, w2);
    pol1 = clause_LiteralIsPositive(clause, w1);
    pol2 = clause_LiteralIsPositive(clause, w2);
    ground1 = subst_TermIsGrounded(termstate, atom1, subst);
    ground2 = subst_TermIsGrounded(termstate, atom2, subst);
    if (ground1)
      value1 = trail_LitStatusFromAtom(Trail, atom1, subst, pol1);
    if (ground2)
      value2 = trail_LitStatusFromAtom(Trail, atom2, subst, pol2);
    if ((ground1 && value1 == SET_FALSE) && (ground2 && value2 == SET_FALSE)) {
      conflict = cur;
      continue;
    }
    if (ground1 && value1 == SET_FALSE)
      if (!twfo_AlreadySet(Twfo, clause_GetAtom(clause, w2), subst, Trail, trail_GetSize(Trail))) prlits_AddIfNotMember(prlit, sharer, termstate, subststate, clause, subst, w2, trail_GetSize(Trail));
    if (ground2 && value2 == SET_FALSE)
      if (!twfo_AlreadySet(Twfo, clause_GetAtom(clause, w1), subst, Trail, trail_GetSize(Trail))) prlits_AddIfNotMember(prlit, sharer, termstate, subststate, clause, subst, w1, trail_GetSize(Trail));
    if (!ground1)
      twfo_GenerateAllFalseInstancesFromWatched(Twfo, cur, TRUE, Trail, Insts);
    if (!ground2)
      twfo_GenerateAllFalseInstancesFromWatched(Twfo, cur, FALSE, Trail, Insts);
  }
  return conflict;
}
INST twfo_CheckArrayOfInstsForRuleApplicationsPos(TWFO Twfo, ARRAY * Insts, TRAIL Trail, unsigned Trailpos)
{
#ifdef SPASS_CHECK
  if (trail_GetSize(Trail) == 0) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Trail is empty.", __func__);
    misc_FinishErrorReport();
  }
  if (array_IsEmpty(*Insts)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Array of instances that should be checked is empty.", __func__);
    misc_FinishErrorReport();
  }
#endif
  MEMORY mem;
  TERMSTATE termstate;
  INST cur, new, conflict;
  CLAUSE clause;
  SUBST subst;
  unsigned w1, w2;
  TERM atom1, atom2;
  BOOL ground1, ground2, pol1, pol2;
  VAR_STATUS value1, value2;
  mem = twfo_GetMemory(Twfo);
  termstate = twfo_GetTermstate(Twfo);
  conflict = NULL;
  while (!array_IsEmpty(*Insts)) {
    cur = (INST)array_Pop(*Insts);
    clause = inst_GetOrigin(cur);
    subst = inst_GetSubst(cur);
    new = twfo_CheckForUnifiableWatched(Twfo, cur, Trail, Trailpos);
    if (new != NULL)
      *Insts = array_Add(mem, *Insts, (intptr_t) new);
    w1 = inst_GetFirstWatched(cur);
    w2 = inst_GetSecondWatched(cur);
    atom1 = clause_GetAtom(clause, w1);
    atom2 = clause_GetAtom(clause, w2);
    pol1 = clause_LiteralIsPositive(clause, w1);
    pol2 = clause_LiteralIsPositive(clause, w2);
    ground1 = subst_TermIsGrounded(termstate, atom1, subst);
    ground2 = subst_TermIsGrounded(termstate, atom2, subst);
    if (ground1)
      value1 = trail_LitStatusFromAtomPos(Trail, atom1, subst, pol1, Trailpos);
    if (ground2)
      value2 = trail_LitStatusFromAtomPos(Trail, atom2, subst, pol2, Trailpos);
    if ((ground1 && value1 == SET_FALSE) && (ground2 && value2 == SET_FALSE)) {
      conflict = cur;
      continue;
    }
    if (ground1 && value1 == SET_FALSE) {
      if (!twfo_AlreadySet(Twfo, clause_GetAtom(clause, w2), subst, Trail, Trailpos + 1)) twfo_PushProp(Twfo, clause, subst, w2);
    }
    if (ground2 && value2 == SET_FALSE) {
      if (!twfo_AlreadySet(Twfo, clause_GetAtom(clause, w1), subst, Trail, Trailpos + 1)) twfo_PushProp(Twfo, clause, subst, w1);
    }
    if (!ground1)
      twfo_GenerateAllFalseInstancesFromWatchedPos(Twfo, cur, TRUE, Trail, Insts, Trailpos);
    if (!ground2)
      twfo_GenerateAllFalseInstancesFromWatchedPos(Twfo, cur, FALSE, Trail, Insts, Trailpos);
  }
  return conflict;
}
INST twfo_NewLiteralOnTrail(TWFO Twfo, TRAIL Trail)
{
#ifdef SPASS_CHECK
  if (trail_GetSize(Trail) == 0) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Trail is empty.", __func__);
    misc_FinishErrorReport();
  }
#endif
  MEMORY mem;
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  SUBSTSTATE subststate;
  FOLSTATE folstate;
  INSTSET instset;
  SHARER sharer;
  PRLITS prlit;
  ARRAY candidates;
  INST_QUERY it;
  INST inst, conflict, new;
  CLAUSE clause;
  unsigned trailsize, w_cand, w_other;
  TERM atom_cand, atom_other, new_atom;
  BOOL pol_other, first_false, grounded_other;
  VAR_STATUS value_other;
  SUBST subst;
  mem = twfo_GetMemory(Twfo);
  termstate = twfo_GetTermstate(Twfo);
  symbstate = twfo_GetSymbstate(Twfo);
  subststate = twfo_GetSubststate(Twfo);
  folstate = twfo_GetFolstate(Twfo);
  sharer = twfo_Sharer(Twfo);
  instset = twfo_GetInstset(Twfo);
  prlit = twfo_GetPrlit(Twfo);
  trailsize = trail_GetSize(Trail);
  new_atom = trail_GetAtomFromTrailPos(Trail, trailsize - 1);
  candidates = array_Clean(twfo_GetCandidates(Twfo));
  candidates = instset_SearchNewlyFalseWatched(mem, instset, termstate, new_atom, trail_IsPositiveFromTrailPos(Trail, trailsize - 1), &candidates, trailsize-1);
  array_Clean(twfo_GetNewInstances(Twfo));
  conflict = NULL;
  while (!array_IsEmpty(candidates)) {
    it = (INST_QUERY)array_Pop(candidates);
    inst = inst_GetQueryInst(it);
    first_false = inst_GetQueryFirstWatched(it);
    if (first_false) {
      w_cand = inst_GetFirstWatched(inst);
      w_other = inst_GetSecondWatched(inst);
    } else {
      w_other = inst_GetFirstWatched(inst);
      w_cand = inst_GetSecondWatched(inst);
    }
    clause = inst_GetOrigin(inst);
    subst = inst_GetSubst(inst);
    atom_cand = clause_GetAtom(clause, w_cand);
    if (subst_TermIsGrounded(termstate, atom_cand, subst)) {
      atom_other = clause_GetAtom(clause, w_other);
      pol_other = clause_LiteralIsPositive(clause, w_other);
      grounded_other = subst_TermIsGrounded(termstate, atom_other, subst);
      if (grounded_other) {
        value_other = trail_LitStatusFromAtom(Trail, atom_other, subst, pol_other);
        if (value_other == SET_TRUE)
          continue;
      }
      if (instset_TryUpdateWatched(mem, instset, termstate, inst, first_false, Trail)) {
        conflict = twfo_CheckInstForRuleApplications(Twfo, inst, Trail);
        if (conflict != NULL)
          break;
      } else {
        if (grounded_other) {
          if (value_other == SET_FALSE) {
            conflict = inst;
            break;
          }
        }
        if (!twfo_AlreadySet(Twfo, clause_GetAtom(clause, w_other), subst, Trail, trailsize)) prlits_AddIfNotMember(prlit, sharer, termstate, subststate, clause, subst, w_other, trailsize);
      }
    } else {
      subst_ContextStart(subststate, symbstate);
      if (!subst_FolTermMatchTermsSubsts(subststate, symbstate, termstate, folstate, atom_cand, clause_GetTypes(clause), subst, new_atom, NULL, NULL) ||
          !twfo_CheckInstContextSize(Twfo, inst)) {
        subst_ContextStop(subststate);
        continue;
      }
      new = instset_IfNotInAddNewInstanceFromContext(mem, sharer, termstate, instset, inst, subststate, (first_false ? 1 : 2), Trail, TRUE, trail_GetSize(Trail));
      subst_ContextStop(subststate);
      if (new == NULL)
        continue;
      conflict = twfo_CheckInstForRuleApplications(Twfo, new, Trail);
      if (conflict != NULL)
        break;
    }
  }
  twfo_SetCandidates(Twfo, candidates);
  return conflict;
}
void twfo_BacktrackLiteralOnTrail(TWFO Twfo, TRAIL Trail, unsigned Pos, CLAUSE Clause)
{
#ifdef SPASS_CHECK
  if (trail_GetSize(Trail) == 0) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Trail is empty.", __func__);
    misc_FinishErrorReport();
  }
#endif
  MEMORY mem;
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  SUBSTSTATE subststate;
  FOLSTATE folstate;
  INSTSET instset;
  SHARER sharer;
  ARRAY candidates;
  ARRAY *new_instances;
  INST_QUERY it;
  INST inst, conflict, new;
  CLAUSE clause;
  unsigned w_cand, w_updated, w_other;
  TERM atom_cand, atom_updated, atom_other, new_atom;
  BOOL pol_other, first_false, grounded_other;
  VAR_STATUS value_other;
  SUBST subst;
  mem = twfo_GetMemory(Twfo);
  termstate = twfo_GetTermstate(Twfo);
  symbstate = twfo_GetSymbstate(Twfo);
  subststate = twfo_GetSubststate(Twfo);
  folstate = twfo_GetFolstate(Twfo);
  sharer = twfo_Sharer(Twfo);
  instset = twfo_GetInstset(Twfo);
  new_atom = trail_GetAtomFromTrailPos(Trail, Pos);
  candidates = array_Clean(twfo_GetCandidates(Twfo));
  candidates = instset_SearchNewlyFalseWatched(mem, instset, termstate, new_atom, trail_IsPositiveFromTrailPos(Trail, Pos), &candidates, Pos);
  array_Clean(twfo_GetNewInstances(Twfo));
  new_instances = &(Twfo->newInstances);
  conflict = NULL;
  while (!array_IsEmpty(candidates)) {
    it = (INST_QUERY)array_Pop(candidates);
    inst = inst_GetQueryInst(it);
    first_false = inst_GetQueryFirstWatched(it);
    if (first_false) {
      w_cand = inst_GetFirstWatched(inst);
      w_other = inst_GetSecondWatched(inst);
    }
    else {
      w_other = inst_GetFirstWatched(inst);
      w_cand = inst_GetSecondWatched(inst);
    }
    clause = inst_GetOrigin(inst);
    subst = inst_GetSubst(inst);
    atom_cand = clause_GetAtom(clause, w_cand);
    if (clause == Clause) {
      if (subst_TermIsGrounded(termstate, atom_cand, subst)) {
 atom_other = clause_GetAtom(clause, w_other);
 pol_other = clause_LiteralIsPositive(clause, w_other);
 grounded_other = subst_TermIsGrounded(termstate, atom_other, subst);
 if (grounded_other) {
   value_other = trail_LitStatusFromAtomPos(Trail, atom_other, subst, pol_other, Pos);
   if (value_other == SET_TRUE)
     continue;
 }
 if (instset_TryUpdateWatchedPos(mem, instset, termstate, inst, first_false, Trail, Pos)) {
   if (first_false)
     w_updated = inst_GetFirstWatched(inst);
   else
     w_updated = inst_GetSecondWatched(inst);
   atom_updated = clause_GetAtom(clause, w_updated);
   new = twfo_CheckForUnifiableWatched(Twfo, inst, Trail, Pos);
   if (new != NULL)
     *new_instances = array_Add(mem, *new_instances, (intptr_t) new);
   if (!subst_TermIsGrounded(termstate, atom_updated, subst))
     twfo_GenerateAllFalseInstancesFromWatchedPos(Twfo, inst, first_false, Trail, new_instances,Pos);
   if (array_IsEmpty(*new_instances))
     continue;
   conflict = twfo_CheckArrayOfInstsForRuleApplicationsPos(Twfo, new_instances, Trail, Pos);
   if (conflict != NULL) {
     misc_StartErrorReport();
     trail_ClausePrintSubst(Trail, termstate, inst_GetOrigin(conflict), inst_GetSubst(conflict)); printf("\n");
     misc_ErrorReport("\n In %s: Conflict found but should have found propagation first.", __func__);
     misc_FinishErrorReport();
   }
 } else {
   if (grounded_other) {
     if (value_other == SET_FALSE) {
       misc_StartErrorReport();
       trail_ClausePrintSubst(Trail, termstate, inst_GetOrigin(inst), inst_GetSubst(inst)); printf("\n");
       misc_ErrorReport("\n In %s: Conflict found but should have found propagation first.", __func__);
       misc_FinishErrorReport();
     }
   }
   if (!twfo_AlreadySet(Twfo, clause_GetAtom(clause, w_other), subst, Trail, Pos + 1))
     twfo_PushProp(Twfo, clause, subst, w_other);
 }
      } else {
 subst_ContextStart(subststate, symbstate);
 if (!subst_FolTermMatchTermsSubsts(subststate, symbstate, termstate, folstate, atom_cand, clause_GetTypes(clause), subst, new_atom, NULL, NULL) ||
     !twfo_CheckInstContextSize(Twfo, inst)) {
   subst_ContextStop(subststate);
   continue;
 }
 new = instset_IfNotInAddNewInstanceFromContext(mem, sharer, termstate, instset, inst, subststate, (first_false ? 1 : 2), Trail, TRUE, Pos);
 subst_ContextStop(subststate);
 if (new == NULL)
   continue;
 conflict = twfo_CheckInstForRuleApplicationsPos(Twfo, new, Trail, Pos);
 if (conflict != NULL) {
   misc_StartErrorReport();
   trail_ClausePrintSubst(Trail, termstate, inst_GetOrigin(conflict), inst_GetSubst(conflict)); printf("\n");
   misc_ErrorReport("\n In %s: Conflict found but should have found propagation first.", __func__);
   misc_FinishErrorReport();
 }
      }
    }
  }
  twfo_SetCandidates(Twfo, candidates);
}
void twfo_RestartForgetAndGrow(TWFO Twfo, ARRAY Forget, ARRAY NewClauses, TRAIL Trail, BOOL DeleteInstances)
{
#ifdef SPASS_CHECK
  int c_i;
  CLAUSE c_clause;
  if (trail_GetSize(Trail) > 0) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Trail is not empty.", __func__);
    misc_FinishErrorReport();
  }
  if (NewClauses != NULL) {
    twfo_CheckSetOfOriginsDuplicateFree(twfo_GetTermstate(Twfo), NewClauses);
    for (c_i = 0; c_i < array_GetSize(NewClauses); c_i++) {
      c_clause = (CLAUSE)array_GetElement(NewClauses, c_i);
      twfo_CheckIfOriginIsShared(twfo_GetTermstate(Twfo), c_clause);
      twfo_CheckIfOriginNoDuplicates(twfo_GetTermstate(Twfo), c_clause);
      twfo_CheckIfNotSimpleTautology(twfo_GetTermstate(Twfo), c_clause);
      if (!instset_CheckIfOriginNotMember(twfo_GetInstset(Twfo), c_clause)) {
        misc_StartErrorReport();
        misc_ErrorReport("\n In %s: Given clause\n ", __func__);
        clause_Print(twfo_GetTermstate(Twfo), c_clause);
        printf("\n");
        misc_ErrorReport(" is already as an origin clause in the set of instances.");
        misc_FinishErrorReport();
      }
    }
  }
#endif
  MEMORY mem;
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  INSTSET instset;
  PRLITS plit;
  CLAUSE new_clause;
  int it;
  mem = twfo_GetMemory(Twfo);
  termstate = twfo_GetTermstate(Twfo);
  symbstate = twfo_GetSymbstate(Twfo);
  instset = twfo_GetInstset(Twfo);
  plit = twfo_GetPrlit(Twfo);
  prlits_RestartAndForget(plit, termstate, Forget);
  instset_RestartAndForget(mem, symbstate, instset, Forget, DeleteInstances);
  if (NewClauses == NULL)
    return;
  for (it = 0; it < array_GetSize(NewClauses); it++) {
    new_clause = (CLAUSE)array_GetElement(NewClauses, it);
    twfo_LearnNewClause(Twfo, Trail, new_clause, FALSE, trail_GetSize(Trail));
  }
}
void twfo_RefreshInstances(TWFO Twfo)
{
  instset_RefreshInstances(twfo_GetMemory(Twfo), twfo_GetTermstate(Twfo), twfo_GetInstset(Twfo));
  twfo_SetFactors(Twfo, 0);
}
void twfo_FactorizeRefreshedInstances(TWFO Twfo, TRAIL Trail)
{
  MEMORY mem;
  ARRAY insts;
  unsigned i;
  INST cur;
  mem = twfo_GetMemory(Twfo);
  insts = array_Create(mem, 200);
  insts = instset_GetAllInstances(mem, twfo_GetInstset(Twfo), &insts);
  for (i = 0; i < array_GetSize(insts); i++) {
    cur = (INST)array_GetElement(insts, i);
    twfo_FullyFactorizeInst(Twfo, cur, Trail, FALSE, trail_GetSize(Trail));
  }
  array_Delete(mem,insts);
}
void twfo_CheckSetOfOriginsDuplicateFree(TERMSTATE Termstate, ARRAY Origins)
{
  int i, j;
  unsigned cur_id;
  CLAUSE cur;
  for (i = 0; i < array_GetSize(Origins); i++) {
    cur = (CLAUSE)array_GetElement(Origins, i);
    cur_id = clause_GetId(cur);
    for (j = i + 1; j < array_GetSize(Origins); j++) {
      if (cur_id == clause_GetId((CLAUSE)array_GetElement(Origins, j))) {
        misc_StartErrorReport();
        misc_ErrorReport("\n In %s: Clause\n ", __func__);
        clause_Print(Termstate, cur);
        printf("\n");
        misc_ErrorReport(" is at least twice in the set of origin clauses.");
        misc_FinishErrorReport();
      }
    }
  }
}
void twfo_CheckIfOriginNoDuplicates(TERMSTATE Termstate, CLAUSE Origin)
{
  unsigned i, j;
  TERM cur;
  for (i = 0; i < clause_GetPremiseLiterals(Origin); i++) {
    cur = clause_GetAtom(Origin, i);
    for (j = i + 1; j < clause_GetPremiseLiterals(Origin); j++) {
      if (cur == clause_GetAtom(Origin, j)) {
        misc_StartErrorReport();
        misc_ErrorReport("\n In %s: Origin clause\n ", __func__);
        clause_Print(Termstate, Origin);
        printf("\n");
        misc_ErrorReport(" is not fully condensed.");
        misc_FinishErrorReport();
      }
    }
  }
  for (i = clause_GetPremiseLiterals(Origin); i < clause_GetFolLiterals(Origin); i++) {
    cur = clause_GetAtom(Origin, i);
    for (j = i + 1; j < clause_GetFolLiterals(Origin); j++) {
      if (cur == clause_GetAtom(Origin, j)) {
        misc_StartErrorReport();
        misc_ErrorReport("\n In %s: Origin clause\n ", __func__);
        clause_Print(Termstate, Origin);
        printf("\n");
        misc_ErrorReport(" is not fully condensed.");
        misc_FinishErrorReport();
      }
    }
  }
}
void twfo_CheckIfNotSimpleTautology(TERMSTATE Termstate, CLAUSE Origin)
{
  unsigned i, j;
  TERM cur;
  for (i = 0; i < clause_GetPremiseLiterals(Origin); i++) {
    cur = clause_GetAtom(Origin, i);
    for (j = clause_GetPremiseLiterals(Origin); j < clause_GetFolLiterals(Origin); j++) {
      if (cur == clause_GetAtom(Origin, j)) {
        misc_StartErrorReport();
        misc_ErrorReport("\n In %s: Origin clause\n ", __func__);
        clause_Print(Termstate, Origin);
        printf("\n");
        misc_ErrorReport(" is a simple tautology.");
        misc_FinishErrorReport();
      }
    }
  }
}
void twfo_CheckIfOriginIsShared(TERMSTATE Termstate, CLAUSE Origin)
{
  unsigned it;
  TERM atom;
  for (it = 0; it < clause_GetFolLiterals(Origin); it++) {
    atom = clause_GetAtom(Origin, it);
    if (!sharing_IsShared(atom)) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: Origin clause\n ", __func__);
      clause_Print(Termstate, Origin);
      printf("\n");
      misc_ErrorReport(" is not shared.");
      misc_FinishErrorReport();
    }
  }
}
unsigned twfo_TestSpecialConstantValue(SYMBSTATE Symbstate, SYMBOL Constant)
{
  char * Name;
  Name = symbol_GetName(Symbstate, Constant);
  if (Name[1] == '1') {
    if (string_Length(Name) == 2)
      return 1;
    else
      return 10;
  }
  if (Name[1] == '2')
    return 2;
  if (Name[1] == '3')
    return 3;
  if (Name[1] == '4')
    return 4;
  if (Name[1] == '5')
    return 5;
  if (Name[1] == '6')
    return 6;
  if (Name[1] == '7')
    return 7;
  if (Name[1] == '8')
    return 8;
  if (Name[1] == '9')
    return 9;
  if (Name[1] == '0')
    return 0;
  return 42;
}
void twfo_Test(MEMORY Mem, ARRAY Clauses, SHARER Sharer, SUBSTSTATE Subststate, TERMSTATE Termstate, SYMBSTATE Symbstate, FOLSTATE Folstate, SYMBOL Control)
{
  TWFO twfo;
  PRLITS pLit;
  TRAIL trail;
  ARRAY origins, forget, instances;
  TERM op, atom;
  int clause_it;
  unsigned it, n;
  CLAUSE clause;
  INST conflict;
  origins = array_Create(Mem, 8);
  for (clause_it = 1; term_TopSymbol(clause_GetAtom((CLAUSE)array_GetElement(Clauses, clause_it), 0)) != Control; clause_it++)
    origins = array_Add(Mem, origins, array_GetElement(Clauses, clause_it));
  instances = array_Create(Mem, 8);
  trail = trail_Create(Mem, Symbstate, Termstate, Folstate, Subststate, Sharer);
  twfo = twfo_Create(Mem, Subststate, Termstate, Symbstate, Folstate, Sharer, origins, trail);
  pLit = twfo_GetPrlit(twfo);
  for (; clause_it < array_GetSize(Clauses); clause_it++) {
    clause = (CLAUSE)array_GetElement(Clauses, clause_it);
    printf("%d:\n", clause_it + 1);
    clause_Print(Termstate, clause);
    printf("\n");
    op = clause_GetAtom(clause, 0);
    clause_RemoveLiteral(clause, 0);
    n = twfo_TestSpecialConstantValue(Symbstate, term_TopSymbol(term_SecondArgument(op)));
    switch (twfo_TestSpecialConstantValue(Symbstate, term_TopSymbol(term_FirstArgument(op)))) {
    case 1:
      trail_Add(trail, clause_GetAtom(clause, 0), clause, NULL, 0, clause_LiteralIsPositive(clause, 0), FALSE);
      conflict = twfo_NewLiteralOnTrail(twfo, trail);
      if (conflict != NULL) {
        printf("Found conflict instance: \n");
        inst_Print(Termstate, conflict);
        printf("\n");
      }
      break;
    case 2:
      for (it = 0; it < n; it++)
        trail_Pop(trail);
      origins = array_Add(Mem, origins, (intptr_t)clause);
      twfo_BacktrackAndLearn(twfo, trail, clause);
      break;
    case 3:
      while (trail_GetSize(trail) > 0)
        trail_Pop(trail);
      if (n < array_GetSize(origins)) {
        forget = array_Create(Mem, clause_GetFolLiterals(clause) * 2);
        forget = array_Add(Mem, forget, array_GetElement(origins, n));
        for (it = 0; it < clause_GetFolLiterals(clause); it++) {
          atom = clause_GetAtom(clause, it);
          if (term_TopSymbol(atom) != Control)
            break;
          n = twfo_TestSpecialConstantValue(Symbstate, term_TopSymbol(term_FirstArgument(atom)));
          if (n < array_GetSize(origins))
            forget = array_Add(Mem, forget, array_GetElement(origins, n));
          n = twfo_TestSpecialConstantValue(Symbstate, term_TopSymbol(term_SecondArgument(atom)));
          if (n < array_GetSize(origins))
            forget = array_Add(Mem, forget, array_GetElement(origins, n));
        }
      } else
        forget = NULL;
      if (clause_GetFolLiterals(clause) != 0) {
        atom = clause_GetAtom(clause, clause_GetFolLiterals(clause) - 1);
      }
      twfo_RestartForgetAndGrow(twfo, forget, NULL, trail, TRUE);
      if (forget != NULL) {
        for (it = 0; it < array_GetSize(forget); it++)
          array_PointerRemoveElement(origins, array_GetElement(forget, it));
        array_Delete(Mem, forget);
      }
      printf("current clauses: \n");
      for (it = 0; it < array_GetSize(origins); it++) {
        clause_Print(Termstate, (CLAUSE)array_GetElement(origins, it));
        printf("\n");
      }
      break;
    }
#ifdef SPASS_CHECK
    instset_CheckAllInstancesForWatched(Mem, twfo_GetInstset(twfo), Termstate, trail, TRUE);
#endif
    printf("Literals that can be propagated: ");
    prlits_Print(pLit, Termstate, TRUE);
    printf("\nTrail: ");
    trail_Print(trail);
    printf("\n\n");
  }
  array_Delete(Mem, instances);
  array_Delete(Mem, origins);
  trail_Delete(trail);
  twfo_Delete(twfo);
}
unsigned twfo_ComputeBacktrackLevelLearnNewClause(TWFO Twfo, TRAIL Trail, CLAUSE NewClause)
{
  TERMSTATE termstate;
  unsigned pos, leveldecision, result;
  SUBST subst;
  CLAUSE clause;
  unsigned litpos;
  BOOL unit;
#ifdef SPASS_CHECK
  twfo_CheckIfOriginIsShared(twfo_GetTermstate(Twfo), NewClause);
  if (!instset_CheckIfOriginNotMember(twfo_GetInstset(Twfo), NewClause)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Given clause\n ", __func__);
    clause_Print(twfo_GetTermstate(Twfo), NewClause);
    printf("\n");
    misc_ErrorReport(" is already as an origin clause in the set of instances.");
    misc_FinishErrorReport();
  }
  twfo_CheckIfOriginNoDuplicates(twfo_GetTermstate(Twfo), NewClause);
  twfo_CheckIfNotSimpleTautology(twfo_GetTermstate(Twfo), NewClause);
#endif
  termstate = twfo_GetTermstate(Twfo);
  array_Clean(twfo_GetProps(Twfo));
  twfo_LearnNewClause(Twfo, Trail, NewClause, TRUE, 0);
  leveldecision = 0;
  pos = 0;
  unit = FALSE;
  if (array_GetSize(twfo_GetProps(Twfo)) == 0) {
    while (pos < trail_GetSize(Trail)) {
      twfo_BacktrackLiteralOnTrail(Twfo, Trail, pos, NewClause);
      if (array_GetSize(twfo_GetProps(Twfo)) == 0)
 pos++;
      else
 break;
    }
  }
  else
    unit = TRUE;
  leveldecision = trail_GetDlFromTrailPos(Trail, pos);
  if (!unit)
    pos++;
  while (trail_GetSize(Trail) > pos) {
    trail_Pop(Trail);
  }
  trail_SetDl(Trail, leveldecision);
  trail_CStackAdjustSize(Trail);
  twfo_Backtrack(Twfo, Trail);
  result = array_GetSize(prlits_GetStack((PRLITS)twfo_GetPrlit(Twfo)));
  while (array_GetSize(twfo_GetProps(Twfo)) > 0) {
    twfo_PopProp(Twfo, &clause, &subst, &litpos);
    prlits_AddIfNotMember(twfo_GetPrlit(Twfo), twfo_Sharer(Twfo), termstate, twfo_GetSubststate(Twfo), clause, subst, litpos, trail_GetSize(Trail));
  }
  return result;
}
