#ifndef _FOLSUBST_
#define _FOLSUBST_ 
#include "array.h"
#include "fol.h"
typedef TERM *SUBST;
typedef SYMBOL *VSUBST;
typedef intptr_t *CONTEXT;
typedef intptr_t *GATOM;
typedef intptr_t *UCONTEXT;
typedef struct SUBSTSTATE_HELP {
  MEMORY memory;
  CONTEXT context;
  ARRAY stack;
  ARRAY matchs;
  BOOL sactive;
  intptr_t mark;
  BOOL active;
  unsigned vars;
  UCONTEXT left;
  UCONTEXT right;
} SUBSTSTATE_NODE,*SUBSTSTATE;
unsigned subst_MaxVars(SUBSTSTATE);
SUBSTSTATE subst_StateCreate(MEMORY, unsigned);
void subst_StateUpdate(MEMORY, SYMBSTATE, SUBSTSTATE, unsigned);
void subst_HotStateUpdate(MEMORY, SYMBSTATE, SUBSTSTATE, unsigned);
void subst_StateDelete(MEMORY, SUBSTSTATE);
void subst_ContextStart(SUBSTSTATE, SYMBSTATE);
void subst_VarNormalize(SUBSTSTATE, TERMSTATE, SYMBSTATE, TERM, ARRAY,TYPE);
void subst_ContextStop(SUBSTSTATE);
void subst_ContextStackStart(SUBSTSTATE);
void subst_ContextStackStop(SUBSTSTATE);
void subst_ContextStackPush(SUBSTSTATE);
void subst_ContextStackPop(SUBSTSTATE);
void subst_ContextSetValueStack(SUBSTSTATE, SYMBOL, intptr_t);
intptr_t subst_ContextGetValue(SUBSTSTATE, SYMBOL);
intptr_t subst_ContextGetExtraValue(SUBSTSTATE, SYMBOL);
BOOL subst_ContextValueIsMarked(SUBSTSTATE, SYMBOL);
void subst_ContextSetValue(SUBSTSTATE, SYMBOL, intptr_t);
void subst_ContextUnsetValue(SUBSTSTATE, SYMBOL);
void subst_ContextSetExtraValue(SUBSTSTATE, SYMBOL, intptr_t);
void subst_ContextSetSecondExtraValue(SUBSTSTATE, SYMBOL, intptr_t);
intptr_t subst_ContextGetSecondExtraValue(SUBSTSTATE, SYMBOL);
void subst_ContextPrint(SUBSTSTATE, TERMSTATE, BOOL);
void subst_UContextSetValue(SUBSTSTATE, UCONTEXT, SYMBOL, TERM, UCONTEXT);
BOOL subst_UContextValueIsMarked(SUBSTSTATE, UCONTEXT, SYMBOL);
TERM subst_UContextGetTerm(SUBSTSTATE, UCONTEXT, SYMBOL);
TYPING subst_UContextGetTyping(UCONTEXT);
BOOL subst_FolUTermUnifyTypes(SUBSTSTATE, FOLSTATE, SYMBSTATE, TERM, TYPING, TERM, TYPING, BOOL);
void subst_UContextFlattenTermChainDisjoint(SUBSTSTATE, TERMSTATE, SYMBOL);
TERM subst_UContextApplyToTerm(SUBSTSTATE, TERMSTATE, TERM);
void subst_UContextClean(SUBSTSTATE, TERMSTATE);
VSUBST subst_VCreate(MEMORY, SYMBSTATE, unsigned);
void subst_VDelete(MEMORY, VSUBST);
void subst_VPrint(SYMBSTATE, VSUBST);
VSUBST subst_VCopy(MEMORY, VSUBST);
unsigned subst_VNumberOfVariables(VSUBST);
void subst_VTermPrintPrefix(TERMSTATE, TERM, VSUBST);
BOOL subst_VVarDefined(SYMBSTATE, VSUBST, SYMBOL);
void subst_VSetValue(VSUBST, SYMBOL, SYMBOL);
void subst_VClean(SYMBSTATE, VSUBST);
SYMBOL subst_VGetValue(VSUBST, SYMBOL);
BOOL subst_VIsTotal(SYMBSTATE, VSUBST);
unsigned subst_VGetFirstUndefinedVar(SYMBSTATE, VSUBST);
BOOL subst_FolTermMatchTerms(SUBSTSTATE, SYMBSTATE, TERMSTATE, FOLSTATE, TERM, TYPING, TERM, TYPING);
BOOL subst_FolTermMatchTermsSubsts(SUBSTSTATE, SYMBSTATE, TERMSTATE, FOLSTATE, TERM, TYPING, SUBST, TERM, TYPING, SUBST);
void subst_BSTermUnifyDisjoint(SUBSTSTATE, TERMSTATE, SYMBSTATE, TERM, TERM);
BOOL subst_FolTermUnifyIdenticalVars(SUBSTSTATE, FOLSTATE, TERMSTATE, SYMBSTATE, TYPING, TERM, TERM, BOOL);
BOOL subst_TermUnifyIdenticalVarsNoTypes(SUBSTSTATE, TERMSTATE, SYMBSTATE, TERM, TERM, BOOL);
BOOL subst_TermUnifyIdenticalVarsNoTypesStack(SUBSTSTATE, TERMSTATE, SYMBSTATE, TERM, TERM, BOOL);
BOOL subst_TermUnifyDisjointVarsNoTypes(SUBSTSTATE, TERMSTATE, SYMBSTATE, TERM, TERM, BOOL);
BOOL subst_FolTermUnifyIdenticalVarsSubst(SUBSTSTATE, FOLSTATE, TERMSTATE, SYMBSTATE, TYPING, SUBST, TERM, TERM, BOOL);
BOOL subst_BSTermUnify(SUBSTSTATE, TERMSTATE, SYMBSTATE, TERM, TERM);
BOOL subst_VTermEqual(SYMBSTATE, TERM, VSUBST, TERM, VSUBST);
void subst_TermMarkVariables(SUBSTSTATE, SYMBSTATE, TERM);
BOOL subst_TermMatchTermsStackFol(SUBSTSTATE, SYMBSTATE, TERMSTATE, FOLSTATE, TERM, TYPING, TERM, TYPING);
void subst_VContextUpdateSubst(SUBSTSTATE, SYMBSTATE, VSUBST);
void subst_ContextFlattenTermChainDisjoint(SUBSTSTATE, SYMBSTATE, SYMBOL);
TERM subst_ContextGetTermValueFollowSymbolChain(SUBSTSTATE, SYMBSTATE, TERM);
void subst_ContextFlattenTerms(SUBSTSTATE, SYMBSTATE, SYMBOL);
TERM subst_ContextTermApplyToTerm(SUBSTSTATE, TERMSTATE, TERM);
SUBST subst_ContextExtractSubst(SUBSTSTATE, TERMSTATE, SYMBSTATE, SYMBOL);
SUBST subst_ContextFlattenExtractSubst(SUBSTSTATE, TERMSTATE, SYMBSTATE, SYMBOL);
TERM subst_ContextFlattenTermApplyToTerm(SUBSTSTATE, TERMSTATE, TERM);
SUBST subst_ContextExtractSubstShallow(SUBSTSTATE, TERMSTATE, SYMBSTATE, SYMBOL);
void subst_BSContextApplyToTerm(SUBSTSTATE, SYMBSTATE, TERM);
TERM subst_BSContextApplyToConstraintTerm(SUBSTSTATE, TERMSTATE, SYMBSTATE, TERM);
void subst_VSubstApplyTerm(SYMBSTATE, TERM, VSUBST);
void subst_VUndefineVariablesInTerm(SYMBSTATE, TERM, VSUBST);
VSUBST subst_VVarNormalize(SUBSTSTATE, TERMSTATE, SYMBSTATE, TERM, unsigned);
VSUBST subst_VIdentitySubst(MEMORY, SYMBSTATE, unsigned);
GATOM subst_CreateGAtom(MEMORY, TERMSTATE, TERM, VSUBST, unsigned, BOOL);
VSUBST subst_GatomSubst(GATOM);
TERM subst_GatomAtom(GATOM);
BOOL subst_GatomPhasePositive(GATOM);
void subst_GatomSetPhase(GATOM, BOOL);
unsigned subst_GatomVars(GATOM);
void subst_GatomDelete(MEMORY, GATOM);
GATOM subst_GatomCopy(MEMORY, GATOM);
void subst_GatomPrint(SYMBSTATE, TERMSTATE, GATOM);
void subst_GatomMapUnusedVariablesIdle(SYMBSTATE, SUBSTSTATE, TERMSTATE, GATOM);
SUBST subst_Create(MEMORY, unsigned);
void subst_Delete(MEMORY, SUBST);
void subst_DeleteWithTerms(TERMSTATE, MEMORY, SUBST);
void subst_Print(TERMSTATE, SYMBSTATE, SUBST);
SUBST subst_Copy(MEMORY, SUBST);
SUBST subst_CopyWitTerms(TERMSTATE, SUBST, unsigned);
void subst_TermPrintPrefix(TERMSTATE, TERM, SUBST);
BOOL subst_VarDefined(SUBST, SYMBOL);
void subst_SetValue(SUBST, SYMBOL, TERM);
unsigned subst_NumberOfVariables(SUBST);
void subst_Clean(SUBST);
TERM subst_GetValue(SUBST, SYMBOL);
BOOL subst_IsTotal(SUBST);
unsigned subst_GetFirstUndefinedVar(SUBST);
TERM subst_SubstApplyTerm(TERMSTATE, TERM, SUBST, BOOL);
SUBST subst_ApplyToSubst(TERMSTATE, SUBST, SUBST, BOOL);
SUBST subst_ContextApplyToSubst(SUBSTSTATE, TERMSTATE, SUBST, BOOL);
SUBST subst_ContextFlattenApplyToSubst(SUBSTSTATE, TERMSTATE, SUBST, BOOL);
BOOL subst_TermIsGrounded(TERMSTATE, TERM, SUBST);
SUBST subst_BSSubstApplyContext(SUBSTSTATE, TERMSTATE, SYMBSTATE, SUBST);
SUBST subst_SubstApplyUContext(SUBSTSTATE, TERMSTATE, SUBST);
BOOL subst_TermEqualModuloSubsts(SYMBSTATE, TERM, SUBST, TERM, SUBST);
BOOL subst_TermEqualModuloSubstsAndTypes(SYMBSTATE, TERM, SUBST, TYPING, TERM, SUBST, TYPING);
BOOL subst_IsInstance(SUBSTSTATE, SYMBSTATE, TERMSTATE, SUBST, SUBST);
BOOL subst_OccurCheck(SUBSTSTATE, SYMBSTATE, SYMBOL, TERM);
SYMBOL subst_ContextGetValueFollowSymbolChainRight(SUBSTSTATE, SYMBSTATE, SYMBOL);
SYMBOL subst_ContextGetValueFollowSymbolChainLeft(SUBSTSTATE, SYMBSTATE, SYMBOL);
void subst_ContextSetExtraValueWithMark(SUBSTSTATE, SYMBOL, intptr_t);
UCONTEXT subst_UContextLeft(SUBSTSTATE);
UCONTEXT subst_UContextRight(SUBSTSTATE);
BOOL subst_OccurCheckSubst(SUBSTSTATE, SYMBSTATE, SUBST, SYMBOL, TERM);
TERM subst_UContextGetValueFollowSymbolChain(SUBSTSTATE, SYMBSTATE, UCONTEXT *, TERM);
void subst_UContextSetTyping(UCONTEXT, TYPING);
BOOL subst_UOccurCheck(SUBSTSTATE, SYMBSTATE, UCONTEXT, SYMBOL, UCONTEXT, TERM);
#endif
