hopDfs.c 17.2 KB
Newer Older
Alan Mishchenko committed
1 2
/**CFile****************************************************************

Alan Mishchenko committed
3
  FileName    [hopDfs.c]
Alan Mishchenko committed
4 5 6 7 8 9 10 11 12 13 14 15 16

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Minimalistic And-Inverter Graph package.]

  Synopsis    [DFS traversal procedures.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - May 11, 2006.]

Alan Mishchenko committed
17
  Revision    [$Id: hopDfs.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
Alan Mishchenko committed
18 19 20

***********************************************************************/

Alan Mishchenko committed
21
#include "hop.h"
Alan Mishchenko committed
22

23 24 25
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [Collects internal nodes in the DFS order.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
45
void Hop_ManDfs_rec( Hop_Obj_t * pObj, Vec_Ptr_t * vNodes )
Alan Mishchenko committed
46
{
Alan Mishchenko committed
47 48
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
49
        return;
Alan Mishchenko committed
50 51 52 53
    Hop_ManDfs_rec( Hop_ObjFanin0(pObj), vNodes );
    Hop_ManDfs_rec( Hop_ObjFanin1(pObj), vNodes );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA(pObj);
Alan Mishchenko committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67
    Vec_PtrPush( vNodes, pObj );
}

/**Function*************************************************************

  Synopsis    [Collects internal nodes in the DFS order.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
68
Vec_Ptr_t * Hop_ManDfs( Hop_Man_t * p )
Alan Mishchenko committed
69 70
{
    Vec_Ptr_t * vNodes;
Alan Mishchenko committed
71
    Hop_Obj_t * pObj;
Alan Mishchenko committed
72
    int i;
Alan Mishchenko committed
73 74 75 76 77
    vNodes = Vec_PtrAlloc( Hop_ManNodeNum(p) );
    Hop_ManForEachNode( p, pObj, i )
        Hop_ManDfs_rec( pObj, vNodes );
    Hop_ManForEachNode( p, pObj, i )
        Hop_ObjClearMarkA(pObj);
Alan Mishchenko committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91
    return vNodes;
}

/**Function*************************************************************

  Synopsis    [Collects internal nodes in the DFS order.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
92
Vec_Ptr_t * Hop_ManDfsNode( Hop_Man_t * p, Hop_Obj_t * pNode )
Alan Mishchenko committed
93 94
{
    Vec_Ptr_t * vNodes;
Alan Mishchenko committed
95
    Hop_Obj_t * pObj;
Alan Mishchenko committed
96
    int i;
Alan Mishchenko committed
97
    assert( !Hop_IsComplement(pNode) );
Alan Mishchenko committed
98
    vNodes = Vec_PtrAlloc( 16 );
Alan Mishchenko committed
99
    Hop_ManDfs_rec( pNode, vNodes );
100
    Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i )
Alan Mishchenko committed
101
        Hop_ObjClearMarkA(pObj);
Alan Mishchenko committed
102 103 104 105 106 107 108 109 110 111 112 113 114 115
    return vNodes;
}

/**Function*************************************************************

  Synopsis    [Computes the max number of levels in the manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
116
int Hop_ManCountLevels( Hop_Man_t * p )
Alan Mishchenko committed
117 118
{
    Vec_Ptr_t * vNodes;
Alan Mishchenko committed
119
    Hop_Obj_t * pObj;
Alan Mishchenko committed
120 121
    int i, LevelsMax, Level0, Level1;
    // initialize the levels
Alan Mishchenko committed
122 123
    Hop_ManConst1(p)->pData = NULL;
    Hop_ManForEachPi( p, pObj, i )
Alan Mishchenko committed
124 125
        pObj->pData = NULL;
    // compute levels in a DFS order
Alan Mishchenko committed
126
    vNodes = Hop_ManDfs( p );
127
    Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i )
Alan Mishchenko committed
128
    {
Alan Mishchenko committed
129 130
        Level0 = (int)(ABC_PTRUINT_T)Hop_ObjFanin0(pObj)->pData;
        Level1 = (int)(ABC_PTRUINT_T)Hop_ObjFanin1(pObj)->pData;
131
        pObj->pData = (void *)(ABC_PTRUINT_T)(1 + Hop_ObjIsExor(pObj) + Abc_MaxInt(Level0, Level1));
Alan Mishchenko committed
132 133 134 135
    }
    Vec_PtrFree( vNodes );
    // get levels of the POs
    LevelsMax = 0;
Alan Mishchenko committed
136
    Hop_ManForEachPo( p, pObj, i )
137
        LevelsMax = Abc_MaxInt( LevelsMax, (int)(ABC_PTRUINT_T)Hop_ObjFanin0(pObj)->pData );
Alan Mishchenko committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151
    return LevelsMax;
}

/**Function*************************************************************

  Synopsis    [Creates correct reference counters at each node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
152
void Hop_ManCreateRefs( Hop_Man_t * p )
Alan Mishchenko committed
153
{
Alan Mishchenko committed
154
    Hop_Obj_t * pObj;
Alan Mishchenko committed
155 156 157 158 159
    int i;
    if ( p->fRefCount )
        return;
    p->fRefCount = 1;
    // clear refs
Alan Mishchenko committed
160 161 162 163 164 165 166
    Hop_ObjClearRef( Hop_ManConst1(p) );
    Hop_ManForEachPi( p, pObj, i )
        Hop_ObjClearRef( pObj );
    Hop_ManForEachNode( p, pObj, i )
        Hop_ObjClearRef( pObj );
    Hop_ManForEachPo( p, pObj, i )
        Hop_ObjClearRef( pObj );
Alan Mishchenko committed
167
    // set refs
Alan Mishchenko committed
168
    Hop_ManForEachNode( p, pObj, i )
Alan Mishchenko committed
169
    {
Alan Mishchenko committed
170 171
        Hop_ObjRef( Hop_ObjFanin0(pObj) );
        Hop_ObjRef( Hop_ObjFanin1(pObj) );
Alan Mishchenko committed
172
    }
Alan Mishchenko committed
173 174
    Hop_ManForEachPo( p, pObj, i )
        Hop_ObjRef( Hop_ObjFanin0(pObj) );
Alan Mishchenko committed
175 176 177 178 179 180 181 182 183 184 185 186 187
}

/**Function*************************************************************

  Synopsis    [Counts the number of AIG nodes rooted at this cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
188
void Hop_ConeMark_rec( Hop_Obj_t * pObj )
Alan Mishchenko committed
189
{
Alan Mishchenko committed
190 191
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
192
        return;
Alan Mishchenko committed
193 194 195 196
    Hop_ConeMark_rec( Hop_ObjFanin0(pObj) );
    Hop_ConeMark_rec( Hop_ObjFanin1(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
Alan Mishchenko committed
197 198 199 200 201 202 203 204 205 206 207 208 209
}

/**Function*************************************************************

  Synopsis    [Counts the number of AIG nodes rooted at this cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
210
void Hop_ConeCleanAndMark_rec( Hop_Obj_t * pObj )
Alan Mishchenko committed
211
{
Alan Mishchenko committed
212 213
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
214
        return;
Alan Mishchenko committed
215 216 217 218
    Hop_ConeCleanAndMark_rec( Hop_ObjFanin0(pObj) );
    Hop_ConeCleanAndMark_rec( Hop_ObjFanin1(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
Alan Mishchenko committed
219 220 221 222 223 224 225 226 227 228 229 230 231 232
    pObj->pData = NULL;
}

/**Function*************************************************************

  Synopsis    [Counts the number of AIG nodes rooted at this cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
233
int Hop_ConeCountAndMark_rec( Hop_Obj_t * pObj )
Alan Mishchenko committed
234 235
{
    int Counter;
Alan Mishchenko committed
236 237
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
238
        return 0;
Alan Mishchenko committed
239 240 241 242
    Counter = 1 + Hop_ConeCountAndMark_rec( Hop_ObjFanin0(pObj) ) + 
        Hop_ConeCountAndMark_rec( Hop_ObjFanin1(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
Alan Mishchenko committed
243 244 245 246 247 248 249 250 251 252 253 254 255 256
    return Counter;
}

/**Function*************************************************************

  Synopsis    [Counts the number of AIG nodes rooted at this cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
257
void Hop_ConeUnmark_rec( Hop_Obj_t * pObj )
Alan Mishchenko committed
258
{
Alan Mishchenko committed
259 260
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || !Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
261
        return;
Alan Mishchenko committed
262 263 264 265
    Hop_ConeUnmark_rec( Hop_ObjFanin0(pObj) ); 
    Hop_ConeUnmark_rec( Hop_ObjFanin1(pObj) );
    assert( Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjClearMarkA( pObj );
Alan Mishchenko committed
266 267 268 269 270 271 272 273 274 275 276 277 278
}

/**Function*************************************************************

  Synopsis    [Counts the number of AIG nodes rooted at this cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
279
int Hop_DagSize( Hop_Obj_t * pObj )
Alan Mishchenko committed
280 281
{
    int Counter;
Alan Mishchenko committed
282 283
    Counter = Hop_ConeCountAndMark_rec( Hop_Regular(pObj) );
    Hop_ConeUnmark_rec( Hop_Regular(pObj) );
Alan Mishchenko committed
284 285 286 287 288
    return Counter;
}

/**Function*************************************************************

289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
  Synopsis    [Counts how many fanout the given node has.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Hop_ObjFanoutCount_rec( Hop_Obj_t * pObj, Hop_Obj_t * pPivot )
{
    int Counter;
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
        return (int)(pObj == pPivot);
    Counter = Hop_ObjFanoutCount_rec( Hop_ObjFanin0(pObj), pPivot ) + 
              Hop_ObjFanoutCount_rec( Hop_ObjFanin1(pObj), pPivot );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
    return Counter;
}
int Hop_ObjFanoutCount( Hop_Obj_t * pObj, Hop_Obj_t * pPivot )
{
    int Counter;
    assert( !Hop_IsComplement(pPivot) );
    Counter = Hop_ObjFanoutCount_rec( Hop_Regular(pObj), pPivot );
    Hop_ConeUnmark_rec( Hop_Regular(pObj) );
    return Counter;
}

/**Function*************************************************************

Alan Mishchenko committed
321 322 323 324 325 326 327 328 329
  Synopsis    [Transfers the AIG from one manager into another.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
330
void Hop_Transfer_rec( Hop_Man_t * pDest, Hop_Obj_t * pObj )
Alan Mishchenko committed
331
{
Alan Mishchenko committed
332 333
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
334
        return;
Alan Mishchenko committed
335 336 337 338 339
    Hop_Transfer_rec( pDest, Hop_ObjFanin0(pObj) ); 
    Hop_Transfer_rec( pDest, Hop_ObjFanin1(pObj) );
    pObj->pData = Hop_And( pDest, Hop_ObjChild0Copy(pObj), Hop_ObjChild1Copy(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
Alan Mishchenko committed
340 341 342 343 344 345 346 347 348 349 350 351 352
}

/**Function*************************************************************

  Synopsis    [Transfers the AIG from one manager into another.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
353
Hop_Obj_t * Hop_Transfer( Hop_Man_t * pSour, Hop_Man_t * pDest, Hop_Obj_t * pRoot, int nVars )
Alan Mishchenko committed
354
{
Alan Mishchenko committed
355
    Hop_Obj_t * pObj;
Alan Mishchenko committed
356 357 358 359
    int i;
    // solve simple cases
    if ( pSour == pDest )
        return pRoot;
Alan Mishchenko committed
360 361
    if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) )
        return Hop_NotCond( Hop_ManConst1(pDest), Hop_IsComplement(pRoot) );
Alan Mishchenko committed
362
    // set the PI mapping
Alan Mishchenko committed
363
    Hop_ManForEachPi( pSour, pObj, i )
Alan Mishchenko committed
364 365 366
    {
        if ( i == nVars )
           break;
Alan Mishchenko committed
367
        pObj->pData = Hop_IthVar(pDest, i);
Alan Mishchenko committed
368
    }
Alan Mishchenko committed
369
    // transfer and set markings
Alan Mishchenko committed
370
    Hop_Transfer_rec( pDest, Hop_Regular(pRoot) );
Alan Mishchenko committed
371
    // clear the markings
Alan Mishchenko committed
372
    Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
373
    return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
Alan Mishchenko committed
374 375
}

Alan Mishchenko committed
376 377 378 379 380 381 382 383 384 385 386
/**Function*************************************************************

  Synopsis    [Composes the AIG (pRoot) with the function (pFunc) using PI var (iVar).]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
387
void Hop_Compose_rec( Hop_Man_t * p, Hop_Obj_t * pObj, Hop_Obj_t * pFunc, Hop_Obj_t * pVar )
Alan Mishchenko committed
388
{
Alan Mishchenko committed
389 390
    assert( !Hop_IsComplement(pObj) );
    if ( Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
391
        return;
Alan Mishchenko committed
392
    if ( Hop_ObjIsConst1(pObj) || Hop_ObjIsPi(pObj) )
Alan Mishchenko committed
393 394 395 396
    {
        pObj->pData = pObj == pVar ? pFunc : pObj;
        return;
    }
Alan Mishchenko committed
397 398 399 400 401
    Hop_Compose_rec( p, Hop_ObjFanin0(pObj), pFunc, pVar ); 
    Hop_Compose_rec( p, Hop_ObjFanin1(pObj), pFunc, pVar );
    pObj->pData = Hop_And( p, Hop_ObjChild0Copy(pObj), Hop_ObjChild1Copy(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
Alan Mishchenko committed
402 403 404 405 406 407 408 409 410 411 412 413 414
}

/**Function*************************************************************

  Synopsis    [Composes the AIG (pRoot) with the function (pFunc) using PI var (iVar).]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
415
Hop_Obj_t * Hop_Compose( Hop_Man_t * p, Hop_Obj_t * pRoot, Hop_Obj_t * pFunc, int iVar )
Alan Mishchenko committed
416 417
{
    // quit if the PI variable is not defined
Alan Mishchenko committed
418
    if ( iVar >= Hop_ManPiNum(p) )
Alan Mishchenko committed
419
    {
Alan Mishchenko committed
420
        printf( "Hop_Compose(): The PI variable %d is not defined.\n", iVar );
Alan Mishchenko committed
421 422 423
        return NULL;
    }
    // recursively perform composition
Alan Mishchenko committed
424
    Hop_Compose_rec( p, Hop_Regular(pRoot), pFunc, Hop_ManPi(p, iVar) );
Alan Mishchenko committed
425
    // clear the markings
Alan Mishchenko committed
426
    Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
427
    return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
Alan Mishchenko committed
428 429
}

Alan Mishchenko committed
430 431
/**Function*************************************************************

432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
  Synopsis    [Complements the AIG (pRoot) with the function (pFunc) using PI var (iVar).]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Hop_Complement_rec( Hop_Man_t * p, Hop_Obj_t * pObj, Hop_Obj_t * pVar )
{
    assert( !Hop_IsComplement(pObj) );
    if ( Hop_ObjIsMarkA(pObj) )
        return;
    if ( Hop_ObjIsConst1(pObj) || Hop_ObjIsPi(pObj) )
    {
        pObj->pData = pObj == pVar ? Hop_Not(pObj) : pObj;
        return;
    }
    Hop_Complement_rec( p, Hop_ObjFanin0(pObj), pVar ); 
    Hop_Complement_rec( p, Hop_ObjFanin1(pObj), pVar );
    pObj->pData = Hop_And( p, Hop_ObjChild0Copy(pObj), Hop_ObjChild1Copy(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
}

/**Function*************************************************************

  Synopsis    [Complements the AIG (pRoot) with the function (pFunc) using PI var (iVar).]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Hop_Obj_t * Hop_Complement( Hop_Man_t * p, Hop_Obj_t * pRoot, int iVar )
{
    // quit if the PI variable is not defined
    if ( iVar >= Hop_ManPiNum(p) )
    {
        printf( "Hop_Complement(): The PI variable %d is not defined.\n", iVar );
        return NULL;
    }
    // recursively perform composition
    Hop_Complement_rec( p, Hop_Regular(pRoot), Hop_ManPi(p, iVar) );
    // clear the markings
    Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
    return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
}

/**Function*************************************************************

Alan Mishchenko committed
486
  Synopsis    [Remaps the AIG (pRoot) to have the given support (uSupp).]
Alan Mishchenko committed
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Hop_Remap_rec( Hop_Man_t * p, Hop_Obj_t * pObj )
{
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
        return;
    Hop_Remap_rec( p, Hop_ObjFanin0(pObj) ); 
    Hop_Remap_rec( p, Hop_ObjFanin1(pObj) );
    pObj->pData = Hop_And( p, Hop_ObjChild0Copy(pObj), Hop_ObjChild1Copy(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
}

/**Function*************************************************************

Alan Mishchenko committed
509
  Synopsis    [Remaps the AIG (pRoot) to have the given support (uSupp).]
Alan Mishchenko committed
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Hop_Obj_t * Hop_Remap( Hop_Man_t * p, Hop_Obj_t * pRoot, unsigned uSupp, int nVars )
{
    Hop_Obj_t * pObj;
    int i, k;
    // quit if the PI variable is not defined
    if ( nVars > Hop_ManPiNum(p) )
    {
        printf( "Hop_Remap(): The number of variables (%d) is more than the manager size (%d).\n", nVars, Hop_ManPiNum(p) );
        return NULL;
    }
    // return if constant
    if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) )
        return pRoot;
    if ( uSupp == 0 )
        return Hop_NotCond( Hop_ManConst0(p), Hop_ObjPhaseCompl(pRoot) );
    // set the PI mapping
    k = 0;
    Hop_ManForEachPi( p, pObj, i )
    {
        if ( i == nVars )
           break;
        if ( uSupp & (1 << i) )
            pObj->pData = Hop_IthVar(p, k++);
        else
            pObj->pData = Hop_ManConst0(p);
    }
    assert( k > 0 && k < nVars );
    // recursively perform composition
    Hop_Remap_rec( p, Hop_Regular(pRoot) );
    // clear the markings
    Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
549
    return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
Alan Mishchenko committed
550 551
}

552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
/**Function*************************************************************

  Synopsis    [Permute the AIG according to the given permutation.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Hop_Obj_t * Hop_Permute( Hop_Man_t * p, Hop_Obj_t * pRoot, int nRootVars, int * pPermute )
{
    Hop_Obj_t * pObj;
    int i;
    // return if constant
    if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) )
        return pRoot;
    // create mapping
    Hop_ManForEachPi( p, pObj, i )
    {
        if ( i == nRootVars )
            break;
        assert( pPermute[i] >= 0 && pPermute[i] < Hop_ManPiNum(p) );
        pObj->pData = Hop_IthVar( p, pPermute[i] );
    }
    // recursively perform composition
    Hop_Remap_rec( p, Hop_Regular(pRoot) );
    // clear the markings
    Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
    return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
}

Alan Mishchenko committed
585 586 587 588 589
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


590 591
ABC_NAMESPACE_IMPL_END