
/* ###--------------------------------------------------------------### */
/*									*/
/* file		: sl_util.c						*/
/* date		: september 22 91					*/
/* author	: BURGUN L.						*/
/*									*/
/*									*/
/* ###--------------------------------------------------------------### */

#include MUT_H
#include LOG_H
#include BEH_H
#include <dirent.h>
#include "lax_param.h"
#include "../synthe/sl_type.h"
#include <math.h>
#include "sl_util.h"
#include <sys/errno.h>
#include <stdio.h>
#include "../mapping/types.h"

/*------------- Fonctions communes a NETOPTIM et LOGIC --------------------*/

/****************************************************************************/
/******* addArite : ajoute l'arite a chaque operateur de l'ABL **************/
/****************************************************************************/
void addArite(exp)
chain_list *exp;

{
if (!ATOM(exp))
        {
        CAR(exp)->NEXT = (chain_list *)lengthExpr(exp);
        mapExpr(addArite,exp);
        }
}

/******************************************************************************//***** inversArg : ajoute un NOT en tete d'expression *************************//******************************************************************************/chain_list *inversArg(exp)
chain_list *exp;
{
chain_list *op;
 
op = createExpr(NOT);
addHExpr(op,copyExpr(exp));
return op;
}

/******************************************************************************//** nivNot : renvoie la profondeur de l'expression sans tenir compte des NOT **//******************************************************************************/int nivNot(exp)
chain_list *exp;

{
if (ATOM(exp))
   return 0;
if ((int)OPER(exp) == NOT)
   return nivNot(CADR(exp));
else
   {
   int max=0,profCar;

   while (exp = CDR(exp))
      {
      profCar = nivNot(CAR(exp));
      if (profCar >max)
         max = profCar;
      }
   return(++max);
   }
}
 
/*--------------------------------------------------------------------------
 testObj        : recherche un element dans les tables de hachage
----------------------------------------------------------------------------
retour          : void.
--------------------------------------------------------------------------*/
int testObj(name,type)
char *name;
char type;

{
int val;

   switch(type)
   {
        case 'a' : val = searchTH(mappSys->abl_hash,name);
                   if ((val != VIDETH) && (val != DELETETH))
                        return (int)val;
                   return (int)NULL;
        case 'c' : val = searchTH(mappSys->cell_hash,name);
                   if ((val != VIDETH) && (val != DELETETH))
                        return (int)val;
                   return (int)NULL;
        case 's' : val = searchTH(mappSys->sig_hash,name);
                   if ((val != VIDETH) && (val != DELETETH))
                        return (int)val;
                   return (int)NULL;
        case 'v' : val = searchTH(mappSys->virt_hash,name);
                   if ((val != VIDETH) && (val != DELETETH))
                        return (int)val;
                   return (int)NULL;
        default : printf("testObj : bad type for the hash table");
                  return (int)NULL;
   }
}

/*--------------------------------------------------------------------------
searchAlist     : recherche une variable de nom "name"
----------------------------------------------------------------------------
retour          : un pointeur de tablist
--------------------------------------------------------------------------*/
Alist *searchAlist(ptTL,name)
Alist *ptTL;
char *name;
{
if (!ptTL) return NULL;
   do
     if (ptTL->name == name)
        return ptTL;
   while (ptTL = ptTL->NEXT);
return (Alist *)NULL;
}

/*--------------------------------------------------------------------------
createAlist     : creer une liste associative de variables.
----------------------------------------------------------------------------
retour          : un pointeur de tablist
--------------------------------------------------------------------------*/

Alist *createAlist(ptTHead,expr)
Alist *ptTHead;
chain_list *expr;
{
   Alist *ptTL;

   if (ATOM(expr) && (!searchAlist(ptTHead,VALUE_ATOM(expr))))
      {
      ptTL = (Alist *)mbkalloc (sizeof(Alist));

      ptTL->name = VALUE_ATOM(expr);
      ptTL->ptChain = NULL;
      ptTL->NEXT = ptTHead;
      ptTHead = ptTL;
      }
   else
      while (expr = CDR(expr))
         ptTHead = createAlist(ptTHead,CAR(expr));
   return (Alist *)reverse(ptTHead);
}

/*--------------------------------------------------------------------------
searchPtype     : recherche d'un virtuel de la reference
----------------------------------------------------------------------------
retour          : pointeur sur le niveau ou NULL.
--------------------------------------------------------------------------*/

long searchPtype(pTL,name)
ptype_list *pTL;
char *name;
 
{
ptype_list *p;
 
for(p = pTL;p;p = CDR(p))
        if ((char *)p->DATA == name)
                return p->TYPE;
return 0;
}
 
/*------------- FIN Fonctions communes a NETOPTIM et LOGIC -----------------*/

/*---------------------------------------------------------------------------
existDirectory  : renvoie si le repertoire path existe ou non.
-----------------------------------------------------------------------------
retour		: int 
---------------------------------------------------------------------------*/

int existDirectory(path)
char *path;
{
FILE *fich;
DIR *retour;

retour = opendir(path);

if (retour)
   {
   free(retour);
   return(1);
   }
else
   return(0);
}

/*---------------------------------------------------------------------------
SLgetFile		: fait un "ls" en colonnes des fichiers d'un type donne et
                  renvoie une liste chainee de noms de fichier.
-----------------------------------------------------------------------------
retour		: chain_list *
---------------------------------------------------------------------------*/

chain_list *SLgetFile(path,ext)
char *path,*ext;
{
FILE	*fich;
char	*st,*commande = (char *) mbkalloc(200);
chain_list *head=NULL;

strcpy(commande,"ls ");
strcat(commande,path);
strcat(commande,"/*.");

system(strcat(strcat(commande,ext),"> fich"));

#if MACHINE != pc
mbkfree(commande);
#endif

fich = fopen("fich","r");
while (!feof(fich))
   {
   st = (char *)mbkalloc (150);
   fscanf(fich,"%s",st);
   if (!feof(fich))
      {
      if (strlen(st) != 0) 
         head = addchain(head,st); 
      }
   }
fclose(fich);
system("rm fich");
return head;
}

/*------------------------------------------------------------------------------
logsup2 		: calcule le log a base 2 d'un int 
------------------------------------------------------
parametres  	: un int 
-------------------------------------------------------
return 		: un int
------------------------------------------------------------------------------*/
int logsup2(val)
int val;
{
int co;
int sup;

if (val < 1)
   {
   printf("warning : logsup2 domain error\n");
   return(0);
   }

sup = 0;
co =  0;
while (val > 1)
   {
   if (val & 1)
      sup = 1;
   co++;
   val = (val >> 1);
   }
return(co + sup);
}

/*-------------------------------------------------------------------------
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 *retour;
int length = strlen(name);

name1 = (char *)  mbkalloc (length+7);
sprintf(name1,"%s%d",name,num);
retour = namealloc(name1);
#if MACHINE != pc
   mbkfree((void *)name1);	/* chaine */
#endif
return(retour);
}

/*-------------------------------------------------------------------------
verifCohBeh 	: verifie la coherence 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,*newBEAUX;


aux = beh->BEAUX;
newBEAUX = NULL;

		/* parcours de la chain_list des aux a sauvegarder */
while (saveAux)
   {
   aux1 = beh->BEAUX;
   while (aux1)
      {
      if (!strcmp(aux1->NAME,saveAux->DATA))
         break;
      aux1 = aux1->NEXT;
      }   
   if (aux1)		/* variable a sauvegarder */
      {
      newBEAUX = beh_addbeaux(newBEAUX,aux1->NAME,aux1->ABL,NULL);
      aux1->ABL = NULL;
      newBEAUX->NODE = aux1->NODE;
      }
   saveAux = saveAux->NEXT;
   }

		/* desallocation */

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

beh->BEAUX = newBEAUX;
}


/*-------------------------------------------------------------------------
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;
bebux_list *bux;
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;
   }

bux = beh->BEBUX;
while (bux) 
   {
   biabl = bux->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         flatArityExpr(biabl->CNDABL);
         flatArityExpr(biabl->VALABL);
         }
      biabl = biabl->NEXT;
      }
   bux = bux->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 (!strcmp(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,BEBUS ou 
                  BEBUX 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;
bebux_list *bux = beh->BEBUX;

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

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

while (bux)
   {
   if (name == bux->NAME)
      return(1);
   bux = bux->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);
}

/*------------------------------------------------------------------
  IDENT : profExprFact
  ------------------------------------------------------------------
  FUNCTION : calcule la profondeur d'une expression.
  ------------------------------------------------------------------*/

int profExprFact(expr)
chain_list *expr;
{
if (ATOM(expr))
   return(0);
else
   {
   int max=0,profCar;
   int arity;
   short oper;

   oper = OPER(expr);
   if (oper == NOT)
      return(profExprFact(CADR(expr)));

   arity = lengthExpr(expr);
   while (expr = CDR(expr))
      {
      profCar = profExprFact(CAR(expr));
      if (profCar >max)
         max = profCar;
      }
   if (oper == XOR)
      return(max +2*logsup2(arity));
   else
      return(max +logsup2(arity));
   }
}

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

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

if (ATOM(expr))
   {
   if (!strcmp(VALUE_ATOM(expr),"'d'") ||
       !strcmp(VALUE_ATOM(expr),"'0'") || !strcmp(VALUE_ATOM(expr),"'1'"))
      return(0);
		/* c'est un auxiliaire deja calcule */

   if (profTH != NULL)
      if ((result = searchTH(profTH,VALUE_ATOM(expr))) != EMPTYTH)
         return(result); 

   if (existInputBeh(beh,VALUE_ATOM(expr)))  	/* c'est une PI */
      {
      addTH(profTH,VALUE_ATOM(expr),0);
      return(0);
      }
   else
      {						/* c'est une AUX */
      beaux_list *aux = beh->BEAUX;

			/* on recupere l'ABL */

      while (aux)
         {
         if (!strcmp(aux->NAME,VALUE_ATOM(expr)))
            {
            int result = profExprBeh(beh,aux->ABL,profTH);
            if (profTH != NULL)
               addTH(profTH,VALUE_ATOM(expr),result);
            return(result);
            }
         aux = aux->NEXT;
         }
      printf("profExprBeh : error auxilliary variable doesn't exist\n");
      exit(-1);
      }
   }
else
		/* traitement operateur */
   {
   int maxProf=0,inter;
   short operInt = OPER(expr);
   int arity = lengthExpr(expr);

   if (operInt == NOT)
      return(profExprBeh(beh,CADR(expr),profTH));

   while (expr = CDR(expr))
      {
      inter = profExprBeh(beh,CAR(expr),profTH);
      if (maxProf < inter)
         maxProf = inter;
      } 
   if (operInt == XOR)
      return(maxProf + 2*logsup2(arity));
   else
      return(maxProf + logsup2 (arity));
   }
}

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

long numberAtomExprBeh(beh,expr,numberTH)
befig_list *beh;
chain_list *expr;
pTH numberTH;
{
long result;

if (ATOM(expr))
   {
   if (!strcmp(VALUE_ATOM(expr),"'d'") ||
       !strcmp(VALUE_ATOM(expr),"'0'") || !strcmp(VALUE_ATOM(expr),"'1'"))
      return(1);

		/* c'est un auxiliaire deja calcule */

   if (numberTH != NULL)
      if ((result = searchTH(numberTH,VALUE_ATOM(expr))) != EMPTYTH)
         return(result); 

   if (existInputBeh(beh,VALUE_ATOM(expr)))  	/* c'est une PI */
      {
      addTH(numberTH,VALUE_ATOM(expr),1);
      return(1);
      }
   else
      {						/* c'est un AUX */
      beaux_list *aux = beh->BEAUX;

      while (aux)
         {
         if (!strcmp(aux->NAME,VALUE_ATOM(expr)))
            {
            result = numberAtomExprBeh(beh,aux->ABL,numberTH);
            if (numberTH != NULL && result < 10000000)
               addTH(numberTH,VALUE_ATOM(expr),(int) result);
            return(result);
            }
         aux = aux->NEXT;
         }
      printf("numberAtomExprBeh : error auxilliary variable doesn't exist ");
      printf("--> %s\n",VALUE_ATOM(expr));
      exit(-1);
      }
   }
else
		/* traitement operateur */
   {
   result=0;

   if (OPER(expr) == NOT)
      return(numberAtomExprBeh(beh,CADR(expr),numberTH));

   while (expr = CDR(expr))
      {
      result += numberAtomExprBeh(beh,CAR(expr),numberTH);
      } 
   return(result);
   }
}
/*-------------------------------------------------------------------------
delElementChain_list 	: elimine une donnee d'une liste chainee 
---------------------------------------------------------------------------
retour		: un pointeur de chain_list.
---------------------------------------------------------------------------*/
chain_list *delElementChain_list(cl,data)
chain_list *cl;
void *data;
{
chain_list *initcl = cl;

if (cl == NULL)
   return(NULL);
else
   {
   if (cl->DATA == data)
      return(cl->NEXT);

   while (cl->NEXT)
      {
      if ((cl->NEXT)->DATA == data)
         {
         cl->NEXT = (cl->NEXT)->NEXT; 
         return(initcl);
         }
      else
         cl = cl->NEXT;
      }
   return(initcl);
   }
}
/*-------------------------------------------------------------------------
copyChain_list 	: copy une chain_list au niveau desa dorsale. 
---------------------------------------------------------------------------
retour		: un pointeur de chain_list.
---------------------------------------------------------------------------*/
chain_list *copyChain_list(cl)
chain_list *cl;
{

if (cl == NULL)
   return(NULL);
else
   {
   chain_list *lst = addchain(NULL, cl->DATA);
   chain_list *initLst;

   initLst = lst;
   while (cl->NEXT)
      {
      lst->NEXT = addchain(NULL, cl->NEXT->DATA);
      lst = lst->NEXT;
      cl = cl->NEXT;
      };
   return(initLst);
   }
}
/*-------------------------------------------------------------------------
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,(void *)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);
}

/*----------------------------------------------------------------------------
afficheLC : affiche en colonnes les entrees ou sortie donnees par une LC
------------------------------------------------------------------------------
retour		: void 
----------------------------------------------------------------------------*/ 


void		 afficheLC( IO)
chain_list	*IO;
{
int num = 2;

while (IO)
   {
   printf(" %s(%d)\t",IO->DATA,num);
   num++;
   if (!(num % 4))
      printf("\n");
   IO = IO->NEXT;
   }
printf("\n");
}


/*----------------------------------------------------------------------------
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(" %.3f",((float)(IOt->TYPE))/1000);
		IOt = IOt->NEXT;
		currentLig++;
		}
	currentCol += largeurCol;
	currentLig = ligneDepart;
	};
return ( nbCol );
}
			
/*-----------------------------------------------------------------------------
fusionLC	: fusionne deux listes chainees 
-------------------------------------------------------------------------------
retour		: un chain_list *
-----------------------------------------------------------------------------*/
chain_list *fusionLC(l1,l2)
chain_list *l1;
chain_list *l2;
{
chain_list *res = NULL;
chain_list *tete;
int exist;


tete = l1;
while (l1)
   {
   res = addchain(res,l1->DATA);
   l1 = l1->NEXT;
   }
l1 = tete;

while (l2) 
   {
   exist = 0;
   tete = l1;
   while (l1)
      {
      if ((int) l1->DATA == (int) l2->DATA)
         exist = 1;
      l1 = l1->NEXT;
      }
   l1 = tete;
   if (exist == 0)
      res = addchain(res,l2->DATA);
   l2 = l2->NEXT;
   }

return res;
}

/*-----------------------------------------------------------------------------
countChain_list	: count le nombre d'elements d'une chaine_list
-------------------------------------------------------------------------------
retour		: un int
-----------------------------------------------------------------------------*/
int		 countChain_list( CL )
chain_list	*CL;
{
int 		count = 0;
 
while ( CL ) {
	CL = CL->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( (char *) 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( (char *)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,createAux,ppAux)
struct befig *ptr_befig;		/* pointer on current BEFIG	*/
pCircuit      ptr_circuit;		/* pointer on current circuit	*/
int           reorder;			/* order parameter 		*/
int trace;
int max_node;
int createAux;
chain_list **ppAux;

  {
  pNode makeBddAbl();
  int vhb_numberNode = numberNodeAllBdd();
  int vhb_count = 0;

  ptr_ctrlst = NULL;

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


  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,(void *)ptr_beout->NAME);
          ptr_beout->NODE = makeBddAbl (ptr_circuit,ptr_beout->ABL,ptr_befig,&vhb_count,createAux,ppAux);
          ptr_ctrlst = delchain (ptr_ctrlst,ptr_ctrlst);
	  }

      ptr_beout = ptr_beout->NEXT;
      vhb_count++;
      if ( vhb_count>1 &&
           reorder && 
           ((numberNodeAllBdd() - 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,createAux,ppAux);
	      }

           vhb_count++;
           if ( vhb_count>1 &&
                reorder && 
                ((numberNodeAllBdd() - vhb_numberNode) /vhb_count) >max_node)
             {
             return(1);
             }
          
          if ( ptr_biabl->VALABL != NULL )
	      {
              ptr_ctrlst = addchain (ptr_ctrlst,(void *)ptr_bebus->NAME);
              ptr_binode->VALNODE = makeBddAbl (ptr_circuit,ptr_biabl->VALABL,ptr_befig,&vhb_count,createAux,ppAux);
              ptr_ctrlst = delchain (ptr_ctrlst,ptr_ctrlst);
	      }

           vhb_count++;
           if ( vhb_count>1 &&
                reorder && 
                ((numberNodeAllBdd() - 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->BEBUX != NULL)
    {
    struct bebux *ptr_bebux;
    ptr_bebux=ptr_befig->BEBUX;
    while (ptr_bebux != NULL)
      {
      if (ptr_bebux->BIABL != NULL)
        {
        struct biabl *ptr_biabl;
        struct binode *ptr_binode;
        ptr_biabl = ptr_bebux->BIABL;
        ptr_binode = ptr_bebux->BINODE;
        while (ptr_biabl != NULL)
          {
          if (ptr_biabl->CNDABL != NULL)
	      {
              ptr_binode->CNDNODE = makeBddAbl (ptr_circuit, ptr_biabl->CNDABL, ptr_befig,&vhb_count,createAux,ppAux);
	      }

           vhb_count++;
           if ( vhb_count>1 &&
                reorder && 
                ((numberNodeAllBdd() - vhb_numberNode) /vhb_count) >max_node)
             {
             return(1);
             }
          
          if ( ptr_biabl->VALABL != NULL )
	      {
              ptr_ctrlst = addchain (ptr_ctrlst,(void *)ptr_bebux->NAME);
              ptr_binode->VALNODE = makeBddAbl (ptr_circuit,ptr_biabl->VALABL,ptr_befig,&vhb_count,createAux,ppAux);
              ptr_ctrlst = delchain (ptr_ctrlst,ptr_ctrlst);
	      }

           vhb_count++;
           if ( vhb_count>1 &&
                reorder && 
                ((numberNodeAllBdd() - vhb_numberNode) /vhb_count) >max_node)
             {
             return(1);
             }

          ptr_biabl = ptr_biabl->NEXT;
          ptr_binode = ptr_binode->NEXT;
          }
        }
      ptr_bebux = ptr_bebux->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,createAux,ppAux);
	      }

           vhb_count++;
           if ( vhb_count>1 &&
                reorder && 
                ((numberNodeAllBdd() - vhb_numberNode) /vhb_count) >max_node)
             {
             return(1);
             }

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

           vhb_count++;
           if ( vhb_count>1 &&
                reorder && 
                ((numberNodeAllBdd() - 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->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,createAux,ppAux);
	  }
      ptr_bemsg = ptr_bemsg->NEXT;
      }
    }

	/* on devrait traiter les noeuds auxilliaires par profondeur
           decroissante ... */

  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,(void *)ptr_aux->NAME);
          ptr_aux->NODE = makeBddAbl (ptr_circuit,ptr_aux->ABL,ptr_befig,&vhb_count,createAux,ppAux);
          ptr_ctrlst = delchain (ptr_ctrlst,ptr_ctrlst);
          addOutputCct(ptr_circuit,ptr_aux->NAME,ptr_aux->NODE);
	  }
      ptr_aux = ptr_aux->NEXT;
      vhb_count++;
      if ( vhb_count>1 &&
           reorder && 
           ((numberNodeAllBdd() - vhb_numberNode) /vhb_count) >max_node)
           {
           return(1);
           }
      }
    }

		/* destruction des auxiliares */

  destroyTH(ptr_circuit->pTO);
  ptr_circuit->pTO = createTH(100);

  return(0);
  }

/*-------------------------------------------------------------------------
nameIntVect 	: calcule un identificateur en gardant les vecteurs.
---------------------------------------------------------------------------
retour		: un pointeur de chaine de caracteres.
---------------------------------------------------------------------------*/
char *nameIntVect(name)
char *name;
{
char *name1;
char *retour;
int i;
int length = strlen(name);

name1 = (char *)  mbkalloc (length+2);
strcpy(name1,name);
i = 0;
while (name1[i] != '\0')
   {
   if (name1[i] == '(')
      name1[i] = '[';
   if (name1[i] == ')')
      {
      name1[i] = ']';
      }
   if (name1[i] == ' ')
      name1[i] = '_';
   i++;
   }
name = namealloc(name1);
#if MACHINE != pc
   mbkfree((void *)name1);	/* chaine */
#endif

if (name[0] == 'a' && name[1] == 'u' && name[2] == 'x')
   {
   length = strlen(name);
   name1 = (char *)  mbkalloc (length+3);
   
   strcpy(name1,name);
   name1[length] =  '_';
   name1[length+1]   =  'a';
   name1[length+2] = '\0';
   retour = namealloc(name1);
#if MACHINE != pc
   mbkfree((void *)name1);	/* chaine */
#endif
   }
else
   retour = name;
   
return(retour);
}
/*-------------------------------------------------------------------------
nameInt 	: calcule un identificateur.
---------------------------------------------------------------------------
retour		: un pointeur de chaine de caracteres.
---------------------------------------------------------------------------*/
char *nameInt(name)
char *name;
{
char *name1;
char *retour;
int i;
int length = strlen(name);

name1 = (char *)  mbkalloc (length+2);
strcpy(name1,name);
i = 0;
while (name1[i] != '\0')
   {
   if (name1[i] == '(' || name1[i] == '[')
      name1[i] = '_';
   if (name1[i] == ')' || name1[i] == ']')
      {
      name1[i] = '\0';
      i--;
      }
   i++;
   }
name = namealloc(name1);
#if MACHINE != pc
   mbkfree((void *)name1);	/* chaine */
#endif

if (name[0] == 'a' && name[1] == 'u' && name[2] == 'x')
   {
   length = strlen(name);
   name1 = (char *)  mbkalloc (length+3);
   
   strcpy(name1,name);
   name1[length] =  '_';
   name1[length+1]   =  'a';
   name1[length+2] = '\0';
   retour = namealloc(name1);
#if MACHINE != pc
   mbkfree((void *)name1);	/* chaine */
#endif
   }
else
   retour = name;
   
return(retour);
}
/*-------------------------------------------------------------------------
renameExpr 	: renommage d'une expression avec une fonction
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/
void renameExpr(expr,func)
chain_list *expr;
char *(*func)();
{
if (ATOM(expr))
   expr->DATA = (void *)(* func)(VALUE_ATOM(expr));
else
   {
   while (expr = CDR(expr))
      {
      renameExpr(CAR(expr),func);
      }
   }
}

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

void renameBeh(beh,func)
befig_list *beh;
char *(*func)();
{
beout_list *out;
bereg_list *reg;
bebus_list *bus;
bebux_list *bux;
biabl_list *biabl;
beaux_list *aux;
berin_list *in;
bepor_list *port;
bemsg_list *msg;
begen_list *generic;
int i;
char *genNAME();

   for (generic = beh->BEGEN; generic; generic = generic->NEXT)
   {
   char *gen = generic->NAME;
   char *val = generic->NAME;

		/* on avance dans val jusqu'au '_'  */

      for (i=0;i<strlen(gen) && gen[i] != '_';i++)
         val++;
   
	
      if (i < strlen(gen))	/* le '_' existe bien */
      {
      char *newval;
      char *field;
      char *racine = (char *) mbkalloc(10);

         strncpy(racine,gen,++i);
         racine[i] = '\0';

         val++;
         newval = (* func) (val);
         field = (char *) mbkalloc(10 + strlen(newval));
         sprintf(field,"%s%s",racine,newval);

	 generic->NAME = namealloc(field);

#if MACHINE != pc
         mbkfree(field);	/* chaine */
         mbkfree(racine);		/* chaine */
#endif
      }
   }

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

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

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

msg = beh->BEMSG;
while (msg)
    {
    if (msg->ABL)
       {
       renameExpr(msg->ABL,func); 
       }
    msg = msg->NEXT;
    }

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

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

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

bux = beh->BEBUX;
while (bux) 
   {
   bux->NAME = (* func)(bux->NAME);
   biabl = bux->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         renameExpr(biabl->CNDABL,func);
         renameExpr(biabl->VALABL,func);
         }
      biabl = biabl->NEXT;
      }
   bux = bux->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,createAux,ppAux)
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;
int createAux;
chain_list **ppAux;
  {
  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 : error ABL = NULL \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);
    if (!strcmp(atom, "'d'"))
      return (zero);
    					/* 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)
         {
         printf("makeBddAbl : error signal %s not found\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 : error signal %s in combinatory loop \n",atom);
          exit(1);
          }
        else
          {
          if (ptr_beaux->NODE == NULL)	/* no treated signal */
            {
            ptr_ctrlst = addchain ( ptr_ctrlst,(void *)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,createAux,ppAux );

            *vhb_count = *vhb_count+1;
            ptr_ctrlst = delchain (ptr_ctrlst,ptr_ctrlst);


            if (numberNodeBdd(ptr_beaux->NODE) > createAux)
               {
/*
	       printf("AUX : %s - number of nodes = %d\n",
                      ptr_beaux->NAME,numberNodeBdd(ptr_beaux->NODE));
*/

               *ppAux = addchain(*ppAux,ptr_beaux->NAME);
               return (createNodeTermBdd 
                            (addInputCct (ptr_circuit,ptr_beaux->NAME))); 
               }

            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 ) )
      {
      pNode ptNode = makeBddAbl(ptr_circuit,CAR(expr),ptr_befig,
                                vhb_count,createAux,ppAux);
      lstGbd = addListBdd (lstGbd,ptNode);
      }
    
		/* patch pour stable */

    if (oper == STABLE)
       oper = NOT;
    pt = applyBdd(oper,lstGbd);
    freechain (lstGbd);
    return(pt);
    }
  }

/*-------------------------------------------------------------------------
checkABL 	: verifie le non partage des expressions dans un ABL 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/

void checkABL(expr,pTable)
chain_list *expr;
pTH pTable;
{
int exprRed = VIDETH;

if (ATOM(expr))
   {
   if ((exprRed = searchTH(pTable,expr)) != VIDETH)
      {
      printf("checkExprBeh : Warning - reduced expression\n");
      displayExpr((chain_list *)exprRed);
      displayExpr(expr);
      }
   else
      {
      addTH(pTable,expr,expr);
      }
   }
else
   {
   chain_list *oldExpr = expr;

   if ((exprRed = searchTH(pTable,expr)) != VIDETH) /* operateur */
      {
      printf("checkExprBeh : Warning - reduced expression\n");
      displayExpr((chain_list *) exprRed);
      displayExpr(expr);
      }
   else
      {
      addTH(pTable,expr,expr);
      }

   while ((expr = CDR(expr)) && 
          (exprRed == VIDETH)) /* liste des arguments */
      {
      if ((exprRed = searchTH(pTable,expr)) != VIDETH)
         {
         printf("checkExprBeh : Warning - reduced expression\n");
         displayExpr((chain_list *) exprRed);
         displayExpr(oldExpr);
         }
      else
         {
         addTH(pTable,expr,oldExpr);
         checkABL(CAR(expr),pTable);
         }
      }
   }
}
/*-------------------------------------------------------------------------
checkExprBeh 	: verifie le non partage des expressions dans une BEFIG 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/

void checkExprBeh(beh)
befig_list *beh;
{
beout_list *out;
bereg_list *reg;
bebus_list *bus;
bebux_list *bux;
biabl_list *biabl;
beaux_list *aux;
pTH  redTable;

redTable = createTH(10000);

aux = beh->BEAUX;
while (aux) 
   {
   if (aux->ABL)
      {
      checkABL(aux->ABL,redTable);
      }
   aux = aux->NEXT;
   }

out = beh->BEOUT;
while (out) 
   {
   if (out->ABL)
      {
      checkABL(out->ABL,redTable);
      }
   out = out->NEXT;
   }

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


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

bux = beh->BEBUX;
while (bux) 
   {
   biabl = bux->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         checkABL(biabl->CNDABL,redTable);
         checkABL(biabl->VALABL,redTable);
         }
      biabl = biabl->NEXT;
      }
   bux = bux->NEXT;
   }

destroyTH(redTable);
}


/* ------ Traitement des connecteurs de sortie apparaissant dans les ABL ---- */


void displayBeh(befig,nb)
befig_list *befig;
short nb;
{
berin_list *i;
beout_list *o;
bereg_list *r;
bebus_list *b;
bebux_list *x;
beaux_list *a;
bepor_list *p;
begen_list *g;

fprintf(stderr,"----- display Befig (%s) -----\n",nb ? "behavioral" : "structural");
printf("  *********** BEFIG : %s *********\n",befig->NAME);
if (befig->BEOUT)
   printf(" OUT :\n");
for(o = befig->BEOUT;o;o = o->NEXT)
	{
	printf("   => %s =",o->NAME);
        if (numberAtomExpr(o->ABL) < 100)
	   displayExpr(o->ABL);
        else printf("expression too big!\n");
	}

if (befig->BEAUX)
   printf(" AUX :\n");
for(a = befig->BEAUX;a;a = a->NEXT)
	{
	printf("   => %s =",a->NAME);
        if (numberAtomExpr(a->ABL) < 100)
	   displayExpr(a->ABL);
        else printf("expression too big!\n");
	}

if (befig->BEBUS)
   printf(" BUS :\n");
for(b = befig->BEBUS;b;b = b->NEXT)
	{
	biabl_list *bi;

	printf("   => %s  ",b->NAME);
	for(bi = b->BIABL;bi;bi = bi->NEXT)
	    {
	    printf("VAL :",b->NAME);
            if (numberAtomExpr(bi->VALABL) < 100)
	       displayExpr(bi->VALABL);
            else printf("expression too big!\n");
	    if (nb)
               {
	       printf("           CND :");
               if (numberAtomExpr(bi->CNDABL) < 100)
	          displayExpr(bi->CNDABL);
               else printf("expression too big!\n");
 	       }
	    }
	}

if (befig->BEBUX)
   printf(" BUX :\n");
for(x = befig->BEBUX;x;x = x->NEXT)
	{
	biabl_list *bi;

	printf("   => %s  ",x->NAME);
	for(bi = x->BIABL;bi;bi = bi->NEXT)
	    {
	    printf("VAL :",x->NAME);
            if (numberAtomExpr(bi->VALABL) < 100)
	       displayExpr(bi->VALABL);
            else printf("expression too big!\n");
	    if (nb)
               {
	       printf("           CND :");
               if (numberAtomExpr(bi->CNDABL) < 100)
	          displayExpr(bi->CNDABL);
               else printf("expression too big!\n");
 	       }
	    }
	}

if (befig->BEREG)
   printf(" REG :\n");

for(r = befig->BEREG;r;r = r->NEXT)
	{
	biabl_list *bi;

	printf("   => %s  ",r->NAME);
	if (!nb)
           {
	    displayExpr(r->BIABL->VALABL);
           }
	else
	  for(bi = r->BIABL;bi;bi = bi->NEXT)
	    {
            printf("USER = %d\n",bi->USER);
            printf("VAL = ");
            if (numberAtomExpr(bi->VALABL) < 100)
	       displayExpr(bi->VALABL);
            else printf("expression too big!\n");
            printf("          CND = ");
            if (numberAtomExpr(bi->CNDABL) < 100)
	       displayExpr(bi->CNDABL);
            else printf("expression too big!\n");
	    }
	}
for(g = befig->BEGEN;g;g = g->NEXT)
   {
   printf("%s = %d\n", g->NAME, *(int *)g->VALUE);
   }
if (befig->NEXT)
   printf("NEXT = %s\n",(befig->NEXT)->NAME);

fprintf(stderr,"----- Fin displayBeh -----\n");
}

/*-------------------------------------------------------------------------
removeDCBeh 	: elimine les DC ('d' --> '0') 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/
void removeDCBeh(beh)
befig_list *beh;
{
beout_list *out;
beaux_list *aux;
bebus_list *bus;
bebux_list *bux;
bereg_list *reg;
biabl_list *biabl;

out = beh->BEOUT;
while (out)
   {
   if (out->ABL)
      {
      if (searchExpr(out->ABL,"'d'"))
         {
         if (!ATOM(out->ABL))
            substPhyExpr(out->ABL,"'d'",createAtom("'0'"));
         else
            out->ABL = createAtom("'0'");
         }
      }  
   out = out->NEXT;
   }  
 
aux = beh->BEAUX;
while (aux)
   {
   if (aux->ABL)
      {
      if (searchExpr(aux->ABL,"'d'"))
         {
         if (!ATOM(aux->ABL))
            substPhyExpr(aux->ABL,"'d'",createAtom("'0'"));
         else
            aux->ABL = createAtom("'0'");
         }
      }  
   aux = aux->NEXT;
   }

reg = beh->BEREG;
while (reg)
   {
   biabl = reg->BIABL;
   while (biabl)
      {
      if (biabl->VALABL)
         {
         if (searchExpr(biabl->VALABL,"'d'"))
            {
            if (!ATOM(biabl->VALABL))
               substPhyExpr(biabl->VALABL,"'d'",createAtom("'0'"));
            else
               biabl->VALABL = createAtom("'0'");
            }
         }
      biabl = biabl->NEXT;
      }  
   reg = reg->NEXT;
   }  
 
bus = beh->BEBUS;
while (bus)
   {
   biabl = bus->BIABL;
   while (biabl)
      {
      if (biabl->VALABL)
         {
         if (searchExpr(biabl->VALABL,"'d'"))
            {
            if (!ATOM(biabl->VALABL))
               substPhyExpr(biabl->VALABL,"'d'",createAtom("'0'"));
            else
               biabl->VALABL = createAtom("'0'");
            }
         }
      biabl = biabl->NEXT;
      }  
   bus = bus->NEXT;
   }  
 
bux = beh->BEBUX;
while (bux)
   {
   biabl = bux->BIABL;
   while (biabl)
      {
      if (biabl->VALABL)
         {
         if (searchExpr(biabl->VALABL,"'d'"))
            {
            if (!ATOM(biabl->VALABL))
               substPhyExpr(biabl->VALABL,"'d'",createAtom("'0'"));
            else
               biabl->VALABL = createAtom("'0'");
            }
         }
      biabl = biabl->NEXT;
      }  
   bux = bux->NEXT;
   }  
}

/*-------------------------------------------------------------------------
AND2	: creation d'un and2 
---------------------------------------------------------------------------
retour		: une expression 
---------------------------------------------------------------------------*/
chain_list *AND2(expr1,expr2)
chain_list *expr1, *expr2;
{
chain_list *ret;

ret = addchain(NULL,(void *) addchain(NULL,(void *) AND)); 
ret->NEXT = addchain(ret->NEXT,(void *) expr2);
ret->NEXT = addchain(ret->NEXT,(void *) expr1);
return ret;
}     

/*-------------------------------------------------------------------------
OR2	: creation d'un or2 
---------------------------------------------------------------------------
retour		: une expression 
---------------------------------------------------------------------------*/
chain_list *OR2(expr1,expr2)
chain_list *expr1, *expr2;
{
chain_list *ret;

ret = addchain(NULL,(void *) addchain(NULL,(void *) OR)); 
ret->NEXT = addchain(ret->NEXT,(void *) expr2);
ret->NEXT = addchain(ret->NEXT,(void *) expr1);
return ret;
}     

/*-------------------------------------------------------------------------
videBddBefig 	: vide tous les bdd calcules dans une befig. 
---------------------------------------------------------------------------
retour		: rien.
---------------------------------------------------------------------------*/
void videBddBefig(beh)
befig_list *beh;
{
beout_list *out;
beaux_list *aux;
bebus_list *bus;
bebux_list *bux;
bereg_list *reg;
bemsg_list *msg;
binode_list *binode;

out = beh->BEOUT;
while (out) 		/* les sorties primaires */
   {
   out->NODE = NULL;
   out = out->NEXT;
   }

aux = beh->BEAUX;
while (aux) 		/* les auxiliaires */
   {
   aux->NODE = NULL;
   aux = aux->NEXT;
   }

bus = beh->BEBUS;
while (bus) 		/* les bus */
   {
   binode = bus->BINODE;
   while (binode)
      {
      binode->CNDNODE = NULL;
      binode->VALNODE = NULL;
      binode = binode->NEXT;
      }
   bus = bus->NEXT;
   }

bux = beh->BEBUX;
while (bux) 		/* les bux */
   {
   binode = bux->BINODE;
   while (binode)
      {
      binode->CNDNODE = NULL;
      binode->VALNODE = NULL;
      binode = binode->NEXT;
      }
   bux = bux->NEXT;
   }


reg = beh->BEREG;
while (reg) 		/* les registres */
   {
   binode = reg->BINODE;
   while (binode)
      {
      binode->CNDNODE = NULL;
      binode->VALNODE = NULL;
      binode = binode->NEXT;
      }
   reg = reg->NEXT;
   }
msg = beh->BEMSG;
while (msg) 		/* les messages */
   {
   msg->NODE = NULL;
   msg = msg->NEXT;
   }
}
/*-------------------------------------------------------------------------
exprToCLBeh 	: remplit une liste chainee de pointeurs sur tout les ABL
                  d'une BEFIG 
---------------------------------------------------------------------------
retour		: un pointeur de chain_list.
---------------------------------------------------------------------------*/
chain_list *exprToCLBeh(beh)
befig_list *beh;
{
beout_list *out;
beaux_list *aux;
bebus_list *bus;
bebux_list *bux;
bereg_list *reg;
bemsg_list *msg;
biabl_list *biabl;
chain_list *ret=NULL;

out = beh->BEOUT;
while (out) 		/* les sorties primaires */
   {
   ret = addchain(ret,out->ABL);
   out = out->NEXT;
   }

aux = beh->BEAUX;
while (aux) 		/* les auxiliaires */
   {
   ret = addchain(ret,aux->ABL);
   aux = aux->NEXT;
   }

bus = beh->BEBUS;
while (bus) 		/* les bus */
   {
   biabl = bus->BIABL;
   while (biabl)
      {
      ret = addchain(ret,biabl->VALABL);
      ret = addchain(ret,biabl->CNDABL);
      biabl = biabl->NEXT;
      }
   bus = bus->NEXT;
   }

bux = beh->BEBUX;
while (bux) 		/* les bux */
   {
   biabl = bux->BIABL;
   while (biabl)
      {
      ret = addchain(ret,biabl->VALABL);
      ret = addchain(ret,biabl->CNDABL);
      biabl = biabl->NEXT;
      }
   bux = bux->NEXT;
   }


reg = beh->BEREG;
while (reg) 		/* les registres */
   {
   biabl = reg->BIABL;
   while (biabl)
      {
      ret = addchain(ret,biabl->VALABL);
      ret = addchain(ret,biabl->CNDABL);
      biabl = biabl->NEXT;
      }
   reg = reg->NEXT;
   }
msg = beh->BEMSG;
while (msg) 		/* les messages */
   {
   ret = addchain(ret,msg->ABL);
   msg = msg->NEXT;
   }
return ret;
}
