#ifdef DOC_BUILD_INTERNAL
#endif
#include "tptp.h"
const char *const TPTP_LangFOF = "fof";
const char *const TPTP_LangCNF = "cnf";
const char *const TPTP_RoleAxiom = "axiom";
const char *const TPTP_RoleHypothesis = "hypothesis";
const char *const TPTP_RoleDefinition = "definition";
const char *const TPTP_RoleLemma = "lemma";
const char *const TPTP_RoleTheorem = "theorem";
const char *const TPTP_RoleCorollary = "corollary";
const char *const TPTP_RolePlain = "plain";
const char *const TPTP_RoleConjecture = "conjecture";
const char *const TPTP_RoleNegatedConjecture = "negated_conjecture";
TPTP_FORMULA tptp_AllocateFormula(MEMORY Mem)
{
  TPTP_FORMULA formula;
  formula = (TPTP_FORMULA)memory_Malloc(Mem, sizeof(TPTP_FORMULA_NODE));
  tptp_SetLanguage(formula, NULL);
  tptp_SetRole(formula, NULL);
  tptp_SetTerm(formula, NULL);
  tptp_SetFilename(formula, NULL);
  tptp_SetBasename(formula, NULL);
  tptp_SetProofstep(formula, NULL);
  return formula;
}
void tptp_FreeFormula(MEMORY Mem, TPTP_FORMULA Formula)
{
  if (tptp_GetName(Formula) != NULL)
    string_StringFree(Mem, tptp_GetName(Formula));
  if (Formula->basename != NULL)
    string_StringFree(Mem, Formula->basename);
  if (tptp_GetFilename(Formula) != NULL)
    string_StringFree(Mem, tptp_GetFilename(Formula));
  memory_Free(Mem, (POINTER)Formula, sizeof(TPTP_FORMULA_NODE));
}
const char *tptp_GetLanguage(TPTP_FORMULA Formula) {
  return Formula->language;
}
void tptp_SetLanguage(TPTP_FORMULA Formula, const char *Str) {
  Formula->language = Str;
}
char *tptp_GetName(TPTP_FORMULA Formula) {
  return Formula->name;
}
void tptp_SetName(TPTP_FORMULA Formula, char *Str) {
  Formula->name = Str;
}
const char *tptp_GetRole(TPTP_FORMULA Formula) {
  return Formula->role;
}
void tptp_SetRole(TPTP_FORMULA Formula, const char *Str) {
  Formula->role = Str;
}
BOOL tptp_TrySettingRole(TPTP_FORMULA Formula, char *Str, const char *Role)
{
  if (0 == strcmp(Str, Role)) {
    tptp_SetRole(Formula, Role);
    return TRUE;
  }
  else return FALSE;
}
TERM tptp_GetTerm(TPTP_FORMULA Formula) {
  return (TERM)Formula->data;
}
void tptp_SetTerm(TPTP_FORMULA Formula, TERM Term) {
  Formula->data = (intptr_t)Term;
}
CLAUSE tptp_GetClause(TPTP_FORMULA Formula) {
  return (CLAUSE)Formula->data;
}
void tptp_SetClause(TPTP_FORMULA Formula, CLAUSE Clause) {
  Formula->data = (intptr_t)Clause;
}
char *tptp_GetFilename(TPTP_FORMULA Formula) {
  return Formula->filename;
}
void tptp_SetFilename(TPTP_FORMULA Formula, char *Str) {
  Formula->filename = Str;
}
char *tptp_GetBasename(TPTP_FORMULA Formula) {
  return (Formula->basename ? Formula->basename : Formula->name);
}
void tptp_SetBasename(TPTP_FORMULA Formula, char *Str) {
  Formula->basename = Str;
}
TPTP_PROOFSTEP tptp_GetProofstep(TPTP_FORMULA Formula) {
  return Formula->proofstep;
}
void tptp_SetProofstep(TPTP_FORMULA Formula, TPTP_PROOFSTEP Proofstep) {
  Formula->proofstep = Proofstep;
}
static const char* StrOrNull(const char *Str)
{
  return Str?Str:"[NULL]";
}
TPTP_PROOFSTEP tptp_AllocateProofstep(MEMORY Mem)
{
  TPTP_PROOFSTEP proofstep;
  proofstep = (TPTP_PROOFSTEP)memory_Malloc(Mem, sizeof(TPTP_PROOFSTEP_NODE));
  proofstep->type = TPTP_PS_UNDEFINED;
  proofstep->visited = FALSE;
  proofstep->data = 0;
  return proofstep;
}
TPTP_PROOFSTEP tptp_CreateProofstep(TPTPSTATE Tptpstate)
{
  TPTP_PROOFSTEP proofstep = tptp_AllocateProofstep(tptp_GetMemory(Tptpstate));
  Tptpstate->proofsteps = array_Add(tptp_GetMemory(Tptpstate),
                                    Tptpstate->proofsteps,
                                    (intptr_t)proofstep);
  return proofstep;
}
TPTP_PROOFSTEP tptp_CreateProofstepStoreString(TPTPSTATE Tptpstate, char *Str)
{
  TPTP_PROOFSTEP proofstep = tptp_CreateProofstep(Tptpstate);
  ARRAY arr = array_Create(tptp_GetMemory(Tptpstate), 4);
  arr = array_Add(tptp_GetMemory(Tptpstate), arr, (intptr_t)Str);
  proofstep->data = (intptr_t)arr;
  proofstep->type = TPTP_PS_STORED_AS_STRING;
  return proofstep;
}
TPTP_PROOFSTEP tptp_GetProofstepByClauseID(TPTPSTATE Tptpstate, unsigned ClauseID)
{
  if (ClauseID < array_GetSize(Tptpstate->clauseIDtoPS)) {
    return (TPTP_PROOFSTEP)array_GetElement(Tptpstate->clauseIDtoPS, ClauseID);
  }
  else
    return NULL;
}
void tptp_SetProofstepByClauseID(TPTPSTATE Tptpstate, unsigned ClauseID, TPTP_PROOFSTEP Proofstep)
{
  tptp_ResizeClauseIDtoPS(Tptpstate, ClauseID);
  array_SetElement(Tptpstate->clauseIDtoPS, ClauseID, (intptr_t)Proofstep);
}
TPTP_PROOFSTEP tptp_CreateProofstepForClause(TPTPSTATE Tptpstate, CLAUSE Clause, const char *ClauseMsg)
{
  TPTP_PROOFSTEP proofstep;
  unsigned clauseID = clause_GetId(Clause);
  proofstep = tptp_GetProofstepByClauseID(Tptpstate, clauseID);
  if (proofstep == NULL) {
    proofstep = tptp_CreateProofstep(Tptpstate);
    proofstep->data = (intptr_t)Clause;
    proofstep->type = TPTP_PS_SPASSCLAUSE;
    tptp_SetProofstepByClauseID(Tptpstate, clauseID, proofstep);
  }
  else {
  }
  return proofstep;
}
void tptp_ProofstepAddParent(MEMORY Mem, TPTP_PROOFSTEP Proofstep, TPTP_PROOFSTEP Parent)
{
  ARRAY arr = (ARRAY)Proofstep->data;
#ifdef SPASS_CHECK
  if (Proofstep->type != TPTP_PS_STORED_AS_STRING || arr == NULL) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: bad proofstep", __func__);
    misc_FinishErrorReport();
  }
#endif
  arr = array_Add(Mem, arr, (intptr_t)Parent);
  Proofstep->data = (intptr_t)arr;
}
void tptp_FreeProofstep(MEMORY Mem, TPTP_PROOFSTEP Proofstep)
{
  ARRAY arr;
  if (Proofstep == NULL) return;
  switch(Proofstep->type) {
  case TPTP_PS_STORED_AS_STRING:
    arr = (ARRAY)Proofstep->data;
    string_StringFree(Mem, (char*)array_GetElement(arr, 0));
    array_Delete(Mem, arr);
    break;
  default:
    break;
  }
  memory_Free(Mem, (POINTER)Proofstep, sizeof(TPTP_PROOFSTEP_NODE));
}
char* tptp_ProofstepGetString(TPTP_PROOFSTEP Proofstep)
{
  ARRAY arr;
  switch(Proofstep->type) {
  case TPTP_PS_STORED_AS_STRING:
    arr = (ARRAY)Proofstep->data;
    return (char*)array_GetElement(arr, 0);
  default:
    break;
  }
#ifdef SPASS_CHECK
  misc_StartErrorReport();
  misc_ErrorReport("\n In %s: String access for non-stored-as-string proofstep!", __func__);
  misc_FinishErrorReport();
#endif
  return NULL;
}
void tptp_ProofstepSetString(TPTP_PROOFSTEP Proofstep, const char* Str)
{
  ARRAY arr;
  switch(Proofstep->type) {
  case TPTP_PS_STORED_AS_STRING:
    arr = (ARRAY)Proofstep->data;
    array_SetElement(arr, 0, (intptr_t)Str);
    return;
  default:
    break;
  }
#ifdef SPASS_CHECK
  misc_StartErrorReport();
  misc_ErrorReport("\n In %s: String access for non-stored-as-string proofstep!", __func__);
  misc_FinishErrorReport();
#endif
  return;
}
TPTPSTATE tptp_Init(MEMORY Mem, FOLSTATE Folstate)
{
  TPTPSTATE tptpstate;
  tptpstate = (TPTPSTATE)memory_Malloc(Mem, sizeof(TPTPSTATE_NODE));
  memset((void*)tptpstate, 0, sizeof(TPTPSTATE_NODE));
  tptpstate->mem = Mem;
  tptpstate->folstate = Folstate;
  tptpstate->proofsteps = array_Create(Mem, 10);
  tptpstate->clauseIDtoPS = array_Create(Mem, 10);
  tptpstate->clauseNames = array_Create(Mem, 10);
  tptp_DetermineGenericClauseNamePrefix(tptpstate);
  tptpstate->strbuf = string_Init(Mem);
  return tptpstate;
}
MEMORY tptp_GetMemory(TPTPSTATE Tptpstate)
{
  return Tptpstate->mem;
}
FOLSTATE tptp_GetFolstate(TPTPSTATE Tptpstate)
{
  return Tptpstate->folstate;
}
TERMSTATE tptp_GetTermstate(TPTPSTATE Tptpstate)
{
  return fol_GetTermstate(tptp_GetFolstate(Tptpstate));
}
SYMBSTATE tptp_GetSymbstate(TPTPSTATE Tptpstate)
{
  return fol_GetSymbstate(tptp_GetFolstate(Tptpstate));
}
const char* tptp_GetProblemName(TPTPSTATE Tptpstate)
{
  return Tptpstate->problemName ? Tptpstate->problemName : "unknown";
}
void tptp_SetProblemName(TPTPSTATE Tptpstate, const char *Path)
{
  MEMORY mem;
  const char *basename;
  const char *dot;
  mem = tptp_GetMemory(Tptpstate);
  if (Tptpstate->problemName != NULL)
    string_StringFree(mem, Tptpstate->problemName);
  basename = Path ? string_GetPostfix(Path, '/') : "unknown";
  dot = strrchr(basename, '.');
  if (dot != NULL && dot > basename)
    Tptpstate->problemName = string_Prefix(mem, basename, dot - basename);
  else
    Tptpstate->problemName = string_StringCopy(mem, basename);
}
char* tptp_AllocateFormulaName(TPTPSTATE Tptpstate, const char *Str)
{
  char *s = NULL;
  if (Str != NULL) {
    s = memory_Malloc(tptp_GetMemory(Tptpstate), sizeof(char)*(strlen(Str)+1));
    strcpy(s, Str);
  }
  return s;
}
void tptp_FreeFormulaName(TPTPSTATE Tptpstate, char *Str)
{
  if (Str != NULL) {
    memory_Free(tptp_GetMemory(Tptpstate), Str, sizeof(char)*(strlen(Str)+1));
  }
}
void tptp_Free(TPTPSTATE Tptpstate)
{
  MEMORY mem = tptp_GetMemory(Tptpstate);
  for (unsigned i=0; i<array_GetSize(Tptpstate->clauseNames); ++i) {
    tptp_FreeFormulaName(Tptpstate, (char*)array_GetElement(Tptpstate->clauseNames, i));
  }
  array_Delete(mem, Tptpstate->clauseNames);
  for (unsigned i=0; i<array_GetSize(Tptpstate->proofsteps); ++i) {
    TPTP_PROOFSTEP proofstep = (TPTP_PROOFSTEP)array_GetElement(Tptpstate->proofsteps, i);
    tptp_FreeProofstep(mem, proofstep);
  }
  array_Delete(mem, Tptpstate->proofsteps);
  array_Delete(mem, Tptpstate->clauseIDtoPS);
  string_Free(Tptpstate->strbuf);
  if (Tptpstate->problemName != NULL)
    string_StringFree(mem, Tptpstate->problemName);
  memory_Free(mem, Tptpstate, sizeof(TPTPSTATE_NODE));
}
void tptp_RegisterClauseName(TPTPSTATE Tptpstate, unsigned ClauseID, char *Name)
{
  Tptpstate->clauseNames = array_Reserve(tptp_GetMemory(Tptpstate),
                                         Tptpstate->clauseNames,
                                         ClauseID+1);
  array_Claim(Tptpstate->clauseNames);
#ifdef SPASS_CHECK
  if (array_GetElement(Tptpstate->clauseNames, ClauseID)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: have already a name for this clause", __func__);
    misc_FinishErrorReport();
  }
#endif
  array_SetElement(Tptpstate->clauseNames, ClauseID, (intptr_t)Name);
}
const char* tptp_GetClauseName(TPTPSTATE Tptpstate, unsigned ClauseID)
{
  if ((ClauseID < array_GetSize(Tptpstate->clauseNames))
      && array_GetElement(Tptpstate->clauseNames, ClauseID)) {
    return (const char*)array_GetElement(Tptpstate->clauseNames, ClauseID);
  }
  sprintf(Tptpstate->clauseStr + Tptpstate->clausePrefixLen, "%u", ClauseID);
  return Tptpstate->clauseStr;
}
void tptp_DetermineGenericClauseNamePrefix(TPTPSTATE Tptpstate)
{
  for (unsigned i=0;; ++i) {
    if (i==0) sprintf(Tptpstate->clauseStr, "c_");
    else sprintf(Tptpstate->clauseStr, "c%u_", i-1);
    Tptpstate->clausePrefixLen = strlen(Tptpstate->clauseStr);
    BOOL good = TRUE;
    for (unsigned j=0; j<array_GetSize(Tptpstate->clauseNames); ++j) {
      const char *name = (const char*)array_GetElement(Tptpstate->clauseNames, j);
      if (name != NULL && string_IsPrefix(Tptpstate->clauseStr, name)) {
        good = FALSE;
        break;
      }
    }
    if (good) return;
  }
}
void tptp_FPrintFormulaContent(FILE *File, FOLSTATE Folstate, TPTP_FORMULA Formula)
{
  if (strcmp(TPTP_LangCNF, tptp_GetLanguage(Formula)) == 0) {
    tptp_FPrintClause(File, Folstate, tptp_GetClause(Formula));
  }
  else if (strcmp(TPTP_LangFOF, tptp_GetLanguage(Formula)) == 0) {
    tptp_FPrintTerm(File, Folstate, tptp_GetTerm(Formula), 4);
  }
}
void tptp_FPrintFormulaAnnotated(FILE *File, FOLSTATE Folstate, TPTP_FORMULA Formula)
{
  if(File) fprintf(File, "%s(%s, %s, ",
                   StrOrNull(tptp_GetLanguage(Formula)),
                   StrOrNull(tptp_GetName(Formula)),
                   StrOrNull(tptp_GetRole(Formula)));
  tptp_FPrintFormulaContent(File, Folstate, Formula);
  if (tptp_GetFilename(Formula)) {
    if(File) fprintf(File, ", '%s'", tptp_GetFilename(Formula));
  }
  if(File) fprintf(File, ")");
}
void tptp_FPrintClauseName(FILE *File, TPTPSTATE Tptpstate, unsigned ClauseID)
{
  if(File) fprintf(File, "%s", tptp_GetClauseName(Tptpstate, ClauseID));
}
void tptp_FPrintSymbol(FILE *File, SYMBSTATE Symbstate, SYMBOL Symbol)
{
  MEMORY memory;
  char *name, *requote;
  unsigned i, requoteLen;
  memory = symbol_GetStateMemory(Symbstate);
  if (symbol_IsVariable(Symbstate, Symbol)) {
#if defined(SPASS_SYMBOL_INDEXVARS)
    if (symbol_IsStandardVariable(Symbstate, Symbol))
      if(File) fprintf(File, "X%lu", (NAT)Symbol);
      else
        if(File) fprintf(File, "I%lu", (NAT)Symbol);
#else
    if(File) fprintf(File, "X%lu", (NAT)Symbol);
#endif
  }
  else {
    name = symbol_GetName(Symbstate, Symbol);
    if (name) {
      requoteLen = strlen(name)*2+4;
      requote = memory_Malloc(memory, requoteLen);
      for (i = 0; *name; ++name) {
        if (*name == '\'' || *name == '\\') {
          requote[i++] = '\\';
        }
        requote[i++] = *name;
      }
      if (requote[i-1] == '\'') {
        requote[i-2] = '\'';
        requote[i-1] = '\0';
        i = 1;
      }
      else {
        requote[i] = '\0';
        i = 0;
      }
      if(File) fprintf(File, "%s", requote+i);
      memory_Free(memory, requote, requoteLen);
    }
    else {
      if(File) fprintf(File, "__SPASS_UNNAMED_0x%"PRIxPTR, Symbol);
    }
  }
}
void tptp_FPrintAtom(FILE *File, FOLSTATE Folstate, TERM Term)
{
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  unsigned i;
  char *symbTPTP;
  termstate = fol_GetTermstate(Folstate);
  symbstate = term_GetSymbstate(termstate);
  symbTPTP = (char *)
    (fol_IsTrue(Folstate, Term) ? "$true" :
     fol_IsFalse(Folstate, Term) ? "$false" :
     NULL);
  if (fol_IsTrue(Folstate, Term)
      || fol_IsFalse(Folstate, Term)) {
    if(File) fputs(symbTPTP, File);
  }
  else if (term_IsVariable(termstate, Term)) {
    tptp_FPrintSymbol(File, symbstate, term_TopSymbol(Term));
  }
  else if (fol_IsEqual(Folstate, Term)) {
    tptp_FPrintAtom(File, Folstate, term_FirstArgument(Term));
    if(File) fputs(" = ", File);
    tptp_FPrintAtom(File, Folstate, term_SecondArgument(Term));
  }
  else if (fol_IsEqualBool(Folstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: no support for fol_EqualBool", __func__);
    misc_FinishErrorReport();
  }
  else {
    if (term_IsValueConstant(termstate, Term)) {
      symbol_GetPrintFunc(symbstate, term_TopSymbol(Term))
        (File, term_GetValue(termstate, Term));
    }
    else {
      tptp_FPrintSymbol(File, symbstate, term_TopSymbol(Term));
      if (term_GetArity(Term) > 0) {
        if(File) fputc('(', File);
        for (i = 0; i < term_GetArity(Term); ++i) {
          tptp_FPrintAtom(File, Folstate, term_GetArgument(Term, i));
          if (i < term_GetArity(Term)-1) {
            if(File) fputs(",", File);
          }
        }
        if(File) fputs(")", File);
      }
    }
  }
}
void tptp_FPrintTerm(FILE *File, FOLSTATE Folstate, TERM Term, unsigned Depth)
{
  unsigned i;
  char *symbTPTP;
  symbTPTP = (char *)
    (fol_IsTrue(Folstate, Term) ? "$true" :
     fol_IsFalse(Folstate, Term) ? "$false" :
     fol_IsForall(Folstate, Term) ? "! " :
     fol_IsAnd(Folstate, Term) ? "& " :
     fol_IsExist(Folstate, Term) ? "? " :
     fol_IsOr(Folstate, Term) ? "| " :
     fol_IsNot(Folstate, Term) ? "~ " :
     fol_IsImplies(Folstate, Term) ? "=> " :
     fol_IsEquiv(Folstate, Term) ? "<=> " :
     fol_IsEqualBool(Folstate, Term) ? NULL :
     fol_IsEqual(Folstate, Term) ? NULL :
     fol_IsXor(Folstate, Term) ? NULL :
     fol_IsIte(Folstate, Term) ? NULL :
     fol_IsQuantVars(Folstate, Term) ? NULL :
     NULL);
  Depth = 0;
  if (fol_IsAtom(Folstate, Term)
      || fol_IsTrue(Folstate, Term)
      || fol_IsFalse(Folstate, Term)) {
    tptp_FPrintAtom(File, Folstate, Term);
  }
  else {
    if (fol_IsNot(Folstate, Term)) {
      if(File) fputs(symbTPTP, File);
      tptp_FPrintTerm(File, Folstate, term_FirstArgument(Term), Depth);
    }
    else if (fol_IsQuantifier(Folstate, Term)) {
      if(File) fputs(symbTPTP, File);
      if(File) fputs("[", File);
      tptp_FPrintAtom(File, Folstate, term_FirstArgument(Term));
      if(File) fputs("] :\n", File);
      tptp_FPrintTerm(File, Folstate, term_SecondArgument(Term), Depth);
    }
    else {
      for (i = 0; i < term_GetArity(Term); ++i) {
        if (i == 0) {
          if(File) fputs("(", File);
        }
        else {
          if(File) fputs(symbTPTP, File);
        }
        tptp_FPrintTerm(File, Folstate, term_GetArgument(Term, i), Depth);
        if (i < term_GetArity(Term)-1) {
          if(File) fputs("\n", File);
        }
      }
      if(File) fputs(") ", File);
    }
  }
}
void tptp_FPrintLiteralArray(FILE *File, FOLSTATE Folstate, ARRAY LitArr)
{
  TERM literal;
  unsigned i;
  for (i=0; i<array_GetSize(LitArr); ++i) {
    literal = (TERM)array_GetElement(LitArr, i);
#ifdef SPASS_CHECK
    if (!fol_IsLiteral(Folstate, literal) &&
        !fol_IsTrue(Folstate, literal) &&
        !fol_IsFalse(Folstate, literal)) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: not a literal", __func__);
      term_PrettyPrint(fol_GetTermstate(Folstate), literal);
      misc_FinishErrorReport();
    }
#endif
    tptp_FPrintTerm(File, Folstate, literal, 0);
    if (i<array_GetSize(LitArr)-1) if(File) fprintf(File, " | ");
  }
}
void tptp_FPrintClause(FILE *File, FOLSTATE Folstate, CLAUSE Clause)
{
  TERM atom;
  unsigned i;
  if (clause_IsEmpty(Clause)) {
    if(File) fprintf(File, "%s", "$false");
  }
  for (i=0; i<clause_GetFolLiterals(Clause); ++i) {
    atom = clause_GetAtom(Clause, i);
#ifdef SPASS_CHECK
    if (!fol_IsLiteral(Folstate, atom) &&
        !fol_IsTrue(Folstate, atom) &&
        !fol_IsFalse(Folstate, atom)) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: not an atom", __func__);
      term_PrettyPrint(fol_GetTermstate(Folstate), atom);
      misc_FinishErrorReport();
    }
#endif
    if (i<clause_GetPremiseLiterals(Clause))
      if(File) fprintf(File, "~");
    tptp_FPrintAtom(File, Folstate, atom);
    if (i<clause_GetFolLiterals(Clause)-1)
      if(File) fprintf(File, " | ");
  }
}
void tptp_FPrintFOF(FILE *File, FOLSTATE Folstate, TERM Term,
                    const char *Name, const char *Role)
{
  if(File) fprintf(File, "%s(%s,%s,\n", TPTP_LangFOF, Name, Role);
  tptp_FPrintTerm(File, Folstate, Term, 3);
  if(File) fprintf(File, ").\n\n");
}
void tptp_FPrintCNF(FILE *File, FOLSTATE Folstate, CLAUSE Clause,
                    const char *Name, const char *Role)
{
  if(File) fprintf(File, "%s(%s,%s,\n   ", TPTP_LangCNF, Name, Role);
  tptp_FPrintClause(File, Folstate, Clause);
  if(File) fprintf(File, ").\n\n");
}
void tptp_FPrintCNFArrArrLit(FILE *File, FOLSTATE Folstate, ARRAY Cnf)
{
  MEMORY memory;
  ARRAY clause;
  char *name;
  unsigned i;
  memory = fol_GetStateMemory(Folstate);
  for (i=0; i<array_GetSize(Cnf); ++i) {
    clause = (ARRAY)array_GetElement(Cnf, i);
    name = string_Nconc(memory,
                          string_StringCopy(memory, "clause"),
                          string_IntToString(memory, i+1));
    if(File) fprintf(File, "cnf(%s,%s,\n", name, "plain");
    string_StringFree(memory, name);
    tptp_FPrintLiteralArray(File, Folstate, clause);
    if(File) fprintf(File, " ).\n\n");
  }
}
void tptp_FPrintFileRecord(FILE *File, TPTPSTATE Tptpstate, FOLSTATE Folstate, TPTP_FORMULA Formula)
{
  if(File) fprintf(File, "\n%% FILE RECORD\n");
  if(File) fprintf(File, "%s(%s,%s,\n    ",
                   tptp_GetLanguage(Formula),
                   tptp_GetName(Formula),
                   tptp_GetRole(Formula));
  tptp_FPrintFormulaContent(File, Folstate, Formula);
  if(File) fprintf(File, ",\n    file('%s',%s) ).\n\n",
                   tptp_GetFilename(Formula),
                   tptp_GetName(Formula));
}
void tptp_FNegateConjectureIfNecessary(FILE *File, TPTPSTATE Tptpstate,
                                       FOLSTATE Folstate, TPTP_FORMULA Formula)
{
  MEMORY mem;
  char *oldName, *newName;
  mem = tptp_GetMemory(Tptpstate);
  if (strcmp(tptp_GetRole(Formula), TPTP_RoleConjecture) == 0) {
#ifdef SPASS_CHECK
    if (strcmp(tptp_GetLanguage(Formula), TPTP_LangFOF)) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: Semantic of role conjecture only implemented for FOF!", __func__);
      misc_FinishErrorReport();
    }
#endif
    tptp_SetTerm(Formula, fol_NegateToggle(Folstate, tptp_GetTerm(Formula)));
    tptp_SetRole(Formula, TPTP_RoleNegatedConjecture);
    oldName = tptp_GetName(Formula);
    newName = string_Conc(mem, oldName, "_nc");
    if(File) fprintf(File, "\n%% NEGATING CONJECTURE\n");
    if(File) fprintf(File, "%s(%s,%s,\n    ",
                     tptp_GetLanguage(Formula),
                     newName,
                     tptp_GetRole(Formula));
    tptp_FPrintFormulaContent(File, Folstate, Formula);
    if(File) fprintf(File, ",\n    inference(%s,[status(cth)],[%s]) ).\n\n",
                     "negating_conjecture",
                     oldName);
    string_StringFree(mem, oldName);
    tptp_SetName(Formula, newName);
  }
}
void tptp_FPrintFofSimpleInference(FILE *File, FOLSTATE Folstate, TPTP_FORMULA Formula, TERM NewTerm,
                                   const char *Rule, BOOL RenamedVariables)
{
  MEMORY mem;
  char *oldName, *newName;
  mem = fol_GetMemory(Folstate);
  oldName = tptp_GetName(Formula);
  newName = string_Conc(mem, tptp_GetBasename(Formula), Rule);
  tptp_SetLanguage(Formula, TPTP_LangFOF);
  tptp_SetTerm(Formula, NewTerm);
  if(File) fprintf(File, "\n%% FOF SIMPLE INFERENCE\n");
  if(File) fprintf(File, "%s(%s,%s,\n    ",
                   tptp_GetLanguage(Formula),
                   newName,
                   tptp_GetRole(Formula));
  tptp_FPrintFormulaContent(File, Folstate, Formula);
  if(File) fprintf(File, ",\n    inference(%s,[status(thm)],", Rule);
  if (RenamedVariables) {
    if(File) fprintf(File, "[inference(variable_rename,[status(thm)],[%s])]", oldName);
  }
  else {
    if(File) fprintf(File, "[%s]", oldName);
  }
  if(File) fprintf(File, ") ).\n\n");
  string_StringFree(mem, oldName);
  tptp_SetName(Formula, newName);
}
TPTP_FORMULA tptp_FPrintIntroduceRenaming(FILE *File, FOLSTATE Folstate, char *Name,
                                          TERM Term, TPTP_FORMULA Parent)
{
  misc_StartErrorReport();
  misc_ErrorReport("\n In %s: Deprecated version. If needed adapt to use tptp_BPrint...", __func__);
  misc_FinishErrorReport();
  MEMORY mem;
  TPTP_FORMULA formula;
  mem = fol_GetMemory(Folstate);
  formula = tptp_AllocateFormula(mem);
  tptp_SetLanguage(formula, TPTP_LangFOF);
  tptp_SetTerm(formula, Term);
  tptp_SetName(formula, string_Conc(mem, Name, "_defn"));
  tptp_SetBasename(formula, string_Conc(mem, Name, "_"));
  tptp_SetRole(formula, TPTP_RoleDefinition);
  if(File) fprintf(File, "\n%% FOF INTRODUCE RENAMING\n");
  if(File) fprintf(File, "%s(%s,%s,\n    ",
                   tptp_GetLanguage(formula),
                   tptp_GetName(formula),
                   tptp_GetRole(formula));
  tptp_FPrintFormulaContent(File, Folstate, formula);
  if(File) fprintf(File, ",\n    introduced(%s,[new_symbols(definition,[%s])],", TPTP_RoleDefinition, Name);
  if(File) fprintf(File, "[%s]", tptp_GetName(Parent));
  if(File) fprintf(File, ") ).\n\n");
  string_StringFree(mem, Name);
  return formula;
}
void tptp_FPrintRenamingInference(FILE *File, FOLSTATE Folstate, TPTP_FORMULA Formula, ARRAY Renamings)
{
  misc_StartErrorReport();
  misc_ErrorReport("\n In %s: Deprecated version. If needed adapt to use tptp_BPrint...", __func__);
  misc_FinishErrorReport();
  MEMORY mem;
  char *oldName, *newName;
  unsigned i;
  const char *rule = "renObv";
  mem = fol_GetMemory(Folstate);
  oldName = tptp_GetName(Formula);
  newName = string_Conc(mem, tptp_GetBasename(Formula), rule);
  tptp_SetLanguage(Formula, TPTP_LangFOF);
  if(File) fprintf(File, "\n%% FOF RENAMING INFERENCE\n");
  if(File) fprintf(File, "%s(%s,%s,\n    ",
                   tptp_GetLanguage(Formula),
                   newName,
                   tptp_GetRole(Formula));
  tptp_FPrintFormulaContent(File, Folstate, Formula);
  if(File) fprintf(File, ",\n    inference(renaming,[status(esa)],");
  if(File) fprintf(File, "[%s", oldName);
  for (i=0; i<array_GetSize(Renamings); ++i) {
    if(File) fprintf(File, ",%s", tptp_GetName((TPTP_FORMULA)array_GetElement(Renamings, i)));
  }
  if(File) fprintf(File, "]) ).\n\n");
  string_StringFree(mem, oldName);
  tptp_SetName(Formula, newName);
}
void tptp_FPrintSkolemInference(FILE *File, FOLSTATE Folstate, TPTP_FORMULA Formula, TERM NewTerm)
{
  misc_StartErrorReport();
  misc_ErrorReport("\n In %s: Deprecated version. If needed adapt to use tptp_BPrint...", __func__);
  misc_FinishErrorReport();
  MEMORY mem;
  char *oldName, *newName;
  const char *rule = "skol";
  mem = fol_GetMemory(Folstate);
  oldName = tptp_GetName(Formula);
  newName = string_Conc(mem, tptp_GetBasename(Formula), rule);
  tptp_SetLanguage(Formula, TPTP_LangFOF);
  tptp_SetTerm(Formula, NewTerm);
  if(File) fprintf(File, "\n%% FOF SKOLEM INFERENCE. WIP!!\n");
  if(File) fprintf(File, "%s(%s,%s,\n    ",
                   tptp_GetLanguage(Formula),
                   newName,
                   tptp_GetRole(Formula));
  tptp_FPrintFormulaContent(File, Folstate, Formula);
  if(File) fprintf(File, ",\n    inference(%s,[status(esa)],", rule);
  if(File) fprintf(File, "[%s]", oldName);
  if(File) fprintf(File, ") ).\n\n");
  string_StringFree(mem, oldName);
  tptp_SetName(Formula, newName);
}
void tptp_FPrintPushDisjInference(FILE *File, TPTPSTATE Tptpstate, FOLSTATE Folstate,
                                  TPTP_FORMULA Formula, CLAUSE Clause)
{
  misc_StartErrorReport();
  misc_ErrorReport("\n In %s: Deprecated version. If needed adapt to use tptp_BPrint...", __func__);
  misc_FinishErrorReport();
  if(File) fprintf(File, "\n%% FOF PUSH DISJ SPLITTING.\n");
  if(File) fprintf(File, "%s(%s,%s,\n    ",
                   TPTP_LangCNF,
                   tptp_GetClauseName(Tptpstate, clause_GetId(Clause)),
                   TPTP_RolePlain);
  tptp_FPrintClause(File, Folstate, Clause);
  if(File) fprintf(File, ",\n    inference(split_conjunct,[status(thm)],");
  if(File) fprintf(File, "[inference(push_disj,[status(thm)],[%s])]", tptp_GetName(Formula));
  if(File) fprintf(File, ") ).\n\n");
}
void tptp_BPrintFormulaContent(STRBUF Buf, FOLSTATE Folstate, TPTP_FORMULA Formula)
{
  if (strcmp(TPTP_LangCNF, tptp_GetLanguage(Formula)) == 0) {
    tptp_BPrintClause(Buf, Folstate, tptp_GetClause(Formula));
  }
  else if (strcmp(TPTP_LangFOF, tptp_GetLanguage(Formula)) == 0) {
    tptp_BPrintTerm(Buf, Folstate, tptp_GetTerm(Formula), 4);
  }
}
void tptp_BPrintFormulaAnnotated(STRBUF Buf, FOLSTATE Folstate, TPTP_FORMULA Formula)
{
  string_Printf(Buf, "%s(%s, %s, ",
                StrOrNull(tptp_GetLanguage(Formula)),
                StrOrNull(tptp_GetName(Formula)),
                StrOrNull(tptp_GetRole(Formula)));
  tptp_BPrintFormulaContent(Buf, Folstate, Formula);
  if (tptp_GetFilename(Formula)) {
    string_Printf(Buf, ", '%s'", tptp_GetFilename(Formula));
  }
  string_Printf(Buf, ")");
}
void tptp_BPrintClauseName(STRBUF Buf, TPTPSTATE Tptpstate, unsigned ClauseID)
{
  string_Printf(Buf, "%s", tptp_GetClauseName(Tptpstate, ClauseID));
}
void tptp_BPrintSymbol(STRBUF Buf, SYMBSTATE Symbstate, SYMBOL Symbol)
{
  MEMORY memory;
  char *name, *requote;
  unsigned i, requoteLen;
  memory = symbol_GetStateMemory(Symbstate);
  if (symbol_IsVariable(Symbstate, Symbol)) {
#if defined(SPASS_SYMBOL_INDEXVARS)
    if (symbol_IsStandardVariable(Symbstate, Symbol))
      string_Printf(Buf, "X%lu", (NAT)Symbol);
    else
      string_Printf(Buf, "I%lu", (NAT)Symbol);
#else
    string_Printf(Buf, "X%lu", (NAT)Symbol);
#endif
  }
  else {
    name = symbol_GetName(Symbstate, Symbol);
    if (name) {
      requoteLen = strlen(name)*2+4;
      requote = memory_Malloc(memory, requoteLen);
      for (i = 0; *name; ++name) {
        if (*name == '\'' || *name == '\\') {
          requote[i++] = '\\';
        }
        requote[i++] = *name;
      }
      if (requote[i-1] == '\'') {
        requote[i-2] = '\'';
        requote[i-1] = '\0';
        i = 1;
      }
      else {
        requote[i] = '\0';
        i = 0;
      }
      string_Printf(Buf, "%s", requote+i);
      memory_Free(memory, requote, requoteLen);
    }
    else {
      string_Printf(Buf, "__SPASS_UNNAMED_0x%"PRIxPTR, Symbol);
    }
  }
}
void tptp_BPrintAtom(STRBUF Buf, FOLSTATE Folstate, TERM Term)
{
  TERMSTATE termstate;
  SYMBSTATE symbstate;
  unsigned i;
  char *symbTPTP;
  termstate = fol_GetTermstate(Folstate);
  symbstate = term_GetSymbstate(termstate);
  symbTPTP = (char *)
    (fol_IsTrue(Folstate, Term) ? "$true" :
     fol_IsFalse(Folstate, Term) ? "$false" :
     NULL);
  if (fol_IsTrue(Folstate, Term)
      || fol_IsFalse(Folstate, Term)) {
    string_AddStr(Buf, symbTPTP);
  }
  else if (term_IsVariable(termstate, Term)) {
    tptp_BPrintSymbol(Buf, symbstate, term_TopSymbol(Term));
  }
  else if (fol_IsEqual(Folstate, Term)) {
    tptp_BPrintAtom(Buf, Folstate, term_FirstArgument(Term));
    string_AddStr(Buf, " = ");
    tptp_BPrintAtom(Buf, Folstate, term_SecondArgument(Term));
  }
  else if (fol_IsEqualBool(Folstate, Term)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: no support for fol_EqualBool", __func__);
    misc_FinishErrorReport();
  }
  else {
    if (term_IsValueConstant(termstate, Term)) {
      string_AddStr(Buf, "valueconstant");
    }
    else {
      tptp_BPrintSymbol(Buf, symbstate, term_TopSymbol(Term));
      if (term_GetArity(Term) > 0) {
        string_AddChar(Buf, '(');
        for (i = 0; i < term_GetArity(Term); ++i) {
          tptp_BPrintAtom(Buf, Folstate, term_GetArgument(Term, i));
          if (i < term_GetArity(Term)-1) {
            string_AddStr(Buf, ",");
          }
        }
        string_AddStr(Buf, ")");
      }
    }
  }
}
void tptp_BPrintTerm(STRBUF Buf, FOLSTATE Folstate, TERM Term, unsigned Depth)
{
  unsigned i;
  char *symbTPTP;
  symbTPTP = (char *)
    (fol_IsTrue(Folstate, Term) ? "$true" :
     fol_IsFalse(Folstate, Term) ? "$false" :
     fol_IsForall(Folstate, Term) ? "! " :
     fol_IsAnd(Folstate, Term) ? "& " :
     fol_IsExist(Folstate, Term) ? "? " :
     fol_IsOr(Folstate, Term) ? "| " :
     fol_IsNot(Folstate, Term) ? "~ " :
     fol_IsImplies(Folstate, Term) ? "=> " :
     fol_IsEquiv(Folstate, Term) ? "<=> " :
     fol_IsEqualBool(Folstate, Term) ? NULL :
     fol_IsEqual(Folstate, Term) ? NULL :
     fol_IsXor(Folstate, Term) ? NULL :
     fol_IsIte(Folstate, Term) ? NULL :
     fol_IsQuantVars(Folstate, Term) ? NULL :
     NULL);
  Depth = 0;
  if (symbol_IsConstant(term_TopSymbol(Term)) ||
      symbol_IsFunction(term_TopSymbol(Term)) ||
      symbol_IsVariable(fol_GetSymbstate(Folstate), term_TopSymbol(Term))) {
    tptp_BPrintAtom(Buf, Folstate, Term);
  }
  if (fol_IsAtom(Folstate, Term) ||
      fol_IsTrue(Folstate, Term) ||
      fol_IsFalse(Folstate, Term)) {
    tptp_BPrintAtom(Buf, Folstate, Term);
  }
  else {
    if (fol_IsNot(Folstate, Term)) {
      string_AddStr(Buf, symbTPTP);
      tptp_BPrintTerm(Buf, Folstate, term_FirstArgument(Term), Depth);
    }
    else if (fol_IsQuantifier(Folstate, Term)) {
      string_AddStr(Buf, symbTPTP);
      string_AddStr(Buf, "[");
      tptp_BPrintAtom(Buf, Folstate, term_FirstArgument(Term));
      string_AddStr(Buf, "] :\n");
      tptp_BPrintTerm(Buf, Folstate, term_SecondArgument(Term), Depth);
    }
    else {
      for (i = 0; i < term_GetArity(Term); ++i) {
        if (i == 0) {
          string_AddStr(Buf, "(");
        }
        else {
          string_AddStr(Buf, symbTPTP);
        }
        tptp_BPrintTerm(Buf, Folstate, term_GetArgument(Term, i), Depth);
        if (i < term_GetArity(Term)-1) {
          string_AddStr(Buf, "\n");
        }
      }
      string_AddStr(Buf, ") ");
    }
  }
}
void tptp_BPrintTermFlipFirstImplication(STRBUF Buf, FOLSTATE Folstate, TERM Term,
                                         unsigned Depth, BOOL FlipFirstImplication)
{
  unsigned i;
  char *symbTPTP;
  symbTPTP = (char *)
    (fol_IsTrue(Folstate, Term) ? "$true" :
     fol_IsFalse(Folstate, Term) ? "$false" :
     fol_IsForall(Folstate, Term) ? "! " :
     fol_IsAnd(Folstate, Term) ? "& " :
     fol_IsExist(Folstate, Term) ? "? " :
     fol_IsOr(Folstate, Term) ? "| " :
     fol_IsNot(Folstate, Term) ? "~ " :
     fol_IsImplies(Folstate, Term) ? "=> " :
     fol_IsEquiv(Folstate, Term) ? "<=> " :
     fol_IsEqualBool(Folstate, Term) ? NULL :
     fol_IsEqual(Folstate, Term) ? NULL :
     fol_IsXor(Folstate, Term) ? NULL :
     fol_IsIte(Folstate, Term) ? NULL :
     fol_IsQuantVars(Folstate, Term) ? NULL :
     NULL);
  Depth = 0;
  if (symbol_IsConstant(term_TopSymbol(Term)) ||
      symbol_IsFunction(term_TopSymbol(Term)) ||
      symbol_IsVariable(fol_GetSymbstate(Folstate), term_TopSymbol(Term))) {
    tptp_BPrintAtom(Buf, Folstate, Term);
  }
  if (fol_IsAtom(Folstate, Term) ||
      fol_IsTrue(Folstate, Term) ||
      fol_IsFalse(Folstate, Term)) {
    tptp_BPrintAtom(Buf, Folstate, Term);
  }
  else {
    if (fol_IsNot(Folstate, Term)) {
      string_AddStr(Buf, symbTPTP);
      tptp_BPrintTermFlipFirstImplication(Buf, Folstate, term_FirstArgument(Term),
                                          Depth, FlipFirstImplication);
    }
    else if (fol_IsQuantifier(Folstate, Term)) {
      string_AddStr(Buf, symbTPTP);
      string_AddStr(Buf, "[");
      tptp_BPrintAtom(Buf, Folstate, term_FirstArgument(Term));
      string_AddStr(Buf, "] :\n");
      tptp_BPrintTermFlipFirstImplication(Buf, Folstate, term_SecondArgument(Term),
                                          Depth, FlipFirstImplication);
    }
    else {
      BOOL nextFlip = FlipFirstImplication;
      int iOffset = 0;
      int iFactor = 1;
      if (fol_IsImplies(Folstate, Term) && FlipFirstImplication) {
        nextFlip = FALSE;
        iFactor = -1;
        iOffset = 1;
        symbTPTP = (char*)"<= ";
      }
      for (i = 0; i < term_GetArity(Term); ++i) {
        if (i == 0) {
          string_AddStr(Buf, "(");
        }
        else {
          string_AddStr(Buf, symbTPTP);
        }
        tptp_BPrintTermFlipFirstImplication(Buf, Folstate,
                                            term_GetArgument(Term, iOffset+iFactor*i),
                                            Depth, nextFlip);
        if (i < term_GetArity(Term)-1) {
          string_AddStr(Buf, "\n");
        }
      }
      string_AddStr(Buf, ") ");
    }
  }
}
void tptp_BPrintLiteralArray(STRBUF Buf, FOLSTATE Folstate, ARRAY LitArr)
{
  TERM literal;
  unsigned i;
  for (i=0; i<array_GetSize(LitArr); ++i) {
    literal = (TERM)array_GetElement(LitArr, i);
#ifdef SPASS_CHECK
    if (!fol_IsLiteral(Folstate, literal) &&
        !fol_IsTrue(Folstate, literal) &&
        !fol_IsFalse(Folstate, literal)) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: not a literal", __func__);
      term_PrettyPrint(fol_GetTermstate(Folstate), literal);
      misc_FinishErrorReport();
    }
#endif
    tptp_BPrintTerm(Buf, Folstate, literal, 0);
    if (i<array_GetSize(LitArr)-1) string_Printf(Buf, " | ");
  }
}
void tptp_BPrintClause(STRBUF Buf, FOLSTATE Folstate, CLAUSE Clause)
{
  TERM atom;
  unsigned i;
  if (clause_IsEmpty(Clause)) {
    string_AddStr(Buf, "$false");
  }
  for (i=0; i<clause_GetFolLiterals(Clause); ++i) {
    atom = clause_GetAtom(Clause, i);
#ifdef SPASS_CHECK
    if (atom == NULL) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: atom %i of clause %i (at %x) is NULL!", __func__,
                       i, clause_GetId(Clause), Clause);
      misc_FinishErrorReport();
    }
    else if (!fol_IsLiteral(Folstate, atom) &&
             !fol_IsTrue(Folstate, atom) &&
             !fol_IsFalse(Folstate, atom)) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: not an atom", __func__);
      term_PrettyPrint(fol_GetTermstate(Folstate), atom);
      misc_FinishErrorReport();
    }
#endif
    if (i<clause_GetPremiseLiterals(Clause))
      string_Printf(Buf, "~");
    tptp_BPrintAtom(Buf, Folstate, atom);
    if (i<clause_GetFolLiterals(Clause)-1)
      string_Printf(Buf, " | ");
  }
}
void tptp_BPrintFOF(STRBUF Buf, FOLSTATE Folstate, TERM Term,
                    const char *Name, const char *Role)
{
  string_Printf(Buf, "%s(%s,%s,\n", TPTP_LangFOF, Name, Role);
  tptp_BPrintTerm(Buf, Folstate, Term, 3);
  string_Printf(Buf, ").\n\n");
}
void tptp_BPrintCNF(STRBUF Buf, FOLSTATE Folstate, CLAUSE Clause,
                    const char *Name, const char *Role)
{
  string_Printf(Buf, "%s(%s,%s,\n   ", TPTP_LangCNF, Name, Role);
  tptp_BPrintClause(Buf, Folstate, Clause);
  string_Printf(Buf, ").\n\n");
}
void tptp_BPrintCNFArrArrLit(STRBUF Buf, FOLSTATE Folstate, ARRAY Cnf)
{
  MEMORY memory;
  ARRAY clause;
  char *name;
  unsigned i;
  memory = fol_GetStateMemory(Folstate);
  for (i=0; i<array_GetSize(Cnf); ++i) {
    clause = (ARRAY)array_GetElement(Cnf, i);
    name = string_Nconc(memory,
                          string_StringCopy(memory, "clause"),
                          string_IntToString(memory, i+1));
    string_Printf(Buf, "cnf(%s,%s,\n", name, "plain");
    string_StringFree(memory, name);
    tptp_BPrintLiteralArray(Buf, Folstate, clause);
    string_Printf(Buf, " ).\n\n");
  }
}
void tptp_StoreFileRecord(TPTPSTATE Tptpstate, TPTP_FORMULA Formula)
{
  TPTP_PROOFSTEP newPS;
  FOLSTATE folstate = tptp_GetFolstate(Tptpstate);
  STRBUF buf = Tptpstate->strbuf;
  string_Clear(buf);
  string_Printf(buf, "%% FILE RECORD\n");
  string_Printf(buf, "%s(%s,%s,\n    ",
                tptp_GetLanguage(Formula),
                tptp_GetName(Formula),
                tptp_GetRole(Formula));
  tptp_BPrintFormulaContent(buf, folstate, Formula);
  string_Printf(buf, ",\n    file('%s',%s) ).",
                tptp_GetFilename(Formula),
                tptp_GetName(Formula));
  newPS = tptp_CreateProofstepStoreString(Tptpstate, string_CopyStr(buf));
  tptp_SetProofstep(Formula, newPS);
}
void tptp_NegateConjectureIfNecessary(TPTPSTATE Tptpstate, TPTP_FORMULA Formula)
{
  char *oldName, *newName;
  TPTP_PROOFSTEP newPS;
  MEMORY mem = tptp_GetMemory(Tptpstate);
  FOLSTATE folstate = tptp_GetFolstate(Tptpstate);
  STRBUF buf = Tptpstate->strbuf;
  string_Clear(buf);
  if (strcmp(tptp_GetRole(Formula), TPTP_RoleConjecture) == 0) {
#ifdef SPASS_CHECK
    if (strcmp(tptp_GetLanguage(Formula), TPTP_LangFOF)) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: Semantic of role conjecture only implemented for FOF!", __func__);
      misc_FinishErrorReport();
    }
#endif
    tptp_SetTerm(Formula, fol_NegateToggle(folstate, tptp_GetTerm(Formula)));
    tptp_SetRole(Formula, TPTP_RoleNegatedConjecture);
    oldName = tptp_GetName(Formula);
    newName = string_Conc(mem, oldName, "_nc");
    string_Printf(buf, "%% NEGATING CONJECTURE\n");
    string_Printf(buf, "%s(%s,%s,\n    ",
                  tptp_GetLanguage(Formula),
                  newName,
                  tptp_GetRole(Formula));
    tptp_BPrintFormulaContent(buf, folstate, Formula);
    string_Printf(buf, ",\n    inference(%s,[status(cth)],[%s]) ).",
                  "negating_conjecture",
                  oldName);
    newPS = tptp_CreateProofstepStoreString(Tptpstate, string_CopyStr(buf));
    tptp_ProofstepAddParent(mem, newPS, tptp_GetProofstep(Formula));
    tptp_SetProofstep(Formula, newPS);
    string_StringFree(mem, oldName);
    tptp_SetName(Formula, newName);
  }
}
void tptp_FofSimpleInference(TPTPSTATE Tptpstate, TPTP_FORMULA Formula, TERM NewTerm,
                             const char *Rule, BOOL RenamedVariables)
{
  char *oldName, *newName;
  TPTP_PROOFSTEP newPS;
  MEMORY mem = tptp_GetMemory(Tptpstate);
  FOLSTATE folstate = tptp_GetFolstate(Tptpstate);
  STRBUF buf = Tptpstate->strbuf;
  string_Clear(buf);
  oldName = tptp_GetName(Formula);
  newName = string_Conc(mem, tptp_GetBasename(Formula), Rule);
  tptp_SetLanguage(Formula, TPTP_LangFOF);
  tptp_SetTerm(Formula, NewTerm);
  string_Clear(buf);
  string_Printf(buf, "%% FOF SIMPLE INFERENCE\n");
  string_Printf(buf, "%s(%s,%s,\n    ",
                tptp_GetLanguage(Formula),
                newName,
                tptp_GetRole(Formula));
  tptp_BPrintFormulaContent(buf, folstate, Formula);
  string_Printf(buf, ",\n    inference(%s,[status(thm)],", Rule);
  if (RenamedVariables) {
    string_Printf(buf, "[inference(variable_rename,[status(thm)],[%s])]", oldName);
  }
  else {
    string_Printf(buf, "[%s]", oldName);
  }
  string_Printf(buf, ") ).");
  newPS = tptp_CreateProofstepStoreString(Tptpstate, string_CopyStr(buf));
  tptp_ProofstepAddParent(mem, newPS, tptp_GetProofstep(Formula));
  tptp_SetProofstep(Formula, newPS);
  string_StringFree(mem, oldName);
  tptp_SetName(Formula, newName);
}
TPTP_FORMULA tptp_IntroduceRenaming(TPTPSTATE Tptpstate, char *Name,
                                    TERM Term, TPTP_FORMULA Parent)
{
  TPTP_PROOFSTEP newPS;
  TPTP_FORMULA formula;
  MEMORY mem = tptp_GetMemory(Tptpstate);
  FOLSTATE folstate = tptp_GetFolstate(Tptpstate);
  STRBUF buf = Tptpstate->strbuf;
  string_Clear(buf);
  formula = tptp_AllocateFormula(mem);
  tptp_SetLanguage(formula, TPTP_LangFOF);
  tptp_SetTerm(formula, Term);
  tptp_SetName(formula, string_Conc(mem, Name, "_defn"));
  tptp_SetBasename(formula, string_Conc(mem, Name, "_"));
  tptp_SetRole(formula, TPTP_RoleDefinition);
  string_Printf(buf, "%% FOF INTRODUCE RENAMING\n");
  string_Printf(buf, "%s(%s,%s,\n    ",
                tptp_GetLanguage(formula),
                tptp_GetName(formula),
                tptp_GetRole(formula));
  if ("CHECK FOR PRINTING BACKWARDS IMPLICATIONS....") {
    TERM t = Term;
    while (fol_IsForall(folstate, t)) {
      t = term_GetArgument(t, 1);
    }
    SYMBOL symbR = term_TopSymbol(term_GetArgument(t, 1));
    if (fol_IsImplies(folstate, t)
        && !symbol_IsVariable(tptp_GetSymbstate(Tptpstate), symbR)
        && 0 == strcmp(symbol_GetName(tptp_GetSymbstate(Tptpstate), symbR), Name)) {
      tptp_BPrintTermFlipFirstImplication(buf, folstate, Term, 4, TRUE);
    }
    else {
      tptp_BPrintFormulaContent(buf, folstate, formula);
    }
  }
  else {
    tptp_BPrintFormulaContent(buf, folstate, formula);
  }
  string_Printf(buf, ",\n    introduced(%s,[new_symbols(definition,[%s])],", TPTP_RoleDefinition, Name);
  string_Printf(buf, "[%s]", tptp_GetName(Parent));
  string_Printf(buf, ") ).");
  newPS = tptp_CreateProofstepStoreString(Tptpstate, string_CopyStr(buf));
  tptp_ProofstepAddParent(mem, newPS, tptp_GetProofstep(Parent));
  tptp_SetProofstep(formula, newPS);
  tptp_SetRole(formula, TPTP_RolePlain);
  string_StringFree(mem, Name);
  return formula;
}
void tptp_RenamingInference(TPTPSTATE Tptpstate, TPTP_FORMULA Formula, ARRAY Renamings)
{
  const char *rule = "renObv";
  char *oldName, *newName;
  TPTP_PROOFSTEP newPS;
  MEMORY mem = tptp_GetMemory(Tptpstate);
  FOLSTATE folstate = tptp_GetFolstate(Tptpstate);
  STRBUF buf = Tptpstate->strbuf;
  string_Clear(buf);
  oldName = tptp_GetName(Formula);
  newName = string_Conc(mem, tptp_GetBasename(Formula), rule);
  newPS = tptp_CreateProofstepStoreString(Tptpstate, (char*)"RENAMING PLACEHOLDER STRING");
  tptp_SetLanguage(Formula, TPTP_LangFOF);
  string_Printf(buf, "%% FOF RENAMING INFERENCE\n");
  string_Printf(buf, "%s(%s,%s,\n    ",
                tptp_GetLanguage(Formula),
                newName,
                tptp_GetRole(Formula));
  tptp_BPrintFormulaContent(buf, folstate, Formula);
  string_Printf(buf, ",\n    inference(renaming,[status(esa)],");
  string_Printf(buf, "[%s", oldName);
  for (unsigned i=0; i<array_GetSize(Renamings); ++i) {
    TPTP_FORMULA parent = (TPTP_FORMULA)array_GetElement(Renamings, i);
    string_Printf(buf, ",%s", tptp_GetName(parent));
    tptp_ProofstepAddParent(mem, newPS, tptp_GetProofstep(parent));
  }
  string_Printf(buf, "]) ).");
  tptp_ProofstepSetString(newPS, string_CopyStr(buf));
  tptp_SetProofstep(Formula, newPS);
  string_StringFree(mem, oldName);
  tptp_SetName(Formula, newName);
}
void tptp_SkolemInferenceOLD(TPTPSTATE Tptpstate, TPTP_FORMULA Formula, TERM NewTerm)
{
  char *oldName, *newName;
  TPTP_PROOFSTEP newPS;
  MEMORY mem = tptp_GetMemory(Tptpstate);
  FOLSTATE folstate = tptp_GetFolstate(Tptpstate);
  STRBUF buf = Tptpstate->strbuf;
  string_Clear(buf);
  oldName = tptp_GetName(Formula);
  newName = string_Conc(mem, tptp_GetBasename(Formula), "skol");
  tptp_SetLanguage(Formula, TPTP_LangFOF);
  tptp_SetTerm(Formula, NewTerm);
  string_Printf(buf, "%% FOF SKOLEM INFERENCE. WIP!!\n");
  string_Printf(buf, "%s(%s,%s,\n    ",
                tptp_GetLanguage(Formula),
                newName,
                tptp_GetRole(Formula));
  tptp_BPrintFormulaContent(buf, folstate, Formula);
  string_Printf(buf, ",\n    inference(skolemize, [status(esa)],");
  string_Printf(buf, "[%s]", oldName);
  string_Printf(buf, ") ).");
  newPS = tptp_CreateProofstepStoreString(Tptpstate, string_CopyStr(buf));
  tptp_ProofstepAddParent(mem, newPS, tptp_GetProofstep(Formula));
  tptp_SetProofstep(Formula, newPS);
  string_StringFree(mem, oldName);
  tptp_SetName(Formula, newName);
}
void tptp_SkolemInference(TPTPSTATE Tptpstate, TPTP_FORMULA Formula,
                          TERM NewTerm, ARRAY VarSkolem)
{
  tptp_SetTerm(Formula, NewTerm);
  if (array_GetSize(VarSkolem) == 0) {
    return;
  }
  char *oldName, *newName;
  TPTP_PROOFSTEP newPS;
  MEMORY mem = tptp_GetMemory(Tptpstate);
  FOLSTATE folstate = tptp_GetFolstate(Tptpstate);
  STRBUF buf = Tptpstate->strbuf;
  string_Clear(buf);
  oldName = tptp_GetName(Formula);
  newName = string_Conc(mem, tptp_GetBasename(Formula), "skol");
  tptp_SetLanguage(Formula, TPTP_LangFOF);
  string_Printf(buf, "%% FOF SKOLEM INFERENCE. WIP!!\n");
  string_Printf(buf, "%s(%s,%s,\n    ",
                tptp_GetLanguage(Formula),
                newName,
                tptp_GetRole(Formula));
  tptp_BPrintFormulaContent(buf, folstate, Formula);
  string_Printf(buf, ",\n    inference(skolemize, [status(esa),");
  string_Printf(buf, "\n                          new_symbols(skolem,[");
  for (unsigned int i=0; i<array_GetSize(VarSkolem); i+=2) {
    TERM sko = (TERM)array_GetElement(VarSkolem, i+1);
    string_Printf(buf, "%s", symbol_GetName(tptp_GetSymbstate(Tptpstate),
                                             term_TopSymbol(sko)));
    string_Printf(buf, "%s", (i+2 >= array_GetSize(VarSkolem) ? "]),\n" : ","));
  }
  for (unsigned int i=0; i<array_GetSize(VarSkolem); i+=2) {
    TERM var = (TERM)array_GetElement(VarSkolem, i);
    TERM sko = (TERM)array_GetElement(VarSkolem, i+1);
    string_Printf(buf, "                          skolemize(");
    tptp_BPrintAtom(buf, tptp_GetFolstate(Tptpstate), var);
    string_Printf(buf, ",");
    tptp_BPrintAtom(buf, tptp_GetFolstate(Tptpstate), sko);
    string_Printf(buf, ")");
    string_Printf(buf, "%s", (i+2 >= array_GetSize(VarSkolem) ? "]," : ",\n"));
    term_Delete(tptp_GetTermstate(Tptpstate), var);
    term_Delete(tptp_GetTermstate(Tptpstate), sko);
  }
  string_Printf(buf, " [%s]", oldName);
  string_Printf(buf, ") ).");
  newPS = tptp_CreateProofstepStoreString(Tptpstate, string_CopyStr(buf));
  tptp_ProofstepAddParent(mem, newPS, tptp_GetProofstep(Formula));
  tptp_SetProofstep(Formula, newPS);
  string_StringFree(mem, oldName);
  tptp_SetName(Formula, newName);
}
void tptp_PushDisjInference(TPTPSTATE Tptpstate, TPTP_FORMULA Formula, CLAUSE Clause)
{
  TPTP_PROOFSTEP newPS;
  MEMORY mem = tptp_GetMemory(Tptpstate);
  FOLSTATE folstate = tptp_GetFolstate(Tptpstate);
  STRBUF buf = Tptpstate->strbuf;
  string_Clear(buf);
  string_Printf(buf, "%% FOF PUSH DISJ SPLITTING.\n");
  string_Printf(buf, "%s(%s,%s,\n    ",
                TPTP_LangCNF,
                tptp_GetClauseName(Tptpstate, clause_GetId(Clause)),
                TPTP_RolePlain);
  tptp_BPrintClause(buf, folstate, Clause);
  string_Printf(buf, ",\n    inference(split_conjunct,[status(thm)],");
  string_Printf(buf, "[inference(push_disj,[status(thm)],[%s])]", tptp_GetName(Formula));
  string_Printf(buf, ") ).");
  newPS = tptp_CreateProofstepStoreString(Tptpstate, string_CopyStr(buf));
  tptp_ProofstepAddParent(mem, newPS, tptp_GetProofstep(Formula));
  tptp_SetProofstepByClauseID(Tptpstate, clause_GetId(Clause), newPS);
}
void tptp_BPrintSPASSClauseResolution(STRBUF Buf, TPTPSTATE Tptpstate, CLAUSE Clause)
{
  ARRAY parents = (ARRAY)clause_GetParents(Clause);
  unsigned nParents = (parents == NULL ? 0 : array_GetSize(parents)/2);
  string_Printf(Buf, "%% CNF SPASS RESOLUTION.\n");
  string_Printf(Buf, "%s(%s,%s,\n    ",
                TPTP_LangCNF,
                tptp_GetClauseName(Tptpstate, clause_GetId(Clause)),
                TPTP_RolePlain);
  tptp_BPrintClause(Buf, tptp_GetFolstate(Tptpstate), Clause);
  string_Printf(Buf, ",\n    inference(%s,[status(thm)],",
                (clause_IsMarkedPropAbstr(Clause) ? "byPropositionalAbstraction" : "resolution"));
  string_Printf(Buf, "[");
  for (unsigned i=0; i<nParents; ++i) {
    unsigned parentClauseID = (unsigned)array_GetElement(parents, i*2);
    string_Printf(Buf, "%s%s",
                  (i ? ", " : "\n      "),
                  tptp_GetClauseName(Tptpstate, parentClauseID));
  }
  string_Printf(Buf, "]");
  string_Printf(Buf, ") ).");
}
void tptp_FPrintSPASSClauseResolution(FILE *File, TPTPSTATE Tptpstate, CLAUSE Clause)
{
  STRBUF buf = Tptpstate->strbuf;
  string_Clear(buf);
  tptp_BPrintSPASSClauseResolution(buf, Tptpstate, Clause);
  if(File) fprintf(File, "%s\n", string_GetStr(buf));
}
void tptp_ResizeClauseIDtoPS(TPTPSTATE Tptpstate, unsigned MaxClauseID)
{
  MEMORY mem = tptp_GetMemory(Tptpstate);
  Tptpstate->clauseIDtoPS = array_Reserve(mem, Tptpstate->clauseIDtoPS, MaxClauseID + 2);
  array_Claim(Tptpstate->clauseIDtoPS);
}
void tptp_RegisterClauses(TPTPSTATE Tptpstate, ARRAY Clauses, const char *ClauseMsg)
{
  for (unsigned i=0; i<array_GetSize(Clauses); ++i) {
    tptp_CreateProofstepForClause(Tptpstate, (CLAUSE)array_GetElement(Clauses, i), ClauseMsg);
  }
}
void tptp_FPrintDerivation(FILE *File, TPTPSTATE Tptpstate, TPTP_PROOFSTEP Proofstep)
{
  CLAUSE clause;
  ARRAY arr, parents;
#ifdef SPASS_CHECK
  if (Proofstep == NULL) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Proofstep == NULL!", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (Proofstep->visited) return;
  Proofstep->visited = TRUE;
  switch (Proofstep->type) {
  case TPTP_PS_STORED_AS_STRING:
    arr = (ARRAY)Proofstep->data;
    for (unsigned i=1; i<array_GetSize(arr); ++i) {
      tptp_FPrintDerivation(File, Tptpstate,
                            (TPTP_PROOFSTEP)array_GetElement(arr, i));
    }
    fprintf(File, "\n%s\n", (const char*)array_GetElement(arr, 0));
    break;
  case TPTP_PS_SPASSCLAUSE:
    clause = (CLAUSE)Proofstep->data;
    parents = (ARRAY)clause_GetParents(clause);
    if (parents != NULL) {
      for (unsigned i=0; i<array_GetSize(parents); i+=2) {
        unsigned parentClauseID = (unsigned)array_GetElement(parents, i);
        TPTP_PROOFSTEP parentPS = tptp_GetProofstepByClauseID(Tptpstate, parentClauseID);
        if (parentPS == NULL) {
          printf("%% WARNING! Clause %u (%s)", clause_GetId(clause),
                 tptp_GetClauseName(Tptpstate, clause_GetId(clause)));
          printf(" references a parent clause (ID %u) that doesn't exists!\n", parentClauseID);
          puts("% For now I'll just skip that parent\n");
        }
        else {
          tptp_FPrintDerivation(File, Tptpstate, parentPS);
        }
      }
    }
    fprintf(File, "\n");
    tptp_FPrintSPASSClauseResolution(File, Tptpstate, clause);
    fprintf(File, "\n");
    break;
  default:
#ifdef SPASS_CHECK
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Unexpected Proofstep->type!", __func__);
    misc_FinishErrorReport();
#endif
    break;
  }
}
void tptp_PrintDerivationWrapper(TPTPSTATE Tptpstate, ARRAY Clauses, ARRAY RedClauses, CLAUSE EmptyClause)
{
  if (!EmptyClause) {
    puts("%% NO EMPTY CLAUSE. ABORTING PROOF OUTPUT.");
    return;
  }
  puts("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
  printf("%% SZS output start Proof for %s\n",
         tptp_GetProblemName(Tptpstate));
  tptp_RegisterClauses(Tptpstate, Clauses, "regular");
  tptp_RegisterClauses(Tptpstate, RedClauses, "reduced");
  tptp_FPrintDerivation(stdout, Tptpstate,
                        tptp_GetProofstepByClauseID(Tptpstate, clause_GetId(EmptyClause)));
  printf("%% SZS output end Proof for %s\n",
         tptp_GetProblemName(Tptpstate));
  puts("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
}
