src/sat/fraig/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

Fraig_Node_tFraig_NodeAndCanon (Fraig_Man_t *pMan, Fraig_Node_t *p1, Fraig_Node_t *p2)

Function Documentation

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

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

FileName [fraigCanon.c]

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

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

Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>]

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

] DECLARATIONS /// 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 49 of file fraigCanon.c.

00050 {
00051     Fraig_Node_t * pNodeNew, * pNodeOld, * pNodeRepr;
00052     int fUseSatCheck;
00053 //    int RetValue;
00054 
00055     // check for trivial cases
00056     if ( p1 == p2 )
00057         return p1;
00058     if ( p1 == Fraig_Not(p2) )
00059         return Fraig_Not(pMan->pConst1);
00060     if ( Fraig_NodeIsConst(p1) )
00061     {
00062         if ( p1 == pMan->pConst1 )
00063             return p2;
00064         return Fraig_Not(pMan->pConst1);
00065     }
00066     if ( Fraig_NodeIsConst(p2) )
00067     {
00068         if ( p2 == pMan->pConst1 )
00069             return p1;
00070         return Fraig_Not(pMan->pConst1);
00071     }
00072 /*
00073     // check for less trivial cases
00074     if ( Fraig_IsComplement(p1) )
00075     {
00076         if ( RetValue = Fraig_NodeIsInSupergate( Fraig_Regular(p1), p2 ) )
00077         {
00078             if ( RetValue == -1 )
00079                 pMan->nImplies0++;
00080             else
00081                 pMan->nImplies1++;
00082 
00083             if ( RetValue == -1 )
00084                 return p2;
00085         }
00086     }
00087     else
00088     {
00089         if ( RetValue = Fraig_NodeIsInSupergate( p1, p2 ) )
00090         {
00091             if ( RetValue == 1 )
00092                 pMan->nSimplifies1++;
00093             else
00094                 pMan->nSimplifies0++;
00095 
00096             if ( RetValue == 1 )
00097                 return p1;
00098             return Fraig_Not(pMan->pConst1);
00099         }
00100     }
00101  
00102     if ( Fraig_IsComplement(p2) )
00103     {
00104         if ( RetValue = Fraig_NodeIsInSupergate( Fraig_Regular(p2), p1 ) )
00105         {
00106             if ( RetValue == -1 )
00107                 pMan->nImplies0++;
00108             else
00109                 pMan->nImplies1++;
00110 
00111             if ( RetValue == -1 )
00112                 return p1;
00113         }
00114     }
00115     else
00116     {
00117         if ( RetValue = Fraig_NodeIsInSupergate( p2, p1 ) )
00118         {
00119             if ( RetValue == 1 )
00120                 pMan->nSimplifies1++;
00121             else
00122                 pMan->nSimplifies0++;
00123 
00124             if ( RetValue == 1 )
00125                 return p2;
00126             return Fraig_Not(pMan->pConst1);
00127         }
00128     }
00129 */
00130     // perform level-one structural hashing
00131     if ( Fraig_HashTableLookupS( pMan, p1, p2, &pNodeNew ) ) // the node with these children is found
00132     {
00133         // if the existent node is part of the cone of unused logic
00134         // (that is logic feeding the node which is equivalent to the given node)
00135         // return the canonical representative of this node
00136         // determine the phase of the given node, with respect to its canonical form
00137         pNodeRepr = Fraig_Regular(pNodeNew)->pRepr;
00138         if ( pMan->fFuncRed && pNodeRepr )
00139             return Fraig_NotCond( pNodeRepr, Fraig_IsComplement(pNodeNew) ^ Fraig_NodeComparePhase(Fraig_Regular(pNodeNew), pNodeRepr) );
00140         // otherwise, the node is itself a canonical representative, return it
00141         return pNodeNew;
00142     }
00143     // the same node is not found, but the new one is created
00144 
00145     // if one level hashing is requested (without functionality hashing), return
00146     if ( !pMan->fFuncRed )
00147         return pNodeNew;
00148 
00149     // check if the new node is unique using the simulation info
00150     if ( pNodeNew->nOnes == 0 || pNodeNew->nOnes == (unsigned)pMan->nWordsRand * 32 )
00151     {
00152         pMan->nSatZeros++;
00153         if ( !pMan->fDoSparse ) // if we do not do sparse functions, skip
00154             return pNodeNew;
00155         // check the sparse function simulation hash table
00156         pNodeOld = Fraig_HashTableLookupF0( pMan, pNodeNew );
00157         if ( pNodeOld == NULL ) // the node is unique (it is added to the table)
00158             return pNodeNew;
00159     }
00160     else
00161     {
00162         // check the simulation hash table
00163         pNodeOld = Fraig_HashTableLookupF( pMan, pNodeNew );
00164         if ( pNodeOld == NULL ) // the node is unique
00165             return pNodeNew;
00166     }
00167     assert( pNodeOld->pRepr == 0 );
00168     // there is another node which looks the same according to simulation
00169 
00170     // use SAT to resolve the ambiguity
00171     fUseSatCheck = (pMan->nInspLimit == 0 || Fraig_ManReadInspects(pMan) < pMan->nInspLimit); 
00172     if ( fUseSatCheck && Fraig_NodeIsEquivalent( pMan, pNodeOld, pNodeNew, pMan->nBTLimit, 1000000 ) )
00173     {
00174         // set the node to be equivalent with this node
00175         // to prevent loops, only set if the old node is not in the TFI of the new node
00176         // the loop may happen in the following case: suppose 
00177         // NodeC = AND(NodeA, NodeB) and at the same time NodeA => NodeB
00178         // in this case, NodeA and NodeC are functionally equivalent
00179         // however, NodeA is a fanin of node NodeC (this leads to the loop)
00180         // add the node to the list of equivalent nodes or dereference it
00181         if ( pMan->fChoicing && !Fraig_CheckTfi( pMan, pNodeOld, pNodeNew ) )
00182         { 
00183             // if the old node is not in the TFI of the new node and choicing 
00184             // is enabled, add the new node to the list of equivalent ones
00185             pNodeNew->pNextE = pNodeOld->pNextE;
00186             pNodeOld->pNextE = pNodeNew;
00187         }
00188         // set the canonical representative of this node
00189         pNodeNew->pRepr = pNodeOld;
00190         // return the equivalent node
00191         return Fraig_NotCond( pNodeOld, Fraig_NodeComparePhase(pNodeOld, pNodeNew) );
00192     }
00193 
00194     // now we add another member to this simulation class
00195     if ( pNodeNew->nOnes == 0 || pNodeNew->nOnes == (unsigned)pMan->nWordsRand * 32 )
00196     {
00197         Fraig_Node_t * pNodeTemp;
00198         assert( pMan->fDoSparse );
00199         pNodeTemp = Fraig_HashTableLookupF0( pMan, pNodeNew );
00200 //        assert( pNodeTemp == NULL );
00201 //        Fraig_HashTableInsertF0( pMan, pNodeNew );
00202     }
00203     else
00204     {
00205         pNodeNew->pNextD = pNodeOld->pNextD;
00206         pNodeOld->pNextD = pNodeNew;
00207     }
00208     // return the new node
00209     assert( pNodeNew->pRepr == 0 );
00210     return pNodeNew;
00211 }


Generated on Tue Jan 5 12:19:38 2010 for abc70930 by  doxygen 1.6.1