summaryrefslogtreecommitdiff
path: root/src/runtime/c/teyjus/simulator/printterm.c
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2012-07-31 15:16:04 +0000
committerkr.angelov <kr.angelov@gmail.com>2012-07-31 15:16:04 +0000
commit83b321d862472f31c0c9f7feca8360ad5bfe8a75 (patch)
tree0f0ef20ad78e25b320013c7bb160211a8612d4e9 /src/runtime/c/teyjus/simulator/printterm.c
parent314662dd09d5d1480007faa79258b0e93cc2aa59 (diff)
An initial import of the teyjus source code in the C runtime for GF. The two runtime are still not connected but the source code compiles.
Diffstat (limited to 'src/runtime/c/teyjus/simulator/printterm.c')
-rw-r--r--src/runtime/c/teyjus/simulator/printterm.c814
1 files changed, 814 insertions, 0 deletions
diff --git a/src/runtime/c/teyjus/simulator/printterm.c b/src/runtime/c/teyjus/simulator/printterm.c
new file mode 100644
index 000000000..2fbe03fd2
--- /dev/null
+++ b/src/runtime/c/teyjus/simulator/printterm.c
@@ -0,0 +1,814 @@
+//////////////////////////////////////////////////////////////////////////////
+//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 <http://www.gnu.org/licenses/>. //
+//////////////////////////////////////////////////////////////////////////////
+/****************************************************************************
+ * *
+ * 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 <lc- and end 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 <stdlib.h>
+#include <string.h>
+#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 <stdio.h>
+
+/* 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;
+ }
+ }
+ } 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;
+ }
+ }
+ }
+ }
+ 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_writeLam(WordPtr outStream, int numabs)
+{ STREAM_printf(outStream, "lam(%d, ", numabs); }
+
+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, "<stream ");
+ if (stream == STREAM_ILLEGAL) STREAM_printf(outStream, "-- closed>");
+ 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, "<lc-%d-%d>", 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);
+ DF_TermPtr arg;
+ 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;
+ int prec;
+
+ 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;
+
+}