ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
decFactor.c
Go to the documentation of this file.
1
18
19#include "base/abc/abc.h"
20#include "base/main/main.h"
21#include "misc/mvc/mvc.h"
22#include "dec.h"
23
24#ifdef ABC_USE_CUDD
25#include "bdd/extrab/extraBdd.h"
26#endif
27
29
30
34
35static Dec_Edge_t Dec_Factor_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover );
36static Dec_Edge_t Dec_FactorLF_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cover_t * pSimple );
37static Dec_Edge_t Dec_FactorTrivial( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover );
38static Dec_Edge_t Dec_FactorTrivialCube( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cube_t * pCube, Vec_Int_t * vEdgeLits );
39static Dec_Edge_t Dec_FactorTrivialTree_rec( Dec_Graph_t * pFForm, Dec_Edge_t * peNodes, int nNodes, int fNodeOr );
40static int Dec_FactorVerify( char * pSop, Dec_Graph_t * pFForm );
41static Mvc_Cover_t * Dec_ConvertSopToMvc( char * pSop );
42
46
58Dec_Graph_t * Dec_Factor( char * pSop )
59{
60 Mvc_Cover_t * pCover;
61 Dec_Graph_t * pFForm;
62 Dec_Edge_t eRoot;
63 if ( Abc_SopIsConst0(pSop) )
64 return Dec_GraphCreateConst0();
65 if ( Abc_SopIsConst1(pSop) )
66 return Dec_GraphCreateConst1();
67
68 // derive the cover from the SOP representation
69 pCover = Dec_ConvertSopToMvc( pSop );
70
71 // make sure the cover is CCS free (should be done before CST)
72 Mvc_CoverContain( pCover );
73
74 // check for trivial functions
75 assert( !Mvc_CoverIsEmpty(pCover) );
76 assert( !Mvc_CoverIsTautology(pCover) );
77
78 // perform CST
79 Mvc_CoverInverse( pCover ); // CST
80 // start the factored form
81 pFForm = Dec_GraphCreate( Abc_SopGetVarNum(pSop) );
82 // factor the cover
83 eRoot = Dec_Factor_rec( pFForm, pCover );
84 // finalize the factored form
85 Dec_GraphSetRoot( pFForm, eRoot );
86 // complement the factored form if SOP is complemented
87 if ( Abc_SopIsComplement(pSop) )
88 Dec_GraphComplement( pFForm );
89 // verify the factored form
90// if ( !Dec_FactorVerify( pSop, pFForm ) )
91// printf( "Verification has failed.\n" );
92// Mvc_CoverInverse( pCover ); // undo CST
93 Mvc_CoverFree( pCover );
94 return pFForm;
95}
96
108Dec_Edge_t Dec_Factor_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover )
109{
110 Mvc_Cover_t * pDiv, * pQuo, * pRem, * pCom;
111 Dec_Edge_t eNodeDiv, eNodeQuo, eNodeRem;
112 Dec_Edge_t eNodeAnd, eNode;
113
114 // make sure the cover contains some cubes
115 assert( Mvc_CoverReadCubeNum(pCover) );
116
117 // get the divisor
118 pDiv = Mvc_CoverDivisor( pCover );
119 if ( pDiv == NULL )
120 return Dec_FactorTrivial( pFForm, pCover );
121
122 // divide the cover by the divisor
123 Mvc_CoverDivideInternal( pCover, pDiv, &pQuo, &pRem );
125
126 Mvc_CoverFree( pDiv );
127 Mvc_CoverFree( pRem );
128
129 // check the trivial case
130 if ( Mvc_CoverReadCubeNum(pQuo) == 1 )
131 {
132 eNode = Dec_FactorLF_rec( pFForm, pCover, pQuo );
133 Mvc_CoverFree( pQuo );
134 return eNode;
135 }
136
137 // make the quotient cube ABC_FREE
138 Mvc_CoverMakeCubeFree( pQuo );
139
140 // divide the cover by the quotient
141 Mvc_CoverDivideInternal( pCover, pQuo, &pDiv, &pRem );
142
143 // check the trivial case
144 if ( Mvc_CoverIsCubeFree( pDiv ) )
145 {
146 eNodeDiv = Dec_Factor_rec( pFForm, pDiv );
147 eNodeQuo = Dec_Factor_rec( pFForm, pQuo );
148 Mvc_CoverFree( pDiv );
149 Mvc_CoverFree( pQuo );
150 eNodeAnd = Dec_GraphAddNodeAnd( pFForm, eNodeDiv, eNodeQuo );
151 if ( Mvc_CoverReadCubeNum(pRem) == 0 )
152 {
153 Mvc_CoverFree( pRem );
154 return eNodeAnd;
155 }
156 else
157 {
158 eNodeRem = Dec_Factor_rec( pFForm, pRem );
159 Mvc_CoverFree( pRem );
160 return Dec_GraphAddNodeOr( pFForm, eNodeAnd, eNodeRem );
161 }
162 }
163
164 // get the common cube
165 pCom = Mvc_CoverCommonCubeCover( pDiv );
166 Mvc_CoverFree( pDiv );
167 Mvc_CoverFree( pQuo );
168 Mvc_CoverFree( pRem );
169
170 // solve the simple problem
171 eNode = Dec_FactorLF_rec( pFForm, pCover, pCom );
172 Mvc_CoverFree( pCom );
173 return eNode;
174}
175
176
188Dec_Edge_t Dec_FactorLF_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cover_t * pSimple )
189{
190 Dec_Man_t * pManDec = (Dec_Man_t *)Abc_FrameReadManDec();
191 Vec_Int_t * vEdgeLits = pManDec->vLits;
192 Mvc_Cover_t * pDiv, * pQuo, * pRem;
193 Dec_Edge_t eNodeDiv, eNodeQuo, eNodeRem;
194 Dec_Edge_t eNodeAnd;
195
196 // get the most often occurring literal
197 pDiv = Mvc_CoverBestLiteralCover( pCover, pSimple );
198 // divide the cover by the literal
199 Mvc_CoverDivideByLiteral( pCover, pDiv, &pQuo, &pRem );
200 // get the node pointer for the literal
201 eNodeDiv = Dec_FactorTrivialCube( pFForm, pDiv, Mvc_CoverReadCubeHead(pDiv), vEdgeLits );
202 Mvc_CoverFree( pDiv );
203 // factor the quotient and remainder
204 eNodeQuo = Dec_Factor_rec( pFForm, pQuo );
205 Mvc_CoverFree( pQuo );
206 eNodeAnd = Dec_GraphAddNodeAnd( pFForm, eNodeDiv, eNodeQuo );
207 if ( Mvc_CoverReadCubeNum(pRem) == 0 )
208 {
209 Mvc_CoverFree( pRem );
210 return eNodeAnd;
211 }
212 else
213 {
214 eNodeRem = Dec_Factor_rec( pFForm, pRem );
215 Mvc_CoverFree( pRem );
216 return Dec_GraphAddNodeOr( pFForm, eNodeAnd, eNodeRem );
217 }
218}
219
220
221
233Dec_Edge_t Dec_FactorTrivial( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover )
234{
235 Dec_Man_t * pManDec = (Dec_Man_t *)Abc_FrameReadManDec();
236 Vec_Int_t * vEdgeCubes = pManDec->vCubes;
237 Vec_Int_t * vEdgeLits = pManDec->vLits;
238 Dec_Edge_t eNode;
239 Mvc_Cube_t * pCube;
240 // create the factored form for each cube
241 Vec_IntClear( vEdgeCubes );
242 Mvc_CoverForEachCube( pCover, pCube )
243 {
244 eNode = Dec_FactorTrivialCube( pFForm, pCover, pCube, vEdgeLits );
245 Vec_IntPush( vEdgeCubes, Dec_EdgeToInt_(eNode) );
246 }
247 // balance the factored forms
248 return Dec_FactorTrivialTree_rec( pFForm, (Dec_Edge_t *)vEdgeCubes->pArray, vEdgeCubes->nSize, 1 );
249}
250
262Dec_Edge_t Dec_FactorTrivialCube( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cube_t * pCube, Vec_Int_t * vEdgeLits )
263{
264 Dec_Edge_t eNode;
265 int iBit, Value;
266 // create the factored form for each literal
267 Vec_IntClear( vEdgeLits );
268 Mvc_CubeForEachBit( pCover, pCube, iBit, Value )
269 if ( Value )
270 {
271 eNode = Dec_EdgeCreate( iBit/2, iBit%2 ); // CST
272 Vec_IntPush( vEdgeLits, Dec_EdgeToInt_(eNode) );
273 }
274 // balance the factored forms
275 return Dec_FactorTrivialTree_rec( pFForm, (Dec_Edge_t *)vEdgeLits->pArray, vEdgeLits->nSize, 0 );
276}
277
289Dec_Edge_t Dec_FactorTrivialTree_rec( Dec_Graph_t * pFForm, Dec_Edge_t * peNodes, int nNodes, int fNodeOr )
290{
291 Dec_Edge_t eNode1, eNode2;
292 int nNodes1, nNodes2;
293
294 if ( nNodes == 1 )
295 return peNodes[0];
296
297 // split the nodes into two parts
298 nNodes1 = nNodes/2;
299 nNodes2 = nNodes - nNodes1;
300// nNodes2 = nNodes/2;
301// nNodes1 = nNodes - nNodes2;
302
303 // recursively construct the tree for the parts
304 eNode1 = Dec_FactorTrivialTree_rec( pFForm, peNodes, nNodes1, fNodeOr );
305 eNode2 = Dec_FactorTrivialTree_rec( pFForm, peNodes + nNodes1, nNodes2, fNodeOr );
306
307 if ( fNodeOr )
308 return Dec_GraphAddNodeOr( pFForm, eNode1, eNode2 );
309 else
310 return Dec_GraphAddNodeAnd( pFForm, eNode1, eNode2 );
311}
312
313
314
326Mvc_Cover_t * Dec_ConvertSopToMvc( char * pSop )
327{
328 Dec_Man_t * pManDec = (Dec_Man_t *)Abc_FrameReadManDec();
329 Mvc_Manager_t * pMem = (Mvc_Manager_t *)pManDec->pMvcMem;
330 Mvc_Cover_t * pMvc;
331 Mvc_Cube_t * pMvcCube;
332 char * pCube;
333 int nVars, Value, v;
334
335 // start the cover
336 nVars = Abc_SopGetVarNum(pSop);
337 assert( nVars > 0 );
338 pMvc = Mvc_CoverAlloc( pMem, nVars * 2 );
339 // check the logic function of the node
340 Abc_SopForEachCube( pSop, nVars, pCube )
341 {
342 // create and add the cube
343 pMvcCube = Mvc_CubeAlloc( pMvc );
344 Mvc_CoverAddCubeTail( pMvc, pMvcCube );
345 // fill in the literals
346 Mvc_CubeBitFill( pMvcCube );
347 Abc_CubeForEachVar( pCube, Value, v )
348 {
349 if ( Value == '0' )
350 Mvc_CubeBitRemove( pMvcCube, v * 2 + 1 );
351 else if ( Value == '1' )
352 Mvc_CubeBitRemove( pMvcCube, v * 2 );
353 }
354 }
355 return pMvc;
356}
357
358#ifdef ABC_USE_CUDD
359
371int Dec_FactorVerify( char * pSop, Dec_Graph_t * pFForm )
372{
373 extern DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, DdNode ** pbVars );
374 extern DdNode * Dec_GraphDeriveBdd( DdManager * dd, Dec_Graph_t * pGraph );
375 DdManager * dd = (DdManager *)Abc_FrameReadManDd();
376 DdNode * bFunc1, * bFunc2;
377 int RetValue;
378 bFunc1 = Abc_ConvertSopToBdd( dd, pSop, NULL ); Cudd_Ref( bFunc1 );
379 bFunc2 = Dec_GraphDeriveBdd( dd, pFForm ); Cudd_Ref( bFunc2 );
380//Extra_bddPrint( dd, bFunc1 ); printf("\n");
381//Extra_bddPrint( dd, bFunc2 ); printf("\n");
382 RetValue = (bFunc1 == bFunc2);
383 if ( bFunc1 != bFunc2 )
384 {
385 int s;
386 Extra_bddPrint( dd, bFunc1 ); printf("\n");
387 Extra_bddPrint( dd, bFunc2 ); printf("\n");
388 s = 0;
389 }
390 Cudd_RecursiveDeref( dd, bFunc1 );
391 Cudd_RecursiveDeref( dd, bFunc2 );
392 return RetValue;
393}
394
395#endif
396
400
401
403
ABC_DLL int Abc_SopIsConst0(char *pSop)
Definition abcSop.c:724
#define Abc_CubeForEachVar(pCube, Value, i)
Definition abc.h:536
#define Abc_SopForEachCube(pSop, nFanins, pCube)
Definition abc.h:538
ABC_DLL int Abc_SopGetVarNum(char *pSop)
Definition abcSop.c:584
ABC_DLL int Abc_SopIsComplement(char *pSop)
Definition abcSop.c:703
ABC_DLL int Abc_SopIsConst1(char *pSop)
Definition abcSop.c:740
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
ABC_DLL void * Abc_FrameReadManDd()
ABC_DLL void * Abc_FrameReadManDec()
Definition mainFrame.c:66
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
Dec_Graph_t * Dec_Factor(char *pSop)
FUNCTION DEFINITIONS ///.
Definition decFactor.c:58
struct Dec_Man_t_ Dec_Man_t
Definition dec.h:79
typedefABC_NAMESPACE_HEADER_START struct Dec_Edge_t_ Dec_Edge_t
INCLUDES ///.
Definition dec.h:42
struct Dec_Graph_t_ Dec_Graph_t
Definition dec.h:68
void Extra_bddPrint(DdManager *dd, DdNode *F)
#define Mvc_CoverAddCubeTail(pCover, pCube)
Definition mvc.h:501
Mvc_Cover_t * Mvc_CoverCommonCubeCover(Mvc_Cover_t *pCover)
Definition mvcUtils.c:220
void Mvc_CoverDivideInternal(Mvc_Cover_t *pCover, Mvc_Cover_t *pDiv, Mvc_Cover_t **ppQuo, Mvc_Cover_t **ppRem)
Definition mvcDivide.c:81
struct MvcCubeStruct Mvc_Cube_t
Definition mvc.h:56
void Mvc_CoverFree(Mvc_Cover_t *pCover)
Definition mvcCover.c:138
void Mvc_CoverMakeCubeFree(Mvc_Cover_t *pCover)
Definition mvcUtils.c:198
struct MvcManagerStruct Mvc_Manager_t
Definition mvc.h:60
int Mvc_CoverContain(Mvc_Cover_t *pCover)
FUNCTION DEFINITIONS ///.
Definition mvcContain.c:47
#define Mvc_CubeBitRemove(Cube, Bit)
Definition mvc.h:140
Mvc_Cover_t * Mvc_CoverAlloc(Mvc_Manager_t *pMem, int nBits)
DECLARATIONS ///.
Definition mvcCover.c:43
#define Mvc_CubeBitFill(Cube)
Definition mvc.h:385
int Mvc_CoverIsEmpty(Mvc_Cover_t *pCover)
Definition mvcApi.c:93
int Mvc_CoverIsTautology(Mvc_Cover_t *pCover)
Definition mvcApi.c:109
#define Mvc_CoverForEachCube(Cover, Cube)
Definition mvc.h:528
Mvc_Cube_t * Mvc_CubeAlloc(Mvc_Cover_t *pCover)
DECLARATIONS ///.
Definition mvcCube.c:43
struct MvcCoverStruct Mvc_Cover_t
Definition mvc.h:58
Mvc_Cover_t * Mvc_CoverDivisor(Mvc_Cover_t *pCover)
FUNCTION DEFINITIONS ///.
Definition mvcDivisor.c:46
#define Mvc_CubeForEachBit(Cover, Cube, iBit, Value)
Definition mvc.h:553
void Mvc_CoverInverse(Mvc_Cover_t *pCover)
Definition mvcUtils.c:481
Mvc_Cube_t * Mvc_CoverReadCubeHead(Mvc_Cover_t *pCover)
Definition mvcApi.c:46
void Mvc_CoverDivideByLiteral(Mvc_Cover_t *pCover, Mvc_Cover_t *pDiv, Mvc_Cover_t **ppQuo, Mvc_Cover_t **ppRem)
Definition mvcDivide.c:323
int Mvc_CoverReadCubeNum(Mvc_Cover_t *pCover)
Definition mvcApi.c:45
int Mvc_CoverIsCubeFree(Mvc_Cover_t *pCover)
Definition mvcUtils.c:176
Mvc_Cover_t * Mvc_CoverBestLiteralCover(Mvc_Cover_t *pCover, Mvc_Cover_t *pSimple)
Definition mvcLits.c:223
Vec_Int_t * vCubes
Definition dec.h:83
void * pMvcMem
Definition dec.h:82
Vec_Int_t * vLits
Definition dec.h:84
#define assert(ex)
Definition util_old.h:213