/***************************************************************************
* Fonctions utiles pour befig : optimisation des abl d'un befig, evaluation *
* du cout . . . 															*
* 					Le 01/09/92.
****************************************************************************/
#include <stdio.h>
#include  MUT_H
#include  LOG_H
#include"../beh104/beh104.h"
#include"../syf/syf_auto.h"

/*extern int syf_eval ;*/
/*--------------------------------------------------------
coutBehAuto		: Compte le nombre des literaux d'un befig.
--------------------------------
parametres		: befig .
--------------------------------
return			: le nombre de literaux total .
---------------------------------------------------------------*/
int coutBehAuto(beh)
syf_befig_list *beh ;
{
int lit ;
syf_beout_list *out ;
syf_beaux_list *aux ;
syf_bereg_list *reg ;
biabl_list *biabl ;


lit = 0 ;
out = beh->BEOUT;
while (out)
	{
	if (out->ABL)
			lit   = lit + numberAtomExpr(out->ABL);
	out = out->NEXT ;
	}

aux = beh->BEAUX;
while (aux)
	{   
	if (aux->ABL)
		lit   = lit + numberAtomExpr(aux->ABL); 
	aux = aux->NEXT ;
	} 
									 
reg = beh->BEREG;
while (reg)
	{   
	biabl = reg->BIABL ;
	while(biabl)
		{
		lit   = lit + numberAtomExpr(biabl->VALABL); 
		lit   = lit + numberAtomExpr(biabl->CNDABL); 
		biabl = biabl->NEXT ;
		} 
	reg = reg->NEXT ;
	}
return(lit) ;
}
/*------------------------------------------------------------------------i
syf_mapCarExprBeh	: applique une fonction de conversion sur chaque expression
                  d'une befig 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/
void syf_mapCarExprBeh(beh,func)

syf_befig_list *beh;
chain_list *(*func)();
{
syf_beout_list *out;
syf_bereg_list *reg;
syf_bebus_list *bus;
syf_bebux_list *bux;
biabl_list *biabl;
syf_beaux_list *aux;
chain_list *expr;


aux = beh->BEAUX;
while (aux) 
   {
   if (aux->ABL)
      {
      expr = (*func)(aux->ABL);
      freeExpr(aux->ABL); 
      aux->ABL = expr;
      }
   aux = aux->NEXT;
   }

out = beh->BEOUT;
while (out) 
   {
   if (out->ABL)
      {
      expr = (*func)(out->ABL);
      freeExpr(out->ABL);
      out->ABL = expr;
      }
   out = out->NEXT;
   }

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

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

bux = beh->BEBUX;
while (bux) 
   {
   biabl = bux->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         expr = (*func)(biabl->CNDABL);
         freeExpr(biabl->CNDABL);
         biabl->CNDABL = expr;
         expr = (*func)(biabl->VALABL);
         freeExpr(biabl->VALABL);
         biabl->VALABL = expr;
         }
      biabl = biabl->NEXT;
      }
   bux = bux->NEXT;
   }
}
/*---------------------------------------------------------------------------
makeCctBeh	: remplie le champ CIRCUI d'un beh.
------------------------------------------------
parametres	: beh, auxSave.
------------------------------------------------
return	: le circuit..
-----------------------------------------------------------------------------*/
pCircuit makeCctBeh(beh,auxSave,trace)
struct syf_befig *beh ;
int auxSave ;
int trace ;
{
pState state;
int i,coInter ;
chain_list *orderPI, *syf_berinToChain_list() ;
chain_list *ptChain ;
syf_beaux_list *aux ;
int gcOk ;

/*orderPI = makeOrderAbl(beh,order,0) ;*/
orderPI = syf_berinToChain_list(beh) ;

coInter = 0;

/*if(syf_eval)
	if(auxSave != 0)
		{
		aux = beh->BEAUX;
   		while(aux)
   			{
   			orderPI = addchain(orderPI,aux->NAME);
   			aux = aux->NEXT ;
   			coInter++;
   			}
		}*/

beh->CIRCUI = initializeCct(beh->NAME,coInter+2*syf_countInputBeh(beh) + 1,100) ;

ptChain = orderPI;
  while (ptChain)
  {
  addInputCct(beh->CIRCUI,ptChain->DATA);
  ptChain = ptChain->NEXT ;
  } 
/*
state = autoSys->state ;
for(i = 0; i < autoSys->numberState; i++)
  {
  addInputCct(beh->CIRCUI,nameSl(state->name));
  state++ ;
  } 
*/
gcOk = 0 ;
syf_makeBddBeh(beh,beh->CIRCUI,1,trace,50) ;
/*
if(syf_eval)
	delAuxBeh(beh,trace) ;
*/
/*while( syf_makeBddBeh(beh,beh->CIRCUI,1,trace,50) == 1 )
   {
   orderPI = makeOrderBddBeh (beh,0,NULL,NULL,2,10,gcOK,0,8,0);
   vhb_reorder--;
   }*/
return(beh->CIRCUI) ;
}
/*-----------------------------------------------------------------------
syf_berinToChain_list : forme une chaine liste des entrees.
					prend l'odre d'apparition.
-----------------------------------------------------------------------
parametres 		   : beh.
---------------------------------------------------------------------------
retour      : un pointeur de chain_list.
---------------------------------------------------------------------------*/
chain_list *syf_berinToChain_list(beh)
syf_befig_list *beh;
{
syf_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);
}

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

int syf_countInputBeh(beh)
syf_befig_list *beh;
{
syf_berin_list *in;
int count = 0;

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

return(count);
}
/*----------------------------------------------------------------------------
syf_displayChain_list : affiche en colonnes les entrees ou sortie donnees par une LC
------------------------------------------------------------------------------
retour		: le nombre de colonnes affichees    (int)
----------------------------------------------------------------------------*/ 
int syf_displayChain_list( IO)
chain_list	*IO;
{
chain_list *list ;

list = IO ;

printf("*********** syf_displayChain_list ************\n") ;
while ( list )  {
			  printf(" %s\n",list->DATA);
			  list = list->NEXT;
			  }
printf("*********** END display ************\n") ;
fflush(stdout) ;
}
/* --------------------------------------------------------------------
syf_displayBehMap 	: affiche les signaux d'une befig et leur ABL
---------------------------------------------------------------
parametres		:   nb = 1 : befig comportementale
				    nb = 0 : befig structurelle
					befig.
---------------------------------------------------------------
return			:  rien.

 -------------------------------------------------------------------- */
void syf_displayBehMap(befig,nb)
syf_befig_list *befig;
short nb;
{
int j ;
syf_berin_list *i;
syf_bepor_list *p;
syf_beout_list *o;
syf_bereg_list *r;
syf_bebus_list *b;
syf_beaux_list *a;

j = 0 ;
fprintf(stdout,"----- display Befig (%s) -----\n",nb ? "comportementale" : "structurelle");
printf("***************** DISPLAY BEFIG ******************\n");
printf(" POR :\n");
for(p = befig->BEPOR;p;p = p->NEXT)
	{
	printf("%d   => %s\n",j,p->NAME);
	j++ ;
	}

j = 0 ;
printf(" IN :\n");
for(i = befig->BERIN;i;i = i->NEXT)
	{
	printf("%d   => %s\n",j,i->NAME);
	j++ ;
	}
printf(" OUT :\n");
for(o = befig->BEOUT;o;o = o->NEXT)
	{
	printf("   => %s =",o->NAME);
	displayExpr(o->ABL);printf("\n");
	}
printf(" AUX :\n");
for(a = befig->BEAUX;a;a = a->NEXT)
	{
	printf("   => %s =",a->NAME);
	displayExpr(a->ABL);printf("\n");
	}
printf(" BUS :\n");
for(b = befig->BEBUS;b;b = b->NEXT)
	{
	biabl_list *bi;

	printf("   => %s\n",b->NAME);
	for(bi = b->BIABL;bi;bi = bi->NEXT)
	    {
	    printf("         = VAL :",b->NAME);
	    displayExpr(bi->VALABL);printf("\n");
	    if (nb)
               {
	       printf("         = CND :");
	       displayExpr(bi->CNDABL);printf("\n");
 	       }
	    }
	}
printf(" REG :\n");
for(r = befig->BEREG;r;r = r->NEXT)
	{
	biabl_list *bi;

	printf("   => %s =",r->NAME);
	if (!nb)
	    {
	    displayExpr(r->BIABL->VALABL);
	    printf("\n");
	    }
	else
	for(bi = r->BIABL;bi;bi = bi->NEXT)
	    {
	    displayExpr(bi->VALABL);printf("\n");
	    displayExpr(bi->CNDABL);printf("\n");
	    }
	}
printf("***************** END DISPLAY ******************\n");
}
