/**CFile****************************************************************

  FileName    [fxuList.c]

  PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]

  Synopsis    [Operations on lists.]

  Author      [MVSIS Group]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - February 1, 2003.]

  Revision    [$Id: fxuList.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]

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

#include "fxuInt.h"

////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

// matrix -> var

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListMatrixAddVariable( Fxu_Matrix * p, Fxu_Var * pLink ) 
{
	Fxu_ListVar * pList = &p->lVars;
	if ( pList->pHead == NULL )
	{
		pList->pHead = pLink;
		pList->pTail = pLink;
		pLink->pPrev = NULL;
		pLink->pNext = NULL;
	}
	else
	{
		pLink->pNext = NULL;
		pList->pTail->pNext = pLink;
		pLink->pPrev = pList->pTail;
		pList->pTail = pLink;
	}
	pList->nItems++;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListMatrixDelVariable( Fxu_Matrix * p, Fxu_Var * pLink )
{
	Fxu_ListVar * pList = &p->lVars;
	if ( pList->pHead == pLink )
		 pList->pHead = pLink->pNext;
	if ( pList->pTail == pLink )
		 pList->pTail = pLink->pPrev;
	if ( pLink->pPrev )
		 pLink->pPrev->pNext = pLink->pNext;
	if ( pLink->pNext )
		 pLink->pNext->pPrev = pLink->pPrev;
	pList->nItems--;
}


// matrix -> cube

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pLink )
{
	Fxu_ListCube * pList = &p->lCubes;
	if ( pList->pHead == NULL )
	{
		pList->pHead = pLink;
		pList->pTail = pLink;
		pLink->pPrev = NULL;
		pLink->pNext = NULL;
	}
	else
	{
		pLink->pNext = NULL;
		pList->pTail->pNext = pLink;
		pLink->pPrev = pList->pTail;
		pList->pTail = pLink;
	}
	pList->nItems++;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListMatrixDelCube( Fxu_Matrix * p, Fxu_Cube * pLink )
{
	Fxu_ListCube * pList = &p->lCubes;
	if ( pList->pHead == pLink )
		 pList->pHead = pLink->pNext;
	if ( pList->pTail == pLink )
		 pList->pTail = pLink->pPrev;
	if ( pLink->pPrev )
		 pLink->pPrev->pNext = pLink->pNext;
	if ( pLink->pNext )
		 pLink->pNext->pPrev = pLink->pPrev;
	pList->nItems--;
}


// matrix -> single

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListMatrixAddSingle( Fxu_Matrix * p, Fxu_Single * pLink )
{
	Fxu_ListSingle * pList = &p->lSingles;
	if ( pList->pHead == NULL )
	{
		pList->pHead = pLink;
		pList->pTail = pLink;
		pLink->pPrev = NULL;
		pLink->pNext = NULL;
	}
	else
	{
		pLink->pNext = NULL;
		pList->pTail->pNext = pLink;
		pLink->pPrev = pList->pTail;
		pList->pTail = pLink;
	}
	pList->nItems++;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListMatrixDelSingle( Fxu_Matrix * p, Fxu_Single * pLink )
{
	Fxu_ListSingle * pList = &p->lSingles;
	if ( pList->pHead == pLink )
		 pList->pHead = pLink->pNext;
	if ( pList->pTail == pLink )
		 pList->pTail = pLink->pPrev;
	if ( pLink->pPrev )
		 pLink->pPrev->pNext = pLink->pNext;
	if ( pLink->pNext )
		 pLink->pNext->pPrev = pLink->pPrev;
	pList->nItems--;
}


// table -> divisor

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListTableAddDivisor( Fxu_Matrix * p, Fxu_Double * pLink ) 
{
	Fxu_ListDouble * pList = &(p->pTable[pLink->Key]);
	if ( pList->pHead == NULL )
	{
		pList->pHead = pLink;
		pList->pTail = pLink;
		pLink->pPrev = NULL;
		pLink->pNext = NULL;
	}
	else
	{
		pLink->pNext = NULL;
		pList->pTail->pNext = pLink;
		pLink->pPrev = pList->pTail;
		pList->pTail = pLink;
	}
	pList->nItems++;
    p->nDivs++;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListTableDelDivisor( Fxu_Matrix * p, Fxu_Double * pLink ) 
{
	Fxu_ListDouble * pList = &(p->pTable[pLink->Key]);
	if ( pList->pHead == pLink )
		 pList->pHead = pLink->pNext;
	if ( pList->pTail == pLink )
		 pList->pTail = pLink->pPrev;
	if ( pLink->pPrev )
		 pLink->pPrev->pNext = pLink->pNext;
	if ( pLink->pNext )
		 pLink->pNext->pPrev = pLink->pPrev;
	pList->nItems--;
    p->nDivs--;
}


// cube -> literal 

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListCubeAddLiteral( Fxu_Cube * pCube, Fxu_Lit * pLink )
{
	Fxu_ListLit * pList = &(pCube->lLits);
	if ( pList->pHead == NULL )
	{
		pList->pHead = pLink;
		pList->pTail = pLink;
		pLink->pHPrev = NULL;
		pLink->pHNext = NULL;
	}
	else
	{
		pLink->pHNext = NULL;
		pList->pTail->pHNext = pLink;
		pLink->pHPrev = pList->pTail;
		pList->pTail = pLink;
	}
	pList->nItems++;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListCubeDelLiteral( Fxu_Cube * pCube, Fxu_Lit * pLink )
{
	Fxu_ListLit * pList = &(pCube->lLits);
	if ( pList->pHead == pLink )
		 pList->pHead = pLink->pHNext;
	if ( pList->pTail == pLink )
		 pList->pTail = pLink->pHPrev;
	if ( pLink->pHPrev )
		 pLink->pHPrev->pHNext = pLink->pHNext;
	if ( pLink->pHNext )
		 pLink->pHNext->pHPrev = pLink->pHPrev;
	pList->nItems--;
}


// var -> literal

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListVarAddLiteral( Fxu_Var * pVar, Fxu_Lit * pLink )
{
	Fxu_ListLit * pList = &(pVar->lLits);
	if ( pList->pHead == NULL )
	{
		pList->pHead = pLink;
		pList->pTail = pLink;
		pLink->pVPrev = NULL;
		pLink->pVNext = NULL;
	}
	else
	{
		pLink->pVNext = NULL;
		pList->pTail->pVNext = pLink;
		pLink->pVPrev = pList->pTail;
		pList->pTail = pLink;
	}
	pList->nItems++;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListVarDelLiteral( Fxu_Var * pVar, Fxu_Lit * pLink )
{
	Fxu_ListLit * pList = &(pVar->lLits);
	if ( pList->pHead == pLink )
		 pList->pHead = pLink->pVNext;
	if ( pList->pTail == pLink )
		 pList->pTail = pLink->pVPrev;
	if ( pLink->pVPrev )
		 pLink->pVPrev->pVNext = pLink->pVNext;
	if ( pLink->pVNext )
		 pLink->pVNext->pVPrev = pLink->pVPrev;
	pList->nItems--;
}



// divisor -> pair

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListDoubleAddPairLast( Fxu_Double * pDiv, Fxu_Pair * pLink )
{
	Fxu_ListPair * pList = &pDiv->lPairs;
	if ( pList->pHead == NULL )
	{
		pList->pHead = pLink;
		pList->pTail = pLink;
		pLink->pDPrev = NULL;
		pLink->pDNext = NULL;
	}
	else
	{
		pLink->pDNext = NULL;
		pList->pTail->pDNext = pLink;
		pLink->pDPrev = pList->pTail;
		pList->pTail = pLink;
	}
	pList->nItems++;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListDoubleAddPairFirst( Fxu_Double * pDiv, Fxu_Pair * pLink )
{
	Fxu_ListPair * pList = &pDiv->lPairs;
	if ( pList->pHead == NULL )
	{
		pList->pHead = pLink;
		pList->pTail = pLink;
		pLink->pDPrev = NULL;
		pLink->pDNext = NULL;
	}
	else
	{
		pLink->pDPrev = NULL;
		pList->pHead->pDPrev = pLink;
		pLink->pDNext = pList->pHead;
		pList->pHead = pLink;
	}
	pList->nItems++;
}

/**Function*************************************************************

  Synopsis    [Adds the entry in the middle of the list after the spot.]

  Description [Assumes that spot points to the link, after which the given
  link should be added. Spot cannot be NULL or the tail of the list.
  Therefore, the head and the tail of the list are not changed.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListDoubleAddPairMiddle( Fxu_Double * pDiv, Fxu_Pair * pSpot, Fxu_Pair * pLink )
{
	Fxu_ListPair * pList = &pDiv->lPairs;
	assert( pSpot );
	assert( pSpot != pList->pTail );
	pLink->pDPrev = pSpot;
	pLink->pDNext = pSpot->pDNext;
	pLink->pDPrev->pDNext = pLink;
	pLink->pDNext->pDPrev = pLink;
	pList->nItems++;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListDoubleDelPair( Fxu_Double * pDiv, Fxu_Pair * pLink )
{
	Fxu_ListPair * pList = &pDiv->lPairs;
	if ( pList->pHead == pLink )
		 pList->pHead = pLink->pDNext;
	if ( pList->pTail == pLink )
		 pList->pTail = pLink->pDPrev;
	if ( pLink->pDPrev )
		 pLink->pDPrev->pDNext = pLink->pDNext;
	if ( pLink->pDNext )
		 pLink->pDNext->pDPrev = pLink->pDPrev;
	pList->nItems--;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fxu_ListDoubleAddPairPlace( Fxu_Double * pDiv, Fxu_Pair * pPair, Fxu_Pair * pPairSpot )
{
	fprintf(outStream,  "Fxu_ListDoubleAddPairPlace() is called!\n" );
}



////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


