ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
fraigCanon.c File Reference
#include <limits.h>
#include "fraigInt.h"
Include dependency graph for fraigCanon.c:

Go to the source code of this file.

Functions

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

Function Documentation

◆ Fraig_NodeAndCanon()

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}
Fraig_Node_t * Fraig_HashTableLookupF(Fraig_Man_t *pMan, Fraig_Node_t *pNode)
Definition fraigTable.c:136
int Fraig_HashTableLookupS(Fraig_Man_t *pMan, Fraig_Node_t *p1, Fraig_Node_t *p2, Fraig_Node_t **ppNodeRes)
Definition fraigTable.c:90
Fraig_Node_t * Fraig_HashTableLookupF0(Fraig_Man_t *pMan, Fraig_Node_t *pNode)
Definition fraigTable.c:193
int Fraig_ManReadInspects(Fraig_Man_t *p)
Definition fraigApi.c:75
#define Fraig_IsComplement(p)
GLOBAL VARIABLES ///.
Definition fraig.h:107
int Fraig_NodeIsConst(Fraig_Node_t *p)
Definition fraigApi.c:151
#define Fraig_Regular(p)
Definition fraig.h:108
#define Fraig_Not(p)
Definition fraig.h:109
int Fraig_NodeComparePhase(Fraig_Node_t *p1, Fraig_Node_t *p2)
Definition fraigApi.c:154
#define Fraig_NotCond(p, c)
Definition fraig.h:110
int Fraig_NodeIsEquivalent(Fraig_Man_t *p, Fraig_Node_t *pOld, Fraig_Node_t *pNew, int nBTLimit, int nTimeLimit)
Definition fraigSat.c:302
struct Fraig_NodeStruct_t_ Fraig_Node_t
Definition fraig.h:41
int Fraig_CheckTfi(Fraig_Man_t *pMan, Fraig_Node_t *pOld, Fraig_Node_t *pNew)
Definition fraigUtil.c:173
Fraig_Node_t * pRepr
Definition fraigInt.h:242
Fraig_Node_t * pNextE
Definition fraigInt.h:241
Fraig_Node_t * pNextD
Definition fraigInt.h:240
#define assert(ex)
Definition util_old.h:213
Here is the call graph for this function:
Here is the caller graph for this function: