summaryrefslogtreecommitdiffstats
path: root/src/opt/sim/simUtils.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2007-09-30 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2007-09-30 08:01:00 -0700
commite54d9691616b9a0326e2fdb3156bb4eeb8abfcd7 (patch)
treede3ffe87c3e17950351e3b7d97fa18318bd5ea9a /src/opt/sim/simUtils.c
parent7d7e60f2dc84393cd4c5db22d2eaf7b1fb1a79b2 (diff)
downloadabc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.tar.gz
abc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.tar.bz2
abc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.zip
Version abc70930
Diffstat (limited to 'src/opt/sim/simUtils.c')
-rw-r--r--src/opt/sim/simUtils.c711
1 files changed, 0 insertions, 711 deletions
diff --git a/src/opt/sim/simUtils.c b/src/opt/sim/simUtils.c
deleted file mode 100644
index b0660001..00000000
--- a/src/opt/sim/simUtils.c
+++ /dev/null
@@ -1,711 +0,0 @@
-/**CFile****************************************************************
-
- FileName [simUtils.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [Network and node package.]
-
- Synopsis [Various simulation utilities.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: simUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "abc.h"
-#include "sim.h"
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-static int bit_count[256] = {
- 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
- 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
- 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
- 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
- 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
-};
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis [Allocates simulation information for all nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Sim_UtilInfoAlloc( int nSize, int nWords, bool fClean )
-{
- Vec_Ptr_t * vInfo;
- int i;
- assert( nSize > 0 && nWords > 0 );
- vInfo = Vec_PtrAlloc( nSize );
- vInfo->pArray[0] = ALLOC( unsigned, nSize * nWords );
- if ( fClean )
- memset( vInfo->pArray[0], 0, sizeof(unsigned) * nSize * nWords );
- for ( i = 1; i < nSize; i++ )
- vInfo->pArray[i] = ((unsigned *)vInfo->pArray[i-1]) + nWords;
- vInfo->nSize = nSize;
- return vInfo;
-}
-
-/**Function*************************************************************
-
- Synopsis [Allocates simulation information for all nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilInfoFree( Vec_Ptr_t * p )
-{
- free( p->pArray[0] );
- Vec_PtrFree( p );
-}
-
-/**Function*************************************************************
-
- Synopsis [Adds the second supp-info the first.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilInfoAdd( unsigned * pInfo1, unsigned * pInfo2, int nWords )
-{
- int w;
- for ( w = 0; w < nWords; w++ )
- pInfo1[w] |= pInfo2[w];
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns the positions where pInfo2 is 1 while pInfo1 is 0.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilInfoDetectDiffs( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs )
-{
- int w, b;
- unsigned uMask;
- vDiffs->nSize = 0;
- for ( w = 0; w < nWords; w++ )
- if ( uMask = (pInfo2[w] ^ pInfo1[w]) )
- for ( b = 0; b < 32; b++ )
- if ( uMask & (1 << b) )
- Vec_IntPush( vDiffs, 32*w + b );
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns the positions where pInfo2 is 1 while pInfo1 is 0.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilInfoDetectNews( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs )
-{
- int w, b;
- unsigned uMask;
- vDiffs->nSize = 0;
- for ( w = 0; w < nWords; w++ )
- if ( uMask = (pInfo2[w] & ~pInfo1[w]) )
- for ( b = 0; b < 32; b++ )
- if ( uMask & (1 << b) )
- Vec_IntPush( vDiffs, 32*w + b );
-}
-
-/**Function*************************************************************
-
- Synopsis [Flips the simulation info of the node.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilInfoFlip( Sim_Man_t * p, Abc_Obj_t * pNode )
-{
- unsigned * pSimInfo1, * pSimInfo2;
- int k;
- pSimInfo1 = p->vSim0->pArray[pNode->Id];
- pSimInfo2 = p->vSim1->pArray[pNode->Id];
- for ( k = 0; k < p->nSimWords; k++ )
- pSimInfo2[k] = ~pSimInfo1[k];
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns 1 if the simulation infos are equal.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-bool Sim_UtilInfoCompare( Sim_Man_t * p, Abc_Obj_t * pNode )
-{
- unsigned * pSimInfo1, * pSimInfo2;
- int k;
- pSimInfo1 = p->vSim0->pArray[pNode->Id];
- pSimInfo2 = p->vSim1->pArray[pNode->Id];
- for ( k = 0; k < p->nSimWords; k++ )
- if ( pSimInfo2[k] != pSimInfo1[k] )
- return 0;
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Simulates the internal nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilSimulate( Sim_Man_t * p, bool fType )
-{
- Abc_Obj_t * pNode;
- int i;
- // simulate the internal nodes
- Abc_NtkForEachNode( p->pNtk, pNode, i )
- Sim_UtilSimulateNode( p, pNode, fType, fType, fType );
- // assign simulation info of the CO nodes
- Abc_NtkForEachCo( p->pNtk, pNode, i )
- Sim_UtilSimulateNode( p, pNode, fType, fType, fType );
-}
-
-/**Function*************************************************************
-
- Synopsis [Simulates one node.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fType1, bool fType2 )
-{
- unsigned * pSimmNode, * pSimmNode1, * pSimmNode2;
- int k, fComp1, fComp2;
- // simulate the internal nodes
- if ( Abc_ObjIsNode(pNode) )
- {
- if ( fType )
- pSimmNode = p->vSim1->pArray[ pNode->Id ];
- else
- pSimmNode = p->vSim0->pArray[ pNode->Id ];
-
- if ( fType1 )
- pSimmNode1 = p->vSim1->pArray[ Abc_ObjFaninId0(pNode) ];
- else
- pSimmNode1 = p->vSim0->pArray[ Abc_ObjFaninId0(pNode) ];
-
- if ( fType2 )
- pSimmNode2 = p->vSim1->pArray[ Abc_ObjFaninId1(pNode) ];
- else
- pSimmNode2 = p->vSim0->pArray[ Abc_ObjFaninId1(pNode) ];
-
- fComp1 = Abc_ObjFaninC0(pNode);
- fComp2 = Abc_ObjFaninC1(pNode);
- if ( fComp1 && fComp2 )
- for ( k = 0; k < p->nSimWords; k++ )
- pSimmNode[k] = ~pSimmNode1[k] & ~pSimmNode2[k];
- else if ( fComp1 && !fComp2 )
- for ( k = 0; k < p->nSimWords; k++ )
- pSimmNode[k] = ~pSimmNode1[k] & pSimmNode2[k];
- else if ( !fComp1 && fComp2 )
- for ( k = 0; k < p->nSimWords; k++ )
- pSimmNode[k] = pSimmNode1[k] & ~pSimmNode2[k];
- else // if ( fComp1 && fComp2 )
- for ( k = 0; k < p->nSimWords; k++ )
- pSimmNode[k] = pSimmNode1[k] & pSimmNode2[k];
- }
- else
- {
- assert( Abc_ObjFaninNum(pNode) == 1 );
- if ( fType )
- pSimmNode = p->vSim1->pArray[ pNode->Id ];
- else
- pSimmNode = p->vSim0->pArray[ pNode->Id ];
-
- if ( fType1 )
- pSimmNode1 = p->vSim1->pArray[ Abc_ObjFaninId0(pNode) ];
- else
- pSimmNode1 = p->vSim0->pArray[ Abc_ObjFaninId0(pNode) ];
-
- fComp1 = Abc_ObjFaninC0(pNode);
- if ( fComp1 )
- for ( k = 0; k < p->nSimWords; k++ )
- pSimmNode[k] = ~pSimmNode1[k];
- else
- for ( k = 0; k < p->nSimWords; k++ )
- pSimmNode[k] = pSimmNode1[k];
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Simulates one node.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords, int nOffset )
-{
- unsigned * pSimmNode, * pSimmNode1, * pSimmNode2;
- int k, fComp1, fComp2;
- // simulate the internal nodes
- assert( Abc_ObjIsNode(pNode) );
- pSimmNode = Vec_PtrEntry(vSimInfo, pNode->Id);
- pSimmNode1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode));
- pSimmNode2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode));
- pSimmNode += nOffset;
- pSimmNode1 += nOffset;
- pSimmNode2 += nOffset;
- fComp1 = Abc_ObjFaninC0(pNode);
- fComp2 = Abc_ObjFaninC1(pNode);
- if ( fComp1 && fComp2 )
- for ( k = 0; k < nSimWords; k++ )
- pSimmNode[k] = ~pSimmNode1[k] & ~pSimmNode2[k];
- else if ( fComp1 && !fComp2 )
- for ( k = 0; k < nSimWords; k++ )
- pSimmNode[k] = ~pSimmNode1[k] & pSimmNode2[k];
- else if ( !fComp1 && fComp2 )
- for ( k = 0; k < nSimWords; k++ )
- pSimmNode[k] = pSimmNode1[k] & ~pSimmNode2[k];
- else // if ( fComp1 && fComp2 )
- for ( k = 0; k < nSimWords; k++ )
- pSimmNode[k] = pSimmNode1[k] & pSimmNode2[k];
-}
-
-/**Function*************************************************************
-
- Synopsis [Simulates one node.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilTransferNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords, int nOffset, int fShift )
-{
- unsigned * pSimmNode, * pSimmNode1;
- int k, fComp1;
- // simulate the internal nodes
- assert( Abc_ObjIsCo(pNode) );
- pSimmNode = Vec_PtrEntry(vSimInfo, pNode->Id);
- pSimmNode1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode));
- pSimmNode += nOffset + (fShift > 0)*nSimWords;
- pSimmNode1 += nOffset;
- fComp1 = Abc_ObjFaninC0(pNode);
- if ( fComp1 )
- for ( k = 0; k < nSimWords; k++ )
- pSimmNode[k] = ~pSimmNode1[k];
- else
- for ( k = 0; k < nSimWords; k++ )
- pSimmNode[k] = pSimmNode1[k];
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns 1 if the simulation infos are equal.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Sim_UtilCountSuppSizes( Sim_Man_t * p, int fStruct )
-{
- Abc_Obj_t * pNode, * pNodeCi;
- int i, v, Counter;
- Counter = 0;
- if ( fStruct )
- {
- Abc_NtkForEachCo( p->pNtk, pNode, i )
- Abc_NtkForEachCi( p->pNtk, pNodeCi, v )
- Counter += Sim_SuppStrHasVar( p->vSuppStr, pNode, v );
- }
- else
- {
- Abc_NtkForEachCo( p->pNtk, pNode, i )
- Abc_NtkForEachCi( p->pNtk, pNodeCi, v )
- Counter += Sim_SuppFunHasVar( p->vSuppFun, i, v );
- }
- return Counter;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of 1's in the bitstring.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Sim_UtilCountOnes( unsigned * pSimInfo, int nSimWords )
-{
- unsigned char * pBytes;
- int nOnes, nBytes, i;
- pBytes = (unsigned char *)pSimInfo;
- nBytes = 4 * nSimWords;
- nOnes = 0;
- for ( i = 0; i < nBytes; i++ )
- nOnes += bit_count[ pBytes[i] ];
- return nOnes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of 1's in the bitstring.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Int_t * Sim_UtilCountOnesArray( Vec_Ptr_t * vInfo, int nSimWords )
-{
- Vec_Int_t * vCounters;
- unsigned * pSimInfo;
- int i;
- vCounters = Vec_IntStart( Vec_PtrSize(vInfo) );
- Vec_PtrForEachEntry( vInfo, pSimInfo, i )
- Vec_IntWriteEntry( vCounters, i, Sim_UtilCountOnes(pSimInfo, nSimWords) );
- return vCounters;
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns random patterns.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilSetRandom( unsigned * pPatRand, int nSimWords )
-{
- int k;
- for ( k = 0; k < nSimWords; k++ )
- pPatRand[k] = SIM_RANDOM_UNSIGNED;
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns complemented patterns.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilSetCompl( unsigned * pPatRand, int nSimWords )
-{
- int k;
- for ( k = 0; k < nSimWords; k++ )
- pPatRand[k] = ~pPatRand[k];
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns constant patterns.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilSetConst( unsigned * pPatRand, int nSimWords, int fConst1 )
-{
- int k;
- for ( k = 0; k < nSimWords; k++ )
- pPatRand[k] = 0;
- if ( fConst1 )
- Sim_UtilSetCompl( pPatRand, nSimWords );
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns 1 if equal.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Sim_UtilInfoIsEqual( unsigned * pPats1, unsigned * pPats2, int nSimWords )
-{
- int k;
- for ( k = 0; k < nSimWords; k++ )
- if ( pPats1[k] != pPats2[k] )
- return 0;
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns 1 if Node1 implies Node2.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Sim_UtilInfoIsImp( unsigned * pPats1, unsigned * pPats2, int nSimWords )
-{
- int k;
- for ( k = 0; k < nSimWords; k++ )
- if ( pPats1[k] & ~pPats2[k] )
- return 0;
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns 1 if Node1 v Node2 is always true.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Sim_UtilInfoIsClause( unsigned * pPats1, unsigned * pPats2, int nSimWords )
-{
- int k;
- for ( k = 0; k < nSimWords; k++ )
- if ( ~pPats1[k] & ~pPats2[k] )
- return 0;
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the total number of pairs.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Sim_UtilCountAllPairs( Vec_Ptr_t * vSuppFun, int nSimWords, Vec_Int_t * vCounters )
-{
- unsigned * pSupp;
- int Counter, nOnes, nPairs, i;
- Counter = 0;
- Vec_PtrForEachEntry( vSuppFun, pSupp, i )
- {
- nOnes = Sim_UtilCountOnes( pSupp, nSimWords );
- nPairs = nOnes * (nOnes - 1) / 2;
- Vec_IntWriteEntry( vCounters, i, nPairs );
- Counter += nPairs;
- }
- return Counter;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of entries in the array of matrices.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Sim_UtilCountPairsOne( Extra_BitMat_t * pMat, Vec_Int_t * vSupport )
-{
- int i, k, Index1, Index2;
- int Counter = 0;
-// int Counter2;
- Vec_IntForEachEntry( vSupport, i, Index1 )
- Vec_IntForEachEntryStart( vSupport, k, Index2, Index1+1 )
- Counter += Extra_BitMatrixLookup1( pMat, i, k );
-// Counter2 = Extra_BitMatrixCountOnesUpper(pMat);
-// assert( Counter == Counter2 );
- return Counter;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of entries in the array of matrices.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Sim_UtilCountPairsOnePrint( Extra_BitMat_t * pMat, Vec_Int_t * vSupport )
-{
- int i, k, Index1, Index2;
- Vec_IntForEachEntry( vSupport, i, Index1 )
- Vec_IntForEachEntryStart( vSupport, k, Index2, Index1+1 )
- if ( Extra_BitMatrixLookup1( pMat, i, k ) )
- printf( "(%d,%d) ", i, k );
- return 0;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of entries in the array of matrices.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilCountPairsAllPrint( Sym_Man_t * p )
-{
- int i, clk;
-clk = clock();
- for ( i = 0; i < p->nOutputs; i++ )
- {
- printf( "Output %2d :", i );
- Sim_UtilCountPairsOnePrint( Vec_PtrEntry(p->vMatrSymms, i), Vec_VecEntry(p->vSupports, i) );
- printf( "\n" );
- }
-p->timeCount += clock() - clk;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of entries in the array of matrices.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Sim_UtilCountPairsAll( Sym_Man_t * p )
-{
- int nPairsTotal, nPairsSym, nPairsNonSym, i, clk;
-clk = clock();
- p->nPairsSymm = 0;
- p->nPairsNonSymm = 0;
- for ( i = 0; i < p->nOutputs; i++ )
- {
- nPairsTotal = Vec_IntEntry(p->vPairsTotal, i);
- nPairsSym = Vec_IntEntry(p->vPairsSym, i);
- nPairsNonSym = Vec_IntEntry(p->vPairsNonSym,i);
- assert( nPairsTotal >= nPairsSym + nPairsNonSym );
- if ( nPairsTotal == nPairsSym + nPairsNonSym )
- {
- p->nPairsSymm += nPairsSym;
- p->nPairsNonSymm += nPairsNonSym;
- continue;
- }
- nPairsSym = Sim_UtilCountPairsOne( Vec_PtrEntry(p->vMatrSymms, i), Vec_VecEntry(p->vSupports, i) );
- nPairsNonSym = Sim_UtilCountPairsOne( Vec_PtrEntry(p->vMatrNonSymms,i), Vec_VecEntry(p->vSupports, i) );
- assert( nPairsTotal >= nPairsSym + nPairsNonSym );
- Vec_IntWriteEntry( p->vPairsSym, i, nPairsSym );
- Vec_IntWriteEntry( p->vPairsNonSym, i, nPairsNonSym );
- p->nPairsSymm += nPairsSym;
- p->nPairsNonSymm += nPairsNonSym;
-// printf( "%d ", nPairsTotal - nPairsSym - nPairsNonSym );
- }
-//printf( "\n" );
- p->nPairsRem = p->nPairsTotal-p->nPairsSymm-p->nPairsNonSymm;
-p->timeCount += clock() - clk;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Sim_UtilMatrsAreDisjoint( Sym_Man_t * p )
-{
- int i;
- for ( i = 0; i < p->nOutputs; i++ )
- if ( !Extra_BitMatrixIsDisjoint( Vec_PtrEntry(p->vMatrSymms,i), Vec_PtrEntry(p->vMatrNonSymms,i) ) )
- return 0;
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-