C:/Users/Dennis/src/lang/Life_start/Life/life-1.02/source/print.c

Go to the documentation of this file.
00001 /* Copyright 1991 Digital Equipment Corporation.
00002 ** All Rights Reserved.
00003 *****************************************************************/
00004 /*      $Id: print.c,v 1.4 1995/01/14 00:27:20 duchier Exp $     */
00005 
00006 #ifndef lint
00007 static char vcid[] = "$Id: print.c,v 1.4 1995/01/14 00:27:20 duchier Exp $";
00008 #endif /* lint */
00009 
00010 #define DOTDOT ": "   /*  RM: Dec 14 1992, should be " : "  */
00011 
00012 
00013 #include "extern.h"
00014 #include "trees.h"
00015 #include "types.h"
00016 #include "memory.h"
00017 #include "print.h"  
00018 #include "modules.h"  /*  RM: Jan 13 1993  */
00019 #include "login.h"
00020 
00021 
00022 
00023 ptr_node printed_pointers, pointer_names;
00024 
00025 long print_depth=PRINT_DEPTH;
00026 long indent=FALSE;
00027 long const_quote=TRUE;
00028 long write_resids=FALSE;
00029 long write_canon=FALSE;
00030 long write_stderr=FALSE;
00031 long write_corefs=TRUE;
00032 
00033 long gen_sym_counter;
00034 long page_width=PAGE_WIDTH;
00035 
00036 long display_persistent=FALSE;
00037   
00038 char *no_name="pointer";
00039 char *name="symbol";
00040 char *buffer;
00041 char seg_format[PRINT_POWER+4];
00042 
00043 item pretty_things[PRETTY_SIZE];
00044 ptr_item indx;
00045 
00046 /* Used to distinguish listings from other writes */
00047 static long listing_flag;
00048 
00049 /* Used to list function bodies in a nice way */
00050 /* Only valid if listing_flag==TRUE */
00051 static long func_flag;
00052 
00053 /* The output stream for a given print command is put in here */
00054 /* This will be set to stdout, to stderr, or to output_stream */
00055 FILE *outfile;
00056 
00057 void pretty_psi_term();
00058 void pretty_attr();
00059 void pretty_tag_or_psi_term();
00060 
00061 /* Precedence of the comma and colon operators (or 0 if none exists) */
00062 #define COMMA_PREC ((commasym->op_data)?(commasym->op_data->precedence):0)
00063 #define COLON_PREC ((colonsym->op_data)?(colonsym->op_data->precedence):0)
00064 
00065 
00066 /* Initialize size of single segment of split printing.  Wild_Life         */
00067 /* integers are represented as REALS, and therefore can have higher        */
00068 /* precision than the machine integers.  They will be printed in segments. */
00069 void init_print()
00070 {
00071   sprintf(seg_format,"%%0%ldd",PRINT_POWER);
00072 }
00073 
00074 
00075 /* Generate a nice-looking new variable name. */
00076 char *heap_nice_name()
00077 {
00078   string tmp1,tmp2;
00079   long g,len,leading_a;
00080 
00081   g= ++gen_sym_counter;
00082   len=2;
00083   strcpy(tmp2,"");
00084   do {
00085     g--;
00086     /* Prefix one character to tmp2: */
00087     sprintf(tmp1,"%c",g%26+'A');
00088     strcat(tmp1,tmp2);
00089     strcpy(tmp2,tmp1);
00090     g=g/26;
00091     len++;
00092   } while (g>0 && len<STRLEN);
00093   if (len>=STRLEN)
00094     perr("Variable name too long -- the universe has ceased to exist.");
00095 
00096   strcpy(tmp1,"_");
00097   strcat(tmp1,tmp2);
00098   
00099   return heap_copy_string(tmp1);
00100 }
00101 
00102 
00103 /* Make sure that the new variable name does not exist in the var_tree. */
00104 /* (This situation should be rare.) */
00105 /* Time to print a term is proportional to product of var_tree size and */
00106 /* number of tags in the term.  This may become large in pathological   */
00107 /* cases. */
00108 GENERIC unique_name()
00109 {
00110   char *name;
00111 
00112   do name=heap_nice_name(); while (find(strcmp,name,var_tree));
00113 
00114   return (GENERIC) name;
00115 }
00116 
00117 
00118 
00119 /******** STR_TO_INT(s) 
00120   Converts the string S into a positive integer.
00121   Returns -1 if s is not an integer.
00122 */
00123 long str_to_int(s)
00124 char *s;
00125 {
00126   long v=0;
00127   char c;
00128 
00129   c=(*s);
00130   if (c==0)
00131     v= -1;
00132   else {
00133     while (DIGIT(c)) {
00134       v=v*10+(c-'0');
00135       s++;
00136       c=(*s);
00137     }
00138     if (c!=0) v= -1;
00139   }
00140 
00141   return v;
00142 }
00143 
00144 
00145 
00146 /******** PRINT_BIN(b)
00147   Print the integer B under binary format (currently 26 is printed **-*-).
00148   This is used to print the binary codes used in type encryption.
00149 */
00150 void print_bin(b)
00151 long b;
00152 {
00153   long p;
00154 
00155   for (p=INT_SIZE;p--;p>0) 
00156   {
00157     fprintf(outfile,(b&1?"X":" "));
00158     b = b>>1;
00159   }
00160 }
00161 
00162 
00163 
00164 /******** PRINT_CODE(s,c)
00165   Print a binary code C to a stream s (as used in type encoding).
00166 */
00167 void print_code(s,c)
00168 FILE *s;
00169 ptr_int_list c;
00170 {
00171   outfile=s;
00172 
00173   if (c==NOT_CODED)
00174     fprintf(outfile,"  (not coded) ");
00175   else {
00176     fprintf(outfile,"  [");
00177     while (c) {
00178       print_bin(c->value);
00179       c=c->next;
00180     }
00181     fprintf(outfile,"]");
00182   }
00183 }
00184 
00185 
00186 void go_through();
00187 
00188 
00189 
00190 /******** PRINT_OPERATOR_KIND(s,kind)
00191   Print the kind of an operator.
00192 */
00193 void print_operator_kind(s,kind)
00194 FILE *s;
00195 operator kind;
00196 {
00197   switch (kind) {
00198   case xf:
00199     fprintf(s,"xf");
00200     break;
00201   case fx:
00202     fprintf(s,"fx");
00203     break;
00204   case yf:
00205     fprintf(s,"yf");
00206     break;
00207   case fy:
00208     fprintf(s,"fy");
00209     break;
00210   case xfx:
00211     fprintf(s,"xfx");
00212     break;
00213   case xfy:
00214     fprintf(s,"xfy");
00215     break;
00216   case yfx:
00217     fprintf(s,"yfx");
00218     break;
00219   default:
00220     fprintf(s,"illegal");
00221     break;
00222   }
00223 }
00224 
00225 
00226 
00227 /******** CHECK_POINTER(p)
00228   Count the number of times address P has been encountered in the current
00229   psi-term being printed. If it is more than once then a tag will have to
00230   be used.
00231   If P has not already been seen, then explore the psi_term it points to.
00232 */
00233 void check_pointer(p)
00234 ptr_psi_term p;
00235 {
00236   ptr_node n;
00237   
00238   if (p) {
00239     deref_ptr(p);
00240     n=find(intcmp,p,pointer_names);
00241     if (n==NULL) {
00242       heap_insert(intcmp,p,&pointer_names,NULL);
00243       go_through(p);
00244     }
00245     else
00246       n->data=(GENERIC)no_name;
00247   }
00248 }
00249 
00250 
00251 
00252 /******** GO_THROUGH_TREE(t)
00253   Explore all the pointers in the attribute tree T.
00254   Pointers that occur more than once will need a tag.
00255 */
00256 void go_through_tree(t)
00257 ptr_node t;
00258 {
00259   if (t) {
00260     go_through_tree(t->left);
00261     check_pointer((ptr_psi_term)t->data);
00262     go_through_tree(t->right);
00263   }
00264 }
00265 
00266 
00267 
00268 /******** GO_THROUGH(t)
00269   This routine goes through all the sub_terms of psi_term T to determine which
00270   pointers need to have names given to them for printing because they are
00271   referred to elsewhere. T is a dereferenced psi_term.
00272 */
00273 void go_through(t)
00274 ptr_psi_term t;
00275 {
00276   ptr_list l;
00277 
00278 
00279   go_through_tree(t->attr_list);
00280 
00281   /*
00282   if(r=t->resid)
00283     while(r) {
00284       if(r->goal->pending)
00285         go_through(r->goal->a);
00286       r=r->next;
00287     } */
00288 }
00289 
00290 
00291 
00292 /******** INSERT_VARIABLES(vars,force)
00293   This routine gives the name of the query variable to the corresponding
00294   pointer in the POINTER_NAMES.
00295   If FORCE is TRUE then variables will be printed as TAGS, even if not
00296   referred to elsewhere.
00297 */
00298 void insert_variables(vars,force)
00299 ptr_node vars;
00300 long force;
00301 {
00302   ptr_psi_term p;
00303   ptr_node n;
00304   
00305   if(vars) {
00306     insert_variables(vars->right,force);
00307     p=(ptr_psi_term )vars->data;
00308     deref_ptr(p);
00309     n=find(intcmp,p,pointer_names);
00310     if (n)
00311       if (n->data || force)
00312         n->data=(GENERIC)vars->key;
00313     insert_variables(vars->left,force);
00314   }
00315 }
00316 
00317 
00318 
00319 /******** FORBID_VARIABLES
00320   This inserts the value of the dereferenced variables into the
00321   PRINTED_POINTERS tree, so that they will never be printed as
00322   NAME:value inside a psi-term.
00323   Each variable is printed as NAME = VALUE by the PRINT_VARIABLES routine.
00324 */
00325 void forbid_variables(n)
00326 ptr_node n;
00327 {
00328   ptr_psi_term v;
00329   
00330   if(n) {
00331     forbid_variables(n->right);
00332     v=(ptr_psi_term )n->data;
00333     deref_ptr(v);
00334     heap_insert(intcmp,v,&printed_pointers,n->key);
00335     forbid_variables(n->left);
00336   }
00337 }
00338 
00339 
00340 
00341 
00342 /******************************************************************************
00343   PRINTING ROUTINES.
00344 
00345   These routines allow the correct printing in minimal form of a set of
00346   possibly cyclic psi-terms with coreferences from one to another.
00347 
00348   First the term to be printed is explored to locate any cyclic terms or
00349   coreferences. Then is printed into memory where is it formatted to fit
00350   within PAGE_WIDTH of the output page. Then it is effectively printed to the
00351   output stream.
00352 
00353  *****************************************************************************/
00354 
00355 
00356 
00357 /* Printing into memory involves the use of an array containing a TAB
00358 position on which to align things then a string to print. The routine
00359 WORK_OUT_LENGTH tries (by trial and error) to print the psi_term into
00360 PAGE_WIDTH columns by inserting line feeds whereever possible */
00361 
00362 
00363 /* Does the work of prettyf and prettyf_quote */
00364 /* The q argument is a flag telling whether to quote or not. */
00365 void prettyf_inner(s,q,c)
00366 char *s;
00367 long q;
00368 char c; /* the quote character */
00369 {
00370   char *sb=buffer;
00371 
00372   if (indent) {
00373     while (*sb) sb++;
00374     if (q) { *sb = c; sb++; }
00375     while (*s) {
00376       if (q && *s==c) { *sb = *s; sb++; }
00377       *sb = *s; sb++; s++;
00378     }
00379     if (q) { *sb = c; sb++; }
00380     *sb=0;
00381   }
00382   else {
00383     if (q) putc(c,outfile);
00384     while (*s) {
00385       if (q && *s==c) { putc(*s,outfile); }
00386       putc(*s,outfile);
00387       s++;
00388     }
00389     if (q) putc(c,outfile);
00390   }
00391 }
00392 
00393 
00394 /* Return TRUE iff s starts with a non-lowercase character. */
00395 long starts_nonlower(s)
00396 char *s;
00397 {
00398   return (*s && !LOWER(s[0]));
00399 }
00400 
00401 /* Return TRUE iff s contains a character that is not alphanumeric. */
00402 long has_non_alpha(s)
00403 char *s;
00404 {
00405   while (*s) {
00406     if (!ISALPHA(*s)) return TRUE;
00407     s++;
00408   }
00409   return FALSE;
00410 }
00411 
00412 /* Return TRUE iff s contains only SYMBOL characters. */
00413 long all_symbol(s)
00414 char *s;
00415 {
00416   while (*s) {
00417     if (!SYMBOL(*s)) return FALSE;
00418     s++;
00419   }
00420   return TRUE;
00421 }
00422 
00423 /* Return TRUE if s represents an integer. */
00424 long is_integer(s)
00425 char *s;
00426 {
00427   if (!*s) return FALSE;
00428   if (*s=='-') s++;
00429   while (*s) {
00430     if (!DIGIT(*s)) return FALSE;
00431     s++;
00432   }
00433   return TRUE;
00434 }
00435 
00436 /* Return TRUE if s does not have to be quoted, i.e., */
00437 /* s starts with '_' or a lowercase symbol and contains */
00438 /* all digits, letters, and '_'. */
00439 long no_quote(s)
00440 char *s;
00441 {
00442   if (!s[0]) return FALSE;
00443 
00444   if (s[0]=='%') return FALSE;
00445   if (SINGLE(s[0]) && s[1]==0) return TRUE;
00446   if (s[0]=='_'    && s[1]==0) return FALSE;
00447   if (all_symbol(s)) return TRUE;
00448 
00449   if (!LOWER(s[0])) return FALSE;
00450   s++;
00451   while (*s) {
00452     if (!ISALPHA(*s)) return FALSE;
00453     s++;
00454   }
00455   return TRUE;
00456 }
00457   
00458 
00459 
00460 /******** PRETTYF(s)
00461   This prints the string S into the BUFFER.
00462 */
00463 void prettyf(s)
00464 char *s;
00465 {
00466   prettyf_inner(s,FALSE,'\'');
00467 }
00468 
00469 
00470 void prettyf_quoted_string(s)
00471 char *s;
00472 {
00473   prettyf_inner(s,const_quote,'"');
00474 }
00475 
00476 
00477 
00478 /****** PRETTYF_QUOTE(s)
00479   This prints the string S into the buffer.
00480   S is surrounded by quotes if:
00481     (1) const_quote==TRUE, and
00482     (2) S does not represent an integer, and
00483     (2) S contains a non-alphanumeric character
00484         or starts with a non-lowercase character, and
00485     (3) if S is longer than one character, it is not true that S has only
00486         non-SINGLE SYMBOL characters (in that case, S does not need quotes),and
00487     (4) if S has only one character, it is a single space or underscore.
00488   When S is surrounded by quotes, a quote inside S is printed as two quotes.
00489 */
00490 void prettyf_quote(s)
00491 char *s;
00492 {
00493   prettyf_inner(s, const_quote && !no_quote(s), '\'');
00494 }
00495 /*
00496                   !is_integer(s) &&
00497                   (starts_nonlower(s) || has_non_alpha(s)) &&
00498                   ((int)strlen(s)>1
00499                   ? !all_symbol(s):
00500                     ((int)strlen(s)==1
00501                     ? (s[0]==' ' || s[0]=='_' || UPPER(s[0]) || DIGIT(s[0]))
00502                     : TRUE
00503                     )
00504                   ),
00505                 '\'');
00506 */
00507 
00508 
00509 /******** END_TAB()
00510   Mark the end of an item.
00511   Copy the item's string into global space and point to the next item.
00512 */
00513 void end_tab()
00514 {
00515   if (indent) {
00516     indx->str=(char *)heap_alloc(strlen(buffer)+1);
00517     strcpy(indx->str,buffer);
00518     indx++;
00519     *buffer=0;
00520   }
00521 }
00522 
00523 
00524 
00525 /******** MARK_TAB(t)
00526   Mark a tabbing position T.
00527   Make the current item point to tabbing position T.
00528 */
00529 void mark_tab(t)
00530 ptr_tab_brk t;
00531 {
00532   end_tab();
00533   indx->tab=t;
00534 }
00535 
00536 
00537 
00538 /******** NEW_TAB(t)
00539   Create a new tabulation mark T.
00540 */
00541 void new_tab(t)
00542 ptr_tab_brk *t;
00543 {
00544   (*t)=HEAP_ALLOC(tab_brk);
00545   (*t)->broken=FALSE;
00546   (*t)->printed=FALSE;
00547   (*t)->column=0;
00548 }
00549 
00550 
00551 /* Utility to correctly handle '\n' inside strings being printed: */
00552 /* What is the column after printing str, when the starting position */
00553 /* is pos? */
00554 /* Same as strlen, except that the length count starts with pos and */
00555 /* \n resets it. */
00556 long strpos(pos, str)
00557 long pos;
00558 char *str;
00559 {
00560   while (*str) {
00561     if (str[0]=='\n') pos=0; else pos++;
00562     str++;
00563   }
00564   return pos;
00565 }
00566 
00567 
00568 /******** WORK_OUT_LENGTH()
00569   Calculate the number of blanks before each tabulation.
00570   Insert line feeds until it all fits into PAGE_WIDTH columns.
00571   This is done by a trial and error mechanism.
00572 */
00573 void work_out_length()
00574 {
00575   ptr_item i;
00576   long done=FALSE;
00577   long pos;
00578   ptr_tab_brk worst,root;
00579   long w;
00580   
00581   while(!done) {
00582     
00583     pos=0;
00584     done=TRUE;
00585     
00586     w= -1;
00587     worst=NULL;
00588     root=NULL;
00589     
00590     for(i=pretty_things+1;(unsigned long)i<(unsigned long)indx;i++) {
00591       
00592       if(i->tab->broken && i->tab->printed) {
00593         pos=i->tab->column;
00594         root=NULL;
00595       }
00596       
00597       if(!i->tab->printed) i->tab->column=pos;
00598       
00599       if(!(i->tab->broken))
00600         if(!root || (root && (root->column)>=(i->tab->column)))
00601           root=i->tab;
00602       
00603       /* pos=pos+strlen(i->str); */
00604       pos=strpos(pos,i->str);
00605       i->tab->printed=TRUE;
00606       
00607       if(pos>page_width)
00608         done=FALSE;
00609       
00610       if(pos>w) {
00611         w=pos;
00612         worst=root;
00613       }
00614     }
00615 
00616     for(i=pretty_things+1;(unsigned long)i<(unsigned long)indx;i++)
00617       i->tab->printed=FALSE;
00618     
00619     if(!done)      
00620       if(worst)
00621         worst->broken=TRUE;
00622       else
00623         done=TRUE;
00624   }
00625 }
00626 
00627 
00628 
00629 /*** RM: Dec 11 1992  (START) ***/
00630 
00631 /******** COUNT_FEATURES(t)
00632   Return the number of features of a tree.
00633   */
00634 
00635 long count_features(t)
00636 
00637      ptr_node t;
00638 {
00639   long c=0;
00640   if(t) {
00641     if(t->left)
00642       c+=count_features(t->left);
00643     c++;
00644     if(t->right)
00645       c+=count_features(t->right);
00646   }
00647   return c;
00648 }
00649 
00650 
00651 
00652 /******** CHECK_LEGAL_CONS(t,t_type)
00653 
00654   Check that T is of type T_TYPE, that it has exactly the attributes '1' and
00655   '2' and that the 2nd is either nil or also long check_legal_cons(t,t_type)
00656 */
00657 
00658 long check_legal_cons(t,t_type)
00659      ptr_psi_term t;
00660      ptr_definition t_type;
00661      
00662 {
00663   return (t->type==t_type &&
00664           count_features(t->attr_list)==2 &&
00665           find(featcmp,one,t->attr_list) &&
00666           find(featcmp,two,t->attr_list));
00667 }
00668 
00669 /*** RM: Dec 11 1992  (END) ***/
00670 
00671     
00672 
00673 /******** PRETTY_LIST(t,depth)
00674   Pretty print a list.
00675   On entry we know that T is a legal CONS pair, so we can immediately print
00676   the opening bracket etc...
00677 */
00678 void pretty_list(t,depth)
00679 ptr_psi_term t;
00680 long depth;
00681 {
00682   ptr_tab_brk new;
00683   ptr_list l;
00684   ptr_definition t_type;
00685   ptr_psi_term car,cdr;
00686   ptr_node n,n2;
00687   char *tag=NULL;
00688   char colon[2],sep[4],end[3];
00689   long list_depth; /* 20.8 */
00690   long done=FALSE; /* RM: Dec 11 1992 */
00691   
00692   
00693   strcpy(sep,"ab");
00694   strcpy(end,"cd");
00695   t_type=t->type;
00696   
00697   if (overlap_type(t_type,alist)) {
00698     if (!equal_types(t_type,alist)) {
00699       pretty_symbol(t_type->keyword);  /*  RM: Jan 13 1993  */
00700       prettyf(DOTDOT);
00701     }
00702     prettyf("[");
00703     strcpy(sep,",");
00704     strcpy(end,"]");
00705   }
00706 
00707   /*
00708     else if (equal_types(t_type,conjunction)) {
00709       prettyf("(");
00710       strcpy(sep,DOTDOT);
00711       strcpy(end,")");
00712       }
00713       */
00714   
00715   else if (equal_types(t_type,disjunction)) {
00716     prettyf("{");
00717     strcpy(sep,";");
00718     strcpy(end,"}");
00719   }
00720 
00721   
00722   /* RM: Dec 11 1992  New code for printing lists */
00723   
00724   new_tab(&new);
00725   list_depth=0; /* 20.8 */
00726   while(!done) {
00727     mark_tab(new);
00728     if(list_depth==print_depth)
00729       prettyf("...");
00730 
00731     get_two_args(t->attr_list,&car,&cdr);
00732     deref_ptr(car);
00733     deref_ptr(cdr);
00734 
00735     
00736     if(list_depth<print_depth)
00737       pretty_tag_or_psi_term(car,COMMA_PREC,depth);
00738     
00739     /* Determine how to print the CDR */
00740     n=find(intcmp,cdr,pointer_names);
00741     
00742     if(n && n->data) {
00743       prettyf("|");
00744       pretty_tag_or_psi_term(cdr,MAX_PRECEDENCE+1,depth);
00745       done=TRUE;
00746     }
00747     else
00748       if(( /*  RM: Feb  1 1993  */
00749           (cdr->type==nil && overlap_type(t_type,alist)) ||
00750           (cdr->type==disj_nil && t_type==disjunction)
00751           )
00752           && !cdr->attr_list)
00753         done=TRUE;
00754       else
00755         if(!check_legal_cons(cdr,t_type)) {
00756           prettyf("|");
00757           pretty_tag_or_psi_term(cdr,MAX_PRECEDENCE+1,depth);
00758           done=TRUE;
00759         }
00760         else {
00761           if(list_depth<print_depth)
00762             prettyf(sep);
00763           t=cdr;
00764         }
00765     
00766     list_depth++;
00767   }
00768   
00769   prettyf(end);
00770 }
00771 
00772 
00773 
00774 /******** PRETTY_TAG_OR_PSI_TERM(p,depth)
00775   Print a psi-term, but first precede it with the appropriate TAG. Don't
00776   reprint the same psi-term twice.
00777 */
00778 void pretty_tag_or_psi_term(p, sprec, depth)
00779 ptr_psi_term p;
00780 long sprec;
00781 long depth;
00782 {
00783   ptr_node n,n2;
00784 
00785   if (p==NULL) {
00786     prettyf("<VOID>");
00787     return;
00788   }
00789   if (FALSE /*depth>=print_depth*/) { /* 20.8 */
00790     prettyf("...");
00791     return;
00792   }
00793   deref_ptr(p);
00794   
00795   n=find(intcmp,p,pointer_names);
00796   
00797   if (n && n->data) {
00798     if (n->data==(GENERIC)no_name) {
00799       n->data=unique_name();
00800       /* sprintf(name,"_%ld%c",++gen_sym_counter,0); */
00801       /* n->data=(GENERIC)heap_copy_string(name); */
00802     }
00803     n2=find(intcmp,p,printed_pointers);
00804     if(n2==NULL) {
00805       prettyf(n->data);
00806       heap_insert(intcmp,p,&printed_pointers,n->data);
00807       if (!is_top(p)) {
00808         prettyf(DOTDOT);
00809         pretty_psi_term(p,COLON_PREC,depth);
00810       }
00811     }
00812     else
00813       prettyf(n2->data);
00814   }
00815   else
00816     pretty_psi_term(p,sprec,depth);
00817 }
00818 
00819 
00820 
00821 /****************************************************************************/
00822 /* Routines to handle printing of operators. */
00823 /* The main routine is pretty_psi_with_ops, which is called in */
00824 /* pretty_psi_term. */
00825 
00826 
00827 /* Check arguments of a potential operator. */
00828 /* Returns existence of arguments 1 and 2 in low two bits of result. */
00829 /* If only argument "1" exists, returns 1. */
00830 /* If only arguments "1" and "2"  exist, returns 3. */
00831 /* Existence of any other arguments causes third bit to be set as well. */
00832 long check_opargs(n)
00833 ptr_node n;
00834 {
00835   if (n) {
00836     long f=check_opargs(n->left) | check_opargs(n->right);
00837     if (!featcmp(n->key,"1")) return 1 | f;
00838     if (!featcmp(n->key,"2")) return 2 | f;
00839     return 4 | f;
00840   }
00841   else
00842     return 0;
00843 }
00844 
00845 #define NOTOP 0
00846 #define INFIX 1
00847 #define PREFIX 2
00848 #define POSTFIX 3
00849 
00850 
00851 /* Get information about an operator. */
00852 /* If t is an operator with the correct arguments, return one of     */
00853 /* {INFIX, PREFIX, POSTFIX} and also its precedence and type.        */
00854 /* If t is not an operator, or it has wrong arguments, return NOTOP  */
00855 /* and prec=0.                                                       */
00856 long opcheck(t, prec, type)
00857 ptr_psi_term t;
00858 long *prec;
00859 operator *type;
00860 {
00861   operator op;
00862   long result=NOTOP;
00863   long numarg=check_opargs(t->attr_list);
00864   ptr_operator_data opdat=t->type->op_data;
00865 
00866   *prec=0;
00867   if (numarg!=1 && numarg!=3) return NOTOP;
00868   while (opdat) {
00869     op=opdat->type;
00870     if (numarg==1) {
00871       if (op==xf || op==yf) { result=POSTFIX; break; }
00872       if (op==fx || op==fy) { result=PREFIX; break; }
00873     }
00874     if (numarg==3)
00875       if (op==xfx || op==xfy || op==yfx) { result=INFIX; break; }
00876     opdat=opdat->next;
00877   }
00878   if (opdat==NULL) return NOTOP;
00879   *prec=opdat->precedence;
00880   *type=op;
00881   return result;
00882 }
00883 
00884 
00885 /* Write an expression with its operators. */
00886 /* Return TRUE iff the arguments of t are written here (i.e. t was indeed */
00887 /* a valid operator, and is therefore taken care of here).                */
00888 long pretty_psi_with_ops(t,sprec,depth)
00889 ptr_psi_term t;
00890 long sprec;
00891 long depth;
00892 {
00893   ptr_tab_brk new;
00894   ptr_psi_term arg1, arg2;
00895   operator ttype, a1type, a2type;
00896   long tprec, a1prec, a2prec;
00897   long tkind, a1kind, a2kind;
00898   long p1, p2, argswritten;
00899   long sp; /* surrounding parentheses */
00900 
00901   if (write_canon) return FALSE; /* PVR 24.2.94 */
00902 
00903   argswritten=TRUE;
00904   tkind=opcheck(t, &tprec, &ttype);
00905   sp=(tkind==INFIX||tkind==PREFIX||tkind==POSTFIX) && tprec>=sprec;
00906   if (sp) prettyf("(");
00907   if (tkind==INFIX) {
00908     get_two_args(t->attr_list, &arg1, &arg2);
00909     deref_ptr(arg1); /* 16.9 */
00910     deref_ptr(arg2); /* 16.9 */
00911     a1kind = opcheck(arg1, &a1prec, &a1type);
00912     a2kind = opcheck(arg2, &a2prec, &a2type);
00913 
00914     /* The p1 and p2 flags tell whether to put parens around t's args */
00915     /* Calculate p1 flag: */
00916     if      (a1prec>tprec) p1=TRUE;
00917     else if (a1prec<tprec) p1=FALSE;
00918     else /* equal priority */
00919       if (ttype==xfy || ttype==xfx) p1=TRUE;
00920       else /* yfx */
00921         if (a1type==yfx || a1type==fx || a1type==fy) p1=FALSE;
00922         else p1=TRUE;
00923 
00924     /* Calculate p2 flag: */
00925     if      (a2prec>tprec) p2=TRUE;
00926     else if (a2prec<tprec) p2=FALSE;
00927     else /* equal priority */
00928       if (ttype==yfx || ttype==xfx) p2=TRUE;
00929       else /* xfy */
00930         if (a2type==xfy || a2type==xf || a2type==yf) p2=FALSE;
00931         else p2=TRUE;
00932 
00933     /* Write the expression */
00934     if (p1) prettyf("(");
00935     pretty_tag_or_psi_term(arg1,MAX_PRECEDENCE+1,depth);
00936     if (p1) prettyf(")");
00937     if (!p1 && strcmp(t->type->keyword->symbol,",")) {
00938       prettyf(" ");
00939     }
00940     pretty_quote_symbol(t->type->keyword); /*  RM: Jan 13 1993  */
00941     if (listing_flag && !func_flag &&
00942         (!strcmp(t->type->keyword->symbol,",") ||
00943          !strcmp(t->type->keyword->symbol,":-"))) {
00944       prettyf("\n        ");
00945     }
00946     else {
00947       if (!p2 && strcmp(t->type->keyword->symbol,".")) prettyf(" ");
00948     }
00949     if (p2) prettyf("(");
00950     pretty_tag_or_psi_term(arg2,MAX_PRECEDENCE+1,depth);
00951     if (p2) prettyf(")");
00952   }
00953   else if (tkind==PREFIX) {
00954     get_two_args(t->attr_list, &arg1, &arg2); /* arg2 does not exist */
00955     a1kind = opcheck(arg1, &a1prec, &a1type);
00956 
00957     /* Calculate p1 flag: */
00958     if (a1type==fx || a1type==fy) p1=FALSE;
00959     else p1=(tprec<=a1prec);
00960 
00961     pretty_quote_symbol(t->type->keyword);  /*  RM: Jan 13 1993  */
00962     if (!p1) prettyf(" ");
00963     if (p1) prettyf("(");
00964     pretty_tag_or_psi_term(arg1,MAX_PRECEDENCE+1,depth);
00965     if (p1) prettyf(")");
00966   }
00967   else if (tkind==POSTFIX) {
00968     get_two_args(t->attr_list, &arg1, &arg2); /* arg2 does not exist */
00969     a1kind = opcheck(arg1, &a1prec, &a1type);
00970 
00971     /* Calculate p1 flag: */
00972     if (a1type==xf || a1type==yf) p1=FALSE;
00973     else p1=(tprec<=a1prec);
00974 
00975     if (p1) prettyf("(");
00976     pretty_tag_or_psi_term(arg1,MAX_PRECEDENCE+1,depth);
00977     if (p1) prettyf(")");
00978     if (!p1) prettyf(" ");
00979     pretty_quote_symbol(t->type->keyword); /*  RM: Jan 13 1993  */
00980   }
00981   else {
00982     argswritten=FALSE;
00983   }
00984   if (sp) prettyf(")");
00985   return argswritten;
00986 }
00987 
00988 /****************************************************************************/
00989 
00990 
00991 /******** PRETTY_PSI_TERM(t,sprec,depth)  
00992   Pretty print a psi_term T with sugar for lists.
00993 */
00994 void pretty_psi_term(t,sprec,depth)
00995      ptr_psi_term t;
00996      long sprec;
00997      long depth;
00998 {
00999   char buf[STRLEN]; /* Big enough for a long number */
01000   ptr_residuation r;
01001   long argswritten;
01002   double fmod();
01003   
01004   if (t) {
01005     deref_ptr(t); /* PVR */
01006 
01007     /* if (trace) printf("<%d>",t->status); For brunobug.lf PVR 14.2.94 */
01008 
01009     /*  RM: Feb 12 1993  */
01010     if(display_persistent &&
01011        (GENERIC)t>heap_pointer)
01012       prettyf(" $");
01013     
01014     if((t->type==alist || t->type==disjunction) && check_legal_cons(t,t->type))
01015       pretty_list(t,depth+1); /*  RM: Dec 11 1992  */
01016     else
01017       if(t->type==nil && !t->attr_list)
01018         prettyf("[]");
01019       else
01020         if(t->type==disj_nil && !t->attr_list) /*  RM: Feb  1 1993  */
01021           prettyf("{}");
01022         else {
01023         argswritten=FALSE;
01024         if (t->value) {
01025 #ifdef CLIFE
01026           if(t->type->type==block) {  /* RM 20 Jan 1993 */
01027             pretty_block(t);          /* AA 21 Jan 1993 */
01028           }
01029           else
01030 #endif /* CLIFE */
01031           if (sub_type(t->type,integer)) {
01032             /* Print integers in chunks up to the full precision of the REAL */
01033             long seg,neg,i;
01034             REAL val;
01035             char segbuf[100][PRINT_POWER+3];
01036             
01037             val = *(REAL *)t->value;
01038             neg = (val<0.0);
01039             if (neg) val = -val;
01040             if (val>WL_MAXINT) goto PrintReal;
01041             seg=0;
01042             while (val>=(double)PRINT_SPLIT) {
01043               double tmp;
01044               tmp=(REAL)fmod((double)val,(double)PRINT_SPLIT);
01045               sprintf(segbuf[seg],seg_format,(unsigned long)tmp);
01046               val=floor(val/(double)PRINT_SPLIT);
01047               seg++;
01048             }
01049             sprintf(segbuf[seg],"%s%ld",(neg?"-":""),(unsigned long)val);
01050             for (i=seg; i>=0; i--) prettyf(segbuf[i]);
01051             if (!equal_types(t->type,integer)) {
01052               prettyf(DOTDOT);
01053               pretty_symbol(t->type->keyword); /*  RM: Jan 13 1993  */
01054             }
01055           }
01056           else if (sub_type(t->type,real)) {
01057           PrintReal:
01058             sprintf(buf,"%lg",*(REAL *)t->value);
01059             prettyf(buf);
01060             if (!equal_types(t->type,real) &&
01061                 !equal_types(t->type,integer)) {
01062               prettyf(DOTDOT);
01063               pretty_symbol(t->type->keyword); /*  RM: Jan 13 1993  */
01064             }
01065           }
01066           else if (sub_type(t->type,quoted_string)) {
01067             prettyf_quoted_string(t->value);
01068             if(!equal_types(t->type,quoted_string)) {
01069               prettyf(DOTDOT);
01070               pretty_quote_symbol(t->type->keyword); /*  RM: Jan 13 1993  */
01071             }
01072           }
01073           /* DENYS: BYTEDATA */
01074           else if (sub_type(t->type,sys_bytedata)) {
01075             pretty_quote_symbol(t->type->keyword);
01076           }
01077           else if (equal_types(t->type,stream)) {
01078             sprintf(buf,"stream(%ld)",t->value);
01079             prettyf(buf);
01080           }
01081           else if (equal_types(t->type,eof))
01082             pretty_quote_symbol(eof->keyword); /*  RM: Jan 13 1993  */
01083           else if (equal_types(t->type,cut))
01084             pretty_quote_symbol(cut->keyword); /*  RM: Jan 13 1993  */
01085           else {
01086             prettyf("*** bad object '");
01087             pretty_symbol(t->type->keyword); /*  RM: Jan 13 1993  */
01088             prettyf("'***");
01089           }
01090         }
01091         else {
01092           if (depth<print_depth) /* 20.8 */
01093             argswritten=pretty_psi_with_ops(t,sprec,depth+1);
01094           /*  RM: Jan 13 1993  */
01095           if (!argswritten) pretty_quote_symbol(t->type->keyword);
01096         }
01097         
01098         /* write_canon -- PVR 24.2.94 */
01099         if (!argswritten && t->attr_list &&
01100             (depth<print_depth || write_canon)) /* 20.8 */
01101           pretty_attr(t->attr_list,depth+1);
01102         
01103         if (depth>=print_depth && !write_canon && t->attr_list) /* 20.8 */
01104           prettyf("(...)");
01105       }
01106     if (r=t->resid)
01107       while (r) {
01108         if (r->goal->pending) {
01109           if (FALSE /* write_resids 11.8 */) {
01110             prettyf("\\");
01111             pretty_psi_term(r->goal->a,0,depth);
01112           }
01113           else
01114             prettyf("~");
01115         }
01116         r=r->next;
01117       }
01118   }
01119 }
01120 
01121 
01122 
01123 /******** DO_PRETTY_ATTR(t,tab,cnt,depth)
01124   Pretty print the attribute tree T at position TAB.
01125 
01126   CNT is what the value of the first integer label should be, so that
01127   "p(1=>a,2=>b)" is printed "p(a,b)"
01128   but
01129   "p(2=>a,3=>b)" is printed as "p(2 => a,3 => b)".
01130 */
01131 void do_pretty_attr(t,tab,cnt,two,depth)
01132 ptr_node t;
01133 ptr_tab_brk tab;
01134 long *cnt;
01135 long two;
01136 long depth;
01137 {
01138   long v;
01139   /* char *s="nnn"; 18.5 */
01140   char s[4];
01141   ptr_module module;
01142 
01143   
01144   if (t) {
01145     if (t->left) {
01146       do_pretty_attr(t->left,tab,cnt,two,depth);
01147       prettyf(",");
01148     }
01149     
01150     /* Don't start each argument on a new line, */
01151     /* unless printing a function body: */
01152     mark_tab(tab);
01153     
01154     v=str_to_int(t->key);
01155     if (v<0) {
01156       if(display_modules) { /*  RM: Jan 21 1993  */
01157         module=extract_module_from_name(t->key);
01158         if(module) {
01159           prettyf(module->module_name);
01160           prettyf("#");
01161         }
01162       }
01163       prettyf_quote(strip_module_name(t->key));
01164 
01165       prettyf(" => ");
01166     }
01167     else if (v== *cnt)
01168       (*cnt)++ ;
01169     else {
01170       sprintf(s,"%ld",v);
01171       prettyf(s); /* 6.10 */
01172       prettyf(" => ");
01173     }
01174     
01175     /* pretty_tag_or_psi_term(t->data,(two?COMMA_PREC:MAX_PRECEDENCE+1)); */
01176     pretty_tag_or_psi_term(t->data,COMMA_PREC,depth);
01177     
01178     if (t->right) {
01179       prettyf(",");
01180       do_pretty_attr(t->right,tab,cnt,two,depth);
01181     }
01182   }
01183 }
01184 
01185 
01186 /* Return true if number of attributes is greater than 1 */
01187 long two_or_more(t)
01188 ptr_node t;
01189 {
01190   if (t) {
01191     if (t->left || t->right) return TRUE; else return FALSE;
01192   }
01193   else
01194     return FALSE;
01195 }
01196 
01197 
01198 /******** PRETTY_ATTR(t,depth)
01199   Pretty print the attributes. This calls DO_PRETTY_ATTR which does the real
01200   work.
01201 */
01202 void pretty_attr(t,depth)
01203 ptr_node t;
01204 long depth;
01205 {
01206   ptr_tab_brk new;
01207   long cnt=1;
01208 
01209   prettyf("(");
01210   new_tab(&new);
01211 
01212   do_pretty_attr(t,new,&cnt,two_or_more(t),depth);
01213 
01214   prettyf(")");
01215 }
01216 
01217 
01218 
01219 /******** PRETTY_OUTPUT()
01220   Final output of all these pretty things which have been built up.
01221 */
01222 void pretty_output()
01223 {
01224   ptr_item i;
01225   long j;
01226   
01227   for(i=pretty_things+1;(unsigned long)i<(unsigned long)indx;i++) {
01228     if(i->tab->broken && i->tab->printed) {
01229       fprintf(outfile,"\n");
01230       for(j=0;j<i->tab->column;j++)
01231         fprintf(outfile," ");
01232     }
01233     fprintf(outfile,"%s",i->str);
01234     i->tab->printed=TRUE;
01235   }
01236 }
01237 
01238 
01239 
01240 
01241 /******** PRETTY_VARIABLES(n,tab)
01242   Pretty print the variables at position TAB.
01243 */
01244 void pretty_variables(n,tab)
01245 ptr_node n;
01246 ptr_tab_brk tab;
01247 {
01248   ptr_psi_term tok;
01249   ptr_node n2;
01250   
01251   if(n->left) {
01252     pretty_variables(n->left,tab);
01253     prettyf(", ");
01254   }
01255 
01256   mark_tab(tab);
01257   prettyf(n->key);
01258   prettyf(" = ");
01259 
01260   tok=(ptr_psi_term )n->data;
01261   deref_ptr(tok);
01262   n2=find(intcmp,tok,printed_pointers);
01263   if(strcmp((char *)n2->data,n->key)<0)
01264     /* Reference to previously printed variable */
01265     prettyf(n2->data);
01266   else {
01267     if (eqsym->op_data) {
01268       long tkind, tprec, ttype, eqprec;
01269       eqprec=eqsym->op_data->precedence;
01270       tkind=opcheck(tok, &tprec, &ttype);
01271       if (tprec>=eqprec) prettyf("(");
01272       pretty_psi_term(tok,MAX_PRECEDENCE+1,0);
01273       if (tprec>=eqprec) prettyf(")");
01274     }
01275     else
01276       pretty_psi_term(tok,MAX_PRECEDENCE+1,0);
01277   }
01278   
01279   if(n->right) {
01280     prettyf(", ");
01281     pretty_variables(n->right,tab);
01282   }
01283 }
01284 
01285 
01286 
01287 /******** PRINT_VARIABLES
01288   This prints all the query variables.
01289   Symbols generated to print one variable are coherent with those used in
01290   other variables.
01291   Returns TRUE iff the set of query variables is nonempty.
01292 */
01293 
01294 long print_variables(printflag)
01295      
01296      long printflag;
01297 {
01298   ptr_tab_brk new;
01299   GENERIC old_heap_pointer;
01300   
01301   if (!printflag) return FALSE; /* 21.1 */
01302   
01303   outfile=output_stream;
01304   listing_flag=FALSE;
01305   old_heap_pointer=heap_pointer;
01306   
01307   pointer_names=NULL;
01308   printed_pointers=NULL;
01309   gen_sym_counter=0;
01310   go_through_tree(var_tree);
01311   insert_variables(var_tree,TRUE);
01312   forbid_variables(var_tree);
01313   
01314   indent=TRUE;
01315   const_quote=TRUE;
01316   write_resids=TRUE;
01317   write_canon=FALSE;
01318   *buffer=0;
01319   indx=pretty_things;
01320 
01321   if (var_tree) {
01322     new_tab(&new);
01323     pretty_variables(var_tree,new);
01324     prettyf(".");
01325     mark_tab(new);
01326     prettyf("\n");
01327     end_tab();
01328 
01329     if (indent) {
01330       work_out_length();
01331       pretty_output();
01332     }
01333   }
01334   heap_pointer=old_heap_pointer;
01335   return (var_tree!=NULL);
01336 }
01337 
01338 
01339 
01340 /******** WRITE_ATTRIBUTES(n)
01341   Used by all versions of the built-in predicate write,
01342   and by the built-in predicate listing.
01343 */
01344 void write_attributes(n,tab)
01345 ptr_node n;
01346 ptr_tab_brk tab;
01347 {
01348   if(n) {
01349     write_attributes(n->left,tab);
01350     mark_tab(tab);
01351     pretty_tag_or_psi_term(n->data,MAX_PRECEDENCE+1,0);
01352     write_attributes(n->right,tab);
01353   }
01354 }
01355 
01356 
01357 /******** PRED_WRITE(n)
01358   N is an attribute tree to be printed in one lump. This is called by WRITE.
01359 */
01360 
01361 void main_pred_write();
01362 
01363 /* For the listing built-in */
01364 void listing_pred_write(n,fflag)
01365 ptr_node n;
01366 long fflag;
01367 {
01368   long old_print_depth;
01369 
01370   listing_flag=TRUE;
01371   func_flag=fflag;
01372   indent=TRUE;
01373   const_quote=TRUE;
01374   write_corefs=TRUE;
01375   write_stderr=FALSE;
01376   write_resids=FALSE;
01377   write_canon=FALSE;
01378   outfile=output_stream;
01379   old_print_depth=print_depth;
01380   print_depth=PRINT_DEPTH;
01381   main_pred_write(n);
01382   print_depth=old_print_depth;
01383   fflush(outfile);
01384 }
01385 
01386 /* For all write builtins */
01387 /* I.e: write, writeq, pretty_write, pretty_writeq, write_err, writeq_err. */
01388 void pred_write(n)
01389 ptr_node n;
01390 {
01391   listing_flag=FALSE;
01392   /* write_stderr=FALSE; */
01393   outfile=(write_stderr?stderr:output_stream);
01394   main_pred_write(n);
01395   fflush(outfile);
01396 }
01397 
01398 void main_pred_write(n)
01399 ptr_node n;
01400 {
01401   if (n) {
01402     GENERIC old_heap_pointer;
01403     ptr_tab_brk new;
01404  
01405     if (!write_corefs) main_pred_write(n->left);
01406 
01407     old_heap_pointer=heap_pointer;
01408     pointer_names=NULL;
01409     printed_pointers=NULL;
01410     gen_sym_counter=0;
01411     if (write_corefs)
01412       go_through_tree(n);
01413     else
01414       check_pointer((ptr_psi_term)n->data);
01415     insert_variables(var_tree,FALSE);
01416 
01417     *buffer=0;
01418     
01419     indx=pretty_things;
01420     new_tab(&new);
01421 
01422     if (write_corefs) {
01423       write_attributes(n,new);
01424     }
01425     else {
01426       mark_tab(new);
01427       pretty_tag_or_psi_term(n->data,MAX_PRECEDENCE+1,0);
01428     }
01429 
01430     end_tab();
01431 
01432     if (indent) {
01433       work_out_length();
01434       pretty_output();
01435     }
01436     
01437     heap_pointer=old_heap_pointer;
01438 
01439     if (!write_corefs) main_pred_write(n->right);
01440   }
01441 }
01442 
01443 
01444 void main_display_psi_term(); /* Forward declaration */
01445 
01446 
01447 /******** DISPLAY_PSI_STDOUT(t)
01448   Print the psi_term T to stdout as simply as possible (no indenting).
01449 */
01450 void display_psi_stdout(t)
01451 ptr_psi_term t;
01452 {
01453   outfile=stdout;
01454   main_display_psi_term(t);
01455 }
01456 
01457 
01458 /******** DISPLAY_PSI_STDERR(t)
01459   Print the psi_term T to stderr as simply as possible (no indenting).
01460 */
01461 void display_psi_stderr(t)
01462 ptr_psi_term t;
01463 {
01464   outfile=stderr;
01465   main_display_psi_term(t);
01466 }
01467 
01468 
01469 /******** DISPLAY_PSI_STREAM(t)
01470   Print the psi_term T to output_stream as simply as possible (no indenting).
01471 */
01472 void display_psi_stream(t)
01473 ptr_psi_term t;
01474 {
01475   outfile=output_stream;
01476   main_display_psi_term(t);
01477 }
01478 
01479 
01480 /******** DISPLAY_PSI(stream,t)
01481   Print the psi_term T to the given stream.
01482 */
01483 void display_psi(s,t)
01484 FILE *s;
01485 ptr_psi_term t;
01486 {
01487   outfile=s;
01488   main_display_psi_term(t);
01489 }
01490 
01491 
01492 /* Main loop for previous two entry points */
01493 void main_display_psi_term(t)
01494 ptr_psi_term t;
01495 {
01496   GENERIC old_heap_pointer;
01497   ptr_tab_brk new;
01498 
01499   listing_flag=FALSE;
01500   if(t) {
01501 
01502     deref_ptr(t);
01503     
01504     old_heap_pointer=heap_pointer;
01505     pointer_names=NULL;
01506     printed_pointers=NULL;
01507     gen_sym_counter=0;
01508     go_through(t);
01509     insert_variables(var_tree,FALSE);
01510     
01511     indent=FALSE;
01512     const_quote=TRUE;
01513     write_resids=FALSE;
01514     write_canon=FALSE;
01515     *buffer=0;
01516     indx=pretty_things;
01517 
01518     new_tab(&new);
01519     mark_tab(new);
01520     pretty_tag_or_psi_term(t,MAX_PRECEDENCE+1,0);
01521     end_tab();
01522     if (indent) {
01523       work_out_length();
01524       pretty_output();
01525     }
01526     
01527     heap_pointer=old_heap_pointer;
01528   }
01529   else
01530     printf("*null psi_term*");
01531 }
01532 
01533 
01534 
01535 /******** DISPLAY_COUPLE(u,s,v)
01536   Print a couple of psi-terms (u,v) with the correct co-referencing. Print
01537   string S in between.
01538 */
01539 void display_couple(u,s,v)
01540 ptr_psi_term u;
01541 char *s;
01542 ptr_psi_term v;
01543 {
01544   GENERIC old_heap_pointer;
01545   ptr_tab_brk new;
01546 
01547   output_stream=stdout;
01548   listing_flag=FALSE;
01549   old_heap_pointer=heap_pointer;
01550   
01551   pointer_names=NULL;
01552   printed_pointers=NULL;
01553   gen_sym_counter=0;
01554   check_pointer(u);
01555   check_pointer(v);
01556   insert_variables(var_tree,TRUE);
01557   
01558   indent=FALSE;
01559   const_quote=TRUE;
01560   write_resids=FALSE;
01561   write_canon=FALSE;
01562   *buffer=0;
01563   indx=pretty_things;
01564   new_tab(&new);
01565   mark_tab(new);
01566   pretty_tag_or_psi_term(u,MAX_PRECEDENCE+1,0);
01567   prettyf(s);
01568   pretty_tag_or_psi_term(v,MAX_PRECEDENCE+1,0);
01569   end_tab();
01570 
01571   if (indent) {
01572     work_out_length();
01573     pretty_output();
01574   }
01575   
01576   heap_pointer=old_heap_pointer;
01577 }
01578 
01579 
01580 
01581 /******** PRINT_RESID_MESSAGE
01582   This is called in trace mode to print the residuated goal along with the
01583   RV set.
01584 */
01585 void print_resid_message(t,r)
01586 ptr_psi_term t;
01587 ptr_resid_list r; /* 21.9 */
01588 {
01589   GENERIC old_heap_pointer;
01590   ptr_tab_brk new;
01591   ptr_resid_list r2; /* 21.9 */
01592   
01593   outfile=stdout;
01594   listing_flag=FALSE;
01595   old_heap_pointer=heap_pointer;
01596   
01597   pointer_names=NULL;
01598   printed_pointers=NULL;
01599   gen_sym_counter=0;
01600 
01601   check_pointer(t);
01602 
01603   r2=r;
01604   while(r2) {
01605     check_pointer(r2->var);
01606     r2=r2->next;
01607   }
01608   
01609   insert_variables(var_tree,TRUE);
01610   
01611   indent=FALSE;
01612   const_quote=TRUE;
01613   write_resids=FALSE;
01614   write_canon=FALSE;
01615   *buffer=0;
01616   indx=pretty_things;
01617   new_tab(&new);
01618   mark_tab(new);
01619 
01620   prettyf("residuating ");
01621   pretty_tag_or_psi_term(t,MAX_PRECEDENCE+1,0);
01622   prettyf(" on variable(s) {");
01623 
01624   r2=r;
01625   while(r2) {
01626     pretty_tag_or_psi_term(r2->var,MAX_PRECEDENCE+1,0);
01627     r2=r2->next;
01628     if(r2)
01629       prettyf(",");
01630   }
01631 
01632   prettyf("}\n");
01633   end_tab();
01634   
01635   heap_pointer=old_heap_pointer;
01636 }

Generated on Sat Jan 26 08:48:07 2008 for WildLife by  doxygen 1.5.4