#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include "vec.h"
#include "aig.h"
#include "dar.h"
Go to the source code of this file.
Data Structures | |
struct | Dar_Cut_t_ |
struct | Dar_Man_t_ |
Defines | |
#define | Dar_ObjForEachCutAll(pObj, pCut, i) for ( (pCut) = Dar_ObjCuts(pObj), i = 0; i < (int)(pObj)->nCuts; i++, pCut++ ) |
#define | Dar_ObjForEachCut(pObj, pCut, i) for ( (pCut) = Dar_ObjCuts(pObj), i = 0; i < (int)(pObj)->nCuts; i++, pCut++ ) if ( (pCut)->fUsed==0 ) {} else |
#define | Dar_CutForEachLeaf(p, pCut, pLeaf, i) for ( i = 0; (i < (int)(pCut)->nLeaves) && (((pLeaf) = Aig_ManObj(p, (pCut)->pLeaves[i])), 1); i++ ) |
Typedefs | |
typedef struct Dar_Man_t_ | Dar_Man_t |
typedef struct Dar_Cut_t_ | Dar_Cut_t |
Functions | |
static Dar_Cut_t * | Dar_ObjCuts (Aig_Obj_t *pObj) |
static void | Dar_ObjSetCuts (Aig_Obj_t *pObj, Dar_Cut_t *pCuts) |
void | Dar_ManCutsStart (Dar_Man_t *p) |
void | Dar_ManCutsFree (Dar_Man_t *p) |
Dar_Cut_t * | Dar_ObjComputeCuts_rec (Dar_Man_t *p, Aig_Obj_t *pObj) |
Dar_Cut_t * | Dar_ObjComputeCuts (Dar_Man_t *p, Aig_Obj_t *pObj) |
Vec_Int_t * | Dar_LibReadNodes () |
Vec_Int_t * | Dar_LibReadOuts () |
Vec_Int_t * | Dar_LibReadPrios () |
void | Dar_LibStart () |
void | Dar_LibStop () |
void | Dar_LibPrepare (int nSubgraphs) |
void | Dar_LibReturnCanonicals (unsigned *pCanons) |
void | Dar_LibEval (Dar_Man_t *p, Aig_Obj_t *pRoot, Dar_Cut_t *pCut, int Required) |
Aig_Obj_t * | Dar_LibBuildBest (Dar_Man_t *p) |
Dar_Man_t * | Dar_ManStart (Aig_Man_t *pAig, Dar_RwrPar_t *pPars) |
void | Dar_ManStop (Dar_Man_t *p) |
void | Dar_ManPrintStats (Dar_Man_t *p) |
char ** | Dar_Permutations (int n) |
void | Dar_Truth4VarNPN (unsigned short **puCanons, char **puPhases, char **puPerms, unsigned char **puMap) |
#define Dar_CutForEachLeaf | ( | p, | |||
pCut, | |||||
pLeaf, | |||||
i | ) | for ( i = 0; (i < (int)(pCut)->nLeaves) && (((pLeaf) = Aig_ManObj(p, (pCut)->pLeaves[i])), 1); i++ ) |
#define Dar_ObjForEachCut | ( | pObj, | |||
pCut, | |||||
i | ) | for ( (pCut) = Dar_ObjCuts(pObj), i = 0; i < (int)(pObj)->nCuts; i++, pCut++ ) if ( (pCut)->fUsed==0 ) {} else |
#define Dar_ObjForEachCutAll | ( | pObj, | |||
pCut, | |||||
i | ) | for ( (pCut) = Dar_ObjCuts(pObj), i = 0; i < (int)(pObj)->nCuts; i++, pCut++ ) |
typedef struct Dar_Cut_t_ Dar_Cut_t |
typedef struct Dar_Man_t_ Dar_Man_t |
CFile****************************************************************
FileName [darInt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Internal declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [
] INCLUDES /// PARAMETERS /// BASIC TYPES ///
Function*************************************************************
Synopsis [Reconstructs the best cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 966 of file darLib.c.
00967 { 00968 int i, Counter = 4; 00969 for ( i = 0; i < Vec_PtrSize(p->vLeavesBest); i++ ) 00970 s_DarLib->pDatas[i].pFunc = Vec_PtrEntry( p->vLeavesBest, i ); 00971 Dar_LibBuildClear_rec( Dar_LibObj(s_DarLib, p->OutBest), &Counter ); 00972 return Dar_LibBuildBest_rec( p, Dar_LibObj(s_DarLib, p->OutBest) ); 00973 }
Function*************************************************************
Synopsis [Evaluates one cut.]
Description [Returns the best gain.]
SideEffects []
SeeAlso []
Definition at line 859 of file darLib.c.
00860 { 00861 int fTraining = 0; 00862 Dar_LibObj_t * pObj; 00863 int Out, k, Class, nNodesSaved, nNodesAdded, nNodesGained, clk; 00864 clk = clock(); 00865 if ( pCut->nLeaves != 4 ) 00866 return; 00867 // check if the cut exits and assigns leaves and their levels 00868 if ( !Dar_LibCutMatch(p, pCut) ) 00869 return; 00870 // mark MFFC of the node 00871 nNodesSaved = Dar_LibCutMarkMffc( p->pAig, pRoot, pCut->nLeaves ); 00872 // evaluate the cut 00873 Class = s_DarLib->pMap[pCut->uTruth]; 00874 Dar_LibEvalAssignNums( p, Class ); 00875 // profile outputs by their savings 00876 p->nTotalSubgs += s_DarLib->nSubgr0[Class]; 00877 p->ClassSubgs[Class] += s_DarLib->nSubgr0[Class]; 00878 for ( Out = 0; Out < s_DarLib->nSubgr0[Class]; Out++ ) 00879 { 00880 pObj = Dar_LibObj(s_DarLib, s_DarLib->pSubgr0[Class][Out]); 00881 if ( Aig_Regular(s_DarLib->pDatas[pObj->Num].pFunc) == pRoot ) 00882 continue; 00883 nNodesAdded = Dar_LibEval_rec( pObj, Out, nNodesSaved - !p->pPars->fUseZeros, Required ); 00884 nNodesGained = nNodesSaved - nNodesAdded; 00885 if ( fTraining && nNodesGained >= 0 ) 00886 Dar_LibIncrementScore( Class, Out, nNodesGained + 1 ); 00887 if ( nNodesGained < 0 || (nNodesGained == 0 && !p->pPars->fUseZeros) ) 00888 continue; 00889 if ( nNodesGained < p->GainBest || 00890 (nNodesGained == p->GainBest && s_DarLib->pDatas[pObj->Num].Level >= p->LevelBest) ) 00891 continue; 00892 // remember this possibility 00893 Vec_PtrClear( p->vLeavesBest ); 00894 for ( k = 0; k < (int)pCut->nLeaves; k++ ) 00895 Vec_PtrPush( p->vLeavesBest, s_DarLib->pDatas[k].pFunc ); 00896 p->OutBest = s_DarLib->pSubgr0[Class][Out]; 00897 p->OutNumBest = Out; 00898 p->LevelBest = s_DarLib->pDatas[pObj->Num].Level; 00899 p->GainBest = nNodesGained; 00900 p->ClassBest = Class; 00901 assert( p->LevelBest <= Required ); 00902 } 00903 clk = clock() - clk; 00904 p->ClassTimes[Class] += clk; 00905 p->timeEval += clk; 00906 }
void Dar_LibPrepare | ( | int | nSubgraphs | ) |
Function*************************************************************
Synopsis [Starts the library.]
Description []
SideEffects []
SeeAlso []
Definition at line 453 of file darLib.c.
00454 { 00455 Dar_Lib_t * p = s_DarLib; 00456 int i, k, nNodes0Total; 00457 if ( p->nSubgraphs == nSubgraphs ) 00458 return; 00459 00460 // favor special classes: 00461 // 1 : F = (!d*!c*!b*!a) 00462 // 4 : F = (!d*!c*!(b*a)) 00463 // 12 : F = (!d*!(c*!(!b*!a))) 00464 // 20 : F = (!d*!(c*b*a)) 00465 00466 // set the subgraph counters 00467 p->nSubgr0Total = 0; 00468 for ( i = 0; i < 222; i++ ) 00469 { 00470 // if ( i == 1 || i == 4 || i == 12 || i == 20 ) // special classes 00471 if ( i == 1 ) // special classes 00472 p->nSubgr0[i] = p->nSubgr[i]; 00473 else 00474 p->nSubgr0[i] = AIG_MIN( p->nSubgr[i], nSubgraphs ); 00475 p->nSubgr0Total += p->nSubgr0[i]; 00476 for ( k = 0; k < p->nSubgr0[i]; k++ ) 00477 p->pSubgr0[i][k] = p->pSubgr[i][ p->pPrios[i][k] ]; 00478 } 00479 00480 // count the number of nodes 00481 // clean node counters 00482 for ( i = 0; i < 222; i++ ) 00483 p->nNodes0[i] = 0; 00484 // create traversal IDs 00485 for ( i = 0; i < p->iObj; i++ ) 00486 Dar_LibObj(p, i)->Num = 0xff; 00487 // count nodes in each class 00488 // count the total number of nodes and the largest class 00489 p->nNodes0Total = 0; 00490 p->nNodes0Max = 0; 00491 for ( i = 0; i < 222; i++ ) 00492 { 00493 for ( k = 0; k < p->nSubgr0[i]; k++ ) 00494 Dar_LibSetup0_rec( p, Dar_LibObj(p, p->pSubgr0[i][k]), i, 0 ); 00495 p->nNodes0Total += p->nNodes0[i]; 00496 p->nNodes0Max = AIG_MAX( p->nNodes0Max, p->nNodes0[i] ); 00497 } 00498 00499 // clean node counters 00500 for ( i = 0; i < 222; i++ ) 00501 p->nNodes0[i] = 0; 00502 // create traversal IDs 00503 for ( i = 0; i < p->iObj; i++ ) 00504 Dar_LibObj(p, i)->Num = 0xff; 00505 // add the nodes to storage 00506 nNodes0Total = 0; 00507 for ( i = 0; i < 222; i++ ) 00508 { 00509 for ( k = 0; k < p->nSubgr0[i]; k++ ) 00510 Dar_LibSetup0_rec( p, Dar_LibObj(p, p->pSubgr0[i][k]), i, 1 ); 00511 nNodes0Total += p->nNodes0[i]; 00512 } 00513 assert( nNodes0Total == p->nNodes0Total ); 00514 // prepare the number of the PI nodes 00515 for ( i = 0; i < 4; i++ ) 00516 Dar_LibObj(p, i)->Num = i; 00517 00518 // realloc the datas 00519 Dar_LibCreateData( p, p->nNodes0Max + 32 ); 00520 // allocated more because Dar_LibBuildBest() sometimes requires more entries 00521 }
Vec_Int_t* Dar_LibReadNodes | ( | ) |
Function*************************************************************
Synopsis [Reads library from array.]
Description []
SideEffects []
SeeAlso []
Definition at line 11093 of file darData.c.
11093 { 11094 Vec_Int_t * vResult; 11095 int i; 11096 vResult = Vec_IntAlloc( s_nDataSize1 ); 11097 for ( i = 0; i < s_nDataSize1; i++ ) 11098 Vec_IntPush( vResult, s_Data1[i] ); 11099 return vResult; 11100 } 11101
Vec_Int_t* Dar_LibReadOuts | ( | ) |
Function*************************************************************
Synopsis [Reads library from array.]
Description []
SideEffects []
SeeAlso []
Definition at line 11114 of file darData.c.
11114 { 11115 Vec_Int_t * vResult; 11116 int i; 11117 vResult = Vec_IntAlloc( s_nDataSize2 ); 11118 for ( i = 0; i < s_nDataSize2; i++ ) 11119 Vec_IntPush( vResult, s_Data2[i] ); 11120 return vResult; 11121 } 11122
Vec_Int_t* Dar_LibReadPrios | ( | ) |
Function*************************************************************
Synopsis [Reads library from array.]
Description []
SideEffects []
SeeAlso []
Definition at line 11135 of file darData.c.
11135 { 11136 Vec_Int_t * vResult; 11137 int i; 11138 vResult = Vec_IntAlloc( s_nDataSize3 ); 11139 for ( i = 0; i < s_nDataSize3; i++ ) 11140 Vec_IntPush( vResult, s_Data3[i] ); 11141 return vResult; 11142 } 11143
void Dar_LibReturnCanonicals | ( | unsigned * | pCanons | ) |
Function*************************************************************
Synopsis [Returns canonical truth tables.]
Description []
SideEffects []
SeeAlso []
void Dar_LibStart | ( | ) |
Function*************************************************************
Synopsis [Starts the library.]
Description []
SideEffects []
SeeAlso []
Definition at line 568 of file darLib.c.
00569 { 00570 // int clk = clock(); 00571 assert( s_DarLib == NULL ); 00572 s_DarLib = Dar_LibRead(); 00573 // printf( "The 4-input library started with %d nodes and %d subgraphs. ", s_DarLib->nObjs - 4, s_DarLib->nSubgrTotal ); 00574 // PRT( "Time", clock() - clk ); 00575 }
void Dar_LibStop | ( | ) |
void Dar_ManCutsFree | ( | Dar_Man_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
void Dar_ManCutsStart | ( | Dar_Man_t * | p | ) |
FUNCTION DECLARATIONS ///
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 581 of file darCut.c.
00582 { 00583 Aig_Obj_t * pObj; 00584 int i; 00585 Aig_ManCleanData( p->pAig ); 00586 Aig_MmFixedRestart( p->pMemCuts ); 00587 Dar_ObjPrepareCuts( p, Aig_ManConst1(p->pAig) ); 00588 Aig_ManForEachPi( p->pAig, pObj, i ) 00589 Dar_ObjPrepareCuts( p, pObj ); 00590 }
void Dar_ManPrintStats | ( | Dar_Man_t * | p | ) |
Function*************************************************************
Synopsis [Stops the AIG manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 90 of file darMan.c.
00091 { 00092 unsigned pCanons[222]; 00093 int Gain, i; 00094 extern void Kit_DsdPrintFromTruth( unsigned * pTruth, int nVars ); 00095 00096 Gain = p->nNodesInit - Aig_ManNodeNum(p->pAig); 00097 printf( "Tried = %8d. Beg = %8d. End = %8d. Gain = %6d. (%6.2f %%). Cut mem = %d Mb\n", 00098 p->nNodesTried, p->nNodesInit, Aig_ManNodeNum(p->pAig), Gain, 100.0*Gain/p->nNodesInit, p->nCutMemUsed ); 00099 printf( "Cuts = %8d. Tried = %8d. Used = %8d. Bad = %5d. Skipped = %5d. Ave = %.2f.\n", 00100 p->nCutsAll, p->nCutsTried, p->nCutsUsed, p->nCutsBad, p->nCutsSkipped, 00101 (float)p->nCutsUsed/Aig_ManNodeNum(p->pAig) ); 00102 00103 printf( "Bufs = %5d. BufMax = %5d. BufReplace = %6d. BufFix = %6d. Levels = %4d.\n", 00104 Aig_ManBufNum(p->pAig), p->pAig->nBufMax, p->pAig->nBufReplaces, p->pAig->nBufFixes, Aig_ManLevels(p->pAig) ); 00105 PRT( "Cuts ", p->timeCuts ); 00106 PRT( "Eval ", p->timeEval ); 00107 PRT( "Other ", p->timeOther ); 00108 PRT( "TOTAL ", p->timeTotal ); 00109 00110 if ( !p->pPars->fVeryVerbose ) 00111 return; 00112 Dar_LibReturnCanonicals( pCanons ); 00113 for ( i = 0; i < 222; i++ ) 00114 { 00115 if ( p->ClassGains[i] == 0 && p->ClassTimes[i] == 0 ) 00116 continue; 00117 printf( "%3d : ", i ); 00118 printf( "G = %6d (%5.2f %%) ", p->ClassGains[i], Gain? 100.0*p->ClassGains[i]/Gain : 0.0 ); 00119 printf( "S = %8d (%5.2f %%) ", p->ClassSubgs[i], p->nTotalSubgs? 100.0*p->ClassSubgs[i]/p->nTotalSubgs : 0.0 ); 00120 printf( "R = %7d ", p->ClassGains[i]? p->ClassSubgs[i]/p->ClassGains[i] : 9999999 ); 00121 // Kit_DsdPrintFromTruth( pCanons + i, 4 ); 00122 // PRTP( "T", p->ClassTimes[i], p->timeEval ); 00123 printf( "\n" ); 00124 } 00125 }
Dar_Man_t* Dar_ManStart | ( | Aig_Man_t * | pAig, | |
Dar_RwrPar_t * | pPars | |||
) |
CFile****************************************************************
FileName [darMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [AIG manager.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [
] DECLARATIONS /// FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Starts the rewriting manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 42 of file darMan.c.
00043 { 00044 Dar_Man_t * p; 00045 // start the manager 00046 p = ALLOC( Dar_Man_t, 1 ); 00047 memset( p, 0, sizeof(Dar_Man_t) ); 00048 p->pPars = pPars; 00049 p->pAig = pAig; 00050 // prepare the internal memory manager 00051 p->pMemCuts = Aig_MmFixedStart( p->pPars->nCutsMax * sizeof(Dar_Cut_t), 1024 ); 00052 // other data 00053 p->vLeavesBest = Vec_PtrAlloc( 4 ); 00054 return p; 00055 }
void Dar_ManStop | ( | Dar_Man_t * | p | ) |
Function*************************************************************
Synopsis [Stops the rewriting manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 68 of file darMan.c.
00069 { 00070 if ( p->pPars->fVerbose ) 00071 Dar_ManPrintStats( p ); 00072 if ( p->pMemCuts ) 00073 Aig_MmFixedStop( p->pMemCuts, 0 ); 00074 if ( p->vLeavesBest ) 00075 Vec_PtrFree( p->vLeavesBest ); 00076 free( p ); 00077 }
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 603 of file darCut.c.
00604 { 00605 Aig_Obj_t * pFanin0 = Aig_ObjReal_rec( Aig_ObjChild0(pObj) ); 00606 Aig_Obj_t * pFanin1 = Aig_ObjReal_rec( Aig_ObjChild1(pObj) ); 00607 Aig_Obj_t * pFaninR0 = Aig_Regular(pFanin0); 00608 Aig_Obj_t * pFaninR1 = Aig_Regular(pFanin1); 00609 Dar_Cut_t * pCutSet, * pCut0, * pCut1, * pCut; 00610 int i, k, RetValue; 00611 00612 assert( !Aig_IsComplement(pObj) ); 00613 assert( Aig_ObjIsNode(pObj) ); 00614 assert( Dar_ObjCuts(pObj) == NULL ); 00615 assert( Dar_ObjCuts(pFaninR0) != NULL ); 00616 assert( Dar_ObjCuts(pFaninR1) != NULL ); 00617 00618 // set up the first cut 00619 pCutSet = Dar_ObjPrepareCuts( p, pObj ); 00620 // make sure fanins cuts are computed 00621 Dar_ObjForEachCut( pFaninR0, pCut0, i ) 00622 Dar_ObjForEachCut( pFaninR1, pCut1, k ) 00623 { 00624 p->nCutsAll++; 00625 // make sure K-feasible cut exists 00626 if ( Dar_WordCountOnes(pCut0->uSign | pCut1->uSign) > 4 ) 00627 continue; 00628 // get the next cut of this node 00629 pCut = Dar_CutFindFree( p, pObj ); 00630 // create the new cut 00631 if ( !Dar_CutMerge( pCut, pCut0, pCut1 ) ) 00632 { 00633 assert( !pCut->fUsed ); 00634 continue; 00635 } 00636 p->nCutsTried++; 00637 // check dominance 00638 if ( Dar_CutFilter( pObj, pCut ) ) 00639 { 00640 assert( !pCut->fUsed ); 00641 continue; 00642 } 00643 // compute truth table 00644 pCut->uTruth = 0xFFFF & Dar_CutTruth( pCut, pCut0, pCut1, Aig_IsComplement(pFanin0), Aig_IsComplement(pFanin1) ); 00645 00646 // minimize support of the cut 00647 if ( Dar_CutSuppMinimize( pCut ) ) 00648 { 00649 RetValue = Dar_CutFilter( pObj, pCut ); 00650 assert( !RetValue ); 00651 } 00652 00653 // assign the value of the cut 00654 pCut->Value = Dar_CutFindValue( p, pCut ); 00655 // if the cut contains removed node, do not use it 00656 if ( pCut->Value == 0 ) 00657 { 00658 p->nCutsSkipped++; 00659 pCut->fUsed = 0; 00660 } 00661 else if ( pCut->nLeaves < 2 ) 00662 return pCutSet; 00663 } 00664 // count the number of nontrivial cuts cuts 00665 Dar_ObjForEachCut( pObj, pCut, i ) 00666 p->nCutsUsed += pCut->fUsed; 00667 // discount trivial cut 00668 p->nCutsUsed--; 00669 return pCutSet; 00670 }
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 683 of file darCut.c.
00684 { 00685 if ( Dar_ObjCuts(pObj) ) 00686 return Dar_ObjCuts(pObj); 00687 if ( Aig_ObjIsBuf(pObj) ) 00688 return Dar_ObjComputeCuts_rec( p, Aig_ObjFanin0(pObj) ); 00689 Dar_ObjComputeCuts_rec( p, Aig_ObjFanin0(pObj) ); 00690 Dar_ObjComputeCuts_rec( p, Aig_ObjFanin1(pObj) ); 00691 return Dar_ObjComputeCuts( p, pObj ); 00692 }
Definition at line 107 of file darInt.h.
00107 { assert( !Aig_ObjIsNone(pObj) ); pObj->pData = pCuts; }
char** Dar_Permutations | ( | int | n | ) |
Function********************************************************************
Synopsis [Computes the set of all permutations.]
Description [The number of permutations in the array is n!. The number of entries in each permutation is n. Therefore, the resulting array is a two-dimentional array of the size: n! x n. To free the resulting array, call free() on the pointer returned by this procedure.]
SideEffects []
SeeAlso []
Definition at line 141 of file darPrec.c.
00142 { 00143 char Array[50]; 00144 char ** pRes; 00145 int nFact, i; 00146 // allocate memory 00147 nFact = Dar_Factorial( n ); 00148 pRes = Dar_ArrayAlloc( nFact, n, sizeof(char) ); 00149 // fill in the permutations 00150 for ( i = 0; i < n; i++ ) 00151 Array[i] = i; 00152 Dar_Permutations_rec( pRes, nFact, n, Array ); 00153 // print the permutations 00154 /* 00155 { 00156 int i, k; 00157 for ( i = 0; i < nFact; i++ ) 00158 { 00159 printf( "{" ); 00160 for ( k = 0; k < n; k++ ) 00161 printf( " %d", pRes[i][k] ); 00162 printf( " }\n" ); 00163 } 00164 } 00165 */ 00166 return pRes; 00167 }
void Dar_Truth4VarNPN | ( | unsigned short ** | puCanons, | |
char ** | puPhases, | |||
char ** | puPerms, | |||
unsigned char ** | puMap | |||
) |
Function*************************************************************
Synopsis [Computes NPN canonical forms for 4-variable functions.]
Description []
SideEffects []
SeeAlso []
Definition at line 290 of file darPrec.c.
00291 { 00292 unsigned short * uCanons; 00293 unsigned char * uMap; 00294 unsigned uTruth, uPhase, uPerm; 00295 char ** pPerms4, * uPhases, * uPerms; 00296 int nFuncs, nClasses; 00297 int i, k; 00298 00299 nFuncs = (1 << 16); 00300 uCanons = ALLOC( unsigned short, nFuncs ); 00301 uPhases = ALLOC( char, nFuncs ); 00302 uPerms = ALLOC( char, nFuncs ); 00303 uMap = ALLOC( unsigned char, nFuncs ); 00304 memset( uCanons, 0, sizeof(unsigned short) * nFuncs ); 00305 memset( uPhases, 0, sizeof(char) * nFuncs ); 00306 memset( uPerms, 0, sizeof(char) * nFuncs ); 00307 memset( uMap, 0, sizeof(unsigned char) * nFuncs ); 00308 pPerms4 = Dar_Permutations( 4 ); 00309 00310 nClasses = 1; 00311 nFuncs = (1 << 15); 00312 for ( uTruth = 1; uTruth < (unsigned)nFuncs; uTruth++ ) 00313 { 00314 // skip already assigned 00315 if ( uCanons[uTruth] ) 00316 { 00317 assert( uTruth > uCanons[uTruth] ); 00318 uMap[~uTruth & 0xFFFF] = uMap[uTruth] = uMap[uCanons[uTruth]]; 00319 continue; 00320 } 00321 uMap[uTruth] = nClasses++; 00322 for ( i = 0; i < 16; i++ ) 00323 { 00324 uPhase = Dar_TruthPolarize( uTruth, i, 4 ); 00325 for ( k = 0; k < 24; k++ ) 00326 { 00327 uPerm = Dar_TruthPermute( uPhase, pPerms4[k], 4, 0 ); 00328 if ( uCanons[uPerm] == 0 ) 00329 { 00330 uCanons[uPerm] = uTruth; 00331 uPhases[uPerm] = i; 00332 uPerms[uPerm] = k; 00333 00334 uPerm = ~uPerm & 0xFFFF; 00335 uCanons[uPerm] = uTruth; 00336 uPhases[uPerm] = i | 16; 00337 uPerms[uPerm] = k; 00338 } 00339 else 00340 assert( uCanons[uPerm] == uTruth ); 00341 } 00342 uPhase = Dar_TruthPolarize( ~uTruth & 0xFFFF, i, 4 ); 00343 for ( k = 0; k < 24; k++ ) 00344 { 00345 uPerm = Dar_TruthPermute( uPhase, pPerms4[k], 4, 0 ); 00346 if ( uCanons[uPerm] == 0 ) 00347 { 00348 uCanons[uPerm] = uTruth; 00349 uPhases[uPerm] = i; 00350 uPerms[uPerm] = k; 00351 00352 uPerm = ~uPerm & 0xFFFF; 00353 uCanons[uPerm] = uTruth; 00354 uPhases[uPerm] = i | 16; 00355 uPerms[uPerm] = k; 00356 } 00357 else 00358 assert( uCanons[uPerm] == uTruth ); 00359 } 00360 } 00361 } 00362 uPhases[(1<<16)-1] = 16; 00363 assert( nClasses == 222 ); 00364 free( pPerms4 ); 00365 if ( puCanons ) 00366 *puCanons = uCanons; 00367 else 00368 free( uCanons ); 00369 if ( puPhases ) 00370 *puPhases = uPhases; 00371 else 00372 free( uPhases ); 00373 if ( puPerms ) 00374 *puPerms = uPerms; 00375 else 00376 free( uPerms ); 00377 if ( puMap ) 00378 *puMap = uMap; 00379 else 00380 free( uMap ); 00381 }