abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
fraigCanon.c File Reference
#include <limits.h>
#include "fraigInt.h"

Go to the source code of this file.

Functions

ABC_NAMESPACE_IMPL_START
Fraig_Node_t
Fraig_NodeAndCanon (Fraig_Man_t *pMan, Fraig_Node_t *p1, Fraig_Node_t *p2)
 DECLARATIONS ///. More...
 

Function Documentation

ABC_NAMESPACE_IMPL_START Fraig_Node_t* Fraig_NodeAndCanon ( Fraig_Man_t pMan,
Fraig_Node_t p1,
Fraig_Node_t p2 
)

DECLARATIONS ///.

FUNCTION DEFINITIONS ///.

CFile****************************************************************

FileName [fraigCanon.c]

PackageName [FRAIG: Functionally reduced AND-INV graphs.]

Synopsis [AND-node creation and elementary AND-operation.]

Author [Alan Mishchenko alanm.nosp@m.i@ee.nosp@m.cs.be.nosp@m.rkel.nosp@m.ey.ed.nosp@m.u]

Affiliation [UC Berkeley]

Date [Ver. 2.0. Started - October 1, 2004]

Revision [

Id:
fraigCanon.c,v 1.4 2005/07/08 01:01:31 alanmi Exp

]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 52 of file fraigCanon.c.

53 {
54  Fraig_Node_t * pNodeNew, * pNodeOld, * pNodeRepr;
55  int fUseSatCheck;
56 // int RetValue;
57 
58  // check for trivial cases
59  if ( p1 == p2 )
60  return p1;
61  if ( p1 == Fraig_Not(p2) )
62  return Fraig_Not(pMan->pConst1);
63  if ( Fraig_NodeIsConst(p1) )
64  {
65  if ( p1 == pMan->pConst1 )
66  return p2;
67  return Fraig_Not(pMan->pConst1);
68  }
69  if ( Fraig_NodeIsConst(p2) )
70  {
71  if ( p2 == pMan->pConst1 )
72  return p1;
73  return Fraig_Not(pMan->pConst1);
74  }
75 /*
76  // check for less trivial cases
77  if ( Fraig_IsComplement(p1) )
78  {
79  if ( RetValue = Fraig_NodeIsInSupergate( Fraig_Regular(p1), p2 ) )
80  {
81  if ( RetValue == -1 )
82  pMan->nImplies0++;
83  else
84  pMan->nImplies1++;
85 
86  if ( RetValue == -1 )
87  return p2;
88  }
89  }
90  else
91  {
92  if ( RetValue = Fraig_NodeIsInSupergate( p1, p2 ) )
93  {
94  if ( RetValue == 1 )
95  pMan->nSimplifies1++;
96  else
97  pMan->nSimplifies0++;
98 
99  if ( RetValue == 1 )
100  return p1;
101  return Fraig_Not(pMan->pConst1);
102  }
103  }
104 
105  if ( Fraig_IsComplement(p2) )
106  {
107  if ( RetValue = Fraig_NodeIsInSupergate( Fraig_Regular(p2), p1 ) )
108  {
109  if ( RetValue == -1 )
110  pMan->nImplies0++;
111  else
112  pMan->nImplies1++;
113 
114  if ( RetValue == -1 )
115  return p1;
116  }
117  }
118  else
119  {
120  if ( RetValue = Fraig_NodeIsInSupergate( p2, p1 ) )
121  {
122  if ( RetValue == 1 )
123  pMan->nSimplifies1++;
124  else
125  pMan->nSimplifies0++;
126 
127  if ( RetValue == 1 )
128  return p2;
129  return Fraig_Not(pMan->pConst1);
130  }
131  }
132 */
133  // perform level-one structural hashing
134  if ( Fraig_HashTableLookupS( pMan, p1, p2, &pNodeNew ) ) // the node with these children is found
135  {
136  // if the existent node is part of the cone of unused logic
137  // (that is logic feeding the node which is equivalent to the given node)
138  // return the canonical representative of this node
139  // determine the phase of the given node, with respect to its canonical form
140  pNodeRepr = Fraig_Regular(pNodeNew)->pRepr;
141  if ( pMan->fFuncRed && pNodeRepr )
142  return Fraig_NotCond( pNodeRepr, Fraig_IsComplement(pNodeNew) ^ Fraig_NodeComparePhase(Fraig_Regular(pNodeNew), pNodeRepr) );
143  // otherwise, the node is itself a canonical representative, return it
144  return pNodeNew;
145  }
146  // the same node is not found, but the new one is created
147 
148  // if one level hashing is requested (without functionality hashing), return
149  if ( !pMan->fFuncRed )
150  return pNodeNew;
151 
152  // check if the new node is unique using the simulation info
153  if ( pNodeNew->nOnes == 0 || pNodeNew->nOnes == (unsigned)pMan->nWordsRand * 32 )
154  {
155  pMan->nSatZeros++;
156  if ( !pMan->fDoSparse ) // if we do not do sparse functions, skip
157  return pNodeNew;
158  // check the sparse function simulation hash table
159  pNodeOld = Fraig_HashTableLookupF0( pMan, pNodeNew );
160  if ( pNodeOld == NULL ) // the node is unique (it is added to the table)
161  return pNodeNew;
162  }
163  else
164  {
165  // check the simulation hash table
166  pNodeOld = Fraig_HashTableLookupF( pMan, pNodeNew );
167  if ( pNodeOld == NULL ) // the node is unique
168  return pNodeNew;
169  }
170  assert( pNodeOld->pRepr == 0 );
171  // there is another node which looks the same according to simulation
172 
173  // use SAT to resolve the ambiguity
174  fUseSatCheck = (pMan->nInspLimit == 0 || Fraig_ManReadInspects(pMan) < pMan->nInspLimit);
175  if ( fUseSatCheck && Fraig_NodeIsEquivalent( pMan, pNodeOld, pNodeNew, pMan->nBTLimit, 1000000 ) )
176  {
177  // set the node to be equivalent with this node
178  // to prevent loops, only set if the old node is not in the TFI of the new node
179  // the loop may happen in the following case: suppose
180  // NodeC = AND(NodeA, NodeB) and at the same time NodeA => NodeB
181  // in this case, NodeA and NodeC are functionally equivalent
182  // however, NodeA is a fanin of node NodeC (this leads to the loop)
183  // add the node to the list of equivalent nodes or dereference it
184  if ( pMan->fChoicing && !Fraig_CheckTfi( pMan, pNodeOld, pNodeNew ) )
185  {
186  // if the old node is not in the TFI of the new node and choicing
187  // is enabled, add the new node to the list of equivalent ones
188  pNodeNew->pNextE = pNodeOld->pNextE;
189  pNodeOld->pNextE = pNodeNew;
190  }
191  // set the canonical representative of this node
192  pNodeNew->pRepr = pNodeOld;
193  // return the equivalent node
194  return Fraig_NotCond( pNodeOld, Fraig_NodeComparePhase(pNodeOld, pNodeNew) );
195  }
196 
197  // now we add another member to this simulation class
198  if ( pNodeNew->nOnes == 0 || pNodeNew->nOnes == (unsigned)pMan->nWordsRand * 32 )
199  {
200  Fraig_Node_t * pNodeTemp;
201  assert( pMan->fDoSparse );
202  pNodeTemp = Fraig_HashTableLookupF0( pMan, pNodeNew );
203 // assert( pNodeTemp == NULL );
204 // Fraig_HashTableInsertF0( pMan, pNodeNew );
205  }
206  else
207  {
208  pNodeNew->pNextD = pNodeOld->pNextD;
209  pNodeOld->pNextD = pNodeNew;
210  }
211  // return the new node
212  assert( pNodeNew->pRepr == 0 );
213  return pNodeNew;
214 }
int Fraig_NodeIsEquivalent(Fraig_Man_t *p, Fraig_Node_t *pOld, Fraig_Node_t *pNew, int nBTLimit, int nTimeLimit)
Definition: fraigSat.c:302
int Fraig_NodeComparePhase(Fraig_Node_t *p1, Fraig_Node_t *p2)
Definition: fraigApi.c:154
int Fraig_CheckTfi(Fraig_Man_t *pMan, Fraig_Node_t *pOld, Fraig_Node_t *pNew)
Definition: fraigUtil.c:173
Fraig_Node_t * pNextD
Definition: fraigInt.h:240
int Fraig_HashTableLookupS(Fraig_Man_t *pMan, Fraig_Node_t *p1, Fraig_Node_t *p2, Fraig_Node_t **ppNodeRes)
Definition: fraigTable.c:90
int Fraig_ManReadInspects(Fraig_Man_t *p)
Definition: fraigApi.c:75
#define Fraig_Not(p)
Definition: fraig.h:109
Fraig_Node_t * pNextE
Definition: fraigInt.h:241
Fraig_Node_t * Fraig_HashTableLookupF0(Fraig_Man_t *pMan, Fraig_Node_t *pNode)
Definition: fraigTable.c:193
#define Fraig_IsComplement(p)
GLOBAL VARIABLES ///.
Definition: fraig.h:107
Fraig_Node_t * pRepr
Definition: fraigInt.h:242
int Fraig_NodeIsConst(Fraig_Node_t *p)
Definition: fraigApi.c:151
Fraig_Node_t * Fraig_HashTableLookupF(Fraig_Man_t *pMan, Fraig_Node_t *pNode)
Definition: fraigTable.c:136
#define Fraig_Regular(p)
Definition: fraig.h:108
#define Fraig_NotCond(p, c)
Definition: fraig.h:110
#define assert(ex)
Definition: util_old.h:213