////////////////////////////////////////////////////////////////////////////// //Copyright 2008 // Andrew Gacek, Steven Holte, Gopalan Nadathur, Xiaochu Qi, Zach Snow ////////////////////////////////////////////////////////////////////////////// // This file is part of Teyjus. // // // // Teyjus 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 3 of the License, or // // (at your option) any later version. // // // // Teyjus 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 Teyjus. If not, see . // ////////////////////////////////////////////////////////////////////////////// /**************************************************************************** * * * File printterm.c. This file contains routines for printing out lambda * * terms. It is assumed that these routines will be needed in two * * situations: printing out answers to queries and displaying terms as * * needed by invocation of builtin goals. * * The difference between these two situations is in the display of * * free term variables. Only when displaying answers is an attempt made to * * present these using sensible names: in this case, either the name in the * * query is used or a concise name is cooked up. In the other situation, * * the address of the variable cell is used as the name. * * * * Certain assumptions are relevant to avoiding name clashes. For local * * constants, the assumption is that no constant names in user * * programs begin with . The use of this idea is * * buried inside the routine PRINT_writeHCName. * * Violation of this condition is *not* checked. For term variables, the * * assumption is that bound variables do not begin with _. * * * ****************************************************************************/ #include #include #include "printterm.h" #include "mctypes.h" #include "mcstring.h" #include "hnorm.h" #include "dataformats.h" #include "abstmachine.h" #include "io-datastructures.h" #include "builtins/builtins.h" #include "../system/stream.h" #include "../system/error.h" #include "../system/operators.h" #include "../tables/pervasives.h" //temp #include /* This variable records the number of query variables */ int PRINT_numQueryVars; /* flag determining whether or not to print sensible names for free vars */ Boolean PRINT_names = FALSE; static void PRINT_writeTerm(WordPtr outStream, DF_TermPtr tmPtr, OP_FixityType infx, int inprec, OP_TermContext tc); /**************************************************************************** * Auxiliary routines used in this file * ****************************************************************************/ static Boolean PRINT_parenNeeded(OP_FixityType opfx, int opprec, OP_TermContext context, OP_FixityType fx, int prec) { Boolean pparen = FALSE; if (context == OP_LEFT_TERM) { switch (fx) { case OP_INFIX: case OP_INFIXR: case OP_POSTFIX: if (opprec <= prec) pparen = TRUE; break; case OP_INFIXL: case OP_POSTFIXL: { switch (opfx) { case OP_PREFIX: case OP_INFIX: case OP_INFIXL: case OP_POSTFIX: case OP_POSTFIXL: if (opprec < prec) pparen = TRUE; break; default: if (opprec <= prec) pparen = TRUE; break; } break; } default: break; } } else if (context == OP_RIGHT_TERM) { switch (fx) { case OP_INFIX: case OP_INFIXL: case OP_PREFIX: if (opprec <= prec) pparen = TRUE; break; case OP_INFIXR: case OP_PREFIXR: { switch (opfx) { case OP_INFIXL: case OP_POSTFIXL: if (opprec <= prec) pparen = TRUE; break; default: if (opprec < prec) pparen = TRUE; break; } } default: break; } } return pparen; } /* making a name from the address of an unbound term variable */ static long PRINT_makeNumberName(DF_TermPtr tmPtr) { return (long)tmPtr - (long)AM_heapBeg; } /**************************************************************************** * Routines for printing out keywords and punctuation symbols in the course * * of displaying lambda terms. These have been extracted out of the other * * routines so as to make stylistic changes at a later point easier to * * effect. * ****************************************************************************/ static void PRINT_writeLParen(WordPtr outStream) { STREAM_printf(outStream, "("); } static void PRINT_writeRParen(WordPtr outStream) { STREAM_printf(outStream, ")"); } static void PRINT_writeConsSymbol(WordPtr outStream) { STREAM_printf(outStream, " :: "); } static void PRINT_writeNilSymbol(WordPtr outStream) { STREAM_printf(outStream, "nil"); } static void PRINT_writeInfixLam(WordPtr outStream) { STREAM_printf(outStream, "\\ "); } static void PRINT_writeSpace(WordPtr outStream, int i) { while (i--) STREAM_printf(outStream, " "); } static void PRINT_writeEquals(WordPtr outStream) { STREAM_printf(outStream, " = "); } static void PRINT_writeComma(WordPtr outStream) { STREAM_printf(outStream, ","); } static void PRINT_writeDPairStart(WordPtr outStream) { STREAM_printf(outStream, "<"); } static void PRINT_writeDPairEnd(WordPtr outStream) { STREAM_printf(outStream, ">"); } /*************************************************************************** * Writing out terms corresponding to the builtin constants. * ***************************************************************************/ /* Writing out an integer term to a given output stream */ static void PRINT_writeInt(WordPtr outStream, DF_TermPtr tmPtr) { STREAM_printf(outStream, "%d", DF_intValue(tmPtr)); } /* Writing out a float term to a given output stream */ static void PRINT_writeFloat(WordPtr outStream, DF_TermPtr tmPtr) { STREAM_printf(outStream, "%f", DF_floatValue(tmPtr)); } /* Writing out a string term to a given output stream */ static void PRINT_writeString(WordPtr outStream, DF_TermPtr tmPtr) { STREAM_printf(outStream, "\"%s\"", MCSTR_toCString(DF_strValue(tmPtr))); } /* Writing out a stream constant to a given output stream */ static void PRINT_writeStream(WordPtr outStream, DF_TermPtr tmPtr) { WordPtr stream = DF_streamTabIndex(tmPtr); STREAM_printf(outStream, ""); else STREAM_printf(outStream, "-- \"%s\">", STREAM_getName(stream)); } /**************************************************************************** * Writing out a constant. Use the index into the runtime constant table * * stored in the constant to get the constant name if one exists. If one * * does not exist, i.e. if the constant is a local or hidden one, look for * * it in a list of constants. If it is not in this list, make up a new * * name. Eventually, the name consists of three parts: a generic name for * * hidden constants, a part based on the runtime table index and a part * * based on the universe index. * ****************************************************************************/ /* A structure for maintaining information about local constants encountered while printing; this structure enables the assignment of a unique integer to each runtime symbol table slot for such a constant. */ typedef struct PRINT_ConstList_ *PRINT_ConstList; struct PRINT_ConstList_ { int constInd; int count; PRINT_ConstList next; }; static PRINT_ConstList PRINT_clist = NULL; static int PRINT_lccount = 0; static void PRINT_cleanCList() { PRINT_ConstList tmp; PRINT_lccount = 0; while (PRINT_clist){ tmp = PRINT_clist; PRINT_clist = PRINT_clist -> next; free(tmp); } } /* writing out a hidden (local) constant name; as side effect, a note may be made of a new hidden (local) constant seen during this printing. */ static void PRINT_writeHCName(WordPtr outStream, int constInd, int uc) { PRINT_ConstList lclist = PRINT_clist; while (lclist && (lclist->constInd != constInd)) lclist = lclist->next; if (!lclist) { lclist = (PRINT_ConstList)EM_malloc(sizeof(struct PRINT_ConstList_)); lclist->constInd = constInd; lclist->count = PRINT_lccount++; lclist->next = PRINT_clist; PRINT_clist = lclist; } STREAM_printf(outStream, "", lclist->count, uc); } /* Writing out a constant, hidden or global. */ static void PRINT_writeConst(WordPtr outStream, DF_TermPtr tmPtr) { int constInd = DF_constTabIndex(tmPtr); char* name = AM_cstName(constInd); if (name) STREAM_printf(outStream, "%s", name); else PRINT_writeHCName(outStream, constInd, DF_constUnivCount(tmPtr)); } /**************************************************************************** * Writing out a free variable. Two situations are possible, one where a * * symbolic name is to be produced and the other where the `address' could * * serve as the name. In the first case, if the variable is a query * * variable, then its name from the query is used. Otherwise a new name is * * invented that is distinct from other free term variable names; the * * initial segment of the name guarantees that it will be distinct from * * that of bound variables. * ****************************************************************************/ /* counter used to generate free variable name */ static int PRINT_fvcounter = 1; /* Create a free term variable name; this starts with _ has a standard string prefix and then a digit sequence */ static DF_StrDataPtr PRINT_makeFVarName() { int digits = 0; int i = PRINT_fvcounter; int length; char* cname; DF_StrDataPtr fvname; while(i) { digits++; i = i/10; } length = digits + 3; cname = (char*)EM_malloc(sizeof(char)*length); cname[0] = '_'; cname[1] = 'T'; cname[length-1] = '\0'; i = PRINT_fvcounter; while(i) { cname[digits+1] = (i%10 + '0'); i = i/10; digits--; } PRINT_fvcounter++; fvname = (DF_StrDataPtr)EM_malloc(sizeof(Word)*(MCSTR_numWords(length) + DF_STRDATA_HEAD_SIZE)); DF_mkStrDataHead((MemPtr)fvname); MCSTR_toString((MemPtr)((MemPtr)fvname + DF_STRDATA_HEAD_SIZE), cname, length); free(cname); return fvname; } /* Does a made up name occur in the free term variable table? Clash can only occur with names in the user query */ static Boolean PRINT_nameInFVTab(DF_StrDataPtr name) { int i; for (i = 0; i < PRINT_numQueryVars ; i++){ if (MCSTR_sameStrs(DF_strDataValue(name), DF_strDataValue(IO_freeVarTab[i].varName))) return TRUE; } return FALSE; } /* The main routine for printing out an unbound term variable */ static void PRINT_writeFVar(WordPtr outStream, DF_TermPtr tmPtr) { int fvind = 0; DF_StrDataPtr fvname; //PRINT_names = TRUE; if (PRINT_names) { IO_freeVarTab[IO_freeVarTabTop].rigdes = tmPtr; while (tmPtr != IO_freeVarTab[fvind].rigdes) fvind++; if (fvind == IO_freeVarTabTop) { /* i.e., a free variable not seen before */ if (IO_freeVarTabTop == IO_MAX_FREE_VARS) EM_error(BI_ERROR_TYFVAR_CAP); while(1) {//make a name fvname = PRINT_makeFVarName(); if (!PRINT_nameInFVTab(fvname)) break; free(fvname); } IO_freeVarTab[fvind].varName = fvname; IO_freeVarTabTop++; } STREAM_printf(outStream, MCSTR_toCString(DF_strDataValue(IO_freeVarTab[fvind].varName))); } else { //PRINT_names = FALSE STREAM_printf(outStream, "_%ld", PRINT_makeNumberName(tmPtr)); } } /**************************************************************************** * Routines for writing out bound variables (in lambda abstraction and * * bound variable occurrence) * ****************************************************************************/ /* prefix for bound variables */ static char* PRINT_bvname = "W"; /* a counter for determining the suffix part of bound variables */ static int PRINT_bvcounter = 1; /* A structure for maintaining information about bound variable names */ typedef struct PRINT_BVList_ *PRINT_BVList; struct PRINT_BVList_ { DF_StrDataPtr name; PRINT_BVList next; }; /* the initial list of bound variable names; initialized in SIM_InitIo */ static PRINT_BVList PRINT_bvs = NULL; static void PRINT_cleanBV(PRINT_BVList bv) { free(bv->name); free(bv); } /* releasing the space for bound variables; needed only in case of error exit */ static void PRINT_cleanBVList() { PRINT_BVList tbvl; PRINT_bvcounter = 1; while (PRINT_bvs) { tbvl = PRINT_bvs; PRINT_bvs = PRINT_bvs->next; PRINT_cleanBV(tbvl); } } /**************************************************************************** * Writing out a bound variable * ****************************************************************************/ static void PRINT_writeBVar(WordPtr outStream, DF_TermPtr tmPtr) { int i; int bvind = DF_bvIndex(tmPtr); PRINT_BVList lbvs = PRINT_bvs; for (i = bvind; ((i != 1) && lbvs) ; i--) lbvs = lbvs->next; // Is this checking and the else branch really necessary? // Printing should start from top-level closed terms? if (lbvs) STREAM_printf(outStream, "%s", MCSTR_toCString(DF_strDataValue(lbvs->name))); else STREAM_printf(outStream, "#%d", i); } /**************************************************************************** * Writing out an empty list * ****************************************************************************/ static void PRINT_writeNil(WordPtr outStream) { PRINT_writeNilSymbol(outStream); } /**************************************************************************** * Writing out a non-empty list. * ****************************************************************************/ static void PRINT_writeCons(WordPtr outStream, DF_TermPtr tmPtr, OP_FixityType fx, int prec, OP_TermContext tc) { DF_TermPtr args = DF_consArgs(tmPtr); OP_FixityType consfix = (OP_FixityType)AM_cstFixity(PERV_CONS_INDEX); int consprec = AM_cstPrecedence(PERV_CONS_INDEX); Boolean pparen = PRINT_parenNeeded(consfix, consprec, tc, fx,prec); if (pparen) PRINT_writeLParen(outStream); PRINT_writeTerm(outStream, args, consfix, consprec, OP_LEFT_TERM); PRINT_writeConsSymbol(outStream); do { args++; tmPtr = DF_termDeref(args); if (DF_termTag(tmPtr) != DF_TM_TAG_CONS) break; args = DF_consArgs(tmPtr); PRINT_writeTerm(outStream, args, consfix, consprec, OP_LEFT_TERM); PRINT_writeConsSymbol(outStream); } while(1); PRINT_writeTerm(outStream, tmPtr, consfix, consprec, OP_RIGHT_TERM); if (pparen) PRINT_writeRParen(outStream); } /**************************************************************************** * Writing out an abstraction. * ****************************************************************************/ /* creating a bound variable name with bound variable prefix followed by the*/ /* current bound variable counter value. */ static DF_StrDataPtr PRINT_makeBVarName() { int digits = 0; int i = PRINT_bvcounter; int length; char* cname; DF_StrDataPtr bvname; while(i) { digits++; i = i/10; } length = digits + 2; cname = (char*)EM_malloc(sizeof(char)*length); strcpy(cname, PRINT_bvname); cname[length-1] = '\0'; i = PRINT_bvcounter; while(i) { cname[digits] = (i%10 + '0'); i = i/10; digits--; } PRINT_bvcounter++; bvname = (DF_StrDataPtr)EM_malloc(sizeof(Word)*(MCSTR_numWords(length) + DF_STRDATA_HEAD_SIZE)); DF_mkStrDataHead((MemPtr)bvname); MCSTR_toString((MemPtr)((MemPtr)bvname + DF_STRDATA_HEAD_SIZE), cname, length); free(cname); return bvname; } static void PRINT_writeAbstBinders(WordPtr outStream, int nabs) { DF_StrDataPtr bvname; PRINT_BVList tmpbvs; while(nabs > 0) { nabs--; while(1) {//make a bvname not in FV table bvname = PRINT_makeBVarName(); if (!PRINT_nameInFVTab(bvname)) break; free(bvname); } //record the name into the head of the current bvlist tmpbvs = (PRINT_BVList)EM_malloc(sizeof(struct PRINT_BVList_)); tmpbvs->name = bvname; tmpbvs->next = PRINT_bvs; PRINT_bvs = tmpbvs; //write out binder STREAM_printf(outStream, "%s", MCSTR_toCString(DF_strDataValue(bvname))); PRINT_writeInfixLam(outStream); } } static void PRINT_writeAbst(WordPtr outStream, DF_TermPtr tmPtr, OP_FixityType fx, int prec, OP_TermContext tc) { int numabs = 0; Boolean pparen = PRINT_parenNeeded(OP_LAM_FIXITY,OP_LAM_PREC,tc,fx,prec); PRINT_BVList tmpbvs; int tmpbvc = PRINT_bvcounter; if (pparen) PRINT_writeLParen(outStream); while (DF_isLam(tmPtr)){ numabs += DF_lamNumAbs(tmPtr); tmPtr = DF_termDeref(DF_lamBody(tmPtr)); } PRINT_writeAbstBinders(outStream, numabs); PRINT_writeTerm(outStream, tmPtr, OP_LAM_FIXITY,OP_LAM_PREC,OP_RIGHT_TERM); if (pparen) PRINT_writeRParen(outStream); while (numabs > 0) { numabs--; tmpbvs = PRINT_bvs; PRINT_bvs = PRINT_bvs->next; PRINT_cleanBV(tmpbvs); } PRINT_bvcounter = tmpbvc; } /**************************************************************************** * WRITING OUT AN APPLICATION * * * * Note that it is assumed that nested application structures are flattened * * during the full normalization process. * ****************************************************************************/ /* Getting the fixity and precedence for the head of an application. Assume the pointer to the term head is already dereferenced. */ static void PRINT_getHeadInfo(DF_TermPtr hdPtr, OP_FixityType *fx, int* prec) { int cstInd; switch (DF_termTag(hdPtr)) { case DF_TM_TAG_CONST: cstInd = DF_constTabIndex(hdPtr); if (AM_cstName(cstInd)) { *fx = (OP_FixityType)AM_cstFixity(cstInd); *prec = AM_cstPrecedence(cstInd); } else { *fx = OP_NONE; *prec = 0; } break; case DF_TM_TAG_VAR: *fx = OP_NONE; *prec = OP_MINPREC; break; case DF_TM_TAG_BVAR: *fx = OP_NONE; *prec = OP_MINPREC; break; } } /* Writing out a term with a prefix operator as head; we use the knowledge that the operator must be a constant here and that the pointer to it is fully dereferenced */ static void PRINT_writePrefixTerm(WordPtr outStream, DF_TermPtr head, OP_FixityType opfx, int opprec, OP_TermContext tc, OP_FixityType fx,int prec, DF_TermPtr args) { Boolean pparen = PRINT_parenNeeded(opfx, opprec, tc, fx, prec); if (pparen) PRINT_writeLParen(outStream); PRINT_writeConst(outStream, head); PRINT_writeSpace(outStream, 1); PRINT_writeTerm(outStream, args, opfx, opprec, OP_RIGHT_TERM); if (pparen) PRINT_writeRParen(outStream); } static void PRINT_writeInfixTerm(WordPtr outStream, DF_TermPtr head, OP_FixityType opfx, int opprec, OP_TermContext tc, OP_FixityType fx, int prec, DF_TermPtr args) { Boolean pparen = PRINT_parenNeeded(opfx, opprec, tc, fx, prec); if(pparen) PRINT_writeLParen(outStream); PRINT_writeTerm(outStream, args, opfx, opprec, OP_LEFT_TERM); PRINT_writeSpace(outStream, 1); PRINT_writeConst(outStream, head); PRINT_writeSpace(outStream, 1); PRINT_writeTerm(outStream, args+1, opfx, opprec, OP_RIGHT_TERM); if (pparen) PRINT_writeRParen(outStream); } static void PRINT_writePostfixTerm(WordPtr outStream, DF_TermPtr head, OP_FixityType opfx, int opprec, OP_TermContext tc,OP_FixityType fx,int prec, DF_TermPtr args) { Boolean pparen = PRINT_parenNeeded(opfx, opprec, tc, fx, prec); if(pparen) PRINT_writeLParen(outStream); PRINT_writeTerm(outStream, args, opfx, opprec, OP_LEFT_TERM); PRINT_writeSpace(outStream, 1); PRINT_writeConst(outStream, head); if (pparen) PRINT_writeRParen(outStream); } /* Main routine for writing out an application term */ static void PRINT_writeApp(WordPtr outStream, DF_TermPtr tmPtr, OP_FixityType infx, int inprec, OP_TermContext tc) { DF_TermPtr head = DF_termDeref(DF_appFunc(tmPtr)); DF_TermPtr args = DF_appArgs(tmPtr); int arity = DF_appArity(tmPtr); Boolean pparen = PRINT_parenNeeded(OP_APP_FIXITY, OP_APP_PREC, tc, infx, inprec); OP_FixityType fix = 0; int prec = 0; HN_hnorm(tmPtr); PRINT_getHeadInfo(AM_head, &fix, &prec); switch(fix){ case OP_PREFIX: case OP_PREFIXR: if (arity == 1) { pparen = FALSE; PRINT_writePrefixTerm(outStream, head, fix, prec, tc, infx, inprec, args); } else { if (pparen) PRINT_writeLParen(outStream); PRINT_writePrefixTerm(outStream, head, fix, prec, OP_LEFT_TERM, OP_APP_FIXITY, OP_APP_PREC, args); } arity--; args++; break; case OP_INFIX: case OP_INFIXL: case OP_INFIXR: if (arity == 2) { pparen = FALSE; PRINT_writeInfixTerm(outStream, head, fix, prec, tc, infx, inprec, args); } else { if (pparen) PRINT_writeLParen(outStream); PRINT_writeInfixTerm(outStream, head, fix, prec, OP_LEFT_TERM, OP_APP_FIXITY, OP_APP_PREC, args); } arity -= 2; args += 2; break; case OP_POSTFIX: case OP_POSTFIXL: if (arity == 1) { pparen = FALSE; PRINT_writePostfixTerm(outStream, head, fix, prec, tc, infx, inprec, args); } else { if (pparen) PRINT_writeLParen(outStream); PRINT_writePostfixTerm(outStream, head, fix, prec, OP_LEFT_TERM, OP_APP_FIXITY, OP_APP_PREC, args); } break; case OP_NONE: if (pparen) PRINT_writeLParen(outStream); PRINT_writeTerm(outStream,head,OP_APP_FIXITY,OP_APP_PREC,OP_LEFT_TERM); break; } /*switch*/ /* print the arguments (if any) of the application */ while (arity > 0) { PRINT_writeSpace(outStream, 1); PRINT_writeTerm(outStream, args, OP_APP_FIXITY, OP_APP_PREC, OP_RIGHT_TERM); args++; arity--; } if (pparen) PRINT_writeRParen(outStream); } /***************************************************************************** * The main routine for writing out a term; this is called by the interface * * routines to do the real job of printing. * *****************************************************************************/ static void PRINT_writeTerm(WordPtr outStream, DF_TermPtr tmPtr, OP_FixityType infx, int inprec, OP_TermContext tc) { tmPtr = DF_termDeref(tmPtr); switch (DF_termTag(tmPtr)) { case DF_TM_TAG_INT: PRINT_writeInt(outStream, tmPtr); break; case DF_TM_TAG_FLOAT: PRINT_writeFloat(outStream, tmPtr); break; case DF_TM_TAG_STR: PRINT_writeString(outStream, tmPtr); break; case DF_TM_TAG_STREAM: PRINT_writeStream(outStream, tmPtr); break; case DF_TM_TAG_CONST: PRINT_writeConst(outStream, tmPtr); break; case DF_TM_TAG_VAR: PRINT_writeFVar(outStream, tmPtr); break; case DF_TM_TAG_BVAR: PRINT_writeBVar(outStream, tmPtr); break; case DF_TM_TAG_NIL: PRINT_writeNil(outStream); break; case DF_TM_TAG_CONS: PRINT_writeCons(outStream, tmPtr, infx, inprec, tc); break; case DF_TM_TAG_LAM: PRINT_writeAbst(outStream, tmPtr, infx, inprec, tc); break; case DF_TM_TAG_APP: PRINT_writeApp(outStream, tmPtr, infx, inprec, tc); break; } /* switch */ } /* Printing a term to a specified output stream; names will be invented for free variables if the boolean variable PRINT_names is set. */ void PRINT_fPrintTerm(WordPtr outStream, DF_TermPtr tmPtr) { HN_lnorm(tmPtr); PRINT_writeTerm(outStream, tmPtr, OP_NONE, 0, OP_WHOLE_TERM); } /* Printing routine for debugging */ void PRINT_printTerm(DF_TermPtr tmPtr) { PRINT_fPrintTerm(STREAM_stdout, tmPtr); STREAM_printf(STREAM_stdout, "\n"); } /* printing an answer substitution pair */ static void PRINT_printSubsPair(WordPtr outStream, int ind) { DF_TermPtr tmPtr; char *varName = MCSTR_toCString(DF_strDataValue(IO_freeVarTab[ind].varName)); /* print the variable name if it is not an anonymous variable */ if (strcmp(varName, "_") != 0) { STREAM_printf(outStream, varName); /* Print the equals sign */ PRINT_writeEquals(outStream); /* Print the binding of the variable */ tmPtr = IO_freeVarTab[ind].rigdes; HN_lnorm(tmPtr); PRINT_writeTerm(outStream, tmPtr, OP_NONE, 0, OP_WHOLE_TERM); } } void PRINT_showAnswerSubs() { int i; PRINT_names = TRUE; for (i = 0; i < PRINT_numQueryVars; i++) { PRINT_printSubsPair(STREAM_stdout, i); STREAM_printf(STREAM_stdout, "\n"); } } /* Printing a disagreement pair to a specified output stream */ static void PRINT_printDPair(WordPtr outStream, DF_DisPairPtr dpair) { DF_TermPtr tmPtr; PRINT_writeDPairStart(outStream); tmPtr = DF_disPairFirstTerm(dpair); HN_lnorm(tmPtr); PRINT_writeTerm(outStream, tmPtr, OP_NONE, 0, OP_WHOLE_TERM); PRINT_writeComma(outStream); PRINT_writeSpace(outStream, 1); tmPtr = DF_disPairSecondTerm(dpair); HN_lnorm(tmPtr); PRINT_writeTerm(outStream, tmPtr, OP_NONE, 0, OP_WHOLE_TERM); PRINT_writeDPairEnd(outStream); } void PRINT_showDisAgreeList() { DF_DisPairPtr liveList = AM_llreg; while (DF_isNEmpDisSet(liveList)) { PRINT_printDPair(STREAM_stdout, liveList); liveList = DF_disPairNext(liveList); STREAM_printf(STREAM_stdout, "\n"); } } void PRINT_setQueryFreeVariables() { PRINT_numQueryVars = IO_freeVarTabTop; } /* Use this function to reset the top of the free variable table after a read; this is logical and also needed to avoid trying to release print name space accidentally at some other point. */ void PRINT_resetFreeVarTab() { IO_freeVarTabTop = PRINT_numQueryVars; } void PRINT_resetPrintState() { /* release space for term variables created during printing */ while (IO_freeVarTabTop > PRINT_numQueryVars){ IO_freeVarTabTop--; free(IO_freeVarTab[IO_freeVarTabTop].varName); } /* reset counters used in names of anonymous term and type variables */ PRINT_fvcounter = 1; /* free space for information created for local consts and reset counter */ PRINT_cleanCList(); /* free space for information created for bound vars and reset counter */ PRINT_cleanBVList(); } Boolean PRINT_queryHasVars() { int i = PRINT_numQueryVars - 1; while (!(i < 0) && (strcmp(MCSTR_toCString(DF_strDataValue(IO_freeVarTab[i].varName)), "_") == 0)) i--; if (i < 0) return FALSE; else return TRUE; }