//////////////////////////////////////////////////////////////////////////////
//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;
}