blob: 798b04ac1b73cfcd0e9a328b5f88a5e08392049d [file] [log] [blame]
/**************************************************************/
/* ********************************************************** */
/* * * */
/* * CONTEXTS FOR VARIABLES * */
/* * * */
/* * $Module: CONTEXT * */
/* * * */
/* * Copyright (C) 1997, 1998, 1999, 2000, 2001 * */
/* * MPI fuer Informatik * */
/* * * */
/* * This program is free software; you can redistribute * */
/* * it and/or modify it under the terms of the GNU * */
/* * General Public License as published by the Free * */
/* * Software Foundation; either version 2 of the License, * */
/* * or (at your option) any later version. * */
/* * * */
/* * This program is distributed in the hope that it will * */
/* * be useful, but WITHOUT ANY WARRANTY; without even * */
/* * the implied warranty of MERCHANTABILITY or FITNESS * */
/* * FOR A PARTICULAR PURPOSE. See the GNU General Public * */
/* * License for more details. * */
/* * * */
/* * You should have received a copy of the GNU General * */
/* * Public License along with this program; if not, write * */
/* * to the Free Software Foundation, Inc., 59 Temple * */
/* * Place, Suite 330, Boston, MA 02111-1307 USA * */
/* * * */
/* * * */
/* $Revision$ * */
/* $State$ * */
/* $Date$ * */
/* $Author$ * */
/* * * */
/* * Contact: * */
/* * Christoph Weidenbach * */
/* * MPI fuer Informatik * */
/* * Stuhlsatzenhausweg 85 * */
/* * 66123 Saarbruecken * */
/* * Email: weidenb@mpi-sb.mpg.de * */
/* * Germany * */
/* * * */
/* ********************************************************** */
/**************************************************************/
/* $RCSfile$ */
#define SHOWBINDINGS 0
#ifndef _CONTEXT_
#define _CONTEXT_
/**************************************************************/
/* Includes */
/**************************************************************/
#include "term.h"
#include "symbol.h"
#include "list.h"
/**************************************************************/
/* Structures */
/**************************************************************/
/* Set 'SHOWBINDINGS' to non-zero value to enable debug output. */
/* #define SHOWBINDINGS 1 */
#define cont__SIZE symbol__MAXVARIABLES
extern int cont_NOOFCONTEXTS;
extern LIST cont_LISTOFCONTEXTS;
extern int cont_BINDINGS;
/* An array to remember bindings for the variables. The array */
/* is indexed by the variable index and holds the binding term. */
typedef struct binding {
SYMBOL symbol;
SYMBOL renaming;
TERM term;
struct binding *context;
struct binding *link;
} *CONTEXT, CONTEXT_NODE;
extern CONTEXT cont_LASTBINDING; /* The last binding made. */
extern CONTEXT cont_CURRENTBINDING; /* Help variable. */
extern SYMBOL cont_INDEXVARSCANNER;
/* Two contexts are allocated by default */
extern CONTEXT cont_LEFTCONTEXT;
extern CONTEXT cont_RIGHTCONTEXT;
extern CONTEXT cont_INSTANCECONTEXT; /* This context is used as a label only (dummy context) */
static __inline__ CONTEXT cont_LeftContext(void)
{
return cont_LEFTCONTEXT;
}
static __inline__ CONTEXT cont_RightContext(void)
{
return cont_RIGHTCONTEXT;
}
static __inline__ CONTEXT cont_InstanceContext(void)
{
return cont_INSTANCECONTEXT;
}
/**************************************************************/
/* A stack for the number of established bindings */
/**************************************************************/
#define cont__STACKSIZE 1000
typedef int cont_STACK_TYPE[cont__STACKSIZE];
extern cont_STACK_TYPE cont_STACK;
extern int cont_STACKPOINTER;
/* Stack operations */
static __inline__ void cont_StackInit(void)
{
cont_STACKPOINTER = 1;
}
static __inline__ void cont_StackPush(int Entry)
{
#ifdef CHECK
if (cont_STACKPOINTER >= cont__STACKSIZE) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_StackPush: Context stack overflow!\n");
misc_FinishErrorReport();
}
#endif
cont_STACK[cont_STACKPOINTER++] = Entry;
}
static __inline__ void cont_StackPop(void)
{
--cont_STACKPOINTER;
}
static __inline__ int cont_StackPopResult(void)
{
return cont_STACK[--cont_STACKPOINTER];
}
static __inline__ void cont_StackNPop(int N)
{
cont_STACKPOINTER -= N;
}
static __inline__ int cont_StackTop(void)
{
return cont_STACK[cont_STACKPOINTER - 1];
}
static __inline__ int cont_StackNthTop(int N)
{
return cont_STACK[cont_STACKPOINTER - (1 + N)];
}
static __inline__ void cont_StackRplacTop(int Entry)
{
cont_STACK[cont_STACKPOINTER - 1] = Entry;
}
static __inline__ void cont_StackRplacNthTop(int N, int Entry)
{
cont_STACK[cont_STACKPOINTER - (1 + N)] = Entry;
}
static __inline__ void cont_StackRplacNth(int N, int Entry)
{
cont_STACK[N] = Entry;
}
static __inline__ int cont_StackBottom(void)
{
return cont_STACKPOINTER;
}
static __inline__ void cont_StackSetBottom(int Pointer)
{
cont_STACKPOINTER = Pointer;
}
static __inline__ BOOL cont_StackEmpty(int Pointer)
{
return cont_STACKPOINTER == Pointer;
}
static __inline__ void cont_StartBinding(void)
{
cont_StackPush(cont_BINDINGS);
cont_BINDINGS = 0;
}
static __inline__ int cont_BindingsSinceLastStart(void)
{
return cont_BINDINGS;
}
static __inline__ void cont_StopAndStartBinding(void)
{
cont_StackRplacTop(cont_StackTop() + cont_BINDINGS);
cont_BINDINGS = 0;
}
/**************************************************************/
/* Access */
/**************************************************************/
static __inline__ CONTEXT cont_Binding(CONTEXT C, SYMBOL Var)
{
return &(C)[Var];
}
static __inline__ CONTEXT cont_BindingLink(CONTEXT B)
{
return B->link;
}
static __inline__ void cont_SetBindingLink(CONTEXT B, CONTEXT L)
{
B->link = L;
}
static __inline__ TERM cont_BindingTerm(CONTEXT B)
{
return B->term;
}
static __inline__ void cont_SetBindingTerm(CONTEXT B, TERM T)
{
B->term = T;
}
static __inline__ SYMBOL cont_BindingSymbol(CONTEXT B)
{
return B->symbol;
}
static __inline__ void cont_SetBindingSymbol(CONTEXT B, SYMBOL S)
{
B->symbol = S;
}
static __inline__ SYMBOL cont_BindingRenaming(CONTEXT B)
{
return B->renaming;
}
static __inline__ void cont_SetBindingRenaming(CONTEXT B, SYMBOL S)
{
B->renaming = S;
}
static __inline__ CONTEXT cont_BindingContext(CONTEXT B)
{
return B->context;
}
static __inline__ void cont_SetBindingContext(CONTEXT B, CONTEXT C)
{
B->context = C;
}
static __inline__ CONTEXT cont_ContextBindingLink(CONTEXT C,SYMBOL Var)
{
return C[Var].link;
}
static __inline__ TERM cont_ContextBindingTerm(CONTEXT C,SYMBOL Var)
{
return C[Var].term;
}
static __inline__ void cont_SetContextBindingTerm(CONTEXT C, SYMBOL Var, TERM t)
{
C[Var].term = t;
}
static __inline__ SYMBOL cont_ContextBindingSymbol(CONTEXT C,SYMBOL Var)
{
return C[Var].symbol;
}
static __inline__ SYMBOL cont_ContextBindingRenaming(CONTEXT C,SYMBOL Var)
{
return C[Var].renaming;
}
static __inline__ void cont_SetContextBindingRenaming(CONTEXT C, SYMBOL Var,
SYMBOL R)
{
C[Var].renaming = R;
}
static __inline__ CONTEXT cont_ContextBindingContext(CONTEXT C,SYMBOL Var)
{
return C[Var].context;
}
/**************************************************************/
/* Predicates */
/**************************************************************/
static __inline__ BOOL cont_VarIsBound(CONTEXT C, SYMBOL Var)
{
return cont_ContextBindingTerm(C,Var) != (TERM) NULL;
}
static __inline__ BOOL cont_VarIsUsed(CONTEXT C, SYMBOL Var)
{
return cont_ContextBindingContext(C,Var) != (CONTEXT) NULL;
}
static __inline__ BOOL cont_VarIsLinked(CONTEXT C, SYMBOL Var)
{
return cont_ContextBindingLink(C,Var) != (CONTEXT) NULL;
}
static __inline__ BOOL cont_VarIsRenamed(CONTEXT C, SYMBOL Var)
{
return cont_ContextBindingRenaming(C, Var) != symbol_Null();
}
static __inline__ BOOL cont_VarIsClosed(CONTEXT C,SYMBOL Var)
{
return !cont_VarIsBound(C,Var) && cont_VarIsUsed(C,Var);
}
static __inline__ BOOL cont_BindingIsBound(CONTEXT B)
{
return cont_BindingTerm(B) != (TERM) NULL;
}
static __inline__ BOOL cont_BindingIsUsed(CONTEXT B)
{
return cont_BindingContext(B) != (CONTEXT) NULL;
}
/**************************************************************/
/* Aux functions for backtracking */
/**************************************************************/
static __inline__ CONTEXT cont_LastBinding(void)
{
return cont_LASTBINDING;
}
static __inline__ void cont_SetLastBinding(CONTEXT B)
{
cont_LASTBINDING = B;
}
static __inline__ TERM cont_LastBindingTerm(void)
{
return cont_BindingTerm(cont_LastBinding());
}
static __inline__ SYMBOL cont_LastBindingSymbol(void)
{
return cont_BindingSymbol(cont_LastBinding());
}
static __inline__ CONTEXT cont_LastBindingContext(void)
{
return cont_BindingContext(cont_LastBinding());
}
static __inline__ BOOL cont_LastIsBound(void)
{
return cont_BindingIsBound(cont_LastBinding());
}
static __inline__ BOOL cont_LastIsUsed(void)
{
return cont_LastBindingContext() != (CONTEXT) NULL;
}
static __inline__ BOOL cont_LastIsClosed(void)
{
return !cont_LastIsBound() && cont_LastIsUsed();
}
static __inline__ BOOL cont_IsInContext(CONTEXT C, SYMBOL Var, CONTEXT B)
{
return cont_Binding(C, Var) == B;
}
static __inline__ CONTEXT cont_ContextOfBinding(CONTEXT B)
{
CONTEXT Result;
LIST Scan;
for (Result = NULL, Scan = cont_LISTOFCONTEXTS;
list_Exist(Scan);
Scan = list_Cdr(Scan)) {
if (cont_IsInContext(list_Car(Scan), cont_BindingSymbol(B), B)) {
Result = list_Car(Scan);
break;
}
}
#ifdef CHECK
if (Result == NULL) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_ContextOfBinding: Unknown context.\n");
misc_FinishErrorReport();
}
#endif
return Result;
}
/**************************************************************/
/* Initialization */
/**************************************************************/
static __inline__ void cont_InitBinding(CONTEXT C, SYMBOL Var)
{
cont_CURRENTBINDING = cont_Binding(C, Var);
cont_SetBindingLink(cont_CURRENTBINDING, (CONTEXT)NULL);
cont_SetBindingTerm(cont_CURRENTBINDING, (TERM)NULL);
cont_SetBindingSymbol(cont_CURRENTBINDING, Var);
cont_SetBindingRenaming(cont_CURRENTBINDING, symbol_Null());
cont_SetBindingContext(cont_CURRENTBINDING, (CONTEXT)NULL);
}
static __inline__ void cont_InitContext(CONTEXT C)
{
int i;
for (i = 0; i < cont__SIZE; i++)
cont_InitBinding(C, i);
}
/**************************************************************/
/* Creation and deletion of contexts */
/**************************************************************/
static __inline__ CONTEXT cont_Create(void)
{
CONTEXT Result;
Result = (CONTEXT)memory_Malloc(cont__SIZE*sizeof(CONTEXT_NODE));
cont_InitContext(Result);
cont_LISTOFCONTEXTS = list_Cons(Result, cont_LISTOFCONTEXTS);
cont_NOOFCONTEXTS++;
return Result;
}
static __inline__ void cont_Delete(CONTEXT C)
{
#ifdef CHECK
if ((cont_NOOFCONTEXTS == 0) ||
!list_PointerMember(cont_LISTOFCONTEXTS, C)) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_Delete: Context %ld not registered.\n",
(unsigned long)C);
misc_FinishErrorReport();
}
#endif
cont_LISTOFCONTEXTS = list_PointerDeleteOneElement(cont_LISTOFCONTEXTS, C);
cont_NOOFCONTEXTS--;
memory_Free(C, cont__SIZE*sizeof(CONTEXT_NODE));
}
static __inline__ void cont_ResetIndexVarScanner(void)
{
cont_INDEXVARSCANNER = symbol_GetInitialIndexVarCounter();
}
/**************************************************************/
/* Output bindings */
/**************************************************************/
static __inline__ void cont_BindingOutput(CONTEXT C, SYMBOL Var)
{
symbol_Print(cont_ContextBindingSymbol(C, Var));
putchar(':');
symbol_Print(Var);
fputs(" -> ", stdout);
if (cont_VarIsBound(C, Var)) {
term_PrintPrefix(cont_ContextBindingTerm(C, Var));
} else
fputs("unbound", stdout);
fputs(" in ", stdout);
if (cont_VarIsUsed(C, Var)) {
printf("%ld", (unsigned long)cont_ContextBindingContext(C, Var));
} else
fputs("NULL (unused)", stdout);
fputs(". ", stdout);
if (cont_VarIsClosed(C, Var)) {
fputs("(closed)", stdout);
}
if (!cont_VarIsBound(C, Var) &&
!cont_VarIsUsed(C, Var)) {
fputs(",(free)", stdout);
}
if (cont_VarIsRenamed(C, Var)) {
fputs(",(renamed): ", stdout);
symbol_Print(Var);
fputs(" -> ", stdout);
symbol_Print(cont_ContextBindingRenaming(C, Var));
}
fflush(stdout);
}
static __inline__ void cont_PrintCurrentTrail(void)
{
fputs("\nPrint bindings:", stdout);
cont_CURRENTBINDING = cont_LastBinding();
while (cont_CURRENTBINDING) {
cont_BindingOutput(cont_ContextOfBinding(cont_CURRENTBINDING),
cont_BindingSymbol(cont_CURRENTBINDING));
cont_CURRENTBINDING = cont_BindingLink(cont_CURRENTBINDING);
if (cont_CURRENTBINDING)
putchar('\n');
}
fflush(stdout);
}
/**************************************************************/
/* Close bindings */
/**************************************************************/
static __inline__ void cont_CloseBindingHelp(CONTEXT C, SYMBOL Var)
{
cont_SetContextBindingTerm(C, Var, NULL);
}
static __inline__ void cont_CloseBindingBindingHelp(CONTEXT B)
{
cont_SetBindingTerm(B, NULL);
}
#if SHOWBINDINGS
static __inline__ void cont_CloseBinding(CONTEXT C, SYMBOL Var)
{
fputs("\nClose binding from ", stdout);
cont_BindingOutput(C, Var);
cont_CloseBindingHelp(C, Var);
}
#else
static __inline__ void cont_CloseBinding(CONTEXT C, SYMBOL Var)
{
cont_CloseBindingHelp(C, Var);
}
#endif
static __inline__ void cont_CloseBindingBinding(CONTEXT B) {
cont_CloseBindingBindingHelp(B);
}
/**************************************************************/
/* Establish bindings */
/**************************************************************/
static __inline__ void cont_CreateBindingHelp(CONTEXT C, SYMBOL Var,
CONTEXT CTerm, TERM Term)
{
#ifdef CHECK
if (cont_VarIsBound(C, Var)) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_CreateBindingHelp: Variable already bound.\n");
misc_FinishErrorReport();
}
#endif
cont_CURRENTBINDING = cont_Binding(C,Var);
cont_SetBindingTerm(cont_CURRENTBINDING, Term);
cont_SetBindingContext(cont_CURRENTBINDING, CTerm);
cont_SetBindingLink(cont_CURRENTBINDING, cont_LastBinding());
cont_SetLastBinding(cont_CURRENTBINDING);
}
#if SHOWBINDINGS
static __inline__ int cont_CreateBinding(CONTEXT C, SYMBOL Var, CONTEXT CTerm, TERM Term)
{
cont_CreateBindingHelp(C,Var,CTerm,Term);
fputs("\nEstablish binding from ", stdout);
cont_BindingOutput(C, Var);
return ++cont_BINDINGS;
}
static __inline__ int cont_CreateClosedBinding(CONTEXT C, SYMBOL Var)
{
cont_CreateBindingHelp(C, Var, C, NULL);
fputs("\nEstablish closed binding from ", stdout);
cont_BindingOutput(C,Var);
return ++cont_BINDINGS;
}
#else
static __inline__ int cont_CreateBinding(CONTEXT C, SYMBOL Var, CONTEXT CTerm, TERM Term)
{
cont_CreateBindingHelp(C,Var,CTerm,Term);
return ++cont_BINDINGS;
}
static __inline__ int cont_CreateClosedBinding(CONTEXT C, SYMBOL Var)
{
cont_CreateBindingHelp(C, Var, C, NULL);
return ++cont_BINDINGS;
}
#endif
/**************************************************************/
/* Backtracking */
/**************************************************************/
static __inline__ void cont_BackTrackLastBindingHelp(void)
{
cont_CURRENTBINDING = cont_LastBinding();
cont_SetLastBinding(cont_BindingLink(cont_CURRENTBINDING));
cont_SetBindingTerm(cont_CURRENTBINDING, NULL);
cont_SetBindingContext(cont_CURRENTBINDING, NULL);
cont_SetBindingRenaming(cont_CURRENTBINDING, symbol_Null());
cont_SetBindingLink(cont_CURRENTBINDING, NULL);
cont_BINDINGS--;
}
#if SHOWBINDINGS
static __inline__ void cont_BackTrackLastBinding(void)
{
CONTEXT LastContext;
SYMBOL LastSymbol;
LastContext = cont_ContextOfBinding(cont_LastBinding());
LastSymbol = cont_LastBindingSymbol();
fputs("\nBacktrack binding from ", stdout);
cont_BindingOutput(LastContext, LastSymbol);
cont_BackTrackLastBindingHelp();
}
static __inline__ int cont_BackTrack(void)
{
printf("\nBacktrack %d bindings:", cont_BINDINGS);
while (cont_BINDINGS > 0)
cont_BackTrackLastBinding();
if (!cont_StackEmpty(0))
cont_BINDINGS = cont_StackPopResult();
fflush(stdout);
return 0;
}
static __inline__ int cont_StopAndBackTrack(void)
{
#ifdef CHECK
if (cont_BINDINGS > 0) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_StopAndBackTrack: Bindings not reset!\n");
misc_FinishErrorReport();
} else if (cont_StackEmpty(0)) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_StopAndBackTrack: No bindings on stack!\n");
misc_FinishErrorReport();
}
#endif
cont_BINDINGS = cont_StackPopResult();
printf("\nStop and Backtrack %d bindings:", cont_BINDINGS);
while (cont_BINDINGS > 0)
cont_BackTrackLastBinding();
fflush(stdout);
return 0;
}
static __inline__ int cont_BackTrackAndStart(void)
{
printf("\nBacktrack %d bindings:", cont_BINDINGS);
while (cont_BINDINGS > 0)
cont_BackTrackLastBinding();
fflush(stdout);
return 0;
}
static __inline__ void cont_Reset(void)
{
fputs("\nReset bindings:", stdout);
while (cont_LastBinding())
cont_BackTrackLastBinding();
cont_BINDINGS = 0;
cont_StackInit();
cont_ResetIndexVarScanner();
fflush(stdout);
}
#else
static __inline__ void cont_BackTrackLastBinding(void)
{
cont_BackTrackLastBindingHelp();
}
static __inline__ int cont_BackTrack(void)
{
while (cont_BINDINGS > 0)
cont_BackTrackLastBinding();
if (!cont_StackEmpty(0))
cont_BINDINGS = cont_StackPopResult();
return 0;
}
static __inline__ int cont_StopAndBackTrack(void)
{
#ifdef CHECK
if (cont_BINDINGS > 0) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_StopAndBackTrack: Bindings not reset!\n");
misc_FinishErrorReport();
} else if (cont_StackEmpty(0)) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_StopAndBackTrack: No bindings on stack!\n");
misc_FinishErrorReport();
}
#endif
cont_BINDINGS = cont_StackPopResult();
while (cont_BINDINGS > 0)
cont_BackTrackLastBinding();
return 0;
}
static __inline__ int cont_BackTrackAndStart(void)
{
while (cont_BINDINGS > 0)
cont_BackTrackLastBinding();
return 0;
}
static __inline__ void cont_Reset(void)
{
while (cont_LastBinding())
cont_BackTrackLastBinding();
cont_BINDINGS = 0;
cont_StackInit();
cont_ResetIndexVarScanner();
}
#endif
/**************************************************************/
/* Check state of bindings */
/**************************************************************/
#define cont__CHECKSTACKSIZE 1000
#define cont__CHECKSTACKEMPTY 0
typedef POINTER cont_CHECKSTACK_TYPE[cont__CHECKSTACKSIZE];
extern cont_CHECKSTACK_TYPE cont_CHECKSTACK;
extern int cont_CHECKSTACKPOINTER;
/* Stack operations */
static __inline__ void cont_CheckStackInit(void)
{
cont_CHECKSTACKPOINTER = cont__CHECKSTACKEMPTY;
}
static __inline__ void cont_CheckStackPush(POINTER Entry)
{
#ifdef CHECK
if (cont_CHECKSTACKPOINTER >= cont__STACKSIZE) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_CheckStackPush: Context check stack overflow!\n");
misc_FinishErrorReport();
}
#endif
cont_CHECKSTACK[cont_CHECKSTACKPOINTER++] = Entry;
}
static __inline__ void cont_CheckStackPop(void)
{
--cont_CHECKSTACKPOINTER;
}
static __inline__ POINTER cont_CheckStackPopResult(void)
{
return cont_CHECKSTACK[--cont_CHECKSTACKPOINTER];
}
static __inline__ void cont_CheckStackNPop(int N)
{
cont_CHECKSTACKPOINTER -= N;
}
static __inline__ POINTER cont_CheckStackTop(void)
{
return cont_CHECKSTACK[cont_CHECKSTACKPOINTER - 1];
}
static __inline__ POINTER cont_CheckStackNthTop(int N)
{
return cont_CHECKSTACK[cont_CHECKSTACKPOINTER - (1 + N)];
}
static __inline__ void cont_CheckStackRplacTop(POINTER Entry)
{
cont_CHECKSTACK[cont_CHECKSTACKPOINTER - 1] = Entry;
}
static __inline__ void cont_CheckStackRplacNthTop(int N, POINTER Entry)
{
cont_CHECKSTACK[cont_CHECKSTACKPOINTER - (1 + N)] = Entry;
}
static __inline__ void cont_CheckStackRplacNth(int N, POINTER Entry)
{
cont_CHECKSTACK[N] = Entry;
}
static __inline__ int cont_CheckStackBottom(void)
{
return cont_CHECKSTACKPOINTER;
}
static __inline__ void cont_CheckStackSetBottom(int Pointer)
{
cont_CHECKSTACKPOINTER = Pointer;
}
static __inline__ BOOL cont_CheckStackEmpty(int Pointer)
{
return cont_CHECKSTACKPOINTER == Pointer;
}
extern CONTEXT cont_STATELASTBINDING; /* Storage to save state of trails. */
extern int cont_STATEBINDINGS; /* Storage to save number of current bindings. */
extern int cont_STATESTACK; /* Storage to save state of stack. */
extern int cont_STATETOPSTACK; /* Storage to save state of the top element of the stack. */
static __inline__ BOOL cont_CheckLastBinding(CONTEXT Check, int Bindings)
{
CONTEXT Scan;
BOOL Result;
Scan = cont_LastBinding();
while (Bindings > 0) {
Scan = cont_BindingLink(Scan);
Bindings--;
}
if (Check == Scan)
Result = TRUE;
else
Result = FALSE;
return Result;
}
static __inline__ void cont_CheckState(void)
{
if (cont_CheckStackEmpty(cont__CHECKSTACKEMPTY)) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_CheckState: No states saved.\n");
misc_FinishErrorReport();
}
cont_STATETOPSTACK = (int)cont_CheckStackPopResult();
cont_STATESTACK = (int)cont_CheckStackPopResult();
cont_STATEBINDINGS = (int)cont_CheckStackPopResult();
cont_STATELASTBINDING = (CONTEXT)cont_CheckStackPopResult();
if ((cont_STATELASTBINDING != cont_LastBinding()) ||
(cont_STATEBINDINGS != cont_BINDINGS) ||
(!cont_StackEmpty(cont_STATESTACK)) ||
(cont_STATETOPSTACK != cont_StackTop())) {
misc_StartErrorReport();
misc_ErrorReport("\n In cont_CheckState: State of contexts does not match saved state.");
misc_ErrorReport("\nTrail: Saved state: %ld; current state: %ld.",
(long)cont_STATELASTBINDING, (long)cont_LastBinding());
misc_ErrorReport("\nNumber of bindings: Saved state: %d; current state: %d.",
cont_STATEBINDINGS, cont_BINDINGS);
misc_ErrorReport("\nBinding stack pointer: Saved state: %d; current state: %d.",
cont_STATESTACK, cont_StackBottom());
misc_ErrorReport("\nNumber of bindings on top of stack: Saved state: %d; current state: %d.\n\n",
cont_STATETOPSTACK, cont_StackTop());
misc_FinishErrorReport();
}
}
static __inline__ void cont_SaveState(void)
{
cont_CheckStackPush((POINTER)cont_LastBinding());
cont_CheckStackPush((POINTER)cont_BINDINGS);
cont_CheckStackPush((POINTER)cont_StackBottom());
cont_CheckStackPush((POINTER)cont_StackTop());
}
static __inline__ BOOL cont_IsContextEmpty(const CONTEXT Check)
{
int i;
for (i = 0; i < cont__SIZE; i++)
if (cont_VarIsBound(Check, i) ||
cont_VarIsUsed(Check, i) ||
cont_VarIsLinked(Check, i) ||
cont_VarIsRenamed(Check, i))
return FALSE;
return TRUE;
}
/**************************************************************/
/* Generation of index variables */
/**************************************************************/
static __inline__ SYMBOL cont_NextIndexVariable(const CONTEXT IndexContext)
{
if (symbol_Equal(cont_INDEXVARSCANNER, symbol_LastIndexVariable()))
cont_INDEXVARSCANNER = symbol_CreateIndexVariable();
else
for (;;) {
cont_INDEXVARSCANNER = symbol_NextIndexVariable(cont_INDEXVARSCANNER);
if (!cont_VarIsUsed(IndexContext, cont_INDEXVARSCANNER))
break;
else
if (symbol_Equal(cont_INDEXVARSCANNER, symbol_LastIndexVariable())) {
cont_INDEXVARSCANNER = symbol_CreateIndexVariable();
break;
}
}
return cont_INDEXVARSCANNER;
}
/**************************************************************/
/* Dereferencing of terms wrt. contexts */
/**************************************************************/
static __inline__ TERM cont_Deref(CONTEXT* Context, TERM Term)
/**************************************************************
INPUT: A call-by-ref context and a term.
RETURNS: The dereferenced term and the corresponding context.
SUMMARY: Dereferences bindings of variables.
CAUTION: In general, the context of the returned term
is different to the input context.
***************************************************************/
{
while (term_IsVariable(Term) && *Context != cont_InstanceContext()) {
SYMBOL TermTop;
TermTop = term_TopSymbol(Term);
if (cont_VarIsBound(*Context, TermTop)) {
CONTEXT HelpContext;
HelpContext = cont_ContextBindingContext(*Context, TermTop);
Term = cont_ContextBindingTerm(*Context, TermTop);
*Context = HelpContext;
}
else
return Term;
}
return Term;
}
/**************************************************************/
/* Functions for Initialization and Controlling */
/**************************************************************/
void cont_Init(void);
void cont_Check(void);
void cont_Free(void);
/**************************************************************/
/* Functions for Term Equality Test with respect to Bindings */
/**************************************************************/
BOOL cont_TermEqual(CONTEXT, TERM, CONTEXT, TERM);
BOOL cont_TermEqualModuloBindings(CONTEXT, CONTEXT, TERM, CONTEXT, TERM);
/**************************************************************/
/* Functions for Applying Bindings */
/**************************************************************/
TERM cont_CopyAndApplyBindings(CONTEXT, TERM);
TERM cont_CopyAndApplyBindingsCom(const CONTEXT, TERM);
TERM cont_ApplyBindingsModuloMatching(const CONTEXT, TERM, BOOL);
TERM cont_ApplyBindingsModuloMatchingReverse(const CONTEXT, TERM);
BOOL cont_BindingsAreRenamingModuloMatching(const CONTEXT);
/**************************************************************/
/* Misc Functions */
/**************************************************************/
SYMBOL cont_TermMaxVar(CONTEXT, TERM);
NAT cont_TermSize(CONTEXT, TERM);
BOOL cont_TermContainsSymbol(CONTEXT, TERM, SYMBOL);
/**************************************************************/
/* Functions for Output */
/**************************************************************/
void cont_TermPrintPrefix(CONTEXT, TERM);
#endif