/***********************************
  (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
 $Log: board.c,v $
 * Revision 2.7  1993/07/06  15:13:47  lotos
 * bug fis: reference to tables to find out variable sorts
 *
 * Revision 2.6  1993/06/28  19:12:30  lotos
 * max_var -> max_accepted
 *
 * Revision 2.5  1993/06/23  15:44:45  lotos
 * remove undesired traces (level 2)
 *
 * Revision 2.4  1993/01/18  18:25:53  lotos
 * distribution issues
 *
 * Revision 2.3  1993/01/12  14:28:53  lotos
 * minor bug fixing
 *
 * Revision 2.2  1992/11/17  17:27:06  lotos
 * var -> rav
 * success -> xto
 * distinguish kdatum / udatum
 *
 * Revision 2.1  1992/10/20  17:49:56  lotos
 * new KT evaluation algorithm
 * new Lbeta interface
 * cleaning, code optimization, space saving, bugs, ...
 *
 * Revision 1.9  1992/05/07  19:53:06  lotos
 * initialization of structures revisited for completeness
 *
 * Revision 1.8  92/05/06  18:54:50  lotos
 * send traces to stderr
 * make min-delay functionality upward compatible
 * 
 * Revision 1.7  92/03/05  17:37:11  lotos
 * just a few more bugs went to the hell
 * 
 * Revision 1.6  92/03/04  14:52:53  lotos
 * 100 minor bugettes
 * 
 * Revision 1.5  92/02/29  13:26:13  lotos
 * miscellaneous bug fixing
 * 
 * Revision 1.4  92/02/12  18:47:48  lotos
 * ni idea, era una version que andaba por ahi ...
 * 
 * Revision 1.3  92/01/15  12:41:07  lotos
 * a bug in frames
 * change success and values
 * 
 * Revision 1.2  92/01/14  19:38:06  lotos
 * lint fixes
 * 
 * Revision 1.1  92/01/14  19:26:10  lotos
 * Initial revision
 * 
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: board.c,v 2.7 1993/07/06 15:13:47 lotos Exp $";
#endif

#include "swbus.h"
/* LINTLIBRARY */

  /*------------------------------------------------
    ------------------------------------------------
    --           OBJECT MANAGEMENT                --
    ------------------------------------------------
    ------------------------------------------------*/
   
PUBLIC void 
cut (brd)
 board brd;
{
     brd->offer = NULL;  

     if (brd->sons != NULL) {
       if (brd->sons->bth != NULL){
	 cut (brd->sons->bth);
	 brd->sons->bth= NULL;
	 }
       cut (brd->sons);
       brd->sons= NULL;
     }   
     if(brd->btype == b_ad ||
	brd->btype == b_ex ||
	brd->btype == b_dl ||
	brd->btype == b_wt ||
	brd->btype == b_ii ) 
       remove_lq (brd);
     freeboard (brd);
} 

       /***********************************/ 
  
void  
  clean (brd)
board brd ;

{
  while(brd != NULL){
    brd->offer = NULL;
    if (brd->bth != NULL) 
      clean (brd->bth);
    brd=  brd->sons;
  }
} 

      /****************************************/

void
  sustitute_brd (target, new)
board target;
board new;
{
  board brt;

  /* kill the other branch */
  
  brt       = brother(new);
  if(brt != NULL) {
    brt->bth  = NULL;
    new->bth  = NULL;
    cut (brt);
  }
  new->bth = target->bth;
  if (target->fth->sons != target) 
    target->fth->sons->bth = new;
  else
    target->fth->sons = new;
  new->fth = target->fth;

  target->bth = NULL;
  target->fth = NULL;
  target->sons = NULL;
  target->offer= NULL;
  freeboard(target);	
}
      /****************************************/

void  
value_en_passing (b)
 board b;

{
  register int i;

  if (b->num_fields != 0) {
    for (i=0; i < b->num_fields; i++) 
      b->frm->rav[b->rav[i]]=ud_copy(TSsorts[b->frm->but][b->rav[i]],xto[i]);
    freevar (b->rav);
    b->rav        = NULL;
    b->num_fields = 0;
  }
  b->btype      = b_us; 
}

      /****************************************/

PUBLIC board 
initial_tree ()
{
  board H= newboard ();
  board B= newboard ();
  frame F= newframe ();   
  
  set_type (H,b_kt);
  B->frm    = F;
  F->but    = 0;
  F->ent    = 0;
  H->sons   = B;
  B->fth    = H;
  H->bth    = NULL;
  Ready_queue  = NULL;
  Leaves_queue = NULL;
  return H;
}

     /*--------------------------------------
     --- AUX FUNCTIONS FOR MAKING THE TREE --
     --------------------------------------*/

void 
  one_new_son (b,e)
board b;
entryp e;

{
  frame frm  = b->frm;
  board brs  = newboard ();
  
  brs->fth   = b;
  b->sons    = brs;
  brs->frm   = frm;
  b->frm     = NULL;
  frm->ent   = e;
}

void 
  two_new_sons (b,e1,e2)
board    b;
entryp   e1; 
entryp   e2;

{
  frame    frm  = b->frm;
  frame    frm2 ;
  board    sl   = newboard ();        /* son left  */
  board    sr   = newboard ();        /* son right */
  
  b->frm  = NULL;
  frm2    = frmcpy (frm);
  
  sl->fth = b;
  sr->fth = b;
  b->sons = sl;
  sl->bth = sr;     
  
  sl->frm = frm;
  sr->frm = frm2;

  frm->ent  = e1;
  frm2->ent = e2;
}

void 
evol_annot (brd)
 board brd;
{
  if (konfig.trace != 0)
    draw_node(brd);

  remove_lq(brd);  
  brd->prd    = NO_PRD; 
  brd->btype  = b_us;
  bctbl (brd);
}


  /*------------------------------------------------
    ------------------------------------------------
    --             MEMORY MANAGEMENT             --
    ------------------------------------------------
    ------------------------------------------------*/
PRIVATE board free_board = NULL;

#define BRD_BUCK 300

       /*  --         CREATE        -- */
PUBLIC  board
newboard ()
{
  static   unsigned buck_size= sizeof(st_board) * BRD_BUCK;
  register board  b;
  register int    i;
  
  if (free_board == NULL) {
    b= (board) my_malloc (buck_size);
    free_board = b;
    for (i= 0; i < (BRD_BUCK -1); i++)
      b[i].mmg= &b[i+1];
    b[BRD_BUCK -1].mmg= NULL;
  }
  b= free_board;
  free_board = b->mmg;
  b->fth        = NULL;
  b->bth        = NULL;
  b->sons       = NULL;
  b->num_fields = 0;
  b->frm        = NULL;
  b->offer      = NULL;
  b->gte        = NULL;
  b->gte_r      = NULL;
  b->r_leaf     = NULL;
  b->l_leaf     = NULL;
  b->rav        = NULL;
  b->offer      = NULL;
  b->btype = b_us;
  b->mmg   = NULL;
  b->prd   = NO_PRD;
  b->stime = 0;
  return b;
 }

       /*  --         DESTROY       -- */
void 
freeboard (b)
  board b;  
{
  
  if (b->btype == b_hd ||
      b->btype == b_pe) {
    freegte(b->gte);
    b->gte = NULL;
  } else if (b->btype == b_re) {
    freergte(b->gte_r);
    b->gte_r = NULL;
  } else if (b->btype == b_en) {
    if (b->rav != NULL) {
      freevar(b->rav);
      b->rav = NULL;
    }
  }

  if (b->frm != NULL) {
    freeframe (b->frm);
    b->frm = NULL;
  }
  b->btype = b_fr;
  b->mmg = free_board;
  free_board =b;

} 


  
  /*------------------------------------------------
    ------------------------------------------------
    --                    DRAW                    --
    ------------------------------------------------
    ------------------------------------------------*/


 
void   
draw_node (n)
board n;
{
  dump_node (stderr,n);
}

 
void   
  dump_node (fp,n)
FILE * fp;
board n;
{
  gate_list  ig;
  var_list   ivt;
  frame      frm;
  int        num;
  int        i;
  offert     o;  
  int        t;

  if (n == NULL) 
    return;
  
  
  ig  = n->gte;
  ivt = n->rav;
  frm = n->frm;
  num = n->num_fields;
  if (frm!=NULL)
    o = n->frm->off;
  else 
    o = NULL;

  switch (n->btype) {
  case b_re :
    (void) fprintf (fp, "relabel [");
    for (i=1; i<= num; i++) 
      (void) fprintf (fp," %d - %d ", n->gte_r [i],i);
    (void) fprintf (fp, " ]");
    break;    
  case b_hd :
    (void) fprintf (fp, "hide [");
    for (i=0; i< max_gte; i++) 
      if (ig[i])
	(void) fprintf (fp,"%d ", i);
    (void) fprintf (fp, " ] in ");
    break;    
  case b_en :
    (void) fprintf (fp, ">>");
      (void) fprintf (fp, " accept ");
    for (i=0; i< num; i++)  {
      if (g_flag)
	(void) fprintf (fp," %s : %s",TSvariables[frm->but][ivt[i]],
			sort_tbl [TSsorts[frm->but][ivt[i]]].name);
      else
	(void) fprintf (fp," %d ",ivt[i]);
    }
    break;    
  case b_ds :
    (void) fprintf (fp, "[>");
    break;    
  case b_ps :
    (void) fprintf (fp, "|| ");
    break;
  case b_pi :   
    (void) fprintf (fp, "|||");
    break;
  case b_pe :      
    (void) fprintf (fp, "|[ ");
    for (i=0; i< max_gte ; i++) 
      if( ig[i])
	(void) fprintf (fp,"%d ",i);
    (void) fprintf (fp, "]| ");
    break;
  case b_ch : 
    (void) fprintf (fp, "[] ");
    break;    
  case b_st :
    (void) fprintf (fp, "stop ");
    break;    
  case b_ii :
    (void) fprintf (fp, "i ;");
    break;    
  case b_ad :
    if (!g_flag )
      (void) fprintf (fp, "(ad)");  
    if (o != NULL) {
      if(!g_flag)  {
	(void) fprintf (fp,"%d-%d  ", o->adg,o->sort_id);
      } else {
	(void) fprintf (fp,"%s", TSgates[frm->but][o->adg]);
      }
      
      for (i=0; i< TSsizes[o->sort_id]; i++) {
	if (o->exp[i]->class == '!') 
	  (void) fprintf (fp, " ! %s", 
		   draw (TSsbes[o->sort_id][i], o->exp[i]->val));
	if (o->exp[i]->class == '?') 
	  if(!g_flag)
	    (void) fprintf(fp, " ? %d", o->exp[i]->rav);
	  else
	(void) fprintf (fp," %s : %s",TSvariables[frm->but][o->exp[i]->rav],
			sort_tbl [TSsbes[n->offer->sort_id][i]].name);
	if (o->exp[i]->class == '*') 
	  (void) fprintf (fp, " * ");
      }
      if (o->prd != NO_PRD) 
	(void) fprintf (fp," [ %d ]", o->prd);
    }
    break;    
  case b_ex :
    (void) fprintf (fp, "exit ");
  if (o != NULL) {

    for (i=0; i< TSsizes[o->sort_id]; i++) {
      if (o->exp[i]->class == '!') 
	  (void) fprintf (fp, " ! %s", 
		   draw (TSsbes[o->sort_id][i],o->exp[i]->val));
	if (o->exp[i]->class == '?')
	  if(!g_flag)
	    (void) fprintf(fp, " ? %d", o->exp[i]->rav);
	  else
	    (void) fprintf(fp," %s : %s",TSvariables[frm->but][o->exp[i]->rav],
			    sort_tbl [TSsbes[n->offer->sort_id][i]].name);
      if (o->exp[i]->class == '*') 
	(void) fprintf (fp, "*");
    }
    if (o->prd != NO_PRD) 
      (void) fprintf (fp," [ %d ]", o->prd);
  }
    break;
  case b_dl :
    t =((n->stime)-time(NULL) );
     if (t == 0)
       (void) fprintf (fp,"(*| delay |*)");
     else
       (void) fprintf (fp,"(*| delay %d |*)",((n->stime)-time(NULL)));
    break;    
  case b_wt :   
    (void) fprintf (fp,"(*| wait %d |*) ", n->prd);
    break;
  case b_se : 
    (void) fprintf (fp, "Successful Exit ");
    break;    
  case b_us :
    (void) fprintf (fp, "UNSTABLE ");
    break;    
  case b_kt :
    (void) fprintf (fp, "<b_kt>");
    break;
    default :
      (void) fprintf (fp, "< %d > ",n->btype);
  } 
  
  
/*   dump_frame (fp,frm); */
  
  (void) fprintf (fp, "\n");
  
}




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

  
  /*------------------------------------------------
    ------------------------------------------------
    --             MEMORY MANAGEMENT             --
    ------------------------------------------------
    ------------------------------------------------*/

PRIVATE var_list   var_free  = NULL; 
PRIVATE gate_list  gte_free  = NULL; 
PRIVATE rel_g_list rgte_free = NULL; 


#define  VAR_BUCK  50
#define  GTE_BUCK  50
#define  RGTE_BUCK 50

       /*  --         CREATE        -- */

/*  variables list */

var_list
  newvar ()
{
  static  var_list  v;
  register int i; 

  if (var_free == NULL ) {
    v = (var_list)my_malloc (VAR_BUCK * max_accepted * sizeof(variable));
    var_free    = v;
    for (i=0; i< VAR_BUCK; i ++) 
      v[i * max_accepted] = (variable) & v[ (i+1) * max_accepted];
    v[(VAR_BUCK -1)* max_accepted] = (variable) NULL;
  }
  
  v = var_free;
  var_free = (var_list) v[0];

  for (i=0; i < max_accepted ; i++) 
    v[i] = NO_VAR;
 
  return v;
}


/*  gate list */

gate_list
  newgte ()
{
  static  gate_list  g;
  register int i;

 if (gte_free == NULL ) {
    g = (gate_list)my_malloc (GTE_BUCK * max_gte * sizeof(boolean));
    gte_free    = g;
    for (i=0; i< (GTE_BUCK); i ++) 
      g[i * max_gte] = (boolean) & g[ (i+1) * max_gte];
    g[(GTE_BUCK -1)* max_gte] = (boolean) NULL;
  }
  g = gte_free;
  gte_free = (gate_list) g[0];

  for (i=0; i < max_gte ; i++) 
    g[i] = FALSE;
  
  return g;
}

/* relabel gate list */

rel_g_list
  newrgte ()
{
  rel_g_list  g;
  register int i;

 if (rgte_free == NULL ) {
    g = (rel_g_list)my_malloc (RGTE_BUCK * max_gte * sizeof(gate));
    rgte_free    = g;
    for (i=0; i< (RGTE_BUCK); i ++) 
      g[i * max_gte] = (gate) & g[ (i+1) * max_gte];
    g[(RGTE_BUCK -1)* max_gte] = (gate) NULL;
  }
    g = rgte_free;
    rgte_free = (rel_g_list) g[0];

  for (i=0; i < max_gte ; i++) 
    g[i] = NO_GTE;

  return g;
}


       /*  --         DESTROY       -- */



/*  gate list */
void 
  freegte (g) 
gate_list g; 
{
 g[0] = (boolean) gte_free;
 gte_free = g;
}


/* relabel gate list */

void 
  freergte (g)
rel_g_list g;
{
 g[0] = (gate) rgte_free;
 rgte_free = g;
}
/*  variables list */


void 
freevar (v)
var_list v;
{
 v[0] = (variable) var_free;
 var_free = v;
}

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



