/*******************************************************************************
*									       *
*  	fonctions de factorisation de BDD --> GF			                       *
*									       *
*				Version : 16/04/92 par chaker SARWARY.    *
*									       *
*******************************************************************************/
#include<stdio.h>
#include MUT_H
#include LOG_H
#include"../beh104/beh104.h"
#include"fact.h"

#define NBRE_VAR 500
/*--------------------------------------------------------
minimBehAbl		: factorise les abl d'un befig
--------------------------------
parametres		: befig .
--------------------------------
return			: void .
---------------------------------------------------------------*/
void minimBehAbl(beh,trace)
struct syf_befig *beh ;
int trace ;
{
pTabFact tabFact ;
pNode bdd ;
struct syf_beout *out ;
struct syf_beaux *aux ;
struct syf_bereg *reg ;
struct biabl *biabl ;

if(trace)
	printf("************* MINIMISATION OF BEFIG ABLs *************\n");
tabFact= createTabFact(TAILLE_TAB_FACT) ;

oneFact = addTabFact(tabFact,one,NULL,NULL) ;
zeroFact = addTabFact(tabFact,zero,NULL,NULL) ;

out = beh->BEOUT;
while (out)
	{
	if(trace)
		{
		printf("out : %s\n",out->NAME) ;
		displayExpr(out->ABL) ;
		printf("before optimization : %d\n",numberAtomExpr(out->ABL)) ;
		}
	bdd   = ablToBddCct(beh->CIRCUI,out->ABL);
	freeExpr(out->ABL) ;
	out->ABL = factBdd(tabFact,bdd,beh->CIRCUI) ;
	if(trace)
		{
		printf("after optimization : %d\n",numberAtomExpr(out->ABL)) ;
		}
	out = out->NEXT ;
	}

aux = beh->BEAUX;
while (aux)    
	{   
	if(trace)
		{
		printf("aux : %s\n",aux->NAME) ;
		printf("before optimization : %d\n",numberAtomExpr(aux->ABL)) ;
		}
	bdd   = ablToBddCct(beh->CIRCUI,aux->ABL);
	freeExpr(aux->ABL) ;
	aux->ABL = factBdd(tabFact,bdd,beh->CIRCUI) ;
	if(trace)
		{
		printf("after optimization : %d\n",numberAtomExpr(aux->ABL)) ;
		}
	aux = aux->NEXT ;
	} 

reg = beh->BEREG;
while (reg)
	{   
	biabl = reg->BIABL ;
	if(trace)
		{
		printf("reg : %s\n",reg->NAME) ;
		}
	while(biabl)
		{
		/*
		printf("********* ERREUR ***********\n") ;
		printf("regName : %s\n",reg->NAME) ;
		fflush(stdout) ;
		displayExpr(biabl->VALABL) ;
		fflush(stdout) ;
		*/
		if(trace)
			{
			printf("before optimization : %d\n",numberAtomExpr(biabl->VALABL)) ;
			}
		bdd   = ablToBddCct(beh->CIRCUI,biabl->VALABL);
		freeExpr(biabl->VALABL) ;
		biabl->VALABL = factBdd(tabFact,bdd,beh->CIRCUI) ;
		if(trace)
			{
			printf("after optimization : %d\n",numberAtomExpr(biabl->VALABL)) ;
			}
		biabl = biabl->NEXT ;
		} 
	reg = reg->NEXT ;
	}
if(trace)
	printf("********** END OF MINIMISATION ************\n") ;
destroyTabFact(tabFact) ;
/*syf_createAuxBeh(beh) ;*/
}
/*------------------------------------------------------------------------------
factTabAbl	:	factorise ts les ABL de la liste passee en parametre, et
			calcule leurs poids . 
------------------------------------------------------
parametres	:	listAbl : liste des ABLs .
			pC : pointeur sur le circuit.
------------------------------------------------------
return		:	table des poids.
------------------------------------------------------------------------------*/
int *factTabAbl(listAbl,pC)
chain_list *listAbl ;
pCircuit pC ;
{
int i ;
pTabFact tabFact ;
chain_list *listAblCur ;
pNode bdd ;
chain_list *abl ;
int *tabPoid ;

tabFact = createTabFact(TAILLE_TAB_FACT) ;

oneFact = addTabFact(tabFact,one,NULL,NULL) ;
zeroFact = addTabFact(tabFact,zero,NULL,NULL) ;

for(listAblCur = listAbl; listAblCur != NULL; listAblCur = listAblCur->NEXT)
	i++ ;

if(!(tabPoid = (int *)mbkalloc((i + 1) * sizeof(int))))
	{
	printf("factTabAbl : Allocation impossible......\n") ;
	exit(-1) ;
	}
listAblCur = listAbl ;
while(listAblCur)
	{
	bdd = ablToBddCct(pC,listAblCur->DATA) ;
	abl = factBdd(tabFact,bdd,pC) ;
	*tabPoid = numberAtomExpr(abl) ;
	tabPoid++ ;
	*tabPoid = -1 ;
	listAblCur = listAblCur->NEXT ;
	}
}
/*------------------------------------------------------------------------------
factBdd		:	genere un GF a partir d'un BDD, et le met sous la forme
			ABL . 
------------------------------------------------------
parametres	:	pBdd : pointeur sur le Bdd a factoriser.
			tabInput : table des noms des variables d'entrees .
			tabFact : table de hash pour la factorisation .
------------------------------------------------------
return		:	pointeur sur ABL.
------------------------------------------------------------------------------*/
chain_list *factBdd(tabFact,pBdd,pC)
pTabFact tabFact ;
pNode pBdd ;
pCircuit pC ;
{
pFact fact, reduceFact1,reduceFact2,reduceFact3 ;
chain_list *abl ;
pNode *divRecom, bddF ;
int numOrig, numFact ;

if(pBdd == zero)
	return(createAtom("'0'")) ;
if(pBdd == one)
	return(createAtom("'1'")) ;
divRecom = (pNode *)mbkalloc((pC->countI + 1) * sizeof(pNode) ) ;
initializeTabPBddFSM(pC->countI + 1,divRecom) ;

if(MODE == OUI)
	printf("**************** factBdd : %d *************** \n",pBdd) ;
fact = factorise3(pC,tabFact,pBdd,divRecom) ;
reduceFact1 = reduceGF(tabFact,fact) ;
reduceFact2 = reduceGF(tabFact,reduceFact1) ;
reduceFact3 = reduceGF(tabFact,reduceFact2) ;

/************************************************destroyGF(fact) ;*/
/*displayTabFact(tabFact) ;*/
/*
if(MODE == OUI)
	{
	printf("*******affichage PGF\n") ;
	displayChainFact(reduceFact,pC->pNameI) ;
	printf("*******fin affichage PGF\n") ;
	}
*/
/*
printf("**********************************************debut 2eme passe\n") ;
divRecom = (pNode *)mbkalloc((pC->countI * sizeof(pNode)) + 1) ;
initializeTabPBddFSM(pC->countI + 1,divRecom) ;
tabFact = createTabFact(TAILLE_TAB_FACT) ;
printf("**********************************************fin initialisation\n") ;
fact = factorise3(pC,tabFact,GFToBdd(reduceGF),divRecom) ;
printf("**********************************************fin factorisation\n") ;
reduceFact = reduceGF(tabFact,fact) ;
reduceFact = reduceGF(tabFact,reduceFact) ;
reduceFact = reduceGF(tabFact,reduceFact) ;
*/


abl = GFToAbl(reduceFact3,pC->pNameI) ;/*remplacer fact par reduceFact3 */
/************ choix entre F factorisee et F original ***************/
/*
bddF = GFToBdd(reduceFact) ;
numOrig = syf_numberAtomFact(pBdd) ;
numFact = syf_numberAtomFact(bddF) ;
if(numOrig < numFact)
	{
	abl = bddToAbl(pBdd,pC->pNameI) ;	
	}
else
	{
	abl = GFToAbl(reduceFact,pC->pNameI) ;
	}
if(MODE == OUI)
	{
	printf("******** EQUIVALENT GF :\n") ;
	displayExpr(abl) ;
	}
*/
/*
deleteFact(reduceFact1) ;
deleteFact(reduceFact2) ;
deleteFact(reduceFact3) ;
*/
/*destroyTabFact(tabFact) ;*/
mbkfree(divRecom) ;
return(abl) ;
}
