/***********************************
  (C) Copyright 1992-1993; dit/upm
  Distributed under the conditions stated in the
  TOPO General Public License (see file LICENSE)
  ***********************************/

/***********************************
  
  Maria Hultstrom
  
  10-4-1990
  
  Statistic about the memory usage.
  
  ************************************/ 

/* LINTLIBRARY */


#include "listdh.h"
#include "limisc.h"
#include "listdout.h"
#include "lilists.h"
#include "licell.h"
#include "listrbk.h"
#include "libst.h"
#include "babeh.h"
#include "baattr.h"
#include "batables.h"
#include "baexpr.h"
#include "bamove.h"
#include "instat.h"
#include "badefca.h"
#include "baprint.h"
#include "basynset.h"
#include "excomp.h"

#ifdef SDEBUG

/***************************************************************************
 *
 *    Global declarations of data to calculate the statistic of
 *    the expressions.
 *
 ***************************************************************************/

/* n_exprs
 * To calculate how many expression cells are used and the number 
 * of list nodes used on them.
 * n_exprs[0] is the real number of variable cells.
 * n_exprs[1] is the real number of operation cells.
 * n_exprs[2] is the real number of list nodes used in the expressions.
 * n_exprs[3] is the virtual number of variable cells.
 * n_exprs[4] is the virtual number of operation cells.
 * n_exprs[5] is the virtual number of list nodes used in the expressions.
 *
 * Real means the real number of cell used. Reused cells are only counted 
 * one time.
 * Virtual values are calculated regarless of the sharing feature.
 */ 
static int n_exprs[6];

/***************************************************************************
 *
 *    Global declarations of data to calculate the statistic of
 *    the table of processes.
 *
 ***************************************************************************/

/* p_BehCells
 * To calculate how many cells are used.
 * Cells are used only in the behaviours in the process table.
 * p_BehCells[i][0] is the number of cells of type i 
 * p_BehCells[i][1] is the copy value of cells of type i 
 */ 
static int p_BehCells[N_DEF_CELLS][2];

/* p_AttrCells
 * To calculate how many attribute nodes are used.
 * Attributes are used only in the behaviours in the process table.
 * p_AttrCells[i][0] is the number of attributes of type i 
 * p_AttrCells[i][1] is the cont value of attributes of type i 
 */ 
static int p_AttrCells[N_DEF_ATTRS][2];

/* p_AttrLNodes
 * Is the number of list nodes used to make the lists of attributes.
 */
static int p_AttrLNodes; 

/* n_ELA 
 * Arrays of three dimensions to store statistic about the atribute ELA.
 * Position 0 is the number of list nodes in the attribute.
 * Position 1 is the number of VariableC cell in the attribute.
 * Position 2 is the number of OperationC cell in the attribute.
 */
static int n_ELA[3];

/* n_VALA
 * Arrays of three dimensions to store statistic about the atribute VAL.
 * Position 0 is the number of list nodes in the attribute.
 * Position 1 is the number of VariableC cell in the attribute.
 * Position 2 is the number of OperationC cell in the attribute.
 * Position 3 is the number of var-assign nodes in the attribute.
 */
static int n_VALA[4];

/* n_OLA 
 * Arrays of three dimensions to store statistic about this attribute.
 * Position 0 is the number of OLA nodes in the attribute.
 * Position 1 is the number of VariableC cell in the attribute.
 * Position 2 is the number of OperationC cell in the attribute.
 * Position 3 is the number of list nodes in the attribute.
 */
static int n_OLA[4];

/* n_PA 
 * Array of two dimensions to store statistic about the atribute PA.
 * Position 0 is the number of VariableC cell in the attribute.
 * Position 1 is the number of OperationC cell in the attribute.
 * Position 2 is the number of list nodes in the attribute.
 * Position 3 is the number of predicate nodes in the attribute.
 */
static int n_PA[4]; 

/* n_GLA 
 * Variable to store statistic about these attribute.
 * It contains the number of list nodes used in this attribute.
 */
static int n_GLA;

/* n_ITCLA 
 * Variable to store statistic about these attribute.
 * It contains the number of list nodes ([0]) and ITC nodes ([1])
 * used in this attribute.
 */
static int n_ITCLA[2];

/* n_GDLA 
 * Variable to store statistic about this attribute.
 * It contains the number of list nodes ([0]) and the gate sets ([1]) 
 * used in this attribute.
 */
static int n_GDLA[2]; 

/* n_RFLA
 * Variable to store statistic about this attribute.
 * It contains the number of RFL nodes used in these attributes.
 */
static int n_RFLA; 

/* n_GSA
 * Variable to store statistic about this attribute.
 * It contains the number of gate sets used.
 */
static int n_GSA; 


/* n_TA 
 * Array of two dimensions to store statistic about the atribute TA.
 * Position 0 is the number of VariableC cell in the attribute.
 * Position 1 is the number of OperationC cell in the attribute.
 * Position 2 is the number of list nodes in the attribute.
 * Position 3 is the number of time nodes in the attribute.
 */
static int n_TA[4]; 


/* Total
 * Total number of attribute nodes and cells used in the behaviours.
 */
static int p_attrs, p_cells;

/* Total
 * Real number of list nodes in the behaviours.
 */
static int p_lists;


/***************************************************************************
 *
 *    Global declarations of data to calculate the statistic of
 *    the table of gates.
 *
 ***************************************************************************/

/* gtgs
 * gate sets used in the tables of gates.
 */
static int gtgs;

/***************************************************************************
 *
 *    Global declarations of data to calculate the statistic of
 *    the table of variables.
 *
 ***************************************************************************/
/***************************************************************************
 *
 *    Global declarations of data to calculate the statistic of
 *    the table of operations.
 *
 ***************************************************************************/

/* Statistic of the operations table.
 *
 * otvarv: virtual number of variable cells.
 * otopnv: virtual number of operations cells.
 * otvarr: real number of variable cells.
 * otopnr: real number of operations cells.
 * otnlev: virtual number of list nodes used in the expressions.
 * otnler: real number of list nodes used in the expressions.
 * otnlv: virtual number of list nodes (not used in expr.).
 * otnlr: real number of list nodes (not used in expr.).
 * otrule: rewrite nule nodes.
 * otpmt: pmt nodes.
 */
static int otvarv, otvarr, otopnv, otopnr;
static int otnlev, otnler, otnlv, otnlr;
static int otrule, otpmt;

/***************************************************************************
 *
 *    Global declarations of data to calculate the statistic of
 *    the table of sorts.
 *
 ***************************************************************************/
/***************************************************************************
 *
 *    Global declarations of data to calculate the statistic of
 *    the table of functionalities.
 *
 ***************************************************************************/

/* ftcell, ftnode
 * cells and list nodes used in the tables of functionalities.
 */
static int ftcell, ftnode;

/***************************************************************************
 *
 *    Global declarations of data to calculate the statistic of
 *    the movement module.
 *
 ***************************************************************************/

/* nodes_move
 * List nodes used by the module INmove.
 */
static int  nodes_move;

/***************************************************************************
 *
 *    Global declarations of data to calculate the statistic about
 *    the lost of memory.
 *
 ***************************************************************************/

/*
 *  allocations, releases and maximum-used data structures.
 * 
 *   ul, rl      : list nodes.
 *   uc, rc, mc      : cells
 *   ua, ra, ma      : attrs
 *   uo, ro, mo      : offers
 *   upr, rpr, mpr   : predicates
 *   ur, rr      : relab func
 *   us, rs      : gate sets
 *   ue, re, me      : expressions cells
 *   uva,  rva   : var assigns
 *   ugd,  rgd   : gate declarations
 *   uitc, ritc  : interleaved conts
 *   utn,  rtn, mtn   : expression tnodes
 *   urule,rrule : rules
 *   upmt, rpmt  : pattern match nodes
 *   uvp,  rvp   : var pairs
 *   uss,  rss   : sync sets
 *   u2w,  r2w   : 2 words
 *   usb,  rsb   : string blocks
 *   ubsn, rbsn  : binary search tree nodes
 *   utime, rtime, mtime   : predicates
 */
static int ul, rl, ml, uc, rc, mc, ua, ra, ma,
uo, ro, mo, upr, rpr, mpr, ur, rr, mr, us, rs, ms,
ue, re, me, uva, rva, mva, ugd, rgd, mgd,
uitc, ritc, mitc, urule, rrule, mrule, uvp, rvp, mvp,
uss, rss, mss, u2w, r2w, m2w, usb, rsb, msb,
utn, rtn, mtn, upmt, rpmt, mpmt, ubsn, rbsn, mbsn;
#ifdef TIME
static int utime, rtime, mtime;
#endif 
/***************************************************************************
 *
 *  Auxiliary functions.
 *
 ***************************************************************************/

/* l_cont
 * List of attributes whose copy or cont field is greater
 * than 1.
 * Their sign is changed to process them only one time.
 */
static ListTyp l_cont; 

/***************************************************************************
 *
 *  Auxiliary functions.
 *
 ***************************************************************************/

/* ChangeContSign
 * Change the sign of the cont value of an attribute
 */ 
static void ChangeContSign(a)
     PAttrTyp a;
{
  LASSERT(a != NULL);
  a->cont = -a->cont; 
}

/***************************************************************************
 *
 *  Initiation and clean of the data used to calculate the statistic.
 *
 ***************************************************************************/

/* InitStat
 * Inits module. Must be called before calculating any statistic
 */
extern void InitStat()
{
  int i;
  
  /* EXPRESSIONS */
  for (i = 0; i < 6; ++i ) n_exprs[i] = 0;
  
  /* TABLE OF PROCESSES */
  for (i = 0; i < N_DEF_CELLS; ++i ) p_BehCells[i][0] = p_BehCells[i][1] = 0;
  for (i = 0; i < N_DEF_ATTRS; ++i ) p_AttrCells[i][0] = p_AttrCells[i][1] = 0;
  p_AttrLNodes = 0;
  for (i = 0; i < 3 ; ++i) n_ELA[i] = 0;
  for (i = 0; i < 4 ; ++i) n_VALA[i] = 0;
  for (i = 0; i < 4 ; ++i) n_OLA[i] = 0;
  for (i = 0; i < 4 ; ++i) n_PA[i] = 0;
#ifdef TIME
  for (i = 0; i < 4 ; ++i) n_TA[i] = 0;
#endif
  n_GLA   = 0;
  for (i = 0; i < 2 ; ++i) n_ITCLA[i] = 0;
  for (i = 0; i < 2 ; ++i) n_GDLA[i] = 0;
  n_RFLA  = 0;
  n_GSA  = 0;
  p_cells = p_lists = p_attrs = 0 ;
  
  /* TABLE OF GATES */
  gtgs = 0;
  
  /* TABLE OF VARIABLES */
  
  /* TABLE OF OPERATIONS */
  otvarv = otvarr = otopnv = otopnr = 0;
  otnlev = otnler = otnlv = otnlr = 0;
  otrule = otpmt = 0;
  
  /* TABLE OF SORTS */
  
  /* TABLE OF FUNCTIONALITIES */
  ftcell = ftnode = 0;
  
  /* MOVEMENT MODULE */
  nodes_move = 0;
  
  /* LOST MEMORY */
  ul = rl = ml = uc = rc = mc = ua = ra = ma = uo = ro = mo = ur = rr = mr = 0;
  us = rs = ms = ue = re = me = uva = rva = mva = ugd = rgd = mgd = 0;
  uitc = ritc = mitc = urule = rrule = mrule = uvp = rvp = mvp = 0;
  uss = rss = mss = u2w = r2w = m2w = usb = rsb = msb = utn = rtn = mtn = 0;
  upmt = rpmt = mpmt = ubsn = rbsn = mbsn = 0;
  upr = rpr = mpr = 0;
#ifdef TIME  
utime = rtime = mtime = 0;
#endif 
  /* AUXILIARY */
  l_cont = Create_list(); 
  Begin_VisitB();
  Begin_VisitE();
}

/***************************************************************************
 *
 *  Calculates the statistics.
 *
 ***************************************************************************/

/* Count_GLA
 * Counts the nodes of a Gate List Attribute and gets its cont value
 */ 
static void Count_GLA(a)
     PAttrTyp a; 
{
  int l;
  
  l = Length_list( (ListTyp)LookAInfo(a) );
  n_GLA += l;
  p_lists += l;
}     

/* ------------------------------------------------------------------------- */

/* Count_ELA
 * Counts the nodes, variables, operations of an Expr List Attribute
 */
static void Count_ELA(a)
     PAttrTyp a;
{
  int op1, var1, n1, op2, var2, n2, nl; 
  ExprListTyp el;
  
  el = (ExprListTyp)LookAInfo(a);
  
  StatisticEL( el,&n1,&var1,&op1,&n2,&var2,&op2,&nl);
  
  n_exprs[0] += var2;
  n_exprs[1] += op2;
  n_exprs[2] += n2;
  n_exprs[3] += var1;
  n_exprs[4] += op1;
  n_exprs[5] += n1;
  
  p_lists += nl + n2;
  
  n_ELA[0] += n1+nl;
  n_ELA[1] += var1;
  n_ELA[2] += op1;  
}     

/* ------------------------------------------------------------------------- */

/* Count_PA
 * Counts the variables and operations of a Predicate Attribute 
 */
static void Count_PA(a)
     PAttrTyp a;  
{ 
  int op1, var1, n1, op2, var2, n2; 
  PredicateTyp p;
  
  for (p=(PredicateTyp)LookAInfo(a) ; p!=NULL ; p=Next_list(p) ) {
    StatisticE( LookRwPred(p), &n1, &var1, &op1, &n2, &var2, &op2 );
    n_exprs[0] += var2;
    n_exprs[1] += op2;
    n_exprs[2] += n2;
    n_exprs[3] += var1;
    n_exprs[4] += op1;
    n_exprs[5] += n1;
    p_lists    += n2;
    n_PA[0]    += var1;
    n_PA[1]    += op1;
    n_PA[2]    += n1;
    n_PA[3]    += 1;
    p_lists++;
    if ( LookOrPred(p)!=NULL) {
      StatisticE( LookOrPred(p) ,&n1,&var1,&op1,&n2,&var2,&op2);
      n_exprs[0] += var2;
      n_exprs[1] += op2;
      n_exprs[2] += n2;
      n_exprs[3] += var1;
      n_exprs[4] += op1;
      n_exprs[5] += n1;
      p_lists += n2;
      n_PA[0]    += var1;
      n_PA[1]    += op1;
      n_PA[2]    += n1;
    }     
  }     
}     

/* ------------------------------------------------------------------------- */

/* Count_TA
 * Counts the variables and operations of a Predicate Attribute 
 */
#ifdef TIME
static void Count_TA(a)
     PAttrTyp a;  
{ 
  int op1, var1, n1, op2, var2, n2; 
  PTimeTyp p;
  
  p = (PTimeTyp)LookAInfo(a);
  StatisticE( p->lower_bound, &n1, &var1, &op1, &n2, &var2, &op2 );
  n_exprs[0] += var2;
  n_exprs[1] += op2;
  n_exprs[2] += n2;
  n_exprs[3] += var1;
  n_exprs[4] += op1;
  n_exprs[5] += n1;
  p_lists    += n2;
  n_TA[0]    += var1;
  n_TA[1]    += op1;
  n_TA[2]    += n1;
  n_TA[3]    += 1;
  
  StatisticE( p->upper_bound, &n1, &var1, &op1, &n2, &var2, &op2 );
  n_exprs[0] += var2;
  n_exprs[1] += op2;
  n_exprs[2] += n2;
  n_exprs[3] += var1;
  n_exprs[4] += op1;
  n_exprs[5] += n1;
  p_lists    += n2;
  n_TA[0]    += var1;
  n_TA[1]    += op1;
  n_TA[2]    += n1;
  if (p->tvar != NULL) {
    StatisticE( p->tvar, &n1, &var1, &op1, &n2, &var2, &op2 );
    n_exprs[0] += var2;
    n_exprs[1] += op2;
    n_exprs[2] += n2;
    n_exprs[3] += var1;
    n_exprs[4] += op1;
    n_exprs[5] += n1;
    p_lists    += n2;
    n_TA[0]    += var1;
    n_TA[1]    += op1;
    n_TA[2]    += n1;
  }
}     
#endif

/* ------------------------------------------------------------------------- */

/* Count_OLA
 * Counts the nodes, variables and operations of an Offer List Attribute
 */
static void Count_OLA(a)
     PAttrTyp a;
{
  int op1, var1, n1, op2, var2, n2, no; 
  OfferListTyp ol;
  
  ol = (OfferListTyp)LookAInfo(a);
  
  StatisticOL( ol,&n1,&var1,&op1,&n2,&var2,&op2,&no );
  
  n_exprs[0] += var2;
  n_exprs[1] += op2;
  n_exprs[2] += n2;
  n_exprs[3] += var1;
  n_exprs[4] += op1;
  n_exprs[5] += n1;
  
  p_lists += n2;
  
  n_OLA[0] += no;
  n_OLA[1] += var1;
  n_OLA[2] += op1;  
  n_OLA[3] += n1;  
}     

/* ------------------------------------------------------------------------- */

/* Count_VALA
 * Counts the nodes, variables and operations of a Var Assign List Attribute
 */
static void Count_VALA(a)
     PAttrTyp a; 
{
  int op1, var1, n1, op2, var2, n2, va, nl; 
  VarAssignListTyp val;
  
  val = (VarAssignListTyp)LookAInfo(a);
  
  StatisticVAL( val,&n1,&var1,&op1,&n2,&var2,&op2,&va,&nl );
  
  n_exprs[0] += var2;
  n_exprs[1] += op2;
  n_exprs[2] += n2;
  n_exprs[3] += var1;
  n_exprs[4] += op1;
  n_exprs[5] += n1;
  
  p_lists += nl + n2;
  
  n_VALA[0] += n1+nl;
  n_VALA[1] += var1;
  n_VALA[2] += op1;  
  n_VALA[3] += va;  
}     

/* ------------------------------------------------------------------------- */

/* Count_GSA
 * Count the number of Gate Set Attributes
 */ 
static void Count_GSA()
{
  n_GSA ++;
}     

/* ------------------------------------------------------------------------- */

/* Count_GDLA
 * Counts the list nodes and the gate sets of a Gate Declaration List 
 * Attribute.
 */
static void Count_GDLA(a)
     PAttrTyp a; 
{
  int            n,gs;
  GateDecListTyp gdl; 
  
  gdl = (GateDecListTyp)LookAInfo(a);
  StatisticGDL( gdl, &n, &gs );
  p_lists   += n;
  n_GDLA[0] += n;
  n_GDLA[1] += gs;
}

/* ------------------------------------------------------------------------- */

/* Count_RFLA
 * Counts the nodes of a Relab Func List Attribute and gets its cont value.
 */
static void Count_RFLA(a)
     PAttrTyp a; 
{
  n_RFLA += LengthRFL((RelabFuncListTyp)LookAInfo(a));
}     

/* ------------------------------------------------------------------------- */

static void StatBeh(); 

/* Count_ITCLA
 * Counts the nodes and cells of a Interleaved Continuation List Attribute, 
 * calls StatBeh with the continuations
 */
static void Count_ITCLA(a)
     PAttrTyp a;
{
  ITContListTyp itcl;
  int           ln,itcn;
  ListTyp       behlist;
  
  itcl = (ITContListTyp)LookAInfo(a);
  behlist = StatisticITC( itcl, &itcn, &ln );
  p_lists += ln;
  n_ITCLA[0] += ln;
  n_ITCLA[1] += itcn;
  Apply_Proc_list(behlist,StatBeh);
  Disp_list(behlist);
}     

/*-------------------------------------------------------------------------*/

/* StatBeh 
 * Calculates the statistic of the behaviour "b".
 */ 
static void StatBeh(b) 
     BehTyp b; 
{ 
  int type; 
  PAttrTyp a; 
  PAttrsTyp as;
  
  LASSERT((b==NULL) || (LookCopy(b)!=0));
  if (b && !VisitedB(b) ) {
    type = LookTypeB(b);
    for ( as =LookAttr(b); as != NULL ; as = Next_list(as)) {
      p_AttrLNodes++;
      p_lists++;
      a = (PAttrTyp) LookInfo_list(as);
      LASSERT(a->cont != 0);
      if ( a->cont > 0 ) {
	if ( a->cont > 1 ) {
	  ChangeContSign(a);
	  l_cont = Insert_list( (DataListTyp) a, l_cont);
	}
	p_attrs++;
	p_AttrCells[a->type][0]++;
	p_AttrCells[a->type][1] += a->cont>0 ? a->cont : -a->cont ;
	switch( a->type )
	  { case GLA  :   
	      Count_GLA(LookA(b,GLA ));
	      break;
	    case ELA  :   
	      Count_ELA(LookA(b,ELA ));
	      break;
	    case PA   :   
	      Count_PA(LookA(b,PA ));
	      break;
#ifdef TIME	  
	    case TA   :   
	      Count_TA(LookA(b,TA ));
	      break;
#endif
	    case OLA  :   
	      Count_OLA(LookA(b,OLA ));
	      break;
	    case VALA :   
	      Count_VALA(LookA(b,VALA ));
	      break;
	    case GSA  :   
	      Count_GSA();
	      break;
	    case GDLA :   
	      Count_GDLA(LookA(b,GDLA ));
	      break;
	    case RFLA :   
	      Count_RFLA(LookA(b,RFLA ));
	      break;
	    case ITCLA:   
	      Count_ITCLA(LookA(b,ITCLA));
	      break;
	    }
      }
    }
    p_BehCells[type][0] ++;    
    p_cells++;
    p_BehCells[type][1] += LookCopy(b)>0 ? LookCopy(b) : -LookCopy(b) ;
    StatBeh(b->b1);    
    StatBeh(b->b2);
  }
} 

/***************************************************************************
 *
 *  Print results.
 *
 ***************************************************************************/

/* PrintStatExpr
 * Prints the statistic about the expressions.
 */
extern void PrintStatExpr()
{
  char buff[256];
  
  printTarget("   ------------------- EXPRESSIONS -------------------\n\n"); 
  
  (void)sprintf(buff,"           Real accounting -> var=%d  ope=%d  list_nodes=%d\n",
		n_exprs[0],  n_exprs[1],  n_exprs[2]);
  printTarget(buff);
  (void)sprintf(buff,"        Virtual accounting -> var=%d  ope=%d  list_nodes=%d\n",
		n_exprs[3],  n_exprs[4],  n_exprs[5]);
  printTarget(buff);
  
  printTarget("\n\n");
}


/* ------------------------------------------------------------------------- */

/* PrintStatPT
 * Prints the statistic about the process table.
 */
extern void PrintStatPT()
{
  int i;
  char buff[256];
  
  printTarget("   --------------- TABLE OF PROCESSES ---------------\n\n"); 
  printTarget("     Usage of cells       cells /   copy\n"); 
  for (i=0 ; i<N_DEF_CELLS ; i++ ) {
    (void)sprintf(buff,"       %15s = %6d / %6d\n", 
		  GetNameCell(i),p_BehCells[i][0], p_BehCells[i][1]); 
    printTarget(buff);
  }
  printTarget("\n");
  
  printTarget("     Usage of attributes: (attr,cont) \n"); 
  
  (void)sprintf(buff,"       GLA   (%d,%d) List nodes:%d\n",
		p_AttrCells[GLA][0],p_AttrCells[GLA][1],n_GLA);  
  printTarget(buff);
  
  (void)sprintf(buff,"       GSA   (%d,%d)\n",
		p_AttrCells[GSA][0],p_AttrCells[GSA][1]);  
  printTarget(buff);
  
  (void)sprintf(buff,"       PA    (%d,%d) Var:%d  Oper:%d  ListNodes:%d\n",
		p_AttrCells[PA][0],p_AttrCells[PA][1],
		n_PA[0],n_PA[1],n_PA[2]);   
  printTarget(buff);
#ifdef TIME
  (void)sprintf(buff,"       TA    (%d,%d) Var:%d  Oper:%d  ListNodes:%d\n",
		p_AttrCells[TA][0],p_AttrCells[TA][1],
		n_TA[0],n_TA[1],n_TA[2]);   
  printTarget(buff);
#endif   
  (void)sprintf(buff,"       ELA   (%d,%d) List nodes:%d  Var:%d  Oper:%d\n",
		p_AttrCells[ELA][0],p_AttrCells[ELA][1],
		n_ELA[0],n_ELA[1],n_ELA[2]);  
  printTarget(buff);
  
  (void)sprintf(buff,"       OLA   (%d,%d) OLnodes:%d  Var:%d  Oper:%d  ListNodes:%d\n",
		p_AttrCells[OLA][0],p_AttrCells[OLA][1],
		n_OLA[0],n_OLA[1],n_OLA[2],n_OLA[3]);  
  printTarget(buff);
  
  (void)sprintf(buff,"       RFLA  (%d,%d) RFL nodes:%d\n",
		p_AttrCells[RFLA][0],p_AttrCells[RFLA][1],n_RFLA); 
  printTarget(buff);
  
  (void)sprintf(buff,
                "       VALA  (%d,%d) VA nodes:%d  List nodes:%d  Var:%d  Oper:%d\n",
		p_AttrCells[VALA][0],p_AttrCells[VALA][1],
		n_VALA[3],n_VALA[0],n_VALA[1],n_VALA[2]);   
  printTarget(buff);
  
  (void)sprintf( buff,
		"       GDLA  (%d,%d) GD nodes:%d  List nodes:%d  Gate sets:%d\n",
		p_AttrCells[GDLA][0],p_AttrCells[GDLA][1],n_GDLA[0],
		n_GDLA[0],n_GDLA[1]);   
  printTarget(buff);
  
  (void)sprintf(buff,"       ITCLA (%d,%d) ITC nodes:%d  List nodes:%d\n",
		p_AttrCells[ITCLA][0],p_AttrCells[ITCLA][1],
		n_ITCLA[1],n_ITCLA[0]);  
  printTarget(buff);
  
  printTarget("\n\n");
}


/* ------------------------------------------------------------------------- */

/* PrintStatGT
 * Prints the statistic about the gate table.
 */
extern void PrintStatGT()
{
  char buff[256];
  
  printTarget("   --------------- TABLE OF GATES ------------\n\n"); 
  (void)sprintf(buff,"     Gate sets used = %d \n\n",gtgs);
  printTarget(buff);
}

/* ------------------------------------------------------------------------- */

/* PrintStatFT
 * Prints the statistic about the functionality table.
 */
extern void PrintStatFT()
{
  char buff[256];
  
  printTarget("   ------------- TABLE OF FUNCTIONALITIES ------------\n\n"); 
  (void)sprintf(buff,"     Used cell = %d    Used list nodes = %d\n\n",
		ftcell,ftnode);
  printTarget(buff);
}

/* ------------------------------------------------------------------------- */

/* PrintStatOT
 * Prints the statistic about the operation table.
 */
extern void PrintStatOT()
{
  char buff[256];
  
  printTarget("   ------------- TABLE OF OPERATIONS -----------\n\n"); 
  printTarget("                               REAL   VIRTUAL \n"); 
  (void)sprintf(buff,"     Var. cells         = %9d %9d\n",
		otvarr,otvarv);
  printTarget(buff);
  (void)sprintf(buff,"     Opn. cells         = %9d %9d\n",
		otopnr,otopnv);
  printTarget(buff);
  (void)sprintf(buff,"     List nodes in expr = %9d %9d\n",
		otnler,otnlev);
  printTarget(buff);
  (void)sprintf(buff,"     Other list nodes   = %9d %9d\n\n",
		otnlr,otnlv);
  printTarget(buff);
  (void)sprintf(buff,"     Used rule cells = %d\n",otrule );
  printTarget(buff);
  (void)sprintf(buff,"     Used pmt nodes  = %d\n\n",otpmt );
  printTarget(buff);
}

/* ------------------------------------------------------------------------- */

/* PrintStatMove
 * Prints the statistic about the module move.
 */
extern void PrintStatMove()
{
  char buff[256];
  
  printTarget("   -------------------MODULE MOVE------------------\n\n"); 
  (void)sprintf(buff,"     Used list nodes = %d\n\n",nodes_move);
  printTarget(buff);
}

/* ------------------------------------------------------------------------- */


/* PMemoryLoss
 * Prints the results of the check of memory utilization
 */ 
extern void PMemoryLoss()
{
  char buff[256];
  
  printTarget("   ----------------- LOST MEMORY --------------------\n\n"); 
  printTarget("                 (queries,currently used,releases,lost,max)\n\n");   
  (void)sprintf(buff,"           Cells: %8d %8d %8d %8d %8d\n",
		uc,p_cells,rc,uc-rc-p_cells,mc);
  printTarget(buff);
  (void)sprintf(buff,"           Lists: %8d %8d %8d %8d %8d\n",
		ul , p_lists+otnler+otnlr+ftnode+nodes_move
		, rl , 
		ul-rl-p_lists-otnler-otnlr-ftnode-nodes_move, ml);  
  printTarget(buff);
  (void)sprintf(buff,"            Attr: %8d %8d %8d %8d %8d\n",
		ua,p_attrs,ra,ua-ra-p_attrs,ma);
  printTarget(buff);
  (void)sprintf(buff,"     offer nodes: %8d %8d %8d %8d %8d\n",
		uo,n_OLA[0],ro,uo-ro-n_OLA[0],mo);
  printTarget(buff);
  (void)sprintf(buff,"        RF nodes: %8d %8d %8d %8d %8d\n",
		ur,n_RFLA,rr,ur-rr-n_RFLA,mr);
  printTarget(buff);
  (void)sprintf(buff,"      gate sets : %8d %8d %8d %8d %8d\n",
		us,n_GSA+gtgs+n_GDLA[1],rs,us-rs-n_GSA-gtgs-n_GDLA[1],ms);  
  printTarget(buff);
  (void)sprintf(buff,"     expr. cells: %8d %8d %8d %8d %8d\n",
		ue,n_exprs[0]+n_exprs[1]+ftcell,re,
		ue-re-n_exprs[0]-n_exprs[1]-ftcell,me);
  printTarget(buff);
  (void)sprintf(buff,"       predicate: %8d %8d %8d %8d %8d\n",
		upr,n_PA[3],rpr,upr-rpr-n_PA[3],mpr);  
  printTarget(buff);
  (void)sprintf(buff,"              VA: %8d %8d %8d %8d %8d\n",
		uva,n_VALA[3],rva,uva-rva-n_VALA[3],mva);  
  printTarget(buff);
  (void)sprintf(buff,"              GD: %8d %8d %8d %8d %8d\n",
		ugd,n_GDLA[1],rgd,ugd-rgd-n_GDLA[1],mgd);  
  printTarget(buff);
  (void)sprintf(buff,"             ITC: %8d %8d %8d %8d %8d\n",
		uitc,n_ITCLA[1],ritc,uitc-ritc-n_ITCLA[1],mitc);  
  printTarget(buff);
  (void)sprintf(buff,"           tnode: %8d %8d %8d %8d %8d\n",
		utn,0,rtn,utn-rtn,mtn);  
  printTarget(buff);
  (void)sprintf(buff,"            rule: %8d %8d %8d %8d\n",
		urule,otrule,rrule,urule-rrule-otrule);  
  printTarget(buff);
  (void)sprintf(buff,"             pmt: %8d %8d %8d %8d\n",
		upmt,otpmt,rpmt,upmt-rpmt-otpmt);  
  printTarget(buff);
  (void)sprintf(buff,"        var pair: %8d %8d %8d %8d\n",
		uvp,0,rvp,uvp-rvp);  
  printTarget(buff);
  (void)sprintf(buff,"              SS: %8d %8d %8d %8d\n",
		uss,0,rss,uss-rss);  
  printTarget(buff);
  (void)sprintf(buff,"              2W: %8d %8d %8d %8d\n",
		u2w,0,r2w,u2w-r2w);  
  printTarget(buff);
  (void)sprintf(buff,"          StrBck: %8d %8d %8d %8d\n",
		usb,StatPrint(),rsb,usb-rsb-StatPrint());  
  printTarget(buff);
  (void)sprintf(buff,"             BST: %8d %8d %8d %8d\n",
		ubsn,0,rbsn,ubsn-rbsn);  
  printTarget(buff);

#ifdef TIME
  (void)sprintf(buff,"            time: %8d %8d %8d %8d %8d\n",
		utime,n_TA[3],rtime,utime-rtime-n_TA[3],mtime);  
  printTarget(buff);
#endif  
  printTarget("\n");
}

/*---------------------------------------------------------------------------*/

/* Calculate
 * Calculates the statistics
 */
extern void Calculate()
{
  int i;
  
  InitStat();       /* Initiate variables of this module    */
  
  /* PROCESS TABLE */
  for (i=1; i <= LastTableP(); ++i)
    StatBeh(GetP_def(i));
  
  /* FUNCTIONALITY TABLE */
  StatisticTableF(&ftcell, &ftnode); 
  
  /* OPERATION TABLE */
  StatisticTableO(&otvarv,&otopnv,&otvarr,&otopnr,
		  &otnlev,&otnler,&otnlv,&otnlr,
		  &otrule,&otpmt);
  n_exprs[0] += otvarr;
  n_exprs[1] += otopnr;
  n_exprs[2] += otnler;
  n_exprs[3] += otvarv;
  n_exprs[4] += otopnv;
  n_exprs[5] += otnlev;
  
  /* MOVE */
  nodes_move = StatMove();
  
  /* GATE TABLE */
  StatisticTableG(&gtgs); 
  
  /* MEMORY LOSS */
  StatCell(&uc, &rc, &mc, &ua, &ra, &ma);
  StatOffer(&uo, &ro, &mo);
  StatPred(&upr, &rpr, &mpr);
  StatRF(&ur,&rr,&mr);
  StatGS(&us,&rs,&ms);
  StatE(&ue,&re,&me,&utn,&rtn,&mtn);
#ifdef TIME
  StatTime(&utime, &rtime, &mtime);
#endif  
  StatVA(&uva,&rva,&mva);
  StatGD(&ugd,&rgd,&mgd);
  StatITC(&uitc,&ritc,&mitc);
  StatRule(&urule,&rrule);
  StatPMT(&upmt,&rpmt);
  StatVP(&uvp,&rvp);
  StatSS(&uss,&rss);
  Stat2W(&u2w,&r2w);
  StatStrBck(&usb,&rsb);
  StatBST(&ubsn,&rbsn);
  
  End_VisitB();
  Free_list(l_cont, ChangeContSign);
  End_VisitE();
  Stat_list(&ul, &rl, &ml);
}

/*---------------------------------------------------------------------------*/

/* PCellDistribution
 * Prints the cell distribution by sizes.
 */ 
static void PCellDistribution()
{
  char buff[256];
  int i,total,released;
  
  printTarget("   ----------------- CELL DISTRIBUTION -----------------\n\n"); 
  printTarget("           (cell size: total,released,granted)\n\n");   
  for ( i=MINBLOCKSIZE; i<=MAXBLOCKSIZE; i += WORDBYTES ){
    StatCellM( i, &total, &released );
    if ( total!=0 ){
      (void)sprintf(buff,"           %8d: %8d %8d %8d\n",
		    i,total,released,total-released);
      printTarget(buff);
    }
  }
}

#endif  /* SDEBUG */

/*---------------------------------------------------------------------------*/

/***************************************************************************
 *
 *  Main function.
 *
 ***************************************************************************/

/* Statistic
 * Calculates and prints statistics about the usage of memory.
 */
extern void Statistic()
{
  PrintUsageMemoTime();   /* Memory and time usage */
  
#ifdef SDEBUG
  Calculate();
  
  PrintStatExpr();
  PrintStatPT();
  PrintStatFT();    
  PrintStatGT();    
  PrintStatOT();    
  PrintStatMove();    
  PMemoryLoss();
  PrintSize_Tables(); 
  PCellDistribution();
  printTarget("\n");
#endif
}


/*---------------------------------------------------------------------------*/

