/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : DESB  v2.n                                                  */
/*    Fichier : sl_util.c                                                   */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) : Luc BURGUN                            le : 06/09/1991     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include"head.h"

chain_list * ptr_ctrlst = NULL ;

/*-------------------------------------------------------------------------
gensym 		: calcule un identificateur avec concatenation d'un numero.
---------------------------------------------------------------------------
retour		: un pointeur de chaine de caracteres.
---------------------------------------------------------------------------*/
char *gensym(name,num)
char *name;
int num;
{
char *name1;
char number[5];
char *retour;

name1 = (char *) malloc (strlen(name)+7);
sprintf(name1,"%s%d\0",name,num);
retour = namealloc(name1);
free(name1);
return(retour);
}

/*-------------------------------------------------------------------------
verifCohBeh 	: verifie la cohenrence de la befig / param. 
---------------------------------------------------------------------------
retour		: 1 si Ok , 0 sinon.
---------------------------------------------------------------------------*/

int verifCohBeh(beh,delaypi,optimpo)
befig_list *beh;
ptype_list *delaypi;
chain_list *optimpo;
{
while (delaypi)
   {
   if (!existInputBeh(beh,delaypi->DATA) && !existAuxBeh(beh,delaypi->DATA))
      {
      printf("warning : input '%s' doesn't exists in '%s'\n",delaypi->DATA,beh->NAME);
      }
   delaypi = delaypi->NEXT;
   }
while (optimpo)
   {
   if (!existOutputBeh(beh,optimpo->DATA))
      {
      printf("warning : output '%s' doesn't exists in '%s'\n",optimpo->DATA,beh->NAME);
      }
   optimpo = optimpo->NEXT;
   }
}

/*-------------------------------------------------------------------------
removeAuxBeh 	: elimination des variables auxiliaires d'une befig
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/

void removeAuxBeh(beh,saveAux)
befig_list *beh;
chain_list *saveAux;
{
beaux_list *aux,*aux1;
beaux_list *beh_addbeaux();


aux = beh->BEAUX;
beh->BEAUX = NULL;

		/* parcours de la ptype_list des aux a sauvegarder */
while (saveAux)
   {
   aux1 = aux;
   while (aux1)
      {
      if (aux1->NAME == (char*)saveAux->DATA)
         break;
      aux1 = aux1->NEXT;
      }   
   if (aux1)
      {
      printf("remove : sauve %s\n",saveAux->DATA);
      beh->BEAUX = beh_addbeaux(beh->BEAUX,saveAux->DATA,copyExpr(aux1->ABL),NULL);
      (beh->BEAUX)->NODE = aux1->NODE;
      }
   saveAux = saveAux->NEXT;
   }

while (aux)
   {
   aux1 = aux->NEXT;
   aux->NEXT = NULL;
   if (aux->ABL != NULL)
      freeExpr(aux->ABL);
   free(aux); 
   aux = aux1;
   }
}


/*-------------------------------------------------------------------------
flatArityExprBeh: mise a plat (elimination des operateurs redondants)
                  des abl(s) d'une befig. 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/
void flatArityExprBeh(beh)
befig_list *beh;
{
beout_list *out;
bereg_list *reg;
bebus_list *bus;
biabl_list *biabl;
beaux_list *aux;

aux = beh->BEAUX;
while (aux) 
   {
   if (aux->ABL)
      {
      flatArityExpr(aux->ABL);
      }
   aux = aux->NEXT;
   }

out = beh->BEOUT;
while (out) 
   {
   if (out->ABL)
      {
      flatArityExpr(out->ABL);
      }
   out = out->NEXT;
   }

reg = beh->BEREG;
while (reg) 
   {
   biabl = reg->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         flatArityExpr(biabl->CNDABL);
         flatArityExpr(biabl->VALABL);
         }
      biabl = biabl->NEXT;
      }
   reg = reg->NEXT;
   }

bus = beh->BEBUS;
while (bus) 
   {
   biabl = bus->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         flatArityExpr(biabl->CNDABL);
         flatArityExpr(biabl->VALABL);
         }
      biabl = biabl->NEXT;
      }
   bus = bus->NEXT;
   }
}

/*-------------------------------------------------------------------------
existAuxBeh	: verifie l'existence de name dans BEAUX de beh. 
---------------------------------------------------------------------------
retour		: 1 si OK, 0 sinon. 
---------------------------------------------------------------------------*/
int existAuxBeh(beh,name)
befig_list *beh;
char *name;
{
beaux_list *aux = beh->BEAUX;
while (aux)
   {
   if (name == aux->NAME)
      return(1);
   aux = aux->NEXT;
   }
return(0);
}


/*-------------------------------------------------------------------------
existInputBeh	: verifie l'existence de name dans BERIN de beh. 
---------------------------------------------------------------------------
retour		: 1 si OK, 0 sinon. 
---------------------------------------------------------------------------*/
int existInputBeh(beh,name)
befig_list *beh;
char *name;
{
berin_list *in = beh->BERIN;
while (in)
   {
   if (name == in->NAME)
      return(1);
   in = in->NEXT;
   }
return(0);
}


/*-------------------------------------------------------------------------
existOutputBeh	: verifie l'existence de name dans BEOUT,BEREG ou BEBUS de beh. 
---------------------------------------------------------------------------
retour		: 1 si OK, 0 sinon. 
---------------------------------------------------------------------------*/
int existOutputBeh(beh,name)
befig_list *beh;
char *name;
{
beout_list *out = beh->BEOUT;
bereg_list *reg = beh->BEREG;
bebus_list *bus = beh->BEBUS;

while (out)
   {
   if (name == out->NAME)
      return(1);
   out = out->NEXT;
   }

while (bus)
   {
   if (name == bus->NAME)
      return(1);
   bus = bus->NEXT;
   }

while (reg)
   {
   if (name == reg->NAME)
      return(1);
   reg = reg->NEXT;
   }
return(0);
}

/*-------------------------------------------------------------------------
countInputBeh 	: compte les entrees d'un circuit (berin)
---------------------------------------------------------------------------
retour		: un int.
---------------------------------------------------------------------------*/

int countInputBeh(beh)
befig_list *beh;
{
berin_list *in;
int count = 0;

in = beh->BERIN;	/* entrees primaires */
while (in)
   {
   in = in->NEXT;
   count++;
   };

return(count);
}

/*-------------------------------------------------------------------------
profExprBeh 	: calcule la profondeur d'une PO jusqu'a ses PI. 
---------------------------------------------------------------------------
retour		: un int.
---------------------------------------------------------------------------*/

int profExprBeh(beh,expr)
befig_list *beh;
chain_list *expr;
{
int result;

ptype_list **aux;
aux = (ptype_list **) malloc (sizeof (ptype_list *));
*aux = NULL;
result = profExprBehInt(expr,beh,1000,aux);
freeptype(aux);
return(result);
}

int profExprBehInt(expr,beh,oper,ppAux)
chain_list *expr;
befig_list *beh;
int oper;
ptype_list **ppAux;
{
if (ATOM(expr))
   {
   if (VALUE_ATOM(expr) == namealloc("'0'") ||  /* constante */
       VALUE_ATOM(expr) == namealloc("'1'"))
      return(0);
   if (existInputBeh(beh,VALUE_ATOM(expr)))  	/* c'est une PI */
      return(0);
   else
      {						/* c'est une AUX */
      beaux_list *aux = beh->BEAUX;
      ptype_list *lstAux = *ppAux;

      while (lstAux)				/* Aux deja calcule ? */
         {
         if ((char*)lstAux->DATA == VALUE_ATOM(expr))
            return((int) lstAux->TYPE);
         lstAux = lstAux->NEXT;
         }
			/* on recupere l'ABL */

      while (aux)
         {
         if (aux->NAME == VALUE_ATOM(expr))
            {
            int prof = profExprBehInt(aux->ABL,beh,oper,ppAux);

			/* insertion liste ppAux */

            *ppAux = addptype(*ppAux,prof,VALUE_ATOM(expr));             
            return(prof);
            }
         aux = aux->NEXT;
         }
      printf("profExprBeh : error auxilliary variable doesn't exist\n");
      exit(-1);
      }
   }
else
		/* traitement operateur */
   {
   int maxProf=0,inter;
   int operInt = OPER(expr);
   int arity = lengthExpr(expr);

   if (operInt == NOT)
      return(profExprBehInt(CADR(expr),beh,operInt,ppAux));

   while (expr = CDR(expr))
      {
      inter = profExprBehInt(CAR(expr),beh,operInt,ppAux);
      if (maxProf < inter)
         maxProf = inter;
      } 
/*
   if (oper == operInt)
      return(maxProf);
*/
   if (arity > 3)
      return(++maxProf + log ((double) arity));
   else
      return(++maxProf);
   }
}

/*-------------------------------------------------------------------------
numberAtomExprBeh 	: calcule le nombre de litteraux d'une PO jusqu'a
                          ses PI. 
---------------------------------------------------------------------------
retour		: un int.
---------------------------------------------------------------------------*/

int numberAtomExprBeh(beh,expr)
befig_list *beh;
chain_list *expr;
{
int result;

ptype_list **aux;
aux = (ptype_list **) malloc (sizeof (ptype_list *));
*aux = NULL;
result = numberAtomExprBehInt(expr,beh,aux);
freeptype(aux);
return(result);
}

int numberAtomExprBehInt(expr,beh,ppAux)
chain_list *expr;
befig_list *beh;
ptype_list **ppAux;
{
if (ATOM(expr))
   {
   if (VALUE_ATOM(expr) == namealloc("'0'") ||  /* constante */
       VALUE_ATOM(expr) == namealloc("'1'"))
      return(1);
   if (existInputBeh(beh,VALUE_ATOM(expr)))  	/* c'est une PI */
      return(1);
   else
      {						/* c'est une AUX */
      beaux_list *aux = beh->BEAUX;
      ptype_list *lstAux = *ppAux;

      while (lstAux)				/* Aux deja calcule ? */
         {
         if ((char*)lstAux->DATA == VALUE_ATOM(expr))
            return((int) lstAux->TYPE);
         lstAux = lstAux->NEXT;
         }

      while (aux)
         {
         if (aux->NAME == VALUE_ATOM(expr))
            {
            int sum = numberAtomExprBehInt(aux->ABL,beh,ppAux);

			/* insertion liste ppAux */

            *ppAux = addptype(*ppAux,sum,VALUE_ATOM(expr));             
            return(sum);
            }
         aux = aux->NEXT;
         }
      printf("numberAtomExprBeh : error auxilliary variable doesn't exist ");
      printf("--> %s\n",VALUE_ATOM(expr));
      exit(-1);
      }
   }
else
		/* traitement operateur */
   {
   int sum=0;

   if (OPER(expr) == NOT)
      return(numberAtomExprBehInt(CADR(expr),beh,ppAux));

   while (expr = CDR(expr))
      {
      sum += numberAtomExprBehInt(CAR(expr),beh,ppAux);
      } 
   return(sum);
   }
}
/*-------------------------------------------------------------------------
berinToChain_list 	: prend l'odre d'apparition.
---------------------------------------------------------------------------
retour		: un pointeur de chain_list.
---------------------------------------------------------------------------*/
chain_list *berinToChain_list(beh)
befig_list *beh;
{
berin_list *in;
chain_list *lst;

in = beh->BERIN;	/* entrees primaires */
lst = NULL;
while (in)
   {
   lst = addchain(lst,in->NAME);
   in = in->NEXT;
   };

return(lst);
}

/*-------------------------------------------------------------------------
createExprCL 	: cree une expression d'operateur oper et d'arguments
		  existants dans la liste chainee LC 
---------------------------------------------------------------------------
retour		: un pointeur de chain_list.
---------------------------------------------------------------------------*/
chain_list *createExprCL(oper,LC)
short oper;
chain_list *LC;
{
chain_list *result;

result = createExpr(oper);
while (LC)
   {
   addQExpr(result,createAtom(LC->DATA));
   LC = LC->NEXT;
   }
return(result);
}

/*----------------------------------------------------------------------------
displayChain_list : affiche en colonnes les entrees ou sortie donnees par une LC
------------------------------------------------------------------------------
retour		: le nombre de colonnes affichees    (int)
----------------------------------------------------------------------------*/ 


int		 displayChain_list( IO, nbCol, nbLig, ligneDepart )
chain_list	*IO;
int		 nbCol;
int		 nbLig;
int		 ligneDepart;

{
int		 largeurCol;
int		 currentCol = 1;
int		 currentLig = ligneDepart;
 
while ( nbCol*nbLig < countChain_list( IO ) )  nbCol++;

largeurCol = 80/nbCol;
while ( IO )  {
	while ( (currentLig<(nbLig+ligneDepart)) && (IO!=NULL) ) {
		gotolc( currentLig, currentCol );
		printf(" %s",IO->DATA);
		IO = IO->NEXT;
		currentLig++;
		}
	currentCol += largeurCol;
	currentLig = ligneDepart;
	};
return ( nbCol );
}


/*----------------------------------------------------------------------------
displayPtype_list: affiche en colonnes les entrees donnees par une LC typee
------------------------------------------------------------------------------
retour		: le nombre de colonnes affichees    (int)
----------------------------------------------------------------------------*/ 

int		 displayPtype_list( IOt, nbCol, nbLig, ligneDepart )
ptype_list	*IOt;
int		 nbCol;
int		 nbLig;
int		 ligneDepart;

{
int		 largeurCol;
int		 currentCol = 1;
int		 currentLig = ligneDepart;
 
while ( nbCol*nbLig < countPtype_list( IOt ) )  nbCol++;

largeurCol = 80/nbCol;

while ( IOt )  {
	while ( (currentLig<(nbLig+ligneDepart)) && (IOt!=NULL) ) {
		gotolc( currentLig, currentCol );
		printf(" %s:", IOt->DATA );
		printf(" %.2f",((float)(IOt->TYPE))/100);
		IOt = IOt->NEXT;
		currentLig++;
		}
	currentCol += largeurCol;
	currentLig = ligneDepart;
	};
return ( nbCol );
}
			


/*-----------------------------------------------------------------------------
countChain_list	: count le nombre d'elements d'une chaine_list
-------------------------------------------------------------------------------
retour		: un int
-----------------------------------------------------------------------------*/
int		 countChain_list( CL )
chain_list	*CL;
{
int 		count = 0;
chain_list	*auxiliaire = CL;

while ( auxiliaire ) {
	auxiliaire = auxiliaire->NEXT;
	count++;
	};
return ( count );
}


/*-----------------------------------------------------------------------------
countPtype_list	: count le nombre d'elements d'une chaine_list typee
-------------------------------------------------------------------------------
retour		: un int
-----------------------------------------------------------------------------*/
int		 countPtype_list( CL )
ptype_list	*CL;
{
int 		count = 0;
ptype_list	*auxiliaire = CL;

while ( auxiliaire ) {
	auxiliaire = auxiliaire->NEXT;
	count++;
	};
return ( count );
}



/*-----------------------------------------------------------------------------
inChain_list	: renvoie la position d'une DATA  dans une LC et 0 si elle
		n'existe pas
-------------------------------------------------------------------------------
retour		: un int
-----------------------------------------------------------------------------*/
int		 inChain_list( CL, data )
chain_list	*CL;
char		*data;
{
int 		count = 1;
chain_list	*auxiliaire = CL;

while ( auxiliaire ) {
	if ( strcmp( auxiliaire->DATA, data ) == 0 )  return ( count );
	auxiliaire = auxiliaire->NEXT;
	count++;
	};
return ( 0 );
}


/*-----------------------------------------------------------------------------
inPtype_list	: renvoie la position d'une DATA  dans une LC typee et 
		  0 si elle n'existe pas
-------------------------------------------------------------------------------
retour		: un int
-----------------------------------------------------------------------------*/
int		 inPtype_list( CL, data )
chain_list	*CL;
char		*data;
{
int 		count = 1;
chain_list	*auxiliaire = CL;

while ( auxiliaire ) {
	if ( strcmp( auxiliaire->DATA, data ) == 0 )  return ( count );
	auxiliaire = auxiliaire->NEXT;
	count++;
	};
return ( 0 );
}

/*-----------------------------------------------------------------------------
searchExprBeh	: renvoie l'abl d'une AUX ou d'une OUT si il existe.
                  si type est a 0 : recherche dans les BEOUT.
                                1 :                    BEAUX.
                  sinon double recherche.
-------------------------------------------------------------------------------
retour		: un pointeur de chain_list ou NULL
-----------------------------------------------------------------------------*/
chain_list *searchExprBeh(beh,name,type)
befig_list *beh;
char *name;
int type;
{

if (type != 0)
   {
   beaux_list *aux=beh->BEAUX;
   while (aux) 
      {
      if (aux->NAME == name)
         return(aux->ABL);
      aux = aux->NEXT;
      }
   }

if (type != 1)
   {
   beout_list *out=beh->BEOUT;
   while (out) 
      {
      if (out->NAME == name)
         return(out->ABL);
      out = out->NEXT;
      }
   }
		/* rien trouve ! */
return(NULL);
}


/* ###--------------------------------------------------------------### */
/* function	: makeBddBeh						*/
/* description	: evalue bdds for each input, output or bus, connector	*/
/*    	          register signal, and auxilliary signal of ptr_befig	*/
/* called func.	: makeBddAbl, addchain <mbk> 				*/
/* ###--------------------------------------------------------------### */

int makeBddBeh( ptr_befig, ptr_circuit, reorder, trace, max_node )

struct befig *ptr_befig;		/* pointer on current BEFIG	*/
pCircuit      ptr_circuit;		/* pointer on current circuit	*/
int           reorder;			/* order parameter 		*/
int trace;
int max_node;

  {
  pNode makeBddAbl();
  int vhb_numberNode = sysBdd.pRT->compteur;
  int vhb_count = 0;

  ptr_ctrlst = NULL;

  if (trace)
    {
    printf("Running Abl2Bdd on `%s`...\n\n",ptr_befig->NAME);
    }


  if (ptr_befig->BEMSG != NULL)
    {
    struct bemsg *ptr_bemsg;
    ptr_bemsg=ptr_befig->BEMSG;
    while (ptr_bemsg != NULL)
      {
      if ((ptr_bemsg->ABL != NULL) && (ptr_bemsg->NODE == NULL))
          {
          ptr_bemsg->NODE = makeBddAbl (ptr_circuit,ptr_bemsg->ABL,ptr_befig,&vhb_count);
	  }
      ptr_bemsg = ptr_bemsg->NEXT;
      }
    }

  if (ptr_befig->BEOUT != NULL)
    {
    struct beout *ptr_beout;
    ptr_beout=ptr_befig->BEOUT;
    while (ptr_beout != NULL)
      {
      if ((ptr_beout->ABL != NULL) && (ptr_beout->NODE == NULL))
	  {
          ptr_ctrlst = addchain (ptr_ctrlst,ptr_beout->NAME);
          ptr_beout->NODE = makeBddAbl (ptr_circuit,ptr_beout->ABL,ptr_befig,&vhb_count);
          ptr_ctrlst = delchain (ptr_ctrlst,ptr_ctrlst);
	  }
      ptr_beout = ptr_beout->NEXT;
      vhb_count++;
      if ( vhb_count>5 &&
           reorder && 
           ((sysBdd.pRT->compteur - vhb_numberNode) /vhb_count) >max_node)
        {
        return(1);
        }
      }
    }
  if (ptr_befig->BEBUS != NULL)
    {
    struct bebus *ptr_bebus;
    ptr_bebus=ptr_befig->BEBUS;
    while (ptr_bebus != NULL)
      {
      if (ptr_bebus->BIABL != NULL)
        {
        struct biabl *ptr_biabl;
        struct binode *ptr_binode;
        ptr_biabl = ptr_bebus->BIABL;
        ptr_binode = ptr_bebus->BINODE;
        while (ptr_biabl != NULL)
          {
          if (ptr_biabl->CNDABL != NULL)
	      {
              ptr_binode->CNDNODE = makeBddAbl (ptr_circuit, ptr_biabl->CNDABL, ptr_befig,&vhb_count);
	      }

           vhb_count++;
           if ( vhb_count>5 &&
                reorder && 
                ((sysBdd.pRT->compteur - vhb_numberNode) /vhb_count) >max_node)
             {
             return(1);
             }
          
          if ( ptr_biabl->VALABL != NULL )
	      {
              ptr_ctrlst = addchain (ptr_ctrlst,ptr_bebus->NAME);
              ptr_binode->VALNODE = makeBddAbl (ptr_circuit,ptr_biabl->VALABL,ptr_befig,&vhb_count);
              ptr_ctrlst = delchain (ptr_ctrlst,ptr_ctrlst);
	      }

           vhb_count++;
           if ( vhb_count>5 &&
                reorder && 
                ((sysBdd.pRT->compteur - vhb_numberNode) /vhb_count) >max_node)
             {
             return(1);
             }

          ptr_biabl = ptr_biabl->NEXT;
          ptr_binode = ptr_binode->NEXT;
          }
        }
      ptr_bebus = ptr_bebus->NEXT;
      }
    }

  if (ptr_befig->BEREG != NULL)
    {
    struct bereg *ptr_bereg;
    ptr_bereg=ptr_befig->BEREG;
    while (ptr_bereg != NULL)
      {
      if (ptr_bereg->BIABL != NULL)
        {
        struct biabl *ptr_biabl;
        struct binode *ptr_binode;
        ptr_biabl = ptr_bereg->BIABL;
        ptr_binode = ptr_bereg->BINODE;
        while (ptr_biabl != NULL)
          {
          if (ptr_biabl->CNDABL != NULL)
	      {
              ptr_binode->CNDNODE = makeBddAbl (ptr_circuit,ptr_biabl->CNDABL,ptr_befig,&vhb_count);
	      }

           vhb_count++;
           if ( vhb_count>5 &&
                reorder && 
                ((sysBdd.pRT->compteur - vhb_numberNode) /vhb_count) >max_node)
             {
             return(1);
             }

          if (ptr_biabl->VALABL != NULL)
	      {
              ptr_ctrlst = addchain (ptr_ctrlst,ptr_bereg->NAME);
              ptr_binode->VALNODE = makeBddAbl (ptr_circuit,ptr_biabl->VALABL,ptr_befig,&vhb_count);
              ptr_ctrlst = delchain (ptr_ctrlst,ptr_ctrlst);
	      }

           vhb_count++;
           if ( vhb_count>5 &&
                reorder && 
                ((sysBdd.pRT->compteur - vhb_numberNode) /vhb_count) >max_node)
             {
             return(1);
             }

          ptr_biabl = ptr_biabl->NEXT;
          ptr_binode = ptr_binode->NEXT;
          }
        }
      ptr_bereg = ptr_bereg->NEXT;
      }
    }
  if (ptr_befig->BEAUX != NULL)
    {
    struct beaux *ptr_aux;
    ptr_aux=ptr_befig->BEAUX;
    while (ptr_aux != NULL)
      {
      if ((ptr_aux->ABL != NULL) && (ptr_aux->NODE == NULL))
          {
          ptr_ctrlst = addchain (ptr_ctrlst,ptr_aux->NAME);
          ptr_aux->NODE = makeBddAbl (ptr_circuit,ptr_aux->ABL,ptr_befig,&vhb_count);
          ptr_ctrlst = delchain (ptr_ctrlst,ptr_ctrlst);
	  }
      ptr_aux = ptr_aux->NEXT;
      vhb_count++;
      if ( vhb_count>5 &&
           reorder && 
           ((sysBdd.pRT->compteur - vhb_numberNode) /vhb_count) >max_node)
           {
           return(1);
           }
      }
    }

  return(0);
  }

/*-------------------------------------------------------------------------
nameInt 	: calcule un identificateur.
---------------------------------------------------------------------------
retour		: un pointeur de chaine de caracteres.
---------------------------------------------------------------------------*/
char *nameInt(name)
char *name;
{
char *name1;
char *retour;
int i;

name1 = (char *) malloc (strlen(name)+2);
strcpy(name1,name);
i = 0;
while (name1[i] != '\0')
   {
   if (name1[i] == '(')
      name1[i] = '_';
   if (name1[i] == ')')
      {
      name1[i] = '\0';
      i--;
      }
   i++;
   }
retour = namealloc(name1);
free(name1);
return(retour);
}
/*-------------------------------------------------------------------------
renameExpr 	: renommage d'une expr. 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/
void renameExpr(expr)
chain_list *expr;
{
if (ATOM(expr))
   expr->DATA = (void*)nameInt(VALUE_ATOM(expr));
else
   {
   while (expr = CDR(expr))
      {
      renameExpr(CAR(expr));
      }
   }
}

/*-------------------------------------------------------------------------
renameBeh 	: renommage d'une befig 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/

void renameBeh(beh)
befig_list *beh;
{
beout_list *out;
bereg_list *reg;
bebus_list *bus;
biabl_list *biabl;
beaux_list *aux;
berin_list *in;
bepor_list *port;

port = beh->BEPOR;
while (port) 
   {
   port->NAME = nameInt(port->NAME);
   port = port->NEXT;
   }

in = beh->BERIN;
while (in) 
   {
   in->NAME = nameInt(in->NAME);
   in = in->NEXT;
   }

aux = beh->BEAUX;
while (aux) 
   {
   aux->NAME = nameInt(aux->NAME);
   if (aux->ABL)
      {
      renameExpr(aux->ABL);
      }
   aux = aux->NEXT;
   }

out = beh->BEOUT;
while (out) 
   {
   out->NAME = nameInt(out->NAME);
   if (out->ABL)
      {
      renameExpr(out->ABL);
      }
   out = out->NEXT;
   }

reg = beh->BEREG;
while (reg) 
   {
   reg->NAME = nameInt(reg->NAME);
   biabl = reg->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         renameExpr(biabl->CNDABL);
         renameExpr(biabl->VALABL);
         }
      biabl = biabl->NEXT;
      }
   reg = reg->NEXT;
   }

bus = beh->BEBUS;
while (bus) 
   {
   bus->NAME = nameInt(bus->NAME);
   biabl = bus->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         renameExpr(biabl->CNDABL);
         renameExpr(biabl->VALABL);
         }
      biabl = biabl->NEXT;
      }
   bus = bus->NEXT;
   }
}

/* ###--------------------------------------------------------------### */
/* function	: makeBddAbl						*/
/* description	: transform recursively abl in bdd 			*/
/* algorithm    : if ATOM(expr)is an operand --terminal variable, 	*/
/*		  then 							*/
/*		    if (it is a constant or a primary variable)		*/
/*		    then return that bdd that is already known 		*/
/*		    else 						*/
/*		      if ((it is an auxilliary variable)&&		*/
/*			  (there is no self-dependence))		*/
/*	   	      then return makeBddAbl(that terminal variable)	*/
/*		      else ERROR					*/
/*		  else apply OPER(expr) 				*/
/*			to makeBddAbl(every operands) 			*/
/* called func.	: seachInputCct <bdd>, createNodeTermBdd <bdd>,		*/
/* 		: addListBdd <bdd>, applyBdd <bdd>,      		*/
/* 		: addchain <mbk>, freechain <mbk>,			*/
/* 		: vhb_mfrfrst 						*/
/* 		: makeBddAbl -- that function is recursive !!!		*/
/* ###--------------------------------------------------------------### */

pNode makeBddAbl (ptr_circuit, expr, ptr_befig,vhb_count)
pCircuit ptr_circuit;		/* circuit for level 1 bdd functions 	*/
chain_list *expr;		/* pointer abl expression		*/
struct befig *ptr_befig;	/* pointer on  behavioural figure	*/
int *vhb_count;
  {
  short         oper;
  pNode         pt;
  chain_list   *lstGbd;
  chain_list   *ptr_cntrl=ptr_ctrlst;
  struct beaux *ptr_beaux=ptr_befig->BEAUX;
  int           index;
  char         *atom;

  if (expr == NULL)
    {
    printf("makeBddAbl : erreur ABL vide \n");
    exit(1);
    }

  if (ATOM(expr))
    {					/* is atom a constant ?           */
    atom = (char *)VALUE_ATOM (expr);
					
    if (!strcmp(atom, "'0'"))
      return (zero);
    if (!strcmp(atom, "'1'"))
      return (one);
    					/* is atom a primary variable ?     */
    if ((index=searchInputCct (ptr_circuit, atom)) != VIDETH)
      {
      return (createNodeTermBdd (index));
      }

    else				/* neither constant, nor primary     */
      {					/* it must be an auxilliary variable */

      while ((ptr_beaux != NULL) && (strcmp(ptr_beaux->NAME,atom)))
        ptr_beaux = ptr_beaux->NEXT;

      if (ptr_beaux == NULL)		/* neither constant, nor primary, nor */
         {
         printf("makeBddAbl : erreur variable %s non trouvee\n",atom);
         exit(1);
         }
      else				/* does that signal depends of        */
	{				/* himself ? ptr_ctrlst is the        */
					/* dependance list of expression being*/
					/* transformed from abl to bdd        */
        while ((ptr_cntrl != NULL) && ((char *) ptr_cntrl->DATA != atom))
          ptr_cntrl = ptr_cntrl->NEXT;

        if (ptr_cntrl != NULL)
					/* to ensure that no signal depends  */
					/* of himself			     */
          {				/* if it does it's a fatal error!    */
          printf("makeBddAbl : erreur variable %s rebouclee \n",atom);
          exit(1);
          }
        else
          {
          if (ptr_beaux->NODE == NULL)
            {
            ptr_ctrlst = addchain ( ptr_ctrlst,atom);
					/* add a signal to the dependences    */
					/* list that ptr_ctrlst is pointing at*/
            ptr_beaux->NODE = makeBddAbl ( ptr_circuit,ptr_beaux->ABL,ptr_befig,
                                           vhb_count );
            *vhb_count = *vhb_count+1;
            ptr_ctrlst = delchain (ptr_ctrlst,ptr_ctrlst);
					/* del a signal to the dependences    */
            return (ptr_beaux->NODE);
            }
          else
            {
            return (ptr_beaux->NODE);
            }
          }
        }
      }
    }
  else
    {
    oper = OPER( expr );		/* operator to be applyed on lstgbd  */
    lstGbd = NULL;		  	/* list of operands		     */
    while ( expr = CDR( expr ) )
      lstGbd = addListBdd (lstGbd,makeBddAbl(ptr_circuit,CAR(expr),
                           ptr_befig,vhb_count));
    pt = applyBdd(oper,lstGbd);
    freechain (lstGbd);
    return(pt);
    }
  }
