1 /**CFile****************************************************************
2 
3   FileName    [ioReadPla.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Command processing package.]
8 
9   Synopsis    [Procedure to read network from file.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: ioReadPla.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "ioAbc.h"
22 #include "misc/util/utilTruth.h"
23 
24 ABC_NAMESPACE_IMPL_START
25 
26 
27 ////////////////////////////////////////////////////////////////////////
28 ///                        DECLARATIONS                              ///
29 ////////////////////////////////////////////////////////////////////////
30 
31 static Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p, int fZeros, int fBoth, int fOnDc, int fSkipPrepro );
32 
33 ////////////////////////////////////////////////////////////////////////
34 ///                     FUNCTION DEFINITIONS                         ///
35 ////////////////////////////////////////////////////////////////////////
36 
37 /**Function*************************************************************
38 
39   Synopsis    [Checks if cubes are distance-1.]
40 
41   Description []
42 
43   SideEffects []
44 
45   SeeAlso     []
46 
47 ***********************************************************************/
Io_ReadPlaPrintCube(word * p,int nVars)48 static inline void Io_ReadPlaPrintCube( word * p, int nVars )
49 {
50     char Symbs[3] = {'-', '0', '1'}; int v;
51     for ( v = 0; v < nVars; v++ )
52         printf( "%c", Symbs[Abc_TtGetQua(p, v)] );
53     printf( "\n" );
54 }
55 
56 /**Function*************************************************************
57 
58   Synopsis    [Checks if cubes are distance-1.]
59 
60   Description []
61 
62   SideEffects []
63 
64   SeeAlso     []
65 
66 ***********************************************************************/
Io_ReadPlaDistance1(word * p,word * q,int nWords)67 static inline int Io_ReadPlaDistance1( word * p, word * q, int nWords )
68 {
69     word Test; int c, fFound = 0;
70     for ( c = 0; c < nWords; c++ )
71     {
72         if ( p[c] == q[c] )
73             continue;
74         if ( fFound )
75             return 0;
76         // check if the number of 1s is one
77 //        Test = ((p[c] ^ q[c]) & ((p[c] ^ q[c]) >> 1)) & ABC_CONST(0x5555555555555555); // exactly one 0/1 literal (but may be -/0 or -/1)
78         Test = ((p[c] ^ q[c]) | ((p[c] ^ q[c]) >> 1)) & ABC_CONST(0x5555555555555555);
79         if ( !Abc_TtOnlyOneOne(Test) )
80             return 0;
81         fFound = 1;
82     }
83     return fFound;
84 }
Io_ReadPlaConsensus(word * p,word * q,int nWords,int * piVar)85 static inline int Io_ReadPlaConsensus( word * p, word * q, int nWords, int * piVar )
86 {
87     word Test; int c, fFound = 0;
88     for ( c = 0; c < nWords; c++ )
89     {
90         if ( p[c] == q[c] )
91             continue;
92         if ( fFound )
93             return 0;
94         // check if there is exactly one opposite literal (0/1) but may have other diffs (-/0 or -/1)
95         Test = ((p[c] ^ q[c]) & ((p[c] ^ q[c]) >> 1)) & ABC_CONST(0x5555555555555555);
96         if ( !Abc_TtOnlyOneOne(Test) )
97             return 0;
98         fFound = 1;
99         *piVar = c * 32 + Abc_Tt6FirstBit(Test)/2;
100     }
101     return fFound;
102 }
103 
104 
105 /**Function*************************************************************
106 
107   Synopsis    []
108 
109   Description []
110 
111   SideEffects []
112 
113   SeeAlso     []
114 
115 ***********************************************************************/
Io_ReadPlaMarkIdentical(word ** pCs,int nCubes,int nWords,Vec_Bit_t * vMarks)116 void Io_ReadPlaMarkIdentical( word ** pCs, int nCubes, int nWords, Vec_Bit_t * vMarks )
117 {
118     int c1, c2;
119     Vec_BitFill( vMarks, nCubes, 0 );
120     for ( c1 = 0; c1 < nCubes; c1++ )
121         if ( !Vec_BitEntry(vMarks, c1) )
122             for ( c2 = c1 + 1; c2 < nCubes; c2++ )
123                 if ( !Vec_BitEntry(vMarks, c2) )
124                     if ( Abc_TtEqual(pCs[c1], pCs[c2], nWords) )
125                         Vec_BitWriteEntry( vMarks, c2, 1 );
126 }
Io_ReadPlaMarkContained(word ** pCs,int nCubes,int nWords,Vec_Bit_t * vMarks)127 void Io_ReadPlaMarkContained( word ** pCs, int nCubes, int nWords, Vec_Bit_t * vMarks )
128 {
129     int c1, c2;
130     Vec_BitFill( vMarks, nCubes, 0 );
131     for ( c1 = 0; c1 < nCubes; c1++ )
132         if ( !Vec_BitEntry(vMarks, c1) )
133             for ( c2 = c1 + 1; c2 < nCubes; c2++ )
134                 if ( !Vec_BitEntry(vMarks, c2) )
135                 {
136                     if ( Abc_TtImply(pCs[c1], pCs[c2], nWords) )
137                         Vec_BitWriteEntry( vMarks, c2, 1 );
138                     else if ( Abc_TtImply(pCs[c2], pCs[c1], nWords) )
139                     {
140                         Vec_BitWriteEntry( vMarks, c1, 1 );
141                         break;
142                     }
143                 }
144 }
Io_ReadPlaRemoveMarked(word ** pCs,int nCubes,int nWords,Vec_Bit_t * vMarks)145 int Io_ReadPlaRemoveMarked( word ** pCs, int nCubes, int nWords, Vec_Bit_t * vMarks )
146 {
147     int c1, c;
148     for ( c1 = c = 0; c1 < nCubes; c1++ )
149         if ( !Vec_BitEntry(vMarks, c1) )
150         {
151             if ( c == c1 )
152                 c++;
153             else
154                 Abc_TtCopy( pCs[c++], pCs[c1], nWords, 0 );
155         }
156     return c;
157 }
Io_ReadPlaMergeDistance1(word ** pCs,int nCubes,int nWords,Vec_Bit_t * vMarks)158 int Io_ReadPlaMergeDistance1( word ** pCs, int nCubes, int nWords, Vec_Bit_t * vMarks )
159 {
160     int c1, c2, Res, Counter = 0;
161     Vec_BitFill( vMarks, nCubes, 0 );
162     for ( c1 = 0; c1 < nCubes; c1++ )
163         if ( !Vec_BitEntry(vMarks, c1) )
164             for ( c2 = c1 + 1; c2 < nCubes; c2++ )
165                 if ( !Vec_BitEntry(vMarks, c2) )
166                 {
167                     Res = Io_ReadPlaDistance1( pCs[c1], pCs[c2], nWords );
168                     if ( !Res )
169                         continue;
170                     Abc_TtAnd( pCs[c1], pCs[c1], pCs[c2], nWords, 0 );
171                     Vec_BitWriteEntry( vMarks, c2, 1 );
172                     Counter++;
173                     break;
174                 }
175     return Counter;
176 }
Io_ReadPlaSelfSubsumption(word ** pCs,int nCubes,int nWords,Vec_Bit_t * vMarks)177 int Io_ReadPlaSelfSubsumption( word ** pCs, int nCubes, int nWords, Vec_Bit_t * vMarks )
178 {
179     int c1, c2, Res, Counter = 0, iVar = -1, Val0, Val1;
180     Vec_BitFill( vMarks, nCubes, 0 );
181     for ( c1 = 0; c1 < nCubes; c1++ )
182         if ( !Vec_BitEntry(vMarks, c1) )
183             for ( c2 = c1 + 1; c2 < nCubes; c2++ )
184                 if ( !Vec_BitEntry(vMarks, c2) )
185                 {
186                     Res = Io_ReadPlaConsensus( pCs[c1], pCs[c2], nWords, &iVar );
187                     if ( !Res )
188                         continue;
189                     assert( iVar >= 0  && iVar < nWords*32 );
190                     Val0 = Abc_TtGetQua( pCs[c1], iVar );
191                     Val1 = Abc_TtGetQua( pCs[c2], iVar );
192                     // remove values
193                     Abc_TtXorQua( pCs[c1], iVar, Val0 );
194                     Abc_TtXorQua( pCs[c2], iVar, Val1 );
195                     // check containment
196                     if ( Abc_TtImply(pCs[c1], pCs[c2], nWords) )
197                     {
198                         Abc_TtXorQua( pCs[c1], iVar, Val0 );
199                         Vec_BitWriteEntry( vMarks, c2, 1 );
200                         Counter++;
201                     }
202                     else if ( Abc_TtImply(pCs[c2], pCs[c1], nWords) )
203                     {
204                         Abc_TtXorQua( pCs[c2], iVar, Val1 );
205                         Vec_BitWriteEntry( vMarks, c1, 1 );
206                         Counter++;
207                         break;
208                     }
209                     else
210                     {
211                         Abc_TtXorQua( pCs[c1], iVar, Val0 );
212                         Abc_TtXorQua( pCs[c2], iVar, Val1 );
213                     }
214 
215 /*
216                     printf( "Var = %3d  ", iVar );
217                     printf( "Cube0 = %d  ", Abc_TtGetQua(pCs[c1], iVar) );
218                     printf( "Cube1 = %d  ", Abc_TtGetQua(pCs[c2], iVar) );
219                     printf( "\n" );
220                     Io_ReadPlaPrintCube( pCs[c1], 32 * nWords );
221                     Io_ReadPlaPrintCube( pCs[c2], 32 * nWords );
222                     printf( "\n" );
223 */
224                     break;
225                 }
226     return Counter;
227 }
228 
229 /**Function*************************************************************
230 
231   Synopsis    []
232 
233   Description []
234 
235   SideEffects []
236 
237   SeeAlso     []
238 
239 ***********************************************************************/
Io_ReadPlaCubeSetup(Vec_Str_t * vSop)240 word ** Io_ReadPlaCubeSetup( Vec_Str_t * vSop )
241 {
242     char * pSop = Vec_StrArray( vSop ), * pCube, Lit;
243     int nCubes  = Abc_SopGetCubeNum( pSop );
244     int nVars   = Abc_SopGetVarNum( pSop );
245     int nWords  = Abc_Bit6WordNum( 2*nVars ), c, v;
246     word ** pCs = ABC_ALLOC( word *, nCubes );
247     pCs[0] = ABC_CALLOC( word, nCubes * nWords );
248     for ( c = 1; c < nCubes; c++ )
249         pCs[c] = pCs[c-1] + nWords;
250     c = 0;
251     Abc_SopForEachCube( pSop, nVars, pCube )
252     {
253         Abc_CubeForEachVar( pCube, Lit, v )
254             if ( Lit == '0' )
255                 Abc_TtSetBit( pCs[c], Abc_Var2Lit(v,0) );
256             else if ( Lit == '1' )
257                 Abc_TtSetBit( pCs[c], Abc_Var2Lit(v,1) );
258         c++;
259     }
260     assert( c == nCubes );
261     return pCs;
262 }
Io_ReadPlaCubeSetdown(Vec_Str_t * vSop,word ** pCs,int nCubes,int nVars)263 void Io_ReadPlaCubeSetdown( Vec_Str_t * vSop, word ** pCs, int nCubes, int nVars )
264 {
265     char Symbs[3] = {'-', '0', '1'}; int c, v;
266     Vec_StrClear( vSop );
267     for ( c = 0; c < nCubes; c++ )
268     {
269         for ( v = 0; v < nVars; v++ )
270             Vec_StrPush( vSop, Symbs[Abc_TtGetQua(pCs[c], v)] );
271         Vec_StrPrintStr( vSop, " 1\n" );
272     }
273     Vec_StrPush( vSop, 0 );
274 }
Io_ReadPlaCubePreprocess(Vec_Str_t * vSop,int iCover,int fVerbose)275 void Io_ReadPlaCubePreprocess( Vec_Str_t * vSop, int iCover, int fVerbose )
276 {
277     word ** pCs = Io_ReadPlaCubeSetup( vSop );
278     int nCubes  = Abc_SopGetCubeNum( Vec_StrArray(vSop) );
279     int nVars   = Abc_SopGetVarNum( Vec_StrArray(vSop) );
280     int nWords  = Abc_Bit6WordNum( 2*nVars );
281     int nCubesNew, Count, Iter = 0;
282     Vec_Bit_t * vMarks = Vec_BitStart( nCubes );
283     if ( fVerbose )
284         printf( "Cover %5d : V =%5d  C%d =%5d", iCover, nVars, Iter, nCubes );
285 
286     do
287     {
288         Iter++;
289         do
290         {
291             // remove contained
292             Io_ReadPlaMarkContained( pCs, nCubes, nWords, vMarks );
293             nCubesNew = Io_ReadPlaRemoveMarked( pCs, nCubes, nWords, vMarks );
294             //if ( fVerbose )
295             //    printf( "  C =%5d", nCubes - nCubesNew );
296             nCubes = nCubesNew;
297             // merge distance-1
298             Count = Io_ReadPlaMergeDistance1( pCs, nCubes, nWords, vMarks );
299         } while ( Count );
300         if ( fVerbose )
301             printf( "  C%d =%5d", Iter, nCubes );
302         // try consensus
303         //Count = Io_ReadPlaSelfSubsumption( pCs, nCubes, nWords, vMarks );
304         if ( fVerbose )
305             printf( "%4d", Count );
306     } while ( Count );
307 
308     // translate
309     Io_ReadPlaCubeSetdown( vSop, pCs, nCubes, nVars );
310     // finalize
311     if ( fVerbose )
312         printf( "\n" );
313     Vec_BitFree( vMarks );
314     ABC_FREE( pCs[0] );
315     ABC_FREE( pCs );
316 }
317 
318 /**Function*************************************************************
319 
320   Synopsis    [Reads the network from a PLA file.]
321 
322   Description []
323 
324   SideEffects []
325 
326   SeeAlso     []
327 
328 ***********************************************************************/
Io_ReadPla(char * pFileName,int fZeros,int fBoth,int fOnDc,int fSkipPrepro,int fCheck)329 Abc_Ntk_t * Io_ReadPla( char * pFileName, int fZeros, int fBoth, int fOnDc, int fSkipPrepro, int fCheck )
330 {
331     Extra_FileReader_t * p;
332     Abc_Ntk_t * pNtk;
333 
334     // start the file
335     p = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t|" );
336 //    p = Extra_FileReaderAlloc( pFileName, "", "\n\r", " \t|" );
337     if ( p == NULL )
338         return NULL;
339 
340     // read the network
341     pNtk = Io_ReadPlaNetwork( p, fZeros, fBoth, fOnDc, fSkipPrepro );
342     Extra_FileReaderFree( p );
343     if ( pNtk == NULL )
344         return NULL;
345 
346     // make sure that everything is okay with the network structure
347     if ( fCheck && !Abc_NtkCheckRead( pNtk ) )
348     {
349         printf( "Io_ReadPla: The network check has failed.\n" );
350         Abc_NtkDelete( pNtk );
351         return NULL;
352     }
353     return pNtk;
354 }
355 /**Function*************************************************************
356 
357   Synopsis    []
358 
359   Description []
360 
361   SideEffects []
362 
363   SeeAlso     []
364 
365 ***********************************************************************/
Io_ReadPlaNetwork(Extra_FileReader_t * p,int fZeros,int fBoth,int fOnDc,int fSkipPrepro)366 Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p, int fZeros, int fBoth, int fOnDc, int fSkipPrepro )
367 {
368     ProgressBar * pProgress;
369     Vec_Ptr_t * vTokens;
370     Abc_Ntk_t * pNtk;
371     Abc_Obj_t * pTermPi, * pTermPo, * pNode;
372     Vec_Str_t ** ppSops = NULL;
373     char Buffer[100];
374     int nInputs = -1, nOutputs = -1, nProducts = -1;
375     char * pCubeIn, * pCubeOut;
376     int i, k, iLine, nDigits, nCubes;
377 
378     // allocate the empty network
379     pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) );
380 
381     // go through the lines of the file
382     nCubes = 0;
383     pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p) );
384     while ( (vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p)) )
385     {
386         Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p), NULL );
387         iLine = Extra_FileReaderGetLineNumber( p, 0 );
388 
389         // if it is the end of file, quit the loop
390         if ( strncmp( (char *)vTokens->pArray[0], ".e", 2 ) == 0 )
391             break;
392 
393         // if it is type directive, ignore it for now
394         if ( strncmp( (char *)vTokens->pArray[0], ".type", 5 ) == 0 )
395             continue;
396 
397         // if it is the model name, get the name
398         if ( strcmp( (char *)vTokens->pArray[0], ".model" ) == 0 )
399         {
400             ABC_FREE( pNtk->pName );
401             pNtk->pName = Extra_UtilStrsav( (char *)vTokens->pArray[1] );
402             continue;
403         }
404 
405         if ( vTokens->nSize == 1 )
406         {
407             printf( "%s (line %d): Wrong number of token.\n",
408                 Extra_FileReaderGetFileName(p), iLine );
409             Abc_NtkDelete( pNtk );
410             Extra_ProgressBarStop( pProgress );
411             ABC_FREE( ppSops );
412             return NULL;
413         }
414 
415         if ( strcmp( (char *)vTokens->pArray[0], ".i" ) == 0 )
416             nInputs = atoi((char *)vTokens->pArray[1]);
417         else if ( strcmp( (char *)vTokens->pArray[0], ".o" ) == 0 )
418             nOutputs = atoi((char *)vTokens->pArray[1]);
419         else if ( strcmp( (char *)vTokens->pArray[0], ".p" ) == 0 )
420             nProducts = atoi((char *)vTokens->pArray[1]);
421         else if ( strcmp( (char *)vTokens->pArray[0], ".ilb" ) == 0 )
422         {
423             if ( vTokens->nSize - 1 != nInputs )
424                 printf( "Warning: Mismatch between the number of PIs on the .i line (%d) and the number of PIs on the .ilb line (%d).\n", nInputs, vTokens->nSize - 1 );
425             for ( i = 1; i < vTokens->nSize; i++ )
426                 Io_ReadCreatePi( pNtk, (char *)vTokens->pArray[i] );
427         }
428         else if ( strcmp( (char *)vTokens->pArray[0], ".ob" ) == 0 )
429         {
430             if ( vTokens->nSize - 1 != nOutputs )
431                 printf( "Warning: Mismatch between the number of POs on the .o line (%d) and the number of POs on the .ob line (%d).\n", nOutputs, vTokens->nSize - 1 );
432             for ( i = 1; i < vTokens->nSize; i++ )
433                 Io_ReadCreatePo( pNtk, (char *)vTokens->pArray[i] );
434         }
435         else
436         {
437             // check if the input/output names are given
438             if ( Abc_NtkPiNum(pNtk) == 0 )
439             {
440                 if ( nInputs == -1 )
441                 {
442                     printf( "%s: The number of inputs is not specified.\n", Extra_FileReaderGetFileName(p) );
443                     Abc_NtkDelete( pNtk );
444                     Extra_ProgressBarStop( pProgress );
445                     ABC_FREE( ppSops );
446                     return NULL;
447                 }
448                 nDigits = Abc_Base10Log( nInputs );
449                 for ( i = 0; i < nInputs; i++ )
450                 {
451                     sprintf( Buffer, "x%0*d", nDigits, i );
452                     Io_ReadCreatePi( pNtk, Buffer );
453                 }
454             }
455             if ( Abc_NtkPoNum(pNtk) == 0 )
456             {
457                 if ( nOutputs == -1 )
458                 {
459                     printf( "%s: The number of outputs is not specified.\n", Extra_FileReaderGetFileName(p) );
460                     Abc_NtkDelete( pNtk );
461                     Extra_ProgressBarStop( pProgress );
462                     ABC_FREE( ppSops );
463                     return NULL;
464                 }
465                 nDigits = Abc_Base10Log( nOutputs );
466                 for ( i = 0; i < nOutputs; i++ )
467                 {
468                     sprintf( Buffer, "z%0*d", nDigits, i );
469                     Io_ReadCreatePo( pNtk, Buffer );
470                 }
471             }
472             if ( Abc_NtkNodeNum(pNtk) == 0 )
473             { // first time here
474                 // create the PO drivers and add them
475                 // start the SOP covers
476                 ppSops = ABC_ALLOC( Vec_Str_t *, nOutputs );
477                 Abc_NtkForEachPo( pNtk, pTermPo, i )
478                 {
479                     ppSops[i] = Vec_StrAlloc( 100 );
480                     // create the node
481                     pNode = Abc_NtkCreateNode(pNtk);
482                     // connect the node to the PO net
483                     Abc_ObjAddFanin( Abc_ObjFanin0Ntk(pTermPo), pNode );
484                     // connect the node to the PI nets
485                     Abc_NtkForEachPi( pNtk, pTermPi, k )
486                         Abc_ObjAddFanin( pNode, Abc_ObjFanout0Ntk(pTermPi) );
487                 }
488             }
489             // read the cubes
490             if ( vTokens->nSize != 2 )
491             {
492                 printf( "%s (line %d): Input and output cubes are not specified.\n",
493                     Extra_FileReaderGetFileName(p), iLine );
494                 Abc_NtkDelete( pNtk );
495                 Extra_ProgressBarStop( pProgress );
496                 ABC_FREE( ppSops );
497                 return NULL;
498             }
499             pCubeIn  = (char *)vTokens->pArray[0];
500             pCubeOut = (char *)vTokens->pArray[1];
501             if ( (int)strlen(pCubeIn) != nInputs )
502             {
503                 printf( "%s (line %d): Input cube length (%d) differs from the number of inputs (%d).\n",
504                     Extra_FileReaderGetFileName(p), iLine, (int)strlen(pCubeIn), nInputs );
505                 Abc_NtkDelete( pNtk );
506                 ABC_FREE( ppSops );
507                 return NULL;
508             }
509             if ( (int)strlen(pCubeOut) != nOutputs )
510             {
511                 printf( "%s (line %d): Output cube length (%d) differs from the number of outputs (%d).\n",
512                     Extra_FileReaderGetFileName(p), iLine, (int)strlen(pCubeOut), nOutputs );
513                 Abc_NtkDelete( pNtk );
514                 Extra_ProgressBarStop( pProgress );
515                 ABC_FREE( ppSops );
516                 return NULL;
517             }
518             if ( fZeros )
519             {
520                 for ( i = 0; i < nOutputs; i++ )
521                 {
522                     if ( pCubeOut[i] == '0' )
523                     {
524                         Vec_StrPrintStr( ppSops[i], pCubeIn );
525                         Vec_StrPrintStr( ppSops[i], " 1\n" );
526                     }
527                 }
528             }
529             else if ( fBoth )
530             {
531                 for ( i = 0; i < nOutputs; i++ )
532                 {
533                     if ( pCubeOut[i] == '0' || pCubeOut[i] == '1' )
534                     {
535                         Vec_StrPrintStr( ppSops[i], pCubeIn );
536                         Vec_StrPrintStr( ppSops[i], " 1\n" );
537                     }
538                 }
539             }
540             else if ( fOnDc )
541             {
542                 for ( i = 0; i < nOutputs; i++ )
543                 {
544                     if ( pCubeOut[i] == '-' || pCubeOut[i] == '1' )
545                     {
546                         Vec_StrPrintStr( ppSops[i], pCubeIn );
547                         Vec_StrPrintStr( ppSops[i], " 1\n" );
548                     }
549                 }
550             }
551             else
552             {
553                 for ( i = 0; i < nOutputs; i++ )
554                 {
555                     if ( pCubeOut[i] == '1' )
556                     {
557                         Vec_StrPrintStr( ppSops[i], pCubeIn );
558                         Vec_StrPrintStr( ppSops[i], " 1\n" );
559                     }
560                 }
561             }
562             nCubes++;
563         }
564     }
565     Extra_ProgressBarStop( pProgress );
566     if ( nProducts != -1 && nCubes != nProducts )
567         printf( "Warning: Mismatch between the number of cubes (%d) and the number on .p line (%d).\n",
568             nCubes, nProducts );
569 
570     // add the SOP covers
571     Abc_NtkForEachPo( pNtk, pTermPo, i )
572     {
573         pNode = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pTermPo) );
574         if ( ppSops[i]->nSize == 0 )
575         {
576             Abc_ObjRemoveFanins(pNode);
577             pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" );
578             Vec_StrFree( ppSops[i] );
579             continue;
580         }
581         Vec_StrPush( ppSops[i], 0 );
582         if ( !fSkipPrepro )
583             Io_ReadPlaCubePreprocess( ppSops[i], i, 0 );
584         pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, ppSops[i]->pArray );
585         Vec_StrFree( ppSops[i] );
586     }
587     ABC_FREE( ppSops );
588     Abc_NtkFinalizeRead( pNtk );
589     return pNtk;
590 }
591 
592 
593 ////////////////////////////////////////////////////////////////////////
594 ///                       END OF FILE                                ///
595 ////////////////////////////////////////////////////////////////////////
596 
597 
598 
599 ABC_NAMESPACE_IMPL_END
600 
601