#include <limits.h>
#include "fraigInt.h"
Go to the source code of this file.
Functions | |
Fraig_Node_t * | Fraig_NodeAndCanon (Fraig_Man_t *pMan, Fraig_Node_t *p1, Fraig_Node_t *p2) |
Fraig_Node_t* Fraig_NodeAndCanon | ( | Fraig_Man_t * | pMan, | |
Fraig_Node_t * | p1, | |||
Fraig_Node_t * | p2 | |||
) |
CFile****************************************************************
FileName [fraigCanon.c]
PackageName [FRAIG: Functionally reduced AND-INV graphs.]
Synopsis [AND-node creation and elementary AND-operation.]
Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>]
Affiliation [UC Berkeley]
Date [Ver. 2.0. Started - October 1, 2004]
Revision [
] DECLARATIONS /// FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [The internal AND operation for the two FRAIG nodes.]
Description [This procedure is the core of the FRAIG package, because it performs the two-step canonicization of FRAIG nodes. The first step involves the lookup in the structural hash table (which hashes two ANDs into a node that has them as fanins, if such a node exists). If the node is not found in the structural hash table, an attempt is made to find a functionally equivalent node in another hash table (which hashes the simulation info into the nodes, which has this simulation info). Some tricks used on the way are described in the comments to the code and in the paper "FRAIGs: Functionally reduced AND-INV graphs".]
SideEffects []
SeeAlso []
Definition at line 49 of file fraigCanon.c.
00050 { 00051 Fraig_Node_t * pNodeNew, * pNodeOld, * pNodeRepr; 00052 int fUseSatCheck; 00053 // int RetValue; 00054 00055 // check for trivial cases 00056 if ( p1 == p2 ) 00057 return p1; 00058 if ( p1 == Fraig_Not(p2) ) 00059 return Fraig_Not(pMan->pConst1); 00060 if ( Fraig_NodeIsConst(p1) ) 00061 { 00062 if ( p1 == pMan->pConst1 ) 00063 return p2; 00064 return Fraig_Not(pMan->pConst1); 00065 } 00066 if ( Fraig_NodeIsConst(p2) ) 00067 { 00068 if ( p2 == pMan->pConst1 ) 00069 return p1; 00070 return Fraig_Not(pMan->pConst1); 00071 } 00072 /* 00073 // check for less trivial cases 00074 if ( Fraig_IsComplement(p1) ) 00075 { 00076 if ( RetValue = Fraig_NodeIsInSupergate( Fraig_Regular(p1), p2 ) ) 00077 { 00078 if ( RetValue == -1 ) 00079 pMan->nImplies0++; 00080 else 00081 pMan->nImplies1++; 00082 00083 if ( RetValue == -1 ) 00084 return p2; 00085 } 00086 } 00087 else 00088 { 00089 if ( RetValue = Fraig_NodeIsInSupergate( p1, p2 ) ) 00090 { 00091 if ( RetValue == 1 ) 00092 pMan->nSimplifies1++; 00093 else 00094 pMan->nSimplifies0++; 00095 00096 if ( RetValue == 1 ) 00097 return p1; 00098 return Fraig_Not(pMan->pConst1); 00099 } 00100 } 00101 00102 if ( Fraig_IsComplement(p2) ) 00103 { 00104 if ( RetValue = Fraig_NodeIsInSupergate( Fraig_Regular(p2), p1 ) ) 00105 { 00106 if ( RetValue == -1 ) 00107 pMan->nImplies0++; 00108 else 00109 pMan->nImplies1++; 00110 00111 if ( RetValue == -1 ) 00112 return p1; 00113 } 00114 } 00115 else 00116 { 00117 if ( RetValue = Fraig_NodeIsInSupergate( p2, p1 ) ) 00118 { 00119 if ( RetValue == 1 ) 00120 pMan->nSimplifies1++; 00121 else 00122 pMan->nSimplifies0++; 00123 00124 if ( RetValue == 1 ) 00125 return p2; 00126 return Fraig_Not(pMan->pConst1); 00127 } 00128 } 00129 */ 00130 // perform level-one structural hashing 00131 if ( Fraig_HashTableLookupS( pMan, p1, p2, &pNodeNew ) ) // the node with these children is found 00132 { 00133 // if the existent node is part of the cone of unused logic 00134 // (that is logic feeding the node which is equivalent to the given node) 00135 // return the canonical representative of this node 00136 // determine the phase of the given node, with respect to its canonical form 00137 pNodeRepr = Fraig_Regular(pNodeNew)->pRepr; 00138 if ( pMan->fFuncRed && pNodeRepr ) 00139 return Fraig_NotCond( pNodeRepr, Fraig_IsComplement(pNodeNew) ^ Fraig_NodeComparePhase(Fraig_Regular(pNodeNew), pNodeRepr) ); 00140 // otherwise, the node is itself a canonical representative, return it 00141 return pNodeNew; 00142 } 00143 // the same node is not found, but the new one is created 00144 00145 // if one level hashing is requested (without functionality hashing), return 00146 if ( !pMan->fFuncRed ) 00147 return pNodeNew; 00148 00149 // check if the new node is unique using the simulation info 00150 if ( pNodeNew->nOnes == 0 || pNodeNew->nOnes == (unsigned)pMan->nWordsRand * 32 ) 00151 { 00152 pMan->nSatZeros++; 00153 if ( !pMan->fDoSparse ) // if we do not do sparse functions, skip 00154 return pNodeNew; 00155 // check the sparse function simulation hash table 00156 pNodeOld = Fraig_HashTableLookupF0( pMan, pNodeNew ); 00157 if ( pNodeOld == NULL ) // the node is unique (it is added to the table) 00158 return pNodeNew; 00159 } 00160 else 00161 { 00162 // check the simulation hash table 00163 pNodeOld = Fraig_HashTableLookupF( pMan, pNodeNew ); 00164 if ( pNodeOld == NULL ) // the node is unique 00165 return pNodeNew; 00166 } 00167 assert( pNodeOld->pRepr == 0 ); 00168 // there is another node which looks the same according to simulation 00169 00170 // use SAT to resolve the ambiguity 00171 fUseSatCheck = (pMan->nInspLimit == 0 || Fraig_ManReadInspects(pMan) < pMan->nInspLimit); 00172 if ( fUseSatCheck && Fraig_NodeIsEquivalent( pMan, pNodeOld, pNodeNew, pMan->nBTLimit, 1000000 ) ) 00173 { 00174 // set the node to be equivalent with this node 00175 // to prevent loops, only set if the old node is not in the TFI of the new node 00176 // the loop may happen in the following case: suppose 00177 // NodeC = AND(NodeA, NodeB) and at the same time NodeA => NodeB 00178 // in this case, NodeA and NodeC are functionally equivalent 00179 // however, NodeA is a fanin of node NodeC (this leads to the loop) 00180 // add the node to the list of equivalent nodes or dereference it 00181 if ( pMan->fChoicing && !Fraig_CheckTfi( pMan, pNodeOld, pNodeNew ) ) 00182 { 00183 // if the old node is not in the TFI of the new node and choicing 00184 // is enabled, add the new node to the list of equivalent ones 00185 pNodeNew->pNextE = pNodeOld->pNextE; 00186 pNodeOld->pNextE = pNodeNew; 00187 } 00188 // set the canonical representative of this node 00189 pNodeNew->pRepr = pNodeOld; 00190 // return the equivalent node 00191 return Fraig_NotCond( pNodeOld, Fraig_NodeComparePhase(pNodeOld, pNodeNew) ); 00192 } 00193 00194 // now we add another member to this simulation class 00195 if ( pNodeNew->nOnes == 0 || pNodeNew->nOnes == (unsigned)pMan->nWordsRand * 32 ) 00196 { 00197 Fraig_Node_t * pNodeTemp; 00198 assert( pMan->fDoSparse ); 00199 pNodeTemp = Fraig_HashTableLookupF0( pMan, pNodeNew ); 00200 // assert( pNodeTemp == NULL ); 00201 // Fraig_HashTableInsertF0( pMan, pNodeNew ); 00202 } 00203 else 00204 { 00205 pNodeNew->pNextD = pNodeOld->pNextD; 00206 pNodeOld->pNextD = pNodeNew; 00207 } 00208 // return the new node 00209 assert( pNodeNew->pRepr == 0 ); 00210 return pNodeNew; 00211 }